Browse Source

*: vendor prometheus

Xiang Li 11 years ago
parent
commit
fb1a28c65d
100 changed files with 33636 additions and 0 deletions
  1. 43 0
      Godeps/Godeps.json
  2. 40 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/Makefile
  3. 1979 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/all_test.go
  4. 174 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/clone.go
  5. 201 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/clone_test.go
  6. 721 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/decode.go
  7. 1054 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/encode.go
  8. 241 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/equal.go
  9. 166 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/equal_test.go
  10. 353 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/extensions.go
  11. 94 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/extensions_test.go
  12. 740 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/lib.go
  13. 287 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/message_set.go
  14. 66 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/message_set_test.go
  15. 384 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/pointer_reflect.go
  16. 218 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/pointer_unsafe.go
  17. 662 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/properties.go
  18. 63 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/size2_test.go
  19. 120 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/size_test.go
  20. 50 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/testdata/Makefile
  21. 86 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/testdata/golden_test.go
  22. 2356 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/testdata/test.pb.go
  23. 428 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/testdata/test.proto
  24. 695 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/text.go
  25. 687 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/text_parser.go
  26. 468 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/text_parser_test.go
  27. 407 0
      Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/text_test.go
  28. 43 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/Makefile
  29. 2059 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/all_test.go
  30. 197 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go
  31. 226 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/clone_test.go
  32. 821 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go
  33. 1283 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go
  34. 256 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go
  35. 191 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/equal_test.go
  36. 353 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go
  37. 137 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions_test.go
  38. 759 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go
  39. 287 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go
  40. 66 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set_test.go
  41. 479 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_reflect.go
  42. 266 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_unsafe.go
  43. 724 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go
  44. 44 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile
  45. 58 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto
  46. 93 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_test.go
  47. 63 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/size2_test.go
  48. 135 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/size_test.go
  49. 50 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata/Makefile
  50. 86 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata/golden_test.go
  51. 2389 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata/test.pb.go
  52. 434 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata/test.proto
  53. 789 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go
  54. 757 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go
  55. 511 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser_test.go
  56. 435 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/text_test.go
  57. 355 0
      Godeps/_workspace/src/github.com/matttproud/golang_protobuf_extensions/ext/all_test.go
  58. 75 0
      Godeps/_workspace/src/github.com/matttproud/golang_protobuf_extensions/ext/decode.go
  59. 16 0
      Godeps/_workspace/src/github.com/matttproud/golang_protobuf_extensions/ext/doc.go
  60. 46 0
      Godeps/_workspace/src/github.com/matttproud/golang_protobuf_extensions/ext/encode.go
  61. 103 0
      Godeps/_workspace/src/github.com/matttproud/golang_protobuf_extensions/ext/fixtures_test.go
  62. 1 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/goautoneg/MANIFEST
  63. 13 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/goautoneg/Makefile
  64. 67 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/goautoneg/README.txt
  65. 162 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/goautoneg/autoneg.go
  66. 33 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/goautoneg/autoneg_test.go
  67. 63 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/perks/quantile/bench_test.go
  68. 112 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/perks/quantile/example_test.go
  69. 2388 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/perks/quantile/exampledata.txt
  70. 292 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/perks/quantile/stream.go
  71. 185 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/perks/quantile/stream_test.go
  72. 110 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/fingerprinting.go
  73. 63 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname.go
  74. 55 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname_test.go
  75. 64 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelset.go
  76. 36 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue.go
  77. 55 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue_test.go
  78. 164 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric.go
  79. 76 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric_test.go
  80. 15 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/model.go
  81. 79 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample.go
  82. 126 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample_test.go
  83. 37 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/samplevalue.go
  84. 97 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature.go
  85. 120 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature_test.go
  86. 115 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp.go
  87. 86 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp_test.go
  88. 1 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/.gitignore
  89. 53 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/README.md
  90. 131 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/benchmark_test.go
  91. 75 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/collector.go
  92. 175 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/counter.go
  93. 58 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/counter_test.go
  94. 197 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/desc.go
  95. 108 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/doc.go
  96. 130 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/example_clustermanager_test.go
  97. 87 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/example_memstats_test.go
  98. 67 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/example_selfcollector_test.go
  99. 452 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/examples_test.go
  100. 119 0
      Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/expvar.go

+ 43 - 0
Godeps/Godeps.json

@@ -9,6 +9,11 @@
 			"ImportPath": "code.google.com/p/gogoprotobuf/proto",
 			"Rev": "7fd1620f09261338b6b1ca1289ace83aee0ec946"
 		},
+		{
+			"ImportPath": "code.google.com/p/goprotobuf/proto",
+			"Comment": "go.r60-163",
+			"Rev": "9352842ae63ee1d7e74e074ce7bb10370c4b6b9e"
+		},
 		{
 			"ImportPath": "github.com/codahale/hdrhistogram",
 			"Rev": "9208b142303c12d8899bae836fd524ac9338b4fd"
@@ -27,10 +32,48 @@
 			"Comment": "v0.2.0-rc1-130-g6aa2da5",
 			"Rev": "6aa2da5a7a905609c93036b9307185a04a5a84a5"
 		},
+		{
+			"ImportPath": "github.com/golang/protobuf/proto",
+			"Rev": "5677a0e3d5e89854c9974e1256839ee23f8233ca"
+		},
 		{
 			"ImportPath": "github.com/jonboulle/clockwork",
 			"Rev": "72f9bd7c4e0c2a40055ab3d0f09654f730cce982"
 		},
+		{
+			"ImportPath": "github.com/matttproud/golang_protobuf_extensions/ext",
+			"Rev": "7a864a042e844af638df17ebbabf8183dace556a"
+		},
+		{
+			"ImportPath": "github.com/prometheus/client_golang/_vendor/goautoneg",
+			"Comment": "0.1.0-22-g70f5497",
+			"Rev": "70f54973fb9187e8773d738cb6ef6881333f5f25"
+		},
+		{
+			"ImportPath": "github.com/prometheus/client_golang/_vendor/perks/quantile",
+			"Comment": "0.1.0-22-g70f5497",
+			"Rev": "70f54973fb9187e8773d738cb6ef6881333f5f25"
+		},
+		{
+			"ImportPath": "github.com/prometheus/client_golang/model",
+			"Comment": "0.1.0-22-g70f5497",
+			"Rev": "70f54973fb9187e8773d738cb6ef6881333f5f25"
+		},
+		{
+			"ImportPath": "github.com/prometheus/client_golang/prometheus",
+			"Comment": "0.1.0-22-g70f5497",
+			"Rev": "70f54973fb9187e8773d738cb6ef6881333f5f25"
+		},
+		{
+			"ImportPath": "github.com/prometheus/client_golang/text",
+			"Comment": "0.1.0-22-g70f5497",
+			"Rev": "70f54973fb9187e8773d738cb6ef6881333f5f25"
+		},
+		{
+			"ImportPath": "github.com/prometheus/client_model/go",
+			"Comment": "model-0.0.2-12-gfa8ad6f",
+			"Rev": "fa8ad6fec33561be4280a8f0514318c79d7f6cb6"
+		},
 		{
 			"ImportPath": "github.com/stretchr/testify/assert",
 			"Rev": "9cc77fa25329013ce07362c7742952ff887361f2"

+ 40 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/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

+ 1979 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/all_test.go

@@ -0,0 +1,1979 @@
+// 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"
+	"errors"
+	"fmt"
+	"math"
+	"math/rand"
+	"reflect"
+	"runtime/debug"
+	"strings"
+	"testing"
+	"time"
+
+	. "./testdata"
+	. "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/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)
+		}
+	}
+}
+
+// fakeMarshaler is a simple struct implementing Marshaler and Message interfaces.
+type fakeMarshaler struct {
+	b   []byte
+	err error
+}
+
+func (f fakeMarshaler) Marshal() ([]byte, error) {
+	return f.b, f.err
+}
+
+func (f fakeMarshaler) String() string {
+	return fmt.Sprintf("Bytes: %v Error: %v", f.b, f.err)
+}
+
+func (f fakeMarshaler) ProtoMessage() {}
+
+func (f fakeMarshaler) Reset() {}
+
+// Simple tests for proto messages that implement the Marshaler interface.
+func TestMarshalerEncoding(t *testing.T) {
+	tests := []struct {
+		name    string
+		m       Message
+		want    []byte
+		wantErr error
+	}{
+		{
+			name: "Marshaler that fails",
+			m: fakeMarshaler{
+				err: errors.New("some marshal err"),
+				b:   []byte{5, 6, 7},
+			},
+			// Since there's an error, nothing should be written to buffer.
+			want:    nil,
+			wantErr: errors.New("some marshal err"),
+		},
+		{
+			name: "Marshaler that succeeds",
+			m: fakeMarshaler{
+				b: []byte{0, 1, 2, 3, 4, 127, 255},
+			},
+			want:    []byte{0, 1, 2, 3, 4, 127, 255},
+			wantErr: nil,
+		},
+	}
+	for _, test := range tests {
+		b := NewBuffer(nil)
+		err := b.Marshal(test.m)
+		if !reflect.DeepEqual(test.wantErr, err) {
+			t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr)
+		}
+		if !reflect.DeepEqual(test.want, b.Bytes()) {
+			t.Errorf("%s: got bytes %v wanted %v", test.name, b.Bytes(), test.want)
+		}
+	}
+}
+
+// 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 an int32 field can be upgraded to an int64 field.
+func TestNegativeInt32(t *testing.T) {
+	om := &OldMessage{
+		Num: Int32(-1),
+	}
+	b, err := Marshal(om)
+	if err != nil {
+		t.Fatalf("Marshal of OldMessage: %v", err)
+	}
+
+	// Check the size. It should be 11 bytes;
+	// 1 for the field/wire type, and 10 for the negative number.
+	if len(b) != 11 {
+		t.Errorf("%v marshaled as %q, wanted 11 bytes", om, b)
+	}
+
+	// Unmarshal into a NewMessage.
+	nm := new(NewMessage)
+	if err := Unmarshal(b, nm); err != nil {
+		t.Fatalf("Unmarshal to NewMessage: %v", err)
+	}
+	want := &NewMessage{
+		Num: Int64(-1),
+	}
+	if !Equal(nm, want) {
+		t.Errorf("nm = %v, want %v", nm, want)
+	}
+}
+
+// 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)
+	if err == nil {
+		t.Error("expected error, got no error")
+	} else if !strings.Contains(err.Error(), "bad wiretype") {
+		t.Error("expected bad wiretype 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),
+		StrZero:   String(""),
+	}
+	SetDefaults(m)
+	if !Equal(m, expected) {
+		t.Errorf("SetDefaults failed\n 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)}, 11},
+		{&Defaults{F_Uint32: Uint32(uint32(math.MaxInt32) + 1)}, 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)
+	}
+}

+ 174 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/clone.go

@@ -0,0 +1,174 @@
+// 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
+		}
+		if in.Type().Elem().Kind() == reflect.Uint8 {
+			// []byte is a scalar bytes field, not a repeated field.
+			// Make a deep copy.
+			// Append to []byte{} instead of []byte(nil) so that we never end up
+			// with a nil result.
+			out.SetBytes(append([]byte{}, in.Bytes()...))
+			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:
+			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
+	}
+}

+ 201 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/clone_test.go

@@ -0,0 +1,201 @@
+// 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/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+)
+
+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")
+	}
+	// Byte fields and repeated fields should be copied.
+	if &m.Pet[0] == &cloneTestMessage.Pet[0] {
+		t.Error("Pet: repeated field not copied")
+	}
+	if &m.Others[0] == &cloneTestMessage.Others[0] {
+		t.Error("Others: repeated field not copied")
+	}
+	if &m.Others[0].Value[0] == &cloneTestMessage.Others[0].Value[0] {
+		t.Error("Others[0].Value: bytes field not copied")
+	}
+	if &m.RepBytes[0] == &cloneTestMessage.RepBytes[0] {
+		t.Error("RepBytes: repeated field not copied")
+	}
+	if &m.RepBytes[0][0] == &cloneTestMessage.RepBytes[0][0] {
+		t.Error("RepBytes[0]: bytes field not copied")
+	}
+}
+
+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")},
+		},
+	},
+	// Check that a scalar bytes field replaces rather than appends.
+	{
+		src:  &pb.OtherMessage{Value: []byte("foo")},
+		dst:  &pb.OtherMessage{Value: []byte("bar")},
+		want: &pb.OtherMessage{Value: []byte("foo")},
+	},
+}
+
+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)
+		}
+	}
+}

+ 721 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/decode.go

@@ -0,0 +1,721 @@
+// 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"
+)
+
+// 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)
+
+	// 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 fmt.Errorf("proto: %s: wiretype end group for non-group", st)
+		}
+		tag := int(u >> 3)
+		if tag <= 0 {
+			return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
+		}
+		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 = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType)
+				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
+}

+ 1054 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/encode.go

@@ -0,0 +1,1054 @@
+// 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
+	}
+	if p.buf == nil && err == nil {
+		// Return a non-nil slice on success.
+		return []byte{}, nil
+	}
+	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(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(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 := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
+	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 := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+// Encode a uint32.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_uint32(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_uint32(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
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	return o.enc_len_struct(p.sprop, structp, &state)
+}
+
+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.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.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.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 := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		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 := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		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++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		p.valEnc(buf, uint64(x))
+	}
+
+	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++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		bufSize += p.valSize(uint64(x))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of uint32s ([]uint32).
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_uint32(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_uint32(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 uint32s ([]uint32) in packed format.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_packed_uint32(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_uint32(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
+		}
+
+		o.buf = append(o.buf, p.tagcode...)
+		err := o.enc_len_struct(p.sprop, structp, &state)
+		if err != nil && !state.shouldContinue(err, nil) {
+			if err == ErrNil {
+				return ErrRepeatedHasNil
+			}
+			return err
+		}
+	}
+	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.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.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.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(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(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
+}
+
+var zeroes [20]byte // longer than any conceivable sizeVarint
+
+// Encode a struct, preceded by its encoded length (as a varint).
+func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
+	iLen := len(o.buf)
+	o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
+	iMsg := len(o.buf)
+	err := o.enc_struct(prop, base)
+	if err != nil && !state.shouldContinue(err, nil) {
+		return err
+	}
+	lMsg := len(o.buf) - iMsg
+	lLen := sizeVarint(uint64(lMsg))
+	switch x := lLen - (iMsg - iLen); {
+	case x > 0: // actual length is x bytes larger than the space we reserved
+		// Move msg x bytes right.
+		o.buf = append(o.buf, zeroes[:x]...)
+		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
+	case x < 0: // actual length is x bytes smaller than the space we reserved
+		// Move msg x bytes left.
+		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
+		o.buf = o.buf[:len(o.buf)+x] // x is negative
+	}
+	// Encode the length in the reserved space.
+	o.buf = o.buf[:iLen]
+	o.EncodeVarint(uint64(lMsg))
+	o.buf = o.buf[:len(o.buf)+lMsg]
+	return state.err
+}
+
+// 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
+}

+ 241 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/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.
+  - 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
Godeps/_workspace/src/code.google.com/p/goprotobuf/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/Godeps/_workspace/src/code.google.com/p/goprotobuf/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)
+		}
+	}
+}

+ 353 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/extensions.go

@@ -0,0 +1,353 @@
+// 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.
+func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
+	if err := checkExtensionTypes(pb, extension); err != nil {
+		return nil, err
+	}
+
+	emap := pb.ExtensionMap()
+	e, ok := emap[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
+	emap[extension.Field] = e
+	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 == ErrMissingExtension {
+			err = nil
+		}
+		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
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/extensions_test.go

@@ -0,0 +1,94 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2014 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/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+)
+
+func TestGetExtensionsWithMissingExtensions(t *testing.T) {
+	msg := &pb.MyMessage{}
+	ext1 := &pb.Ext{}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
+		t.Fatalf("Could not set ext1: %s", ext1)
+	}
+	exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{
+		pb.E_Ext_More,
+		pb.E_Ext_Text,
+	})
+	if err != nil {
+		t.Fatalf("GetExtensions() failed: %s", err)
+	}
+	if exts[0] != ext1 {
+		t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0])
+	}
+	if exts[1] != nil {
+		t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1])
+	}
+}
+
+func TestGetExtensionStability(t *testing.T) {
+	check := func(m *pb.MyMessage) bool {
+		ext1, err := proto.GetExtension(m, pb.E_Ext_More)
+		if err != nil {
+			t.Fatalf("GetExtension() failed: %s", err)
+		}
+		ext2, err := proto.GetExtension(m, pb.E_Ext_More)
+		if err != nil {
+			t.Fatalf("GetExtension() failed: %s", err)
+		}
+		return ext1 == ext2
+	}
+	msg := &pb.MyMessage{Count: proto.Int32(4)}
+	ext0 := &pb.Ext{}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil {
+		t.Fatalf("Could not set ext1: %s", ext0)
+	}
+	if !check(msg) {
+		t.Errorf("GetExtension() not stable before marshaling")
+	}
+	bb, err := proto.Marshal(msg)
+	if err != nil {
+		t.Fatalf("Marshal() failed: %s", err)
+	}
+	msg1 := &pb.MyMessage{}
+	err = proto.Unmarshal(bb, msg1)
+	if err != nil {
+		t.Fatalf("Unmarshal() failed: %s", err)
+	}
+	if !check(msg1) {
+		t.Errorf("GetExtension() not stable after unmarshaling")
+	}
+}

+ 740 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/lib.go

@@ -0,0 +1,740 @@
+// 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/goprotobuf/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/goprotobuf/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
+
+	// 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 {
+	return &Buffer{buf: e}
+}
+
+// Reset resets the Buffer, ready for marshaling a new protocol buffer.
+func (p *Buffer) Reset() {
+	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 }
+
+/*
+ * 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.HasDefault {
+			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
+}

+ 287 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/message_set.go

@@ -0,0 +1,287 @@
+// 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 (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"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 ErrNoMessageTypeId
+	}
+
+	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 {
+		id := *item.TypeId
+		msg := item.Message
+
+		// Restore wire type and field number varint, plus length varint.
+		// Be careful to preserve duplicate items.
+		b := EncodeVarint(uint64(id)<<3 | WireBytes)
+		if ext, ok := m[id]; ok {
+			// Existing data; rip off the tag and length varint
+			// so we join the new data correctly.
+			// We can assume that ext.enc is set because we are unmarshaling.
+			o := ext.enc[len(b):]   // skip wire type and field number
+			_, n := DecodeVarint(o) // calculate length of length varint
+			o = o[n:]               // skip length varint
+			msg = append(o, msg...) // join old data and new data
+		}
+		b = append(b, EncodeVarint(uint64(len(msg)))...)
+		b = append(b, msg...)
+
+		m[id] = Extension{enc: b}
+	}
+	return nil
+}
+
+// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
+// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
+func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
+	var b bytes.Buffer
+	b.WriteByte('{')
+
+	// Process the map in key order for deterministic output.
+	ids := make([]int32, 0, len(m))
+	for id := range m {
+		ids = append(ids, id)
+	}
+	sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
+
+	for i, id := range ids {
+		ext := m[id]
+		if i > 0 {
+			b.WriteByte(',')
+		}
+
+		msd, ok := messageSetMap[id]
+		if !ok {
+			// Unknown type; we can't render it, so skip it.
+			continue
+		}
+		fmt.Fprintf(&b, `"[%s]":`, msd.name)
+
+		x := ext.value
+		if x == nil {
+			x = reflect.New(msd.t.Elem()).Interface()
+			if err := Unmarshal(ext.enc, x.(Message)); err != nil {
+				return nil, err
+			}
+		}
+		d, err := json.Marshal(x)
+		if err != nil {
+			return nil, err
+		}
+		b.Write(d)
+	}
+	b.WriteByte('}')
+	return b.Bytes(), nil
+}
+
+// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
+// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
+func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error {
+	// Common-case fast path.
+	if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
+		return nil
+	}
+
+	// This is fairly tricky, and it's not clear that it is needed.
+	return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
+}
+
+// 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(m Message, fieldNum int32, name string) {
+	messageSetMap[fieldNum] = messageSetDesc{
+		t:    reflect.TypeOf(m),
+		name: name,
+	}
+}

+ 66 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/message_set_test.go

@@ -0,0 +1,66 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2014 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 (
+	"bytes"
+	"testing"
+)
+
+func TestUnmarshalMessageSetWithDuplicate(t *testing.T) {
+	// Check that a repeated message set entry will be concatenated.
+	in := &MessageSet{
+		Item: []*_MessageSet_Item{
+			{TypeId: Int32(12345), Message: []byte("hoo")},
+			{TypeId: Int32(12345), Message: []byte("hah")},
+		},
+	}
+	b, err := Marshal(in)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+	t.Logf("Marshaled bytes: %q", b)
+
+	m := make(map[int32]Extension)
+	if err := UnmarshalMessageSet(b, m); err != nil {
+		t.Fatalf("UnmarshalMessageSet: %v", err)
+	}
+	ext, ok := m[12345]
+	if !ok {
+		t.Fatalf("Didn't retrieve extension 12345; map is %v", m)
+	}
+	// Skip wire type/field number and length varints.
+	got := skipVarint(skipVarint(ext.enc))
+	if want := []byte("hoohah"); !bytes.Equal(got, want) {
+		t.Errorf("Combined extension is %q, want %q", got, want)
+	}
+}

+ 384 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/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,!appenginevm
+
+// 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
Godeps/_workspace/src/code.google.com/p/goprotobuf/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 appenginevm
+
+// 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)))
+}

+ 662 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/properties.go

@@ -0,0 +1,662 @@
+// 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
+	HasDefault bool   // whether an explicit default was provided
+	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
+	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 p.HasDefault {
+		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.HasDefault = true
+			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
+			}
+		}
+	}
+}
+
+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
+
+	switch t1 := typ; t1.Kind() {
+	default:
+		fmt.Fprintf(os.Stderr, "proto: no coders for %v\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:
+			p.enc = (*Buffer).enc_int32
+			p.dec = (*Buffer).dec_int32
+			p.size = size_int32
+		case reflect.Uint32:
+			p.enc = (*Buffer).enc_uint32
+			p.dec = (*Buffer).dec_int32 // can reuse
+			p.size = size_uint32
+		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_uint32 // can just treat them as bits
+			p.dec = (*Buffer).dec_int32
+			p.size = size_uint32
+		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.Int32:
+			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 reflect.Uint32:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_uint32
+				p.size = size_slice_packed_uint32
+			} else {
+				p.enc = (*Buffer).enc_slice_uint32
+				p.size = size_slice_uint32
+			}
+			p.dec = (*Buffer).dec_slice_int32
+			p.packedDec = (*Buffer).dec_slice_packed_int32
+		case reflect.Int64, reflect.Uint64:
+			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 reflect.Uint8:
+			p.enc = (*Buffer).enc_slice_byte
+			p.dec = (*Buffer).dec_slice_byte
+			p.size = size_slice_byte
+		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_uint32
+					p.size = size_slice_packed_uint32
+				} else {
+					p.enc = (*Buffer).enc_slice_uint32
+					p.size = size_slice_uint32
+				}
+				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
+			}
+		}
+	}
+
+	// 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 {
+	// We're checking for (likely) pointer-receiver methods
+	// so if t is not a pointer, something is very wrong.
+	// The calls above only invoke isMarshaler on pointer types.
+	if t.Kind() != reflect.Ptr {
+		panic("proto: misuse of isMarshaler")
+	}
+	return t.Implements(marshalerType)
+}
+
+// isUnmarshaler reports whether type t implements Unmarshaler.
+func isUnmarshaler(t reflect.Type) bool {
+	// We're checking for (likely) pointer-receiver methods
+	// so if t is not a pointer, something is very wrong.
+	// The calls above only invoke isUnmarshaler on pointer types.
+	if t.Kind() != reflect.Ptr {
+		panic("proto: misuse of isUnmarshaler")
+	}
+	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.
+// t must represent a generated struct type of a protocol message.
+func GetProperties(t reflect.Type) *StructProperties {
+	if t.Kind() != reflect.Struct {
+		panic("proto: type must have kind struct")
+	}
+	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)
+
+// 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
+}

+ 63 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/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)
+		}
+	}
+}

+ 120 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/size_test.go

@@ -0,0 +1,120 @@
+// 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/Godeps/_workspace/src/code.google.com/p/goprotobuf/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)}},
+	{"negative int32", &pb.Defaults{F_Int32: Int32(-1)}},
+	{"small int64", &pb.Defaults{F_Int64: Int64(1)}},
+	{"big int64", &pb.Defaults{F_Int64: Int64(1 << 20)}},
+	{"negative int64", &pb.Defaults{F_Int64: Int64(-1)}},
+	{"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, -1}}},
+	{"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)
+		}
+	}
+}

+ 50 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/testdata/Makefile

@@ -0,0 +1,50 @@
+# 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.
+
+
+include ../../Make.protobuf
+
+all:	regenerate
+
+regenerate:
+	rm -f test.pb.go
+	make test.pb.go
+	
+# 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
Godeps/_workspace/src/code.google.com/p/goprotobuf/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", "--go_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")
+	}
+}

+ 2356 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/testdata/test.pb.go

@@ -0,0 +1,2356 @@
+// Code generated by protoc-gen-go.
+// source: test.proto
+// DO NOT EDIT!
+
+/*
+Package testdata is a generated protocol buffer package.
+
+It is generated from these files:
+	test.proto
+
+It has these top-level messages:
+	GoEnum
+	GoTestField
+	GoTest
+	GoSkipTest
+	NonPackedTest
+	PackedTest
+	MaxTag
+	OldMessage
+	NewMessage
+	InnerMessage
+	OtherMessage
+	MyMessage
+	Ext
+	MyMessageSet
+	Empty
+	MessageList
+	Strings
+	Defaults
+	SubDefaults
+	RepeatedEnum
+	MoreRepeated
+	GroupOld
+	GroupNew
+	FloatingPoint
+*/
+package testdata
+
+import proto "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+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"`
+	Num              *int32             `protobuf:"varint,2,opt,name=num" json:"num,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
+}
+
+func (m *OldMessage) GetNum() int32 {
+	if m != nil && m.Num != nil {
+		return *m.Num
+	}
+	return 0
+}
+
+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"`
+	// This is an int32 in OldMessage.
+	Num              *int64 `protobuf:"varint,2,opt,name=num" json:"num,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
+}
+
+func (m *NewMessage) GetNum() int64 {
+	if m != nil && m.Num != nil {
+		return *m.Num
+	}
+	return 0
+}
+
+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())
+}
+func (m *MyMessageSet) MarshalJSON() ([]byte, error) {
+	return proto.MarshalMessageSetJSON(m.XXX_extensions)
+}
+func (m *MyMessageSet) UnmarshalJSON(buf []byte) error {
+	return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions)
+}
+
+// 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"`
+	// Redundant but explicit defaults.
+	StrZero          *string `protobuf:"bytes,19,opt,name=str_zero,def=" json:"str_zero,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
+}
+
+func (m *Defaults) GetStrZero() string {
+	if m != nil && m.StrZero != nil {
+		return *m.StrZero
+	}
+	return ""
+}
+
+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)
+}

+ 428 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/testdata/test.proto

@@ -0,0 +1,428 @@
+// 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;
+
+  optional int32 num = 2;
+}
+
+// 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;
+
+  // This is an int32 in OldMessage.
+  optional int64 num = 2;
+}
+
+// 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;
+
+  // Redundant but explicit defaults.
+  optional string str_zero = 19 [default=""];
+}
+
+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;
+}

+ 695 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/text.go

@@ -0,0 +1,695 @@
+// 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"
+	"encoding"
+	"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
+					}
+				}
+				v := fv.Index(j)
+				if v.Kind() == reflect.Ptr && v.IsNil() {
+					// A nil message in a repeated field is not valid,
+					// but we can handle that more gracefully than panicking.
+					if _, err := w.Write([]byte("<nil>\n")); err != nil {
+						return err
+					}
+					continue
+				}
+				if err := writeAny(w, v, 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
+		}
+
+		// Enums have a String method, so writeAny will work fine.
+		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)
+
+	// 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 tm, ok := v.Interface().(encoding.TextMarshaler); ok {
+			text, err := tm.MarshalText()
+			if err != nil {
+				return err
+			}
+			if _, err = w.Write(text); err != nil {
+				return err
+			}
+		} else 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,
+	}
+
+	if tm, ok := pb.(encoding.TextMarshaler); ok {
+		text, err := tm.MarshalText()
+		if err != nil {
+			return err
+		}
+		if _, err = aw.Write(text); err != nil {
+			return err
+		}
+		if bw != nil {
+			return bw.Flush()
+		}
+		return nil
+	}
+	// 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()
+}

+ 687 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/text_parser.go

@@ -0,0 +1,687 @@
+// 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 (
+	"encoding"
+	"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 a RequiredNotSetError indicating which required field was not set.
+func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
+	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 &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)}
+		}
+	}
+	return &RequiredNotSetError{fmt.Sprintf("%v.<unknown field name>", 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) error {
+	st := sv.Type()
+	reqCount := GetProperties(st).reqCount
+	var reqFieldErr error
+	fieldSet := make(map[string]bool)
+	// 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 {
+				if _, ok := err.(*RequiredNotSetError); !ok {
+					return err
+				}
+				reqFieldErr = 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.
+			name := tok.value
+			fi, props, ok := structFieldByName(st, name)
+			if !ok {
+				return p.errorf("unknown field name %q in %v", name, st)
+			}
+
+			dst := sv.Field(fi)
+
+			// Check that it's not already set if it's not a repeated field.
+			if !props.Repeated && fieldSet[name] {
+				return p.errorf("non-repeated field %q was repeated", name)
+			}
+
+			if err := p.checkForColon(props, st.Field(fi).Type); err != nil {
+				return err
+			}
+
+			// Parse into the field.
+			fieldSet[name] = true
+			if err := p.readAny(dst, props); err != nil {
+				if _, ok := err.(*RequiredNotSetError); !ok {
+					return err
+				}
+				reqFieldErr = err
+			} else 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 reqFieldErr
+}
+
+func (p *textParser) readAny(v reflect.Value, props *Properties) error {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value == "" {
+		return p.errorf("unexpected EOF")
+	}
+
+	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)
+		}
+		// TODO: Handle nested messages which implement encoding.TextUnmarshaler.
+		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.
+// If a required field is not set and no other error occurs,
+// UnmarshalText returns *RequiredNotSetError.
+func UnmarshalText(s string, pb Message) error {
+	if um, ok := pb.(encoding.TextUnmarshaler); ok {
+		err := um.UnmarshalText([]byte(s))
+		return err
+	}
+	pb.Reset()
+	v := reflect.ValueOf(pb)
+	if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {
+		return pe
+	}
+	return nil
+}

+ 468 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/text_parser_test.go

@@ -0,0 +1,468 @@
+// 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/Godeps/_workspace/src/code.google.com/p/goprotobuf/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: 1 others { key: 123456789012345678901 }",
+		err: "line 1.23: invalid int64: 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:  `name: "Pawel"`,
+		err: `proto: required field "testdata.MyMessage.count" not set`,
+		out: &MyMessage{
+			Name: String("Pawel"),
+		},
+	},
+
+	// 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)
+			} else if _, ok := err.(*RequiredNotSetError); ok && test.out != nil && !reflect.DeepEqual(pb, test.out) {
+				t.Errorf("Test %d: Incorrect populated \nHave: %v\nWant: %v",
+					i, pb, test.out)
+			}
+		}
+	}
+}
+
+func TestUnmarshalTextCustomMessage(t *testing.T) {
+	msg := &textMessage{}
+	if err := UnmarshalText("custom", msg); err != nil {
+		t.Errorf("Unexpected error from custom unmarshal: %v", err)
+	}
+	if UnmarshalText("not custom", msg) == nil {
+		t.Errorf("Didn't get expected error from custom unmarshal")
+	}
+}
+
+// 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)))
+}

+ 407 - 0
Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/text_test.go

@@ -0,0 +1,407 @@
+// 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"
+
+	pb "./testdata"
+	"github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+)
+
+// textMessage implements the methods that allow it to marshal and unmarshal
+// itself as text.
+type textMessage struct {
+}
+
+func (*textMessage) MarshalText() ([]byte, error) {
+	return []byte("custom"), nil
+}
+
+func (*textMessage) UnmarshalText(bytes []byte) error {
+	if string(bytes) != "custom" {
+		return errors.New("expected 'custom'")
+	}
+	return nil
+}
+
+func (*textMessage) Reset()         {}
+func (*textMessage) String() string { return "" }
+func (*textMessage) ProtoMessage()  {}
+
+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 TestMarshalTextCustomMessage(t *testing.T) {
+	buf := new(bytes.Buffer)
+	if err := proto.MarshalText(buf, &textMessage{}); err != nil {
+		t.Fatalf("proto.MarshalText: %v", err)
+	}
+	s := buf.String()
+	if s != "custom" {
+		t.Errorf("Got %q, expected %q", s, "custom")
+	}
+}
+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)
+		}
+	}
+}
+
+func TestRepeatedNilText(t *testing.T) {
+	m := &pb.MessageList{
+		Message: []*pb.MessageList_Message{
+			nil,
+			&pb.MessageList_Message{
+				Name: proto.String("Horse"),
+			},
+			nil,
+		},
+	}
+	want := `Message <nil>
+Message {
+  name: "Horse"
+}
+Message <nil>
+`
+	if s := proto.MarshalTextString(m); s != want {
+		t.Errorf(" got: %s\nwant: %s", s, want)
+	}
+}

+ 43 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/Makefile

@@ -0,0 +1,43 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  All rights reserved.
+# https://github.com/golang/protobuf
+#
+# 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
+	make -C testdata
+	make -C proto3_proto
+	make

+ 2059 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/all_test.go

@@ -0,0 +1,2059 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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"
+	"errors"
+	"fmt"
+	"math"
+	"math/rand"
+	"reflect"
+	"runtime/debug"
+	"strings"
+	"testing"
+	"time"
+
+	. "./testdata"
+	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/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)
+		}
+	}
+}
+
+// fakeMarshaler is a simple struct implementing Marshaler and Message interfaces.
+type fakeMarshaler struct {
+	b   []byte
+	err error
+}
+
+func (f fakeMarshaler) Marshal() ([]byte, error) {
+	return f.b, f.err
+}
+
+func (f fakeMarshaler) String() string {
+	return fmt.Sprintf("Bytes: %v Error: %v", f.b, f.err)
+}
+
+func (f fakeMarshaler) ProtoMessage() {}
+
+func (f fakeMarshaler) Reset() {}
+
+// Simple tests for proto messages that implement the Marshaler interface.
+func TestMarshalerEncoding(t *testing.T) {
+	tests := []struct {
+		name    string
+		m       Message
+		want    []byte
+		wantErr error
+	}{
+		{
+			name: "Marshaler that fails",
+			m: fakeMarshaler{
+				err: errors.New("some marshal err"),
+				b:   []byte{5, 6, 7},
+			},
+			// Since there's an error, nothing should be written to buffer.
+			want:    nil,
+			wantErr: errors.New("some marshal err"),
+		},
+		{
+			name: "Marshaler that succeeds",
+			m: fakeMarshaler{
+				b: []byte{0, 1, 2, 3, 4, 127, 255},
+			},
+			want:    []byte{0, 1, 2, 3, 4, 127, 255},
+			wantErr: nil,
+		},
+	}
+	for _, test := range tests {
+		b := NewBuffer(nil)
+		err := b.Marshal(test.m)
+		if !reflect.DeepEqual(test.wantErr, err) {
+			t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr)
+		}
+		if !reflect.DeepEqual(test.want, b.Bytes()) {
+			t.Errorf("%s: got bytes %v wanted %v", test.name, b.Bytes(), test.want)
+		}
+	}
+}
+
+// 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 an int32 field can be upgraded to an int64 field.
+func TestNegativeInt32(t *testing.T) {
+	om := &OldMessage{
+		Num: Int32(-1),
+	}
+	b, err := Marshal(om)
+	if err != nil {
+		t.Fatalf("Marshal of OldMessage: %v", err)
+	}
+
+	// Check the size. It should be 11 bytes;
+	// 1 for the field/wire type, and 10 for the negative number.
+	if len(b) != 11 {
+		t.Errorf("%v marshaled as %q, wanted 11 bytes", om, b)
+	}
+
+	// Unmarshal into a NewMessage.
+	nm := new(NewMessage)
+	if err := Unmarshal(b, nm); err != nil {
+		t.Fatalf("Unmarshal to NewMessage: %v", err)
+	}
+	want := &NewMessage{
+		Num: Int64(-1),
+	}
+	if !Equal(nm, want) {
+		t.Errorf("nm = %v, want %v", nm, want)
+	}
+}
+
+// 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)
+	if err == nil {
+		t.Error("expected error, got no error")
+	} else if !strings.Contains(err.Error(), "bad wiretype") {
+		t.Error("expected bad wiretype 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),
+		StrZero:   String(""),
+	}
+	SetDefaults(m)
+	if !Equal(m, expected) {
+		t.Errorf("SetDefaults failed\n 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)}, 11},
+		{&Defaults{F_Uint32: Uint32(uint32(math.MaxInt32) + 1)}, 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)
+}
+
+func TestMapFieldMarshal(t *testing.T) {
+	m := &MessageWithMap{
+		NameMapping: map[int32]string{
+			1: "Rob",
+			4: "Ian",
+			8: "Dave",
+		},
+	}
+	b, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+
+	// b should be the concatenation of these three byte sequences in some order.
+	parts := []string{
+		"\n\a\b\x01\x12\x03Rob",
+		"\n\a\b\x04\x12\x03Ian",
+		"\n\b\b\x08\x12\x04Dave",
+	}
+	ok := false
+	for i := range parts {
+		for j := range parts {
+			if j == i {
+				continue
+			}
+			for k := range parts {
+				if k == i || k == j {
+					continue
+				}
+				try := parts[i] + parts[j] + parts[k]
+				if bytes.Equal(b, []byte(try)) {
+					ok = true
+					break
+				}
+			}
+		}
+	}
+	if !ok {
+		t.Fatalf("Incorrect Marshal output.\n got %q\nwant %q (or a permutation of that)", b, parts[0]+parts[1]+parts[2])
+	}
+	t.Logf("FYI b: %q", b)
+
+	(new(Buffer)).DebugPrint("Dump of b", b)
+}
+
+func TestMapFieldRoundTrips(t *testing.T) {
+	m := &MessageWithMap{
+		NameMapping: map[int32]string{
+			1: "Rob",
+			4: "Ian",
+			8: "Dave",
+		},
+		MsgMapping: map[int64]*FloatingPoint{
+			0x7001: &FloatingPoint{F: Float64(2.0)},
+		},
+		ByteMapping: map[bool][]byte{
+			false: []byte("that's not right!"),
+			true:  []byte("aye, 'tis true!"),
+		},
+	}
+	b, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+	t.Logf("FYI b: %q", b)
+	m2 := new(MessageWithMap)
+	if err := Unmarshal(b, m2); err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	for _, pair := range [][2]interface{}{
+		{m.NameMapping, m2.NameMapping},
+		{m.MsgMapping, m2.MsgMapping},
+		{m.ByteMapping, m2.ByteMapping},
+	} {
+		if !reflect.DeepEqual(pair[0], pair[1]) {
+			t.Errorf("Map did not survive a round trip.\ninitial: %v\n  final: %v", pair[0], pair[1])
+		}
+	}
+}
+
+// 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)
+	}
+}

+ 197 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go

@@ -0,0 +1,197 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 and merge.
+// 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.Map:
+		if in.Len() == 0 {
+			return
+		}
+		if out.IsNil() {
+			out.Set(reflect.MakeMap(in.Type()))
+		}
+		// For maps with value types of *T or []byte we need to deep copy each value.
+		elemKind := in.Type().Elem().Kind()
+		for _, key := range in.MapKeys() {
+			var val reflect.Value
+			switch elemKind {
+			case reflect.Ptr:
+				val = reflect.New(in.Type().Elem().Elem())
+				mergeAny(val, in.MapIndex(key))
+			case reflect.Slice:
+				val = in.MapIndex(key)
+				val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
+			default:
+				val = in.MapIndex(key)
+			}
+			out.SetMapIndex(key, val)
+		}
+	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
+		}
+		if in.Type().Elem().Kind() == reflect.Uint8 {
+			// []byte is a scalar bytes field, not a repeated field.
+			// Make a deep copy.
+			// Append to []byte{} instead of []byte(nil) so that we never end up
+			// with a nil result.
+			out.SetBytes(append([]byte{}, in.Bytes()...))
+			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:
+			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
+	}
+}

+ 226 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/clone_test.go

@@ -0,0 +1,226 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+)
+
+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")
+	}
+	// Byte fields and repeated fields should be copied.
+	if &m.Pet[0] == &cloneTestMessage.Pet[0] {
+		t.Error("Pet: repeated field not copied")
+	}
+	if &m.Others[0] == &cloneTestMessage.Others[0] {
+		t.Error("Others: repeated field not copied")
+	}
+	if &m.Others[0].Value[0] == &cloneTestMessage.Others[0].Value[0] {
+		t.Error("Others[0].Value: bytes field not copied")
+	}
+	if &m.RepBytes[0] == &cloneTestMessage.RepBytes[0] {
+		t.Error("RepBytes: repeated field not copied")
+	}
+	if &m.RepBytes[0][0] == &cloneTestMessage.RepBytes[0][0] {
+		t.Error("RepBytes[0]: bytes field not copied")
+	}
+}
+
+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")},
+		},
+	},
+	// Check that a scalar bytes field replaces rather than appends.
+	{
+		src:  &pb.OtherMessage{Value: []byte("foo")},
+		dst:  &pb.OtherMessage{Value: []byte("bar")},
+		want: &pb.OtherMessage{Value: []byte("foo")},
+	},
+	{
+		src: &pb.MessageWithMap{
+			NameMapping: map[int32]string{6: "Nigel"},
+			MsgMapping: map[int64]*pb.FloatingPoint{
+				0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)},
+			},
+			ByteMapping: map[bool][]byte{true: []byte("wowsa")},
+		},
+		dst: &pb.MessageWithMap{
+			NameMapping: map[int32]string{
+				6: "Bruce", // should be overwritten
+				7: "Andrew",
+			},
+		},
+		want: &pb.MessageWithMap{
+			NameMapping: map[int32]string{
+				6: "Nigel",
+				7: "Andrew",
+			},
+			MsgMapping: map[int64]*pb.FloatingPoint{
+				0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)},
+			},
+			ByteMapping: map[bool][]byte{true: []byte("wowsa")},
+		},
+	},
+}
+
+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)
+		}
+	}
+}

+ 821 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go

@@ -0,0 +1,821 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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"
+)
+
+// 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 nil, err
+	}
+
+	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)
+
+	// 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 fmt.Errorf("proto: %s: wiretype end group for non-group", st)
+		}
+		tag := int(u >> 3)
+		if tag <= 0 {
+			return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
+		}
+		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 = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType)
+				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
+}
+
+func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	*structPointer_BoolVal(base, p.field) = u != 0
+	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
+}
+
+func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word32Val_Set(structPointer_Word32Val(base, p.field), 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
+}
+
+func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word64Val_Set(structPointer_Word64Val(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
+	}
+	*structPointer_String(base, p.field) = &s
+	return nil
+}
+
+func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	*structPointer_StringVal(base, p.field) = s
+	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 map field.
+func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
+	raw, err := o.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+	oi := o.index       // index at the end of this map entry
+	o.index -= len(raw) // move buffer back to start of map entry
+
+	mptr := structPointer_Map(base, p.field, p.mtype) // *map[K]V
+	if mptr.Elem().IsNil() {
+		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
+	}
+	v := mptr.Elem() // map[K]V
+
+	// Prepare addressable doubly-indirect placeholders for the key and value types.
+	// See enc_new_map for why.
+	keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
+	keybase := toStructPointer(keyptr.Addr())                  // **K
+
+	var valbase structPointer
+	var valptr reflect.Value
+	switch p.mtype.Elem().Kind() {
+	case reflect.Slice:
+		// []byte
+		var dummy []byte
+		valptr = reflect.ValueOf(&dummy)  // *[]byte
+		valbase = toStructPointer(valptr) // *[]byte
+	case reflect.Ptr:
+		// message; valptr is **Msg; need to allocate the intermediate pointer
+		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
+		valptr.Set(reflect.New(valptr.Type().Elem()))
+		valbase = toStructPointer(valptr)
+	default:
+		// everything else
+		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
+		valbase = toStructPointer(valptr.Addr())                   // **V
+	}
+
+	// Decode.
+	// This parses a restricted wire format, namely the encoding of a message
+	// with two fields. See enc_new_map for the format.
+	for o.index < oi {
+		// tagcode for key and value properties are always a single byte
+		// because they have tags 1 and 2.
+		tagcode := o.buf[o.index]
+		o.index++
+		switch tagcode {
+		case p.mkeyprop.tagcode[0]:
+			if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
+				return err
+			}
+		case p.mvalprop.tagcode[0]:
+			if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
+				return err
+			}
+		default:
+			// TODO: Should we silently skip this instead?
+			return fmt.Errorf("proto: bad map data tag %d", raw[0])
+		}
+	}
+
+	v.SetMapIndex(keyptr.Elem(), valptr.Elem())
+	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
+}

+ 1283 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go

@@ -0,0 +1,1283 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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
+	}
+	if p.buf == nil && err == nil {
+		// Return a non-nil slice on success.
+		return []byte{}, nil
+	}
+	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(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(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 (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
+	v := *structPointer_BoolVal(base, p.field)
+	if !v {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, 1)
+	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
+}
+
+func size_proto3_bool(p *Properties, base structPointer) int {
+	v := *structPointer_BoolVal(base, p.field)
+	if !v {
+		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 := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Val(base, p.field)
+	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
+	if x == 0 {
+		return ErrNil
+	}
+	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 := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+func size_proto3_int32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32Val(base, p.field)
+	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
+	if x == 0 {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+// Encode a uint32.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_uint32(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 (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Val(base, p.field)
+	x := word32Val_Get(v)
+	if x == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_uint32(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
+}
+
+func size_proto3_uint32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32Val(base, p.field)
+	x := word32Val_Get(v)
+	if x == 0 {
+		return 0
+	}
+	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 (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64Val(base, p.field)
+	x := word64Val_Get(v)
+	if x == 0 {
+		return ErrNil
+	}
+	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
+}
+
+func size_proto3_int64(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word64Val(base, p.field)
+	x := word64Val_Get(v)
+	if x == 0 {
+		return 0
+	}
+	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 (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
+	v := *structPointer_StringVal(base, p.field)
+	if v == "" {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeStringBytes(v)
+	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
+}
+
+func size_proto3_string(p *Properties, base structPointer) (n int) {
+	v := *structPointer_StringVal(base, p.field)
+	if v == "" {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeStringBytes(v)
+	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
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	return o.enc_len_struct(p.sprop, structp, &state)
+}
+
+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.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.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.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 (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
+	s := *structPointer_Bytes(base, p.field)
+	if len(s) == 0 {
+		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
+}
+
+func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
+	s := *structPointer_Bytes(base, p.field)
+	if len(s) == 0 {
+		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 := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		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 := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		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++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		p.valEnc(buf, uint64(x))
+	}
+
+	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++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		bufSize += p.valSize(uint64(x))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of uint32s ([]uint32).
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_uint32(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_uint32(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 uint32s ([]uint32) in packed format.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_packed_uint32(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_uint32(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
+		}
+
+		o.buf = append(o.buf, p.tagcode...)
+		err := o.enc_len_struct(p.sprop, structp, &state)
+		if err != nil && !state.shouldContinue(err, nil) {
+			if err == ErrNil {
+				return ErrRepeatedHasNil
+			}
+			return err
+		}
+	}
+	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.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.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.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 map field.
+func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
+	var state errorState // XXX: or do we need to plumb this through?
+
+	/*
+		A map defined as
+			map<key_type, value_type> map_field = N;
+		is encoded in the same way as
+			message MapFieldEntry {
+				key_type key = 1;
+				value_type value = 2;
+			}
+			repeated MapFieldEntry map_field = N;
+	*/
+
+	v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
+	if v.Len() == 0 {
+		return nil
+	}
+
+	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
+
+	enc := func() error {
+		if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
+			return err
+		}
+		if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
+			return err
+		}
+		return nil
+	}
+
+	keys := v.MapKeys()
+	sort.Sort(mapKeys(keys))
+	for _, key := range keys {
+		val := v.MapIndex(key)
+
+		keycopy.Set(key)
+		valcopy.Set(val)
+
+		o.buf = append(o.buf, p.tagcode...)
+		if err := o.enc_len_thing(enc, &state); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func size_new_map(p *Properties, base structPointer) int {
+	v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
+
+	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
+
+	n := 0
+	for _, key := range v.MapKeys() {
+		val := v.MapIndex(key)
+		keycopy.Set(key)
+		valcopy.Set(val)
+
+		// Tag codes are two bytes per map entry.
+		n += 2
+		n += p.mkeyprop.size(p.mkeyprop, keybase)
+		n += p.mvalprop.size(p.mvalprop, valbase)
+	}
+	return n
+}
+
+// mapEncodeScratch returns a new reflect.Value matching the map's value type,
+// and a structPointer suitable for passing to an encoder or sizer.
+func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) {
+	// Prepare addressable doubly-indirect placeholders for the key and value types.
+	// This is needed because the element-type encoders expect **T, but the map iteration produces T.
+
+	keycopy = reflect.New(mapType.Key()).Elem()                 // addressable K
+	keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K
+	keyptr.Set(keycopy.Addr())                                  //
+	keybase = toStructPointer(keyptr.Addr())                    // **K
+
+	// Value types are more varied and require special handling.
+	switch mapType.Elem().Kind() {
+	case reflect.Slice:
+		// []byte
+		var dummy []byte
+		valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte
+		valbase = toStructPointer(valcopy.Addr())
+	case reflect.Ptr:
+		// message; the generated field type is map[K]*Msg (so V is *Msg),
+		// so we only need one level of indirection.
+		valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
+		valbase = toStructPointer(valcopy.Addr())
+	default:
+		// everything else
+		valcopy = reflect.New(mapType.Elem()).Elem()                // addressable V
+		valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V
+		valptr.Set(valcopy.Addr())                                  //
+		valbase = toStructPointer(valptr.Addr())                    // **V
+	}
+	return
+}
+
+// Encode a struct.
+func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
+	var state errorState
+	// Encode fields in tag order so that decoders may use optimizations
+	// that depend on the ordering.
+	// https://developers.google.com/protocol-buffers/docs/encoding#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(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
+}
+
+var zeroes [20]byte // longer than any conceivable sizeVarint
+
+// Encode a struct, preceded by its encoded length (as a varint).
+func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
+	return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
+}
+
+// Encode something, preceded by its encoded length (as a varint).
+func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
+	iLen := len(o.buf)
+	o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
+	iMsg := len(o.buf)
+	err := enc()
+	if err != nil && !state.shouldContinue(err, nil) {
+		return err
+	}
+	lMsg := len(o.buf) - iMsg
+	lLen := sizeVarint(uint64(lMsg))
+	switch x := lLen - (iMsg - iLen); {
+	case x > 0: // actual length is x bytes larger than the space we reserved
+		// Move msg x bytes right.
+		o.buf = append(o.buf, zeroes[:x]...)
+		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
+	case x < 0: // actual length is x bytes smaller than the space we reserved
+		// Move msg x bytes left.
+		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
+		o.buf = o.buf[:len(o.buf)+x] // x is negative
+	}
+	// Encode the length in the reserved space.
+	o.buf = o.buf[:iLen]
+	o.EncodeVarint(uint64(lMsg))
+	o.buf = o.buf[:len(o.buf)+lMsg]
+	return state.err
+}
+
+// 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
+}

+ 256 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go

@@ -0,0 +1,256 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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.
+  - 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.Map:
+		if v1.Len() != v2.Len() {
+			return false
+		}
+		for _, key := range v1.MapKeys() {
+			val2 := v2.MapIndex(key)
+			if !val2.IsValid() {
+				// This key was not found in the second map.
+				return false
+			}
+			if !equalAny(v1.MapIndex(key), val2) {
+				return false
+			}
+		}
+		return true
+	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
+}

+ 191 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/equal_test.go

@@ -0,0 +1,191 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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/Godeps/_workspace/src/github.com/golang/protobuf/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,
+	},
+
+	{
+		"map same",
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
+		true,
+	},
+	{
+		"map different entry",
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
+		&pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}},
+		false,
+	},
+	{
+		"map different key only",
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
+		&pb.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}},
+		false,
+	},
+	{
+		"map different value only",
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
+		false,
+	},
+}
+
+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)
+		}
+	}
+}

+ 353 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go

@@ -0,0 +1,353 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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.
+func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
+	if err := checkExtensionTypes(pb, extension); err != nil {
+		return nil, err
+	}
+
+	emap := pb.ExtensionMap()
+	e, ok := emap[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
+	emap[extension.Field] = e
+	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 == ErrMissingExtension {
+			err = nil
+		}
+		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()]
+}

+ 137 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions_test.go

@@ -0,0 +1,137 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2014 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+)
+
+func TestGetExtensionsWithMissingExtensions(t *testing.T) {
+	msg := &pb.MyMessage{}
+	ext1 := &pb.Ext{}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
+		t.Fatalf("Could not set ext1: %s", ext1)
+	}
+	exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{
+		pb.E_Ext_More,
+		pb.E_Ext_Text,
+	})
+	if err != nil {
+		t.Fatalf("GetExtensions() failed: %s", err)
+	}
+	if exts[0] != ext1 {
+		t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0])
+	}
+	if exts[1] != nil {
+		t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1])
+	}
+}
+
+func TestGetExtensionStability(t *testing.T) {
+	check := func(m *pb.MyMessage) bool {
+		ext1, err := proto.GetExtension(m, pb.E_Ext_More)
+		if err != nil {
+			t.Fatalf("GetExtension() failed: %s", err)
+		}
+		ext2, err := proto.GetExtension(m, pb.E_Ext_More)
+		if err != nil {
+			t.Fatalf("GetExtension() failed: %s", err)
+		}
+		return ext1 == ext2
+	}
+	msg := &pb.MyMessage{Count: proto.Int32(4)}
+	ext0 := &pb.Ext{}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil {
+		t.Fatalf("Could not set ext1: %s", ext0)
+	}
+	if !check(msg) {
+		t.Errorf("GetExtension() not stable before marshaling")
+	}
+	bb, err := proto.Marshal(msg)
+	if err != nil {
+		t.Fatalf("Marshal() failed: %s", err)
+	}
+	msg1 := &pb.MyMessage{}
+	err = proto.Unmarshal(bb, msg1)
+	if err != nil {
+		t.Fatalf("Unmarshal() failed: %s", err)
+	}
+	if !check(msg1) {
+		t.Errorf("GetExtension() not stable after unmarshaling")
+	}
+}
+
+func TestExtensionsRoundTrip(t *testing.T) {
+	msg := &pb.MyMessage{}
+	ext1 := &pb.Ext{
+		Data: proto.String("hi"),
+	}
+	ext2 := &pb.Ext{
+		Data: proto.String("there"),
+	}
+	exists := proto.HasExtension(msg, pb.E_Ext_More)
+	if exists {
+		t.Error("Extension More present unexpectedly")
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
+		t.Error(err)
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext2); err != nil {
+		t.Error(err)
+	}
+	e, err := proto.GetExtension(msg, pb.E_Ext_More)
+	if err != nil {
+		t.Error(err)
+	}
+	x, ok := e.(*pb.Ext)
+	if !ok {
+		t.Errorf("e has type %T, expected testdata.Ext", e)
+	} else if *x.Data != "there" {
+		t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x)
+	}
+	proto.ClearExtension(msg, pb.E_Ext_More)
+	if _, err = proto.GetExtension(msg, pb.E_Ext_More); err != proto.ErrMissingExtension {
+		t.Errorf("got %v, expected ErrMissingExtension", e)
+	}
+	if _, err := proto.GetExtension(msg, pb.E_X215); err == nil {
+		t.Error("expected bad extension error, got nil")
+	}
+	if err := proto.SetExtension(msg, pb.E_X215, 12); err == nil {
+		t.Error("expected extension err")
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, 12); err == nil {
+		t.Error("expected some sort of type mismatch error, got nil")
+	}
+}

+ 759 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go

@@ -0,0 +1,759 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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.
+		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 by the enclosing message's name, or by the
+		enum's type name if it is a top-level enum. Enum types have a String
+		method, and a Enum method to assist in message construction.
+	  - Nested messages, 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 proto "github.com/golang/protobuf/proto"
+		import math "math"
+
+		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))
+		}
+		func (x *FOO) UnmarshalJSON(data []byte) error {
+			value, err := proto.UnmarshalJSONEnum(FOO_value, data)
+			if err != nil {
+				return err
+			}
+			*x = FOO(value)
+			return nil
+		}
+
+		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 (m *Test) Reset()         { *m = Test{} }
+		func (m *Test) String() string { return proto.CompactTextString(m) }
+		func (*Test) ProtoMessage()    {}
+		const Default_Test_Type int32 = 77
+
+		func (m *Test) GetLabel() string {
+			if m != nil && m.Label != nil {
+				return *m.Label
+			}
+			return ""
+		}
+
+		func (m *Test) GetType() int32 {
+			if m != nil && m.Type != nil {
+				return *m.Type
+			}
+			return Default_Test_Type
+		}
+
+		func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
+			if m != nil {
+				return m.Optionalgroup
+			}
+			return nil
+		}
+
+		type Test_OptionalGroup struct {
+			RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
+		}
+		func (m *Test_OptionalGroup) Reset()         { *m = Test_OptionalGroup{} }
+		func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
+
+		func (m *Test_OptionalGroup) GetRequiredField() string {
+			if m != nil && m.RequiredField != nil {
+				return *m.RequiredField
+			}
+			return ""
+		}
+
+		func init() {
+			proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
+		}
+
+	To create and play with a Test object:
+
+		package main
+
+		import (
+			"log"
+
+			"github.com/golang/protobuf/proto"
+			pb "./example.pb"
+		)
+
+		func main() {
+			test := &pb.Test{
+				Label: proto.String("hello"),
+				Type:  proto.Int32(17),
+				Optionalgroup: &pb.Test_OptionalGroup{
+					RequiredField: proto.String("good bye"),
+				},
+			}
+			data, err := proto.Marshal(test)
+			if err != nil {
+				log.Fatal("marshaling error: ", err)
+			}
+			newTest := &pb.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
+
+	// 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 {
+	return &Buffer{buf: e}
+}
+
+// Reset resets the Buffer, ready for marshaling a new protocol buffer.
+func (p *Buffer) Reset() {
+	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 }
+
+/*
+ * 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 {
+	return &v
+}
+
+// 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.HasDefault {
+			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
+}
+
+// Map fields may have key types of non-float scalars, strings and enums.
+// The easiest way to sort them in some deterministic order is to use fmt.
+// If this turns out to be inefficient we can always consider other options,
+// such as doing a Schwartzian transform.
+
+type mapKeys []reflect.Value
+
+func (s mapKeys) Len() int      { return len(s) }
+func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s mapKeys) Less(i, j int) bool {
+	return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
+}

+ 287 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go

@@ -0,0 +1,287 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"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 ErrNoMessageTypeId
+	}
+
+	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 {
+		id := *item.TypeId
+		msg := item.Message
+
+		// Restore wire type and field number varint, plus length varint.
+		// Be careful to preserve duplicate items.
+		b := EncodeVarint(uint64(id)<<3 | WireBytes)
+		if ext, ok := m[id]; ok {
+			// Existing data; rip off the tag and length varint
+			// so we join the new data correctly.
+			// We can assume that ext.enc is set because we are unmarshaling.
+			o := ext.enc[len(b):]   // skip wire type and field number
+			_, n := DecodeVarint(o) // calculate length of length varint
+			o = o[n:]               // skip length varint
+			msg = append(o, msg...) // join old data and new data
+		}
+		b = append(b, EncodeVarint(uint64(len(msg)))...)
+		b = append(b, msg...)
+
+		m[id] = Extension{enc: b}
+	}
+	return nil
+}
+
+// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
+// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
+func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
+	var b bytes.Buffer
+	b.WriteByte('{')
+
+	// Process the map in key order for deterministic output.
+	ids := make([]int32, 0, len(m))
+	for id := range m {
+		ids = append(ids, id)
+	}
+	sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
+
+	for i, id := range ids {
+		ext := m[id]
+		if i > 0 {
+			b.WriteByte(',')
+		}
+
+		msd, ok := messageSetMap[id]
+		if !ok {
+			// Unknown type; we can't render it, so skip it.
+			continue
+		}
+		fmt.Fprintf(&b, `"[%s]":`, msd.name)
+
+		x := ext.value
+		if x == nil {
+			x = reflect.New(msd.t.Elem()).Interface()
+			if err := Unmarshal(ext.enc, x.(Message)); err != nil {
+				return nil, err
+			}
+		}
+		d, err := json.Marshal(x)
+		if err != nil {
+			return nil, err
+		}
+		b.Write(d)
+	}
+	b.WriteByte('}')
+	return b.Bytes(), nil
+}
+
+// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
+// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
+func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error {
+	// Common-case fast path.
+	if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
+		return nil
+	}
+
+	// This is fairly tricky, and it's not clear that it is needed.
+	return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
+}
+
+// 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(m Message, fieldNum int32, name string) {
+	messageSetMap[fieldNum] = messageSetDesc{
+		t:    reflect.TypeOf(m),
+		name: name,
+	}
+}

+ 66 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set_test.go

@@ -0,0 +1,66 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2014 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 (
+	"bytes"
+	"testing"
+)
+
+func TestUnmarshalMessageSetWithDuplicate(t *testing.T) {
+	// Check that a repeated message set entry will be concatenated.
+	in := &MessageSet{
+		Item: []*_MessageSet_Item{
+			{TypeId: Int32(12345), Message: []byte("hoo")},
+			{TypeId: Int32(12345), Message: []byte("hah")},
+		},
+	}
+	b, err := Marshal(in)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+	t.Logf("Marshaled bytes: %q", b)
+
+	m := make(map[int32]Extension)
+	if err := UnmarshalMessageSet(b, m); err != nil {
+		t.Fatalf("UnmarshalMessageSet: %v", err)
+	}
+	ext, ok := m[12345]
+	if !ok {
+		t.Fatalf("Didn't retrieve extension 12345; map is %v", m)
+	}
+	// Skip wire type/field number and length varints.
+	got := skipVarint(skipVarint(ext.enc))
+	if want := []byte("hoohah"); !bytes.Equal(got, want) {
+		t.Errorf("Combined extension is %q, want %q", got, want)
+	}
+}

+ 479 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_reflect.go

@@ -0,0 +1,479 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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)
+}
+
+// BoolVal returns the address of a bool field in the struct.
+func structPointer_BoolVal(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)
+}
+
+// StringVal returns the address of a string field in the struct.
+func structPointer_StringVal(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)
+}
+
+// Map returns the reflect.Value for the address of a map field in the struct.
+func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value {
+	return structPointer_field(p, f).Addr()
+}
+
+// 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 word32Val 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 word32Val struct {
+	v reflect.Value
+}
+
+// Set sets *p to x.
+func word32Val_Set(p word32Val, x uint32) {
+	switch p.v.Type() {
+	case int32Type:
+		p.v.SetInt(int64(x))
+		return
+	case uint32Type:
+		p.v.SetUint(uint64(x))
+		return
+	case float32Type:
+		p.v.SetFloat(float64(math.Float32frombits(x)))
+		return
+	}
+
+	// must be enum
+	p.v.SetInt(int64(int32(x)))
+}
+
+// Get gets the bits pointed at by p, as a uint32.
+func word32Val_Get(p word32Val) uint32 {
+	elem := p.v
+	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")
+}
+
+// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
+func structPointer_Word32Val(p structPointer, f field) word32Val {
+	return word32Val{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)}
+}
+
+// word64Val is like word32Val but for 64-bit values.
+type word64Val struct {
+	v reflect.Value
+}
+
+func word64Val_Set(p word64Val, o *Buffer, x uint64) {
+	switch p.v.Type() {
+	case int64Type:
+		p.v.SetInt(int64(x))
+		return
+	case uint64Type:
+		p.v.SetUint(x)
+		return
+	case float64Type:
+		p.v.SetFloat(math.Float64frombits(x))
+		return
+	}
+	panic("unreachable")
+}
+
+func word64Val_Get(p word64Val) uint64 {
+	elem := p.v
+	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_Word64Val(p structPointer, f field) word64Val {
+	return word64Val{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)}
+}

+ 266 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_unsafe.go

@@ -0,0 +1,266 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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)))
+}
+
+// BoolVal returns the address of a bool field in the struct.
+func structPointer_BoolVal(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)))
+}
+
+// StringVal returns the address of a string field in the struct.
+func structPointer_StringVal(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)))
+}
+
+// Map returns the reflect.Value for the address of a map field in the struct.
+func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value {
+	return reflect.NewAt(typ, 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 word32Val is the address of a 32-bit value field.
+type word32Val *uint32
+
+// Set sets *p to x.
+func word32Val_Set(p word32Val, x uint32) {
+	*p = x
+}
+
+// Get gets the value pointed at by p.
+func word32Val_Get(p word32Val) uint32 {
+	return *p
+}
+
+// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
+func structPointer_Word32Val(p structPointer, f field) word32Val {
+	return word32Val((*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))))
+}
+
+// word64Val is like word32Val but for 64-bit values.
+type word64Val *uint64
+
+func word64Val_Set(p word64Val, o *Buffer, x uint64) {
+	*p = x
+}
+
+func word64Val_Get(p word64Val) uint64 {
+	return *p
+}
+
+func structPointer_Word64Val(p structPointer, f field) word64Val {
+	return word64Val((*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)))
+}

+ 724 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go

@@ -0,0 +1,724 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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
+	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
+
+	Default    string // default value
+	HasDefault bool   // whether an explicit default was provided
+	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
+	sprop         *StructProperties // set for struct types only
+	isMarshaler   bool
+	isUnmarshaler bool
+
+	mtype    reflect.Type // set for map types only
+	mkeyprop *Properties  // set for map types only
+	mvalprop *Properties  // set for map types only
+
+	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 p.proto3 {
+		s += ",proto3"
+	}
+	if len(p.Enum) > 0 {
+		s += ",enum=" + p.Enum
+	}
+	if p.HasDefault {
+		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 f == "proto3":
+			p.proto3 = true
+		case strings.HasPrefix(f, "def="):
+			p.HasDefault = true
+			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
+			}
+		}
+	}
+}
+
+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, f *reflect.StructField, lockGetProp bool) {
+	p.enc = nil
+	p.dec = nil
+	p.size = nil
+
+	switch t1 := typ; t1.Kind() {
+	default:
+		fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
+
+	// proto3 scalar types
+
+	case reflect.Bool:
+		p.enc = (*Buffer).enc_proto3_bool
+		p.dec = (*Buffer).dec_proto3_bool
+		p.size = size_proto3_bool
+	case reflect.Int32:
+		p.enc = (*Buffer).enc_proto3_int32
+		p.dec = (*Buffer).dec_proto3_int32
+		p.size = size_proto3_int32
+	case reflect.Uint32:
+		p.enc = (*Buffer).enc_proto3_uint32
+		p.dec = (*Buffer).dec_proto3_int32 // can reuse
+		p.size = size_proto3_uint32
+	case reflect.Int64, reflect.Uint64:
+		p.enc = (*Buffer).enc_proto3_int64
+		p.dec = (*Buffer).dec_proto3_int64
+		p.size = size_proto3_int64
+	case reflect.Float32:
+		p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
+		p.dec = (*Buffer).dec_proto3_int32
+		p.size = size_proto3_uint32
+	case reflect.Float64:
+		p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
+		p.dec = (*Buffer).dec_proto3_int64
+		p.size = size_proto3_int64
+	case reflect.String:
+		p.enc = (*Buffer).enc_proto3_string
+		p.dec = (*Buffer).dec_proto3_string
+		p.size = size_proto3_string
+
+	case reflect.Ptr:
+		switch t2 := t1.Elem(); t2.Kind() {
+		default:
+			fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
+			break
+		case reflect.Bool:
+			p.enc = (*Buffer).enc_bool
+			p.dec = (*Buffer).dec_bool
+			p.size = size_bool
+		case reflect.Int32:
+			p.enc = (*Buffer).enc_int32
+			p.dec = (*Buffer).dec_int32
+			p.size = size_int32
+		case reflect.Uint32:
+			p.enc = (*Buffer).enc_uint32
+			p.dec = (*Buffer).dec_int32 // can reuse
+			p.size = size_uint32
+		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_uint32 // can just treat them as bits
+			p.dec = (*Buffer).dec_int32
+			p.size = size_uint32
+		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.Int32:
+			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 reflect.Uint32:
+			if p.Packed {
+				p.enc = (*Buffer).enc_slice_packed_uint32
+				p.size = size_slice_packed_uint32
+			} else {
+				p.enc = (*Buffer).enc_slice_uint32
+				p.size = size_slice_uint32
+			}
+			p.dec = (*Buffer).dec_slice_int32
+			p.packedDec = (*Buffer).dec_slice_packed_int32
+		case reflect.Int64, reflect.Uint64:
+			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 reflect.Uint8:
+			p.enc = (*Buffer).enc_slice_byte
+			p.dec = (*Buffer).dec_slice_byte
+			p.size = size_slice_byte
+			if p.proto3 {
+				p.enc = (*Buffer).enc_proto3_slice_byte
+				p.size = size_proto3_slice_byte
+			}
+		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_uint32
+					p.size = size_slice_packed_uint32
+				} else {
+					p.enc = (*Buffer).enc_slice_uint32
+					p.size = size_slice_uint32
+				}
+				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.Map:
+		p.enc = (*Buffer).enc_new_map
+		p.dec = (*Buffer).dec_new_map
+		p.size = size_new_map
+
+		p.mtype = t1
+		p.mkeyprop = &Properties{}
+		p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
+		p.mvalprop = &Properties{}
+		vtype := p.mtype.Elem()
+		if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
+			// The value type is not a message (*T) or bytes ([]byte),
+			// so we need encoders for the pointer to this type.
+			vtype = reflect.PtrTo(vtype)
+		}
+		p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
+	}
+
+	// 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 {
+	// We're checking for (likely) pointer-receiver methods
+	// so if t is not a pointer, something is very wrong.
+	// The calls above only invoke isMarshaler on pointer types.
+	if t.Kind() != reflect.Ptr {
+		panic("proto: misuse of isMarshaler")
+	}
+	return t.Implements(marshalerType)
+}
+
+// isUnmarshaler reports whether type t implements Unmarshaler.
+func isUnmarshaler(t reflect.Type) bool {
+	// We're checking for (likely) pointer-receiver methods
+	// so if t is not a pointer, something is very wrong.
+	// The calls above only invoke isUnmarshaler on pointer types.
+	if t.Kind() != reflect.Ptr {
+		panic("proto: misuse of isUnmarshaler")
+	}
+	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, f, lockGetProp)
+}
+
+var (
+	mutex         sync.Mutex
+	propertiesMap = make(map[reflect.Type]*StructProperties)
+)
+
+// GetProperties returns the list of properties for the type represented by t.
+// t must represent a generated struct type of a protocol message.
+func GetProperties(t reflect.Type) *StructProperties {
+	if t.Kind() != reflect.Struct {
+		panic("proto: type must have kind struct")
+	}
+	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)
+
+// 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
+}

+ 44 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile

@@ -0,0 +1,44 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2014 The Go Authors.  All rights reserved.
+# https://github.com/golang/protobuf
+#
+# 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.
+
+
+include ../../Make.protobuf
+
+all:	regenerate
+
+regenerate:
+	rm -f proto3.pb.go
+	make proto3.pb.go
+
+# The following rules are just aids to development. Not needed for typical testing.
+
+diff:	regenerate
+	git diff proto3.pb.go

+ 58 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto

@@ -0,0 +1,58 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2014 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+syntax = "proto3";
+
+package proto3_proto;
+
+message Message {
+  enum Humour {
+    UNKNOWN = 0;
+    PUNS = 1;
+    SLAPSTICK = 2;
+    BILL_BAILEY = 3;
+  }
+
+  string name = 1;
+  Humour hilarity = 2;
+  uint32 height_in_cm = 3;
+  bytes data = 4;
+  int64 result_count = 7;
+  bool true_scotsman = 8;
+  float score = 9;
+
+  repeated uint64 key = 5;
+  Nested nested = 6;
+}
+
+message Nested {
+  string bunny = 1;
+}

+ 93 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_test.go

@@ -0,0 +1,93 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2014 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 "./proto3_proto"
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+)
+
+func TestProto3ZeroValues(t *testing.T) {
+	tests := []struct {
+		desc string
+		m    proto.Message
+	}{
+		{"zero message", &pb.Message{}},
+		{"empty bytes field", &pb.Message{Data: []byte{}}},
+	}
+	for _, test := range tests {
+		b, err := proto.Marshal(test.m)
+		if err != nil {
+			t.Errorf("%s: proto.Marshal: %v", test.desc, err)
+			continue
+		}
+		if len(b) > 0 {
+			t.Errorf("%s: Encoding is non-empty: %q", test.desc, b)
+		}
+	}
+}
+
+func TestRoundTripProto3(t *testing.T) {
+	m := &pb.Message{
+		Name:         "David",          // (2 | 1<<3): 0x0a 0x05 "David"
+		Hilarity:     pb.Message_PUNS,  // (0 | 2<<3): 0x10 0x01
+		HeightInCm:   178,              // (0 | 3<<3): 0x18 0xb2 0x01
+		Data:         []byte("roboto"), // (2 | 4<<3): 0x20 0x06 "roboto"
+		ResultCount:  47,               // (0 | 7<<3): 0x38 0x2f
+		TrueScotsman: true,             // (0 | 8<<3): 0x40 0x01
+		Score:        8.1,              // (5 | 9<<3): 0x4d <8.1>
+
+		Key: []uint64{1, 0xdeadbeef},
+		Nested: &pb.Nested{
+			Bunny: "Monty",
+		},
+	}
+	t.Logf(" m: %v", m)
+
+	b, err := proto.Marshal(m)
+	if err != nil {
+		t.Fatalf("proto.Marshal: %v", err)
+	}
+	t.Logf(" b: %q", b)
+
+	m2 := new(pb.Message)
+	if err := proto.Unmarshal(b, m2); err != nil {
+		t.Fatalf("proto.Unmarshal: %v", err)
+	}
+	t.Logf("m2: %v", m2)
+
+	if !proto.Equal(m, m2) {
+		t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2)
+	}
+}

+ 63 - 0
Godeps/_workspace/src/github.com/golang/protobuf/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.
+// https://github.com/golang/protobuf
+//
+// 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)
+		}
+	}
+}

+ 135 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/size_test.go

@@ -0,0 +1,135 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2012 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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"
+
+	proto3pb "./proto3_proto"
+	pb "./testdata"
+	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/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)}},
+	{"negative int32", &pb.Defaults{F_Int32: Int32(-1)}},
+	{"small int64", &pb.Defaults{F_Int64: Int64(1)}},
+	{"big int64", &pb.Defaults{F_Int64: Int64(1 << 20)}},
+	{"negative int64", &pb.Defaults{F_Int64: Int64(-1)}},
+	{"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, -1}}},
+	{"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},
+	// proto3 message
+	{"proto3 empty", &proto3pb.Message{}},
+	{"proto3 bool", &proto3pb.Message{TrueScotsman: true}},
+	{"proto3 int64", &proto3pb.Message{ResultCount: 1}},
+	{"proto3 uint32", &proto3pb.Message{HeightInCm: 123}},
+	{"proto3 float", &proto3pb.Message{Score: 12.6}},
+	{"proto3 string", &proto3pb.Message{Name: "Snezana"}},
+	{"proto3 bytes", &proto3pb.Message{Data: []byte("wowsa")}},
+	{"proto3 bytes, empty", &proto3pb.Message{Data: []byte{}}},
+	{"proto3 enum", &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
+
+	{"map field", &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob", 7: "Andrew"}}},
+	{"map field with message", &pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{0x7001: &pb.FloatingPoint{F: Float64(2.0)}}}},
+	{"map field with bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte("this time for sure")}}},
+}
+
+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)
+		}
+	}
+}

+ 50 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata/Makefile

@@ -0,0 +1,50 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  All rights reserved.
+# https://github.com/golang/protobuf
+#
+# 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.
+
+
+include ../../Make.protobuf
+
+all:	regenerate
+
+regenerate:
+	rm -f test.pb.go
+	make test.pb.go
+
+# The following rules are just aids to development. Not needed for typical testing.
+
+diff:	regenerate
+	git diff test.pb.go
+
+restore:
+	cp test.pb.go.golden test.pb.go
+
+preserve:
+	cp test.pb.go test.pb.go.golden

+ 86 - 0
Godeps/_workspace/src/github.com/golang/protobuf/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.
+// https://github.com/golang/protobuf
+//
+// 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", "--go_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")
+	}
+}

+ 2389 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata/test.pb.go

@@ -0,0 +1,2389 @@
+// Code generated by protoc-gen-go.
+// source: test.proto
+// DO NOT EDIT!
+
+/*
+Package testdata is a generated protocol buffer package.
+
+It is generated from these files:
+	test.proto
+
+It has these top-level messages:
+	GoEnum
+	GoTestField
+	GoTest
+	GoSkipTest
+	NonPackedTest
+	PackedTest
+	MaxTag
+	OldMessage
+	NewMessage
+	InnerMessage
+	OtherMessage
+	MyMessage
+	Ext
+	MyMessageSet
+	Empty
+	MessageList
+	Strings
+	Defaults
+	SubDefaults
+	RepeatedEnum
+	MoreRepeated
+	GroupOld
+	GroupNew
+	FloatingPoint
+	MessageWithMap
+*/
+package testdata
+
+import proto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+import math "math"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+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"`
+	Num              *int32             `protobuf:"varint,2,opt,name=num" json:"num,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
+}
+
+func (m *OldMessage) GetNum() int32 {
+	if m != nil && m.Num != nil {
+		return *m.Num
+	}
+	return 0
+}
+
+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"`
+	// This is an int32 in OldMessage.
+	Num              *int64 `protobuf:"varint,2,opt,name=num" json:"num,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
+}
+
+func (m *NewMessage) GetNum() int64 {
+	if m != nil && m.Num != nil {
+		return *m.Num
+	}
+	return 0
+}
+
+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())
+}
+func (m *MyMessageSet) MarshalJSON() ([]byte, error) {
+	return proto.MarshalMessageSetJSON(m.XXX_extensions)
+}
+func (m *MyMessageSet) UnmarshalJSON(buf []byte) error {
+	return proto.UnmarshalMessageSetJSON(buf, m.XXX_extensions)
+}
+
+// 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"`
+	// Redundant but explicit defaults.
+	StrZero          *string `protobuf:"bytes,19,opt,name=str_zero,def=" json:"str_zero,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
+}
+
+func (m *Defaults) GetStrZero() string {
+	if m != nil && m.StrZero != nil {
+		return *m.StrZero
+	}
+	return ""
+}
+
+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
+}
+
+type MessageWithMap struct {
+	NameMapping      map[int32]string         `protobuf:"bytes,1,rep,name=name_mapping" json:"name_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	MsgMapping       map[int64]*FloatingPoint `protobuf:"bytes,2,rep,name=msg_mapping" json:"msg_mapping,omitempty" protobuf_key:"zigzag64,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	ByteMapping      map[bool][]byte          `protobuf:"bytes,3,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	XXX_unrecognized []byte                   `json:"-"`
+}
+
+func (m *MessageWithMap) Reset()         { *m = MessageWithMap{} }
+func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
+func (*MessageWithMap) ProtoMessage()    {}
+
+func (m *MessageWithMap) GetNameMapping() map[int32]string {
+	if m != nil {
+		return m.NameMapping
+	}
+	return nil
+}
+
+func (m *MessageWithMap) GetMsgMapping() map[int64]*FloatingPoint {
+	if m != nil {
+		return m.MsgMapping
+	}
+	return nil
+}
+
+func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
+	if m != nil {
+		return m.ByteMapping
+	}
+	return nil
+}
+
+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)
+}

+ 434 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata/test.proto

@@ -0,0 +1,434 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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;
+
+  optional int32 num = 2;
+}
+
+// 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;
+
+  // This is an int32 in OldMessage.
+  optional int64 num = 2;
+}
+
+// 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;
+
+  // Redundant but explicit defaults.
+  optional string str_zero = 19 [default=""];
+}
+
+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;
+}
+
+message MessageWithMap {
+  map<int32, string> name_mapping = 1;
+  map<sint64, FloatingPoint> msg_mapping = 2;
+  map<bool, bytes> byte_mapping = 3;
+}

+ 789 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go

@@ -0,0 +1,789 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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"
+	"encoding"
+	"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
+					}
+				}
+				v := fv.Index(j)
+				if v.Kind() == reflect.Ptr && v.IsNil() {
+					// A nil message in a repeated field is not valid,
+					// but we can handle that more gracefully than panicking.
+					if _, err := w.Write([]byte("<nil>\n")); err != nil {
+						return err
+					}
+					continue
+				}
+				if err := writeAny(w, v, props); err != nil {
+					return err
+				}
+				if err := w.WriteByte('\n'); err != nil {
+					return err
+				}
+			}
+			continue
+		}
+		if fv.Kind() == reflect.Map {
+			// Map fields are rendered as a repeated struct with key/value fields.
+			keys := fv.MapKeys() // TODO: should we sort these for deterministic output?
+			sort.Sort(mapKeys(keys))
+			for _, key := range keys {
+				val := fv.MapIndex(key)
+				if err := writeName(w, props); err != nil {
+					return err
+				}
+				if !w.compact {
+					if err := w.WriteByte(' '); err != nil {
+						return err
+					}
+				}
+				// open struct
+				if err := w.WriteByte('<'); err != nil {
+					return err
+				}
+				if !w.compact {
+					if err := w.WriteByte('\n'); err != nil {
+						return err
+					}
+				}
+				w.indent()
+				// key
+				if _, err := w.WriteString("key:"); err != nil {
+					return err
+				}
+				if !w.compact {
+					if err := w.WriteByte(' '); err != nil {
+						return err
+					}
+				}
+				if err := writeAny(w, key, props.mkeyprop); err != nil {
+					return err
+				}
+				if err := w.WriteByte('\n'); err != nil {
+					return err
+				}
+				// value
+				if _, err := w.WriteString("value:"); err != nil {
+					return err
+				}
+				if !w.compact {
+					if err := w.WriteByte(' '); err != nil {
+						return err
+					}
+				}
+				if err := writeAny(w, val, props.mvalprop); err != nil {
+					return err
+				}
+				if err := w.WriteByte('\n'); err != nil {
+					return err
+				}
+				// close struct
+				w.unindent()
+				if err := w.WriteByte('>'); err != nil {
+					return err
+				}
+				if err := w.WriteByte('\n'); err != nil {
+					return err
+				}
+			}
+			continue
+		}
+		if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 {
+			// empty bytes field
+			continue
+		}
+		if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
+			// proto3 non-repeated scalar field; skip if zero value
+			switch fv.Kind() {
+			case reflect.Bool:
+				if !fv.Bool() {
+					continue
+				}
+			case reflect.Int32, reflect.Int64:
+				if fv.Int() == 0 {
+					continue
+				}
+			case reflect.Uint32, reflect.Uint64:
+				if fv.Uint() == 0 {
+					continue
+				}
+			case reflect.Float32, reflect.Float64:
+				if fv.Float() == 0 {
+					continue
+				}
+			case reflect.String:
+				if fv.String() == "" {
+					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
+		}
+
+		// Enums have a String method, so writeAny will work fine.
+		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)
+
+	// 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 tm, ok := v.Interface().(encoding.TextMarshaler); ok {
+			text, err := tm.MarshalText()
+			if err != nil {
+				return err
+			}
+			if _, err = w.Write(text); err != nil {
+				return err
+			}
+		} else 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,
+	}
+
+	if tm, ok := pb.(encoding.TextMarshaler); ok {
+		text, err := tm.MarshalText()
+		if err != nil {
+			return err
+		}
+		if _, err = aw.Write(text); err != nil {
+			return err
+		}
+		if bw != nil {
+			return bw.Flush()
+		}
+		return nil
+	}
+	// 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()
+}

+ 757 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go

@@ -0,0 +1,757 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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 (
+	"encoding"
+	"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
+}
+
+func (p *textParser) consumeToken(s string) error {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value != s {
+		p.back()
+		return p.errorf("expected %q, found %q", s, tok.value)
+	}
+	return nil
+}
+
+// Return a RequiredNotSetError indicating which required field was not set.
+func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError {
+	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 &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)}
+		}
+	}
+	return &RequiredNotSetError{fmt.Sprintf("%v.<unknown field name>", 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
+				}
+			} else if typ.Kind() == reflect.String {
+				// The proto3 exception is for a string field,
+				// which requires a colon.
+				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) error {
+	st := sv.Type()
+	reqCount := GetProperties(st).reqCount
+	var reqFieldErr error
+	fieldSet := make(map[string]bool)
+	// 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 {
+				if _, ok := err.(*RequiredNotSetError); !ok {
+					return err
+				}
+				reqFieldErr = 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.
+			name := tok.value
+			fi, props, ok := structFieldByName(st, name)
+			if !ok {
+				return p.errorf("unknown field name %q in %v", name, st)
+			}
+
+			dst := sv.Field(fi)
+
+			if dst.Kind() == reflect.Map {
+				// Consume any colon.
+				if err := p.checkForColon(props, dst.Type()); err != nil {
+					return err
+				}
+
+				// Construct the map if it doesn't already exist.
+				if dst.IsNil() {
+					dst.Set(reflect.MakeMap(dst.Type()))
+				}
+				key := reflect.New(dst.Type().Key()).Elem()
+				val := reflect.New(dst.Type().Elem()).Elem()
+
+				// The map entry should be this sequence of tokens:
+				//	< key : KEY value : VALUE >
+				// Technically the "key" and "value" could come in any order,
+				// but in practice they won't.
+
+				tok := p.next()
+				var terminator string
+				switch tok.value {
+				case "<":
+					terminator = ">"
+				case "{":
+					terminator = "}"
+				default:
+					return p.errorf("expected '{' or '<', found %q", tok.value)
+				}
+				if err := p.consumeToken("key"); err != nil {
+					return err
+				}
+				if err := p.consumeToken(":"); err != nil {
+					return err
+				}
+				if err := p.readAny(key, props.mkeyprop); err != nil {
+					return err
+				}
+				if err := p.consumeToken("value"); err != nil {
+					return err
+				}
+				if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
+					return err
+				}
+				if err := p.readAny(val, props.mvalprop); err != nil {
+					return err
+				}
+				if err := p.consumeToken(terminator); err != nil {
+					return err
+				}
+
+				dst.SetMapIndex(key, val)
+				continue
+			}
+
+			// Check that it's not already set if it's not a repeated field.
+			if !props.Repeated && fieldSet[name] {
+				return p.errorf("non-repeated field %q was repeated", name)
+			}
+
+			if err := p.checkForColon(props, st.Field(fi).Type); err != nil {
+				return err
+			}
+
+			// Parse into the field.
+			fieldSet[name] = true
+			if err := p.readAny(dst, props); err != nil {
+				if _, ok := err.(*RequiredNotSetError); !ok {
+					return err
+				}
+				reqFieldErr = err
+			} else 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 reqFieldErr
+}
+
+func (p *textParser) readAny(v reflect.Value, props *Properties) error {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value == "" {
+		return p.errorf("unexpected EOF")
+	}
+
+	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)
+		}
+		// TODO: Handle nested messages which implement encoding.TextUnmarshaler.
+		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.
+// If a required field is not set and no other error occurs,
+// UnmarshalText returns *RequiredNotSetError.
+func UnmarshalText(s string, pb Message) error {
+	if um, ok := pb.(encoding.TextUnmarshaler); ok {
+		err := um.UnmarshalText([]byte(s))
+		return err
+	}
+	pb.Reset()
+	v := reflect.ValueOf(pb)
+	if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {
+		return pe
+	}
+	return nil
+}

+ 511 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser_test.go

@@ -0,0 +1,511 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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"
+
+	proto3pb "./proto3_proto"
+	. "./testdata"
+	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/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: 1 others { key: 123456789012345678901 }",
+		err: "line 1.23: invalid int64: 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:  `name: "Pawel"`,
+		err: `proto: required field "testdata.MyMessage.count" not set`,
+		out: &MyMessage{
+			Name: String("Pawel"),
+		},
+	},
+
+	// 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)
+			} else if _, ok := err.(*RequiredNotSetError); ok && test.out != nil && !reflect.DeepEqual(pb, test.out) {
+				t.Errorf("Test %d: Incorrect populated \nHave: %v\nWant: %v",
+					i, pb, test.out)
+			}
+		}
+	}
+}
+
+func TestUnmarshalTextCustomMessage(t *testing.T) {
+	msg := &textMessage{}
+	if err := UnmarshalText("custom", msg); err != nil {
+		t.Errorf("Unexpected error from custom unmarshal: %v", err)
+	}
+	if UnmarshalText("not custom", msg) == nil {
+		t.Errorf("Didn't get expected error from custom unmarshal")
+	}
+}
+
+// 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)
+	}
+}
+
+func TestProto3TextParsing(t *testing.T) {
+	m := new(proto3pb.Message)
+	const in = `name: "Wallace" true_scotsman: true`
+	want := &proto3pb.Message{
+		Name:         "Wallace",
+		TrueScotsman: true,
+	}
+	if err := UnmarshalText(in, m); err != nil {
+		t.Fatal(err)
+	}
+	if !Equal(m, want) {
+		t.Errorf("\n got %v\nwant %v", m, want)
+	}
+}
+
+func TestMapParsing(t *testing.T) {
+	m := new(MessageWithMap)
+	const in = `name_mapping:<key:1234 value:"Feist"> name_mapping:<key:1 value:"Beatles">` +
+		`msg_mapping:<key:-4 value:<f: 2.0>>` +
+		`msg_mapping<key:-2 value<f: 4.0>>` + // no colon after "value"
+		`byte_mapping:<key:true value:"so be it">`
+	want := &MessageWithMap{
+		NameMapping: map[int32]string{
+			1:    "Beatles",
+			1234: "Feist",
+		},
+		MsgMapping: map[int64]*FloatingPoint{
+			-4: {F: Float64(2.0)},
+			-2: {F: Float64(4.0)},
+		},
+		ByteMapping: map[bool][]byte{
+			true: []byte("so be it"),
+		},
+	}
+	if err := UnmarshalText(in, m); err != nil {
+		t.Fatal(err)
+	}
+	if !Equal(m, want) {
+		t.Errorf("\n got %v\nwant %v", m, want)
+	}
+}
+
+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)))
+}

+ 435 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/text_test.go

@@ -0,0 +1,435 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// 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"
+
+	proto3pb "./proto3_proto"
+	pb "./testdata"
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+)
+
+// textMessage implements the methods that allow it to marshal and unmarshal
+// itself as text.
+type textMessage struct {
+}
+
+func (*textMessage) MarshalText() ([]byte, error) {
+	return []byte("custom"), nil
+}
+
+func (*textMessage) UnmarshalText(bytes []byte) error {
+	if string(bytes) != "custom" {
+		return errors.New("expected 'custom'")
+	}
+	return nil
+}
+
+func (*textMessage) Reset()         {}
+func (*textMessage) String() string { return "" }
+func (*textMessage) ProtoMessage()  {}
+
+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 TestMarshalTextCustomMessage(t *testing.T) {
+	buf := new(bytes.Buffer)
+	if err := proto.MarshalText(buf, &textMessage{}); err != nil {
+		t.Fatalf("proto.MarshalText: %v", err)
+	}
+	s := buf.String()
+	if s != "custom" {
+		t.Errorf("Got %q, expected %q", s, "custom")
+	}
+}
+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)
+		}
+	}
+}
+
+func TestRepeatedNilText(t *testing.T) {
+	m := &pb.MessageList{
+		Message: []*pb.MessageList_Message{
+			nil,
+			&pb.MessageList_Message{
+				Name: proto.String("Horse"),
+			},
+			nil,
+		},
+	}
+	want := `Message <nil>
+Message {
+  name: "Horse"
+}
+Message <nil>
+`
+	if s := proto.MarshalTextString(m); s != want {
+		t.Errorf(" got: %s\nwant: %s", s, want)
+	}
+}
+
+func TestProto3Text(t *testing.T) {
+	tests := []struct {
+		m    proto.Message
+		want string
+	}{
+		// zero message
+		{&proto3pb.Message{}, ``},
+		// zero message except for an empty byte slice
+		{&proto3pb.Message{Data: []byte{}}, ``},
+		// trivial case
+		{&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`},
+		// empty map
+		{&pb.MessageWithMap{}, ``},
+		// non-empty map; current map format is the same as a repeated struct
+		{
+			&pb.MessageWithMap{NameMapping: map[int32]string{1234: "Feist"}},
+			`name_mapping:<key:1234 value:"Feist" >`,
+		},
+	}
+	for _, test := range tests {
+		got := strings.TrimSpace(test.m.String())
+		if got != test.want {
+			t.Errorf("\n got %s\nwant %s", got, test.want)
+		}
+	}
+}

+ 355 - 0
Godeps/_workspace/src/github.com/matttproud/golang_protobuf_extensions/ext/all_test.go

@@ -0,0 +1,355 @@
+// Copyright 2013 Matt T. Proud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ext
+
+import (
+	"bytes"
+	"math/rand"
+	"reflect"
+	"testing"
+	"testing/quick"
+
+	. "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+	. "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/testdata"
+)
+
+func TestWriteDelimited(t *testing.T) {
+	for _, test := range []struct {
+		msg Message
+		buf []byte
+		n   int
+		err error
+	}{
+		{
+			msg: &Empty{},
+			n:   1,
+			buf: []byte{0},
+		},
+		{
+			msg: &GoEnum{Foo: FOO_FOO1.Enum()},
+			n:   3,
+			buf: []byte{2, 8, 1},
+		},
+		{
+			msg: &Strings{
+				StringField: String(`This is my gigantic, unhappy string.  It exceeds
+the encoding size of a single byte varint.  We are using it to fuzz test the
+correctness of the header decoding mechanisms, which may prove problematic.
+I expect it may.  Let's hope you enjoy testing as much as we do.`),
+			},
+			n: 271,
+			buf: []byte{141, 2, 10, 138, 2, 84, 104, 105, 115, 32, 105, 115, 32, 109,
+				121, 32, 103, 105, 103, 97, 110, 116, 105, 99, 44, 32, 117, 110, 104,
+				97, 112, 112, 121, 32, 115, 116, 114, 105, 110, 103, 46, 32, 32, 73,
+				116, 32, 101, 120, 99, 101, 101, 100, 115, 10, 116, 104, 101, 32, 101,
+				110, 99, 111, 100, 105, 110, 103, 32, 115, 105, 122, 101, 32, 111, 102,
+				32, 97, 32, 115, 105, 110, 103, 108, 101, 32, 98, 121, 116, 101, 32,
+				118, 97, 114, 105, 110, 116, 46, 32, 32, 87, 101, 32, 97, 114, 101, 32,
+				117, 115, 105, 110, 103, 32, 105, 116, 32, 116, 111, 32, 102, 117, 122,
+				122, 32, 116, 101, 115, 116, 32, 116, 104, 101, 10, 99, 111, 114, 114,
+				101, 99, 116, 110, 101, 115, 115, 32, 111, 102, 32, 116, 104, 101, 32,
+				104, 101, 97, 100, 101, 114, 32, 100, 101, 99, 111, 100, 105, 110, 103,
+				32, 109, 101, 99, 104, 97, 110, 105, 115, 109, 115, 44, 32, 119, 104,
+				105, 99, 104, 32, 109, 97, 121, 32, 112, 114, 111, 118, 101, 32, 112,
+				114, 111, 98, 108, 101, 109, 97, 116, 105, 99, 46, 10, 73, 32, 101, 120,
+				112, 101, 99, 116, 32, 105, 116, 32, 109, 97, 121, 46, 32, 32, 76, 101,
+				116, 39, 115, 32, 104, 111, 112, 101, 32, 121, 111, 117, 32, 101, 110,
+				106, 111, 121, 32, 116, 101, 115, 116, 105, 110, 103, 32, 97, 115, 32,
+				109, 117, 99, 104, 32, 97, 115, 32, 119, 101, 32, 100, 111, 46},
+		},
+	} {
+		var buf bytes.Buffer
+		if n, err := WriteDelimited(&buf, test.msg); n != test.n || err != test.err {
+			t.Fatalf("WriteDelimited(buf, %#v) = %v, %v; want %v, %v", test.msg, n, err, test.n, test.err)
+		}
+		if out := buf.Bytes(); !bytes.Equal(out, test.buf) {
+			t.Fatalf("WriteDelimited(buf, %#v); buf = %v; want %v", test.msg, out, test.buf)
+		}
+	}
+}
+
+func TestReadDelimited(t *testing.T) {
+	for _, test := range []struct {
+		buf []byte
+		msg Message
+		n   int
+		err error
+	}{
+		{
+			buf: []byte{0},
+			msg: &Empty{},
+			n:   1,
+		},
+		{
+			n:   3,
+			buf: []byte{2, 8, 1},
+			msg: &GoEnum{Foo: FOO_FOO1.Enum()},
+		},
+		{
+			buf: []byte{141, 2, 10, 138, 2, 84, 104, 105, 115, 32, 105, 115, 32, 109,
+				121, 32, 103, 105, 103, 97, 110, 116, 105, 99, 44, 32, 117, 110, 104,
+				97, 112, 112, 121, 32, 115, 116, 114, 105, 110, 103, 46, 32, 32, 73,
+				116, 32, 101, 120, 99, 101, 101, 100, 115, 10, 116, 104, 101, 32, 101,
+				110, 99, 111, 100, 105, 110, 103, 32, 115, 105, 122, 101, 32, 111, 102,
+				32, 97, 32, 115, 105, 110, 103, 108, 101, 32, 98, 121, 116, 101, 32,
+				118, 97, 114, 105, 110, 116, 46, 32, 32, 87, 101, 32, 97, 114, 101, 32,
+				117, 115, 105, 110, 103, 32, 105, 116, 32, 116, 111, 32, 102, 117, 122,
+				122, 32, 116, 101, 115, 116, 32, 116, 104, 101, 10, 99, 111, 114, 114,
+				101, 99, 116, 110, 101, 115, 115, 32, 111, 102, 32, 116, 104, 101, 32,
+				104, 101, 97, 100, 101, 114, 32, 100, 101, 99, 111, 100, 105, 110, 103,
+				32, 109, 101, 99, 104, 97, 110, 105, 115, 109, 115, 44, 32, 119, 104,
+				105, 99, 104, 32, 109, 97, 121, 32, 112, 114, 111, 118, 101, 32, 112,
+				114, 111, 98, 108, 101, 109, 97, 116, 105, 99, 46, 10, 73, 32, 101, 120,
+				112, 101, 99, 116, 32, 105, 116, 32, 109, 97, 121, 46, 32, 32, 76, 101,
+				116, 39, 115, 32, 104, 111, 112, 101, 32, 121, 111, 117, 32, 101, 110,
+				106, 111, 121, 32, 116, 101, 115, 116, 105, 110, 103, 32, 97, 115, 32,
+				109, 117, 99, 104, 32, 97, 115, 32, 119, 101, 32, 100, 111, 46},
+			msg: &Strings{
+				StringField: String(`This is my gigantic, unhappy string.  It exceeds
+the encoding size of a single byte varint.  We are using it to fuzz test the
+correctness of the header decoding mechanisms, which may prove problematic.
+I expect it may.  Let's hope you enjoy testing as much as we do.`),
+			},
+			n: 271,
+		},
+	} {
+		msg := Clone(test.msg)
+		msg.Reset()
+		if n, err := ReadDelimited(bytes.NewBuffer(test.buf), msg); n != test.n || err != test.err {
+			t.Fatalf("ReadDelimited(%v, msg) = %v, %v; want %v, %v", test.buf, n, err, test.n, test.err)
+		}
+		if !Equal(msg, test.msg) {
+			t.Fatalf("ReadDelimited(%v, msg); msg = %v; want %v", test.buf, msg, test.msg)
+		}
+	}
+}
+
+func TestEndToEndValid(t *testing.T) {
+	for _, test := range [][]Message{
+		[]Message{&Empty{}},
+		[]Message{&GoEnum{Foo: FOO_FOO1.Enum()}, &Empty{}, &GoEnum{Foo: FOO_FOO1.Enum()}},
+		[]Message{&GoEnum{Foo: FOO_FOO1.Enum()}},
+		[]Message{&Strings{
+			StringField: String(`This is my gigantic, unhappy string.  It exceeds
+the encoding size of a single byte varint.  We are using it to fuzz test the
+correctness of the header decoding mechanisms, which may prove problematic.
+I expect it may.  Let's hope you enjoy testing as much as we do.`),
+		}},
+	} {
+		var buf bytes.Buffer
+		var written int
+		for i, msg := range test {
+			n, err := WriteDelimited(&buf, msg)
+			if err != nil {
+				// Assumption: TestReadDelimited and TestWriteDelimited are sufficient
+				//             and inputs for this test are explicitly exercised there.
+				t.Fatalf("WriteDelimited(buf, %v[%d]) = ?, %v; wanted ?, nil", test, i, err)
+			}
+			written += n
+		}
+		var read int
+		for i, msg := range test {
+			out := Clone(msg)
+			out.Reset()
+			n, _ := ReadDelimited(&buf, out)
+			// Decide to do EOF checking?
+			read += n
+			if !Equal(out, msg) {
+				t.Fatalf("out = %v; want %v[%d] = %#v", out, test, i, msg)
+			}
+		}
+		if read != written {
+			t.Fatalf("%v read = %d; want %d", test, read, written)
+		}
+	}
+}
+
+// visitMessage empties the private state fields of the quick.Value()-generated
+// Protocol Buffer messages, for they cause an inordinate amount of problems.
+// This is because we are using an automated fuzz generator on a type with
+// private fields.
+func visitMessage(m Message) {
+	t := reflect.TypeOf(m)
+	if t.Kind() != reflect.Ptr {
+		return
+	}
+	derefed := t.Elem()
+	if derefed.Kind() != reflect.Struct {
+		return
+	}
+	v := reflect.ValueOf(m)
+	elem := v.Elem()
+	for i := 0; i < elem.NumField(); i++ {
+		field := elem.FieldByIndex([]int{i})
+		fieldType := field.Type()
+		if fieldType.Implements(reflect.TypeOf((*Message)(nil)).Elem()) {
+			visitMessage(field.Interface().(Message))
+		}
+		if field.Kind() == reflect.Slice {
+			for i := 0; i < field.Len(); i++ {
+				elem := field.Index(i)
+				elemType := elem.Type()
+				if elemType.Implements(reflect.TypeOf((*Message)(nil)).Elem()) {
+					visitMessage(elem.Interface().(Message))
+				}
+			}
+		}
+	}
+	if field := elem.FieldByName("XXX_unrecognized"); field.IsValid() {
+		field.Set(reflect.ValueOf([]byte{}))
+	}
+	if field := elem.FieldByName("XXX_extensions"); field.IsValid() {
+		field.Set(reflect.ValueOf(nil))
+	}
+}
+
+// rndMessage generates a random valid Protocol Buffer message.
+func rndMessage(r *rand.Rand) Message {
+	var t reflect.Type
+	switch v := rand.Intn(23); v {
+	// TODO(br): Uncomment the elements below once fix is incorporated, except
+	//           for the elements marked as patently incompatible.
+	// case 0:
+	// 	t = reflect.TypeOf(&GoEnum{})
+	// 	break
+	// case 1:
+	// 	t = reflect.TypeOf(&GoTestField{})
+	// 	break
+	case 2:
+		t = reflect.TypeOf(&GoTest{})
+		break
+		// case 3:
+		// 	t = reflect.TypeOf(&GoSkipTest{})
+		// 	break
+		// case 4:
+		// 	t = reflect.TypeOf(&NonPackedTest{})
+		// 	break
+		// case 5:
+		// t = reflect.TypeOf(&PackedTest{})
+		//	break
+	case 6:
+		t = reflect.TypeOf(&MaxTag{})
+		break
+	case 7:
+		t = reflect.TypeOf(&OldMessage{})
+		break
+	case 8:
+		t = reflect.TypeOf(&NewMessage{})
+		break
+	case 9:
+		t = reflect.TypeOf(&InnerMessage{})
+		break
+	case 10:
+		t = reflect.TypeOf(&OtherMessage{})
+		break
+	case 11:
+		// PATENTLY INVALID FOR FUZZ GENERATION
+		// t = reflect.TypeOf(&MyMessage{})
+		break
+		// case 12:
+		// 	t = reflect.TypeOf(&Ext{})
+		// 	break
+	case 13:
+		// PATENTLY INVALID FOR FUZZ GENERATION
+		// t = reflect.TypeOf(&MyMessageSet{})
+		break
+		// case 14:
+		//   t = reflect.TypeOf(&Empty{})
+		//   break
+		// case 15:
+		// t = reflect.TypeOf(&MessageList{})
+		// break
+		// case 16:
+		// 	t = reflect.TypeOf(&Strings{})
+		// 	break
+		// case 17:
+		// 	t = reflect.TypeOf(&Defaults{})
+		// 	break
+		// case 17:
+		// 	t = reflect.TypeOf(&SubDefaults{})
+		// 	break
+		// case 18:
+		// 	t = reflect.TypeOf(&RepeatedEnum{})
+		// 	break
+	case 19:
+		t = reflect.TypeOf(&MoreRepeated{})
+		break
+		// case 20:
+		// 	t = reflect.TypeOf(&GroupOld{})
+		// 	break
+		// case 21:
+		// 	t = reflect.TypeOf(&GroupNew{})
+		// 	break
+	case 22:
+		t = reflect.TypeOf(&FloatingPoint{})
+		break
+	default:
+		// TODO(br): Replace with an unreachable once fixed.
+		t = reflect.TypeOf(&GoTest{})
+		break
+	}
+	if t == nil {
+		t = reflect.TypeOf(&GoTest{})
+	}
+	v, ok := quick.Value(t, r)
+	if !ok {
+		panic("attempt to generate illegal item; consult item 11")
+	}
+	visitMessage(v.Interface().(Message))
+	return v.Interface().(Message)
+}
+
+// rndMessages generates several random Protocol Buffer messages.
+func rndMessages(r *rand.Rand) []Message {
+	n := r.Intn(128)
+	out := make([]Message, 0, n)
+	for i := 0; i < n; i++ {
+		out = append(out, rndMessage(r))
+	}
+	return out
+}
+
+func TestFuzz(t *testing.T) {
+	rnd := rand.New(rand.NewSource(42))
+	check := func() bool {
+		messages := rndMessages(rnd)
+		var buf bytes.Buffer
+		var written int
+		for i, msg := range messages {
+			n, err := WriteDelimited(&buf, msg)
+			if err != nil {
+				t.Fatalf("WriteDelimited(buf, %v[%d]) = ?, %v; wanted ?, nil", messages, i, err)
+			}
+			written += n
+		}
+		var read int
+		for i, msg := range messages {
+			out := Clone(msg)
+			out.Reset()
+			n, _ := ReadDelimited(&buf, out)
+			read += n
+			if !Equal(out, msg) {
+				t.Fatalf("out = %v; want %v[%d] = %#v", out, messages, i, msg)
+			}
+		}
+		if read != written {
+			t.Fatalf("%v read = %d; want %d", messages, read, written)
+		}
+		return true
+	}
+	if err := quick.Check(check, nil); err != nil {
+		t.Fatal(err)
+	}
+}

+ 75 - 0
Godeps/_workspace/src/github.com/matttproud/golang_protobuf_extensions/ext/decode.go

@@ -0,0 +1,75 @@
+// Copyright 2013 Matt T. Proud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ext
+
+import (
+	"encoding/binary"
+	"errors"
+	"io"
+
+	"github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+)
+
+var errInvalidVarint = errors.New("invalid varint32 encountered")
+
+// ReadDelimited decodes a message from the provided length-delimited stream,
+// where the length is encoded as 32-bit varint prefix to the message body.
+// It returns the total number of bytes read and any applicable error.  This is
+// roughly equivalent to the companion Java API's
+// MessageLite#parseDelimitedFrom.  As per the reader contract, this function
+// calls r.Read repeatedly as required until exactly one message including its
+// prefix is read and decoded (or an error has occurred).  The function never
+// reads more bytes from the stream than required.  The function never returns
+// an error if a message has been read and decoded correctly, even if the end
+// of the stream has been reached in doing so.  In that case, any subsequent
+// calls return (0, io.EOF).
+func ReadDelimited(r io.Reader, m proto.Message) (n int, err error) {
+	// Per AbstractParser#parsePartialDelimitedFrom with
+	// CodedInputStream#readRawVarint32.
+	headerBuf := make([]byte, binary.MaxVarintLen32)
+	var bytesRead, varIntBytes int
+	var messageLength uint64
+	for varIntBytes == 0 { // i.e. no varint has been decoded yet.
+		if bytesRead >= len(headerBuf) {
+			return bytesRead, errInvalidVarint
+		}
+		// We have to read byte by byte here to avoid reading more bytes
+		// than required. Each read byte is appended to what we have
+		// read before.
+		newBytesRead, err := r.Read(headerBuf[bytesRead : bytesRead+1])
+		if newBytesRead == 0 {
+			if err != nil {
+				return bytesRead, err
+			}
+			// A Reader should not return (0, nil), but if it does,
+			// it should be treated as no-op (according to the
+			// Reader contract). So let's go on...
+			continue
+		}
+		bytesRead += newBytesRead
+		// Now present everything read so far to the varint decoder and
+		// see if a varint can be decoded already.
+		messageLength, varIntBytes = proto.DecodeVarint(headerBuf[:bytesRead])
+	}
+
+	messageBuf := make([]byte, messageLength)
+	newBytesRead, err := io.ReadFull(r, messageBuf)
+	bytesRead += newBytesRead
+	if err != nil {
+		return bytesRead, err
+	}
+
+	return bytesRead, proto.Unmarshal(messageBuf, m)
+}

+ 16 - 0
Godeps/_workspace/src/github.com/matttproud/golang_protobuf_extensions/ext/doc.go

@@ -0,0 +1,16 @@
+// Copyright 2013 Matt T. Proud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package ext enables record length-delimited Protocol Buffer streaming.
+package ext

+ 46 - 0
Godeps/_workspace/src/github.com/matttproud/golang_protobuf_extensions/ext/encode.go

@@ -0,0 +1,46 @@
+// Copyright 2013 Matt T. Proud
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package ext
+
+import (
+	"encoding/binary"
+	"io"
+
+	"github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+)
+
+// WriteDelimited encodes and dumps a message to the provided writer prefixed
+// with a 32-bit varint indicating the length of the encoded message, producing
+// a length-delimited record stream, which can be used to chain together
+// encoded messages of the same type together in a file.  It returns the total
+// number of bytes written and any applicable error.  This is roughly
+// equivalent to the companion Java API's MessageLite#writeDelimitedTo.
+func WriteDelimited(w io.Writer, m proto.Message) (n int, err error) {
+	buffer, err := proto.Marshal(m)
+	if err != nil {
+		return 0, err
+	}
+
+	buf := make([]byte, binary.MaxVarintLen32)
+	encodedLength := binary.PutUvarint(buf, uint64(len(buffer)))
+
+	sync, err := w.Write(buf[:encodedLength])
+	if err != nil {
+		return sync, err
+	}
+
+	n, err = w.Write(buffer)
+	return n + sync, err
+}

+ 103 - 0
Godeps/_workspace/src/github.com/matttproud/golang_protobuf_extensions/ext/fixtures_test.go

@@ -0,0 +1,103 @@
+// 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 ext
+
+import (
+	. "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+	. "github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto/testdata"
+)
+
+// FROM https://code.google.com/p/goprotobuf/source/browse/proto/all_test.go.
+
+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
+}

+ 1 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/goautoneg/MANIFEST

@@ -0,0 +1 @@
+Imported at 75cd24fc2f2c from https://bitbucket.org/ww/goautoneg.

+ 13 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/goautoneg/Makefile

@@ -0,0 +1,13 @@
+include $(GOROOT)/src/Make.inc
+
+TARG=bitbucket.org/ww/goautoneg
+GOFILES=autoneg.go
+
+include $(GOROOT)/src/Make.pkg
+
+format:
+	gofmt -w *.go
+
+docs:
+	gomake clean
+	godoc ${TARG} > README.txt

+ 67 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/goautoneg/README.txt

@@ -0,0 +1,67 @@
+PACKAGE
+
+package goautoneg
+import "bitbucket.org/ww/goautoneg"
+
+HTTP Content-Type Autonegotiation.
+
+The functions in this package implement the behaviour specified in
+http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+
+Copyright (c) 2011, Open Knowledge Foundation Ltd.
+All rights reserved.
+
+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 the Open Knowledge Foundation Ltd. 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
+HOLDER 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.
+
+
+FUNCTIONS
+
+func Negotiate(header string, alternatives []string) (content_type string)
+Negotiate the most appropriate content_type given the accept header
+and a list of alternatives.
+
+func ParseAccept(header string) (accept []Accept)
+Parse an Accept Header string returning a sorted list
+of clauses
+
+
+TYPES
+
+type Accept struct {
+    Type, SubType string
+    Q             float32
+    Params        map[string]string
+}
+Structure to represent a clause in an HTTP Accept Header
+
+
+SUBDIRECTORIES
+
+	.hg

+ 162 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/goautoneg/autoneg.go

@@ -0,0 +1,162 @@
+/*
+HTTP Content-Type Autonegotiation.
+
+The functions in this package implement the behaviour specified in
+http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
+
+Copyright (c) 2011, Open Knowledge Foundation Ltd.
+All rights reserved.
+
+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 the Open Knowledge Foundation Ltd. 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
+HOLDER 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 goautoneg
+
+import (
+	"sort"
+	"strconv"
+	"strings"
+)
+
+// Structure to represent a clause in an HTTP Accept Header
+type Accept struct {
+	Type, SubType string
+	Q             float64
+	Params        map[string]string
+}
+
+// For internal use, so that we can use the sort interface
+type accept_slice []Accept
+
+func (accept accept_slice) Len() int {
+	slice := []Accept(accept)
+	return len(slice)
+}
+
+func (accept accept_slice) Less(i, j int) bool {
+	slice := []Accept(accept)
+	ai, aj := slice[i], slice[j]
+	if ai.Q > aj.Q {
+		return true
+	}
+	if ai.Type != "*" && aj.Type == "*" {
+		return true
+	}
+	if ai.SubType != "*" && aj.SubType == "*" {
+		return true
+	}
+	return false
+}
+
+func (accept accept_slice) Swap(i, j int) {
+	slice := []Accept(accept)
+	slice[i], slice[j] = slice[j], slice[i]
+}
+
+// Parse an Accept Header string returning a sorted list
+// of clauses
+func ParseAccept(header string) (accept []Accept) {
+	parts := strings.Split(header, ",")
+	accept = make([]Accept, 0, len(parts))
+	for _, part := range parts {
+		part := strings.Trim(part, " ")
+
+		a := Accept{}
+		a.Params = make(map[string]string)
+		a.Q = 1.0
+
+		mrp := strings.Split(part, ";")
+
+		media_range := mrp[0]
+		sp := strings.Split(media_range, "/")
+		a.Type = strings.Trim(sp[0], " ")
+
+		switch {
+		case len(sp) == 1 && a.Type == "*":
+			a.SubType = "*"
+		case len(sp) == 2:
+			a.SubType = strings.Trim(sp[1], " ")
+		default:
+			continue
+		}
+
+		if len(mrp) == 1 {
+			accept = append(accept, a)
+			continue
+		}
+
+		for _, param := range mrp[1:] {
+			sp := strings.SplitN(param, "=", 2)
+			if len(sp) != 2 {
+				continue
+			}
+			token := strings.Trim(sp[0], " ")
+			if token == "q" {
+				a.Q, _ = strconv.ParseFloat(sp[1], 32)
+			} else {
+				a.Params[token] = strings.Trim(sp[1], " ")
+			}
+		}
+
+		accept = append(accept, a)
+	}
+
+	slice := accept_slice(accept)
+	sort.Sort(slice)
+
+	return
+}
+
+// Negotiate the most appropriate content_type given the accept header
+// and a list of alternatives.
+func Negotiate(header string, alternatives []string) (content_type string) {
+	asp := make([][]string, 0, len(alternatives))
+	for _, ctype := range alternatives {
+		asp = append(asp, strings.SplitN(ctype, "/", 2))
+	}
+	for _, clause := range ParseAccept(header) {
+		for i, ctsp := range asp {
+			if clause.Type == ctsp[0] && clause.SubType == ctsp[1] {
+				content_type = alternatives[i]
+				return
+			}
+			if clause.Type == ctsp[0] && clause.SubType == "*" {
+				content_type = alternatives[i]
+				return
+			}
+			if clause.Type == "*" && clause.SubType == "*" {
+				content_type = alternatives[i]
+				return
+			}
+		}
+	}
+	return
+}

+ 33 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/goautoneg/autoneg_test.go

@@ -0,0 +1,33 @@
+package goautoneg
+
+import (
+	"testing"
+)
+
+var chrome = "application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5"
+
+func TestParseAccept(t *testing.T) {
+	alternatives := []string{"text/html", "image/png"}
+	content_type := Negotiate(chrome, alternatives)
+	if content_type != "image/png" {
+		t.Errorf("got %s expected image/png", content_type)
+	}
+
+	alternatives = []string{"text/html", "text/plain", "text/n3"}
+	content_type = Negotiate(chrome, alternatives)
+	if content_type != "text/html" {
+		t.Errorf("got %s expected text/html", content_type)
+	}
+
+	alternatives = []string{"text/n3", "text/plain"}
+	content_type = Negotiate(chrome, alternatives)
+	if content_type != "text/plain" {
+		t.Errorf("got %s expected text/plain", content_type)
+	}
+
+	alternatives = []string{"text/n3", "application/rdf+xml"}
+	content_type = Negotiate(chrome, alternatives)
+	if content_type != "text/n3" {
+		t.Errorf("got %s expected text/n3", content_type)
+	}
+}

+ 63 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/perks/quantile/bench_test.go

@@ -0,0 +1,63 @@
+package quantile
+
+import (
+	"testing"
+)
+
+func BenchmarkInsertTargeted(b *testing.B) {
+	b.ReportAllocs()
+
+	s := NewTargeted(Targets)
+	b.ResetTimer()
+	for i := float64(0); i < float64(b.N); i++ {
+		s.Insert(i)
+	}
+}
+
+func BenchmarkInsertTargetedSmallEpsilon(b *testing.B) {
+	s := NewTargeted(TargetsSmallEpsilon)
+	b.ResetTimer()
+	for i := float64(0); i < float64(b.N); i++ {
+		s.Insert(i)
+	}
+}
+
+func BenchmarkInsertBiased(b *testing.B) {
+	s := NewLowBiased(0.01)
+	b.ResetTimer()
+	for i := float64(0); i < float64(b.N); i++ {
+		s.Insert(i)
+	}
+}
+
+func BenchmarkInsertBiasedSmallEpsilon(b *testing.B) {
+	s := NewLowBiased(0.0001)
+	b.ResetTimer()
+	for i := float64(0); i < float64(b.N); i++ {
+		s.Insert(i)
+	}
+}
+
+func BenchmarkQuery(b *testing.B) {
+	s := NewTargeted(Targets)
+	for i := float64(0); i < 1e6; i++ {
+		s.Insert(i)
+	}
+	b.ResetTimer()
+	n := float64(b.N)
+	for i := float64(0); i < n; i++ {
+		s.Query(i / n)
+	}
+}
+
+func BenchmarkQuerySmallEpsilon(b *testing.B) {
+	s := NewTargeted(TargetsSmallEpsilon)
+	for i := float64(0); i < 1e6; i++ {
+		s.Insert(i)
+	}
+	b.ResetTimer()
+	n := float64(b.N)
+	for i := float64(0); i < n; i++ {
+		s.Query(i / n)
+	}
+}

+ 112 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/perks/quantile/example_test.go

@@ -0,0 +1,112 @@
+// +build go1.1
+
+package quantile_test
+
+import (
+	"bufio"
+	"fmt"
+	"github.com/bmizerany/perks/quantile"
+	"log"
+	"os"
+	"strconv"
+	"time"
+)
+
+func Example_simple() {
+	ch := make(chan float64)
+	go sendFloats(ch)
+
+	// Compute the 50th, 90th, and 99th percentile.
+	q := quantile.NewTargeted(0.50, 0.90, 0.99)
+	for v := range ch {
+		q.Insert(v)
+	}
+
+	fmt.Println("perc50:", q.Query(0.50))
+	fmt.Println("perc90:", q.Query(0.90))
+	fmt.Println("perc99:", q.Query(0.99))
+	fmt.Println("count:", q.Count())
+	// Output:
+	// perc50: 5
+	// perc90: 14
+	// perc99: 40
+	// count: 2388
+}
+
+func Example_mergeMultipleStreams() {
+	// Scenario:
+	// We have multiple database shards. On each shard, there is a process
+	// collecting query response times from the database logs and inserting
+	// them into a Stream (created via NewTargeted(0.90)), much like the
+	// Simple example. These processes expose a network interface for us to
+	// ask them to serialize and send us the results of their
+	// Stream.Samples so we may Merge and Query them.
+	//
+	// NOTES:
+	// * These sample sets are small, allowing us to get them
+	// across the network much faster than sending the entire list of data
+	// points.
+	//
+	// * For this to work correctly, we must supply the same quantiles
+	// a priori the process collecting the samples supplied to NewTargeted,
+	// even if we do not plan to query them all here.
+	ch := make(chan quantile.Samples)
+	getDBQuerySamples(ch)
+	q := quantile.NewTargeted(0.90)
+	for samples := range ch {
+		q.Merge(samples)
+	}
+	fmt.Println("perc90:", q.Query(0.90))
+}
+
+func Example_window() {
+	// Scenario: We want the 90th, 95th, and 99th percentiles for each
+	// minute.
+
+	ch := make(chan float64)
+	go sendStreamValues(ch)
+
+	tick := time.NewTicker(1 * time.Minute)
+	q := quantile.NewTargeted(0.90, 0.95, 0.99)
+	for {
+		select {
+		case t := <-tick.C:
+			flushToDB(t, q.Samples())
+			q.Reset()
+		case v := <-ch:
+			q.Insert(v)
+		}
+	}
+}
+
+func sendStreamValues(ch chan float64) {
+	// Use your imagination
+}
+
+func flushToDB(t time.Time, samples quantile.Samples) {
+	// Use your imagination
+}
+
+// This is a stub for the above example. In reality this would hit the remote
+// servers via http or something like it.
+func getDBQuerySamples(ch chan quantile.Samples) {}
+
+func sendFloats(ch chan<- float64) {
+	f, err := os.Open("exampledata.txt")
+	if err != nil {
+		log.Fatal(err)
+	}
+	sc := bufio.NewScanner(f)
+	for sc.Scan() {
+		b := sc.Bytes()
+		v, err := strconv.ParseFloat(string(b), 64)
+		if err != nil {
+			log.Fatal(err)
+		}
+		ch <- v
+	}
+	if sc.Err() != nil {
+		log.Fatal(sc.Err())
+	}
+	close(ch)
+}

+ 2388 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/perks/quantile/exampledata.txt

@@ -0,0 +1,2388 @@
+8
+5
+26
+12
+5
+235
+13
+6
+28
+30
+3
+3
+3
+3
+5
+2
+33
+7
+2
+4
+7
+12
+14
+5
+8
+3
+10
+4
+5
+3
+6
+6
+209
+20
+3
+10
+14
+3
+4
+6
+8
+5
+11
+7
+3
+2
+3
+3
+212
+5
+222
+4
+10
+10
+5
+6
+3
+8
+3
+10
+254
+220
+2
+3
+5
+24
+5
+4
+222
+7
+3
+3
+223
+8
+15
+12
+14
+14
+3
+2
+2
+3
+13
+3
+11
+4
+4
+6
+5
+7
+13
+5
+3
+5
+2
+5
+3
+5
+2
+7
+15
+17
+14
+3
+6
+6
+3
+17
+5
+4
+7
+6
+4
+4
+8
+6
+8
+3
+9
+3
+6
+3
+4
+5
+3
+3
+660
+4
+6
+10
+3
+6
+3
+2
+5
+13
+2
+4
+4
+10
+4
+8
+4
+3
+7
+9
+9
+3
+10
+37
+3
+13
+4
+12
+3
+6
+10
+8
+5
+21
+2
+3
+8
+3
+2
+3
+3
+4
+12
+2
+4
+8
+8
+4
+3
+2
+20
+1
+6
+32
+2
+11
+6
+18
+3
+8
+11
+3
+212
+3
+4
+2
+6
+7
+12
+11
+3
+2
+16
+10
+6
+4
+6
+3
+2
+7
+3
+2
+2
+2
+2
+5
+6
+4
+3
+10
+3
+4
+6
+5
+3
+4
+4
+5
+6
+4
+3
+4
+4
+5
+7
+5
+5
+3
+2
+7
+2
+4
+12
+4
+5
+6
+2
+4
+4
+8
+4
+15
+13
+7
+16
+5
+3
+23
+5
+5
+7
+3
+2
+9
+8
+7
+5
+8
+11
+4
+10
+76
+4
+47
+4
+3
+2
+7
+4
+2
+3
+37
+10
+4
+2
+20
+5
+4
+4
+10
+10
+4
+3
+7
+23
+240
+7
+13
+5
+5
+3
+3
+2
+5
+4
+2
+8
+7
+19
+2
+23
+8
+7
+2
+5
+3
+8
+3
+8
+13
+5
+5
+5
+2
+3
+23
+4
+9
+8
+4
+3
+3
+5
+220
+2
+3
+4
+6
+14
+3
+53
+6
+2
+5
+18
+6
+3
+219
+6
+5
+2
+5
+3
+6
+5
+15
+4
+3
+17
+3
+2
+4
+7
+2
+3
+3
+4
+4
+3
+2
+664
+6
+3
+23
+5
+5
+16
+5
+8
+2
+4
+2
+24
+12
+3
+2
+3
+5
+8
+3
+5
+4
+3
+14
+3
+5
+8
+2
+3
+7
+9
+4
+2
+3
+6
+8
+4
+3
+4
+6
+5
+3
+3
+6
+3
+19
+4
+4
+6
+3
+6
+3
+5
+22
+5
+4
+4
+3
+8
+11
+4
+9
+7
+6
+13
+4
+4
+4
+6
+17
+9
+3
+3
+3
+4
+3
+221
+5
+11
+3
+4
+2
+12
+6
+3
+5
+7
+5
+7
+4
+9
+7
+14
+37
+19
+217
+16
+3
+5
+2
+2
+7
+19
+7
+6
+7
+4
+24
+5
+11
+4
+7
+7
+9
+13
+3
+4
+3
+6
+28
+4
+4
+5
+5
+2
+5
+6
+4
+4
+6
+10
+5
+4
+3
+2
+3
+3
+6
+5
+5
+4
+3
+2
+3
+7
+4
+6
+18
+16
+8
+16
+4
+5
+8
+6
+9
+13
+1545
+6
+215
+6
+5
+6
+3
+45
+31
+5
+2
+2
+4
+3
+3
+2
+5
+4
+3
+5
+7
+7
+4
+5
+8
+5
+4
+749
+2
+31
+9
+11
+2
+11
+5
+4
+4
+7
+9
+11
+4
+5
+4
+7
+3
+4
+6
+2
+15
+3
+4
+3
+4
+3
+5
+2
+13
+5
+5
+3
+3
+23
+4
+4
+5
+7
+4
+13
+2
+4
+3
+4
+2
+6
+2
+7
+3
+5
+5
+3
+29
+5
+4
+4
+3
+10
+2
+3
+79
+16
+6
+6
+7
+7
+3
+5
+5
+7
+4
+3
+7
+9
+5
+6
+5
+9
+6
+3
+6
+4
+17
+2
+10
+9
+3
+6
+2
+3
+21
+22
+5
+11
+4
+2
+17
+2
+224
+2
+14
+3
+4
+4
+2
+4
+4
+4
+4
+5
+3
+4
+4
+10
+2
+6
+3
+3
+5
+7
+2
+7
+5
+6
+3
+218
+2
+2
+5
+2
+6
+3
+5
+222
+14
+6
+33
+3
+2
+5
+3
+3
+3
+9
+5
+3
+3
+2
+7
+4
+3
+4
+3
+5
+6
+5
+26
+4
+13
+9
+7
+3
+221
+3
+3
+4
+4
+4
+4
+2
+18
+5
+3
+7
+9
+6
+8
+3
+10
+3
+11
+9
+5
+4
+17
+5
+5
+6
+6
+3
+2
+4
+12
+17
+6
+7
+218
+4
+2
+4
+10
+3
+5
+15
+3
+9
+4
+3
+3
+6
+29
+3
+3
+4
+5
+5
+3
+8
+5
+6
+6
+7
+5
+3
+5
+3
+29
+2
+31
+5
+15
+24
+16
+5
+207
+4
+3
+3
+2
+15
+4
+4
+13
+5
+5
+4
+6
+10
+2
+7
+8
+4
+6
+20
+5
+3
+4
+3
+12
+12
+5
+17
+7
+3
+3
+3
+6
+10
+3
+5
+25
+80
+4
+9
+3
+2
+11
+3
+3
+2
+3
+8
+7
+5
+5
+19
+5
+3
+3
+12
+11
+2
+6
+5
+5
+5
+3
+3
+3
+4
+209
+14
+3
+2
+5
+19
+4
+4
+3
+4
+14
+5
+6
+4
+13
+9
+7
+4
+7
+10
+2
+9
+5
+7
+2
+8
+4
+6
+5
+5
+222
+8
+7
+12
+5
+216
+3
+4
+4
+6
+3
+14
+8
+7
+13
+4
+3
+3
+3
+3
+17
+5
+4
+3
+33
+6
+6
+33
+7
+5
+3
+8
+7
+5
+2
+9
+4
+2
+233
+24
+7
+4
+8
+10
+3
+4
+15
+2
+16
+3
+3
+13
+12
+7
+5
+4
+207
+4
+2
+4
+27
+15
+2
+5
+2
+25
+6
+5
+5
+6
+13
+6
+18
+6
+4
+12
+225
+10
+7
+5
+2
+2
+11
+4
+14
+21
+8
+10
+3
+5
+4
+232
+2
+5
+5
+3
+7
+17
+11
+6
+6
+23
+4
+6
+3
+5
+4
+2
+17
+3
+6
+5
+8
+3
+2
+2
+14
+9
+4
+4
+2
+5
+5
+3
+7
+6
+12
+6
+10
+3
+6
+2
+2
+19
+5
+4
+4
+9
+2
+4
+13
+3
+5
+6
+3
+6
+5
+4
+9
+6
+3
+5
+7
+3
+6
+6
+4
+3
+10
+6
+3
+221
+3
+5
+3
+6
+4
+8
+5
+3
+6
+4
+4
+2
+54
+5
+6
+11
+3
+3
+4
+4
+4
+3
+7
+3
+11
+11
+7
+10
+6
+13
+223
+213
+15
+231
+7
+3
+7
+228
+2
+3
+4
+4
+5
+6
+7
+4
+13
+3
+4
+5
+3
+6
+4
+6
+7
+2
+4
+3
+4
+3
+3
+6
+3
+7
+3
+5
+18
+5
+6
+8
+10
+3
+3
+3
+2
+4
+2
+4
+4
+5
+6
+6
+4
+10
+13
+3
+12
+5
+12
+16
+8
+4
+19
+11
+2
+4
+5
+6
+8
+5
+6
+4
+18
+10
+4
+2
+216
+6
+6
+6
+2
+4
+12
+8
+3
+11
+5
+6
+14
+5
+3
+13
+4
+5
+4
+5
+3
+28
+6
+3
+7
+219
+3
+9
+7
+3
+10
+6
+3
+4
+19
+5
+7
+11
+6
+15
+19
+4
+13
+11
+3
+7
+5
+10
+2
+8
+11
+2
+6
+4
+6
+24
+6
+3
+3
+3
+3
+6
+18
+4
+11
+4
+2
+5
+10
+8
+3
+9
+5
+3
+4
+5
+6
+2
+5
+7
+4
+4
+14
+6
+4
+4
+5
+5
+7
+2
+4
+3
+7
+3
+3
+6
+4
+5
+4
+4
+4
+3
+3
+3
+3
+8
+14
+2
+3
+5
+3
+2
+4
+5
+3
+7
+3
+3
+18
+3
+4
+4
+5
+7
+3
+3
+3
+13
+5
+4
+8
+211
+5
+5
+3
+5
+2
+5
+4
+2
+655
+6
+3
+5
+11
+2
+5
+3
+12
+9
+15
+11
+5
+12
+217
+2
+6
+17
+3
+3
+207
+5
+5
+4
+5
+9
+3
+2
+8
+5
+4
+3
+2
+5
+12
+4
+14
+5
+4
+2
+13
+5
+8
+4
+225
+4
+3
+4
+5
+4
+3
+3
+6
+23
+9
+2
+6
+7
+233
+4
+4
+6
+18
+3
+4
+6
+3
+4
+4
+2
+3
+7
+4
+13
+227
+4
+3
+5
+4
+2
+12
+9
+17
+3
+7
+14
+6
+4
+5
+21
+4
+8
+9
+2
+9
+25
+16
+3
+6
+4
+7
+8
+5
+2
+3
+5
+4
+3
+3
+5
+3
+3
+3
+2
+3
+19
+2
+4
+3
+4
+2
+3
+4
+4
+2
+4
+3
+3
+3
+2
+6
+3
+17
+5
+6
+4
+3
+13
+5
+3
+3
+3
+4
+9
+4
+2
+14
+12
+4
+5
+24
+4
+3
+37
+12
+11
+21
+3
+4
+3
+13
+4
+2
+3
+15
+4
+11
+4
+4
+3
+8
+3
+4
+4
+12
+8
+5
+3
+3
+4
+2
+220
+3
+5
+223
+3
+3
+3
+10
+3
+15
+4
+241
+9
+7
+3
+6
+6
+23
+4
+13
+7
+3
+4
+7
+4
+9
+3
+3
+4
+10
+5
+5
+1
+5
+24
+2
+4
+5
+5
+6
+14
+3
+8
+2
+3
+5
+13
+13
+3
+5
+2
+3
+15
+3
+4
+2
+10
+4
+4
+4
+5
+5
+3
+5
+3
+4
+7
+4
+27
+3
+6
+4
+15
+3
+5
+6
+6
+5
+4
+8
+3
+9
+2
+6
+3
+4
+3
+7
+4
+18
+3
+11
+3
+3
+8
+9
+7
+24
+3
+219
+7
+10
+4
+5
+9
+12
+2
+5
+4
+4
+4
+3
+3
+19
+5
+8
+16
+8
+6
+22
+3
+23
+3
+242
+9
+4
+3
+3
+5
+7
+3
+3
+5
+8
+3
+7
+5
+14
+8
+10
+3
+4
+3
+7
+4
+6
+7
+4
+10
+4
+3
+11
+3
+7
+10
+3
+13
+6
+8
+12
+10
+5
+7
+9
+3
+4
+7
+7
+10
+8
+30
+9
+19
+4
+3
+19
+15
+4
+13
+3
+215
+223
+4
+7
+4
+8
+17
+16
+3
+7
+6
+5
+5
+4
+12
+3
+7
+4
+4
+13
+4
+5
+2
+5
+6
+5
+6
+6
+7
+10
+18
+23
+9
+3
+3
+6
+5
+2
+4
+2
+7
+3
+3
+2
+5
+5
+14
+10
+224
+6
+3
+4
+3
+7
+5
+9
+3
+6
+4
+2
+5
+11
+4
+3
+3
+2
+8
+4
+7
+4
+10
+7
+3
+3
+18
+18
+17
+3
+3
+3
+4
+5
+3
+3
+4
+12
+7
+3
+11
+13
+5
+4
+7
+13
+5
+4
+11
+3
+12
+3
+6
+4
+4
+21
+4
+6
+9
+5
+3
+10
+8
+4
+6
+4
+4
+6
+5
+4
+8
+6
+4
+6
+4
+4
+5
+9
+6
+3
+4
+2
+9
+3
+18
+2
+4
+3
+13
+3
+6
+6
+8
+7
+9
+3
+2
+16
+3
+4
+6
+3
+2
+33
+22
+14
+4
+9
+12
+4
+5
+6
+3
+23
+9
+4
+3
+5
+5
+3
+4
+5
+3
+5
+3
+10
+4
+5
+5
+8
+4
+4
+6
+8
+5
+4
+3
+4
+6
+3
+3
+3
+5
+9
+12
+6
+5
+9
+3
+5
+3
+2
+2
+2
+18
+3
+2
+21
+2
+5
+4
+6
+4
+5
+10
+3
+9
+3
+2
+10
+7
+3
+6
+6
+4
+4
+8
+12
+7
+3
+7
+3
+3
+9
+3
+4
+5
+4
+4
+5
+5
+10
+15
+4
+4
+14
+6
+227
+3
+14
+5
+216
+22
+5
+4
+2
+2
+6
+3
+4
+2
+9
+9
+4
+3
+28
+13
+11
+4
+5
+3
+3
+2
+3
+3
+5
+3
+4
+3
+5
+23
+26
+3
+4
+5
+6
+4
+6
+3
+5
+5
+3
+4
+3
+2
+2
+2
+7
+14
+3
+6
+7
+17
+2
+2
+15
+14
+16
+4
+6
+7
+13
+6
+4
+5
+6
+16
+3
+3
+28
+3
+6
+15
+3
+9
+2
+4
+6
+3
+3
+22
+4
+12
+6
+7
+2
+5
+4
+10
+3
+16
+6
+9
+2
+5
+12
+7
+5
+5
+5
+5
+2
+11
+9
+17
+4
+3
+11
+7
+3
+5
+15
+4
+3
+4
+211
+8
+7
+5
+4
+7
+6
+7
+6
+3
+6
+5
+6
+5
+3
+4
+4
+26
+4
+6
+10
+4
+4
+3
+2
+3
+3
+4
+5
+9
+3
+9
+4
+4
+5
+5
+8
+2
+4
+2
+3
+8
+4
+11
+19
+5
+8
+6
+3
+5
+6
+12
+3
+2
+4
+16
+12
+3
+4
+4
+8
+6
+5
+6
+6
+219
+8
+222
+6
+16
+3
+13
+19
+5
+4
+3
+11
+6
+10
+4
+7
+7
+12
+5
+3
+3
+5
+6
+10
+3
+8
+2
+5
+4
+7
+2
+4
+4
+2
+12
+9
+6
+4
+2
+40
+2
+4
+10
+4
+223
+4
+2
+20
+6
+7
+24
+5
+4
+5
+2
+20
+16
+6
+5
+13
+2
+3
+3
+19
+3
+2
+4
+5
+6
+7
+11
+12
+5
+6
+7
+7
+3
+5
+3
+5
+3
+14
+3
+4
+4
+2
+11
+1
+7
+3
+9
+6
+11
+12
+5
+8
+6
+221
+4
+2
+12
+4
+3
+15
+4
+5
+226
+7
+218
+7
+5
+4
+5
+18
+4
+5
+9
+4
+4
+2
+9
+18
+18
+9
+5
+6
+6
+3
+3
+7
+3
+5
+4
+4
+4
+12
+3
+6
+31
+5
+4
+7
+3
+6
+5
+6
+5
+11
+2
+2
+11
+11
+6
+7
+5
+8
+7
+10
+5
+23
+7
+4
+3
+5
+34
+2
+5
+23
+7
+3
+6
+8
+4
+4
+4
+2
+5
+3
+8
+5
+4
+8
+25
+2
+3
+17
+8
+3
+4
+8
+7
+3
+15
+6
+5
+7
+21
+9
+5
+6
+6
+5
+3
+2
+3
+10
+3
+6
+3
+14
+7
+4
+4
+8
+7
+8
+2
+6
+12
+4
+213
+6
+5
+21
+8
+2
+5
+23
+3
+11
+2
+3
+6
+25
+2
+3
+6
+7
+6
+6
+4
+4
+6
+3
+17
+9
+7
+6
+4
+3
+10
+7
+2
+3
+3
+3
+11
+8
+3
+7
+6
+4
+14
+36
+3
+4
+3
+3
+22
+13
+21
+4
+2
+7
+4
+4
+17
+15
+3
+7
+11
+2
+4
+7
+6
+209
+6
+3
+2
+2
+24
+4
+9
+4
+3
+3
+3
+29
+2
+2
+4
+3
+3
+5
+4
+6
+3
+3
+2
+4

+ 292 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/perks/quantile/stream.go

@@ -0,0 +1,292 @@
+// Package quantile computes approximate quantiles over an unbounded data
+// stream within low memory and CPU bounds.
+//
+// A small amount of accuracy is traded to achieve the above properties.
+//
+// Multiple streams can be merged before calling Query to generate a single set
+// of results. This is meaningful when the streams represent the same type of
+// data. See Merge and Samples.
+//
+// For more detailed information about the algorithm used, see:
+//
+// Effective Computation of Biased Quantiles over Data Streams
+//
+// http://www.cs.rutgers.edu/~muthu/bquant.pdf
+package quantile
+
+import (
+	"math"
+	"sort"
+)
+
+// Sample holds an observed value and meta information for compression. JSON
+// tags have been added for convenience.
+type Sample struct {
+	Value float64 `json:",string"`
+	Width float64 `json:",string"`
+	Delta float64 `json:",string"`
+}
+
+// Samples represents a slice of samples. It implements sort.Interface.
+type Samples []Sample
+
+func (a Samples) Len() int           { return len(a) }
+func (a Samples) Less(i, j int) bool { return a[i].Value < a[j].Value }
+func (a Samples) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+
+type invariant func(s *stream, r float64) float64
+
+// NewLowBiased returns an initialized Stream for low-biased quantiles
+// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but
+// error guarantees can still be given even for the lower ranks of the data
+// distribution.
+//
+// The provided epsilon is a relative error, i.e. the true quantile of a value
+// returned by a query is guaranteed to be within (1±Epsilon)*Quantile.
+//
+// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error
+// properties.
+func NewLowBiased(epsilon float64) *Stream {
+	ƒ := func(s *stream, r float64) float64 {
+		return 2 * epsilon * r
+	}
+	return newStream(ƒ)
+}
+
+// NewHighBiased returns an initialized Stream for high-biased quantiles
+// (e.g. 0.01, 0.1, 0.5) where the needed quantiles are not known a priori, but
+// error guarantees can still be given even for the higher ranks of the data
+// distribution.
+//
+// The provided epsilon is a relative error, i.e. the true quantile of a value
+// returned by a query is guaranteed to be within 1-(1±Epsilon)*(1-Quantile).
+//
+// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error
+// properties.
+func NewHighBiased(epsilon float64) *Stream {
+	ƒ := func(s *stream, r float64) float64 {
+		return 2 * epsilon * (s.n - r)
+	}
+	return newStream(ƒ)
+}
+
+// NewTargeted returns an initialized Stream concerned with a particular set of
+// quantile values that are supplied a priori. Knowing these a priori reduces
+// space and computation time. The targets map maps the desired quantiles to
+// their absolute errors, i.e. the true quantile of a value returned by a query
+// is guaranteed to be within (Quantile±Epsilon).
+//
+// See http://www.cs.rutgers.edu/~muthu/bquant.pdf for time, space, and error properties.
+func NewTargeted(targets map[float64]float64) *Stream {
+	ƒ := func(s *stream, r float64) float64 {
+		var m = math.MaxFloat64
+		var f float64
+		for quantile, epsilon := range targets {
+			if quantile*s.n <= r {
+				f = (2 * epsilon * r) / quantile
+			} else {
+				f = (2 * epsilon * (s.n - r)) / (1 - quantile)
+			}
+			if f < m {
+				m = f
+			}
+		}
+		return m
+	}
+	return newStream(ƒ)
+}
+
+// Stream computes quantiles for a stream of float64s. It is not thread-safe by
+// design. Take care when using across multiple goroutines.
+type Stream struct {
+	*stream
+	b      Samples
+	sorted bool
+}
+
+func newStream(ƒ invariant) *Stream {
+	x := &stream{ƒ: ƒ}
+	return &Stream{x, make(Samples, 0, 500), true}
+}
+
+// Insert inserts v into the stream.
+func (s *Stream) Insert(v float64) {
+	s.insert(Sample{Value: v, Width: 1})
+}
+
+func (s *Stream) insert(sample Sample) {
+	s.b = append(s.b, sample)
+	s.sorted = false
+	if len(s.b) == cap(s.b) {
+		s.flush()
+	}
+}
+
+// Query returns the computed qth percentiles value. If s was created with
+// NewTargeted, and q is not in the set of quantiles provided a priori, Query
+// will return an unspecified result.
+func (s *Stream) Query(q float64) float64 {
+	if !s.flushed() {
+		// Fast path when there hasn't been enough data for a flush;
+		// this also yields better accuracy for small sets of data.
+		l := len(s.b)
+		if l == 0 {
+			return 0
+		}
+		i := int(float64(l) * q)
+		if i > 0 {
+			i -= 1
+		}
+		s.maybeSort()
+		return s.b[i].Value
+	}
+	s.flush()
+	return s.stream.query(q)
+}
+
+// Merge merges samples into the underlying streams samples. This is handy when
+// merging multiple streams from separate threads, database shards, etc.
+//
+// ATTENTION: This method is broken and does not yield correct results. The
+// underlying algorithm is not capable of merging streams correctly.
+func (s *Stream) Merge(samples Samples) {
+	sort.Sort(samples)
+	s.stream.merge(samples)
+}
+
+// Reset reinitializes and clears the list reusing the samples buffer memory.
+func (s *Stream) Reset() {
+	s.stream.reset()
+	s.b = s.b[:0]
+}
+
+// Samples returns stream samples held by s.
+func (s *Stream) Samples() Samples {
+	if !s.flushed() {
+		return s.b
+	}
+	s.flush()
+	return s.stream.samples()
+}
+
+// Count returns the total number of samples observed in the stream
+// since initialization.
+func (s *Stream) Count() int {
+	return len(s.b) + s.stream.count()
+}
+
+func (s *Stream) flush() {
+	s.maybeSort()
+	s.stream.merge(s.b)
+	s.b = s.b[:0]
+}
+
+func (s *Stream) maybeSort() {
+	if !s.sorted {
+		s.sorted = true
+		sort.Sort(s.b)
+	}
+}
+
+func (s *Stream) flushed() bool {
+	return len(s.stream.l) > 0
+}
+
+type stream struct {
+	n float64
+	l []Sample
+	ƒ invariant
+}
+
+func (s *stream) reset() {
+	s.l = s.l[:0]
+	s.n = 0
+}
+
+func (s *stream) insert(v float64) {
+	s.merge(Samples{{v, 1, 0}})
+}
+
+func (s *stream) merge(samples Samples) {
+	// TODO(beorn7): This tries to merge not only individual samples, but
+	// whole summaries. The paper doesn't mention merging summaries at
+	// all. Unittests show that the merging is inaccurate. Find out how to
+	// do merges properly.
+	var r float64
+	i := 0
+	for _, sample := range samples {
+		for ; i < len(s.l); i++ {
+			c := s.l[i]
+			if c.Value > sample.Value {
+				// Insert at position i.
+				s.l = append(s.l, Sample{})
+				copy(s.l[i+1:], s.l[i:])
+				s.l[i] = Sample{
+					sample.Value,
+					sample.Width,
+					math.Max(sample.Delta, math.Floor(s.ƒ(s, r))-1),
+					// TODO(beorn7): How to calculate delta correctly?
+				}
+				i++
+				goto inserted
+			}
+			r += c.Width
+		}
+		s.l = append(s.l, Sample{sample.Value, sample.Width, 0})
+		i++
+	inserted:
+		s.n += sample.Width
+		r += sample.Width
+	}
+	s.compress()
+}
+
+func (s *stream) count() int {
+	return int(s.n)
+}
+
+func (s *stream) query(q float64) float64 {
+	t := math.Ceil(q * s.n)
+	t += math.Ceil(s.ƒ(s, t) / 2)
+	p := s.l[0]
+	var r float64
+	for _, c := range s.l[1:] {
+		r += p.Width
+		if r+c.Width+c.Delta > t {
+			return p.Value
+		}
+		p = c
+	}
+	return p.Value
+}
+
+func (s *stream) compress() {
+	if len(s.l) < 2 {
+		return
+	}
+	x := s.l[len(s.l)-1]
+	xi := len(s.l) - 1
+	r := s.n - 1 - x.Width
+
+	for i := len(s.l) - 2; i >= 0; i-- {
+		c := s.l[i]
+		if c.Width+x.Width+x.Delta <= s.ƒ(s, r) {
+			x.Width += c.Width
+			s.l[xi] = x
+			// Remove element at i.
+			copy(s.l[i:], s.l[i+1:])
+			s.l = s.l[:len(s.l)-1]
+			xi -= 1
+		} else {
+			x = c
+			xi = i
+		}
+		r -= c.Width
+	}
+}
+
+func (s *stream) samples() Samples {
+	samples := make(Samples, len(s.l))
+	copy(samples, s.l)
+	return samples
+}

+ 185 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/_vendor/perks/quantile/stream_test.go

@@ -0,0 +1,185 @@
+package quantile
+
+import (
+	"math"
+	"math/rand"
+	"sort"
+	"testing"
+)
+
+var (
+	Targets = map[float64]float64{
+		0.01: 0.001,
+		0.10: 0.01,
+		0.50: 0.05,
+		0.90: 0.01,
+		0.99: 0.001,
+	}
+	TargetsSmallEpsilon = map[float64]float64{
+		0.01: 0.0001,
+		0.10: 0.001,
+		0.50: 0.005,
+		0.90: 0.001,
+		0.99: 0.0001,
+	}
+	LowQuantiles  = []float64{0.01, 0.1, 0.5}
+	HighQuantiles = []float64{0.99, 0.9, 0.5}
+)
+
+const RelativeEpsilon = 0.01
+
+func verifyPercsWithAbsoluteEpsilon(t *testing.T, a []float64, s *Stream) {
+	sort.Float64s(a)
+	for quantile, epsilon := range Targets {
+		n := float64(len(a))
+		k := int(quantile * n)
+		lower := int((quantile - epsilon) * n)
+		if lower < 1 {
+			lower = 1
+		}
+		upper := int(math.Ceil((quantile + epsilon) * n))
+		if upper > len(a) {
+			upper = len(a)
+		}
+		w, min, max := a[k-1], a[lower-1], a[upper-1]
+		if g := s.Query(quantile); g < min || g > max {
+			t.Errorf("q=%f: want %v [%f,%f], got %v", quantile, w, min, max, g)
+		}
+	}
+}
+
+func verifyLowPercsWithRelativeEpsilon(t *testing.T, a []float64, s *Stream) {
+	sort.Float64s(a)
+	for _, qu := range LowQuantiles {
+		n := float64(len(a))
+		k := int(qu * n)
+
+		lowerRank := int((1 - RelativeEpsilon) * qu * n)
+		upperRank := int(math.Ceil((1 + RelativeEpsilon) * qu * n))
+		w, min, max := a[k-1], a[lowerRank-1], a[upperRank-1]
+		if g := s.Query(qu); g < min || g > max {
+			t.Errorf("q=%f: want %v [%f,%f], got %v", qu, w, min, max, g)
+		}
+	}
+}
+
+func verifyHighPercsWithRelativeEpsilon(t *testing.T, a []float64, s *Stream) {
+	sort.Float64s(a)
+	for _, qu := range HighQuantiles {
+		n := float64(len(a))
+		k := int(qu * n)
+
+		lowerRank := int((1 - (1+RelativeEpsilon)*(1-qu)) * n)
+		upperRank := int(math.Ceil((1 - (1-RelativeEpsilon)*(1-qu)) * n))
+		w, min, max := a[k-1], a[lowerRank-1], a[upperRank-1]
+		if g := s.Query(qu); g < min || g > max {
+			t.Errorf("q=%f: want %v [%f,%f], got %v", qu, w, min, max, g)
+		}
+	}
+}
+
+func populateStream(s *Stream) []float64 {
+	a := make([]float64, 0, 1e5+100)
+	for i := 0; i < cap(a); i++ {
+		v := rand.NormFloat64()
+		// Add 5% asymmetric outliers.
+		if i%20 == 0 {
+			v = v*v + 1
+		}
+		s.Insert(v)
+		a = append(a, v)
+	}
+	return a
+}
+
+func TestTargetedQuery(t *testing.T) {
+	rand.Seed(42)
+	s := NewTargeted(Targets)
+	a := populateStream(s)
+	verifyPercsWithAbsoluteEpsilon(t, a, s)
+}
+
+func TestLowBiasedQuery(t *testing.T) {
+	rand.Seed(42)
+	s := NewLowBiased(RelativeEpsilon)
+	a := populateStream(s)
+	verifyLowPercsWithRelativeEpsilon(t, a, s)
+}
+
+func TestHighBiasedQuery(t *testing.T) {
+	rand.Seed(42)
+	s := NewHighBiased(RelativeEpsilon)
+	a := populateStream(s)
+	verifyHighPercsWithRelativeEpsilon(t, a, s)
+}
+
+func TestTargetedMerge(t *testing.T) {
+	rand.Seed(42)
+	s1 := NewTargeted(Targets)
+	s2 := NewTargeted(Targets)
+	a := populateStream(s1)
+	a = append(a, populateStream(s2)...)
+	s1.Merge(s2.Samples())
+	verifyPercsWithAbsoluteEpsilon(t, a, s1)
+}
+
+func TestLowBiasedMerge(t *testing.T) {
+	rand.Seed(42)
+	s1 := NewLowBiased(RelativeEpsilon)
+	s2 := NewLowBiased(RelativeEpsilon)
+	a := populateStream(s1)
+	a = append(a, populateStream(s2)...)
+	s1.Merge(s2.Samples())
+	verifyLowPercsWithRelativeEpsilon(t, a, s2)
+}
+
+func TestHighBiasedMerge(t *testing.T) {
+	rand.Seed(42)
+	s1 := NewHighBiased(RelativeEpsilon)
+	s2 := NewHighBiased(RelativeEpsilon)
+	a := populateStream(s1)
+	a = append(a, populateStream(s2)...)
+	s1.Merge(s2.Samples())
+	verifyHighPercsWithRelativeEpsilon(t, a, s2)
+}
+
+func TestUncompressed(t *testing.T) {
+	q := NewTargeted(Targets)
+	for i := 100; i > 0; i-- {
+		q.Insert(float64(i))
+	}
+	if g := q.Count(); g != 100 {
+		t.Errorf("want count 100, got %d", g)
+	}
+	// Before compression, Query should have 100% accuracy.
+	for quantile := range Targets {
+		w := quantile * 100
+		if g := q.Query(quantile); g != w {
+			t.Errorf("want %f, got %f", w, g)
+		}
+	}
+}
+
+func TestUncompressedSamples(t *testing.T) {
+	q := NewTargeted(map[float64]float64{0.99: 0.001})
+	for i := 1; i <= 100; i++ {
+		q.Insert(float64(i))
+	}
+	if g := q.Samples().Len(); g != 100 {
+		t.Errorf("want count 100, got %d", g)
+	}
+}
+
+func TestUncompressedOne(t *testing.T) {
+	q := NewTargeted(map[float64]float64{0.99: 0.01})
+	q.Insert(3.14)
+	if g := q.Query(0.90); g != 3.14 {
+		t.Error("want PI, got", g)
+	}
+}
+
+func TestDefaults(t *testing.T) {
+	if g := NewTargeted(map[float64]float64{0.99: 0.001}).Query(0.99); g != 0 {
+		t.Errorf("want 0, got %f", g)
+	}
+}

+ 110 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/fingerprinting.go

@@ -0,0 +1,110 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"fmt"
+	"strconv"
+)
+
+// Fingerprint provides a hash-capable representation of a Metric.
+// For our purposes, FNV-1A 64-bit is used.
+type Fingerprint uint64
+
+func (f Fingerprint) String() string {
+	return fmt.Sprintf("%016x", uint64(f))
+}
+
+// Less implements sort.Interface.
+func (f Fingerprint) Less(o Fingerprint) bool {
+	return f < o
+}
+
+// Equal implements sort.Interface.
+func (f Fingerprint) Equal(o Fingerprint) bool {
+	return f == o
+}
+
+// LoadFromString transforms a string representation into a Fingerprint.
+func (f *Fingerprint) LoadFromString(s string) error {
+	num, err := strconv.ParseUint(s, 16, 64)
+	if err != nil {
+		return err
+	}
+	*f = Fingerprint(num)
+	return nil
+}
+
+// Fingerprints represents a collection of Fingerprint subject to a given
+// natural sorting scheme. It implements sort.Interface.
+type Fingerprints []Fingerprint
+
+// Len implements sort.Interface.
+func (f Fingerprints) Len() int {
+	return len(f)
+}
+
+// Less implements sort.Interface.
+func (f Fingerprints) Less(i, j int) bool {
+	return f[i] < f[j]
+}
+
+// Swap implements sort.Interface.
+func (f Fingerprints) Swap(i, j int) {
+	f[i], f[j] = f[j], f[i]
+}
+
+// FingerprintSet is a set of Fingerprints.
+type FingerprintSet map[Fingerprint]struct{}
+
+// Equal returns true if both sets contain the same elements (and not more).
+func (s FingerprintSet) Equal(o FingerprintSet) bool {
+	if len(s) != len(o) {
+		return false
+	}
+
+	for k := range s {
+		if _, ok := o[k]; !ok {
+			return false
+		}
+	}
+
+	return true
+}
+
+// Intersection returns the elements contained in both sets.
+func (s FingerprintSet) Intersection(o FingerprintSet) FingerprintSet {
+	myLength, otherLength := len(s), len(o)
+	if myLength == 0 || otherLength == 0 {
+		return FingerprintSet{}
+	}
+
+	subSet := s
+	superSet := o
+
+	if otherLength < myLength {
+		subSet = o
+		superSet = s
+	}
+
+	out := FingerprintSet{}
+
+	for k := range subSet {
+		if _, ok := superSet[k]; ok {
+			out[k] = struct{}{}
+		}
+	}
+
+	return out
+}

+ 63 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname.go

@@ -0,0 +1,63 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"strings"
+)
+
+const (
+	// ExporterLabelPrefix is the label name prefix to prepend if a
+	// synthetic label is already present in the exported metrics.
+	ExporterLabelPrefix LabelName = "exporter_"
+
+	// MetricNameLabel is the label name indicating the metric name of a
+	// timeseries.
+	MetricNameLabel LabelName = "__name__"
+
+	// ReservedLabelPrefix is a prefix which is not legal in user-supplied
+	// label names.
+	ReservedLabelPrefix = "__"
+
+	// JobLabel is the label name indicating the job from which a timeseries
+	// was scraped.
+	JobLabel LabelName = "job"
+)
+
+// A LabelName is a key for a LabelSet or Metric.  It has a value associated
+// therewith.
+type LabelName string
+
+// LabelNames is a sortable LabelName slice. In implements sort.Interface.
+type LabelNames []LabelName
+
+func (l LabelNames) Len() int {
+	return len(l)
+}
+
+func (l LabelNames) Less(i, j int) bool {
+	return l[i] < l[j]
+}
+
+func (l LabelNames) Swap(i, j int) {
+	l[i], l[j] = l[j], l[i]
+}
+
+func (l LabelNames) String() string {
+	labelStrings := make([]string, 0, len(l))
+	for _, label := range l {
+		labelStrings = append(labelStrings, string(label))
+	}
+	return strings.Join(labelStrings, ", ")
+}

+ 55 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelname_test.go

@@ -0,0 +1,55 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"sort"
+	"testing"
+)
+
+func testLabelNames(t testing.TB) {
+	var scenarios = []struct {
+		in  LabelNames
+		out LabelNames
+	}{
+		{
+			in:  LabelNames{"ZZZ", "zzz"},
+			out: LabelNames{"ZZZ", "zzz"},
+		},
+		{
+			in:  LabelNames{"aaa", "AAA"},
+			out: LabelNames{"AAA", "aaa"},
+		},
+	}
+
+	for i, scenario := range scenarios {
+		sort.Sort(scenario.in)
+
+		for j, expected := range scenario.out {
+			if expected != scenario.in[j] {
+				t.Errorf("%d.%d expected %s, got %s", i, j, expected, scenario.in[j])
+			}
+		}
+	}
+}
+
+func TestLabelNames(t *testing.T) {
+	testLabelNames(t)
+}
+
+func BenchmarkLabelNames(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		testLabelNames(b)
+	}
+}

+ 64 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelset.go

@@ -0,0 +1,64 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"fmt"
+	"sort"
+	"strings"
+)
+
+// A LabelSet is a collection of LabelName and LabelValue pairs.  The LabelSet
+// may be fully-qualified down to the point where it may resolve to a single
+// Metric in the data store or not.  All operations that occur within the realm
+// of a LabelSet can emit a vector of Metric entities to which the LabelSet may
+// match.
+type LabelSet map[LabelName]LabelValue
+
+// Merge is a helper function to non-destructively merge two label sets.
+func (l LabelSet) Merge(other LabelSet) LabelSet {
+	result := make(LabelSet, len(l))
+
+	for k, v := range l {
+		result[k] = v
+	}
+
+	for k, v := range other {
+		result[k] = v
+	}
+
+	return result
+}
+
+func (l LabelSet) String() string {
+	labelStrings := make([]string, 0, len(l))
+	for label, value := range l {
+		labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value))
+	}
+
+	switch len(labelStrings) {
+	case 0:
+		return ""
+	default:
+		sort.Strings(labelStrings)
+		return fmt.Sprintf("{%s}", strings.Join(labelStrings, ", "))
+	}
+}
+
+// MergeFromMetric merges Metric into this LabelSet.
+func (l LabelSet) MergeFromMetric(m Metric) {
+	for k, v := range m {
+		l[k] = v
+	}
+}

+ 36 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue.go

@@ -0,0 +1,36 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"sort"
+)
+
+// A LabelValue is an associated value for a LabelName.
+type LabelValue string
+
+// LabelValues is a sortable LabelValue slice. It implements sort.Interface.
+type LabelValues []LabelValue
+
+func (l LabelValues) Len() int {
+	return len(l)
+}
+
+func (l LabelValues) Less(i, j int) bool {
+	return sort.StringsAreSorted([]string{string(l[i]), string(l[j])})
+}
+
+func (l LabelValues) Swap(i, j int) {
+	l[i], l[j] = l[j], l[i]
+}

+ 55 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/labelvalue_test.go

@@ -0,0 +1,55 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"sort"
+	"testing"
+)
+
+func testLabelValues(t testing.TB) {
+	var scenarios = []struct {
+		in  LabelValues
+		out LabelValues
+	}{
+		{
+			in:  LabelValues{"ZZZ", "zzz"},
+			out: LabelValues{"ZZZ", "zzz"},
+		},
+		{
+			in:  LabelValues{"aaa", "AAA"},
+			out: LabelValues{"AAA", "aaa"},
+		},
+	}
+
+	for i, scenario := range scenarios {
+		sort.Sort(scenario.in)
+
+		for j, expected := range scenario.out {
+			if expected != scenario.in[j] {
+				t.Errorf("%d.%d expected %s, got %s", i, j, expected, scenario.in[j])
+			}
+		}
+	}
+}
+
+func TestLabelValues(t *testing.T) {
+	testLabelValues(t)
+}
+
+func BenchmarkLabelValues(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		testLabelValues(b)
+	}
+}

+ 164 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric.go

@@ -0,0 +1,164 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"encoding/binary"
+	"encoding/json"
+	"fmt"
+	"hash/fnv"
+	"sort"
+	"strings"
+)
+
+var separator = []byte{0}
+
+// A Metric is similar to a LabelSet, but the key difference is that a Metric is
+// a singleton and refers to one and only one stream of samples.
+type Metric map[LabelName]LabelValue
+
+// Equal compares the fingerprints of both metrics.
+func (m Metric) Equal(o Metric) bool {
+	return m.Fingerprint().Equal(o.Fingerprint())
+}
+
+// Before compares the fingerprints of both metrics.
+func (m Metric) Before(o Metric) bool {
+	return m.Fingerprint().Less(o.Fingerprint())
+}
+
+// String implements Stringer.
+func (m Metric) String() string {
+	metricName, hasName := m[MetricNameLabel]
+	numLabels := len(m) - 1
+	if !hasName {
+		numLabels = len(m)
+	}
+	labelStrings := make([]string, 0, numLabels)
+	for label, value := range m {
+		if label != MetricNameLabel {
+			labelStrings = append(labelStrings, fmt.Sprintf("%s=%q", label, value))
+		}
+	}
+
+	switch numLabels {
+	case 0:
+		if hasName {
+			return string(metricName)
+		}
+		return "{}"
+	default:
+		sort.Strings(labelStrings)
+		return fmt.Sprintf("%s{%s}", metricName, strings.Join(labelStrings, ", "))
+	}
+}
+
+// Fingerprint returns a Metric's Fingerprint.
+func (m Metric) Fingerprint() Fingerprint {
+	labelNames := make([]string, 0, len(m))
+	maxLength := 0
+
+	for labelName, labelValue := range m {
+		labelNames = append(labelNames, string(labelName))
+		if len(labelName) > maxLength {
+			maxLength = len(labelName)
+		}
+		if len(labelValue) > maxLength {
+			maxLength = len(labelValue)
+		}
+	}
+
+	sort.Strings(labelNames)
+
+	summer := fnv.New64a()
+	buf := make([]byte, maxLength)
+
+	for _, labelName := range labelNames {
+		labelValue := m[LabelName(labelName)]
+
+		copy(buf, labelName)
+		summer.Write(buf[:len(labelName)])
+
+		summer.Write(separator)
+
+		copy(buf, labelValue)
+		summer.Write(buf[:len(labelValue)])
+	}
+
+	return Fingerprint(binary.LittleEndian.Uint64(summer.Sum(nil)))
+}
+
+// Clone returns a copy of the Metric.
+func (m Metric) Clone() Metric {
+	clone := Metric{}
+	for k, v := range m {
+		clone[k] = v
+	}
+	return clone
+}
+
+// MergeFromLabelSet merges a label set into this Metric, prefixing a collision
+// prefix to the label names merged from the label set where required.
+func (m Metric) MergeFromLabelSet(labels LabelSet, collisionPrefix LabelName) {
+	for k, v := range labels {
+		if collisionPrefix != "" {
+			for {
+				if _, exists := m[k]; !exists {
+					break
+				}
+				k = collisionPrefix + k
+			}
+		}
+
+		m[k] = v
+	}
+}
+
+// COWMetric wraps a Metric to enable copy-on-write access patterns.
+type COWMetric struct {
+	Copied bool
+	Metric Metric
+}
+
+// Set sets a label name in the wrapped Metric to a given value and copies the
+// Metric initially, if it is not already a copy.
+func (m COWMetric) Set(ln LabelName, lv LabelValue) {
+	m.doCOW()
+	m.Metric[ln] = lv
+}
+
+// Delete deletes a given label name from the wrapped Metric and copies the
+// Metric initially, if it is not already a copy.
+func (m *COWMetric) Delete(ln LabelName) {
+	m.doCOW()
+	delete(m.Metric, ln)
+}
+
+// doCOW copies the underlying Metric if it is not already a copy.
+func (m *COWMetric) doCOW() {
+	if !m.Copied {
+		m.Metric = m.Metric.Clone()
+		m.Copied = true
+	}
+}
+
+// String implements fmt.Stringer.
+func (m COWMetric) String() string {
+	return m.Metric.String()
+}
+
+// MarshalJSON implements json.Marshaler.
+func (m COWMetric) MarshalJSON() ([]byte, error) {
+	return json.Marshal(m.Metric)
+}

+ 76 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/metric_test.go

@@ -0,0 +1,76 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import "testing"
+
+func testMetric(t testing.TB) {
+	var scenarios = []struct {
+		input       Metric
+		fingerprint Fingerprint
+	}{
+		{
+			input:       Metric{},
+			fingerprint: 2676020557754725067,
+		},
+		{
+			input: Metric{
+				"first_name":   "electro",
+				"occupation":   "robot",
+				"manufacturer": "westinghouse",
+			},
+			fingerprint: 13260944541294022935,
+		},
+		{
+			input: Metric{
+				"x": "y",
+			},
+			fingerprint: 1470933794305433534,
+		},
+		// The following two demonstrate a bug in fingerprinting. They
+		// should not have the same fingerprint with a sane
+		// fingerprinting function. See
+		// https://github.com/prometheus/client_golang/issues/74 .
+		{
+			input: Metric{
+				"a": "bb",
+				"b": "c",
+			},
+			fingerprint: 3734646176939799877,
+		},
+		{
+			input: Metric{
+				"a":  "b",
+				"bb": "c",
+			},
+			fingerprint: 3734646176939799877,
+		},
+	}
+
+	for i, scenario := range scenarios {
+		if scenario.fingerprint != scenario.input.Fingerprint() {
+			t.Errorf("%d. expected %d, got %d", i, scenario.fingerprint, scenario.input.Fingerprint())
+		}
+	}
+}
+
+func TestMetric(t *testing.T) {
+	testMetric(t)
+}
+
+func BenchmarkMetric(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		testMetric(b)
+	}
+}

+ 15 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/model.go

@@ -0,0 +1,15 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package model contains core representation of Prometheus client primitives.
+package model

+ 79 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample.go

@@ -0,0 +1,79 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+// Sample is a sample value with a timestamp and a metric.
+type Sample struct {
+	Metric    Metric
+	Value     SampleValue
+	Timestamp Timestamp
+}
+
+// Equal compares first the metrics, then the timestamp, then the value.
+func (s *Sample) Equal(o *Sample) bool {
+	if s == o {
+		return true
+	}
+
+	if !s.Metric.Equal(o.Metric) {
+		return false
+	}
+	if !s.Timestamp.Equal(o.Timestamp) {
+		return false
+	}
+	if !s.Value.Equal(o.Value) {
+		return false
+	}
+
+	return true
+}
+
+// Samples is a sortable Sample slice. It implements sort.Interface.
+type Samples []*Sample
+
+func (s Samples) Len() int {
+	return len(s)
+}
+
+// Less compares first the metrics, then the timestamp.
+func (s Samples) Less(i, j int) bool {
+	switch {
+	case s[i].Metric.Before(s[j].Metric):
+		return true
+	case s[j].Metric.Before(s[i].Metric):
+		return false
+	case s[i].Timestamp.Before(s[j].Timestamp):
+		return true
+	default:
+		return false
+	}
+}
+
+func (s Samples) Swap(i, j int) {
+	s[i], s[j] = s[j], s[i]
+}
+
+// Equal compares two sets of samples and returns true if they are equal.
+func (s Samples) Equal(o Samples) bool {
+	if len(s) != len(o) {
+		return false
+	}
+
+	for i, sample := range s {
+		if !sample.Equal(o[i]) {
+			return false
+		}
+	}
+	return true
+}

+ 126 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/sample_test.go

@@ -0,0 +1,126 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"sort"
+	"testing"
+)
+
+func TestSamplesSort(t *testing.T) {
+	input := Samples{
+		&Sample{
+			// Fingerprint: 81f9c9ed24563f8f.
+			Metric: Metric{
+				MetricNameLabel: "A",
+			},
+			Timestamp: 1,
+		},
+		&Sample{
+			// Fingerprint: 81f9c9ed24563f8f.
+			Metric: Metric{
+				MetricNameLabel: "A",
+			},
+			Timestamp: 2,
+		},
+		&Sample{
+			// Fingerprint: 1bf6c9ed24543f8f.
+			Metric: Metric{
+				MetricNameLabel: "C",
+			},
+			Timestamp: 1,
+		},
+		&Sample{
+			// Fingerprint: 1bf6c9ed24543f8f.
+			Metric: Metric{
+				MetricNameLabel: "C",
+			},
+			Timestamp: 2,
+		},
+		&Sample{
+			// Fingerprint: 68f4c9ed24533f8f.
+			Metric: Metric{
+				MetricNameLabel: "B",
+			},
+			Timestamp: 1,
+		},
+		&Sample{
+			// Fingerprint: 68f4c9ed24533f8f.
+			Metric: Metric{
+				MetricNameLabel: "B",
+			},
+			Timestamp: 2,
+		},
+	}
+
+	expected := Samples{
+		&Sample{
+			// Fingerprint: 1bf6c9ed24543f8f.
+			Metric: Metric{
+				MetricNameLabel: "C",
+			},
+			Timestamp: 1,
+		},
+		&Sample{
+			// Fingerprint: 1bf6c9ed24543f8f.
+			Metric: Metric{
+				MetricNameLabel: "C",
+			},
+			Timestamp: 2,
+		},
+		&Sample{
+			// Fingerprint: 68f4c9ed24533f8f.
+			Metric: Metric{
+				MetricNameLabel: "B",
+			},
+			Timestamp: 1,
+		},
+		&Sample{
+			// Fingerprint: 68f4c9ed24533f8f.
+			Metric: Metric{
+				MetricNameLabel: "B",
+			},
+			Timestamp: 2,
+		},
+		&Sample{
+			// Fingerprint: 81f9c9ed24563f8f.
+			Metric: Metric{
+				MetricNameLabel: "A",
+			},
+			Timestamp: 1,
+		},
+		&Sample{
+			// Fingerprint: 81f9c9ed24563f8f.
+			Metric: Metric{
+				MetricNameLabel: "A",
+			},
+			Timestamp: 2,
+		},
+	}
+
+	sort.Sort(input)
+
+	for i, actual := range input {
+		actualFp := actual.Metric.Fingerprint()
+		expectedFp := expected[i].Metric.Fingerprint()
+
+		if !actualFp.Equal(expectedFp) {
+			t.Fatalf("%d. Incorrect fingerprint. Got %s; want %s", i, actualFp.String(), expectedFp.String())
+		}
+
+		if actual.Timestamp != expected[i].Timestamp {
+			t.Fatalf("%d. Incorrect timestamp. Got %s; want %s", i, actual.Timestamp, expected[i].Timestamp)
+		}
+	}
+}

+ 37 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/samplevalue.go

@@ -0,0 +1,37 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"fmt"
+	"strconv"
+)
+
+// A SampleValue is a representation of a value for a given sample at a given
+// time.
+type SampleValue float64
+
+// Equal does a straight v==o.
+func (v SampleValue) Equal(o SampleValue) bool {
+	return v == o
+}
+
+// MarshalJSON implements json.Marshaler.
+func (v SampleValue) MarshalJSON() ([]byte, error) {
+	return []byte(fmt.Sprintf(`"%s"`, v)), nil
+}
+
+func (v SampleValue) String() string {
+	return strconv.FormatFloat(float64(v), 'f', -1, 64)
+}

+ 97 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature.go

@@ -0,0 +1,97 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"bytes"
+	"hash"
+	"hash/fnv"
+)
+
+// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is
+// used to separate label names, label values, and other strings from each other
+// when calculating their combined hash value (aka signature aka fingerprint).
+const SeparatorByte byte = 255
+
+var (
+	// cache the signature of an empty label set.
+	emptyLabelSignature = fnv.New64a().Sum64()
+
+	hashAndBufPool = make(chan *hashAndBuf, 1024)
+)
+
+type hashAndBuf struct {
+	h hash.Hash64
+	b bytes.Buffer
+}
+
+func getHashAndBuf() *hashAndBuf {
+	select {
+	case hb := <-hashAndBufPool:
+		return hb
+	default:
+		return &hashAndBuf{h: fnv.New64a()}
+	}
+}
+
+func putHashAndBuf(hb *hashAndBuf) {
+	select {
+	case hashAndBufPool <- hb:
+	default:
+	}
+}
+
+// LabelsToSignature returns a unique signature (i.e., fingerprint) for a given
+// label set.
+func LabelsToSignature(labels map[string]string) uint64 {
+	if len(labels) == 0 {
+		return emptyLabelSignature
+	}
+
+	var result uint64
+	hb := getHashAndBuf()
+	defer putHashAndBuf(hb)
+
+	for k, v := range labels {
+		hb.b.WriteString(k)
+		hb.b.WriteByte(SeparatorByte)
+		hb.b.WriteString(v)
+		hb.h.Write(hb.b.Bytes())
+		result ^= hb.h.Sum64()
+		hb.h.Reset()
+		hb.b.Reset()
+	}
+	return result
+}
+
+// LabelValuesToSignature returns a unique signature (i.e., fingerprint) for the
+// values of a given label set.
+func LabelValuesToSignature(labels map[string]string) uint64 {
+	if len(labels) == 0 {
+		return emptyLabelSignature
+	}
+
+	var result uint64
+	hb := getHashAndBuf()
+	defer putHashAndBuf(hb)
+
+	for _, v := range labels {
+		hb.b.WriteString(v)
+		hb.h.Write(hb.b.Bytes())
+		result ^= hb.h.Sum64()
+		hb.h.Reset()
+		hb.b.Reset()
+	}
+	return result
+}

+ 120 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/signature_test.go

@@ -0,0 +1,120 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"runtime"
+	"testing"
+)
+
+func testLabelsToSignature(t testing.TB) {
+	var scenarios = []struct {
+		in  map[string]string
+		out uint64
+	}{
+		{
+			in:  map[string]string{},
+			out: 14695981039346656037,
+		},
+		{
+			in:  map[string]string{"name": "garland, briggs", "fear": "love is not enough"},
+			out: 12952432476264840823,
+		},
+	}
+
+	for i, scenario := range scenarios {
+		actual := LabelsToSignature(scenario.in)
+
+		if actual != scenario.out {
+			t.Errorf("%d. expected %d, got %d", i, scenario.out, actual)
+		}
+	}
+}
+
+func TestLabelToSignature(t *testing.T) {
+	testLabelsToSignature(t)
+}
+
+func TestEmptyLabelSignature(t *testing.T) {
+	input := []map[string]string{nil, {}}
+
+	var ms runtime.MemStats
+	runtime.ReadMemStats(&ms)
+
+	alloc := ms.Alloc
+
+	for _, labels := range input {
+		LabelsToSignature(labels)
+	}
+
+	runtime.ReadMemStats(&ms)
+
+	if got := ms.Alloc; alloc != got {
+		t.Fatal("expected LabelsToSignature with empty labels not to perform allocations")
+	}
+}
+
+func BenchmarkLabelToSignature(b *testing.B) {
+	for i := 0; i < b.N; i++ {
+		testLabelsToSignature(b)
+	}
+}
+
+func benchmarkLabelValuesToSignature(b *testing.B, l map[string]string, e uint64) {
+	for i := 0; i < b.N; i++ {
+		if a := LabelValuesToSignature(l); a != e {
+			b.Fatalf("expected signature of %d for %s, got %d", e, l, a)
+		}
+	}
+}
+
+func BenchmarkLabelValuesToSignatureScalar(b *testing.B) {
+	benchmarkLabelValuesToSignature(b, nil, 14695981039346656037)
+}
+
+func BenchmarkLabelValuesToSignatureSingle(b *testing.B) {
+	benchmarkLabelValuesToSignature(b, map[string]string{"first-label": "first-label-value"}, 2653746141194979650)
+}
+
+func BenchmarkLabelValuesToSignatureDouble(b *testing.B) {
+	benchmarkLabelValuesToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value"}, 8893559499616767364)
+}
+
+func BenchmarkLabelValuesToSignatureTriple(b *testing.B) {
+	benchmarkLabelValuesToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 1685970066862087833)
+}
+
+func benchmarkLabelToSignature(b *testing.B, l map[string]string, e uint64) {
+	for i := 0; i < b.N; i++ {
+		if a := LabelsToSignature(l); a != e {
+			b.Fatalf("expected signature of %d for %s, got %d", e, l, a)
+		}
+	}
+}
+
+func BenchmarkLabelToSignatureScalar(b *testing.B) {
+	benchmarkLabelToSignature(b, nil, 14695981039346656037)
+}
+
+func BenchmarkLabelToSignatureSingle(b *testing.B) {
+	benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value"}, 5147259542624943964)
+}
+
+func BenchmarkLabelToSignatureDouble(b *testing.B) {
+	benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value"}, 18269973311206963528)
+}
+
+func BenchmarkLabelToSignatureTriple(b *testing.B) {
+	benchmarkLabelToSignature(b, map[string]string{"first-label": "first-label-value", "second-label": "second-label-value", "third-label": "third-label-value"}, 15738406913934009676)
+}

+ 115 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp.go

@@ -0,0 +1,115 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"math"
+	"strconv"
+
+	native_time "time"
+)
+
+// Timestamp is the number of milliseconds since the epoch
+// (1970-01-01 00:00 UTC) excluding leap seconds.
+type Timestamp int64
+
+const (
+	// MinimumTick is the minimum supported time resolution. This has to be
+	// at least native_time.Second in order for the code below to work.
+	MinimumTick = native_time.Millisecond
+	// second is the timestamp duration equivalent to one second.
+	second = int64(native_time.Second / MinimumTick)
+	// The number of nanoseconds per minimum tick.
+	nanosPerTick = int64(MinimumTick / native_time.Nanosecond)
+
+	// Earliest is the earliest timestamp representable. Handy for
+	// initializing a high watermark.
+	Earliest = Timestamp(math.MinInt64)
+	// Latest is the latest timestamp representable. Handy for initializing
+	// a low watermark.
+	Latest = Timestamp(math.MaxInt64)
+)
+
+// Equal reports whether two timestamps represent the same instant.
+func (t Timestamp) Equal(o Timestamp) bool {
+	return t == o
+}
+
+// Before reports whether the timestamp t is before o.
+func (t Timestamp) Before(o Timestamp) bool {
+	return t < o
+}
+
+// After reports whether the timestamp t is after o.
+func (t Timestamp) After(o Timestamp) bool {
+	return t > o
+}
+
+// Add returns the Timestamp t + d.
+func (t Timestamp) Add(d native_time.Duration) Timestamp {
+	return t + Timestamp(d/MinimumTick)
+}
+
+// Sub returns the Duration t - o.
+func (t Timestamp) Sub(o Timestamp) native_time.Duration {
+	return native_time.Duration(t-o) * MinimumTick
+}
+
+// Time returns the time.Time representation of t.
+func (t Timestamp) Time() native_time.Time {
+	return native_time.Unix(int64(t)/second, (int64(t)%second)*nanosPerTick)
+}
+
+// Unix returns t as a Unix time, the number of seconds elapsed
+// since January 1, 1970 UTC.
+func (t Timestamp) Unix() int64 {
+	return int64(t) / second
+}
+
+// UnixNano returns t as a Unix time, the number of nanoseconds elapsed
+// since January 1, 1970 UTC.
+func (t Timestamp) UnixNano() int64 {
+	return int64(t) * nanosPerTick
+}
+
+// String returns a string representation of the timestamp.
+func (t Timestamp) String() string {
+	return strconv.FormatFloat(float64(t)/float64(second), 'f', -1, 64)
+}
+
+func (t Timestamp) MarshalJSON() ([]byte, error) {
+	return []byte(t.String()), nil
+}
+
+// Now returns the current time as a Timestamp.
+func Now() Timestamp {
+	return TimestampFromTime(native_time.Now())
+}
+
+// TimestampFromTime returns the Timestamp equivalent to the time.Time t.
+func TimestampFromTime(t native_time.Time) Timestamp {
+	return TimestampFromUnixNano(t.UnixNano())
+}
+
+// TimestampFromUnix returns the Timestamp equivalent to the Unix timestamp t
+// provided in seconds.
+func TimestampFromUnix(t int64) Timestamp {
+	return Timestamp(t * second)
+}
+
+// TimestampFromUnixNano returns the Timestamp equivalent to the Unix timestamp
+// t provided in nanoseconds.
+func TimestampFromUnixNano(t int64) Timestamp {
+	return Timestamp(t / nanosPerTick)
+}

+ 86 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/model/timestamp_test.go

@@ -0,0 +1,86 @@
+// Copyright 2013 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package model
+
+import (
+	"testing"
+	native_time "time"
+)
+
+func TestComparators(t *testing.T) {
+	t1a := TimestampFromUnix(0)
+	t1b := TimestampFromUnix(0)
+	t2 := TimestampFromUnix(2*second - 1)
+
+	if !t1a.Equal(t1b) {
+		t.Fatalf("Expected %s to be equal to %s", t1a, t1b)
+	}
+	if t1a.Equal(t2) {
+		t.Fatalf("Expected %s to not be equal to %s", t1a, t2)
+	}
+
+	if !t1a.Before(t2) {
+		t.Fatalf("Expected %s to be before %s", t1a, t2)
+	}
+	if t1a.Before(t1b) {
+		t.Fatalf("Expected %s to not be before %s", t1a, t1b)
+	}
+
+	if !t2.After(t1a) {
+		t.Fatalf("Expected %s to be after %s", t2, t1a)
+	}
+	if t1b.After(t1a) {
+		t.Fatalf("Expected %s to not be after %s", t1b, t1a)
+	}
+}
+
+func TestTimestampConversions(t *testing.T) {
+	unixSecs := int64(1136239445)
+	unixNsecs := int64(123456789)
+	unixNano := unixSecs*1000000000 + unixNsecs
+
+	t1 := native_time.Unix(unixSecs, unixNsecs-unixNsecs%nanosPerTick)
+	t2 := native_time.Unix(unixSecs, unixNsecs)
+
+	ts := TimestampFromUnixNano(unixNano)
+	if !ts.Time().Equal(t1) {
+		t.Fatalf("Expected %s, got %s", t1, ts.Time())
+	}
+
+	// Test available precision.
+	ts = TimestampFromTime(t2)
+	if !ts.Time().Equal(t1) {
+		t.Fatalf("Expected %s, got %s", t1, ts.Time())
+	}
+
+	if ts.UnixNano() != unixNano-unixNano%nanosPerTick {
+		t.Fatalf("Expected %d, got %d", unixNano, ts.UnixNano())
+	}
+}
+
+func TestDuration(t *testing.T) {
+	duration := native_time.Second + native_time.Minute + native_time.Hour
+	goTime := native_time.Unix(1136239445, 0)
+
+	ts := TimestampFromTime(goTime)
+	if !goTime.Add(duration).Equal(ts.Add(duration).Time()) {
+		t.Fatalf("Expected %s to be equal to %s", goTime.Add(duration), ts.Add(duration))
+	}
+
+	earlier := ts.Add(-duration)
+	delta := ts.Sub(earlier)
+	if delta != duration {
+		t.Fatalf("Expected %s to be equal to %s", delta, duration)
+	}
+}

+ 1 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/.gitignore

@@ -0,0 +1 @@
+command-line-arguments.test

+ 53 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/README.md

@@ -0,0 +1,53 @@
+# Overview
+This is the [Prometheus](http://www.prometheus.io) telemetric
+instrumentation client [Go](http://golang.org) client library.  It
+enable authors to define process-space metrics for their servers and
+expose them through a web service interface for extraction,
+aggregation, and a whole slew of other post processing techniques.
+
+# Installing
+    $ go get github.com/prometheus/client_golang/prometheus
+
+# Example
+```go
+package main
+
+import (
+	"net/http"
+
+	"github.com/prometheus/client_golang/prometheus"
+)
+
+var (
+	indexed = prometheus.NewCounter(prometheus.CounterOpts{
+		Namespace: "my_company",
+		Subsystem: "indexer",
+		Name:      "documents_indexed",
+		Help:      "The number of documents indexed.",
+	})
+	size = prometheus.NewGauge(prometheus.GaugeOpts{
+		Namespace: "my_company",
+		Subsystem: "storage",
+		Name:      "documents_total_size_bytes",
+		Help:      "The total size of all documents in the storage.",
+	})
+)
+
+func main() {
+	http.Handle("/metrics", prometheus.Handler())
+
+	indexed.Inc()
+	size.Set(5)
+
+	http.ListenAndServe(":8080", nil)
+}
+
+func init() {
+	prometheus.MustRegister(indexed)
+	prometheus.MustRegister(size)
+}
+```
+
+# Documentation
+
+[![GoDoc](https://godoc.org/github.com/prometheus/client_golang?status.png)](https://godoc.org/github.com/prometheus/client_golang)

+ 131 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/benchmark_test.go

@@ -0,0 +1,131 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package prometheus
+
+import (
+	"testing"
+)
+
+func BenchmarkCounterWithLabelValues(b *testing.B) {
+	m := NewCounterVec(
+		CounterOpts{
+			Name: "benchmark_counter",
+			Help: "A counter to benchmark it.",
+		},
+		[]string{"one", "two", "three"},
+	)
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		m.WithLabelValues("eins", "zwei", "drei").Inc()
+	}
+}
+
+func BenchmarkCounterWithMappedLabels(b *testing.B) {
+	m := NewCounterVec(
+		CounterOpts{
+			Name: "benchmark_counter",
+			Help: "A counter to benchmark it.",
+		},
+		[]string{"one", "two", "three"},
+	)
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		m.With(Labels{"two": "zwei", "one": "eins", "three": "drei"}).Inc()
+	}
+}
+
+func BenchmarkCounterWithPreparedMappedLabels(b *testing.B) {
+	m := NewCounterVec(
+		CounterOpts{
+			Name: "benchmark_counter",
+			Help: "A counter to benchmark it.",
+		},
+		[]string{"one", "two", "three"},
+	)
+	b.ReportAllocs()
+	b.ResetTimer()
+	labels := Labels{"two": "zwei", "one": "eins", "three": "drei"}
+	for i := 0; i < b.N; i++ {
+		m.With(labels).Inc()
+	}
+}
+
+func BenchmarkCounterNoLabels(b *testing.B) {
+	m := NewCounter(CounterOpts{
+		Name: "benchmark_counter",
+		Help: "A counter to benchmark it.",
+	})
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		m.Inc()
+	}
+}
+
+func BenchmarkGaugeWithLabelValues(b *testing.B) {
+	m := NewGaugeVec(
+		GaugeOpts{
+			Name: "benchmark_gauge",
+			Help: "A gauge to benchmark it.",
+		},
+		[]string{"one", "two", "three"},
+	)
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		m.WithLabelValues("eins", "zwei", "drei").Set(3.1415)
+	}
+}
+
+func BenchmarkGaugeNoLabels(b *testing.B) {
+	m := NewGauge(GaugeOpts{
+		Name: "benchmark_gauge",
+		Help: "A gauge to benchmark it.",
+	})
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		m.Set(3.1415)
+	}
+}
+
+func BenchmarkSummaryWithLabelValues(b *testing.B) {
+	m := NewSummaryVec(
+		SummaryOpts{
+			Name: "benchmark_summary",
+			Help: "A summary to benchmark it.",
+		},
+		[]string{"one", "two", "three"},
+	)
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		m.WithLabelValues("eins", "zwei", "drei").Observe(3.1415)
+	}
+}
+
+func BenchmarkSummaryNoLabels(b *testing.B) {
+	m := NewSummary(SummaryOpts{
+		Name: "benchmark_summary",
+		Help: "A summary to benchmark it.",
+	},
+	)
+	b.ReportAllocs()
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		m.Observe(3.1415)
+	}
+}

+ 75 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/collector.go

@@ -0,0 +1,75 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package prometheus
+
+// Collector is the interface implemented by anything that can be used by
+// Prometheus to collect metrics. A Collector has to be registered for
+// collection. See Register, MustRegister, RegisterOrGet, and MustRegisterOrGet.
+//
+// The stock metrics provided by this package (like Gauge, Counter, Summary) are
+// also Collectors (which only ever collect one metric, namely itself). An
+// implementer of Collector may, however, collect multiple metrics in a
+// coordinated fashion and/or create metrics on the fly. Examples for collectors
+// already implemented in this library are the metric vectors (i.e. collection
+// of multiple instances of the same Metric but with different label values)
+// like GaugeVec or SummaryVec, and the ExpvarCollector.
+type Collector interface {
+	// Describe sends the super-set of all possible descriptors of metrics
+	// collected by this Collector to the provided channel and returns once
+	// the last descriptor has been sent. The sent descriptors fulfill the
+	// consistency and uniqueness requirements described in the Desc
+	// documentation. (It is valid if one and the same Collector sends
+	// duplicate descriptors. Those duplicates are simply ignored. However,
+	// two different Collectors must not send duplicate descriptors.) This
+	// method idempotently sends the same descriptors throughout the
+	// lifetime of the Collector. If a Collector encounters an error while
+	// executing this method, it must send an invalid descriptor (created
+	// with NewInvalidDesc) to signal the error to the registry.
+	Describe(chan<- *Desc)
+	// Collect is called by Prometheus when collecting metrics. The
+	// implementation sends each collected metric via the provided channel
+	// and returns once the last metric has been sent. The descriptor of
+	// each sent metric is one of those returned by Describe. Returned
+	// metrics that share the same descriptor must differ in their variable
+	// label values. This method may be called concurrently and must
+	// therefore be implemented in a concurrency safe way. Blocking occurs
+	// at the expense of total performance of rendering all registered
+	// metrics. Ideally, Collector implementations support concurrent
+	// readers.
+	Collect(chan<- Metric)
+}
+
+// SelfCollector implements Collector for a single Metric so that that the
+// Metric collects itself. Add it as an anonymous field to a struct that
+// implements Metric, and call Init with the Metric itself as an argument.
+type SelfCollector struct {
+	self Metric
+}
+
+// Init provides the SelfCollector with a reference to the metric it is supposed
+// to collect. It is usually called within the factory function to create a
+// metric. See example.
+func (c *SelfCollector) Init(self Metric) {
+	c.self = self
+}
+
+// Describe implements Collector.
+func (c *SelfCollector) Describe(ch chan<- *Desc) {
+	ch <- c.self.Desc()
+}
+
+// Collect implements Collector.
+func (c *SelfCollector) Collect(ch chan<- Metric) {
+	ch <- c.self
+}

+ 175 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/counter.go

@@ -0,0 +1,175 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package prometheus
+
+import (
+	"errors"
+	"hash/fnv"
+)
+
+// Counter is a Metric that represents a single numerical value that only ever
+// goes up. That implies that it cannot be used to count items whose number can
+// also go down, e.g. the number of currently running goroutines. Those
+// "counters" are represented by Gauges.
+//
+// A Counter is typically used to count requests served, tasks completed, errors
+// occurred, etc.
+//
+// To create Counter instances, use NewCounter.
+type Counter interface {
+	Metric
+	Collector
+
+	// Set is used to set the Counter to an arbitrary value. It is only used
+	// if you have to transfer a value from an external counter into this
+	// Prometheus metrics. Do not use it for regular handling of a
+	// Prometheus counter (as it can be used to break the contract of
+	// monotonically increasing values).
+	Set(float64)
+	// Inc increments the counter by 1.
+	Inc()
+	// Add adds the given value to the counter. It panics if the value is <
+	// 0.
+	Add(float64)
+}
+
+// CounterOpts is an alias for Opts. See there for doc comments.
+type CounterOpts Opts
+
+// NewCounter creates a new Counter based on the provided CounterOpts.
+func NewCounter(opts CounterOpts) Counter {
+	desc := NewDesc(
+		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
+		opts.Help,
+		nil,
+		opts.ConstLabels,
+	)
+	result := &counter{value: value{desc: desc, valType: CounterValue, labelPairs: desc.constLabelPairs}}
+	result.Init(result) // Init self-collection.
+	return result
+}
+
+type counter struct {
+	value
+}
+
+func (c *counter) Add(v float64) {
+	if v < 0 {
+		panic(errors.New("counter cannot decrease in value"))
+	}
+	c.value.Add(v)
+}
+
+// CounterVec is a Collector that bundles a set of Counters that all share the
+// same Desc, but have different values for their variable labels. This is used
+// if you want to count the same thing partitioned by various dimensions
+// (e.g. number of http requests, partitioned by response code and
+// method). Create instances with NewCounterVec.
+//
+// CounterVec embeds MetricVec. See there for a full list of methods with
+// detailed documentation.
+type CounterVec struct {
+	MetricVec
+}
+
+// NewCounterVec creates a new CounterVec based on the provided CounterOpts and
+// partitioned by the given label names. At least one label name must be
+// provided.
+func NewCounterVec(opts CounterOpts, labelNames []string) *CounterVec {
+	desc := NewDesc(
+		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
+		opts.Help,
+		labelNames,
+		opts.ConstLabels,
+	)
+	return &CounterVec{
+		MetricVec: MetricVec{
+			children: map[uint64]Metric{},
+			desc:     desc,
+			hash:     fnv.New64a(),
+			newMetric: func(lvs ...string) Metric {
+				result := &counter{value: value{
+					desc:       desc,
+					valType:    CounterValue,
+					labelPairs: makeLabelPairs(desc, lvs),
+				}}
+				result.Init(result) // Init self-collection.
+				return result
+			},
+		},
+	}
+}
+
+// GetMetricWithLabelValues replaces the method of the same name in
+// MetricVec. The difference is that this method returns a Counter and not a
+// Metric so that no type conversion is required.
+func (m *CounterVec) GetMetricWithLabelValues(lvs ...string) (Counter, error) {
+	metric, err := m.MetricVec.GetMetricWithLabelValues(lvs...)
+	if metric != nil {
+		return metric.(Counter), err
+	}
+	return nil, err
+}
+
+// GetMetricWith replaces the method of the same name in MetricVec. The
+// difference is that this method returns a Counter and not a Metric so that no
+// type conversion is required.
+func (m *CounterVec) GetMetricWith(labels Labels) (Counter, error) {
+	metric, err := m.MetricVec.GetMetricWith(labels)
+	if metric != nil {
+		return metric.(Counter), err
+	}
+	return nil, err
+}
+
+// WithLabelValues works as GetMetricWithLabelValues, but panics where
+// GetMetricWithLabelValues would have returned an error. By not returning an
+// error, WithLabelValues allows shortcuts like
+//     myVec.WithLabelValues("404", "GET").Add(42)
+func (m *CounterVec) WithLabelValues(lvs ...string) Counter {
+	return m.MetricVec.WithLabelValues(lvs...).(Counter)
+}
+
+// With works as GetMetricWith, but panics where GetMetricWithLabels would have
+// returned an error. By not returning an error, With allows shortcuts like
+//     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
+func (m *CounterVec) With(labels Labels) Counter {
+	return m.MetricVec.With(labels).(Counter)
+}
+
+// CounterFunc is a Counter whose value is determined at collect time by calling a
+// provided function.
+//
+// To create CounterFunc instances, use NewCounterFunc.
+type CounterFunc interface {
+	Metric
+	Collector
+}
+
+// NewCounterFunc creates a new CounterFunc based on the provided
+// CounterOpts. The value reported is determined by calling the given function
+// from within the Write method. Take into account that metric collection may
+// happen concurrently. If that results in concurrent calls to Write, like in
+// the case where a CounterFunc is directly registered with Prometheus, the
+// provided function must be concurrency-safe. The function should also honor
+// the contract for a Counter (values only go up, not down), but compliance will
+// not be checked.
+func NewCounterFunc(opts CounterOpts, function func() float64) CounterFunc {
+	return newValueFunc(NewDesc(
+		BuildFQName(opts.Namespace, opts.Subsystem, opts.Name),
+		opts.Help,
+		nil,
+		opts.ConstLabels,
+	), CounterValue, function)
+}

+ 58 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/counter_test.go

@@ -0,0 +1,58 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package prometheus
+
+import (
+	"math"
+	"testing"
+
+	dto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_model/go"
+)
+
+func TestCounterAdd(t *testing.T) {
+	counter := NewCounter(CounterOpts{
+		Name:        "test",
+		Help:        "test help",
+		ConstLabels: Labels{"a": "1", "b": "2"},
+	}).(*counter)
+	counter.Inc()
+	if expected, got := 1., math.Float64frombits(counter.valBits); expected != got {
+		t.Errorf("Expected %f, got %f.", expected, got)
+	}
+	counter.Add(42)
+	if expected, got := 43., math.Float64frombits(counter.valBits); expected != got {
+		t.Errorf("Expected %f, got %f.", expected, got)
+	}
+
+	if expected, got := "counter cannot decrease in value", decreaseCounter(counter).Error(); expected != got {
+		t.Errorf("Expected error %q, got %q.", expected, got)
+	}
+
+	m := &dto.Metric{}
+	counter.Write(m)
+
+	if expected, got := `label:<name:"a" value:"1" > label:<name:"b" value:"2" > counter:<value:43 > `, m.String(); expected != got {
+		t.Errorf("expected %q, got %q", expected, got)
+	}
+}
+
+func decreaseCounter(c *counter) (err error) {
+	defer func() {
+		if e := recover(); e != nil {
+			err = e.(error)
+		}
+	}()
+	c.Add(-1)
+	return nil
+}

+ 197 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/desc.go

@@ -0,0 +1,197 @@
+package prometheus
+
+import (
+	"bytes"
+	"errors"
+	"fmt"
+	"hash/fnv"
+	"regexp"
+	"sort"
+	"strings"
+
+	"github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/model"
+	dto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_model/go"
+)
+
+var (
+	metricNameRE = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_:]*$`)
+	labelNameRE  = regexp.MustCompile(`^[a-zA-Z_][a-zA-Z0-9_]*$`)
+)
+
+// Labels represents a collection of label name -> value mappings. This type is
+// commonly used with the With(Labels) and GetMetricWith(Labels) methods of
+// metric vector Collectors, e.g.:
+//     myVec.With(Labels{"code": "404", "method": "GET"}).Add(42)
+//
+// The other use-case is the specification of constant label pairs in Opts or to
+// create a Desc.
+type Labels map[string]string
+
+// Desc is the descriptor used by every Prometheus Metric. It is essentially
+// the immutable meta-data of a Metric. The normal Metric implementations
+// included in this package manage their Desc under the hood. Users only have to
+// deal with Desc if they use advanced features like the ExpvarCollector or
+// custom Collectors and Metrics.
+//
+// Descriptors registered with the same registry have to fulfill certain
+// consistency and uniqueness criteria if they share the same fully-qualified
+// name: They must have the same help string and the same label names (aka label
+// dimensions) in each, constLabels and variableLabels, but they must differ in
+// the values of the constLabels.
+//
+// Descriptors that share the same fully-qualified names and the same label
+// values of their constLabels are considered equal.
+//
+// Use NewDesc to create new Desc instances.
+type Desc struct {
+	// fqName has been built from Namespace, Subsystem, and Name.
+	fqName string
+	// help provides some helpful information about this metric.
+	help string
+	// constLabelPairs contains precalculated DTO label pairs based on
+	// the constant labels.
+	constLabelPairs []*dto.LabelPair
+	// VariableLabels contains names of labels for which the metric
+	// maintains variable values.
+	variableLabels []string
+	// id is a hash of the values of the ConstLabels and fqName. This
+	// must be unique among all registered descriptors and can therefore be
+	// used as an identifier of the descriptor.
+	id uint64
+	// dimHash is a hash of the label names (preset and variable) and the
+	// Help string. Each Desc with the same fqName must have the same
+	// dimHash.
+	dimHash uint64
+	// err is an error that occured during construction. It is reported on
+	// registration time.
+	err error
+}
+
+// NewDesc allocates and initializes a new Desc. Errors are recorded in the Desc
+// and will be reported on registration time. variableLabels and constLabels can
+// be nil if no such labels should be set. fqName and help must not be empty.
+//
+// variableLabels only contain the label names. Their label values are variable
+// and therefore not part of the Desc. (They are managed within the Metric.)
+//
+// For constLabels, the label values are constant. Therefore, they are fully
+// specified in the Desc. See the Opts documentation for the implications of
+// constant labels.
+func NewDesc(fqName, help string, variableLabels []string, constLabels Labels) *Desc {
+	d := &Desc{
+		fqName:         fqName,
+		help:           help,
+		variableLabels: variableLabels,
+	}
+	if help == "" {
+		d.err = errors.New("empty help string")
+		return d
+	}
+	if !metricNameRE.MatchString(fqName) {
+		d.err = fmt.Errorf("%q is not a valid metric name", fqName)
+		return d
+	}
+	// labelValues contains the label values of const labels (in order of
+	// their sorted label names) plus the fqName (at position 0).
+	labelValues := make([]string, 1, len(constLabels)+1)
+	labelValues[0] = fqName
+	labelNames := make([]string, 0, len(constLabels)+len(variableLabels))
+	labelNameSet := map[string]struct{}{}
+	// First add only the const label names and sort them...
+	for labelName := range constLabels {
+		if !checkLabelName(labelName) {
+			d.err = fmt.Errorf("%q is not a valid label name", labelName)
+			return d
+		}
+		labelNames = append(labelNames, labelName)
+		labelNameSet[labelName] = struct{}{}
+	}
+	sort.Strings(labelNames)
+	// ... so that we can now add const label values in the order of their names.
+	for _, labelName := range labelNames {
+		labelValues = append(labelValues, constLabels[labelName])
+	}
+	// Now add the variable label names, but prefix them with something that
+	// cannot be in a regular label name. That prevents matching the label
+	// dimension with a different mix between preset and variable labels.
+	for _, labelName := range variableLabels {
+		if !checkLabelName(labelName) {
+			d.err = fmt.Errorf("%q is not a valid label name", labelName)
+			return d
+		}
+		labelNames = append(labelNames, "$"+labelName)
+		labelNameSet[labelName] = struct{}{}
+	}
+	if len(labelNames) != len(labelNameSet) {
+		d.err = errors.New("duplicate label names")
+		return d
+	}
+	h := fnv.New64a()
+	var b bytes.Buffer // To copy string contents into, avoiding []byte allocations.
+	for _, val := range labelValues {
+		b.Reset()
+		b.WriteString(val)
+		b.WriteByte(model.SeparatorByte)
+		h.Write(b.Bytes())
+	}
+	d.id = h.Sum64()
+	// Sort labelNames so that order doesn't matter for the hash.
+	sort.Strings(labelNames)
+	// Now hash together (in this order) the help string and the sorted
+	// label names.
+	h.Reset()
+	b.Reset()
+	b.WriteString(help)
+	b.WriteByte(model.SeparatorByte)
+	h.Write(b.Bytes())
+	for _, labelName := range labelNames {
+		b.Reset()
+		b.WriteString(labelName)
+		b.WriteByte(model.SeparatorByte)
+		h.Write(b.Bytes())
+	}
+	d.dimHash = h.Sum64()
+
+	d.constLabelPairs = make([]*dto.LabelPair, 0, len(constLabels))
+	for n, v := range constLabels {
+		d.constLabelPairs = append(d.constLabelPairs, &dto.LabelPair{
+			Name:  proto.String(n),
+			Value: proto.String(v),
+		})
+	}
+	sort.Sort(LabelPairSorter(d.constLabelPairs))
+	return d
+}
+
+// NewInvalidDesc returns an invalid descriptor, i.e. a descriptor with the
+// provided error set. If a collector returning such a descriptor is registered,
+// registration will fail with the provided error. NewInvalidDesc can be used by
+// a Collector to signal inability to describe itself.
+func NewInvalidDesc(err error) *Desc {
+	return &Desc{
+		err: err,
+	}
+}
+
+func (d *Desc) String() string {
+	lpStrings := make([]string, 0, len(d.constLabelPairs))
+	for _, lp := range d.constLabelPairs {
+		lpStrings = append(
+			lpStrings,
+			fmt.Sprintf("%s=%q", lp.GetName(), lp.GetValue()),
+		)
+	}
+	return fmt.Sprintf(
+		"Desc{fqName: %q, help: %q, constLabels: {%s}, variableLabels: %v}",
+		d.fqName,
+		d.help,
+		strings.Join(lpStrings, ","),
+		d.variableLabels,
+	)
+}
+
+func checkLabelName(l string) bool {
+	return labelNameRE.MatchString(l) &&
+		!strings.HasPrefix(l, model.ReservedLabelPrefix)
+}

+ 108 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/doc.go

@@ -0,0 +1,108 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package prometheus provides embeddable metric primitives for servers and
+// standardized exposition of telemetry through a web services interface.
+//
+// All exported functions and methods are safe to be used concurrently unless
+// specified otherwise.
+//
+// To expose metrics registered with the Prometheus registry, an HTTP server
+// needs to know about the Prometheus handler. The usual endpoint is "/metrics".
+//
+//     http.Handle("/metrics", prometheus.Handler())
+//
+// As a starting point a very basic usage example:
+//
+//    package main
+//
+//    import (
+//    	"net/http"
+//
+//    	"github.com/prometheus/client_golang/prometheus"
+//    )
+//
+//    var (
+//    	cpuTemp = prometheus.NewGauge(prometheus.GaugeOpts{
+//    		Name: "cpu_temperature_celsius",
+//    		Help: "Current temperature of the CPU.",
+//    	})
+//    	hdFailures = prometheus.NewCounter(prometheus.CounterOpts{
+//    		Name: "hd_errors_total",
+//    		Help: "Number of hard-disk errors.",
+//    	})
+//    )
+//
+//    func init() {
+//    	prometheus.MustRegister(cpuTemp)
+//    	prometheus.MustRegister(hdFailures)
+//    }
+//
+//    func main() {
+//    	cpuTemp.Set(65.3)
+//    	hdFailures.Inc()
+//
+//    	http.Handle("/metrics", prometheus.Handler())
+//    	http.ListenAndServe(":8080", nil)
+//    }
+//
+//
+// This is a complete program that exports two metrics, a Gauge and a Counter.
+// It also exports some stats about the HTTP usage of the /metrics
+// endpoint. (See the Handler function for more detail.)
+//
+// A more advanced metric type is the Summary.
+//
+// In addition to the fundamental metric types Gauge, Counter, and Summary, a
+// very important part of the Prometheus data model is the partitioning of
+// samples along dimensions called labels, which results in metric vectors. The
+// fundamental types are GaugeVec, CounterVec, and SummaryVec.
+//
+// Those are all the parts needed for basic usage. Detailed documentation and
+// examples are provided below.
+//
+// Everything else this package offers is essentially for "power users" only. A
+// few pointers to "power user features":
+//
+// All the various ...Opts structs have a ConstLabels field for labels that
+// never change their value (which is only useful under special circumstances,
+// see documentation of the Opts type).
+//
+// The Untyped metric behaves like a Gauge, but signals the Prometheus server
+// not to assume anything about its type.
+//
+// Functions to fine-tune how the metric registry works: EnableCollectChecks,
+// PanicOnCollectError, Register, Unregister, SetMetricFamilyInjectionHook.
+//
+// For custom metric collection, there are two entry points: Custom Metric
+// implementations and custom Collector implementations. A Metric is the
+// fundamental unit in the Prometheus data model: a sample at a point in time
+// together with its meta-data (like its fully-qualified name and any number of
+// pairs of label name and label value) that knows how to marshal itself into a
+// data transfer object (aka DTO, implemented as a protocol buffer). A Collector
+// gets registered with the Prometheus registry and manages the collection of
+// one or more Metrics. Many parts of this package are building blocks for
+// Metrics and Collectors. Desc is the metric descriptor, actually used by all
+// metrics under the hood, and by Collectors to describe the Metrics to be
+// collected, but only to be dealt with by users if they implement their own
+// Metrics or Collectors. To create a Desc, the BuildFQName function will come
+// in handy. Other useful components for Metric and Collector implementation
+// include: LabelPairSorter to sort the DTO version of label pairs,
+// NewConstMetric and MustNewConstMetric to create "throw away" Metrics at
+// collection time, MetricVec to bundle custom Metrics into a metric vector
+// Collector, SelfCollector to make a custom Metric collect itself.
+//
+// A good example for a custom Collector is the ExpVarCollector included in this
+// package, which exports variables exported via the "expvar" package as
+// Prometheus metrics.
+package prometheus

+ 130 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/example_clustermanager_test.go

@@ -0,0 +1,130 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package prometheus_test
+
+import (
+	"sync"
+
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus"
+)
+
+// ClusterManager is an example for a system that might have been built without
+// Prometheus in mind. It models a central manager of jobs running in a
+// cluster. To turn it into something that collects Prometheus metrics, we
+// simply add the two methods required for the Collector interface.
+//
+// An additional challenge is that multiple instances of the ClusterManager are
+// run within the same binary, each in charge of a different zone. We need to
+// make use of ConstLabels to be able to register each ClusterManager instance
+// with Prometheus.
+type ClusterManager struct {
+	Zone     string
+	OOMCount *prometheus.CounterVec
+	RAMUsage *prometheus.GaugeVec
+	mtx      sync.Mutex // Protects OOMCount and RAMUsage.
+	// ... many more fields
+}
+
+// ReallyExpensiveAssessmentOfTheSystemState is a mock for the data gathering a
+// real cluster manager would have to do. Since it may actually be really
+// expensive, it must only be called once per collection. This implementation,
+// obviously, only returns some made-up data.
+func (c *ClusterManager) ReallyExpensiveAssessmentOfTheSystemState() (
+	oomCountByHost map[string]int, ramUsageByHost map[string]float64,
+) {
+	// Just example fake data.
+	oomCountByHost = map[string]int{
+		"foo.example.org": 42,
+		"bar.example.org": 2001,
+	}
+	ramUsageByHost = map[string]float64{
+		"foo.example.org": 6.023e23,
+		"bar.example.org": 3.14,
+	}
+	return
+}
+
+// Describe faces the interesting challenge that the two metric vectors that are
+// used in this example are already Collectors themselves. However, thanks to
+// the use of channels, it is really easy to "chain" Collectors. Here we simply
+// call the Describe methods of the two metric vectors.
+func (c *ClusterManager) Describe(ch chan<- *prometheus.Desc) {
+	c.OOMCount.Describe(ch)
+	c.RAMUsage.Describe(ch)
+}
+
+// Collect first triggers the ReallyExpensiveAssessmentOfTheSystemState. Then it
+// sets the retrieved values in the two metric vectors and then sends all their
+// metrics to the channel (again using a chaining technique as in the Describe
+// method). Since Collect could be called multiple times concurrently, that part
+// is protected by a mutex.
+func (c *ClusterManager) Collect(ch chan<- prometheus.Metric) {
+	oomCountByHost, ramUsageByHost := c.ReallyExpensiveAssessmentOfTheSystemState()
+	c.mtx.Lock()
+	defer c.mtx.Unlock()
+	for host, oomCount := range oomCountByHost {
+		c.OOMCount.WithLabelValues(host).Set(float64(oomCount))
+	}
+	for host, ramUsage := range ramUsageByHost {
+		c.RAMUsage.WithLabelValues(host).Set(ramUsage)
+	}
+	c.OOMCount.Collect(ch)
+	c.RAMUsage.Collect(ch)
+	// All metrics in OOMCount and RAMUsage are sent to the channel now. We
+	// can safely reset the two metric vectors now, so that we can start
+	// fresh in the next Collect cycle. (Imagine a host disappears from the
+	// cluster. If we did not reset here, its Metric would stay in the
+	// metric vectors forever.)
+	c.OOMCount.Reset()
+	c.RAMUsage.Reset()
+}
+
+// NewClusterManager creates the two metric vectors OOMCount and RAMUsage. Note
+// that the zone is set as a ConstLabel. (It's different in each instance of the
+// ClusterManager, but constant over the lifetime of an instance.) The reported
+// values are partitioned by host, which is therefore a variable label.
+func NewClusterManager(zone string) *ClusterManager {
+	return &ClusterManager{
+		Zone: zone,
+		OOMCount: prometheus.NewCounterVec(
+			prometheus.CounterOpts{
+				Subsystem:   "clustermanager",
+				Name:        "oom_count",
+				Help:        "number of OOM crashes",
+				ConstLabels: prometheus.Labels{"zone": zone},
+			},
+			[]string{"host"},
+		),
+		RAMUsage: prometheus.NewGaugeVec(
+			prometheus.GaugeOpts{
+				Subsystem:   "clustermanager",
+				Name:        "ram_usage_bytes",
+				Help:        "RAM usage as reported to the cluster manager",
+				ConstLabels: prometheus.Labels{"zone": zone},
+			},
+			[]string{"host"},
+		),
+	}
+}
+
+func ExampleCollector_clustermanager() {
+	workerDB := NewClusterManager("db")
+	workerCA := NewClusterManager("ca")
+	prometheus.MustRegister(workerDB)
+	prometheus.MustRegister(workerCA)
+
+	// Since we are dealing with custom Collector implementations, it might
+	// be a good idea to enable the collect checks in the registry.
+	prometheus.EnableCollectChecks(true)
+}

+ 87 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/example_memstats_test.go

@@ -0,0 +1,87 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package prometheus_test
+
+import (
+	"runtime"
+
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus"
+)
+
+var (
+	allocDesc = prometheus.NewDesc(
+		prometheus.BuildFQName("", "memstats", "alloc_bytes"),
+		"bytes allocated and still in use",
+		nil, nil,
+	)
+	totalAllocDesc = prometheus.NewDesc(
+		prometheus.BuildFQName("", "memstats", "total_alloc_bytes"),
+		"bytes allocated (even if freed)",
+		nil, nil,
+	)
+	numGCDesc = prometheus.NewDesc(
+		prometheus.BuildFQName("", "memstats", "num_gc_total"),
+		"number of GCs run",
+		nil, nil,
+	)
+)
+
+// MemStatsCollector is an example for a custom Collector that solves the
+// problem of feeding into multiple metrics at the same time. The
+// runtime.ReadMemStats should happen only once, and then the results need to be
+// fed into a number of separate Metrics. In this example, only a few of the
+// values reported by ReadMemStats are used. For each, there is a Desc provided
+// as a var, so the MemStatsCollector itself needs nothing else in the
+// struct. Only the methods need to be implemented.
+type MemStatsCollector struct{}
+
+// Describe just sends the three Desc objects for the Metrics we intend to
+// collect.
+func (_ MemStatsCollector) Describe(ch chan<- *prometheus.Desc) {
+	ch <- allocDesc
+	ch <- totalAllocDesc
+	ch <- numGCDesc
+}
+
+// Collect does the trick by calling ReadMemStats once and then constructing
+// three different Metrics on the fly.
+func (_ MemStatsCollector) Collect(ch chan<- prometheus.Metric) {
+	var ms runtime.MemStats
+	runtime.ReadMemStats(&ms)
+	ch <- prometheus.MustNewConstMetric(
+		allocDesc,
+		prometheus.GaugeValue,
+		float64(ms.Alloc),
+	)
+	ch <- prometheus.MustNewConstMetric(
+		totalAllocDesc,
+		prometheus.GaugeValue,
+		float64(ms.TotalAlloc),
+	)
+	ch <- prometheus.MustNewConstMetric(
+		numGCDesc,
+		prometheus.CounterValue,
+		float64(ms.NumGC),
+	)
+	// To avoid new allocations on each collection, you could also keep
+	// metric objects around and return the same objects each time, just
+	// with new values set.
+}
+
+func ExampleCollector_memstats() {
+	prometheus.MustRegister(&MemStatsCollector{})
+	// Since we are dealing with custom Collector implementations, it might
+	// be a good idea to enable the collect checks in the registry.
+	prometheus.EnableCollectChecks(true)
+}

+ 67 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/example_selfcollector_test.go

@@ -0,0 +1,67 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package prometheus_test
+
+import (
+	"runtime"
+
+	"github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus"
+	dto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_model/go"
+)
+
+func NewCallbackMetric(desc *prometheus.Desc, callback func() float64) *CallbackMetric {
+	result := &CallbackMetric{desc: desc, callback: callback}
+	result.Init(result) // Initialize the SelfCollector.
+	return result
+}
+
+// TODO: Come up with a better example.
+
+// CallbackMetric is an example for a user-defined Metric that exports the
+// result of a function call as a metric of type "untyped" without any
+// labels. It uses SelfCollector to turn the Metric into a Collector so that it
+// can be registered with Prometheus.
+//
+// Note that this example is pretty much academic as the prometheus package
+// already provides an UntypedFunc type.
+type CallbackMetric struct {
+	prometheus.SelfCollector
+
+	desc     *prometheus.Desc
+	callback func() float64
+}
+
+func (cm *CallbackMetric) Desc() *prometheus.Desc {
+	return cm.desc
+}
+
+func (cm *CallbackMetric) Write(m *dto.Metric) error {
+	m.Untyped = &dto.Untyped{Value: proto.Float64(cm.callback())}
+	return nil
+}
+
+func ExampleSelfCollector() {
+	m := NewCallbackMetric(
+		prometheus.NewDesc(
+			"runtime_goroutines_count",
+			"Total number of goroutines that currently exist.",
+			nil, nil, // No labels, these must be nil.
+		),
+		func() float64 {
+			return float64(runtime.NumGoroutine())
+		},
+	)
+	prometheus.MustRegister(m)
+}

+ 452 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/examples_test.go

@@ -0,0 +1,452 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package prometheus_test
+
+import (
+	"flag"
+	"fmt"
+	"math"
+	"net/http"
+	"runtime"
+	"sort"
+
+	"github.com/coreos/etcd/Godeps/_workspace/src/code.google.com/p/goprotobuf/proto"
+	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus"
+	dto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/prometheus/client_model/go"
+)
+
+func ExampleGauge() {
+	opsQueued := prometheus.NewGauge(prometheus.GaugeOpts{
+		Namespace: "our_company",
+		Subsystem: "blob_storage",
+		Name:      "ops_queued",
+		Help:      "Number of blob storage operations waiting to be processed.",
+	})
+	prometheus.MustRegister(opsQueued)
+
+	// 10 operations queued by the goroutine managing incoming requests.
+	opsQueued.Add(10)
+	// A worker goroutine has picked up a waiting operation.
+	opsQueued.Dec()
+	// And once more...
+	opsQueued.Dec()
+}
+
+func ExampleGaugeVec() {
+	binaryVersion := flag.String("binary_version", "debug", "Version of the binary: debug, canary, production.")
+	flag.Parse()
+
+	opsQueued := prometheus.NewGaugeVec(
+		prometheus.GaugeOpts{
+			Namespace:   "our_company",
+			Subsystem:   "blob_storage",
+			Name:        "ops_queued",
+			Help:        "Number of blob storage operations waiting to be processed, partitioned by user and type.",
+			ConstLabels: prometheus.Labels{"binary_version": *binaryVersion},
+		},
+		[]string{
+			// Which user has requested the operation?
+			"user",
+			// Of what type is the operation?
+			"type",
+		},
+	)
+	prometheus.MustRegister(opsQueued)
+
+	// Increase a value using compact (but order-sensitive!) WithLabelValues().
+	opsQueued.WithLabelValues("bob", "put").Add(4)
+	// Increase a value with a map using WithLabels. More verbose, but order
+	// doesn't matter anymore.
+	opsQueued.With(prometheus.Labels{"type": "delete", "user": "alice"}).Inc()
+}
+
+func ExampleGaugeFunc() {
+	if err := prometheus.Register(prometheus.NewGaugeFunc(
+		prometheus.GaugeOpts{
+			Subsystem: "runtime",
+			Name:      "goroutines_count",
+			Help:      "Number of goroutines that currently exist.",
+		},
+		func() float64 { return float64(runtime.NumGoroutine()) },
+	)); err == nil {
+		fmt.Println("GaugeFunc 'goroutines_count' registered.")
+	}
+	// Note that the count of goroutines is a gauge (and not a counter) as
+	// it can go up and down.
+
+	// Output:
+	// GaugeFunc 'goroutines_count' registered.
+}
+
+func ExampleCounter() {
+	pushCounter := prometheus.NewCounter(prometheus.CounterOpts{
+		Name: "repository_pushes", // Note: No help string...
+	})
+	err := prometheus.Register(pushCounter) // ... so this will return an error.
+	if err != nil {
+		fmt.Println("Push counter couldn't be registered, no counting will happen:", err)
+		return
+	}
+
+	// Try it once more, this time with a help string.
+	pushCounter = prometheus.NewCounter(prometheus.CounterOpts{
+		Name: "repository_pushes",
+		Help: "Number of pushes to external repository.",
+	})
+	err = prometheus.Register(pushCounter)
+	if err != nil {
+		fmt.Println("Push counter couldn't be registered AGAIN, no counting will happen:", err)
+		return
+	}
+
+	pushComplete := make(chan struct{})
+	// TODO: Start a goroutine that performs repository pushes and reports
+	// each completion via the channel.
+	for _ = range pushComplete {
+		pushCounter.Inc()
+	}
+	// Output:
+	// Push counter couldn't be registered, no counting will happen: descriptor Desc{fqName: "repository_pushes", help: "", constLabels: {}, variableLabels: []} is invalid: empty help string
+}
+
+func ExampleCounterVec() {
+	binaryVersion := flag.String("environment", "test", "Execution environment: test, staging, production.")
+	flag.Parse()
+
+	httpReqs := prometheus.NewCounterVec(
+		prometheus.CounterOpts{
+			Name:        "http_requests_total",
+			Help:        "How many HTTP requests processed, partitioned by status code and http method.",
+			ConstLabels: prometheus.Labels{"env": *binaryVersion},
+		},
+		[]string{"code", "method"},
+	)
+	prometheus.MustRegister(httpReqs)
+
+	httpReqs.WithLabelValues("404", "POST").Add(42)
+
+	// If you have to access the same set of labels very frequently, it
+	// might be good to retrieve the metric only once and keep a handle to
+	// it. But beware of deletion of that metric, see below!
+	m := httpReqs.WithLabelValues("200", "GET")
+	for i := 0; i < 1000000; i++ {
+		m.Inc()
+	}
+	// Delete a metric from the vector. If you have previously kept a handle
+	// to that metric (as above), future updates via that handle will go
+	// unseen (even if you re-create a metric with the same label set
+	// later).
+	httpReqs.DeleteLabelValues("200", "GET")
+	// Same thing with the more verbose Labels syntax.
+	httpReqs.Delete(prometheus.Labels{"method": "GET", "code": "200"})
+}
+
+func ExampleInstrumentHandler() {
+	// Handle the "/doc" endpoint with the standard http.FileServer handler.
+	// By wrapping the handler with InstrumentHandler, request count,
+	// request and response sizes, and request latency are automatically
+	// exported to Prometheus, partitioned by HTTP status code and method
+	// and by the handler name (here "fileserver").
+	http.Handle("/doc", prometheus.InstrumentHandler(
+		"fileserver", http.FileServer(http.Dir("/usr/share/doc")),
+	))
+	// The Prometheus handler still has to be registered to handle the
+	// "/metrics" endpoint. The handler returned by prometheus.Handler() is
+	// already instrumented - with "prometheus" as the handler name. In this
+	// example, we want the handler name to be "metrics", so we instrument
+	// the uninstrumented Prometheus handler ourselves.
+	http.Handle("/metrics", prometheus.InstrumentHandler(
+		"metrics", prometheus.UninstrumentedHandler(),
+	))
+}
+
+func ExampleLabelPairSorter() {
+	labelPairs := []*dto.LabelPair{
+		&dto.LabelPair{Name: proto.String("status"), Value: proto.String("404")},
+		&dto.LabelPair{Name: proto.String("method"), Value: proto.String("get")},
+	}
+
+	sort.Sort(prometheus.LabelPairSorter(labelPairs))
+
+	fmt.Println(labelPairs)
+	// Output:
+	// [name:"method" value:"get"  name:"status" value:"404" ]
+}
+
+func ExampleRegister() {
+	// Imagine you have a worker pool and want to count the tasks completed.
+	taskCounter := prometheus.NewCounter(prometheus.CounterOpts{
+		Subsystem: "worker_pool",
+		Name:      "completed_tasks_total",
+		Help:      "Total number of tasks completed.",
+	})
+	// This will register fine.
+	if err := prometheus.Register(taskCounter); err != nil {
+		fmt.Println(err)
+	} else {
+		fmt.Println("taskCounter registered.")
+	}
+	// Don't forget to tell the HTTP server about the Prometheus handler.
+	// (In a real program, you still need to start the http server...)
+	http.Handle("/metrics", prometheus.Handler())
+
+	// Now you can start workers and give every one of them a pointer to
+	// taskCounter and let it increment it whenever it completes a task.
+	taskCounter.Inc() // This has to happen somewhere in the worker code.
+
+	// But wait, you want to see how individual workers perform. So you need
+	// a vector of counters, with one element for each worker.
+	taskCounterVec := prometheus.NewCounterVec(
+		prometheus.CounterOpts{
+			Subsystem: "worker_pool",
+			Name:      "completed_tasks_total",
+			Help:      "Total number of tasks completed.",
+		},
+		[]string{"worker_id"},
+	)
+
+	// Registering will fail because we already have a metric of that name.
+	if err := prometheus.Register(taskCounterVec); err != nil {
+		fmt.Println("taskCounterVec not registered:", err)
+	} else {
+		fmt.Println("taskCounterVec registered.")
+	}
+
+	// To fix, first unregister the old taskCounter.
+	if prometheus.Unregister(taskCounter) {
+		fmt.Println("taskCounter unregistered.")
+	}
+
+	// Try registering taskCounterVec again.
+	if err := prometheus.Register(taskCounterVec); err != nil {
+		fmt.Println("taskCounterVec not registered:", err)
+	} else {
+		fmt.Println("taskCounterVec registered.")
+	}
+	// Bummer! Still doesn't work.
+
+	// Prometheus will not allow you to ever export metrics with
+	// inconsistent help strings or label names. After unregistering, the
+	// unregistered metrics will cease to show up in the /metrics http
+	// response, but the registry still remembers that those metrics had
+	// been exported before. For this example, we will now choose a
+	// different name. (In a real program, you would obviously not export
+	// the obsolete metric in the first place.)
+	taskCounterVec = prometheus.NewCounterVec(
+		prometheus.CounterOpts{
+			Subsystem: "worker_pool",
+			Name:      "completed_tasks_by_id",
+			Help:      "Total number of tasks completed.",
+		},
+		[]string{"worker_id"},
+	)
+	if err := prometheus.Register(taskCounterVec); err != nil {
+		fmt.Println("taskCounterVec not registered:", err)
+	} else {
+		fmt.Println("taskCounterVec registered.")
+	}
+	// Finally it worked!
+
+	// The workers have to tell taskCounterVec their id to increment the
+	// right element in the metric vector.
+	taskCounterVec.WithLabelValues("42").Inc() // Code from worker 42.
+
+	// Each worker could also keep a reference to their own counter element
+	// around. Pick the counter at initialization time of the worker.
+	myCounter := taskCounterVec.WithLabelValues("42") // From worker 42 initialization code.
+	myCounter.Inc()                                   // Somewhere in the code of that worker.
+
+	// Note that something like WithLabelValues("42", "spurious arg") would
+	// panic (because you have provided too many label values). If you want
+	// to get an error instead, use GetMetricWithLabelValues(...) instead.
+	notMyCounter, err := taskCounterVec.GetMetricWithLabelValues("42", "spurious arg")
+	if err != nil {
+		fmt.Println("Worker initialization failed:", err)
+	}
+	if notMyCounter == nil {
+		fmt.Println("notMyCounter is nil.")
+	}
+
+	// A different (and somewhat tricky) approach is to use
+	// ConstLabels. ConstLabels are pairs of label names and label values
+	// that never change. You might ask what those labels are good for (and
+	// rightfully so - if they never change, they could as well be part of
+	// the metric name). There are essentially two use-cases: The first is
+	// if labels are constant throughout the lifetime of a binary execution,
+	// but they vary over time or between different instances of a running
+	// binary. The second is what we have here: Each worker creates and
+	// registers an own Counter instance where the only difference is in the
+	// value of the ConstLabels. Those Counters can all be registered
+	// because the different ConstLabel values guarantee that each worker
+	// will increment a different Counter metric.
+	counterOpts := prometheus.CounterOpts{
+		Subsystem:   "worker_pool",
+		Name:        "completed_tasks",
+		Help:        "Total number of tasks completed.",
+		ConstLabels: prometheus.Labels{"worker_id": "42"},
+	}
+	taskCounterForWorker42 := prometheus.NewCounter(counterOpts)
+	if err := prometheus.Register(taskCounterForWorker42); err != nil {
+		fmt.Println("taskCounterVForWorker42 not registered:", err)
+	} else {
+		fmt.Println("taskCounterForWorker42 registered.")
+	}
+	// Obviously, in real code, taskCounterForWorker42 would be a member
+	// variable of a worker struct, and the "42" would be retrieved with a
+	// GetId() method or something. The Counter would be created and
+	// registered in the initialization code of the worker.
+
+	// For the creation of the next Counter, we can recycle
+	// counterOpts. Just change the ConstLabels.
+	counterOpts.ConstLabels = prometheus.Labels{"worker_id": "2001"}
+	taskCounterForWorker2001 := prometheus.NewCounter(counterOpts)
+	if err := prometheus.Register(taskCounterForWorker2001); err != nil {
+		fmt.Println("taskCounterVForWorker2001 not registered:", err)
+	} else {
+		fmt.Println("taskCounterForWorker2001 registered.")
+	}
+
+	taskCounterForWorker2001.Inc()
+	taskCounterForWorker42.Inc()
+	taskCounterForWorker2001.Inc()
+
+	// Yet another approach would be to turn the workers themselves into
+	// Collectors and register them. See the Collector example for details.
+
+	// Output:
+	// taskCounter registered.
+	// taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", constLabels: {}, variableLabels: [worker_id]} has different label names or a different help string
+	// taskCounter unregistered.
+	// taskCounterVec not registered: a previously registered descriptor with the same fully-qualified name as Desc{fqName: "worker_pool_completed_tasks_total", help: "Total number of tasks completed.", constLabels: {}, variableLabels: [worker_id]} has different label names or a different help string
+	// taskCounterVec registered.
+	// Worker initialization failed: inconsistent label cardinality
+	// notMyCounter is nil.
+	// taskCounterForWorker42 registered.
+	// taskCounterForWorker2001 registered.
+}
+
+func ExampleSummary() {
+	temps := prometheus.NewSummary(prometheus.SummaryOpts{
+		Name: "pond_temperature_celsius",
+		Help: "The temperature of the frog pond.", // Sorry, we can't measure how badly it smells.
+	})
+
+	// Simulate some observations.
+	for i := 0; i < 1000; i++ {
+		temps.Observe(30 + math.Floor(120*math.Sin(float64(i)*0.1))/10)
+	}
+
+	// Just for demonstration, let's check the state of the summary by
+	// (ab)using its Write method (which is usually only used by Prometheus
+	// internally).
+	metric := &dto.Metric{}
+	temps.Write(metric)
+	fmt.Println(proto.MarshalTextString(metric))
+
+	// Output:
+	// summary: <
+	//   sample_count: 1000
+	//   sample_sum: 29969.50000000001
+	//   quantile: <
+	//     quantile: 0.5
+	//     value: 31.1
+	//   >
+	//   quantile: <
+	//     quantile: 0.9
+	//     value: 41.3
+	//   >
+	//   quantile: <
+	//     quantile: 0.99
+	//     value: 41.9
+	//   >
+	// >
+}
+
+func ExampleSummaryVec() {
+	temps := prometheus.NewSummaryVec(
+		prometheus.SummaryOpts{
+			Name: "pond_temperature_celsius",
+			Help: "The temperature of the frog pond.", // Sorry, we can't measure how badly it smells.
+		},
+		[]string{"species"},
+	)
+
+	// Simulate some observations.
+	for i := 0; i < 1000; i++ {
+		temps.WithLabelValues("litoria-caerulea").Observe(30 + math.Floor(120*math.Sin(float64(i)*0.1))/10)
+		temps.WithLabelValues("lithobates-catesbeianus").Observe(32 + math.Floor(100*math.Cos(float64(i)*0.11))/10)
+	}
+
+	// Just for demonstration, let's check the state of the summary vector
+	// by (ab)using its Collect method and the Write method of its elements
+	// (which is usually only used by Prometheus internally - code like the
+	// following will never appear in your own code).
+	metricChan := make(chan prometheus.Metric)
+	go func() {
+		defer close(metricChan)
+		temps.Collect(metricChan)
+	}()
+
+	metricStrings := []string{}
+	for metric := range metricChan {
+		dtoMetric := &dto.Metric{}
+		metric.Write(dtoMetric)
+		metricStrings = append(metricStrings, proto.MarshalTextString(dtoMetric))
+	}
+	sort.Strings(metricStrings) // For reproducible print order.
+	fmt.Println(metricStrings)
+
+	// Output:
+	// [label: <
+	//   name: "species"
+	//   value: "lithobates-catesbeianus"
+	// >
+	// summary: <
+	//   sample_count: 1000
+	//   sample_sum: 31956.100000000017
+	//   quantile: <
+	//     quantile: 0.5
+	//     value: 32.4
+	//   >
+	//   quantile: <
+	//     quantile: 0.9
+	//     value: 41.4
+	//   >
+	//   quantile: <
+	//     quantile: 0.99
+	//     value: 41.9
+	//   >
+	// >
+	//  label: <
+	//   name: "species"
+	//   value: "litoria-caerulea"
+	// >
+	// summary: <
+	//   sample_count: 1000
+	//   sample_sum: 29969.50000000001
+	//   quantile: <
+	//     quantile: 0.5
+	//     value: 31.1
+	//   >
+	//   quantile: <
+	//     quantile: 0.9
+	//     value: 41.3
+	//   >
+	//   quantile: <
+	//     quantile: 0.99
+	//     value: 41.9
+	//   >
+	// >
+	// ]
+}

+ 119 - 0
Godeps/_workspace/src/github.com/prometheus/client_golang/prometheus/expvar.go

@@ -0,0 +1,119 @@
+// Copyright 2014 The Prometheus Authors
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package prometheus
+
+import (
+	"encoding/json"
+	"expvar"
+)
+
+// ExpvarCollector collects metrics from the expvar interface. It provides a
+// quick way to expose numeric values that are already exported via expvar as
+// Prometheus metrics. Note that the data models of expvar and Prometheus are
+// fundamentally different, and that the ExpvarCollector is inherently
+// slow. Thus, the ExpvarCollector is probably great for experiments and
+// prototying, but you should seriously consider a more direct implementation of
+// Prometheus metrics for monitoring production systems.
+//
+// Use NewExpvarCollector to create new instances.
+type ExpvarCollector struct {
+	exports map[string]*Desc
+}
+
+// NewExpvarCollector returns a newly allocated ExpvarCollector that still has
+// to be registered with the Prometheus registry.
+//
+// The exports map has the following meaning:
+//
+// The keys in the map correspond to expvar keys, i.e. for every expvar key you
+// want to export as Prometheus metric, you need an entry in the exports
+// map. The descriptor mapped to each key describes how to export the expvar
+// value. It defines the name and the help string of the Prometheus metric
+// proxying the expvar value. The type will always be Untyped.
+//
+// For descriptors without variable labels, the expvar value must be a number or
+// a bool. The number is then directly exported as the Prometheus sample
+// value. (For a bool, 'false' translates to 0 and 'true' to 1). Expvar values
+// that are not numbers or bools are silently ignored.
+//
+// If the descriptor has one variable label, the expvar value must be an expvar
+// map. The keys in the expvar map become the various values of the one
+// Prometheus label. The values in the expvar map must be numbers or bools again
+// as above.
+//
+// For descriptors with more than one variable label, the expvar must be a
+// nested expvar map, i.e. where the values of the topmost map are maps again
+// etc. until a depth is reached that corresponds to the number of labels. The
+// leaves of that structure must be numbers or bools as above to serve as the
+// sample values.
+//
+// Anything that does not fit into the scheme above is silently ignored.
+func NewExpvarCollector(exports map[string]*Desc) *ExpvarCollector {
+	return &ExpvarCollector{
+		exports: exports,
+	}
+}
+
+// Describe implements Collector.
+func (e *ExpvarCollector) Describe(ch chan<- *Desc) {
+	for _, desc := range e.exports {
+		ch <- desc
+	}
+}
+
+// Collect implements Collector.
+func (e *ExpvarCollector) Collect(ch chan<- Metric) {
+	for name, desc := range e.exports {
+		var m Metric
+		expVar := expvar.Get(name)
+		if expVar == nil {
+			continue
+		}
+		var v interface{}
+		labels := make([]string, len(desc.variableLabels))
+		if err := json.Unmarshal([]byte(expVar.String()), &v); err != nil {
+			ch <- NewInvalidMetric(desc, err)
+			continue
+		}
+		var processValue func(v interface{}, i int)
+		processValue = func(v interface{}, i int) {
+			if i >= len(labels) {
+				copiedLabels := append(make([]string, 0, len(labels)), labels...)
+				switch v := v.(type) {
+				case float64:
+					m = MustNewConstMetric(desc, UntypedValue, v, copiedLabels...)
+				case bool:
+					if v {
+						m = MustNewConstMetric(desc, UntypedValue, 1, copiedLabels...)
+					} else {
+						m = MustNewConstMetric(desc, UntypedValue, 0, copiedLabels...)
+					}
+				default:
+					return
+				}
+				ch <- m
+				return
+			}
+			vm, ok := v.(map[string]interface{})
+			if !ok {
+				return
+			}
+			for lv, val := range vm {
+				labels[i] = lv
+				processValue(val, i+1)
+			}
+		}
+		processValue(v, 0)
+	}
+}

Some files were not shown because too many files changed in this diff