Browse Source

Godeps: update gRPC w/ related packages

Gyu-Ho Lee 10 years ago
parent
commit
4bb0481115
100 changed files with 6334 additions and 2402 deletions
  1. 13 16
      Godeps/Godeps.json
  2. 0 1
      Godeps/_workspace/src/github.com/bradfitz/http2/.gitignore
  3. 0 19
      Godeps/_workspace/src/github.com/bradfitz/http2/AUTHORS
  4. 0 19
      Godeps/_workspace/src/github.com/bradfitz/http2/CONTRIBUTORS
  5. 0 5
      Godeps/_workspace/src/github.com/bradfitz/http2/HACKING
  6. 0 7
      Godeps/_workspace/src/github.com/bradfitz/http2/LICENSE
  7. 0 75
      Godeps/_workspace/src/github.com/bradfitz/http2/buffer.go
  8. 0 73
      Godeps/_workspace/src/github.com/bradfitz/http2/buffer_test.go
  9. 0 5
      Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/Makefile
  10. 0 43
      Godeps/_workspace/src/github.com/bradfitz/http2/pipe.go
  11. 0 24
      Godeps/_workspace/src/github.com/bradfitz/http2/pipe_test.go
  12. 0 553
      Godeps/_workspace/src/github.com/bradfitz/http2/transport.go
  13. 0 168
      Godeps/_workspace/src/github.com/bradfitz/http2/transport_test.go
  14. 36 0
      Godeps/_workspace/src/github.com/gogo/protobuf/LICENSE
  15. 1 1
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/Makefile
  16. 109 11
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/all_test.go
  17. 33 7
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone.go
  18. 41 0
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone_test.go
  19. 51 5
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/decode.go
  20. 60 13
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/encode.go
  21. 11 1
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal.go
  22. 18 0
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal_test.go
  23. 39 1
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/extensions.go
  24. 139 0
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/extensions_test.go
  25. 367 274
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/lib.go
  26. 17 24
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/message_set.go
  27. 1 1
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/message_set_test.go
  28. 2 2
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/pointer_reflect.go
  29. 2 2
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/pointer_unsafe.go
  30. 101 1
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/properties.go
  31. 7 0
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto/proto3.pb.go
  32. 5 0
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/size_test.go
  33. 1 1
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/Makefile
  34. 620 32
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.pb.go
  35. 59 0
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.proto
  36. 67 98
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/text.go
  37. 135 94
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser.go
  38. 23 2
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser_test.go
  39. 42 3
      Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_test.go
  40. 31 0
      Godeps/_workspace/src/github.com/golang/protobuf/LICENSE
  41. 1 1
      Godeps/_workspace/src/github.com/golang/protobuf/proto/Makefile
  42. 122 12
      Godeps/_workspace/src/github.com/golang/protobuf/proto/all_test.go
  43. 33 7
      Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go
  44. 41 1
      Godeps/_workspace/src/github.com/golang/protobuf/proto/clone_test.go
  45. 49 3
      Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go
  46. 65 23
      Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go
  47. 29 9
      Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go
  48. 22 1
      Godeps/_workspace/src/github.com/golang/protobuf/proto/equal_test.go
  49. 50 4
      Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go
  50. 294 1
      Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions_test.go
  51. 396 261
      Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go
  52. 17 24
      Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go
  53. 1 1
      Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set_test.go
  54. 2 2
      Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_reflect.go
  55. 2 2
      Godeps/_workspace/src/github.com/golang/protobuf/proto/pointer_unsafe.go
  56. 125 7
      Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go
  57. 0 44
      Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/Makefile
  58. 122 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go
  59. 10 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.proto
  60. 33 1
      Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_test.go
  61. 31 2
      Godeps/_workspace/src/github.com/golang/protobuf/proto/size_test.go
  62. 1095 118
      Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata/test.pb.go
  63. 101 0
      Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata/test.proto
  64. 44 82
      Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go
  65. 135 94
      Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go
  66. 25 4
      Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser_test.go
  67. 43 5
      Godeps/_workspace/src/github.com/golang/protobuf/proto/text_test.go
  68. 1 1
      Godeps/_workspace/src/golang.org/x/net/LICENSE
  69. 22 0
      Godeps/_workspace/src/golang.org/x/net/PATENTS
  70. 1 1
      Godeps/_workspace/src/golang.org/x/net/context/context.go
  71. 2 2
      Godeps/_workspace/src/golang.org/x/net/context/context_test.go
  72. 19 0
      Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go
  73. 23 0
      Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go
  74. 140 0
      Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go
  75. 176 0
      Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp_test.go
  76. 2 0
      Godeps/_workspace/src/golang.org/x/net/http2/.gitignore
  77. 11 4
      Godeps/_workspace/src/golang.org/x/net/http2/Dockerfile
  78. 0 0
      Godeps/_workspace/src/golang.org/x/net/http2/Makefile
  79. 5 2
      Godeps/_workspace/src/golang.org/x/net/http2/README
  80. 225 0
      Godeps/_workspace/src/golang.org/x/net/http2/client_conn_pool.go
  81. 89 0
      Godeps/_workspace/src/golang.org/x/net/http2/configure_transport.go
  82. 16 4
      Godeps/_workspace/src/golang.org/x/net/http2/errors.go
  83. 0 3
      Godeps/_workspace/src/golang.org/x/net/http2/errors_test.go
  84. 60 0
      Godeps/_workspace/src/golang.org/x/net/http2/fixed_buffer.go
  85. 128 0
      Godeps/_workspace/src/golang.org/x/net/http2/fixed_buffer_test.go
  86. 3 4
      Godeps/_workspace/src/golang.org/x/net/http2/flow.go
  87. 3 4
      Godeps/_workspace/src/golang.org/x/net/http2/flow_test.go
  88. 182 26
      Godeps/_workspace/src/golang.org/x/net/http2/frame.go
  89. 157 0
      Godeps/_workspace/src/golang.org/x/net/http2/frame_test.go
  90. 11 0
      Godeps/_workspace/src/golang.org/x/net/http2/go15.go
  91. 5 4
      Godeps/_workspace/src/golang.org/x/net/http2/gotrack.go
  92. 3 3
      Godeps/_workspace/src/golang.org/x/net/http2/gotrack_test.go
  93. 0 0
      Godeps/_workspace/src/golang.org/x/net/http2/h2demo/.gitignore
  94. 8 0
      Godeps/_workspace/src/golang.org/x/net/http2/h2demo/Makefile
  95. 0 0
      Godeps/_workspace/src/golang.org/x/net/http2/h2demo/README
  96. 78 32
      Godeps/_workspace/src/golang.org/x/net/http2/h2demo/h2demo.go
  97. 45 22
      Godeps/_workspace/src/golang.org/x/net/http2/h2demo/launch.go
  98. 0 0
      Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.key
  99. 0 0
      Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.pem
  100. 0 0
      Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.srl

+ 13 - 16
Godeps/Godeps.json

@@ -27,10 +27,6 @@
 			"Comment": "v1.1.0-19-g0b00eff",
 			"Comment": "v1.1.0-19-g0b00eff",
 			"Rev": "0b00effdd7a8270ebd91c24297e51643e370dd52"
 			"Rev": "0b00effdd7a8270ebd91c24297e51643e370dd52"
 		},
 		},
-		{
-			"ImportPath": "github.com/bradfitz/http2",
-			"Rev": "3e36af6d3af0e56fa3da71099f864933dea3d9fb"
-		},
 		{
 		{
 			"ImportPath": "github.com/cheggaaa/pb",
 			"ImportPath": "github.com/cheggaaa/pb",
 			"Rev": "da1f27ad1d9509b16f65f52fd9d8138b0f2dc7b2"
 			"Rev": "da1f27ad1d9509b16f65f52fd9d8138b0f2dc7b2"
@@ -74,7 +70,8 @@
 		},
 		},
 		{
 		{
 			"ImportPath": "github.com/gogo/protobuf/proto",
 			"ImportPath": "github.com/gogo/protobuf/proto",
-			"Rev": "64f27bf06efee53589314a6e5a4af34cdd85adf6"
+			"Comment": "v0.1-118-ge8904f5",
+			"Rev": "e8904f58e872a473a5b91bc9bf3377d223555263"
 		},
 		},
 		{
 		{
 			"ImportPath": "github.com/golang/glog",
 			"ImportPath": "github.com/golang/glog",
@@ -82,7 +79,7 @@
 		},
 		},
 		{
 		{
 			"ImportPath": "github.com/golang/protobuf/proto",
 			"ImportPath": "github.com/golang/protobuf/proto",
-			"Rev": "5677a0e3d5e89854c9974e1256839ee23f8233ca"
+			"Rev": "6aaa8d47701fa6cf07e914ec01fde3d4a1fe79c3"
 		},
 		},
 		{
 		{
 			"ImportPath": "github.com/google/btree",
 			"ImportPath": "github.com/google/btree",
@@ -178,27 +175,27 @@
 		},
 		},
 		{
 		{
 			"ImportPath": "golang.org/x/net/context",
 			"ImportPath": "golang.org/x/net/context",
-			"Rev": "7dbad50ab5b31073856416cdcfeb2796d682f844"
+			"Rev": "04b9de9b512f58addf28c9853d50ebef61c3953e"
 		},
 		},
 		{
 		{
-			"ImportPath": "golang.org/x/oauth2",
-			"Rev": "3046bc76d6dfd7d3707f6640f85e42d9c4050f50"
+			"ImportPath": "golang.org/x/net/http2",
+			"Rev": "04b9de9b512f58addf28c9853d50ebef61c3953e"
 		},
 		},
 		{
 		{
-			"ImportPath": "golang.org/x/sys/unix",
-			"Rev": "9c60d1c508f5134d1ca726b4641db998f2523357"
+			"ImportPath": "golang.org/x/net/internal/timeseries",
+			"Rev": "04b9de9b512f58addf28c9853d50ebef61c3953e"
 		},
 		},
 		{
 		{
-			"ImportPath": "google.golang.org/cloud/compute/metadata",
-			"Rev": "f20d6dcccb44ed49de45ae3703312cb46e627db1"
+			"ImportPath": "golang.org/x/net/trace",
+			"Rev": "04b9de9b512f58addf28c9853d50ebef61c3953e"
 		},
 		},
 		{
 		{
-			"ImportPath": "google.golang.org/cloud/internal",
-			"Rev": "f20d6dcccb44ed49de45ae3703312cb46e627db1"
+			"ImportPath": "golang.org/x/sys/unix",
+			"Rev": "9c60d1c508f5134d1ca726b4641db998f2523357"
 		},
 		},
 		{
 		{
 			"ImportPath": "google.golang.org/grpc",
 			"ImportPath": "google.golang.org/grpc",
-			"Rev": "f5ebd86be717593ab029545492c93ddf8914832b"
+			"Rev": "e29d659177655e589850ba7d3d83f7ce12ef23dd"
 		}
 		}
 	]
 	]
 }
 }

+ 0 - 1
Godeps/_workspace/src/github.com/bradfitz/http2/.gitignore

@@ -1 +0,0 @@
-*~

+ 0 - 19
Godeps/_workspace/src/github.com/bradfitz/http2/AUTHORS

@@ -1,19 +0,0 @@
-# This file is like Go's AUTHORS file: it lists Copyright holders.
-# The list of humans who have contributd is in the CONTRIBUTORS file.
-#
-# To contribute to this project, because it will eventually be folded
-# back in to Go itself, you need to submit a CLA:
-#
-#    http://golang.org/doc/contribute.html#copyright
-#
-# Then you get added to CONTRIBUTORS and you or your company get added
-# to the AUTHORS file.
-
-Blake Mizerany <blake.mizerany@gmail.com> github=bmizerany
-Daniel Morsing <daniel.morsing@gmail.com> github=DanielMorsing
-Gabriel Aszalos <gabriel.aszalos@gmail.com> github=gbbr
-Google, Inc.
-Keith Rarick <kr@xph.us> github=kr
-Matthew Keenan <tank.en.mate@gmail.com> <github@mattkeenan.net> github=mattkeenan
-Matt Layher <mdlayher@gmail.com> github=mdlayher
-Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> github=tatsuhiro-t

+ 0 - 19
Godeps/_workspace/src/github.com/bradfitz/http2/CONTRIBUTORS

@@ -1,19 +0,0 @@
-# This file is like Go's CONTRIBUTORS file: it lists humans.
-# The list of copyright holders (which may be companies) are in the AUTHORS file.
-#
-# To contribute to this project, because it will eventually be folded
-# back in to Go itself, you need to submit a CLA:
-#
-#    http://golang.org/doc/contribute.html#copyright
-#
-# Then you get added to CONTRIBUTORS and you or your company get added
-# to the AUTHORS file.
-
-Blake Mizerany <blake.mizerany@gmail.com> github=bmizerany
-Brad Fitzpatrick <bradfitz@golang.org> github=bradfitz
-Daniel Morsing <daniel.morsing@gmail.com> github=DanielMorsing
-Gabriel Aszalos <gabriel.aszalos@gmail.com> github=gbbr
-Keith Rarick <kr@xph.us> github=kr
-Matthew Keenan <tank.en.mate@gmail.com> <github@mattkeenan.net> github=mattkeenan
-Matt Layher <mdlayher@gmail.com> github=mdlayher
-Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> github=tatsuhiro-t

+ 0 - 5
Godeps/_workspace/src/github.com/bradfitz/http2/HACKING

@@ -1,5 +0,0 @@
-We only accept contributions from users who have gone through Go's
-contribution process (signed a CLA).
-
-Please acknowledge whether you have (and use the same email) if
-sending a pull request.

+ 0 - 7
Godeps/_workspace/src/github.com/bradfitz/http2/LICENSE

@@ -1,7 +0,0 @@
-Copyright 2014 Google & the Go AUTHORS
-
-Go AUTHORS are:
-See https://code.google.com/p/go/source/browse/AUTHORS
-
-Licensed under the terms of Go itself:
-https://code.google.com/p/go/source/browse/LICENSE

+ 0 - 75
Godeps/_workspace/src/github.com/bradfitz/http2/buffer.go

@@ -1,75 +0,0 @@
-// Copyright 2014 The Go Authors.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
-
-package http2
-
-import (
-	"errors"
-)
-
-// buffer is an io.ReadWriteCloser backed by a fixed size buffer.
-// It never allocates, but moves old data as new data is written.
-type buffer struct {
-	buf    []byte
-	r, w   int
-	closed bool
-	err    error // err to return to reader
-}
-
-var (
-	errReadEmpty = errors.New("read from empty buffer")
-	errWriteFull = errors.New("write on full buffer")
-)
-
-// Read copies bytes from the buffer into p.
-// It is an error to read when no data is available.
-func (b *buffer) Read(p []byte) (n int, err error) {
-	n = copy(p, b.buf[b.r:b.w])
-	b.r += n
-	if b.closed && b.r == b.w {
-		err = b.err
-	} else if b.r == b.w && n == 0 {
-		err = errReadEmpty
-	}
-	return n, err
-}
-
-// Len returns the number of bytes of the unread portion of the buffer.
-func (b *buffer) Len() int {
-	return b.w - b.r
-}
-
-// Write copies bytes from p into the buffer.
-// It is an error to write more data than the buffer can hold.
-func (b *buffer) Write(p []byte) (n int, err error) {
-	if b.closed {
-		return 0, errors.New("closed")
-	}
-
-	// Slide existing data to beginning.
-	if b.r > 0 && len(p) > len(b.buf)-b.w {
-		copy(b.buf, b.buf[b.r:b.w])
-		b.w -= b.r
-		b.r = 0
-	}
-
-	// Write new data.
-	n = copy(b.buf[b.w:], p)
-	b.w += n
-	if n < len(p) {
-		err = errWriteFull
-	}
-	return n, err
-}
-
-// Close marks the buffer as closed. Future calls to Write will
-// return an error. Future calls to Read, once the buffer is
-// empty, will return err.
-func (b *buffer) Close(err error) {
-	if !b.closed {
-		b.closed = true
-		b.err = err
-	}
-}

+ 0 - 73
Godeps/_workspace/src/github.com/bradfitz/http2/buffer_test.go

@@ -1,73 +0,0 @@
-// Copyright 2014 The Go Authors.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
-
-package http2
-
-import (
-	"io"
-	"reflect"
-	"testing"
-)
-
-var bufferReadTests = []struct {
-	buf      buffer
-	read, wn int
-	werr     error
-	wp       []byte
-	wbuf     buffer
-}{
-	{
-		buffer{[]byte{'a', 0}, 0, 1, false, nil},
-		5, 1, nil, []byte{'a'},
-		buffer{[]byte{'a', 0}, 1, 1, false, nil},
-	},
-	{
-		buffer{[]byte{'a', 0}, 0, 1, true, io.EOF},
-		5, 1, io.EOF, []byte{'a'},
-		buffer{[]byte{'a', 0}, 1, 1, true, io.EOF},
-	},
-	{
-		buffer{[]byte{0, 'a'}, 1, 2, false, nil},
-		5, 1, nil, []byte{'a'},
-		buffer{[]byte{0, 'a'}, 2, 2, false, nil},
-	},
-	{
-		buffer{[]byte{0, 'a'}, 1, 2, true, io.EOF},
-		5, 1, io.EOF, []byte{'a'},
-		buffer{[]byte{0, 'a'}, 2, 2, true, io.EOF},
-	},
-	{
-		buffer{[]byte{}, 0, 0, false, nil},
-		5, 0, errReadEmpty, []byte{},
-		buffer{[]byte{}, 0, 0, false, nil},
-	},
-	{
-		buffer{[]byte{}, 0, 0, true, io.EOF},
-		5, 0, io.EOF, []byte{},
-		buffer{[]byte{}, 0, 0, true, io.EOF},
-	},
-}
-
-func TestBufferRead(t *testing.T) {
-	for i, tt := range bufferReadTests {
-		read := make([]byte, tt.read)
-		n, err := tt.buf.Read(read)
-		if n != tt.wn {
-			t.Errorf("#%d: wn = %d want %d", i, n, tt.wn)
-			continue
-		}
-		if err != tt.werr {
-			t.Errorf("#%d: werr = %v want %v", i, err, tt.werr)
-			continue
-		}
-		read = read[:n]
-		if !reflect.DeepEqual(read, tt.wp) {
-			t.Errorf("#%d: read = %+v want %+v", i, read, tt.wp)
-		}
-		if !reflect.DeepEqual(tt.buf, tt.wbuf) {
-			t.Errorf("#%d: buf = %+v want %+v", i, tt.buf, tt.wbuf)
-		}
-	}
-}

+ 0 - 5
Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/Makefile

@@ -1,5 +0,0 @@
-h2demo.linux: h2demo.go
-	GOOS=linux go build --tags=h2demo -o h2demo.linux .
-
-upload: h2demo.linux
-	cat h2demo.linux | go run launch.go --write_object=http2-demo-server-tls/h2demo --write_object_is_public

+ 0 - 43
Godeps/_workspace/src/github.com/bradfitz/http2/pipe.go

@@ -1,43 +0,0 @@
-// Copyright 2014 The Go Authors.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
-
-package http2
-
-import (
-	"sync"
-)
-
-type pipe struct {
-	b buffer
-	c sync.Cond
-	m sync.Mutex
-}
-
-// Read waits until data is available and copies bytes
-// from the buffer into p.
-func (r *pipe) Read(p []byte) (n int, err error) {
-	r.c.L.Lock()
-	defer r.c.L.Unlock()
-	for r.b.Len() == 0 && !r.b.closed {
-		r.c.Wait()
-	}
-	return r.b.Read(p)
-}
-
-// Write copies bytes from p into the buffer and wakes a reader.
-// It is an error to write more data than the buffer can hold.
-func (w *pipe) Write(p []byte) (n int, err error) {
-	w.c.L.Lock()
-	defer w.c.L.Unlock()
-	defer w.c.Signal()
-	return w.b.Write(p)
-}
-
-func (c *pipe) Close(err error) {
-	c.c.L.Lock()
-	defer c.c.L.Unlock()
-	defer c.c.Signal()
-	c.b.Close(err)
-}

+ 0 - 24
Godeps/_workspace/src/github.com/bradfitz/http2/pipe_test.go

@@ -1,24 +0,0 @@
-// Copyright 2014 The Go Authors.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
-
-package http2
-
-import (
-	"errors"
-	"testing"
-)
-
-func TestPipeClose(t *testing.T) {
-	var p pipe
-	p.c.L = &p.m
-	a := errors.New("a")
-	b := errors.New("b")
-	p.Close(a)
-	p.Close(b)
-	_, err := p.Read(make([]byte, 1))
-	if err != a {
-		t.Errorf("err = %v want %v", err, a)
-	}
-}

+ 0 - 553
Godeps/_workspace/src/github.com/bradfitz/http2/transport.go

@@ -1,553 +0,0 @@
-// Copyright 2015 The Go Authors.
-// See https://go.googlesource.com/go/+/master/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://go.googlesource.com/go/+/master/LICENSE
-
-package http2
-
-import (
-	"bufio"
-	"bytes"
-	"crypto/tls"
-	"errors"
-	"fmt"
-	"io"
-	"log"
-	"net"
-	"net/http"
-	"strconv"
-	"strings"
-	"sync"
-
-	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/bradfitz/http2/hpack"
-)
-
-type Transport struct {
-	Fallback http.RoundTripper
-
-	// TODO: remove this and make more general with a TLS dial hook, like http
-	InsecureTLSDial bool
-
-	connMu sync.Mutex
-	conns  map[string][]*clientConn // key is host:port
-}
-
-type clientConn struct {
-	t        *Transport
-	tconn    *tls.Conn
-	tlsState *tls.ConnectionState
-	connKey  []string // key(s) this connection is cached in, in t.conns
-
-	readerDone chan struct{} // closed on error
-	readerErr  error         // set before readerDone is closed
-	hdec       *hpack.Decoder
-	nextRes    *http.Response
-
-	mu           sync.Mutex
-	closed       bool
-	goAway       *GoAwayFrame // if non-nil, the GoAwayFrame we received
-	streams      map[uint32]*clientStream
-	nextStreamID uint32
-	bw           *bufio.Writer
-	werr         error // first write error that has occurred
-	br           *bufio.Reader
-	fr           *Framer
-	// Settings from peer:
-	maxFrameSize         uint32
-	maxConcurrentStreams uint32
-	initialWindowSize    uint32
-	hbuf                 bytes.Buffer // HPACK encoder writes into this
-	henc                 *hpack.Encoder
-}
-
-type clientStream struct {
-	ID   uint32
-	resc chan resAndError
-	pw   *io.PipeWriter
-	pr   *io.PipeReader
-}
-
-type stickyErrWriter struct {
-	w   io.Writer
-	err *error
-}
-
-func (sew stickyErrWriter) Write(p []byte) (n int, err error) {
-	if *sew.err != nil {
-		return 0, *sew.err
-	}
-	n, err = sew.w.Write(p)
-	*sew.err = err
-	return
-}
-
-func (t *Transport) RoundTrip(req *http.Request) (*http.Response, error) {
-	if req.URL.Scheme != "https" {
-		if t.Fallback == nil {
-			return nil, errors.New("http2: unsupported scheme and no Fallback")
-		}
-		return t.Fallback.RoundTrip(req)
-	}
-
-	host, port, err := net.SplitHostPort(req.URL.Host)
-	if err != nil {
-		host = req.URL.Host
-		port = "443"
-	}
-
-	for {
-		cc, err := t.getClientConn(host, port)
-		if err != nil {
-			return nil, err
-		}
-		res, err := cc.roundTrip(req)
-		if shouldRetryRequest(err) { // TODO: or clientconn is overloaded (too many outstanding requests)?
-			continue
-		}
-		if err != nil {
-			return nil, err
-		}
-		return res, nil
-	}
-}
-
-// CloseIdleConnections closes any connections which were previously
-// connected from previous requests but are now sitting idle.
-// It does not interrupt any connections currently in use.
-func (t *Transport) CloseIdleConnections() {
-	t.connMu.Lock()
-	defer t.connMu.Unlock()
-	for _, vv := range t.conns {
-		for _, cc := range vv {
-			cc.closeIfIdle()
-		}
-	}
-}
-
-var errClientConnClosed = errors.New("http2: client conn is closed")
-
-func shouldRetryRequest(err error) bool {
-	// TODO: or GOAWAY graceful shutdown stuff
-	return err == errClientConnClosed
-}
-
-func (t *Transport) removeClientConn(cc *clientConn) {
-	t.connMu.Lock()
-	defer t.connMu.Unlock()
-	for _, key := range cc.connKey {
-		vv, ok := t.conns[key]
-		if !ok {
-			continue
-		}
-		newList := filterOutClientConn(vv, cc)
-		if len(newList) > 0 {
-			t.conns[key] = newList
-		} else {
-			delete(t.conns, key)
-		}
-	}
-}
-
-func filterOutClientConn(in []*clientConn, exclude *clientConn) []*clientConn {
-	out := in[:0]
-	for _, v := range in {
-		if v != exclude {
-			out = append(out, v)
-		}
-	}
-	return out
-}
-
-func (t *Transport) getClientConn(host, port string) (*clientConn, error) {
-	t.connMu.Lock()
-	defer t.connMu.Unlock()
-
-	key := net.JoinHostPort(host, port)
-
-	for _, cc := range t.conns[key] {
-		if cc.canTakeNewRequest() {
-			return cc, nil
-		}
-	}
-	if t.conns == nil {
-		t.conns = make(map[string][]*clientConn)
-	}
-	cc, err := t.newClientConn(host, port, key)
-	if err != nil {
-		return nil, err
-	}
-	t.conns[key] = append(t.conns[key], cc)
-	return cc, nil
-}
-
-func (t *Transport) newClientConn(host, port, key string) (*clientConn, error) {
-	cfg := &tls.Config{
-		ServerName:         host,
-		NextProtos:         []string{NextProtoTLS},
-		InsecureSkipVerify: t.InsecureTLSDial,
-	}
-	tconn, err := tls.Dial("tcp", host+":"+port, cfg)
-	if err != nil {
-		return nil, err
-	}
-	if err := tconn.Handshake(); err != nil {
-		return nil, err
-	}
-	if !t.InsecureTLSDial {
-		if err := tconn.VerifyHostname(cfg.ServerName); err != nil {
-			return nil, err
-		}
-	}
-	state := tconn.ConnectionState()
-	if p := state.NegotiatedProtocol; p != NextProtoTLS {
-		// TODO(bradfitz): fall back to Fallback
-		return nil, fmt.Errorf("bad protocol: %v", p)
-	}
-	if !state.NegotiatedProtocolIsMutual {
-		return nil, errors.New("could not negotiate protocol mutually")
-	}
-	if _, err := tconn.Write(clientPreface); err != nil {
-		return nil, err
-	}
-
-	cc := &clientConn{
-		t:                    t,
-		tconn:                tconn,
-		connKey:              []string{key}, // TODO: cert's validated hostnames too
-		tlsState:             &state,
-		readerDone:           make(chan struct{}),
-		nextStreamID:         1,
-		maxFrameSize:         16 << 10, // spec default
-		initialWindowSize:    65535,    // spec default
-		maxConcurrentStreams: 1000,     // "infinite", per spec. 1000 seems good enough.
-		streams:              make(map[uint32]*clientStream),
-	}
-	cc.bw = bufio.NewWriter(stickyErrWriter{tconn, &cc.werr})
-	cc.br = bufio.NewReader(tconn)
-	cc.fr = NewFramer(cc.bw, cc.br)
-	cc.henc = hpack.NewEncoder(&cc.hbuf)
-
-	cc.fr.WriteSettings()
-	// TODO: re-send more conn-level flow control tokens when server uses all these.
-	cc.fr.WriteWindowUpdate(0, 1<<30) // um, 0x7fffffff doesn't work to Google? it hangs?
-	cc.bw.Flush()
-	if cc.werr != nil {
-		return nil, cc.werr
-	}
-
-	// Read the obligatory SETTINGS frame
-	f, err := cc.fr.ReadFrame()
-	if err != nil {
-		return nil, err
-	}
-	sf, ok := f.(*SettingsFrame)
-	if !ok {
-		return nil, fmt.Errorf("expected settings frame, got: %T", f)
-	}
-	cc.fr.WriteSettingsAck()
-	cc.bw.Flush()
-
-	sf.ForeachSetting(func(s Setting) error {
-		switch s.ID {
-		case SettingMaxFrameSize:
-			cc.maxFrameSize = s.Val
-		case SettingMaxConcurrentStreams:
-			cc.maxConcurrentStreams = s.Val
-		case SettingInitialWindowSize:
-			cc.initialWindowSize = s.Val
-		default:
-			// TODO(bradfitz): handle more
-			log.Printf("Unhandled Setting: %v", s)
-		}
-		return nil
-	})
-	// TODO: figure out henc size
-	cc.hdec = hpack.NewDecoder(initialHeaderTableSize, cc.onNewHeaderField)
-
-	go cc.readLoop()
-	return cc, nil
-}
-
-func (cc *clientConn) setGoAway(f *GoAwayFrame) {
-	cc.mu.Lock()
-	defer cc.mu.Unlock()
-	cc.goAway = f
-}
-
-func (cc *clientConn) canTakeNewRequest() bool {
-	cc.mu.Lock()
-	defer cc.mu.Unlock()
-	return cc.goAway == nil &&
-		int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams) &&
-		cc.nextStreamID < 2147483647
-}
-
-func (cc *clientConn) closeIfIdle() {
-	cc.mu.Lock()
-	if len(cc.streams) > 0 {
-		cc.mu.Unlock()
-		return
-	}
-	cc.closed = true
-	// TODO: do clients send GOAWAY too? maybe? Just Close:
-	cc.mu.Unlock()
-
-	cc.tconn.Close()
-}
-
-func (cc *clientConn) roundTrip(req *http.Request) (*http.Response, error) {
-	cc.mu.Lock()
-
-	if cc.closed {
-		cc.mu.Unlock()
-		return nil, errClientConnClosed
-	}
-
-	cs := cc.newStream()
-	hasBody := false // TODO
-
-	// we send: HEADERS[+CONTINUATION] + (DATA?)
-	hdrs := cc.encodeHeaders(req)
-	first := true
-	for len(hdrs) > 0 {
-		chunk := hdrs
-		if len(chunk) > int(cc.maxFrameSize) {
-			chunk = chunk[:cc.maxFrameSize]
-		}
-		hdrs = hdrs[len(chunk):]
-		endHeaders := len(hdrs) == 0
-		if first {
-			cc.fr.WriteHeaders(HeadersFrameParam{
-				StreamID:      cs.ID,
-				BlockFragment: chunk,
-				EndStream:     !hasBody,
-				EndHeaders:    endHeaders,
-			})
-			first = false
-		} else {
-			cc.fr.WriteContinuation(cs.ID, endHeaders, chunk)
-		}
-	}
-	cc.bw.Flush()
-	werr := cc.werr
-	cc.mu.Unlock()
-
-	if hasBody {
-		// TODO: write data. and it should probably be interleaved:
-		//   go ... io.Copy(dataFrameWriter{cc, cs, ...}, req.Body) ... etc
-	}
-
-	if werr != nil {
-		return nil, werr
-	}
-
-	re := <-cs.resc
-	if re.err != nil {
-		return nil, re.err
-	}
-	res := re.res
-	res.Request = req
-	res.TLS = cc.tlsState
-	return res, nil
-}
-
-// requires cc.mu be held.
-func (cc *clientConn) encodeHeaders(req *http.Request) []byte {
-	cc.hbuf.Reset()
-
-	// TODO(bradfitz): figure out :authority-vs-Host stuff between http2 and Go
-	host := req.Host
-	if host == "" {
-		host = req.URL.Host
-	}
-
-	path := req.URL.Path
-	if path == "" {
-		path = "/"
-	}
-
-	cc.writeHeader(":authority", host) // probably not right for all sites
-	cc.writeHeader(":method", req.Method)
-	cc.writeHeader(":path", path)
-	cc.writeHeader(":scheme", "https")
-
-	for k, vv := range req.Header {
-		lowKey := strings.ToLower(k)
-		if lowKey == "host" {
-			continue
-		}
-		for _, v := range vv {
-			cc.writeHeader(lowKey, v)
-		}
-	}
-	return cc.hbuf.Bytes()
-}
-
-func (cc *clientConn) writeHeader(name, value string) {
-	log.Printf("sending %q = %q", name, value)
-	cc.henc.WriteField(hpack.HeaderField{Name: name, Value: value})
-}
-
-type resAndError struct {
-	res *http.Response
-	err error
-}
-
-// requires cc.mu be held.
-func (cc *clientConn) newStream() *clientStream {
-	cs := &clientStream{
-		ID:   cc.nextStreamID,
-		resc: make(chan resAndError, 1),
-	}
-	cc.nextStreamID += 2
-	cc.streams[cs.ID] = cs
-	return cs
-}
-
-func (cc *clientConn) streamByID(id uint32, andRemove bool) *clientStream {
-	cc.mu.Lock()
-	defer cc.mu.Unlock()
-	cs := cc.streams[id]
-	if andRemove {
-		delete(cc.streams, id)
-	}
-	return cs
-}
-
-// runs in its own goroutine.
-func (cc *clientConn) readLoop() {
-	defer cc.t.removeClientConn(cc)
-	defer close(cc.readerDone)
-
-	activeRes := map[uint32]*clientStream{} // keyed by streamID
-	// Close any response bodies if the server closes prematurely.
-	// TODO: also do this if we've written the headers but not
-	// gotten a response yet.
-	defer func() {
-		err := cc.readerErr
-		if err == io.EOF {
-			err = io.ErrUnexpectedEOF
-		}
-		for _, cs := range activeRes {
-			cs.pw.CloseWithError(err)
-		}
-	}()
-
-	// continueStreamID is the stream ID we're waiting for
-	// continuation frames for.
-	var continueStreamID uint32
-
-	for {
-		f, err := cc.fr.ReadFrame()
-		if err != nil {
-			cc.readerErr = err
-			return
-		}
-		log.Printf("Transport received %v: %#v", f.Header(), f)
-
-		streamID := f.Header().StreamID
-
-		_, isContinue := f.(*ContinuationFrame)
-		if isContinue {
-			if streamID != continueStreamID {
-				log.Printf("Protocol violation: got CONTINUATION with id %d; want %d", streamID, continueStreamID)
-				cc.readerErr = ConnectionError(ErrCodeProtocol)
-				return
-			}
-		} else if continueStreamID != 0 {
-			// Continue frames need to be adjacent in the stream
-			// and we were in the middle of headers.
-			log.Printf("Protocol violation: got %T for stream %d, want CONTINUATION for %d", f, streamID, continueStreamID)
-			cc.readerErr = ConnectionError(ErrCodeProtocol)
-			return
-		}
-
-		if streamID%2 == 0 {
-			// Ignore streams pushed from the server for now.
-			// These always have an even stream id.
-			continue
-		}
-		streamEnded := false
-		if ff, ok := f.(streamEnder); ok {
-			streamEnded = ff.StreamEnded()
-		}
-
-		cs := cc.streamByID(streamID, streamEnded)
-		if cs == nil {
-			log.Printf("Received frame for untracked stream ID %d", streamID)
-			continue
-		}
-
-		switch f := f.(type) {
-		case *HeadersFrame:
-			cc.nextRes = &http.Response{
-				Proto:      "HTTP/2.0",
-				ProtoMajor: 2,
-				Header:     make(http.Header),
-			}
-			cs.pr, cs.pw = io.Pipe()
-			cc.hdec.Write(f.HeaderBlockFragment())
-		case *ContinuationFrame:
-			cc.hdec.Write(f.HeaderBlockFragment())
-		case *DataFrame:
-			log.Printf("DATA: %q", f.Data())
-			cs.pw.Write(f.Data())
-		case *GoAwayFrame:
-			cc.t.removeClientConn(cc)
-			if f.ErrCode != 0 {
-				// TODO: deal with GOAWAY more. particularly the error code
-				log.Printf("transport got GOAWAY with error code = %v", f.ErrCode)
-			}
-			cc.setGoAway(f)
-		default:
-			log.Printf("Transport: unhandled response frame type %T", f)
-		}
-		headersEnded := false
-		if he, ok := f.(headersEnder); ok {
-			headersEnded = he.HeadersEnded()
-			if headersEnded {
-				continueStreamID = 0
-			} else {
-				continueStreamID = streamID
-			}
-		}
-
-		if streamEnded {
-			cs.pw.Close()
-			delete(activeRes, streamID)
-		}
-		if headersEnded {
-			if cs == nil {
-				panic("couldn't find stream") // TODO be graceful
-			}
-			// TODO: set the Body to one which notes the
-			// Close and also sends the server a
-			// RST_STREAM
-			cc.nextRes.Body = cs.pr
-			res := cc.nextRes
-			activeRes[streamID] = cs
-			cs.resc <- resAndError{res: res}
-		}
-	}
-}
-
-func (cc *clientConn) onNewHeaderField(f hpack.HeaderField) {
-	// TODO: verifiy pseudo headers come before non-pseudo headers
-	// TODO: verifiy the status is set
-	log.Printf("Header field: %+v", f)
-	if f.Name == ":status" {
-		code, err := strconv.Atoi(f.Value)
-		if err != nil {
-			panic("TODO: be graceful")
-		}
-		cc.nextRes.Status = f.Value + " " + http.StatusText(code)
-		cc.nextRes.StatusCode = code
-		return
-	}
-	if strings.HasPrefix(f.Name, ":") {
-		// "Endpoints MUST NOT generate pseudo-header fields other than those defined in this document."
-		// TODO: treat as invalid?
-		return
-	}
-	cc.nextRes.Header.Add(http.CanonicalHeaderKey(f.Name), f.Value)
-}

+ 0 - 168
Godeps/_workspace/src/github.com/bradfitz/http2/transport_test.go

@@ -1,168 +0,0 @@
-// Copyright 2015 The Go Authors.
-// See https://go.googlesource.com/go/+/master/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://go.googlesource.com/go/+/master/LICENSE
-
-package http2
-
-import (
-	"flag"
-	"io"
-	"io/ioutil"
-	"net/http"
-	"os"
-	"reflect"
-	"strings"
-	"testing"
-	"time"
-)
-
-var (
-	extNet        = flag.Bool("extnet", false, "do external network tests")
-	transportHost = flag.String("transporthost", "http2.golang.org", "hostname to use for TestTransport")
-	insecure      = flag.Bool("insecure", false, "insecure TLS dials")
-)
-
-func TestTransportExternal(t *testing.T) {
-	if !*extNet {
-		t.Skip("skipping external network test")
-	}
-	req, _ := http.NewRequest("GET", "https://"+*transportHost+"/", nil)
-	rt := &Transport{
-		InsecureTLSDial: *insecure,
-	}
-	res, err := rt.RoundTrip(req)
-	if err != nil {
-		t.Fatalf("%v", err)
-	}
-	res.Write(os.Stdout)
-}
-
-func TestTransport(t *testing.T) {
-	const body = "sup"
-	st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
-		io.WriteString(w, body)
-	})
-	defer st.Close()
-
-	tr := &Transport{InsecureTLSDial: true}
-	defer tr.CloseIdleConnections()
-
-	req, err := http.NewRequest("GET", st.ts.URL, nil)
-	if err != nil {
-		t.Fatal(err)
-	}
-	res, err := tr.RoundTrip(req)
-	if err != nil {
-		t.Fatal(err)
-	}
-	defer res.Body.Close()
-
-	t.Logf("Got res: %+v", res)
-	if g, w := res.StatusCode, 200; g != w {
-		t.Errorf("StatusCode = %v; want %v", g, w)
-	}
-	if g, w := res.Status, "200 OK"; g != w {
-		t.Errorf("Status = %q; want %q", g, w)
-	}
-	wantHeader := http.Header{
-		"Content-Length": []string{"3"},
-		"Content-Type":   []string{"text/plain; charset=utf-8"},
-	}
-	if !reflect.DeepEqual(res.Header, wantHeader) {
-		t.Errorf("res Header = %v; want %v", res.Header, wantHeader)
-	}
-	if res.Request != req {
-		t.Errorf("Response.Request = %p; want %p", res.Request, req)
-	}
-	if res.TLS == nil {
-		t.Errorf("Response.TLS = nil; want non-nil", res.TLS)
-	}
-	slurp, err := ioutil.ReadAll(res.Body)
-	if err != nil {
-		t.Error("Body read: %v", err)
-	} else if string(slurp) != body {
-		t.Errorf("Body = %q; want %q", slurp, body)
-	}
-
-}
-
-func TestTransportReusesConns(t *testing.T) {
-	st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
-		io.WriteString(w, r.RemoteAddr)
-	}, optOnlyServer)
-	defer st.Close()
-	tr := &Transport{InsecureTLSDial: true}
-	defer tr.CloseIdleConnections()
-	get := func() string {
-		req, err := http.NewRequest("GET", st.ts.URL, nil)
-		if err != nil {
-			t.Fatal(err)
-		}
-		res, err := tr.RoundTrip(req)
-		if err != nil {
-			t.Fatal(err)
-		}
-		defer res.Body.Close()
-		slurp, err := ioutil.ReadAll(res.Body)
-		if err != nil {
-			t.Fatalf("Body read: %v", err)
-		}
-		addr := strings.TrimSpace(string(slurp))
-		if addr == "" {
-			t.Fatalf("didn't get an addr in response")
-		}
-		return addr
-	}
-	first := get()
-	second := get()
-	if first != second {
-		t.Errorf("first and second responses were on different connections: %q vs %q", first, second)
-	}
-}
-
-func TestTransportAbortClosesPipes(t *testing.T) {
-	shutdown := make(chan struct{})
-	st := newServerTester(t,
-		func(w http.ResponseWriter, r *http.Request) {
-			w.(http.Flusher).Flush()
-			<-shutdown
-		},
-		optOnlyServer,
-	)
-	defer st.Close()
-	defer close(shutdown) // we must shutdown before st.Close() to avoid hanging
-
-	done := make(chan struct{})
-	requestMade := make(chan struct{})
-	go func() {
-		defer close(done)
-		tr := &Transport{
-			InsecureTLSDial: true,
-		}
-		req, err := http.NewRequest("GET", st.ts.URL, nil)
-		if err != nil {
-			t.Fatal(err)
-		}
-		res, err := tr.RoundTrip(req)
-		if err != nil {
-			t.Fatal(err)
-		}
-		defer res.Body.Close()
-		close(requestMade)
-		_, err = ioutil.ReadAll(res.Body)
-		if err == nil {
-			t.Error("expected error from res.Body.Read")
-		}
-	}()
-
-	<-requestMade
-	// Now force the serve loop to end, via closing the connection.
-	st.closeConn()
-	// deadlock? that's a bug.
-	select {
-	case <-done:
-	case <-time.After(3 * time.Second):
-		t.Fatal("timeout")
-	}
-}

+ 36 - 0
Godeps/_workspace/src/github.com/gogo/protobuf/LICENSE

@@ -0,0 +1,36 @@
+Extensions for Protocol Buffers to create more go like structures.
+
+Copyright (c) 2013, Vastech SA (PTY) LTD. All rights reserved.
+http://github.com/gogo/protobuf/gogoproto
+
+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.
+

+ 1 - 1
Godeps/_workspace/src/github.com/gogo/protobuf/proto/Makefile

@@ -39,5 +39,5 @@ test: install generate-test-pbs
 generate-test-pbs:
 generate-test-pbs:
 	make install
 	make install
 	make -C testdata
 	make -C testdata
-	protoc-min-version --version="3.0.0" --proto_path=.:../../../../ proto3_proto/proto3.proto
+	protoc-min-version --version="3.0.0" --proto_path=.:../../../../ --gogo_out=. proto3_proto/proto3.proto
 	make
 	make

+ 109 - 11
Godeps/_workspace/src/github.com/gogo/protobuf/proto/all_test.go

@@ -401,17 +401,18 @@ type fakeMarshaler struct {
 	err error
 	err error
 }
 }
 
 
-func (f fakeMarshaler) Marshal() ([]byte, error) {
-	return f.b, f.err
-}
+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()                   {}
 
 
-func (f fakeMarshaler) String() string {
-	return fmt.Sprintf("Bytes: %v Error: %v", f.b, f.err)
+type msgWithFakeMarshaler struct {
+	M *fakeMarshaler `protobuf:"bytes,1,opt,name=fake"`
 }
 }
 
 
-func (f fakeMarshaler) ProtoMessage() {}
-
-func (f fakeMarshaler) Reset() {}
+func (m *msgWithFakeMarshaler) String() string { return CompactTextString(m) }
+func (m *msgWithFakeMarshaler) ProtoMessage()  {}
+func (m *msgWithFakeMarshaler) Reset()         {}
 
 
 // Simple tests for proto messages that implement the Marshaler interface.
 // Simple tests for proto messages that implement the Marshaler interface.
 func TestMarshalerEncoding(t *testing.T) {
 func TestMarshalerEncoding(t *testing.T) {
@@ -423,7 +424,7 @@ func TestMarshalerEncoding(t *testing.T) {
 	}{
 	}{
 		{
 		{
 			name: "Marshaler that fails",
 			name: "Marshaler that fails",
-			m: fakeMarshaler{
+			m: &fakeMarshaler{
 				err: errors.New("some marshal err"),
 				err: errors.New("some marshal err"),
 				b:   []byte{5, 6, 7},
 				b:   []byte{5, 6, 7},
 			},
 			},
@@ -431,9 +432,25 @@ func TestMarshalerEncoding(t *testing.T) {
 			want:    nil,
 			want:    nil,
 			wantErr: errors.New("some marshal err"),
 			wantErr: errors.New("some marshal err"),
 		},
 		},
+		{
+			name: "Marshaler that fails with RequiredNotSetError",
+			m: &msgWithFakeMarshaler{
+				M: &fakeMarshaler{
+					err: &RequiredNotSetError{},
+					b:   []byte{5, 6, 7},
+				},
+			},
+			// Since there's an error that can be continued after,
+			// the buffer should be written.
+			want: []byte{
+				10, 3, // for &msgWithFakeMarshaler
+				5, 6, 7, // for &fakeMarshaler
+			},
+			wantErr: &RequiredNotSetError{},
+		},
 		{
 		{
 			name: "Marshaler that succeeds",
 			name: "Marshaler that succeeds",
-			m: fakeMarshaler{
+			m: &fakeMarshaler{
 				b: []byte{0, 1, 2, 3, 4, 127, 255},
 				b: []byte{0, 1, 2, 3, 4, 127, 255},
 			},
 			},
 			want:    []byte{0, 1, 2, 3, 4, 127, 255},
 			want:    []byte{0, 1, 2, 3, 4, 127, 255},
@@ -443,6 +460,10 @@ func TestMarshalerEncoding(t *testing.T) {
 	for _, test := range tests {
 	for _, test := range tests {
 		b := NewBuffer(nil)
 		b := NewBuffer(nil)
 		err := b.Marshal(test.m)
 		err := b.Marshal(test.m)
+		if _, ok := err.(*RequiredNotSetError); ok {
+			// We're not in package proto, so we can only assert the type in this case.
+			err = &RequiredNotSetError{}
+		}
 		if !reflect.DeepEqual(test.wantErr, err) {
 		if !reflect.DeepEqual(test.wantErr, err) {
 			t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr)
 			t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr)
 		}
 		}
@@ -1281,7 +1302,7 @@ func TestEnum(t *testing.T) {
 // We don't care what the value actually is, just as long as it doesn't crash.
 // We don't care what the value actually is, just as long as it doesn't crash.
 func TestPrintingNilEnumFields(t *testing.T) {
 func TestPrintingNilEnumFields(t *testing.T) {
 	pb := new(GoEnum)
 	pb := new(GoEnum)
-	fmt.Sprintf("%+v", pb)
+	_ = fmt.Sprintf("%+v", pb)
 }
 }
 
 
 // Verify that absent required fields cause Marshal/Unmarshal to return errors.
 // Verify that absent required fields cause Marshal/Unmarshal to return errors.
@@ -1925,6 +1946,83 @@ func TestMapFieldRoundTrips(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestMapFieldWithNil(t *testing.T) {
+	m := &MessageWithMap{
+		MsgMapping: map[int64]*FloatingPoint{
+			1: nil,
+		},
+	}
+	b, err := Marshal(m)
+	if err == nil {
+		t.Fatalf("Marshal of bad map should have failed, got these bytes: %v", b)
+	}
+}
+
+func TestOneof(t *testing.T) {
+	m := &Communique{}
+	b, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal of empty message with oneof: %v", err)
+	}
+	if len(b) != 0 {
+		t.Errorf("Marshal of empty message yielded too many bytes: %v", b)
+	}
+
+	m = &Communique{
+		Union: &Communique_Name{"Barry"},
+	}
+
+	// Round-trip.
+	b, err = Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal of message with oneof: %v", err)
+	}
+	if len(b) != 7 { // name tag/wire (1) + name len (1) + name (5)
+		t.Errorf("Incorrect marshal of message with oneof: %v", b)
+	}
+	m.Reset()
+	if err := Unmarshal(b, m); err != nil {
+		t.Fatalf("Unmarshal of message with oneof: %v", err)
+	}
+	if x, ok := m.Union.(*Communique_Name); !ok || x.Name != "Barry" {
+		t.Errorf("After round trip, Union = %+v", m.Union)
+	}
+	if name := m.GetName(); name != "Barry" {
+		t.Errorf("After round trip, GetName = %q, want %q", name, "Barry")
+	}
+
+	// Let's try with a message in the oneof.
+	m.Union = &Communique_Msg{&Strings{StringField: String("deep deep string")}}
+	b, err = Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal of message with oneof set to message: %v", err)
+	}
+	if len(b) != 20 { // msg tag/wire (1) + msg len (1) + msg (1 + 1 + 16)
+		t.Errorf("Incorrect marshal of message with oneof set to message: %v", b)
+	}
+	m.Reset()
+	if err := Unmarshal(b, m); err != nil {
+		t.Fatalf("Unmarshal of message with oneof set to message: %v", err)
+	}
+	ss, ok := m.Union.(*Communique_Msg)
+	if !ok || ss.Msg.GetStringField() != "deep deep string" {
+		t.Errorf("After round trip with oneof set to message, Union = %+v", m.Union)
+	}
+}
+
+func TestInefficientPackedBool(t *testing.T) {
+	// https://github.com/golang/protobuf/issues/76
+	inp := []byte{
+		0x12, 0x02, // 0x12 = 2<<3|2; 2 bytes
+		// Usually a bool should take a single byte,
+		// but it is permitted to be any varint.
+		0xb9, 0x30,
+	}
+	if err := Unmarshal(inp, new(MoreRepeated)); err != nil {
+		t.Error(err)
+	}
+}
+
 // Benchmarks
 // Benchmarks
 
 
 func testMsg() *GoTest {
 func testMsg() *GoTest {

+ 33 - 7
Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone.go

@@ -30,7 +30,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 // Protocol buffer deep copy and merge.
 // Protocol buffer deep copy and merge.
-// TODO: MessageSet and RawMessage.
+// TODO: RawMessage.
 
 
 package proto
 package proto
 
 
@@ -75,12 +75,13 @@ func Merge(dst, src Message) {
 }
 }
 
 
 func mergeStruct(out, in reflect.Value) {
 func mergeStruct(out, in reflect.Value) {
+	sprop := GetProperties(in.Type())
 	for i := 0; i < in.NumField(); i++ {
 	for i := 0; i < in.NumField(); i++ {
 		f := in.Type().Field(i)
 		f := in.Type().Field(i)
 		if strings.HasPrefix(f.Name, "XXX_") {
 		if strings.HasPrefix(f.Name, "XXX_") {
 			continue
 			continue
 		}
 		}
-		mergeAny(out.Field(i), in.Field(i))
+		mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
 	}
 	}
 
 
 	if emIn, ok := in.Addr().Interface().(extensionsMap); ok {
 	if emIn, ok := in.Addr().Interface().(extensionsMap); ok {
@@ -103,7 +104,10 @@ func mergeStruct(out, in reflect.Value) {
 	}
 	}
 }
 }
 
 
-func mergeAny(out, in reflect.Value) {
+// mergeAny performs a merge between two values of the same type.
+// viaPtr indicates whether the values were indirected through a pointer (implying proto2).
+// prop is set if this is a struct field (it may be nil).
+func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {
 	if in.Type() == protoMessageType {
 	if in.Type() == protoMessageType {
 		if !in.IsNil() {
 		if !in.IsNil() {
 			if out.IsNil() {
 			if out.IsNil() {
@@ -117,7 +121,21 @@ func mergeAny(out, in reflect.Value) {
 	switch in.Kind() {
 	switch in.Kind() {
 	case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
 	case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
 		reflect.String, reflect.Uint32, reflect.Uint64:
 		reflect.String, reflect.Uint32, reflect.Uint64:
+		if !viaPtr && isProto3Zero(in) {
+			return
+		}
 		out.Set(in)
 		out.Set(in)
+	case reflect.Interface:
+		// Probably a oneof field; copy non-nil values.
+		if in.IsNil() {
+			return
+		}
+		// Allocate destination if it is not set, or set to a different type.
+		// Otherwise we will merge as normal.
+		if out.IsNil() || out.Elem().Type() != in.Elem().Type() {
+			out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T)
+		}
+		mergeAny(out.Elem(), in.Elem(), false, nil)
 	case reflect.Map:
 	case reflect.Map:
 		if in.Len() == 0 {
 		if in.Len() == 0 {
 			return
 			return
@@ -132,7 +150,7 @@ func mergeAny(out, in reflect.Value) {
 			switch elemKind {
 			switch elemKind {
 			case reflect.Ptr:
 			case reflect.Ptr:
 				val = reflect.New(in.Type().Elem().Elem())
 				val = reflect.New(in.Type().Elem().Elem())
-				mergeAny(val, in.MapIndex(key))
+				mergeAny(val, in.MapIndex(key), false, nil)
 			case reflect.Slice:
 			case reflect.Slice:
 				val = in.MapIndex(key)
 				val = in.MapIndex(key)
 				val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
 				val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
@@ -148,13 +166,21 @@ func mergeAny(out, in reflect.Value) {
 		if out.IsNil() {
 		if out.IsNil() {
 			out.Set(reflect.New(in.Elem().Type()))
 			out.Set(reflect.New(in.Elem().Type()))
 		}
 		}
-		mergeAny(out.Elem(), in.Elem())
+		mergeAny(out.Elem(), in.Elem(), true, nil)
 	case reflect.Slice:
 	case reflect.Slice:
 		if in.IsNil() {
 		if in.IsNil() {
 			return
 			return
 		}
 		}
 		if in.Type().Elem().Kind() == reflect.Uint8 {
 		if in.Type().Elem().Kind() == reflect.Uint8 {
 			// []byte is a scalar bytes field, not a repeated field.
 			// []byte is a scalar bytes field, not a repeated field.
+
+			// Edge case: if this is in a proto3 message, a zero length
+			// bytes field is considered the zero value, and should not
+			// be merged.
+			if prop != nil && prop.proto3 && in.Len() == 0 {
+				return
+			}
+
 			// Make a deep copy.
 			// Make a deep copy.
 			// Append to []byte{} instead of []byte(nil) so that we never end up
 			// Append to []byte{} instead of []byte(nil) so that we never end up
 			// with a nil result.
 			// with a nil result.
@@ -172,7 +198,7 @@ func mergeAny(out, in reflect.Value) {
 		default:
 		default:
 			for i := 0; i < n; i++ {
 			for i := 0; i < n; i++ {
 				x := reflect.Indirect(reflect.New(in.Type().Elem()))
 				x := reflect.Indirect(reflect.New(in.Type().Elem()))
-				mergeAny(x, in.Index(i))
+				mergeAny(x, in.Index(i), false, nil)
 				out.Set(reflect.Append(out, x))
 				out.Set(reflect.Append(out, x))
 			}
 			}
 		}
 		}
@@ -189,7 +215,7 @@ func mergeExtension(out, in map[int32]Extension) {
 		eOut := Extension{desc: eIn.desc}
 		eOut := Extension{desc: eIn.desc}
 		if eIn.value != nil {
 		if eIn.value != nil {
 			v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
 			v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
-			mergeAny(v, reflect.ValueOf(eIn.value))
+			mergeAny(v, reflect.ValueOf(eIn.value), false, nil)
 			eOut.value = v.Interface()
 			eOut.value = v.Interface()
 		}
 		}
 		if eIn.enc != nil {
 		if eIn.enc != nil {

+ 41 - 0
Godeps/_workspace/src/github.com/gogo/protobuf/proto/clone_test.go

@@ -35,6 +35,8 @@ import (
 	"testing"
 	"testing"
 
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
+
+	proto3pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto"
 	pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata"
 	pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata"
 )
 )
 
 
@@ -213,6 +215,45 @@ var mergeTests = []struct {
 			ByteMapping: map[bool][]byte{true: []byte("wowsa")},
 			ByteMapping: map[bool][]byte{true: []byte("wowsa")},
 		},
 		},
 	},
 	},
+	// proto3 shouldn't merge zero values,
+	// in the same way that proto2 shouldn't merge nils.
+	{
+		src: &proto3pb.Message{
+			Name: "Aaron",
+			Data: []byte(""), // zero value, but not nil
+		},
+		dst: &proto3pb.Message{
+			HeightInCm: 176,
+			Data:       []byte("texas!"),
+		},
+		want: &proto3pb.Message{
+			Name:       "Aaron",
+			HeightInCm: 176,
+			Data:       []byte("texas!"),
+		},
+	},
+	// Oneof fields should merge by assignment.
+	{
+		src: &pb.Communique{
+			Union: &pb.Communique_Number{Number: 41},
+		},
+		dst: &pb.Communique{
+			Union: &pb.Communique_Name{Name: "Bobby Tables"},
+		},
+		want: &pb.Communique{
+			Union: &pb.Communique_Number{Number: 41},
+		},
+	},
+	// Oneof nil is the same as not set.
+	{
+		src: &pb.Communique{},
+		dst: &pb.Communique{
+			Union: &pb.Communique_Name{Name: "Bobby Tables"},
+		},
+		want: &pb.Communique{
+			Union: &pb.Communique_Name{Name: "Bobby Tables"},
+		},
+	},
 }
 }
 
 
 func TestMerge(t *testing.T) {
 func TestMerge(t *testing.T) {

+ 51 - 5
Godeps/_workspace/src/github.com/gogo/protobuf/proto/decode.go

@@ -46,6 +46,10 @@ import (
 // errOverflow is returned when an integer is too large to be represented.
 // errOverflow is returned when an integer is too large to be represented.
 var errOverflow = errors.New("proto: integer overflow")
 var errOverflow = errors.New("proto: integer overflow")
 
 
+// ErrInternalBadWireType is returned by generated code when an incorrect
+// wire type is encountered. It does not get returned to user code.
+var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
+
 // The fundamental decoders that interpret bytes on the wire.
 // The fundamental decoders that interpret bytes on the wire.
 // Those that take integer types all return uint64 and are
 // Those that take integer types all return uint64 and are
 // therefore of type valueDecoder.
 // therefore of type valueDecoder.
@@ -314,6 +318,24 @@ func UnmarshalMerge(buf []byte, pb Message) error {
 	return NewBuffer(buf).Unmarshal(pb)
 	return NewBuffer(buf).Unmarshal(pb)
 }
 }
 
 
+// DecodeMessage reads a count-delimited message from the Buffer.
+func (p *Buffer) DecodeMessage(pb Message) error {
+	enc, err := p.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+	return NewBuffer(enc).Unmarshal(pb)
+}
+
+// DecodeGroup reads a tag-delimited group from the Buffer.
+func (p *Buffer) DecodeGroup(pb Message) error {
+	typ, base, err := getbase(pb)
+	if err != nil {
+		return err
+	}
+	return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base)
+}
+
 // Unmarshal parses the protocol buffer representation in the
 // Unmarshal parses the protocol buffer representation in the
 // Buffer and places the decoded result in pb.  If the struct
 // 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
 // underlying pb does not match the data in the buffer, the results can be
@@ -370,11 +392,11 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
 			if prop.extendable {
 			if prop.extendable {
 				if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
 				if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
 					if err = o.skip(st, tag, wire); err == nil {
 					if err = o.skip(st, tag, wire); err == nil {
-						if ee, ok := e.(extensionsMap); ok {
+						if ee, eok := e.(extensionsMap); eok {
 							ext := ee.ExtensionMap()[int32(tag)] // may be missing
 							ext := ee.ExtensionMap()[int32(tag)] // may be missing
 							ext.enc = append(ext.enc, o.buf[oi:o.index]...)
 							ext.enc = append(ext.enc, o.buf[oi:o.index]...)
 							ee.ExtensionMap()[int32(tag)] = ext
 							ee.ExtensionMap()[int32(tag)] = ext
-						} else if ee, ok := e.(extensionsBytes); ok {
+						} else if ee, eok := e.(extensionsBytes); eok {
 							ext := ee.GetExtensions()
 							ext := ee.GetExtensions()
 							*ext = append(*ext, o.buf[oi:o.index]...)
 							*ext = append(*ext, o.buf[oi:o.index]...)
 						}
 						}
@@ -382,6 +404,20 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
 					continue
 					continue
 				}
 				}
 			}
 			}
+			// Maybe it's a oneof?
+			if prop.oneofUnmarshaler != nil {
+				m := structPointer_Interface(base, st).(Message)
+				// First return value indicates whether tag is a oneof field.
+				ok, err = prop.oneofUnmarshaler(m, tag, wire, o)
+				if err == ErrInternalBadWireType {
+					// Map the error to something more descriptive.
+					// Do the formatting here to save generated code space.
+					err = fmt.Errorf("bad wiretype for oneof field in %T", m)
+				}
+				if ok {
+					continue
+				}
+			}
 			err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
 			err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
 			continue
 			continue
 		}
 		}
@@ -566,9 +602,13 @@ func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error
 		return err
 		return err
 	}
 	}
 	nb := int(nn) // number of bytes of encoded bools
 	nb := int(nn) // number of bytes of encoded bools
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
 
 
 	y := *v
 	y := *v
-	for i := 0; i < nb; i++ {
+	for o.index < fin {
 		u, err := p.valDec(o)
 		u, err := p.valDec(o)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
@@ -680,7 +720,7 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
 	oi := o.index       // index at the end of this map entry
 	oi := o.index       // index at the end of this map entry
 	o.index -= len(raw) // move buffer back to start of 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
+	mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V
 	if mptr.Elem().IsNil() {
 	if mptr.Elem().IsNil() {
 		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
 		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
 	}
 	}
@@ -732,8 +772,14 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
 			return fmt.Errorf("proto: bad map data tag %d", raw[0])
 			return fmt.Errorf("proto: bad map data tag %d", raw[0])
 		}
 		}
 	}
 	}
+	keyelem, valelem := keyptr.Elem(), valptr.Elem()
+	if !keyelem.IsValid() || !valelem.IsValid() {
+		// We did not decode the key or the value in the map entry.
+		// Either way, it's an invalid map entry.
+		return fmt.Errorf("proto: bad map data: missing key/val")
+	}
 
 
-	v.SetMapIndex(keyptr.Elem(), valptr.Elem())
+	v.SetMapIndex(keyelem, valelem)
 	return nil
 	return nil
 }
 }
 
 

+ 60 - 13
Godeps/_workspace/src/github.com/gogo/protobuf/proto/encode.go

@@ -228,6 +228,20 @@ func Marshal(pb Message) ([]byte, error) {
 	return p.buf, err
 	return p.buf, err
 }
 }
 
 
+// EncodeMessage writes the protocol buffer to the Buffer,
+// prefixed by a varint-encoded length.
+func (p *Buffer) EncodeMessage(pb Message) error {
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return ErrNil
+	}
+	if err == nil {
+		var state errorState
+		err = p.enc_len_struct(GetProperties(t.Elem()), base, &state)
+	}
+	return err
+}
+
 // Marshal takes the protocol buffer
 // Marshal takes the protocol buffer
 // and encodes it into the wire format, writing the result to the
 // and encodes it into the wire format, writing the result to the
 // Buffer.
 // Buffer.
@@ -318,7 +332,7 @@ func size_bool(p *Properties, base structPointer) int {
 
 
 func size_proto3_bool(p *Properties, base structPointer) int {
 func size_proto3_bool(p *Properties, base structPointer) int {
 	v := *structPointer_BoolVal(base, p.field)
 	v := *structPointer_BoolVal(base, p.field)
-	if !v {
+	if !v && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	return len(p.tagcode) + 1 // each bool takes exactly one byte
 	return len(p.tagcode) + 1 // each bool takes exactly one byte
@@ -361,7 +375,7 @@ func size_int32(p *Properties, base structPointer) (n int) {
 func size_proto3_int32(p *Properties, base structPointer) (n int) {
 func size_proto3_int32(p *Properties, base structPointer) (n int) {
 	v := structPointer_Word32Val(base, p.field)
 	v := structPointer_Word32Val(base, p.field)
 	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
 	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -407,7 +421,7 @@ func size_uint32(p *Properties, base structPointer) (n int) {
 func size_proto3_uint32(p *Properties, base structPointer) (n int) {
 func size_proto3_uint32(p *Properties, base structPointer) (n int) {
 	v := structPointer_Word32Val(base, p.field)
 	v := structPointer_Word32Val(base, p.field)
 	x := word32Val_Get(v)
 	x := word32Val_Get(v)
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -452,7 +466,7 @@ func size_int64(p *Properties, base structPointer) (n int) {
 func size_proto3_int64(p *Properties, base structPointer) (n int) {
 func size_proto3_int64(p *Properties, base structPointer) (n int) {
 	v := structPointer_Word64Val(base, p.field)
 	v := structPointer_Word64Val(base, p.field)
 	x := word64Val_Get(v)
 	x := word64Val_Get(v)
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -495,7 +509,7 @@ func size_string(p *Properties, base structPointer) (n int) {
 
 
 func size_proto3_string(p *Properties, base structPointer) (n int) {
 func size_proto3_string(p *Properties, base structPointer) (n int) {
 	v := *structPointer_StringVal(base, p.field)
 	v := *structPointer_StringVal(base, p.field)
-	if v == "" {
+	if v == "" && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -529,7 +543,7 @@ func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
 		}
 		}
 		o.buf = append(o.buf, p.tagcode...)
 		o.buf = append(o.buf, p.tagcode...)
 		o.EncodeRawBytes(data)
 		o.EncodeRawBytes(data)
-		return nil
+		return state.err
 	}
 	}
 
 
 	o.buf = append(o.buf, p.tagcode...)
 	o.buf = append(o.buf, p.tagcode...)
@@ -667,7 +681,7 @@ func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error
 
 
 func size_slice_byte(p *Properties, base structPointer) (n int) {
 func size_slice_byte(p *Properties, base structPointer) (n int) {
 	s := *structPointer_Bytes(base, p.field)
 	s := *structPointer_Bytes(base, p.field)
-	if s == nil {
+	if s == nil && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -677,7 +691,7 @@ func size_slice_byte(p *Properties, base structPointer) (n int) {
 
 
 func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
 func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
 	s := *structPointer_Bytes(base, p.field)
 	s := *structPointer_Bytes(base, p.field)
-	if len(s) == 0 {
+	if len(s) == 0 && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -1084,7 +1098,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
 			repeated MapFieldEntry map_field = N;
 			repeated MapFieldEntry map_field = N;
 	*/
 	*/
 
 
-	v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
+	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
 	if v.Len() == 0 {
 	if v.Len() == 0 {
 		return nil
 		return nil
 	}
 	}
@@ -1101,11 +1115,15 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
 		return nil
 		return nil
 	}
 	}
 
 
-	keys := v.MapKeys()
-	sort.Sort(mapKeys(keys))
-	for _, key := range keys {
+	// Don't sort map keys. It is not required by the spec, and C++ doesn't do it.
+	for _, key := range v.MapKeys() {
 		val := v.MapIndex(key)
 		val := v.MapIndex(key)
 
 
+		// The only illegal map entry values are nil message pointers.
+		if val.Kind() == reflect.Ptr && val.IsNil() {
+			return errors.New("proto: map has nil element")
+		}
+
 		keycopy.Set(key)
 		keycopy.Set(key)
 		valcopy.Set(val)
 		valcopy.Set(val)
 
 
@@ -1118,7 +1136,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
 }
 }
 
 
 func size_new_map(p *Properties, base structPointer) int {
 func size_new_map(p *Properties, base structPointer) int {
-	v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
+	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
 
 
 	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
 	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
 
 
@@ -1196,6 +1214,14 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
 		}
 		}
 	}
 	}
 
 
+	// Do oneof fields.
+	if prop.oneofMarshaler != nil {
+		m := structPointer_Interface(base, prop.stype).(Message)
+		if err := prop.oneofMarshaler(m, o); err != nil {
+			return err
+		}
+	}
+
 	// Add unrecognized fields at the end.
 	// Add unrecognized fields at the end.
 	if prop.unrecField.IsValid() {
 	if prop.unrecField.IsValid() {
 		v := *structPointer_Bytes(base, prop.unrecField)
 		v := *structPointer_Bytes(base, prop.unrecField)
@@ -1221,6 +1247,27 @@ func size_struct(prop *StructProperties, base structPointer) (n int) {
 		n += len(v)
 		n += len(v)
 	}
 	}
 
 
+	// Factor in any oneof fields.
+	// TODO: This could be faster and use less reflection.
+	if prop.oneofMarshaler != nil {
+		sv := reflect.ValueOf(structPointer_Interface(base, prop.stype)).Elem()
+		for i := 0; i < prop.stype.NumField(); i++ {
+			fv := sv.Field(i)
+			if fv.Kind() != reflect.Interface || fv.IsNil() {
+				continue
+			}
+			if prop.stype.Field(i).Tag.Get("protobuf_oneof") == "" {
+				continue
+			}
+			spv := fv.Elem()         // interface -> *T
+			sv := spv.Elem()         // *T -> T
+			sf := sv.Type().Field(0) // StructField inside T
+			var prop Properties
+			prop.Init(sf.Type, "whatever", sf.Tag.Get("protobuf"), &sf)
+			n += prop.size(&prop, toStructPointer(spv))
+		}
+	}
+
 	return
 	return
 }
 }
 
 

+ 11 - 1
Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal.go

@@ -30,7 +30,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 // Protocol buffer comparison.
 // Protocol buffer comparison.
-// TODO: MessageSet.
 
 
 package proto
 package proto
 
 
@@ -154,6 +153,17 @@ func equalAny(v1, v2 reflect.Value) bool {
 		return v1.Float() == v2.Float()
 		return v1.Float() == v2.Float()
 	case reflect.Int32, reflect.Int64:
 	case reflect.Int32, reflect.Int64:
 		return v1.Int() == v2.Int()
 		return v1.Int() == v2.Int()
+	case reflect.Interface:
+		// Probably a oneof field; compare the inner values.
+		n1, n2 := v1.IsNil(), v2.IsNil()
+		if n1 || n2 {
+			return n1 == n2
+		}
+		e1, e2 := v1.Elem(), v2.Elem()
+		if e1.Type() != e2.Type() {
+			return false
+		}
+		return equalAny(e1, e2)
 	case reflect.Map:
 	case reflect.Map:
 		if v1.Len() != v2.Len() {
 		if v1.Len() != v2.Len() {
 			return false
 			return false

+ 18 - 0
Godeps/_workspace/src/github.com/gogo/protobuf/proto/equal_test.go

@@ -180,6 +180,24 @@ var EqualTests = []struct {
 		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
 		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
 		false,
 		false,
 	},
 	},
+	{
+		"oneof same",
+		&pb.Communique{Union: &pb.Communique_Number{Number: 41}},
+		&pb.Communique{Union: &pb.Communique_Number{Number: 41}},
+		true,
+	},
+	{
+		"oneof one nil",
+		&pb.Communique{Union: &pb.Communique_Number{Number: 41}},
+		&pb.Communique{},
+		false,
+	},
+	{
+		"oneof different",
+		&pb.Communique{Union: &pb.Communique_Number{Number: 41}},
+		&pb.Communique{Union: &pb.Communique_Name{Name: "Bobby Tables"}},
+		false,
+	},
 }
 }
 
 
 func TestEqual(t *testing.T) {
 func TestEqual(t *testing.T) {

+ 39 - 1
Godeps/_workspace/src/github.com/gogo/protobuf/proto/extensions.go

@@ -311,7 +311,9 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
 		emap := epb.ExtensionMap()
 		emap := epb.ExtensionMap()
 		e, ok := emap[extension.Field]
 		e, ok := emap[extension.Field]
 		if !ok {
 		if !ok {
-			return nil, ErrMissingExtension
+			// defaultExtensionValue returns the default value or
+			// ErrMissingExtension if there is no default.
+			return defaultExtensionValue(extension)
 		}
 		}
 		if e.value != nil {
 		if e.value != nil {
 			// Already decoded. Check the descriptor, though.
 			// Already decoded. Check the descriptor, though.
@@ -356,10 +358,46 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
 			}
 			}
 			o += n + l
 			o += n + l
 		}
 		}
+		return defaultExtensionValue(extension)
 	}
 	}
 	panic("unreachable")
 	panic("unreachable")
 }
 }
 
 
+// defaultExtensionValue returns the default value for extension.
+// If no default for an extension is defined ErrMissingExtension is returned.
+func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
+	t := reflect.TypeOf(extension.ExtensionType)
+	props := extensionProperties(extension)
+
+	sf, _, err := fieldDefault(t, props)
+	if err != nil {
+		return nil, err
+	}
+
+	if sf == nil || sf.value == nil {
+		// There is no default value.
+		return nil, ErrMissingExtension
+	}
+
+	if t.Kind() != reflect.Ptr {
+		// We do not need to return a Ptr, we can directly return sf.value.
+		return sf.value, nil
+	}
+
+	// We need to return an interface{} that is a pointer to sf.value.
+	value := reflect.New(t).Elem()
+	value.Set(reflect.New(value.Type().Elem()))
+	if sf.kind == reflect.Int32 {
+		// We may have an int32 or an enum, but the underlying data is int32.
+		// Since we can't set an int32 into a non int32 reflect.value directly
+		// set it as a int32.
+		value.Elem().SetInt(int64(sf.value.(int32)))
+	} else {
+		value.Elem().Set(reflect.ValueOf(sf.value))
+	}
+	return value.Interface(), nil
+}
+
 // decodeExtension decodes an extension encoded in b.
 // decodeExtension decodes an extension encoded in b.
 func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
 func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
 	o := NewBuffer(b)
 	o := NewBuffer(b)

+ 139 - 0
Godeps/_workspace/src/github.com/gogo/protobuf/proto/extensions_test.go

@@ -32,6 +32,8 @@
 package proto_test
 package proto_test
 
 
 import (
 import (
+	"fmt"
+	"reflect"
 	"testing"
 	"testing"
 
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
@@ -93,6 +95,143 @@ func TestGetExtensionStability(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestGetExtensionDefaults(t *testing.T) {
+	var setFloat64 float64 = 1
+	var setFloat32 float32 = 2
+	var setInt32 int32 = 3
+	var setInt64 int64 = 4
+	var setUint32 uint32 = 5
+	var setUint64 uint64 = 6
+	var setBool = true
+	var setBool2 = false
+	var setString = "Goodnight string"
+	var setBytes = []byte("Goodnight bytes")
+	var setEnum = pb.DefaultsMessage_TWO
+
+	type testcase struct {
+		ext  *proto.ExtensionDesc // Extension we are testing.
+		want interface{}          // Expected value of extension, or nil (meaning that GetExtension will fail).
+		def  interface{}          // Expected value of extension after ClearExtension().
+	}
+	tests := []testcase{
+		{pb.E_NoDefaultDouble, setFloat64, nil},
+		{pb.E_NoDefaultFloat, setFloat32, nil},
+		{pb.E_NoDefaultInt32, setInt32, nil},
+		{pb.E_NoDefaultInt64, setInt64, nil},
+		{pb.E_NoDefaultUint32, setUint32, nil},
+		{pb.E_NoDefaultUint64, setUint64, nil},
+		{pb.E_NoDefaultSint32, setInt32, nil},
+		{pb.E_NoDefaultSint64, setInt64, nil},
+		{pb.E_NoDefaultFixed32, setUint32, nil},
+		{pb.E_NoDefaultFixed64, setUint64, nil},
+		{pb.E_NoDefaultSfixed32, setInt32, nil},
+		{pb.E_NoDefaultSfixed64, setInt64, nil},
+		{pb.E_NoDefaultBool, setBool, nil},
+		{pb.E_NoDefaultBool, setBool2, nil},
+		{pb.E_NoDefaultString, setString, nil},
+		{pb.E_NoDefaultBytes, setBytes, nil},
+		{pb.E_NoDefaultEnum, setEnum, nil},
+		{pb.E_DefaultDouble, setFloat64, float64(3.1415)},
+		{pb.E_DefaultFloat, setFloat32, float32(3.14)},
+		{pb.E_DefaultInt32, setInt32, int32(42)},
+		{pb.E_DefaultInt64, setInt64, int64(43)},
+		{pb.E_DefaultUint32, setUint32, uint32(44)},
+		{pb.E_DefaultUint64, setUint64, uint64(45)},
+		{pb.E_DefaultSint32, setInt32, int32(46)},
+		{pb.E_DefaultSint64, setInt64, int64(47)},
+		{pb.E_DefaultFixed32, setUint32, uint32(48)},
+		{pb.E_DefaultFixed64, setUint64, uint64(49)},
+		{pb.E_DefaultSfixed32, setInt32, int32(50)},
+		{pb.E_DefaultSfixed64, setInt64, int64(51)},
+		{pb.E_DefaultBool, setBool, true},
+		{pb.E_DefaultBool, setBool2, true},
+		{pb.E_DefaultString, setString, "Hello, string"},
+		{pb.E_DefaultBytes, setBytes, []byte("Hello, bytes")},
+		{pb.E_DefaultEnum, setEnum, pb.DefaultsMessage_ONE},
+	}
+
+	checkVal := func(test testcase, msg *pb.DefaultsMessage, valWant interface{}) error {
+		val, err := proto.GetExtension(msg, test.ext)
+		if err != nil {
+			if valWant != nil {
+				return fmt.Errorf("GetExtension(): %s", err)
+			}
+			if want := proto.ErrMissingExtension; err != want {
+				return fmt.Errorf("Unexpected error: got %v, want %v", err, want)
+			}
+			return nil
+		}
+
+		// All proto2 extension values are either a pointer to a value or a slice of values.
+		ty := reflect.TypeOf(val)
+		tyWant := reflect.TypeOf(test.ext.ExtensionType)
+		if got, want := ty, tyWant; got != want {
+			return fmt.Errorf("unexpected reflect.TypeOf(): got %v want %v", got, want)
+		}
+		tye := ty.Elem()
+		tyeWant := tyWant.Elem()
+		if got, want := tye, tyeWant; got != want {
+			return fmt.Errorf("unexpected reflect.TypeOf().Elem(): got %v want %v", got, want)
+		}
+
+		// Check the name of the type of the value.
+		// If it is an enum it will be type int32 with the name of the enum.
+		if got, want := tye.Name(), tye.Name(); got != want {
+			return fmt.Errorf("unexpected reflect.TypeOf().Elem().Name(): got %v want %v", got, want)
+		}
+
+		// Check that value is what we expect.
+		// If we have a pointer in val, get the value it points to.
+		valExp := val
+		if ty.Kind() == reflect.Ptr {
+			valExp = reflect.ValueOf(val).Elem().Interface()
+		}
+		if got, want := valExp, valWant; !reflect.DeepEqual(got, want) {
+			return fmt.Errorf("unexpected reflect.DeepEqual(): got %v want %v", got, want)
+		}
+
+		return nil
+	}
+
+	setTo := func(test testcase) interface{} {
+		setTo := reflect.ValueOf(test.want)
+		if typ := reflect.TypeOf(test.ext.ExtensionType); typ.Kind() == reflect.Ptr {
+			setTo = reflect.New(typ).Elem()
+			setTo.Set(reflect.New(setTo.Type().Elem()))
+			setTo.Elem().Set(reflect.ValueOf(test.want))
+		}
+		return setTo.Interface()
+	}
+
+	for _, test := range tests {
+		msg := &pb.DefaultsMessage{}
+		name := test.ext.Name
+
+		// Check the initial value.
+		if err := checkVal(test, msg, test.def); err != nil {
+			t.Errorf("%s: %v", name, err)
+		}
+
+		// Set the per-type value and check value.
+		name = fmt.Sprintf("%s (set to %T %v)", name, test.want, test.want)
+		if err := proto.SetExtension(msg, test.ext, setTo(test)); err != nil {
+			t.Errorf("%s: SetExtension(): %v", name, err)
+			continue
+		}
+		if err := checkVal(test, msg, test.want); err != nil {
+			t.Errorf("%s: %v", name, err)
+			continue
+		}
+
+		// Set and check the value.
+		name += " (cleared)"
+		proto.ClearExtension(msg, test.ext)
+		if err := checkVal(test, msg, test.def); err != nil {
+			t.Errorf("%s: %v", name, err)
+		}
+	}
+}
+
 func TestExtensionsRoundTrip(t *testing.T) {
 func TestExtensionsRoundTrip(t *testing.T) {
 	msg := &pb.MyMessage{}
 	msg := &pb.MyMessage{}
 	ext1 := &pb.Ext{
 	ext1 := &pb.Ext{

+ 367 - 274
Godeps/_workspace/src/github.com/gogo/protobuf/proto/lib.go

@@ -30,179 +30,230 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // 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/gogo/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
+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.
+  - Oneof field sets are given a single field in their message,
+	with distinguished wrapper types for each possible field value.
+  - 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;
+	  }
+	  oneof union {
+	    int32 number = 6;
+	    string name = 7;
+	  }
+	}
+
+The resulting file, test.pb.go, is:
+
+	package example
+
+	import proto "github.com/gogo/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"`
+		// Types that are valid to be assigned to Union:
+		//	*Test_Number
+		//	*Test_Name
+		Union            isTest_Union `protobuf_oneof:"union"`
+		XXX_unrecognized []byte       `json:"-"`
+	}
+	func (m *Test) Reset()         { *m = Test{} }
+	func (m *Test) String() string { return proto.CompactTextString(m) }
+	func (*Test) ProtoMessage() {}
+
+	type isTest_Union interface {
+		isTest_Union()
+	}
 
 
-		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:"-"`
+	type Test_Number struct {
+		Number int32 `protobuf:"varint,6,opt,name=number"`
+	}
+	type Test_Name struct {
+		Name string `protobuf:"bytes,7,opt,name=name"`
+	}
+
+	func (*Test_Number) isTest_Union() {}
+	func (*Test_Name) isTest_Union()   {}
+
+	func (m *Test) GetUnion() isTest_Union {
+		if m != nil {
+			return m.Union
 		}
 		}
-		func (m *Test) Reset()         { *m = Test{} }
-		func (m *Test) String() string { return proto.CompactTextString(m) }
-		func (*Test) ProtoMessage()    {}
-		const Default_Test_Type int32 = 77
+		return nil
+	}
+	const Default_Test_Type int32 = 77
 
 
-		func (m *Test) GetLabel() string {
-			if m != nil && m.Label != nil {
-				return *m.Label
-			}
-			return ""
+	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) 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
+	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) }
 
 
-		type Test_OptionalGroup struct {
-			RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
+	func (m *Test_OptionalGroup) GetRequiredField() string {
+		if m != nil && m.RequiredField != nil {
+			return *m.RequiredField
 		}
 		}
-		func (m *Test_OptionalGroup) Reset()         { *m = Test_OptionalGroup{} }
-		func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
+		return ""
+	}
 
 
-		func (m *Test_OptionalGroup) GetRequiredField() string {
-			if m != nil && m.RequiredField != nil {
-				return *m.RequiredField
-			}
-			return ""
+	func (m *Test) GetNumber() int32 {
+		if x, ok := m.GetUnion().(*Test_Number); ok {
+			return x.Number
 		}
 		}
+		return 0
+	}
 
 
-		func init() {
-			proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
+	func (m *Test) GetName() string {
+		if x, ok := m.GetUnion().(*Test_Name); ok {
+			return x.Name
 		}
 		}
+		return ""
+	}
 
 
-	To create and play with a Test object:
+	func init() {
+		proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
+	}
 
 
-		package main
+To create and play with a Test object:
 
 
-		import (
-			"log"
+	package main
 
 
-			"github.com/gogo/protobuf/proto"
-			pb "./example.pb"
-		)
+	import (
+		"log"
 
 
-		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.
+		"github.com/gogo/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"),
+			},
+			Union: &pb.Test_Name{"fred"},
+		}
+		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())
+		}
+		// Use a type switch to determine which oneof was set.
+		switch u := test.Union.(type) {
+		case *pb.Test_Number: // u.Number contains the number.
+		case *pb.Test_Name: // u.Name contains the string.
 		}
 		}
+		// etc.
+	}
 */
 */
 package proto
 package proto
 
 
@@ -211,6 +262,7 @@ import (
 	"fmt"
 	"fmt"
 	"log"
 	"log"
 	"reflect"
 	"reflect"
+	"sort"
 	"strconv"
 	"strconv"
 	"sync"
 	"sync"
 )
 )
@@ -385,13 +437,13 @@ func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32,
 
 
 // DebugPrint dumps the encoded data in b in a debugging format with a header
 // 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.
 // including the string s. Used in testing but made available for general debugging.
-func (o *Buffer) DebugPrint(s string, b []byte) {
+func (p *Buffer) DebugPrint(s string, b []byte) {
 	var u uint64
 	var u uint64
 
 
-	obuf := o.buf
-	index := o.index
-	o.buf = b
-	o.index = 0
+	obuf := p.buf
+	index := p.index
+	p.buf = b
+	p.index = 0
 	depth := 0
 	depth := 0
 
 
 	fmt.Printf("\n--- %s ---\n", s)
 	fmt.Printf("\n--- %s ---\n", s)
@@ -402,12 +454,12 @@ out:
 			fmt.Print("  ")
 			fmt.Print("  ")
 		}
 		}
 
 
-		index := o.index
-		if index == len(o.buf) {
+		index := p.index
+		if index == len(p.buf) {
 			break
 			break
 		}
 		}
 
 
-		op, err := o.DecodeVarint()
+		op, err := p.DecodeVarint()
 		if err != nil {
 		if err != nil {
 			fmt.Printf("%3d: fetching op err %v\n", index, err)
 			fmt.Printf("%3d: fetching op err %v\n", index, err)
 			break out
 			break out
@@ -424,7 +476,7 @@ out:
 		case WireBytes:
 		case WireBytes:
 			var r []byte
 			var r []byte
 
 
-			r, err = o.DecodeRawBytes(false)
+			r, err = p.DecodeRawBytes(false)
 			if err != nil {
 			if err != nil {
 				break out
 				break out
 			}
 			}
@@ -445,7 +497,7 @@ out:
 			fmt.Printf("\n")
 			fmt.Printf("\n")
 
 
 		case WireFixed32:
 		case WireFixed32:
-			u, err = o.DecodeFixed32()
+			u, err = p.DecodeFixed32()
 			if err != nil {
 			if err != nil {
 				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
 				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
 				break out
 				break out
@@ -453,16 +505,15 @@ out:
 			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
 			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
 
 
 		case WireFixed64:
 		case WireFixed64:
-			u, err = o.DecodeFixed64()
+			u, err = p.DecodeFixed64()
 			if err != nil {
 			if err != nil {
 				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
 				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
 				break out
 				break out
 			}
 			}
 			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
 			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
-			break
 
 
 		case WireVarint:
 		case WireVarint:
-			u, err = o.DecodeVarint()
+			u, err = p.DecodeVarint()
 			if err != nil {
 			if err != nil {
 				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
 				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
 				break out
 				break out
@@ -470,30 +521,22 @@ out:
 			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
 			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
 
 
 		case WireStartGroup:
 		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)
 			fmt.Printf("%3d: t=%3d start\n", index, tag)
 			depth++
 			depth++
 
 
 		case WireEndGroup:
 		case WireEndGroup:
 			depth--
 			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)
 			fmt.Printf("%3d: t=%3d end\n", index, tag)
 		}
 		}
 	}
 	}
 
 
 	if depth != 0 {
 	if depth != 0 {
-		fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth)
+		fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
 	}
 	}
 	fmt.Printf("\n")
 	fmt.Printf("\n")
 
 
-	o.buf = obuf
-	o.index = index
+	p.buf = obuf
+	p.index = index
 }
 }
 
 
 // SetDefaults sets unset protocol buffer fields to their default values.
 // SetDefaults sets unset protocol buffer fields to their default values.
@@ -668,112 +711,118 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
 		}
 		}
 		ft := t.Field(fi).Type
 		ft := t.Field(fi).Type
 
 
-		var canHaveDefault, nestedMessage bool
-		switch ft.Kind() {
-		case reflect.Ptr:
-			if ft.Elem().Kind() == reflect.Struct {
-				nestedMessage = true
-			} else {
-				canHaveDefault = true // proto2 scalar field
-			}
+		sf, nested, err := fieldDefault(ft, prop)
+		switch {
+		case err != nil:
+			log.Print(err)
+		case nested:
+			dm.nested = append(dm.nested, fi)
+		case sf != nil:
+			sf.index = fi
+			dm.scalars = append(dm.scalars, *sf)
+		}
+	}
 
 
-		case reflect.Slice:
-			switch ft.Elem().Kind() {
-			case reflect.Ptr:
-				nestedMessage = true // repeated message
-			case reflect.Uint8:
-				canHaveDefault = true // bytes field
-			}
+	return dm
+}
 
 
-		case reflect.Map:
-			if ft.Elem().Kind() == reflect.Ptr {
-				nestedMessage = true // map with message values
-			}
+// fieldDefault returns the scalarField for field type ft.
+// sf will be nil if the field can not have a default.
+// nestedMessage will be true if this is a nested message.
+// Note that sf.index is not set on return.
+func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
+	var canHaveDefault bool
+	switch ft.Kind() {
+	case reflect.Ptr:
+		if ft.Elem().Kind() == reflect.Struct {
+			nestedMessage = true
+		} else {
+			canHaveDefault = true // proto2 scalar field
 		}
 		}
 
 
-		if !canHaveDefault {
-			if nestedMessage {
-				dm.nested = append(dm.nested, fi)
-			}
-			continue
+	case reflect.Slice:
+		switch ft.Elem().Kind() {
+		case reflect.Ptr:
+			nestedMessage = true // repeated message
+		case reflect.Uint8:
+			canHaveDefault = true // bytes field
 		}
 		}
 
 
-		sf := scalarField{
-			index: fi,
-			kind:  ft.Elem().Kind(),
+	case reflect.Map:
+		if ft.Elem().Kind() == reflect.Ptr {
+			nestedMessage = true // map with message values
 		}
 		}
+	}
 
 
-		// scalar fields without defaults
-		if !prop.HasDefault {
-			dm.scalars = append(dm.scalars, sf)
-			continue
+	if !canHaveDefault {
+		if nestedMessage {
+			return nil, true, nil
 		}
 		}
+		return nil, false, nil
+	}
 
 
-		// 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
-		}
+	// We now know that ft is a pointer or slice.
+	sf = &scalarField{kind: ft.Elem().Kind()}
 
 
-		dm.scalars = append(dm.scalars, sf)
+	// scalar fields without defaults
+	if !prop.HasDefault {
+		return sf, false, nil
 	}
 	}
 
 
-	return dm
+	// a scalar field: either *T or []byte
+	switch ft.Elem().Kind() {
+	case reflect.Bool:
+		x, err := strconv.ParseBool(prop.Default)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
+		}
+		sf.value = x
+	case reflect.Float32:
+		x, err := strconv.ParseFloat(prop.Default, 32)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
+		}
+		sf.value = float32(x)
+	case reflect.Float64:
+		x, err := strconv.ParseFloat(prop.Default, 64)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
+		}
+		sf.value = x
+	case reflect.Int32:
+		x, err := strconv.ParseInt(prop.Default, 10, 32)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
+		}
+		sf.value = int32(x)
+	case reflect.Int64:
+		x, err := strconv.ParseInt(prop.Default, 10, 64)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
+		}
+		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 {
+			return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
+		}
+		sf.value = uint32(x)
+	case reflect.Uint64:
+		x, err := strconv.ParseUint(prop.Default, 10, 64)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
+		}
+		sf.value = x
+	default:
+		return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
+	}
+
+	return sf, false, nil
 }
 }
 
 
 // Map fields may have key types of non-float scalars, strings and enums.
 // Map fields may have key types of non-float scalars, strings and enums.
@@ -781,10 +830,54 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
 // If this turns out to be inefficient we can always consider other options,
 // If this turns out to be inefficient we can always consider other options,
 // such as doing a Schwartzian transform.
 // such as doing a Schwartzian transform.
 
 
-type mapKeys []reflect.Value
+func mapKeys(vs []reflect.Value) sort.Interface {
+	s := mapKeySorter{
+		vs: vs,
+		// default Less function: textual comparison
+		less: func(a, b reflect.Value) bool {
+			return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
+		},
+	}
 
 
-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())
+	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
+	// numeric keys are sorted numerically.
+	if len(vs) == 0 {
+		return s
+	}
+	switch vs[0].Kind() {
+	case reflect.Int32, reflect.Int64:
+		s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
+	case reflect.Uint32, reflect.Uint64:
+		s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
+	}
+
+	return s
+}
+
+type mapKeySorter struct {
+	vs   []reflect.Value
+	less func(a, b reflect.Value) bool
+}
+
+func (s mapKeySorter) Len() int      { return len(s.vs) }
+func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
+func (s mapKeySorter) Less(i, j int) bool {
+	return s.less(s.vs[i], s.vs[j])
+}
+
+// isProto3Zero reports whether v is a zero proto3 value.
+func isProto3Zero(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint32, reflect.Uint64:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.String:
+		return v.String() == ""
+	}
+	return false
 }
 }

+ 17 - 24
Godeps/_workspace/src/github.com/gogo/protobuf/proto/message_set.go

@@ -44,11 +44,11 @@ import (
 	"sort"
 	"sort"
 )
 )
 
 
-// ErrNoMessageTypeId occurs when a protocol buffer does not have a message type ID.
+// 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.
 // 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")
+var errNoMessageTypeID = errors.New("proto does not have a message type ID")
 
 
-// The first two types (_MessageSet_Item and MessageSet)
+// The first two types (_MessageSet_Item and messageSet)
 // model what the protocol compiler produces for the following protocol message:
 // model what the protocol compiler produces for the following protocol message:
 //   message MessageSet {
 //   message MessageSet {
 //     repeated group Item = 1 {
 //     repeated group Item = 1 {
@@ -58,27 +58,20 @@ var ErrNoMessageTypeId = errors.New("proto does not have a message type ID")
 //   }
 //   }
 // That is the MessageSet wire format. We can't use a proto to generate these
 // 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.
 // 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 {
 type _MessageSet_Item struct {
 	TypeId  *int32 `protobuf:"varint,2,req,name=type_id"`
 	TypeId  *int32 `protobuf:"varint,2,req,name=type_id"`
 	Message []byte `protobuf:"bytes,3,req,name=message"`
 	Message []byte `protobuf:"bytes,3,req,name=message"`
 }
 }
 
 
-type MessageSet struct {
+type messageSet struct {
 	Item             []*_MessageSet_Item `protobuf:"group,1,rep"`
 	Item             []*_MessageSet_Item `protobuf:"group,1,rep"`
 	XXX_unrecognized []byte
 	XXX_unrecognized []byte
 	// TODO: caching?
 	// TODO: caching?
 }
 }
 
 
-// Make sure MessageSet is a Message.
-var _ Message = (*MessageSet)(nil)
+// Make sure messageSet is a Message.
+var _ Message = (*messageSet)(nil)
 
 
 // messageTypeIder is an interface satisfied by a protocol buffer type
 // messageTypeIder is an interface satisfied by a protocol buffer type
 // that may be stored in a MessageSet.
 // that may be stored in a MessageSet.
@@ -86,7 +79,7 @@ type messageTypeIder interface {
 	MessageTypeId() int32
 	MessageTypeId() int32
 }
 }
 
 
-func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
+func (ms *messageSet) find(pb Message) *_MessageSet_Item {
 	mti, ok := pb.(messageTypeIder)
 	mti, ok := pb.(messageTypeIder)
 	if !ok {
 	if !ok {
 		return nil
 		return nil
@@ -100,24 +93,24 @@ func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
 	return nil
 	return nil
 }
 }
 
 
-func (ms *MessageSet) Has(pb Message) bool {
+func (ms *messageSet) Has(pb Message) bool {
 	if ms.find(pb) != nil {
 	if ms.find(pb) != nil {
 		return true
 		return true
 	}
 	}
 	return false
 	return false
 }
 }
 
 
-func (ms *MessageSet) Unmarshal(pb Message) error {
+func (ms *messageSet) Unmarshal(pb Message) error {
 	if item := ms.find(pb); item != nil {
 	if item := ms.find(pb); item != nil {
 		return Unmarshal(item.Message, pb)
 		return Unmarshal(item.Message, pb)
 	}
 	}
 	if _, ok := pb.(messageTypeIder); !ok {
 	if _, ok := pb.(messageTypeIder); !ok {
-		return ErrNoMessageTypeId
+		return errNoMessageTypeID
 	}
 	}
 	return nil // TODO: return error instead?
 	return nil // TODO: return error instead?
 }
 }
 
 
-func (ms *MessageSet) Marshal(pb Message) error {
+func (ms *messageSet) Marshal(pb Message) error {
 	msg, err := Marshal(pb)
 	msg, err := Marshal(pb)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -130,7 +123,7 @@ func (ms *MessageSet) Marshal(pb Message) error {
 
 
 	mti, ok := pb.(messageTypeIder)
 	mti, ok := pb.(messageTypeIder)
 	if !ok {
 	if !ok {
-		return ErrNoMessageTypeId
+		return errNoMessageTypeID
 	}
 	}
 
 
 	mtid := mti.MessageTypeId()
 	mtid := mti.MessageTypeId()
@@ -141,9 +134,9 @@ func (ms *MessageSet) Marshal(pb Message) error {
 	return nil
 	return nil
 }
 }
 
 
-func (ms *MessageSet) Reset()         { *ms = MessageSet{} }
-func (ms *MessageSet) String() string { return CompactTextString(ms) }
-func (*MessageSet) ProtoMessage()     {}
+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.
 // Support for the message_set_wire_format message option.
 
 
@@ -169,7 +162,7 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
 	}
 	}
 	sort.Ints(ids)
 	sort.Ints(ids)
 
 
-	ms := &MessageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
+	ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
 	for _, id := range ids {
 	for _, id := range ids {
 		e := m[int32(id)]
 		e := m[int32(id)]
 		// Remove the wire type and field number varint, as well as the length varint.
 		// Remove the wire type and field number varint, as well as the length varint.
@@ -186,7 +179,7 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
 // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
 // 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.
 // 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 {
 func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
-	ms := new(MessageSet)
+	ms := new(messageSet)
 	if err := Unmarshal(buf, ms); err != nil {
 	if err := Unmarshal(buf, ms); err != nil {
 		return err
 		return err
 	}
 	}

+ 1 - 1
Godeps/_workspace/src/github.com/gogo/protobuf/proto/message_set_test.go

@@ -38,7 +38,7 @@ import (
 
 
 func TestUnmarshalMessageSetWithDuplicate(t *testing.T) {
 func TestUnmarshalMessageSetWithDuplicate(t *testing.T) {
 	// Check that a repeated message set entry will be concatenated.
 	// Check that a repeated message set entry will be concatenated.
-	in := &MessageSet{
+	in := &messageSet{
 		Item: []*_MessageSet_Item{
 		Item: []*_MessageSet_Item{
 			{TypeId: Int32(12345), Message: []byte("hoo")},
 			{TypeId: Int32(12345), Message: []byte("hoo")},
 			{TypeId: Int32(12345), Message: []byte("hah")},
 			{TypeId: Int32(12345), Message: []byte("hah")},

+ 2 - 2
Godeps/_workspace/src/github.com/gogo/protobuf/proto/pointer_reflect.go

@@ -144,8 +144,8 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
 	return structPointer_ifield(p, f).(*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 {
+// NewAt returns the reflect.Value for a pointer to a field in the struct.
+func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
 	return structPointer_field(p, f).Addr()
 	return structPointer_field(p, f).Addr()
 }
 }
 
 

+ 2 - 2
Godeps/_workspace/src/github.com/gogo/protobuf/proto/pointer_unsafe.go

@@ -130,8 +130,8 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
 	return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 	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 {
+// NewAt returns the reflect.Value for a pointer to a field in the struct.
+func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
 	return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
 	return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
 }
 }
 
 

+ 101 - 1
Godeps/_workspace/src/github.com/gogo/protobuf/proto/properties.go

@@ -42,6 +42,7 @@ package proto
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"log"
 	"os"
 	"os"
 	"reflect"
 	"reflect"
 	"sort"
 	"sort"
@@ -89,6 +90,12 @@ type decoder func(p *Buffer, prop *Properties, base structPointer) error
 // A valueDecoder decodes a single integer in a particular encoding.
 // A valueDecoder decodes a single integer in a particular encoding.
 type valueDecoder func(o *Buffer) (x uint64, err error)
 type valueDecoder func(o *Buffer) (x uint64, err error)
 
 
+// A oneofMarshaler does the marshaling for all oneof fields in a message.
+type oneofMarshaler func(Message, *Buffer) error
+
+// A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
+type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error)
+
 // tagMap is an optimization over map[int]int for typical protocol buffer
 // 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
 // use-cases. Encoded protocol buffers are often in tag order with small tag
 // numbers.
 // numbers.
@@ -137,6 +144,21 @@ type StructProperties struct {
 	order            []int          // list of struct field numbers in tag order
 	order            []int          // list of struct field numbers in tag order
 	unrecField       field          // field id of the XXX_unrecognized []byte field
 	unrecField       field          // field id of the XXX_unrecognized []byte field
 	extendable       bool           // is this an extendable proto
 	extendable       bool           // is this an extendable proto
+
+	oneofMarshaler   oneofMarshaler
+	oneofUnmarshaler oneofUnmarshaler
+	stype            reflect.Type
+
+	// OneofTypes contains information about the oneof fields in this message.
+	// It is keyed by the original name of a field.
+	OneofTypes map[string]*OneofProperties
+}
+
+// OneofProperties represents information about a specific field in a oneof.
+type OneofProperties struct {
+	Type  reflect.Type // pointer to generated struct type for this oneof field
+	Field int          // struct field number of the containing oneof in the message
+	Prop  *Properties
 }
 }
 
 
 // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
 // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
@@ -161,6 +183,7 @@ type Properties struct {
 	Packed   bool   // relevant for repeated primitives only
 	Packed   bool   // relevant for repeated primitives only
 	Enum     string // set for enum types only
 	Enum     string // set for enum types only
 	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
 	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
+	oneof    bool   // whether this is a oneof field
 
 
 	Default    string // default value
 	Default    string // default value
 	HasDefault bool   // whether an explicit default was provided
 	HasDefault bool   // whether an explicit default was provided
@@ -216,6 +239,9 @@ func (p *Properties) String() string {
 	if p.proto3 {
 	if p.proto3 {
 		s += ",proto3"
 		s += ",proto3"
 	}
 	}
+	if p.oneof {
+		s += ",oneof"
+	}
 	if len(p.Enum) > 0 {
 	if len(p.Enum) > 0 {
 		s += ",enum=" + p.Enum
 		s += ",enum=" + p.Enum
 	}
 	}
@@ -292,6 +318,8 @@ func (p *Properties) Parse(s string) {
 			p.Enum = f[5:]
 			p.Enum = f[5:]
 		case f == "proto3":
 		case f == "proto3":
 			p.proto3 = true
 			p.proto3 = true
+		case f == "oneof":
+			p.oneof = true
 		case strings.HasPrefix(f, "def="):
 		case strings.HasPrefix(f, "def="):
 			p.HasDefault = true
 			p.HasDefault = true
 			p.Default = f[4:] // rest of string
 			p.Default = f[4:] // rest of string
@@ -713,6 +741,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 	prop.Prop = make([]*Properties, t.NumField())
 	prop.Prop = make([]*Properties, t.NumField())
 	prop.order = make([]int, t.NumField())
 	prop.order = make([]int, t.NumField())
 
 
+	isOneofMessage := false
 	for i := 0; i < t.NumField(); i++ {
 	for i := 0; i < t.NumField(); i++ {
 		f := t.Field(i)
 		f := t.Field(i)
 		p := new(Properties)
 		p := new(Properties)
@@ -733,6 +762,10 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 		if f.Name == "XXX_unrecognized" { // special case
 		if f.Name == "XXX_unrecognized" { // special case
 			prop.unrecField = toField(&f)
 			prop.unrecField = toField(&f)
 		}
 		}
+		oneof := f.Tag.Get("protobuf_oneof") != "" // special case
+		if oneof {
+			isOneofMessage = true
+		}
 		prop.Prop[i] = p
 		prop.Prop[i] = p
 		prop.order[i] = i
 		prop.order[i] = i
 		if debug {
 		if debug {
@@ -742,7 +775,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 			}
 			}
 			print("\n")
 			print("\n")
 		}
 		}
-		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") {
+		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof {
 			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
 			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
 		}
 		}
 	}
 	}
@@ -750,6 +783,41 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 	// Re-order prop.order.
 	// Re-order prop.order.
 	sort.Sort(prop)
 	sort.Sort(prop)
 
 
+	type oneofMessage interface {
+		XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), []interface{})
+	}
+	if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok {
+		var oots []interface{}
+		prop.oneofMarshaler, prop.oneofUnmarshaler, oots = om.XXX_OneofFuncs()
+		prop.stype = t
+
+		// Interpret oneof metadata.
+		prop.OneofTypes = make(map[string]*OneofProperties)
+		for _, oot := range oots {
+			oop := &OneofProperties{
+				Type: reflect.ValueOf(oot).Type(), // *T
+				Prop: new(Properties),
+			}
+			sft := oop.Type.Elem().Field(0)
+			oop.Prop.Name = sft.Name
+			oop.Prop.Parse(sft.Tag.Get("protobuf"))
+			// There will be exactly one interface field that
+			// this new value is assignable to.
+			for i := 0; i < t.NumField(); i++ {
+				f := t.Field(i)
+				if f.Type.Kind() != reflect.Interface {
+					continue
+				}
+				if !oop.Type.AssignableTo(f.Type) {
+					continue
+				}
+				oop.Field = i
+				break
+			}
+			prop.OneofTypes[oop.Prop.OrigName] = oop
+		}
+	}
+
 	// build required counts
 	// build required counts
 	// build tags
 	// build tags
 	reqCount := 0
 	reqCount := 0
@@ -813,3 +881,35 @@ func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[
 	}
 	}
 	enumStringMaps[typeName] = unusedNameMap
 	enumStringMaps[typeName] = unusedNameMap
 }
 }
+
+// EnumValueMap returns the mapping from names to integers of the
+// enum type enumType, or a nil if not found.
+func EnumValueMap(enumType string) map[string]int32 {
+	return enumValueMaps[enumType]
+}
+
+// A registry of all linked message types.
+// The string is a fully-qualified proto name ("pkg.Message").
+var (
+	protoTypes    = make(map[string]reflect.Type)
+	revProtoTypes = make(map[reflect.Type]string)
+)
+
+// RegisterType is called from generated code and maps from the fully qualified
+// proto name to the type (pointer to struct) of the protocol buffer.
+func RegisterType(x Message, name string) {
+	if _, ok := protoTypes[name]; ok {
+		// TODO: Some day, make this a panic.
+		log.Printf("proto: duplicate proto type registered: %s", name)
+		return
+	}
+	t := reflect.TypeOf(x)
+	protoTypes[name] = t
+	revProtoTypes[t] = name
+}
+
+// MessageName returns the fully-qualified proto name for the given message type.
+func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] }
+
+// MessageType returns the message type (pointer to struct) for a named message.
+func MessageType(name string) reflect.Type { return protoTypes[name] }

+ 7 - 0
Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto/proto3.pb.go

@@ -16,10 +16,14 @@ It has these top-level messages:
 package proto3_proto
 package proto3_proto
 
 
 import proto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
 import proto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
+import fmt "fmt"
+import math "math"
 import testdata "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata"
 import testdata "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata"
 
 
 // Reference imports to suppress errors if they are not otherwise used.
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
 var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
 
 
 type Message_Humour int32
 type Message_Humour int32
 
 
@@ -118,5 +122,8 @@ func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
 }
 }
 
 
 func init() {
 func init() {
+	proto.RegisterType((*Message)(nil), "proto3_proto.Message")
+	proto.RegisterType((*Nested)(nil), "proto3_proto.Nested")
+	proto.RegisterType((*MessageWithMap)(nil), "proto3_proto.MessageWithMap")
 	proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value)
 	proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value)
 }
 }

+ 5 - 0
Godeps/_workspace/src/github.com/gogo/protobuf/proto/size_test.go

@@ -124,6 +124,11 @@ var SizeTests = []struct {
 	{"map field with big entry", &pb.MessageWithMap{NameMapping: map[int32]string{8: strings.Repeat("x", 125)}}},
 	{"map field with big entry", &pb.MessageWithMap{NameMapping: map[int32]string{8: strings.Repeat("x", 125)}}},
 	{"map field with big key and val", &pb.MessageWithMap{StrToStr: map[string]string{strings.Repeat("x", 70): strings.Repeat("y", 70)}}},
 	{"map field with big key and val", &pb.MessageWithMap{StrToStr: map[string]string{strings.Repeat("x", 70): strings.Repeat("y", 70)}}},
 	{"map field with big numeric key", &pb.MessageWithMap{NameMapping: map[int32]string{0xf00d: "om nom nom"}}},
 	{"map field with big numeric key", &pb.MessageWithMap{NameMapping: map[int32]string{0xf00d: "om nom nom"}}},
+
+	{"oneof not set", &pb.Communique{}},
+	{"oneof zero int32", &pb.Communique{Union: &pb.Communique_Number{Number: 0}}},
+	{"oneof int32", &pb.Communique{Union: &pb.Communique_Number{Number: 3}}},
+	{"oneof string", &pb.Communique{Union: &pb.Communique_Name{Name: "Rhythmic Fman"}}},
 }
 }
 
 
 func TestSize(t *testing.T) {
 func TestSize(t *testing.T) {

+ 1 - 1
Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/Makefile

@@ -32,6 +32,6 @@
 all:	regenerate
 all:	regenerate
 
 
 regenerate:
 regenerate:
-	go install github.com/gogo/protobuf/protoc-gen-gogo/version/protoc-min-version
+	go install github.com/gogo/protobuf/protoc-min-version
 	protoc-min-version --version="3.0.0" --gogo_out=. test.proto
 	protoc-min-version --version="3.0.0" --gogo_out=. test.proto
 	
 	

+ 620 - 32
Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.pb.go

@@ -22,6 +22,7 @@ It has these top-level messages:
 	OtherMessage
 	OtherMessage
 	MyMessage
 	MyMessage
 	Ext
 	Ext
+	DefaultsMessage
 	MyMessageSet
 	MyMessageSet
 	Empty
 	Empty
 	MessageList
 	MessageList
@@ -34,14 +35,17 @@ It has these top-level messages:
 	GroupNew
 	GroupNew
 	FloatingPoint
 	FloatingPoint
 	MessageWithMap
 	MessageWithMap
+	Communique
 */
 */
 package testdata
 package testdata
 
 
-import proto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
+import proto "github.com/gogo/protobuf/proto"
+import fmt "fmt"
 import math "math"
 import math "math"
 
 
 // Reference imports to suppress errors if they are not otherwise used.
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
 var _ = proto.Marshal
+var _ = fmt.Errorf
 var _ = math.Inf
 var _ = math.Inf
 
 
 type FOO int32
 type FOO int32
@@ -181,6 +185,42 @@ func (x *MyMessage_Color) UnmarshalJSON(data []byte) error {
 	return nil
 	return nil
 }
 }
 
 
+type DefaultsMessage_DefaultsEnum int32
+
+const (
+	DefaultsMessage_ZERO DefaultsMessage_DefaultsEnum = 0
+	DefaultsMessage_ONE  DefaultsMessage_DefaultsEnum = 1
+	DefaultsMessage_TWO  DefaultsMessage_DefaultsEnum = 2
+)
+
+var DefaultsMessage_DefaultsEnum_name = map[int32]string{
+	0: "ZERO",
+	1: "ONE",
+	2: "TWO",
+}
+var DefaultsMessage_DefaultsEnum_value = map[string]int32{
+	"ZERO": 0,
+	"ONE":  1,
+	"TWO":  2,
+}
+
+func (x DefaultsMessage_DefaultsEnum) Enum() *DefaultsMessage_DefaultsEnum {
+	p := new(DefaultsMessage_DefaultsEnum)
+	*p = x
+	return p
+}
+func (x DefaultsMessage_DefaultsEnum) String() string {
+	return proto.EnumName(DefaultsMessage_DefaultsEnum_name, int32(x))
+}
+func (x *DefaultsMessage_DefaultsEnum) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(DefaultsMessage_DefaultsEnum_value, data, "DefaultsMessage_DefaultsEnum")
+	if err != nil {
+		return err
+	}
+	*x = DefaultsMessage_DefaultsEnum(value)
+	return nil
+}
+
 type Defaults_Color int32
 type Defaults_Color int32
 
 
 const (
 const (
@@ -264,8 +304,8 @@ func (m *GoEnum) GetFoo() FOO {
 }
 }
 
 
 type GoTestField struct {
 type GoTestField struct {
-	Label            *string `protobuf:"bytes,1,req" json:"Label,omitempty"`
-	Type             *string `protobuf:"bytes,2,req" json:"Type,omitempty"`
+	Label            *string `protobuf:"bytes,1,req,name=Label" json:"Label,omitempty"`
+	Type             *string `protobuf:"bytes,2,req,name=Type" json:"Type,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
 	XXX_unrecognized []byte  `json:"-"`
 }
 }
 
 
@@ -289,13 +329,13 @@ func (m *GoTestField) GetType() string {
 
 
 type GoTest struct {
 type GoTest struct {
 	// Some typical parameters
 	// 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"`
+	Kind  *GoTest_KIND `protobuf:"varint,1,req,name=Kind,enum=testdata.GoTest_KIND" json:"Kind,omitempty"`
+	Table *string      `protobuf:"bytes,2,opt,name=Table" json:"Table,omitempty"`
+	Param *int32       `protobuf:"varint,3,opt,name=Param" json:"Param,omitempty"`
 	// Required, repeated and optional foreign fields.
 	// 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"`
+	RequiredField *GoTestField   `protobuf:"bytes,4,req,name=RequiredField" json:"RequiredField,omitempty"`
+	RepeatedField []*GoTestField `protobuf:"bytes,5,rep,name=RepeatedField" json:"RepeatedField,omitempty"`
+	OptionalField *GoTestField   `protobuf:"bytes,6,opt,name=OptionalField" json:"OptionalField,omitempty"`
 	// Required fields of all basic types
 	// Required fields of all basic types
 	F_BoolRequired    *bool    `protobuf:"varint,10,req,name=F_Bool_required" json:"F_Bool_required,omitempty"`
 	F_BoolRequired    *bool    `protobuf:"varint,10,req,name=F_Bool_required" json:"F_Bool_required,omitempty"`
 	F_Int32Required   *int32   `protobuf:"varint,11,req,name=F_Int32_required" json:"F_Int32_required,omitempty"`
 	F_Int32Required   *int32   `protobuf:"varint,11,req,name=F_Int32_required" json:"F_Int32_required,omitempty"`
@@ -896,7 +936,7 @@ func (m *GoTest) GetOptionalgroup() *GoTest_OptionalGroup {
 
 
 // Required, repeated, and optional groups.
 // Required, repeated, and optional groups.
 type GoTest_RequiredGroup struct {
 type GoTest_RequiredGroup struct {
-	RequiredField    *string `protobuf:"bytes,71,req" json:"RequiredField,omitempty"`
+	RequiredField    *string `protobuf:"bytes,71,req,name=RequiredField" json:"RequiredField,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
 	XXX_unrecognized []byte  `json:"-"`
 }
 }
 
 
@@ -912,7 +952,7 @@ func (m *GoTest_RequiredGroup) GetRequiredField() string {
 }
 }
 
 
 type GoTest_RepeatedGroup struct {
 type GoTest_RepeatedGroup struct {
-	RequiredField    *string `protobuf:"bytes,81,req" json:"RequiredField,omitempty"`
+	RequiredField    *string `protobuf:"bytes,81,req,name=RequiredField" json:"RequiredField,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
 	XXX_unrecognized []byte  `json:"-"`
 }
 }
 
 
@@ -928,7 +968,7 @@ func (m *GoTest_RepeatedGroup) GetRequiredField() string {
 }
 }
 
 
 type GoTest_OptionalGroup struct {
 type GoTest_OptionalGroup struct {
-	RequiredField    *string `protobuf:"bytes,91,req" json:"RequiredField,omitempty"`
+	RequiredField    *string `protobuf:"bytes,91,req,name=RequiredField" json:"RequiredField,omitempty"`
 	XXX_unrecognized []byte  `json:"-"`
 	XXX_unrecognized []byte  `json:"-"`
 }
 }
 
 
@@ -1402,6 +1442,29 @@ var E_Ext_Number = &proto.ExtensionDesc{
 	Tag:           "varint,105,opt,name=number",
 	Tag:           "varint,105,opt,name=number",
 }
 }
 
 
+type DefaultsMessage struct {
+	XXX_extensions   map[int32]proto.Extension `json:"-"`
+	XXX_unrecognized []byte                    `json:"-"`
+}
+
+func (m *DefaultsMessage) Reset()         { *m = DefaultsMessage{} }
+func (m *DefaultsMessage) String() string { return proto.CompactTextString(m) }
+func (*DefaultsMessage) ProtoMessage()    {}
+
+var extRange_DefaultsMessage = []proto.ExtensionRange{
+	{100, 536870911},
+}
+
+func (*DefaultsMessage) ExtensionRangeArray() []proto.ExtensionRange {
+	return extRange_DefaultsMessage
+}
+func (m *DefaultsMessage) ExtensionMap() map[int32]proto.Extension {
+	if m.XXX_extensions == nil {
+		m.XXX_extensions = make(map[int32]proto.Extension)
+	}
+	return m.XXX_extensions
+}
+
 type MyMessageSet struct {
 type MyMessageSet struct {
 	XXX_extensions   map[int32]proto.Extension `json:"-"`
 	XXX_extensions   map[int32]proto.Extension `json:"-"`
 	XXX_unrecognized []byte                    `json:"-"`
 	XXX_unrecognized []byte                    `json:"-"`
@@ -1451,7 +1514,7 @@ func (m *Empty) String() string { return proto.CompactTextString(m) }
 func (*Empty) ProtoMessage()    {}
 func (*Empty) ProtoMessage()    {}
 
 
 type MessageList struct {
 type MessageList struct {
-	Message          []*MessageList_Message `protobuf:"group,1,rep" json:"message,omitempty"`
+	Message          []*MessageList_Message `protobuf:"group,1,rep,name=Message" json:"message,omitempty"`
 	XXX_unrecognized []byte                 `json:"-"`
 	XXX_unrecognized []byte                 `json:"-"`
 }
 }
 
 
@@ -1517,24 +1580,24 @@ func (m *Strings) GetBytesField() []byte {
 type Defaults struct {
 type Defaults struct {
 	// Default-valued fields of all basic types.
 	// Default-valued fields of all basic types.
 	// Same as GoTest, but copied here to make testing easier.
 	// 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"`
+	F_Bool    *bool           `protobuf:"varint,1,opt,name=F_Bool,def=1" json:"F_Bool,omitempty"`
+	F_Int32   *int32          `protobuf:"varint,2,opt,name=F_Int32,def=32" json:"F_Int32,omitempty"`
+	F_Int64   *int64          `protobuf:"varint,3,opt,name=F_Int64,def=64" json:"F_Int64,omitempty"`
+	F_Fixed32 *uint32         `protobuf:"fixed32,4,opt,name=F_Fixed32,def=320" json:"F_Fixed32,omitempty"`
+	F_Fixed64 *uint64         `protobuf:"fixed64,5,opt,name=F_Fixed64,def=640" json:"F_Fixed64,omitempty"`
+	F_Uint32  *uint32         `protobuf:"varint,6,opt,name=F_Uint32,def=3200" json:"F_Uint32,omitempty"`
+	F_Uint64  *uint64         `protobuf:"varint,7,opt,name=F_Uint64,def=6400" json:"F_Uint64,omitempty"`
+	F_Float   *float32        `protobuf:"fixed32,8,opt,name=F_Float,def=314159" json:"F_Float,omitempty"`
+	F_Double  *float64        `protobuf:"fixed64,9,opt,name=F_Double,def=271828" json:"F_Double,omitempty"`
+	F_String  *string         `protobuf:"bytes,10,opt,name=F_String,def=hello, \"world!\"\n" json:"F_String,omitempty"`
+	F_Bytes   []byte          `protobuf:"bytes,11,opt,name=F_Bytes,def=Bignose" json:"F_Bytes,omitempty"`
+	F_Sint32  *int32          `protobuf:"zigzag32,12,opt,name=F_Sint32,def=-32" json:"F_Sint32,omitempty"`
+	F_Sint64  *int64          `protobuf:"zigzag64,13,opt,name=F_Sint64,def=-64" json:"F_Sint64,omitempty"`
+	F_Enum    *Defaults_Color `protobuf:"varint,14,opt,name=F_Enum,enum=testdata.Defaults_Color,def=1" json:"F_Enum,omitempty"`
 	// More fields with crazy defaults.
 	// 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"`
+	F_Pinf *float32 `protobuf:"fixed32,15,opt,name=F_Pinf,def=inf" json:"F_Pinf,omitempty"`
+	F_Ninf *float32 `protobuf:"fixed32,16,opt,name=F_Ninf,def=-inf" json:"F_Ninf,omitempty"`
+	F_Nan  *float32 `protobuf:"fixed32,17,opt,name=F_Nan,def=nan" json:"F_Nan,omitempty"`
 	// Sub-message.
 	// Sub-message.
 	Sub *SubDefaults `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"`
 	Sub *SubDefaults `protobuf:"bytes,18,opt,name=sub" json:"sub,omitempty"`
 	// Redundant but explicit defaults.
 	// Redundant but explicit defaults.
@@ -1799,7 +1862,7 @@ func (m *MoreRepeated) GetFixeds() []uint32 {
 }
 }
 
 
 type GroupOld struct {
 type GroupOld struct {
-	G                *GroupOld_G `protobuf:"group,101,opt" json:"g,omitempty"`
+	G                *GroupOld_G `protobuf:"group,101,opt,name=G" json:"g,omitempty"`
 	XXX_unrecognized []byte      `json:"-"`
 	XXX_unrecognized []byte      `json:"-"`
 }
 }
 
 
@@ -1831,7 +1894,7 @@ func (m *GroupOld_G) GetX() int32 {
 }
 }
 
 
 type GroupNew struct {
 type GroupNew struct {
-	G                *GroupNew_G `protobuf:"group,101,opt" json:"g,omitempty"`
+	G                *GroupNew_G `protobuf:"group,101,opt,name=G" json:"g,omitempty"`
 	XXX_unrecognized []byte      `json:"-"`
 	XXX_unrecognized []byte      `json:"-"`
 }
 }
 
 
@@ -1926,6 +1989,205 @@ func (m *MessageWithMap) GetStrToStr() map[string]string {
 	return nil
 	return nil
 }
 }
 
 
+type Communique struct {
+	MakeMeCry *bool `protobuf:"varint,1,opt,name=make_me_cry" json:"make_me_cry,omitempty"`
+	// This is a oneof, called "union".
+	//
+	// Types that are valid to be assigned to Union:
+	//	*Communique_Number
+	//	*Communique_Name
+	//	*Communique_Data
+	//	*Communique_TempC
+	//	*Communique_Col
+	//	*Communique_Msg
+	Union            isCommunique_Union `protobuf_oneof:"union"`
+	XXX_unrecognized []byte             `json:"-"`
+}
+
+func (m *Communique) Reset()         { *m = Communique{} }
+func (m *Communique) String() string { return proto.CompactTextString(m) }
+func (*Communique) ProtoMessage()    {}
+
+type isCommunique_Union interface {
+	isCommunique_Union()
+}
+
+type Communique_Number struct {
+	Number int32 `protobuf:"varint,5,opt,name=number,oneof"`
+}
+type Communique_Name struct {
+	Name string `protobuf:"bytes,6,opt,name=name,oneof"`
+}
+type Communique_Data struct {
+	Data []byte `protobuf:"bytes,7,opt,name=data,oneof"`
+}
+type Communique_TempC struct {
+	TempC float64 `protobuf:"fixed64,8,opt,name=temp_c,oneof"`
+}
+type Communique_Col struct {
+	Col MyMessage_Color `protobuf:"varint,9,opt,name=col,enum=testdata.MyMessage_Color,oneof"`
+}
+type Communique_Msg struct {
+	Msg *Strings `protobuf:"bytes,10,opt,name=msg,oneof"`
+}
+
+func (*Communique_Number) isCommunique_Union() {}
+func (*Communique_Name) isCommunique_Union()   {}
+func (*Communique_Data) isCommunique_Union()   {}
+func (*Communique_TempC) isCommunique_Union()  {}
+func (*Communique_Col) isCommunique_Union()    {}
+func (*Communique_Msg) isCommunique_Union()    {}
+
+func (m *Communique) GetUnion() isCommunique_Union {
+	if m != nil {
+		return m.Union
+	}
+	return nil
+}
+
+func (m *Communique) GetMakeMeCry() bool {
+	if m != nil && m.MakeMeCry != nil {
+		return *m.MakeMeCry
+	}
+	return false
+}
+
+func (m *Communique) GetNumber() int32 {
+	if x, ok := m.GetUnion().(*Communique_Number); ok {
+		return x.Number
+	}
+	return 0
+}
+
+func (m *Communique) GetName() string {
+	if x, ok := m.GetUnion().(*Communique_Name); ok {
+		return x.Name
+	}
+	return ""
+}
+
+func (m *Communique) GetData() []byte {
+	if x, ok := m.GetUnion().(*Communique_Data); ok {
+		return x.Data
+	}
+	return nil
+}
+
+func (m *Communique) GetTempC() float64 {
+	if x, ok := m.GetUnion().(*Communique_TempC); ok {
+		return x.TempC
+	}
+	return 0
+}
+
+func (m *Communique) GetCol() MyMessage_Color {
+	if x, ok := m.GetUnion().(*Communique_Col); ok {
+		return x.Col
+	}
+	return MyMessage_RED
+}
+
+func (m *Communique) GetMsg() *Strings {
+	if x, ok := m.GetUnion().(*Communique_Msg); ok {
+		return x.Msg
+	}
+	return nil
+}
+
+// XXX_OneofFuncs is for the internal use of the proto package.
+func (*Communique) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), []interface{}) {
+	return _Communique_OneofMarshaler, _Communique_OneofUnmarshaler, []interface{}{
+		(*Communique_Number)(nil),
+		(*Communique_Name)(nil),
+		(*Communique_Data)(nil),
+		(*Communique_TempC)(nil),
+		(*Communique_Col)(nil),
+		(*Communique_Msg)(nil),
+	}
+}
+
+func _Communique_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
+	m := msg.(*Communique)
+	// union
+	switch x := m.Union.(type) {
+	case *Communique_Number:
+		_ = b.EncodeVarint(5<<3 | proto.WireVarint)
+		_ = b.EncodeVarint(uint64(x.Number))
+	case *Communique_Name:
+		_ = b.EncodeVarint(6<<3 | proto.WireBytes)
+		_ = b.EncodeStringBytes(x.Name)
+	case *Communique_Data:
+		_ = b.EncodeVarint(7<<3 | proto.WireBytes)
+		_ = b.EncodeRawBytes(x.Data)
+	case *Communique_TempC:
+		_ = b.EncodeVarint(8<<3 | proto.WireFixed64)
+		_ = b.EncodeFixed64(math.Float64bits(x.TempC))
+	case *Communique_Col:
+		_ = b.EncodeVarint(9<<3 | proto.WireVarint)
+		_ = b.EncodeVarint(uint64(x.Col))
+	case *Communique_Msg:
+		_ = b.EncodeVarint(10<<3 | proto.WireBytes)
+		if err := b.EncodeMessage(x.Msg); err != nil {
+			return err
+		}
+	case nil:
+	default:
+		return fmt.Errorf("Communique.Union has unexpected type %T", x)
+	}
+	return nil
+}
+
+func _Communique_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
+	m := msg.(*Communique)
+	switch tag {
+	case 5: // union.number
+		if wire != proto.WireVarint {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeVarint()
+		m.Union = &Communique_Number{int32(x)}
+		return true, err
+	case 6: // union.name
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeStringBytes()
+		m.Union = &Communique_Name{x}
+		return true, err
+	case 7: // union.data
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeRawBytes(true)
+		m.Union = &Communique_Data{x}
+		return true, err
+	case 8: // union.temp_c
+		if wire != proto.WireFixed64 {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeFixed64()
+		m.Union = &Communique_TempC{math.Float64frombits(x)}
+		return true, err
+	case 9: // union.col
+		if wire != proto.WireVarint {
+			return true, proto.ErrInternalBadWireType
+		}
+		x, err := b.DecodeVarint()
+		m.Union = &Communique_Col{MyMessage_Color(x)}
+		return true, err
+	case 10: // union.msg
+		if wire != proto.WireBytes {
+			return true, proto.ErrInternalBadWireType
+		}
+		msg := new(Strings)
+		err := b.DecodeMessage(msg)
+		m.Union = &Communique_Msg{msg}
+		return true, err
+	default:
+		return false, nil
+	}
+}
+
 var E_Greeting = &proto.ExtensionDesc{
 var E_Greeting = &proto.ExtensionDesc{
 	ExtendedType:  (*MyMessage)(nil),
 	ExtendedType:  (*MyMessage)(nil),
 	ExtensionType: ([]string)(nil),
 	ExtensionType: ([]string)(nil),
@@ -1934,6 +2196,262 @@ var E_Greeting = &proto.ExtensionDesc{
 	Tag:           "bytes,106,rep,name=greeting",
 	Tag:           "bytes,106,rep,name=greeting",
 }
 }
 
 
+var E_NoDefaultDouble = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*float64)(nil),
+	Field:         101,
+	Name:          "testdata.no_default_double",
+	Tag:           "fixed64,101,opt,name=no_default_double",
+}
+
+var E_NoDefaultFloat = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*float32)(nil),
+	Field:         102,
+	Name:          "testdata.no_default_float",
+	Tag:           "fixed32,102,opt,name=no_default_float",
+}
+
+var E_NoDefaultInt32 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int32)(nil),
+	Field:         103,
+	Name:          "testdata.no_default_int32",
+	Tag:           "varint,103,opt,name=no_default_int32",
+}
+
+var E_NoDefaultInt64 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int64)(nil),
+	Field:         104,
+	Name:          "testdata.no_default_int64",
+	Tag:           "varint,104,opt,name=no_default_int64",
+}
+
+var E_NoDefaultUint32 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*uint32)(nil),
+	Field:         105,
+	Name:          "testdata.no_default_uint32",
+	Tag:           "varint,105,opt,name=no_default_uint32",
+}
+
+var E_NoDefaultUint64 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*uint64)(nil),
+	Field:         106,
+	Name:          "testdata.no_default_uint64",
+	Tag:           "varint,106,opt,name=no_default_uint64",
+}
+
+var E_NoDefaultSint32 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int32)(nil),
+	Field:         107,
+	Name:          "testdata.no_default_sint32",
+	Tag:           "zigzag32,107,opt,name=no_default_sint32",
+}
+
+var E_NoDefaultSint64 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int64)(nil),
+	Field:         108,
+	Name:          "testdata.no_default_sint64",
+	Tag:           "zigzag64,108,opt,name=no_default_sint64",
+}
+
+var E_NoDefaultFixed32 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*uint32)(nil),
+	Field:         109,
+	Name:          "testdata.no_default_fixed32",
+	Tag:           "fixed32,109,opt,name=no_default_fixed32",
+}
+
+var E_NoDefaultFixed64 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*uint64)(nil),
+	Field:         110,
+	Name:          "testdata.no_default_fixed64",
+	Tag:           "fixed64,110,opt,name=no_default_fixed64",
+}
+
+var E_NoDefaultSfixed32 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int32)(nil),
+	Field:         111,
+	Name:          "testdata.no_default_sfixed32",
+	Tag:           "fixed32,111,opt,name=no_default_sfixed32",
+}
+
+var E_NoDefaultSfixed64 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int64)(nil),
+	Field:         112,
+	Name:          "testdata.no_default_sfixed64",
+	Tag:           "fixed64,112,opt,name=no_default_sfixed64",
+}
+
+var E_NoDefaultBool = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*bool)(nil),
+	Field:         113,
+	Name:          "testdata.no_default_bool",
+	Tag:           "varint,113,opt,name=no_default_bool",
+}
+
+var E_NoDefaultString = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*string)(nil),
+	Field:         114,
+	Name:          "testdata.no_default_string",
+	Tag:           "bytes,114,opt,name=no_default_string",
+}
+
+var E_NoDefaultBytes = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: ([]byte)(nil),
+	Field:         115,
+	Name:          "testdata.no_default_bytes",
+	Tag:           "bytes,115,opt,name=no_default_bytes",
+}
+
+var E_NoDefaultEnum = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil),
+	Field:         116,
+	Name:          "testdata.no_default_enum",
+	Tag:           "varint,116,opt,name=no_default_enum,enum=testdata.DefaultsMessage_DefaultsEnum",
+}
+
+var E_DefaultDouble = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*float64)(nil),
+	Field:         201,
+	Name:          "testdata.default_double",
+	Tag:           "fixed64,201,opt,name=default_double,def=3.1415",
+}
+
+var E_DefaultFloat = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*float32)(nil),
+	Field:         202,
+	Name:          "testdata.default_float",
+	Tag:           "fixed32,202,opt,name=default_float,def=3.14",
+}
+
+var E_DefaultInt32 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int32)(nil),
+	Field:         203,
+	Name:          "testdata.default_int32",
+	Tag:           "varint,203,opt,name=default_int32,def=42",
+}
+
+var E_DefaultInt64 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int64)(nil),
+	Field:         204,
+	Name:          "testdata.default_int64",
+	Tag:           "varint,204,opt,name=default_int64,def=43",
+}
+
+var E_DefaultUint32 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*uint32)(nil),
+	Field:         205,
+	Name:          "testdata.default_uint32",
+	Tag:           "varint,205,opt,name=default_uint32,def=44",
+}
+
+var E_DefaultUint64 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*uint64)(nil),
+	Field:         206,
+	Name:          "testdata.default_uint64",
+	Tag:           "varint,206,opt,name=default_uint64,def=45",
+}
+
+var E_DefaultSint32 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int32)(nil),
+	Field:         207,
+	Name:          "testdata.default_sint32",
+	Tag:           "zigzag32,207,opt,name=default_sint32,def=46",
+}
+
+var E_DefaultSint64 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int64)(nil),
+	Field:         208,
+	Name:          "testdata.default_sint64",
+	Tag:           "zigzag64,208,opt,name=default_sint64,def=47",
+}
+
+var E_DefaultFixed32 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*uint32)(nil),
+	Field:         209,
+	Name:          "testdata.default_fixed32",
+	Tag:           "fixed32,209,opt,name=default_fixed32,def=48",
+}
+
+var E_DefaultFixed64 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*uint64)(nil),
+	Field:         210,
+	Name:          "testdata.default_fixed64",
+	Tag:           "fixed64,210,opt,name=default_fixed64,def=49",
+}
+
+var E_DefaultSfixed32 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int32)(nil),
+	Field:         211,
+	Name:          "testdata.default_sfixed32",
+	Tag:           "fixed32,211,opt,name=default_sfixed32,def=50",
+}
+
+var E_DefaultSfixed64 = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*int64)(nil),
+	Field:         212,
+	Name:          "testdata.default_sfixed64",
+	Tag:           "fixed64,212,opt,name=default_sfixed64,def=51",
+}
+
+var E_DefaultBool = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*bool)(nil),
+	Field:         213,
+	Name:          "testdata.default_bool",
+	Tag:           "varint,213,opt,name=default_bool,def=1",
+}
+
+var E_DefaultString = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*string)(nil),
+	Field:         214,
+	Name:          "testdata.default_string",
+	Tag:           "bytes,214,opt,name=default_string,def=Hello, string",
+}
+
+var E_DefaultBytes = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: ([]byte)(nil),
+	Field:         215,
+	Name:          "testdata.default_bytes",
+	Tag:           "bytes,215,opt,name=default_bytes,def=Hello, bytes",
+}
+
+var E_DefaultEnum = &proto.ExtensionDesc{
+	ExtendedType:  (*DefaultsMessage)(nil),
+	ExtensionType: (*DefaultsMessage_DefaultsEnum)(nil),
+	Field:         216,
+	Name:          "testdata.default_enum",
+	Tag:           "varint,216,opt,name=default_enum,enum=testdata.DefaultsMessage_DefaultsEnum,def=1",
+}
+
 var E_X201 = &proto.ExtensionDesc{
 var E_X201 = &proto.ExtensionDesc{
 	ExtendedType:  (*MyMessageSet)(nil),
 	ExtendedType:  (*MyMessageSet)(nil),
 	ExtensionType: (*Empty)(nil),
 	ExtensionType: (*Empty)(nil),
@@ -2335,15 +2853,85 @@ var E_X250 = &proto.ExtensionDesc{
 }
 }
 
 
 func init() {
 func init() {
+	proto.RegisterType((*GoEnum)(nil), "testdata.GoEnum")
+	proto.RegisterType((*GoTestField)(nil), "testdata.GoTestField")
+	proto.RegisterType((*GoTest)(nil), "testdata.GoTest")
+	proto.RegisterType((*GoTest_RequiredGroup)(nil), "testdata.GoTest.RequiredGroup")
+	proto.RegisterType((*GoTest_RepeatedGroup)(nil), "testdata.GoTest.RepeatedGroup")
+	proto.RegisterType((*GoTest_OptionalGroup)(nil), "testdata.GoTest.OptionalGroup")
+	proto.RegisterType((*GoSkipTest)(nil), "testdata.GoSkipTest")
+	proto.RegisterType((*GoSkipTest_SkipGroup)(nil), "testdata.GoSkipTest.SkipGroup")
+	proto.RegisterType((*NonPackedTest)(nil), "testdata.NonPackedTest")
+	proto.RegisterType((*PackedTest)(nil), "testdata.PackedTest")
+	proto.RegisterType((*MaxTag)(nil), "testdata.MaxTag")
+	proto.RegisterType((*OldMessage)(nil), "testdata.OldMessage")
+	proto.RegisterType((*OldMessage_Nested)(nil), "testdata.OldMessage.Nested")
+	proto.RegisterType((*NewMessage)(nil), "testdata.NewMessage")
+	proto.RegisterType((*NewMessage_Nested)(nil), "testdata.NewMessage.Nested")
+	proto.RegisterType((*InnerMessage)(nil), "testdata.InnerMessage")
+	proto.RegisterType((*OtherMessage)(nil), "testdata.OtherMessage")
+	proto.RegisterType((*MyMessage)(nil), "testdata.MyMessage")
+	proto.RegisterType((*MyMessage_SomeGroup)(nil), "testdata.MyMessage.SomeGroup")
+	proto.RegisterType((*Ext)(nil), "testdata.Ext")
+	proto.RegisterType((*DefaultsMessage)(nil), "testdata.DefaultsMessage")
+	proto.RegisterType((*MyMessageSet)(nil), "testdata.MyMessageSet")
+	proto.RegisterType((*Empty)(nil), "testdata.Empty")
+	proto.RegisterType((*MessageList)(nil), "testdata.MessageList")
+	proto.RegisterType((*MessageList_Message)(nil), "testdata.MessageList.Message")
+	proto.RegisterType((*Strings)(nil), "testdata.Strings")
+	proto.RegisterType((*Defaults)(nil), "testdata.Defaults")
+	proto.RegisterType((*SubDefaults)(nil), "testdata.SubDefaults")
+	proto.RegisterType((*RepeatedEnum)(nil), "testdata.RepeatedEnum")
+	proto.RegisterType((*MoreRepeated)(nil), "testdata.MoreRepeated")
+	proto.RegisterType((*GroupOld)(nil), "testdata.GroupOld")
+	proto.RegisterType((*GroupOld_G)(nil), "testdata.GroupOld.G")
+	proto.RegisterType((*GroupNew)(nil), "testdata.GroupNew")
+	proto.RegisterType((*GroupNew_G)(nil), "testdata.GroupNew.G")
+	proto.RegisterType((*FloatingPoint)(nil), "testdata.FloatingPoint")
+	proto.RegisterType((*MessageWithMap)(nil), "testdata.MessageWithMap")
+	proto.RegisterType((*Communique)(nil), "testdata.Communique")
 	proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value)
 	proto.RegisterEnum("testdata.FOO", FOO_name, FOO_value)
 	proto.RegisterEnum("testdata.GoTest_KIND", GoTest_KIND_name, GoTest_KIND_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.MyMessage_Color", MyMessage_Color_name, MyMessage_Color_value)
+	proto.RegisterEnum("testdata.DefaultsMessage_DefaultsEnum", DefaultsMessage_DefaultsEnum_name, DefaultsMessage_DefaultsEnum_value)
 	proto.RegisterEnum("testdata.Defaults_Color", Defaults_Color_name, Defaults_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.RegisterEnum("testdata.RepeatedEnum_Color", RepeatedEnum_Color_name, RepeatedEnum_Color_value)
 	proto.RegisterExtension(E_Ext_More)
 	proto.RegisterExtension(E_Ext_More)
 	proto.RegisterExtension(E_Ext_Text)
 	proto.RegisterExtension(E_Ext_Text)
 	proto.RegisterExtension(E_Ext_Number)
 	proto.RegisterExtension(E_Ext_Number)
 	proto.RegisterExtension(E_Greeting)
 	proto.RegisterExtension(E_Greeting)
+	proto.RegisterExtension(E_NoDefaultDouble)
+	proto.RegisterExtension(E_NoDefaultFloat)
+	proto.RegisterExtension(E_NoDefaultInt32)
+	proto.RegisterExtension(E_NoDefaultInt64)
+	proto.RegisterExtension(E_NoDefaultUint32)
+	proto.RegisterExtension(E_NoDefaultUint64)
+	proto.RegisterExtension(E_NoDefaultSint32)
+	proto.RegisterExtension(E_NoDefaultSint64)
+	proto.RegisterExtension(E_NoDefaultFixed32)
+	proto.RegisterExtension(E_NoDefaultFixed64)
+	proto.RegisterExtension(E_NoDefaultSfixed32)
+	proto.RegisterExtension(E_NoDefaultSfixed64)
+	proto.RegisterExtension(E_NoDefaultBool)
+	proto.RegisterExtension(E_NoDefaultString)
+	proto.RegisterExtension(E_NoDefaultBytes)
+	proto.RegisterExtension(E_NoDefaultEnum)
+	proto.RegisterExtension(E_DefaultDouble)
+	proto.RegisterExtension(E_DefaultFloat)
+	proto.RegisterExtension(E_DefaultInt32)
+	proto.RegisterExtension(E_DefaultInt64)
+	proto.RegisterExtension(E_DefaultUint32)
+	proto.RegisterExtension(E_DefaultUint64)
+	proto.RegisterExtension(E_DefaultSint32)
+	proto.RegisterExtension(E_DefaultSint64)
+	proto.RegisterExtension(E_DefaultFixed32)
+	proto.RegisterExtension(E_DefaultFixed64)
+	proto.RegisterExtension(E_DefaultSfixed32)
+	proto.RegisterExtension(E_DefaultSfixed64)
+	proto.RegisterExtension(E_DefaultBool)
+	proto.RegisterExtension(E_DefaultString)
+	proto.RegisterExtension(E_DefaultBytes)
+	proto.RegisterExtension(E_DefaultEnum)
 	proto.RegisterExtension(E_X201)
 	proto.RegisterExtension(E_X201)
 	proto.RegisterExtension(E_X202)
 	proto.RegisterExtension(E_X202)
 	proto.RegisterExtension(E_X203)
 	proto.RegisterExtension(E_X203)

+ 59 - 0
Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata/test.proto

@@ -277,6 +277,51 @@ extend MyMessage {
   repeated string greeting = 106;
   repeated string greeting = 106;
 }
 }
 
 
+message DefaultsMessage {
+  enum DefaultsEnum {
+    ZERO = 0;
+    ONE = 1;
+    TWO = 2;
+  };
+  extensions 100 to max;
+}
+
+extend DefaultsMessage {
+  optional double no_default_double = 101;
+  optional float no_default_float = 102;
+  optional int32 no_default_int32 = 103;
+  optional int64 no_default_int64 = 104;
+  optional uint32 no_default_uint32 = 105;
+  optional uint64 no_default_uint64 = 106;
+  optional sint32 no_default_sint32 = 107;
+  optional sint64 no_default_sint64 = 108;
+  optional fixed32 no_default_fixed32 = 109;
+  optional fixed64 no_default_fixed64 = 110;
+  optional sfixed32 no_default_sfixed32 = 111;
+  optional sfixed64 no_default_sfixed64 = 112;
+  optional bool no_default_bool = 113;
+  optional string no_default_string = 114;
+  optional bytes no_default_bytes = 115;
+  optional DefaultsMessage.DefaultsEnum no_default_enum = 116;
+
+  optional double default_double = 201 [default = 3.1415];
+  optional float default_float = 202 [default = 3.14];
+  optional int32 default_int32 = 203 [default = 42];
+  optional int64 default_int64 = 204 [default = 43];
+  optional uint32 default_uint32 = 205 [default = 44];
+  optional uint64 default_uint64 = 206 [default = 45];
+  optional sint32 default_sint32 = 207 [default = 46];
+  optional sint64 default_sint64 = 208 [default = 47];
+  optional fixed32 default_fixed32 = 209 [default = 48];
+  optional fixed64 default_fixed64 = 210 [default = 49];
+  optional sfixed32 default_sfixed32 = 211 [default = 50];
+  optional sfixed64 default_sfixed64 = 212 [default = 51];
+  optional bool default_bool = 213 [default = true];
+  optional string default_string = 214 [default = "Hello, string"];
+  optional bytes default_bytes = 215 [default = "Hello, bytes"];
+  optional DefaultsMessage.DefaultsEnum default_enum = 216 [default = ONE];
+}
+
 message MyMessageSet {
 message MyMessageSet {
   option message_set_wire_format = true;
   option message_set_wire_format = true;
   extensions 100 to max;
   extensions 100 to max;
@@ -433,3 +478,17 @@ message MessageWithMap {
   map<bool, bytes> byte_mapping = 3;
   map<bool, bytes> byte_mapping = 3;
   map<string, string> str_to_str = 4;
   map<string, string> str_to_str = 4;
 }
 }
+
+message Communique {
+  optional bool make_me_cry = 1;
+
+  // This is a oneof, called "union".
+  oneof union {
+    int32 number = 5;
+    string name = 6;
+    bytes data = 7;
+    double temp_c = 8;
+    MyMessage.Color col = 9;
+    Strings msg = 10;
+  }
+}

+ 67 - 98
Godeps/_workspace/src/github.com/gogo/protobuf/proto/text.go

@@ -42,11 +42,11 @@ import (
 	"bufio"
 	"bufio"
 	"bytes"
 	"bytes"
 	"encoding"
 	"encoding"
+	"errors"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"log"
 	"log"
 	"math"
 	"math"
-	"os"
 	"reflect"
 	"reflect"
 	"sort"
 	"sort"
 	"strings"
 	"strings"
@@ -175,20 +175,12 @@ func writeName(w *textWriter, props *Properties) error {
 	return nil
 	return nil
 }
 }
 
 
-var (
-	messageSetType = reflect.TypeOf((*MessageSet)(nil)).Elem()
-)
-
 // raw is the interface satisfied by RawMessage.
 // raw is the interface satisfied by RawMessage.
 type raw interface {
 type raw interface {
 	Bytes() []byte
 	Bytes() []byte
 }
 }
 
 
 func writeStruct(w *textWriter, sv reflect.Value) error {
 func writeStruct(w *textWriter, sv reflect.Value) error {
-	if sv.Type() == messageSetType {
-		return writeMessageSet(w, sv.Addr().Interface().(*MessageSet))
-	}
-
 	st := sv.Type()
 	st := sv.Type()
 	sprops := GetProperties(st)
 	sprops := GetProperties(st)
 	for i := 0; i < sv.NumField(); i++ {
 	for i := 0; i < sv.NumField(); i++ {
@@ -255,7 +247,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
 		}
 		}
 		if fv.Kind() == reflect.Map {
 		if fv.Kind() == reflect.Map {
 			// Map fields are rendered as a repeated struct with key/value fields.
 			// Map fields are rendered as a repeated struct with key/value fields.
-			keys := fv.MapKeys() // TODO: should we sort these for deterministic output?
+			keys := fv.MapKeys()
 			sort.Sort(mapKeys(keys))
 			sort.Sort(mapKeys(keys))
 			for _, key := range keys {
 			for _, key := range keys {
 				val := fv.MapIndex(key)
 				val := fv.MapIndex(key)
@@ -292,20 +284,23 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
 				if err := w.WriteByte('\n'); err != nil {
 				if err := w.WriteByte('\n'); err != nil {
 					return err
 					return err
 				}
 				}
-				// value
-				if _, err := w.WriteString("value:"); err != nil {
-					return err
-				}
-				if !w.compact {
-					if err := w.WriteByte(' '); err != nil {
+				// nil values aren't legal, but we can avoid panicking because of them.
+				if val.Kind() != reflect.Ptr || !val.IsNil() {
+					// 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
 						return err
 					}
 					}
-				}
-				if err := writeAny(w, val, props.mvalprop); err != nil {
-					return err
-				}
-				if err := w.WriteByte('\n'); err != nil {
-					return err
 				}
 				}
 				// close struct
 				// close struct
 				w.unindent()
 				w.unindent()
@@ -324,26 +319,33 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
 		}
 		}
 		if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
 		if props.proto3 && fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
 			// proto3 non-repeated scalar field; skip if zero value
 			// 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 {
+			if isProto3Zero(fv) {
+				continue
+			}
+		}
+
+		if fv.Kind() == reflect.Interface {
+			// Check if it is a oneof.
+			if st.Field(i).Tag.Get("protobuf_oneof") != "" {
+				// fv is nil, or holds a pointer to generated struct.
+				// That generated struct has exactly one field,
+				// which has a protobuf struct tag.
+				if fv.IsNil() {
 					continue
 					continue
 				}
 				}
-			case reflect.String:
-				if fv.String() == "" {
-					continue
+				inner := fv.Elem().Elem() // interface -> *T -> T
+				tag := inner.Type().Field(0).Tag.Get("protobuf")
+				props.Parse(tag) // Overwrite the outer props.
+				// Write the value in the oneof, not the oneof itself.
+				fv = inner.Field(0)
+
+				// Special case to cope with malformed messages gracefully:
+				// If the value in the oneof is a nil pointer, don't panic
+				// in writeAny.
+				if fv.Kind() == reflect.Ptr && fv.IsNil() {
+					// Use errors.New so writeAny won't render quotes.
+					msg := errors.New("/* nil */")
+					fv = reflect.ValueOf(&msg).Elem()
 				}
 				}
 			}
 			}
 		}
 		}
@@ -377,7 +379,13 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
 	}
 	}
 
 
 	// Extensions (the XXX_extensions field).
 	// Extensions (the XXX_extensions field).
-	pv := sv.Addr()
+	pv := sv
+	if pv.CanAddr() {
+		pv = sv.Addr()
+	} else {
+		pv = reflect.New(sv.Type())
+		pv.Elem().Set(sv)
+	}
 	if pv.Type().Implements(extendableProtoType) {
 	if pv.Type().Implements(extendableProtoType) {
 		if err := writeExtensions(w, pv); err != nil {
 		if err := writeExtensions(w, pv); err != nil {
 			return err
 			return err
@@ -413,15 +421,17 @@ func writeAny(w *textWriter, v reflect.Value, props *Properties) error {
 	v = reflect.Indirect(v)
 	v = reflect.Indirect(v)
 
 
 	if props != nil && len(props.CustomType) > 0 {
 	if props != nil && len(props.CustomType) > 0 {
-		var custom Marshaler = v.Interface().(Marshaler)
-		data, err := custom.Marshal()
-		if err != nil {
-			return err
-		}
-		if err := writeString(w, string(data)); err != nil {
-			return err
+		custom, ok := v.Interface().(Marshaler)
+		if ok {
+			data, err := custom.Marshal()
+			if err != nil {
+				return err
+			}
+			if err := writeString(w, string(data)); err != nil {
+				return err
+			}
+			return nil
 		}
 		}
-		return nil
 	}
 	}
 
 
 	// Floats have special cases.
 	// Floats have special cases.
@@ -538,44 +548,6 @@ func writeString(w *textWriter, s string) error {
 	return w.WriteByte('"')
 	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) {
 func writeUnknownStruct(w *textWriter, data []byte) (err error) {
 	if !w.compact {
 	if !w.compact {
 		if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
 		if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
@@ -586,19 +558,19 @@ func writeUnknownStruct(w *textWriter, data []byte) (err error) {
 	for b.index < len(b.buf) {
 	for b.index < len(b.buf) {
 		x, err := b.DecodeVarint()
 		x, err := b.DecodeVarint()
 		if err != nil {
 		if err != nil {
-			_, err := fmt.Fprintf(w, "/* %v */\n", err)
-			return err
+			_, ferr := fmt.Fprintf(w, "/* %v */\n", err)
+			return ferr
 		}
 		}
 		wire, tag := x&7, x>>3
 		wire, tag := x&7, x>>3
 		if wire == WireEndGroup {
 		if wire == WireEndGroup {
 			w.unindent()
 			w.unindent()
-			if _, err := w.Write(endBraceNewline); err != nil {
-				return err
+			if _, werr := w.Write(endBraceNewline); werr != nil {
+				return werr
 			}
 			}
 			continue
 			continue
 		}
 		}
-		if _, err := fmt.Fprint(w, tag); err != nil {
-			return err
+		if _, ferr := fmt.Fprint(w, tag); ferr != nil {
+			return ferr
 		}
 		}
 		if wire != WireStartGroup {
 		if wire != WireStartGroup {
 			if err := w.WriteByte(':'); err != nil {
 			if err := w.WriteByte(':'); err != nil {
@@ -636,7 +608,7 @@ func writeUnknownStruct(w *textWriter, data []byte) (err error) {
 		if err != nil {
 		if err != nil {
 			return err
 			return err
 		}
 		}
-		if err = w.WriteByte('\n'); err != nil {
+		if err := w.WriteByte('\n'); err != nil {
 			return err
 			return err
 		}
 		}
 	}
 	}
@@ -701,10 +673,7 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
 
 
 		pb, err := GetExtension(ep, desc)
 		pb, err := GetExtension(ep, desc)
 		if err != nil {
 		if err != nil {
-			if _, err := fmt.Fprintln(os.Stderr, "proto: failed getting extension: ", err); err != nil {
-				return err
-			}
-			continue
+			return fmt.Errorf("failed getting extension: %v", err)
 		}
 		}
 
 
 		// Repeated extensions will appear as a slice.
 		// Repeated extensions will appear as a slice.

+ 135 - 94
Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser.go

@@ -179,7 +179,7 @@ func (p *textParser) advance() {
 		}
 		}
 		unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
 		unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
 		if err != nil {
 		if err != nil {
-			p.errorf("invalid quoted string %v", p.s[0:i+1])
+			p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err)
 			return
 			return
 		}
 		}
 		p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
 		p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
@@ -390,8 +390,7 @@ func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSet
 }
 }
 
 
 // Returns the index in the struct for the named field, as well as the parsed tag properties.
 // 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)
+func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) {
 	i, ok := sprops.decoderOrigNames[name]
 	i, ok := sprops.decoderOrigNames[name]
 	if ok {
 	if ok {
 		return i, sprops.Prop[i], true
 		return i, sprops.Prop[i], true
@@ -443,7 +442,8 @@ func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseEr
 
 
 func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 	st := sv.Type()
 	st := sv.Type()
-	reqCount := GetProperties(st).reqCount
+	sprops := GetProperties(st)
+	reqCount := sprops.reqCount
 	var reqFieldErr error
 	var reqFieldErr error
 	fieldSet := make(map[string]bool)
 	fieldSet := make(map[string]bool)
 	// A struct is a sequence of "name: value", terminated by one of
 	// A struct is a sequence of "name: value", terminated by one of
@@ -525,99 +525,113 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 				sl = reflect.Append(sl, ext)
 				sl = reflect.Append(sl, ext)
 				SetExtension(ep, desc, sl.Interface())
 				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)
+			if err := p.consumeOptionalSeparator(); err != nil {
+				return err
 			}
 			}
+			continue
+		}
 
 
-			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
-				}
+		// This is a normal, non-extension field.
+		name := tok.value
+		var dst reflect.Value
+		fi, props, ok := structFieldByName(sprops, name)
+		if ok {
+			dst = sv.Field(fi)
+		} else if oop, ok := sprops.OneofTypes[name]; ok {
+			// It is a oneof.
+			props = oop.Prop
+			nv := reflect.New(oop.Type.Elem())
+			dst = nv.Elem().Field(0)
+			sv.Field(oop.Field).Set(nv)
+		}
+		if !dst.IsValid() {
+			return p.errorf("unknown field name %q in %v", name, st)
+		}
 
 
-				dst.SetMapIndex(key, val)
-				continue
+		if dst.Kind() == reflect.Map {
+			// Consume any colon.
+			if err := p.checkForColon(props, dst.Type()); err != nil {
+				return err
 			}
 			}
 
 
-			// 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)
+			// Construct the map if it doesn't already exist.
+			if dst.IsNil() {
+				dst.Set(reflect.MakeMap(dst.Type()))
 			}
 			}
-
-			if err := p.checkForColon(props, st.Field(fi).Type); err != nil {
+			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
 				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--
+			if err := p.consumeToken(":"); err != nil {
+				return err
+			}
+			if err := p.readAny(key, props.mkeyprop); err != nil {
+				return err
+			}
+			if err := p.consumeOptionalSeparator(); 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.consumeOptionalSeparator(); err != nil {
+				return err
+			}
+			if err := p.consumeToken(terminator); err != nil {
+				return err
 			}
 			}
+
+			dst.SetMapIndex(key, val)
+			continue
 		}
 		}
 
 
-		// For backward compatibility, permit a semicolon or comma after a field.
-		tok = p.next()
-		if tok.err != nil {
-			return tok.err
+		// 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, dst.Type()); err != nil {
+			return err
 		}
 		}
-		if tok.value != ";" && tok.value != "," {
-			p.back()
+
+		// 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--
+		}
+
+		if err := p.consumeOptionalSeparator(); err != nil {
+			return err
 		}
 		}
+
 	}
 	}
 
 
 	if reqCount > 0 {
 	if reqCount > 0 {
@@ -626,6 +640,19 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 	return reqFieldErr
 	return reqFieldErr
 }
 }
 
 
+// consumeOptionalSeparator consumes an optional semicolon or comma.
+// It is used in readStruct to provide backward compatibility.
+func (p *textParser) consumeOptionalSeparator() error {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value != ";" && tok.value != "," {
+		p.back()
+	}
+	return nil
+}
+
 func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 	tok := p.next()
 	tok := p.next()
 	if tok.err != nil {
 	if tok.err != nil {
@@ -688,18 +715,32 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 			fv.Set(reflect.ValueOf(bytes))
 			fv.Set(reflect.ValueOf(bytes))
 			return nil
 			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)
+		// Repeated field.
+		if tok.value == "[" {
+			// Repeated field with list notation, like [1,2,3].
+			for {
+				fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
+				err := p.readAny(fv.Index(fv.Len()-1), props)
+				if err != nil {
+					return err
+				}
+				tok := p.next()
+				if tok.err != nil {
+					return tok.err
+				}
+				if tok.value == "]" {
+					break
+				}
+				if tok.value != "," {
+					return p.errorf("Expected ']' or ',' found %q", tok.value)
+				}
+			}
+			return nil
 		}
 		}
-		fv.SetLen(flen + 1)
-
-		// Read one.
+		// One value of the repeated field.
 		p.back()
 		p.back()
-		return p.readAny(fv.Index(flen), props)
+		fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
+		return p.readAny(fv.Index(fv.Len()-1), props)
 	case reflect.Bool:
 	case reflect.Bool:
 		// Either "true", "false", 1 or 0.
 		// Either "true", "false", 1 or 0.
 		switch tok.value {
 		switch tok.value {

+ 23 - 2
Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_parser_test.go

@@ -152,7 +152,7 @@ var unMarshalTextTests = []UnmarshalTextTest{
 	// Bad quoted string
 	// Bad quoted string
 	{
 	{
 		in:  `inner: < host: "\0" >` + "\n",
 		in:  `inner: < host: "\0" >` + "\n",
-		err: `line 1.15: invalid quoted string "\0"`,
+		err: `line 1.15: invalid quoted string "\0": \0 requires 2 following digits`,
 	},
 	},
 
 
 	// Number too large for int64
 	// Number too large for int64
@@ -256,6 +256,15 @@ var unMarshalTextTests = []UnmarshalTextTest{
 		},
 		},
 	},
 	},
 
 
+	// Repeated field with list notation
+	{
+		in: `count:42 pet: ["horsey", "bunny"]`,
+		out: &MyMessage{
+			Count: Int32(42),
+			Pet:   []string{"horsey", "bunny"},
+		},
+	},
+
 	// Repeated message with/without colon and <>/{}
 	// Repeated message with/without colon and <>/{}
 	{
 	{
 		in: `count:42 others:{} others{} others:<> others:{}`,
 		in: `count:42 others:{} others{} others:<> others:{}`,
@@ -462,7 +471,7 @@ func TestProto3TextParsing(t *testing.T) {
 func TestMapParsing(t *testing.T) {
 func TestMapParsing(t *testing.T) {
 	m := new(MessageWithMap)
 	m := new(MessageWithMap)
 	const in = `name_mapping:<key:1234 value:"Feist"> name_mapping:<key:1 value:"Beatles">` +
 	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:-4, value:<f: 2.0>,>` + // separating commas are okay
 		`msg_mapping<key:-2 value<f: 4.0>>` + // no colon after "value"
 		`msg_mapping<key:-2 value<f: 4.0>>` + // no colon after "value"
 		`byte_mapping:<key:true value:"so be it">`
 		`byte_mapping:<key:true value:"so be it">`
 	want := &MessageWithMap{
 	want := &MessageWithMap{
@@ -486,6 +495,18 @@ func TestMapParsing(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestOneofParsing(t *testing.T) {
+	const in = `name:"Shrek"`
+	m := new(Communique)
+	want := &Communique{Union: &Communique_Name{"Shrek"}}
+	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
 var benchInput string
 
 
 func init() {
 func init() {

+ 42 - 3
Godeps/_workspace/src/github.com/gogo/protobuf/proto/text_test.go

@@ -40,6 +40,7 @@ import (
 	"testing"
 	"testing"
 
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto"
+
 	proto3pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto"
 	proto3pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto/proto3_proto"
 	pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata"
 	pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/gogo/protobuf/proto/testdata"
 )
 )
@@ -207,6 +208,30 @@ func TestMarshalTextUnknownEnum(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestTextOneof(t *testing.T) {
+	tests := []struct {
+		m    proto.Message
+		want string
+	}{
+		// zero message
+		{&pb.Communique{}, ``},
+		// scalar field
+		{&pb.Communique{Union: &pb.Communique_Number{Number: 4}}, `number:4`},
+		// message field
+		{&pb.Communique{Union: &pb.Communique_Msg{
+			Msg: &pb.Strings{StringField: proto.String("why hello!")},
+		}}, `msg:<string_field:"why hello!" >`},
+		// bad oneof (should not panic)
+		{&pb.Communique{Union: &pb.Communique_Msg{Msg: nil}}, `msg:/* nil */`},
+	}
+	for _, test := range tests {
+		got := strings.TrimSpace(test.m.String())
+		if got != test.want {
+			t.Errorf("\n got %s\nwant %s", got, test.want)
+		}
+	}
+}
+
 func BenchmarkMarshalTextBuffered(b *testing.B) {
 func BenchmarkMarshalTextBuffered(b *testing.B) {
 	buf := new(bytes.Buffer)
 	buf := new(bytes.Buffer)
 	m := newTestMessage()
 	m := newTestMessage()
@@ -420,10 +445,24 @@ func TestProto3Text(t *testing.T) {
 		{&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`},
 		{&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`},
 		// empty map
 		// empty map
 		{&pb.MessageWithMap{}, ``},
 		{&pb.MessageWithMap{}, ``},
-		// non-empty map; current map format is the same as a repeated struct
+		// non-empty map; map format is the same as a repeated struct,
+		// and they are sorted by key (numerically for numeric keys).
+		{
+			&pb.MessageWithMap{NameMapping: map[int32]string{
+				-1:      "Negatory",
+				7:       "Lucky",
+				1234:    "Feist",
+				6345789: "Otis",
+			}},
+			`name_mapping:<key:-1 value:"Negatory" > ` +
+				`name_mapping:<key:7 value:"Lucky" > ` +
+				`name_mapping:<key:1234 value:"Feist" > ` +
+				`name_mapping:<key:6345789 value:"Otis" >`,
+		},
+		// map with nil value; not well-defined, but we shouldn't crash
 		{
 		{
-			&pb.MessageWithMap{NameMapping: map[int32]string{1234: "Feist"}},
-			`name_mapping:<key:1234 value:"Feist" >`,
+			&pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{7: nil}},
+			`msg_mapping:<key:7 >`,
 		},
 		},
 	}
 	}
 	for _, test := range tests {
 	for _, test := range tests {

+ 31 - 0
Godeps/_workspace/src/github.com/golang/protobuf/LICENSE

@@ -0,0 +1,31 @@
+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.
+

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

@@ -39,5 +39,5 @@ test: install generate-test-pbs
 generate-test-pbs:
 generate-test-pbs:
 	make install
 	make install
 	make -C testdata
 	make -C testdata
-	make -C proto3_proto
+	protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto
 	make
 	make

+ 122 - 12
Godeps/_workspace/src/github.com/golang/protobuf/proto/all_test.go

@@ -44,8 +44,8 @@ import (
 	"testing"
 	"testing"
 	"time"
 	"time"
 
 
-	. "./testdata"
 	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
 	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata"
 )
 )
 
 
 var globalO *Buffer
 var globalO *Buffer
@@ -401,17 +401,18 @@ type fakeMarshaler struct {
 	err error
 	err error
 }
 }
 
 
-func (f fakeMarshaler) Marshal() ([]byte, error) {
-	return f.b, f.err
-}
+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()                   {}
 
 
-func (f fakeMarshaler) String() string {
-	return fmt.Sprintf("Bytes: %v Error: %v", f.b, f.err)
+type msgWithFakeMarshaler struct {
+	M *fakeMarshaler `protobuf:"bytes,1,opt,name=fake"`
 }
 }
 
 
-func (f fakeMarshaler) ProtoMessage() {}
-
-func (f fakeMarshaler) Reset() {}
+func (m *msgWithFakeMarshaler) String() string { return CompactTextString(m) }
+func (m *msgWithFakeMarshaler) ProtoMessage()  {}
+func (m *msgWithFakeMarshaler) Reset()         {}
 
 
 // Simple tests for proto messages that implement the Marshaler interface.
 // Simple tests for proto messages that implement the Marshaler interface.
 func TestMarshalerEncoding(t *testing.T) {
 func TestMarshalerEncoding(t *testing.T) {
@@ -423,7 +424,7 @@ func TestMarshalerEncoding(t *testing.T) {
 	}{
 	}{
 		{
 		{
 			name: "Marshaler that fails",
 			name: "Marshaler that fails",
-			m: fakeMarshaler{
+			m: &fakeMarshaler{
 				err: errors.New("some marshal err"),
 				err: errors.New("some marshal err"),
 				b:   []byte{5, 6, 7},
 				b:   []byte{5, 6, 7},
 			},
 			},
@@ -431,9 +432,25 @@ func TestMarshalerEncoding(t *testing.T) {
 			want:    nil,
 			want:    nil,
 			wantErr: errors.New("some marshal err"),
 			wantErr: errors.New("some marshal err"),
 		},
 		},
+		{
+			name: "Marshaler that fails with RequiredNotSetError",
+			m: &msgWithFakeMarshaler{
+				M: &fakeMarshaler{
+					err: &RequiredNotSetError{},
+					b:   []byte{5, 6, 7},
+				},
+			},
+			// Since there's an error that can be continued after,
+			// the buffer should be written.
+			want: []byte{
+				10, 3, // for &msgWithFakeMarshaler
+				5, 6, 7, // for &fakeMarshaler
+			},
+			wantErr: &RequiredNotSetError{},
+		},
 		{
 		{
 			name: "Marshaler that succeeds",
 			name: "Marshaler that succeeds",
-			m: fakeMarshaler{
+			m: &fakeMarshaler{
 				b: []byte{0, 1, 2, 3, 4, 127, 255},
 				b: []byte{0, 1, 2, 3, 4, 127, 255},
 			},
 			},
 			want:    []byte{0, 1, 2, 3, 4, 127, 255},
 			want:    []byte{0, 1, 2, 3, 4, 127, 255},
@@ -443,6 +460,10 @@ func TestMarshalerEncoding(t *testing.T) {
 	for _, test := range tests {
 	for _, test := range tests {
 		b := NewBuffer(nil)
 		b := NewBuffer(nil)
 		err := b.Marshal(test.m)
 		err := b.Marshal(test.m)
+		if _, ok := err.(*RequiredNotSetError); ok {
+			// We're not in package proto, so we can only assert the type in this case.
+			err = &RequiredNotSetError{}
+		}
 		if !reflect.DeepEqual(test.wantErr, err) {
 		if !reflect.DeepEqual(test.wantErr, err) {
 			t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr)
 			t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr)
 		}
 		}
@@ -1252,7 +1273,8 @@ func TestProto1RepeatedGroup(t *testing.T) {
 	}
 	}
 
 
 	o := old()
 	o := old()
-	if err := o.Marshal(pb); err != ErrRepeatedHasNil {
+	err := o.Marshal(pb)
+	if err == nil || !strings.Contains(err.Error(), "repeated field Message has nil") {
 		t.Fatalf("unexpected or no error when marshaling: %v", err)
 		t.Fatalf("unexpected or no error when marshaling: %v", err)
 	}
 	}
 }
 }
@@ -1441,6 +1463,17 @@ func TestSetDefaultsWithRepeatedSubMessage(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestSetDefaultWithRepeatedNonMessage(t *testing.T) {
+	m := &MyMessage{
+		Pet: []string{"turtle", "wombat"},
+	}
+	expected := Clone(m)
+	SetDefaults(m)
+	if !Equal(m, expected) {
+		t.Errorf("\n got %v\nwant %v", m, expected)
+	}
+}
+
 func TestMaximumTagNumber(t *testing.T) {
 func TestMaximumTagNumber(t *testing.T) {
 	m := &MaxTag{
 	m := &MaxTag{
 		LastField: String("natural goat essence"),
 		LastField: String("natural goat essence"),
@@ -1913,6 +1946,83 @@ func TestMapFieldRoundTrips(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestMapFieldWithNil(t *testing.T) {
+	m := &MessageWithMap{
+		MsgMapping: map[int64]*FloatingPoint{
+			1: nil,
+		},
+	}
+	b, err := Marshal(m)
+	if err == nil {
+		t.Fatalf("Marshal of bad map should have failed, got these bytes: %v", b)
+	}
+}
+
+func TestOneof(t *testing.T) {
+	m := &Communique{}
+	b, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal of empty message with oneof: %v", err)
+	}
+	if len(b) != 0 {
+		t.Errorf("Marshal of empty message yielded too many bytes: %v", b)
+	}
+
+	m = &Communique{
+		Union: &Communique_Name{"Barry"},
+	}
+
+	// Round-trip.
+	b, err = Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal of message with oneof: %v", err)
+	}
+	if len(b) != 7 { // name tag/wire (1) + name len (1) + name (5)
+		t.Errorf("Incorrect marshal of message with oneof: %v", b)
+	}
+	m.Reset()
+	if err := Unmarshal(b, m); err != nil {
+		t.Fatalf("Unmarshal of message with oneof: %v", err)
+	}
+	if x, ok := m.Union.(*Communique_Name); !ok || x.Name != "Barry" {
+		t.Errorf("After round trip, Union = %+v", m.Union)
+	}
+	if name := m.GetName(); name != "Barry" {
+		t.Errorf("After round trip, GetName = %q, want %q", name, "Barry")
+	}
+
+	// Let's try with a message in the oneof.
+	m.Union = &Communique_Msg{&Strings{StringField: String("deep deep string")}}
+	b, err = Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal of message with oneof set to message: %v", err)
+	}
+	if len(b) != 20 { // msg tag/wire (1) + msg len (1) + msg (1 + 1 + 16)
+		t.Errorf("Incorrect marshal of message with oneof set to message: %v", b)
+	}
+	m.Reset()
+	if err := Unmarshal(b, m); err != nil {
+		t.Fatalf("Unmarshal of message with oneof set to message: %v", err)
+	}
+	ss, ok := m.Union.(*Communique_Msg)
+	if !ok || ss.Msg.GetStringField() != "deep deep string" {
+		t.Errorf("After round trip with oneof set to message, Union = %+v", m.Union)
+	}
+}
+
+func TestInefficientPackedBool(t *testing.T) {
+	// https://github.com/golang/protobuf/issues/76
+	inp := []byte{
+		0x12, 0x02, // 0x12 = 2<<3|2; 2 bytes
+		// Usually a bool should take a single byte,
+		// but it is permitted to be any varint.
+		0xb9, 0x30,
+	}
+	if err := Unmarshal(inp, new(MoreRepeated)); err != nil {
+		t.Error(err)
+	}
+}
+
 // Benchmarks
 // Benchmarks
 
 
 func testMsg() *GoTest {
 func testMsg() *GoTest {

+ 33 - 7
Godeps/_workspace/src/github.com/golang/protobuf/proto/clone.go

@@ -30,7 +30,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 // Protocol buffer deep copy and merge.
 // Protocol buffer deep copy and merge.
-// TODO: MessageSet and RawMessage.
+// TODO: RawMessage.
 
 
 package proto
 package proto
 
 
@@ -75,12 +75,13 @@ func Merge(dst, src Message) {
 }
 }
 
 
 func mergeStruct(out, in reflect.Value) {
 func mergeStruct(out, in reflect.Value) {
+	sprop := GetProperties(in.Type())
 	for i := 0; i < in.NumField(); i++ {
 	for i := 0; i < in.NumField(); i++ {
 		f := in.Type().Field(i)
 		f := in.Type().Field(i)
 		if strings.HasPrefix(f.Name, "XXX_") {
 		if strings.HasPrefix(f.Name, "XXX_") {
 			continue
 			continue
 		}
 		}
-		mergeAny(out.Field(i), in.Field(i))
+		mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
 	}
 	}
 
 
 	if emIn, ok := in.Addr().Interface().(extendableProto); ok {
 	if emIn, ok := in.Addr().Interface().(extendableProto); ok {
@@ -98,7 +99,10 @@ func mergeStruct(out, in reflect.Value) {
 	}
 	}
 }
 }
 
 
-func mergeAny(out, in reflect.Value) {
+// mergeAny performs a merge between two values of the same type.
+// viaPtr indicates whether the values were indirected through a pointer (implying proto2).
+// prop is set if this is a struct field (it may be nil).
+func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) {
 	if in.Type() == protoMessageType {
 	if in.Type() == protoMessageType {
 		if !in.IsNil() {
 		if !in.IsNil() {
 			if out.IsNil() {
 			if out.IsNil() {
@@ -112,7 +116,21 @@ func mergeAny(out, in reflect.Value) {
 	switch in.Kind() {
 	switch in.Kind() {
 	case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
 	case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
 		reflect.String, reflect.Uint32, reflect.Uint64:
 		reflect.String, reflect.Uint32, reflect.Uint64:
+		if !viaPtr && isProto3Zero(in) {
+			return
+		}
 		out.Set(in)
 		out.Set(in)
+	case reflect.Interface:
+		// Probably a oneof field; copy non-nil values.
+		if in.IsNil() {
+			return
+		}
+		// Allocate destination if it is not set, or set to a different type.
+		// Otherwise we will merge as normal.
+		if out.IsNil() || out.Elem().Type() != in.Elem().Type() {
+			out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T)
+		}
+		mergeAny(out.Elem(), in.Elem(), false, nil)
 	case reflect.Map:
 	case reflect.Map:
 		if in.Len() == 0 {
 		if in.Len() == 0 {
 			return
 			return
@@ -127,7 +145,7 @@ func mergeAny(out, in reflect.Value) {
 			switch elemKind {
 			switch elemKind {
 			case reflect.Ptr:
 			case reflect.Ptr:
 				val = reflect.New(in.Type().Elem().Elem())
 				val = reflect.New(in.Type().Elem().Elem())
-				mergeAny(val, in.MapIndex(key))
+				mergeAny(val, in.MapIndex(key), false, nil)
 			case reflect.Slice:
 			case reflect.Slice:
 				val = in.MapIndex(key)
 				val = in.MapIndex(key)
 				val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
 				val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
@@ -143,13 +161,21 @@ func mergeAny(out, in reflect.Value) {
 		if out.IsNil() {
 		if out.IsNil() {
 			out.Set(reflect.New(in.Elem().Type()))
 			out.Set(reflect.New(in.Elem().Type()))
 		}
 		}
-		mergeAny(out.Elem(), in.Elem())
+		mergeAny(out.Elem(), in.Elem(), true, nil)
 	case reflect.Slice:
 	case reflect.Slice:
 		if in.IsNil() {
 		if in.IsNil() {
 			return
 			return
 		}
 		}
 		if in.Type().Elem().Kind() == reflect.Uint8 {
 		if in.Type().Elem().Kind() == reflect.Uint8 {
 			// []byte is a scalar bytes field, not a repeated field.
 			// []byte is a scalar bytes field, not a repeated field.
+
+			// Edge case: if this is in a proto3 message, a zero length
+			// bytes field is considered the zero value, and should not
+			// be merged.
+			if prop != nil && prop.proto3 && in.Len() == 0 {
+				return
+			}
+
 			// Make a deep copy.
 			// Make a deep copy.
 			// Append to []byte{} instead of []byte(nil) so that we never end up
 			// Append to []byte{} instead of []byte(nil) so that we never end up
 			// with a nil result.
 			// with a nil result.
@@ -167,7 +193,7 @@ func mergeAny(out, in reflect.Value) {
 		default:
 		default:
 			for i := 0; i < n; i++ {
 			for i := 0; i < n; i++ {
 				x := reflect.Indirect(reflect.New(in.Type().Elem()))
 				x := reflect.Indirect(reflect.New(in.Type().Elem()))
-				mergeAny(x, in.Index(i))
+				mergeAny(x, in.Index(i), false, nil)
 				out.Set(reflect.Append(out, x))
 				out.Set(reflect.Append(out, x))
 			}
 			}
 		}
 		}
@@ -184,7 +210,7 @@ func mergeExtension(out, in map[int32]Extension) {
 		eOut := Extension{desc: eIn.desc}
 		eOut := Extension{desc: eIn.desc}
 		if eIn.value != nil {
 		if eIn.value != nil {
 			v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
 			v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
-			mergeAny(v, reflect.ValueOf(eIn.value))
+			mergeAny(v, reflect.ValueOf(eIn.value), false, nil)
 			eOut.value = v.Interface()
 			eOut.value = v.Interface()
 		}
 		}
 		if eIn.enc != nil {
 		if eIn.enc != nil {

+ 41 - 1
Godeps/_workspace/src/github.com/golang/protobuf/proto/clone_test.go

@@ -36,7 +36,8 @@ import (
 
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
 
 
-	pb "./testdata"
+	proto3pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto"
+	pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata"
 )
 )
 
 
 var cloneTestMessage = &pb.MyMessage{
 var cloneTestMessage = &pb.MyMessage{
@@ -214,6 +215,45 @@ var mergeTests = []struct {
 			ByteMapping: map[bool][]byte{true: []byte("wowsa")},
 			ByteMapping: map[bool][]byte{true: []byte("wowsa")},
 		},
 		},
 	},
 	},
+	// proto3 shouldn't merge zero values,
+	// in the same way that proto2 shouldn't merge nils.
+	{
+		src: &proto3pb.Message{
+			Name: "Aaron",
+			Data: []byte(""), // zero value, but not nil
+		},
+		dst: &proto3pb.Message{
+			HeightInCm: 176,
+			Data:       []byte("texas!"),
+		},
+		want: &proto3pb.Message{
+			Name:       "Aaron",
+			HeightInCm: 176,
+			Data:       []byte("texas!"),
+		},
+	},
+	// Oneof fields should merge by assignment.
+	{
+		src: &pb.Communique{
+			Union: &pb.Communique_Number{41},
+		},
+		dst: &pb.Communique{
+			Union: &pb.Communique_Name{"Bobby Tables"},
+		},
+		want: &pb.Communique{
+			Union: &pb.Communique_Number{41},
+		},
+	},
+	// Oneof nil is the same as not set.
+	{
+		src: &pb.Communique{},
+		dst: &pb.Communique{
+			Union: &pb.Communique_Name{"Bobby Tables"},
+		},
+		want: &pb.Communique{
+			Union: &pb.Communique_Name{"Bobby Tables"},
+		},
+	},
 }
 }
 
 
 func TestMerge(t *testing.T) {
 func TestMerge(t *testing.T) {

+ 49 - 3
Godeps/_workspace/src/github.com/golang/protobuf/proto/decode.go

@@ -46,6 +46,10 @@ import (
 // errOverflow is returned when an integer is too large to be represented.
 // errOverflow is returned when an integer is too large to be represented.
 var errOverflow = errors.New("proto: integer overflow")
 var errOverflow = errors.New("proto: integer overflow")
 
 
+// ErrInternalBadWireType is returned by generated code when an incorrect
+// wire type is encountered. It does not get returned to user code.
+var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
+
 // The fundamental decoders that interpret bytes on the wire.
 // The fundamental decoders that interpret bytes on the wire.
 // Those that take integer types all return uint64 and are
 // Those that take integer types all return uint64 and are
 // therefore of type valueDecoder.
 // therefore of type valueDecoder.
@@ -314,6 +318,24 @@ func UnmarshalMerge(buf []byte, pb Message) error {
 	return NewBuffer(buf).Unmarshal(pb)
 	return NewBuffer(buf).Unmarshal(pb)
 }
 }
 
 
+// DecodeMessage reads a count-delimited message from the Buffer.
+func (p *Buffer) DecodeMessage(pb Message) error {
+	enc, err := p.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+	return NewBuffer(enc).Unmarshal(pb)
+}
+
+// DecodeGroup reads a tag-delimited group from the Buffer.
+func (p *Buffer) DecodeGroup(pb Message) error {
+	typ, base, err := getbase(pb)
+	if err != nil {
+		return err
+	}
+	return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base)
+}
+
 // Unmarshal parses the protocol buffer representation in the
 // Unmarshal parses the protocol buffer representation in the
 // Buffer and places the decoded result in pb.  If the struct
 // 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
 // underlying pb does not match the data in the buffer, the results can be
@@ -377,6 +399,20 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
 					continue
 					continue
 				}
 				}
 			}
 			}
+			// Maybe it's a oneof?
+			if prop.oneofUnmarshaler != nil {
+				m := structPointer_Interface(base, st).(Message)
+				// First return value indicates whether tag is a oneof field.
+				ok, err = prop.oneofUnmarshaler(m, tag, wire, o)
+				if err == ErrInternalBadWireType {
+					// Map the error to something more descriptive.
+					// Do the formatting here to save generated code space.
+					err = fmt.Errorf("bad wiretype for oneof field in %T", m)
+				}
+				if ok {
+					continue
+				}
+			}
 			err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
 			err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
 			continue
 			continue
 		}
 		}
@@ -561,9 +597,13 @@ func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error
 		return err
 		return err
 	}
 	}
 	nb := int(nn) // number of bytes of encoded bools
 	nb := int(nn) // number of bytes of encoded bools
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
 
 
 	y := *v
 	y := *v
-	for i := 0; i < nb; i++ {
+	for o.index < fin {
 		u, err := p.valDec(o)
 		u, err := p.valDec(o)
 		if err != nil {
 		if err != nil {
 			return err
 			return err
@@ -675,7 +715,7 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
 	oi := o.index       // index at the end of this map entry
 	oi := o.index       // index at the end of this map entry
 	o.index -= len(raw) // move buffer back to start of 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
+	mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V
 	if mptr.Elem().IsNil() {
 	if mptr.Elem().IsNil() {
 		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
 		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
 	}
 	}
@@ -727,8 +767,14 @@ func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
 			return fmt.Errorf("proto: bad map data tag %d", raw[0])
 			return fmt.Errorf("proto: bad map data tag %d", raw[0])
 		}
 		}
 	}
 	}
+	keyelem, valelem := keyptr.Elem(), valptr.Elem()
+	if !keyelem.IsValid() || !valelem.IsValid() {
+		// We did not decode the key or the value in the map entry.
+		// Either way, it's an invalid map entry.
+		return fmt.Errorf("proto: bad map data: missing key/val")
+	}
 
 
-	v.SetMapIndex(keyptr.Elem(), valptr.Elem())
+	v.SetMapIndex(keyelem, valelem)
 	return nil
 	return nil
 }
 }
 
 

+ 65 - 23
Godeps/_workspace/src/github.com/golang/protobuf/proto/encode.go

@@ -60,9 +60,9 @@ func (e *RequiredNotSetError) Error() string {
 }
 }
 
 
 var (
 var (
-	// ErrRepeatedHasNil is the error returned if Marshal is called with
+	// errRepeatedHasNil is the error returned if Marshal is called with
 	// a struct with a repeated field containing a nil element.
 	// a struct with a repeated field containing a nil element.
-	ErrRepeatedHasNil = errors.New("proto: repeated field has nil element")
+	errRepeatedHasNil = errors.New("proto: repeated field has nil element")
 
 
 	// ErrNil is the error returned if Marshal is called with nil.
 	// ErrNil is the error returned if Marshal is called with nil.
 	ErrNil = errors.New("proto: Marshal called with nil")
 	ErrNil = errors.New("proto: Marshal called with nil")
@@ -105,6 +105,11 @@ func (p *Buffer) EncodeVarint(x uint64) error {
 	return nil
 	return nil
 }
 }
 
 
+// SizeVarint returns the varint encoding size of an integer.
+func SizeVarint(x uint64) int {
+	return sizeVarint(x)
+}
+
 func sizeVarint(x uint64) (n int) {
 func sizeVarint(x uint64) (n int) {
 	for {
 	for {
 		n++
 		n++
@@ -228,6 +233,20 @@ func Marshal(pb Message) ([]byte, error) {
 	return p.buf, err
 	return p.buf, err
 }
 }
 
 
+// EncodeMessage writes the protocol buffer to the Buffer,
+// prefixed by a varint-encoded length.
+func (p *Buffer) EncodeMessage(pb Message) error {
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return ErrNil
+	}
+	if err == nil {
+		var state errorState
+		err = p.enc_len_struct(GetProperties(t.Elem()), base, &state)
+	}
+	return err
+}
+
 // Marshal takes the protocol buffer
 // Marshal takes the protocol buffer
 // and encodes it into the wire format, writing the result to the
 // and encodes it into the wire format, writing the result to the
 // Buffer.
 // Buffer.
@@ -318,7 +337,7 @@ func size_bool(p *Properties, base structPointer) int {
 
 
 func size_proto3_bool(p *Properties, base structPointer) int {
 func size_proto3_bool(p *Properties, base structPointer) int {
 	v := *structPointer_BoolVal(base, p.field)
 	v := *structPointer_BoolVal(base, p.field)
-	if !v {
+	if !v && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	return len(p.tagcode) + 1 // each bool takes exactly one byte
 	return len(p.tagcode) + 1 // each bool takes exactly one byte
@@ -361,7 +380,7 @@ func size_int32(p *Properties, base structPointer) (n int) {
 func size_proto3_int32(p *Properties, base structPointer) (n int) {
 func size_proto3_int32(p *Properties, base structPointer) (n int) {
 	v := structPointer_Word32Val(base, p.field)
 	v := structPointer_Word32Val(base, p.field)
 	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
 	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -407,7 +426,7 @@ func size_uint32(p *Properties, base structPointer) (n int) {
 func size_proto3_uint32(p *Properties, base structPointer) (n int) {
 func size_proto3_uint32(p *Properties, base structPointer) (n int) {
 	v := structPointer_Word32Val(base, p.field)
 	v := structPointer_Word32Val(base, p.field)
 	x := word32Val_Get(v)
 	x := word32Val_Get(v)
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -452,7 +471,7 @@ func size_int64(p *Properties, base structPointer) (n int) {
 func size_proto3_int64(p *Properties, base structPointer) (n int) {
 func size_proto3_int64(p *Properties, base structPointer) (n int) {
 	v := structPointer_Word64Val(base, p.field)
 	v := structPointer_Word64Val(base, p.field)
 	x := word64Val_Get(v)
 	x := word64Val_Get(v)
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -495,7 +514,7 @@ func size_string(p *Properties, base structPointer) (n int) {
 
 
 func size_proto3_string(p *Properties, base structPointer) (n int) {
 func size_proto3_string(p *Properties, base structPointer) (n int) {
 	v := *structPointer_StringVal(base, p.field)
 	v := *structPointer_StringVal(base, p.field)
-	if v == "" {
+	if v == "" && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -529,7 +548,7 @@ func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
 		}
 		}
 		o.buf = append(o.buf, p.tagcode...)
 		o.buf = append(o.buf, p.tagcode...)
 		o.EncodeRawBytes(data)
 		o.EncodeRawBytes(data)
-		return nil
+		return state.err
 	}
 	}
 
 
 	o.buf = append(o.buf, p.tagcode...)
 	o.buf = append(o.buf, p.tagcode...)
@@ -667,7 +686,7 @@ func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error
 
 
 func size_slice_byte(p *Properties, base structPointer) (n int) {
 func size_slice_byte(p *Properties, base structPointer) (n int) {
 	s := *structPointer_Bytes(base, p.field)
 	s := *structPointer_Bytes(base, p.field)
-	if s == nil {
+	if s == nil && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -677,7 +696,7 @@ func size_slice_byte(p *Properties, base structPointer) (n int) {
 
 
 func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
 func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
 	s := *structPointer_Bytes(base, p.field)
 	s := *structPointer_Bytes(base, p.field)
-	if len(s) == 0 {
+	if len(s) == 0 && !p.oneof {
 		return 0
 		return 0
 	}
 	}
 	n += len(p.tagcode)
 	n += len(p.tagcode)
@@ -939,7 +958,7 @@ func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) err
 	for i := 0; i < l; i++ {
 	for i := 0; i < l; i++ {
 		structp := s.Index(i)
 		structp := s.Index(i)
 		if structPointer_IsNil(structp) {
 		if structPointer_IsNil(structp) {
-			return ErrRepeatedHasNil
+			return errRepeatedHasNil
 		}
 		}
 
 
 		// Can the object marshal itself?
 		// Can the object marshal itself?
@@ -958,7 +977,7 @@ func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) err
 		err := o.enc_len_struct(p.sprop, structp, &state)
 		err := o.enc_len_struct(p.sprop, structp, &state)
 		if err != nil && !state.shouldContinue(err, nil) {
 		if err != nil && !state.shouldContinue(err, nil) {
 			if err == ErrNil {
 			if err == ErrNil {
-				return ErrRepeatedHasNil
+				return errRepeatedHasNil
 			}
 			}
 			return err
 			return err
 		}
 		}
@@ -1001,7 +1020,7 @@ func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error
 	for i := 0; i < l; i++ {
 	for i := 0; i < l; i++ {
 		b := s.Index(i)
 		b := s.Index(i)
 		if structPointer_IsNil(b) {
 		if structPointer_IsNil(b) {
-			return ErrRepeatedHasNil
+			return errRepeatedHasNil
 		}
 		}
 
 
 		o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
 		o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
@@ -1010,7 +1029,7 @@ func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error
 
 
 		if err != nil && !state.shouldContinue(err, nil) {
 		if err != nil && !state.shouldContinue(err, nil) {
 			if err == ErrNil {
 			if err == ErrNil {
-				return ErrRepeatedHasNil
+				return errRepeatedHasNil
 			}
 			}
 			return err
 			return err
 		}
 		}
@@ -1084,7 +1103,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
 			repeated MapFieldEntry map_field = N;
 			repeated MapFieldEntry map_field = N;
 	*/
 	*/
 
 
-	v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
+	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
 	if v.Len() == 0 {
 	if v.Len() == 0 {
 		return nil
 		return nil
 	}
 	}
@@ -1101,11 +1120,15 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
 		return nil
 		return nil
 	}
 	}
 
 
-	keys := v.MapKeys()
-	sort.Sort(mapKeys(keys))
-	for _, key := range keys {
+	// Don't sort map keys. It is not required by the spec, and C++ doesn't do it.
+	for _, key := range v.MapKeys() {
 		val := v.MapIndex(key)
 		val := v.MapIndex(key)
 
 
+		// The only illegal map entry values are nil message pointers.
+		if val.Kind() == reflect.Ptr && val.IsNil() {
+			return errors.New("proto: map has nil element")
+		}
+
 		keycopy.Set(key)
 		keycopy.Set(key)
 		valcopy.Set(val)
 		valcopy.Set(val)
 
 
@@ -1118,7 +1141,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
 }
 }
 
 
 func size_new_map(p *Properties, base structPointer) int {
 func size_new_map(p *Properties, base structPointer) int {
-	v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
+	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
 
 
 	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
 	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
 
 
@@ -1128,10 +1151,12 @@ func size_new_map(p *Properties, base structPointer) int {
 		keycopy.Set(key)
 		keycopy.Set(key)
 		valcopy.Set(val)
 		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)
+		// Tag codes for key and val are the responsibility of the sub-sizer.
+		keysize := p.mkeyprop.size(p.mkeyprop, keybase)
+		valsize := p.mvalprop.size(p.mvalprop, valbase)
+		entry := keysize + valsize
+		// Add on tag code and length of map entry itself.
+		n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry
 	}
 	}
 	return n
 	return n
 }
 }
@@ -1184,6 +1209,9 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
 					if p.Required && state.err == nil {
 					if p.Required && state.err == nil {
 						state.err = &RequiredNotSetError{p.Name}
 						state.err = &RequiredNotSetError{p.Name}
 					}
 					}
+				} else if err == errRepeatedHasNil {
+					// Give more context to nil values in repeated fields.
+					return errors.New("repeated field " + p.OrigName + " has nil element")
 				} else if !state.shouldContinue(err, p) {
 				} else if !state.shouldContinue(err, p) {
 					return err
 					return err
 				}
 				}
@@ -1191,6 +1219,14 @@ func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
 		}
 		}
 	}
 	}
 
 
+	// Do oneof fields.
+	if prop.oneofMarshaler != nil {
+		m := structPointer_Interface(base, prop.stype).(Message)
+		if err := prop.oneofMarshaler(m, o); err != nil {
+			return err
+		}
+	}
+
 	// Add unrecognized fields at the end.
 	// Add unrecognized fields at the end.
 	if prop.unrecField.IsValid() {
 	if prop.unrecField.IsValid() {
 		v := *structPointer_Bytes(base, prop.unrecField)
 		v := *structPointer_Bytes(base, prop.unrecField)
@@ -1216,6 +1252,12 @@ func size_struct(prop *StructProperties, base structPointer) (n int) {
 		n += len(v)
 		n += len(v)
 	}
 	}
 
 
+	// Factor in any oneof fields.
+	if prop.oneofSizer != nil {
+		m := structPointer_Interface(base, prop.stype).(Message)
+		n += prop.oneofSizer(m)
+	}
+
 	return
 	return
 }
 }
 
 

+ 29 - 9
Godeps/_workspace/src/github.com/golang/protobuf/proto/equal.go

@@ -30,7 +30,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 
 // Protocol buffer comparison.
 // Protocol buffer comparison.
-// TODO: MessageSet.
 
 
 package proto
 package proto
 
 
@@ -51,7 +50,9 @@ Equality is defined in this way:
     are equal, and extensions sets are equal.
     are equal, and extensions sets are equal.
   - Two set scalar fields are equal iff their values are equal.
   - Two set scalar fields are equal iff their values are equal.
     If the fields are of a floating-point type, remember that
     If the fields are of a floating-point type, remember that
-    NaN != x for all x, including NaN.
+    NaN != x for all x, including NaN. If the message is defined
+    in a proto3 .proto file, fields are not "set"; specifically,
+    zero length proto3 "bytes" fields are equal (nil == {}).
   - Two repeated fields are equal iff their lengths are the same,
   - Two repeated fields are equal iff their lengths are the same,
     and their corresponding elements are equal (a "bytes" field,
     and their corresponding elements are equal (a "bytes" field,
     although represented by []byte, is not a repeated field)
     although represented by []byte, is not a repeated field)
@@ -89,6 +90,7 @@ func Equal(a, b Message) bool {
 
 
 // v1 and v2 are known to have the same type.
 // v1 and v2 are known to have the same type.
 func equalStruct(v1, v2 reflect.Value) bool {
 func equalStruct(v1, v2 reflect.Value) bool {
+	sprop := GetProperties(v1.Type())
 	for i := 0; i < v1.NumField(); i++ {
 	for i := 0; i < v1.NumField(); i++ {
 		f := v1.Type().Field(i)
 		f := v1.Type().Field(i)
 		if strings.HasPrefix(f.Name, "XXX_") {
 		if strings.HasPrefix(f.Name, "XXX_") {
@@ -114,7 +116,7 @@ func equalStruct(v1, v2 reflect.Value) bool {
 			}
 			}
 			f1, f2 = f1.Elem(), f2.Elem()
 			f1, f2 = f1.Elem(), f2.Elem()
 		}
 		}
-		if !equalAny(f1, f2) {
+		if !equalAny(f1, f2, sprop.Prop[i]) {
 			return false
 			return false
 		}
 		}
 	}
 	}
@@ -141,7 +143,8 @@ func equalStruct(v1, v2 reflect.Value) bool {
 }
 }
 
 
 // v1 and v2 are known to have the same type.
 // v1 and v2 are known to have the same type.
-func equalAny(v1, v2 reflect.Value) bool {
+// prop may be nil.
+func equalAny(v1, v2 reflect.Value, prop *Properties) bool {
 	if v1.Type() == protoMessageType {
 	if v1.Type() == protoMessageType {
 		m1, _ := v1.Interface().(Message)
 		m1, _ := v1.Interface().(Message)
 		m2, _ := v2.Interface().(Message)
 		m2, _ := v2.Interface().(Message)
@@ -154,6 +157,17 @@ func equalAny(v1, v2 reflect.Value) bool {
 		return v1.Float() == v2.Float()
 		return v1.Float() == v2.Float()
 	case reflect.Int32, reflect.Int64:
 	case reflect.Int32, reflect.Int64:
 		return v1.Int() == v2.Int()
 		return v1.Int() == v2.Int()
+	case reflect.Interface:
+		// Probably a oneof field; compare the inner values.
+		n1, n2 := v1.IsNil(), v2.IsNil()
+		if n1 || n2 {
+			return n1 == n2
+		}
+		e1, e2 := v1.Elem(), v2.Elem()
+		if e1.Type() != e2.Type() {
+			return false
+		}
+		return equalAny(e1, e2, nil)
 	case reflect.Map:
 	case reflect.Map:
 		if v1.Len() != v2.Len() {
 		if v1.Len() != v2.Len() {
 			return false
 			return false
@@ -164,16 +178,22 @@ func equalAny(v1, v2 reflect.Value) bool {
 				// This key was not found in the second map.
 				// This key was not found in the second map.
 				return false
 				return false
 			}
 			}
-			if !equalAny(v1.MapIndex(key), val2) {
+			if !equalAny(v1.MapIndex(key), val2, nil) {
 				return false
 				return false
 			}
 			}
 		}
 		}
 		return true
 		return true
 	case reflect.Ptr:
 	case reflect.Ptr:
-		return equalAny(v1.Elem(), v2.Elem())
+		return equalAny(v1.Elem(), v2.Elem(), prop)
 	case reflect.Slice:
 	case reflect.Slice:
 		if v1.Type().Elem().Kind() == reflect.Uint8 {
 		if v1.Type().Elem().Kind() == reflect.Uint8 {
 			// short circuit: []byte
 			// short circuit: []byte
+
+			// Edge case: if this is in a proto3 message, a zero length
+			// bytes field is considered the zero value.
+			if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 {
+				return true
+			}
 			if v1.IsNil() != v2.IsNil() {
 			if v1.IsNil() != v2.IsNil() {
 				return false
 				return false
 			}
 			}
@@ -184,7 +204,7 @@ func equalAny(v1, v2 reflect.Value) bool {
 			return false
 			return false
 		}
 		}
 		for i := 0; i < v1.Len(); i++ {
 		for i := 0; i < v1.Len(); i++ {
-			if !equalAny(v1.Index(i), v2.Index(i)) {
+			if !equalAny(v1.Index(i), v2.Index(i), prop) {
 				return false
 				return false
 			}
 			}
 		}
 		}
@@ -219,7 +239,7 @@ func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
 
 
 		if m1 != nil && m2 != nil {
 		if m1 != nil && m2 != nil {
 			// Both are unencoded.
 			// Both are unencoded.
-			if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) {
+			if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
 				return false
 				return false
 			}
 			}
 			continue
 			continue
@@ -247,7 +267,7 @@ func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
 			log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
 			log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
 			return false
 			return false
 		}
 		}
-		if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) {
+		if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
 			return false
 			return false
 		}
 		}
 	}
 	}

+ 22 - 1
Godeps/_workspace/src/github.com/golang/protobuf/proto/equal_test.go

@@ -34,8 +34,9 @@ package proto_test
 import (
 import (
 	"testing"
 	"testing"
 
 
-	pb "./testdata"
 	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
 	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+	proto3pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto"
+	pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata"
 )
 )
 
 
 // Four identical base messages.
 // Four identical base messages.
@@ -131,6 +132,8 @@ var EqualTests = []struct {
 		&pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}},
 		&pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}},
 		true,
 		true,
 	},
 	},
+	// In proto3, []byte{} and []byte(nil) are equal.
+	{"proto3 bytes, empty vs nil", &proto3pb.Message{Data: []byte{}}, &proto3pb.Message{Data: nil}, true},
 
 
 	{"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false},
 	{"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false},
 	{"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true},
 	{"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true},
@@ -180,6 +183,24 @@ var EqualTests = []struct {
 		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
 		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
 		false,
 		false,
 	},
 	},
+	{
+		"oneof same",
+		&pb.Communique{Union: &pb.Communique_Number{41}},
+		&pb.Communique{Union: &pb.Communique_Number{41}},
+		true,
+	},
+	{
+		"oneof one nil",
+		&pb.Communique{Union: &pb.Communique_Number{41}},
+		&pb.Communique{},
+		false,
+	},
+	{
+		"oneof different",
+		&pb.Communique{Union: &pb.Communique_Number{41}},
+		&pb.Communique{Union: &pb.Communique_Name{"Bobby Tables"}},
+		false,
+	},
 }
 }
 
 
 func TestEqual(t *testing.T) {
 func TestEqual(t *testing.T) {

+ 50 - 4
Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions.go

@@ -37,6 +37,7 @@ package proto
 
 
 import (
 import (
 	"errors"
 	"errors"
+	"fmt"
 	"reflect"
 	"reflect"
 	"strconv"
 	"strconv"
 	"sync"
 	"sync"
@@ -221,7 +222,7 @@ func ClearExtension(pb extendableProto, extension *ExtensionDesc) {
 }
 }
 
 
 // GetExtension parses and returns the given extension of pb.
 // GetExtension parses and returns the given extension of pb.
-// If the extension is not present it returns ErrMissingExtension.
+// If the extension is not present and has no default value it returns ErrMissingExtension.
 func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
 func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
 	if err := checkExtensionTypes(pb, extension); err != nil {
 	if err := checkExtensionTypes(pb, extension); err != nil {
 		return nil, err
 		return nil, err
@@ -230,8 +231,11 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
 	emap := pb.ExtensionMap()
 	emap := pb.ExtensionMap()
 	e, ok := emap[extension.Field]
 	e, ok := emap[extension.Field]
 	if !ok {
 	if !ok {
-		return nil, ErrMissingExtension
+		// defaultExtensionValue returns the default value or
+		// ErrMissingExtension if there is no default.
+		return defaultExtensionValue(extension)
 	}
 	}
+
 	if e.value != nil {
 	if e.value != nil {
 		// Already decoded. Check the descriptor, though.
 		// Already decoded. Check the descriptor, though.
 		if e.desc != extension {
 		if e.desc != extension {
@@ -257,12 +261,46 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
 	return e.value, nil
 	return e.value, nil
 }
 }
 
 
+// defaultExtensionValue returns the default value for extension.
+// If no default for an extension is defined ErrMissingExtension is returned.
+func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
+	t := reflect.TypeOf(extension.ExtensionType)
+	props := extensionProperties(extension)
+
+	sf, _, err := fieldDefault(t, props)
+	if err != nil {
+		return nil, err
+	}
+
+	if sf == nil || sf.value == nil {
+		// There is no default value.
+		return nil, ErrMissingExtension
+	}
+
+	if t.Kind() != reflect.Ptr {
+		// We do not need to return a Ptr, we can directly return sf.value.
+		return sf.value, nil
+	}
+
+	// We need to return an interface{} that is a pointer to sf.value.
+	value := reflect.New(t).Elem()
+	value.Set(reflect.New(value.Type().Elem()))
+	if sf.kind == reflect.Int32 {
+		// We may have an int32 or an enum, but the underlying data is int32.
+		// Since we can't set an int32 into a non int32 reflect.value directly
+		// set it as a int32.
+		value.Elem().SetInt(int64(sf.value.(int32)))
+	} else {
+		value.Elem().Set(reflect.ValueOf(sf.value))
+	}
+	return value.Interface(), nil
+}
+
 // decodeExtension decodes an extension encoded in b.
 // decodeExtension decodes an extension encoded in b.
 func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
 func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
 	o := NewBuffer(b)
 	o := NewBuffer(b)
 
 
 	t := reflect.TypeOf(extension.ExtensionType)
 	t := reflect.TypeOf(extension.ExtensionType)
-	rep := extension.repeated()
 
 
 	props := extensionProperties(extension)
 	props := extensionProperties(extension)
 
 
@@ -284,7 +322,7 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
 			return nil, err
 			return nil, err
 		}
 		}
 
 
-		if !rep || o.index >= len(o.buf) {
+		if o.index >= len(o.buf) {
 			break
 			break
 		}
 		}
 	}
 	}
@@ -321,6 +359,14 @@ func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{
 	if typ != reflect.TypeOf(value) {
 	if typ != reflect.TypeOf(value) {
 		return errors.New("proto: bad extension value type")
 		return errors.New("proto: bad extension value type")
 	}
 	}
+	// nil extension values need to be caught early, because the
+	// encoder can't distinguish an ErrNil due to a nil extension
+	// from an ErrNil due to a missing field. Extensions are
+	// always optional, so the encoder would just swallow the error
+	// and drop all the extensions from the encoded message.
+	if reflect.ValueOf(value).IsNil() {
+		return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
+	}
 
 
 	pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value}
 	pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value}
 	return nil
 	return nil

+ 294 - 1
Godeps/_workspace/src/github.com/golang/protobuf/proto/extensions_test.go

@@ -32,10 +32,13 @@
 package proto_test
 package proto_test
 
 
 import (
 import (
+	"bytes"
+	"fmt"
+	"reflect"
 	"testing"
 	"testing"
 
 
-	pb "./testdata"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+	pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata"
 )
 )
 
 
 func TestGetExtensionsWithMissingExtensions(t *testing.T) {
 func TestGetExtensionsWithMissingExtensions(t *testing.T) {
@@ -93,6 +96,143 @@ func TestGetExtensionStability(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestGetExtensionDefaults(t *testing.T) {
+	var setFloat64 float64 = 1
+	var setFloat32 float32 = 2
+	var setInt32 int32 = 3
+	var setInt64 int64 = 4
+	var setUint32 uint32 = 5
+	var setUint64 uint64 = 6
+	var setBool = true
+	var setBool2 = false
+	var setString = "Goodnight string"
+	var setBytes = []byte("Goodnight bytes")
+	var setEnum = pb.DefaultsMessage_TWO
+
+	type testcase struct {
+		ext  *proto.ExtensionDesc // Extension we are testing.
+		want interface{}          // Expected value of extension, or nil (meaning that GetExtension will fail).
+		def  interface{}          // Expected value of extension after ClearExtension().
+	}
+	tests := []testcase{
+		{pb.E_NoDefaultDouble, setFloat64, nil},
+		{pb.E_NoDefaultFloat, setFloat32, nil},
+		{pb.E_NoDefaultInt32, setInt32, nil},
+		{pb.E_NoDefaultInt64, setInt64, nil},
+		{pb.E_NoDefaultUint32, setUint32, nil},
+		{pb.E_NoDefaultUint64, setUint64, nil},
+		{pb.E_NoDefaultSint32, setInt32, nil},
+		{pb.E_NoDefaultSint64, setInt64, nil},
+		{pb.E_NoDefaultFixed32, setUint32, nil},
+		{pb.E_NoDefaultFixed64, setUint64, nil},
+		{pb.E_NoDefaultSfixed32, setInt32, nil},
+		{pb.E_NoDefaultSfixed64, setInt64, nil},
+		{pb.E_NoDefaultBool, setBool, nil},
+		{pb.E_NoDefaultBool, setBool2, nil},
+		{pb.E_NoDefaultString, setString, nil},
+		{pb.E_NoDefaultBytes, setBytes, nil},
+		{pb.E_NoDefaultEnum, setEnum, nil},
+		{pb.E_DefaultDouble, setFloat64, float64(3.1415)},
+		{pb.E_DefaultFloat, setFloat32, float32(3.14)},
+		{pb.E_DefaultInt32, setInt32, int32(42)},
+		{pb.E_DefaultInt64, setInt64, int64(43)},
+		{pb.E_DefaultUint32, setUint32, uint32(44)},
+		{pb.E_DefaultUint64, setUint64, uint64(45)},
+		{pb.E_DefaultSint32, setInt32, int32(46)},
+		{pb.E_DefaultSint64, setInt64, int64(47)},
+		{pb.E_DefaultFixed32, setUint32, uint32(48)},
+		{pb.E_DefaultFixed64, setUint64, uint64(49)},
+		{pb.E_DefaultSfixed32, setInt32, int32(50)},
+		{pb.E_DefaultSfixed64, setInt64, int64(51)},
+		{pb.E_DefaultBool, setBool, true},
+		{pb.E_DefaultBool, setBool2, true},
+		{pb.E_DefaultString, setString, "Hello, string"},
+		{pb.E_DefaultBytes, setBytes, []byte("Hello, bytes")},
+		{pb.E_DefaultEnum, setEnum, pb.DefaultsMessage_ONE},
+	}
+
+	checkVal := func(test testcase, msg *pb.DefaultsMessage, valWant interface{}) error {
+		val, err := proto.GetExtension(msg, test.ext)
+		if err != nil {
+			if valWant != nil {
+				return fmt.Errorf("GetExtension(): %s", err)
+			}
+			if want := proto.ErrMissingExtension; err != want {
+				return fmt.Errorf("Unexpected error: got %v, want %v", err, want)
+			}
+			return nil
+		}
+
+		// All proto2 extension values are either a pointer to a value or a slice of values.
+		ty := reflect.TypeOf(val)
+		tyWant := reflect.TypeOf(test.ext.ExtensionType)
+		if got, want := ty, tyWant; got != want {
+			return fmt.Errorf("unexpected reflect.TypeOf(): got %v want %v", got, want)
+		}
+		tye := ty.Elem()
+		tyeWant := tyWant.Elem()
+		if got, want := tye, tyeWant; got != want {
+			return fmt.Errorf("unexpected reflect.TypeOf().Elem(): got %v want %v", got, want)
+		}
+
+		// Check the name of the type of the value.
+		// If it is an enum it will be type int32 with the name of the enum.
+		if got, want := tye.Name(), tye.Name(); got != want {
+			return fmt.Errorf("unexpected reflect.TypeOf().Elem().Name(): got %v want %v", got, want)
+		}
+
+		// Check that value is what we expect.
+		// If we have a pointer in val, get the value it points to.
+		valExp := val
+		if ty.Kind() == reflect.Ptr {
+			valExp = reflect.ValueOf(val).Elem().Interface()
+		}
+		if got, want := valExp, valWant; !reflect.DeepEqual(got, want) {
+			return fmt.Errorf("unexpected reflect.DeepEqual(): got %v want %v", got, want)
+		}
+
+		return nil
+	}
+
+	setTo := func(test testcase) interface{} {
+		setTo := reflect.ValueOf(test.want)
+		if typ := reflect.TypeOf(test.ext.ExtensionType); typ.Kind() == reflect.Ptr {
+			setTo = reflect.New(typ).Elem()
+			setTo.Set(reflect.New(setTo.Type().Elem()))
+			setTo.Elem().Set(reflect.ValueOf(test.want))
+		}
+		return setTo.Interface()
+	}
+
+	for _, test := range tests {
+		msg := &pb.DefaultsMessage{}
+		name := test.ext.Name
+
+		// Check the initial value.
+		if err := checkVal(test, msg, test.def); err != nil {
+			t.Errorf("%s: %v", name, err)
+		}
+
+		// Set the per-type value and check value.
+		name = fmt.Sprintf("%s (set to %T %v)", name, test.want, test.want)
+		if err := proto.SetExtension(msg, test.ext, setTo(test)); err != nil {
+			t.Errorf("%s: SetExtension(): %v", name, err)
+			continue
+		}
+		if err := checkVal(test, msg, test.want); err != nil {
+			t.Errorf("%s: %v", name, err)
+			continue
+		}
+
+		// Set and check the value.
+		name += " (cleared)"
+		proto.ClearExtension(msg, test.ext)
+		if err := checkVal(test, msg, test.def); err != nil {
+			t.Errorf("%s: %v", name, err)
+		}
+	}
+}
+
 func TestExtensionsRoundTrip(t *testing.T) {
 func TestExtensionsRoundTrip(t *testing.T) {
 	msg := &pb.MyMessage{}
 	msg := &pb.MyMessage{}
 	ext1 := &pb.Ext{
 	ext1 := &pb.Ext{
@@ -135,3 +275,156 @@ func TestExtensionsRoundTrip(t *testing.T) {
 		t.Error("expected some sort of type mismatch error, got nil")
 		t.Error("expected some sort of type mismatch error, got nil")
 	}
 	}
 }
 }
+
+func TestNilExtension(t *testing.T) {
+	msg := &pb.MyMessage{
+		Count: proto.Int32(1),
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_Text, proto.String("hello")); err != nil {
+		t.Fatal(err)
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, (*pb.Ext)(nil)); err == nil {
+		t.Error("expected SetExtension to fail due to a nil extension")
+	} else if want := "proto: SetExtension called with nil value of type *testdata.Ext"; err.Error() != want {
+		t.Errorf("expected error %v, got %v", want, err)
+	}
+	// Note: if the behavior of Marshal is ever changed to ignore nil extensions, update
+	// this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal.
+}
+
+func TestMarshalUnmarshalRepeatedExtension(t *testing.T) {
+	// Add a repeated extension to the result.
+	tests := []struct {
+		name string
+		ext  []*pb.ComplexExtension
+	}{
+		{
+			"two fields",
+			[]*pb.ComplexExtension{
+				{First: proto.Int32(7)},
+				{Second: proto.Int32(11)},
+			},
+		},
+		{
+			"repeated field",
+			[]*pb.ComplexExtension{
+				{Third: []int32{1000}},
+				{Third: []int32{2000}},
+			},
+		},
+		{
+			"two fields and repeated field",
+			[]*pb.ComplexExtension{
+				{Third: []int32{1000}},
+				{First: proto.Int32(9)},
+				{Second: proto.Int32(21)},
+				{Third: []int32{2000}},
+			},
+		},
+	}
+	for _, test := range tests {
+		// Marshal message with a repeated extension.
+		msg1 := new(pb.OtherMessage)
+		err := proto.SetExtension(msg1, pb.E_RComplex, test.ext)
+		if err != nil {
+			t.Fatalf("[%s] Error setting extension: %v", test.name, err)
+		}
+		b, err := proto.Marshal(msg1)
+		if err != nil {
+			t.Fatalf("[%s] Error marshaling message: %v", test.name, err)
+		}
+
+		// Unmarshal and read the merged proto.
+		msg2 := new(pb.OtherMessage)
+		err = proto.Unmarshal(b, msg2)
+		if err != nil {
+			t.Fatalf("[%s] Error unmarshaling message: %v", test.name, err)
+		}
+		e, err := proto.GetExtension(msg2, pb.E_RComplex)
+		if err != nil {
+			t.Fatalf("[%s] Error getting extension: %v", test.name, err)
+		}
+		ext := e.([]*pb.ComplexExtension)
+		if ext == nil {
+			t.Fatalf("[%s] Invalid extension", test.name)
+		}
+		if !reflect.DeepEqual(ext, test.ext) {
+			t.Errorf("[%s] Wrong value for ComplexExtension: got: %v want: %v\n", test.name, ext, test.ext)
+		}
+	}
+}
+
+func TestUnmarshalRepeatingNonRepeatedExtension(t *testing.T) {
+	// We may see multiple instances of the same extension in the wire
+	// format. For example, the proto compiler may encode custom options in
+	// this way. Here, we verify that we merge the extensions together.
+	tests := []struct {
+		name string
+		ext  []*pb.ComplexExtension
+	}{
+		{
+			"two fields",
+			[]*pb.ComplexExtension{
+				{First: proto.Int32(7)},
+				{Second: proto.Int32(11)},
+			},
+		},
+		{
+			"repeated field",
+			[]*pb.ComplexExtension{
+				{Third: []int32{1000}},
+				{Third: []int32{2000}},
+			},
+		},
+		{
+			"two fields and repeated field",
+			[]*pb.ComplexExtension{
+				{Third: []int32{1000}},
+				{First: proto.Int32(9)},
+				{Second: proto.Int32(21)},
+				{Third: []int32{2000}},
+			},
+		},
+	}
+	for _, test := range tests {
+		var buf bytes.Buffer
+		var want pb.ComplexExtension
+
+		// Generate a serialized representation of a repeated extension
+		// by catenating bytes together.
+		for i, e := range test.ext {
+			// Merge to create the wanted proto.
+			proto.Merge(&want, e)
+
+			// serialize the message
+			msg := new(pb.OtherMessage)
+			err := proto.SetExtension(msg, pb.E_Complex, e)
+			if err != nil {
+				t.Fatalf("[%s] Error setting extension %d: %v", test.name, i, err)
+			}
+			b, err := proto.Marshal(msg)
+			if err != nil {
+				t.Fatalf("[%s] Error marshaling message %d: %v", test.name, i, err)
+			}
+			buf.Write(b)
+		}
+
+		// Unmarshal and read the merged proto.
+		msg2 := new(pb.OtherMessage)
+		err := proto.Unmarshal(buf.Bytes(), msg2)
+		if err != nil {
+			t.Fatalf("[%s] Error unmarshaling message: %v", test.name, err)
+		}
+		e, err := proto.GetExtension(msg2, pb.E_Complex)
+		if err != nil {
+			t.Fatalf("[%s] Error getting extension: %v", test.name, err)
+		}
+		ext := e.(*pb.ComplexExtension)
+		if ext == nil {
+			t.Fatalf("[%s] Invalid extension", test.name)
+		}
+		if !reflect.DeepEqual(*ext, want) {
+			t.Errorf("[%s] Wrong value for ComplexExtension: got: %s want: %s\n", test.name, ext, want)
+		}
+	}
+}

+ 396 - 261
Godeps/_workspace/src/github.com/golang/protobuf/proto/lib.go

@@ -30,179 +30,237 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 // 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
+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.
+  - Oneof field sets are given a single field in their message,
+	with distinguished wrapper types for each possible field value.
+  - Marshal and Unmarshal are functions to encode and decode the wire format.
+
+When the .proto file specifies `syntax="proto3"`, there are some differences:
+
+  - Non-repeated fields of non-message type are values instead of pointers.
+  - Getters are only generated for message and oneof fields.
+  - Enum types do not get an Enum method.
+
+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;
+	  }
+	  oneof union {
+	    int32 number = 6;
+	    string name = 7;
+	  }
+	}
+
+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:"-"`
+	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"`
+		// Types that are valid to be assigned to Union:
+		//	*Test_Number
+		//	*Test_Name
+		Union            isTest_Union `protobuf_oneof:"union"`
+		XXX_unrecognized []byte       `json:"-"`
+	}
+	func (m *Test) Reset()         { *m = Test{} }
+	func (m *Test) String() string { return proto.CompactTextString(m) }
+	func (*Test) ProtoMessage() {}
+
+	type isTest_Union interface {
+		isTest_Union()
+	}
+
+	type Test_Number struct {
+		Number int32 `protobuf:"varint,6,opt,name=number"`
+	}
+	type Test_Name struct {
+		Name string `protobuf:"bytes,7,opt,name=name"`
+	}
+
+	func (*Test_Number) isTest_Union() {}
+	func (*Test_Name) isTest_Union()   {}
+
+	func (m *Test) GetUnion() isTest_Union {
+		if m != nil {
+			return m.Union
 		}
 		}
-		func (m *Test) Reset()         { *m = Test{} }
-		func (m *Test) String() string { return proto.CompactTextString(m) }
-		func (*Test) ProtoMessage()    {}
-		const Default_Test_Type int32 = 77
+		return nil
+	}
+	const Default_Test_Type int32 = 77
 
 
-		func (m *Test) GetLabel() string {
-			if m != nil && m.Label != nil {
-				return *m.Label
-			}
-			return ""
+	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) 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
+	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) }
 
 
-		type Test_OptionalGroup struct {
-			RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
+	func (m *Test_OptionalGroup) GetRequiredField() string {
+		if m != nil && m.RequiredField != nil {
+			return *m.RequiredField
 		}
 		}
-		func (m *Test_OptionalGroup) Reset()         { *m = Test_OptionalGroup{} }
-		func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
+		return ""
+	}
 
 
-		func (m *Test_OptionalGroup) GetRequiredField() string {
-			if m != nil && m.RequiredField != nil {
-				return *m.RequiredField
-			}
-			return ""
+	func (m *Test) GetNumber() int32 {
+		if x, ok := m.GetUnion().(*Test_Number); ok {
+			return x.Number
 		}
 		}
+		return 0
+	}
 
 
-		func init() {
-			proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
+	func (m *Test) GetName() string {
+		if x, ok := m.GetUnion().(*Test_Name); ok {
+			return x.Name
 		}
 		}
+		return ""
+	}
 
 
-	To create and play with a Test object:
+	func init() {
+		proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
+	}
 
 
-		package main
+To create and play with a Test object:
 
 
-		import (
-			"log"
+	package main
 
 
-			"github.com/golang/protobuf/proto"
-			pb "./example.pb"
-		)
+	import (
+		"log"
 
 
-		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.
+		"github.com/golang/protobuf/proto"
+		pb "./example.pb"
+	)
+
+	func main() {
+		test := &pb.Test{
+			Label: proto.String("hello"),
+			Type:  proto.Int32(17),
+			Reps:  []int64{1, 2, 3},
+			Optionalgroup: &pb.Test_OptionalGroup{
+				RequiredField: proto.String("good bye"),
+			},
+			Union: &pb.Test_Name{"fred"},
+		}
+		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())
+		}
+		// Use a type switch to determine which oneof was set.
+		switch u := test.Union.(type) {
+		case *pb.Test_Number: // u.Number contains the number.
+		case *pb.Test_Name: // u.Name contains the string.
+		}
+		// etc.
+	}
 */
 */
 package proto
 package proto
 
 
@@ -211,6 +269,7 @@ import (
 	"fmt"
 	"fmt"
 	"log"
 	"log"
 	"reflect"
 	"reflect"
+	"sort"
 	"strconv"
 	"strconv"
 	"sync"
 	"sync"
 )
 )
@@ -385,13 +444,13 @@ func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32,
 
 
 // DebugPrint dumps the encoded data in b in a debugging format with a header
 // 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.
 // including the string s. Used in testing but made available for general debugging.
-func (o *Buffer) DebugPrint(s string, b []byte) {
+func (p *Buffer) DebugPrint(s string, b []byte) {
 	var u uint64
 	var u uint64
 
 
-	obuf := o.buf
-	index := o.index
-	o.buf = b
-	o.index = 0
+	obuf := p.buf
+	index := p.index
+	p.buf = b
+	p.index = 0
 	depth := 0
 	depth := 0
 
 
 	fmt.Printf("\n--- %s ---\n", s)
 	fmt.Printf("\n--- %s ---\n", s)
@@ -402,12 +461,12 @@ out:
 			fmt.Print("  ")
 			fmt.Print("  ")
 		}
 		}
 
 
-		index := o.index
-		if index == len(o.buf) {
+		index := p.index
+		if index == len(p.buf) {
 			break
 			break
 		}
 		}
 
 
-		op, err := o.DecodeVarint()
+		op, err := p.DecodeVarint()
 		if err != nil {
 		if err != nil {
 			fmt.Printf("%3d: fetching op err %v\n", index, err)
 			fmt.Printf("%3d: fetching op err %v\n", index, err)
 			break out
 			break out
@@ -424,7 +483,7 @@ out:
 		case WireBytes:
 		case WireBytes:
 			var r []byte
 			var r []byte
 
 
-			r, err = o.DecodeRawBytes(false)
+			r, err = p.DecodeRawBytes(false)
 			if err != nil {
 			if err != nil {
 				break out
 				break out
 			}
 			}
@@ -445,7 +504,7 @@ out:
 			fmt.Printf("\n")
 			fmt.Printf("\n")
 
 
 		case WireFixed32:
 		case WireFixed32:
-			u, err = o.DecodeFixed32()
+			u, err = p.DecodeFixed32()
 			if err != nil {
 			if err != nil {
 				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
 				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
 				break out
 				break out
@@ -453,16 +512,15 @@ out:
 			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
 			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
 
 
 		case WireFixed64:
 		case WireFixed64:
-			u, err = o.DecodeFixed64()
+			u, err = p.DecodeFixed64()
 			if err != nil {
 			if err != nil {
 				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
 				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
 				break out
 				break out
 			}
 			}
 			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
 			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
-			break
 
 
 		case WireVarint:
 		case WireVarint:
-			u, err = o.DecodeVarint()
+			u, err = p.DecodeVarint()
 			if err != nil {
 			if err != nil {
 				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
 				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
 				break out
 				break out
@@ -470,30 +528,22 @@ out:
 			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
 			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
 
 
 		case WireStartGroup:
 		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)
 			fmt.Printf("%3d: t=%3d start\n", index, tag)
 			depth++
 			depth++
 
 
 		case WireEndGroup:
 		case WireEndGroup:
 			depth--
 			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)
 			fmt.Printf("%3d: t=%3d end\n", index, tag)
 		}
 		}
 	}
 	}
 
 
 	if depth != 0 {
 	if depth != 0 {
-		fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth)
+		fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
 	}
 	}
 	fmt.Printf("\n")
 	fmt.Printf("\n")
 
 
-	o.buf = obuf
-	o.index = index
+	p.buf = obuf
+	p.index = index
 }
 }
 
 
 // SetDefaults sets unset protocol buffer fields to their default values.
 // SetDefaults sets unset protocol buffer fields to their default values.
@@ -607,13 +657,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
 
 
 	for _, ni := range dm.nested {
 	for _, ni := range dm.nested {
 		f := v.Field(ni)
 		f := v.Field(ni)
-		if f.IsNil() {
-			continue
-		}
-		// f is *T or []*T
-		if f.Kind() == reflect.Ptr {
+		// f is *T or []*T or map[T]*T
+		switch f.Kind() {
+		case reflect.Ptr:
+			if f.IsNil() {
+				continue
+			}
 			setDefaults(f, recur, zeros)
 			setDefaults(f, recur, zeros)
-		} else {
+
+		case reflect.Slice:
 			for i := 0; i < f.Len(); i++ {
 			for i := 0; i < f.Len(); i++ {
 				e := f.Index(i)
 				e := f.Index(i)
 				if e.IsNil() {
 				if e.IsNil() {
@@ -621,6 +673,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
 				}
 				}
 				setDefaults(e, recur, zeros)
 				setDefaults(e, recur, zeros)
 			}
 			}
+
+		case reflect.Map:
+			for _, k := range f.MapKeys() {
+				e := f.MapIndex(k)
+				if e.IsNil() {
+					continue
+				}
+				setDefaults(e, recur, zeros)
+			}
 		}
 		}
 	}
 	}
 }
 }
@@ -646,10 +707,6 @@ type scalarField struct {
 	value interface{}  // the proto-declared default value, or nil
 	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.
 // t is a struct type.
 func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
 func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
 	sprop := GetProperties(t)
 	sprop := GetProperties(t)
@@ -661,88 +718,118 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
 		}
 		}
 		ft := t.Field(fi).Type
 		ft := t.Field(fi).Type
 
 
-		// nested messages
-		if ptrToStruct(ft) || (ft.Kind() == reflect.Slice && ptrToStruct(ft.Elem())) {
+		sf, nested, err := fieldDefault(ft, prop)
+		switch {
+		case err != nil:
+			log.Print(err)
+		case nested:
 			dm.nested = append(dm.nested, fi)
 			dm.nested = append(dm.nested, fi)
-			continue
+		case sf != nil:
+			sf.index = fi
+			dm.scalars = append(dm.scalars, *sf)
 		}
 		}
+	}
 
 
-		sf := scalarField{
-			index: fi,
-			kind:  ft.Elem().Kind(),
-		}
+	return dm
+}
 
 
-		// scalar fields without defaults
-		if !prop.HasDefault {
-			dm.scalars = append(dm.scalars, sf)
-			continue
+// fieldDefault returns the scalarField for field type ft.
+// sf will be nil if the field can not have a default.
+// nestedMessage will be true if this is a nested message.
+// Note that sf.index is not set on return.
+func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
+	var canHaveDefault bool
+	switch ft.Kind() {
+	case reflect.Ptr:
+		if ft.Elem().Kind() == reflect.Struct {
+			nestedMessage = true
+		} else {
+			canHaveDefault = true // proto2 scalar field
 		}
 		}
 
 
-		// a scalar field: either *T or []byte
+	case reflect.Slice:
 		switch ft.Elem().Kind() {
 		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.Ptr:
+			nestedMessage = true // repeated message
 		case reflect.Uint8:
 		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
+			canHaveDefault = true // bytes field
 		}
 		}
 
 
-		dm.scalars = append(dm.scalars, sf)
+	case reflect.Map:
+		if ft.Elem().Kind() == reflect.Ptr {
+			nestedMessage = true // map with message values
+		}
 	}
 	}
 
 
-	return dm
+	if !canHaveDefault {
+		if nestedMessage {
+			return nil, true, nil
+		}
+		return nil, false, nil
+	}
+
+	// We now know that ft is a pointer or slice.
+	sf = &scalarField{kind: ft.Elem().Kind()}
+
+	// scalar fields without defaults
+	if !prop.HasDefault {
+		return sf, false, nil
+	}
+
+	// a scalar field: either *T or []byte
+	switch ft.Elem().Kind() {
+	case reflect.Bool:
+		x, err := strconv.ParseBool(prop.Default)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
+		}
+		sf.value = x
+	case reflect.Float32:
+		x, err := strconv.ParseFloat(prop.Default, 32)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
+		}
+		sf.value = float32(x)
+	case reflect.Float64:
+		x, err := strconv.ParseFloat(prop.Default, 64)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
+		}
+		sf.value = x
+	case reflect.Int32:
+		x, err := strconv.ParseInt(prop.Default, 10, 32)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
+		}
+		sf.value = int32(x)
+	case reflect.Int64:
+		x, err := strconv.ParseInt(prop.Default, 10, 64)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
+		}
+		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 {
+			return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
+		}
+		sf.value = uint32(x)
+	case reflect.Uint64:
+		x, err := strconv.ParseUint(prop.Default, 10, 64)
+		if err != nil {
+			return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
+		}
+		sf.value = x
+	default:
+		return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
+	}
+
+	return sf, false, nil
 }
 }
 
 
 // Map fields may have key types of non-float scalars, strings and enums.
 // Map fields may have key types of non-float scalars, strings and enums.
@@ -750,10 +837,58 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
 // If this turns out to be inefficient we can always consider other options,
 // If this turns out to be inefficient we can always consider other options,
 // such as doing a Schwartzian transform.
 // such as doing a Schwartzian transform.
 
 
-type mapKeys []reflect.Value
+func mapKeys(vs []reflect.Value) sort.Interface {
+	s := mapKeySorter{
+		vs: vs,
+		// default Less function: textual comparison
+		less: func(a, b reflect.Value) bool {
+			return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
+		},
+	}
+
+	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
+	// numeric keys are sorted numerically.
+	if len(vs) == 0 {
+		return s
+	}
+	switch vs[0].Kind() {
+	case reflect.Int32, reflect.Int64:
+		s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
+	case reflect.Uint32, reflect.Uint64:
+		s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
+	}
+
+	return s
+}
+
+type mapKeySorter struct {
+	vs   []reflect.Value
+	less func(a, b reflect.Value) bool
+}
 
 
-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())
+func (s mapKeySorter) Len() int      { return len(s.vs) }
+func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
+func (s mapKeySorter) Less(i, j int) bool {
+	return s.less(s.vs[i], s.vs[j])
 }
 }
+
+// isProto3Zero reports whether v is a zero proto3 value.
+func isProto3Zero(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Bool:
+		return !v.Bool()
+	case reflect.Int32, reflect.Int64:
+		return v.Int() == 0
+	case reflect.Uint32, reflect.Uint64:
+		return v.Uint() == 0
+	case reflect.Float32, reflect.Float64:
+		return v.Float() == 0
+	case reflect.String:
+		return v.String() == ""
+	}
+	return false
+}
+
+// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
+// to assert that that code is compatible with this version of the proto package.
+const ProtoPackageIsVersion1 = true

+ 17 - 24
Godeps/_workspace/src/github.com/golang/protobuf/proto/message_set.go

@@ -44,11 +44,11 @@ import (
 	"sort"
 	"sort"
 )
 )
 
 
-// ErrNoMessageTypeId occurs when a protocol buffer does not have a message type ID.
+// 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.
 // 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")
+var errNoMessageTypeID = errors.New("proto does not have a message type ID")
 
 
-// The first two types (_MessageSet_Item and MessageSet)
+// The first two types (_MessageSet_Item and messageSet)
 // model what the protocol compiler produces for the following protocol message:
 // model what the protocol compiler produces for the following protocol message:
 //   message MessageSet {
 //   message MessageSet {
 //     repeated group Item = 1 {
 //     repeated group Item = 1 {
@@ -58,27 +58,20 @@ var ErrNoMessageTypeId = errors.New("proto does not have a message type ID")
 //   }
 //   }
 // That is the MessageSet wire format. We can't use a proto to generate these
 // 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.
 // 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 {
 type _MessageSet_Item struct {
 	TypeId  *int32 `protobuf:"varint,2,req,name=type_id"`
 	TypeId  *int32 `protobuf:"varint,2,req,name=type_id"`
 	Message []byte `protobuf:"bytes,3,req,name=message"`
 	Message []byte `protobuf:"bytes,3,req,name=message"`
 }
 }
 
 
-type MessageSet struct {
+type messageSet struct {
 	Item             []*_MessageSet_Item `protobuf:"group,1,rep"`
 	Item             []*_MessageSet_Item `protobuf:"group,1,rep"`
 	XXX_unrecognized []byte
 	XXX_unrecognized []byte
 	// TODO: caching?
 	// TODO: caching?
 }
 }
 
 
-// Make sure MessageSet is a Message.
-var _ Message = (*MessageSet)(nil)
+// Make sure messageSet is a Message.
+var _ Message = (*messageSet)(nil)
 
 
 // messageTypeIder is an interface satisfied by a protocol buffer type
 // messageTypeIder is an interface satisfied by a protocol buffer type
 // that may be stored in a MessageSet.
 // that may be stored in a MessageSet.
@@ -86,7 +79,7 @@ type messageTypeIder interface {
 	MessageTypeId() int32
 	MessageTypeId() int32
 }
 }
 
 
-func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
+func (ms *messageSet) find(pb Message) *_MessageSet_Item {
 	mti, ok := pb.(messageTypeIder)
 	mti, ok := pb.(messageTypeIder)
 	if !ok {
 	if !ok {
 		return nil
 		return nil
@@ -100,24 +93,24 @@ func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
 	return nil
 	return nil
 }
 }
 
 
-func (ms *MessageSet) Has(pb Message) bool {
+func (ms *messageSet) Has(pb Message) bool {
 	if ms.find(pb) != nil {
 	if ms.find(pb) != nil {
 		return true
 		return true
 	}
 	}
 	return false
 	return false
 }
 }
 
 
-func (ms *MessageSet) Unmarshal(pb Message) error {
+func (ms *messageSet) Unmarshal(pb Message) error {
 	if item := ms.find(pb); item != nil {
 	if item := ms.find(pb); item != nil {
 		return Unmarshal(item.Message, pb)
 		return Unmarshal(item.Message, pb)
 	}
 	}
 	if _, ok := pb.(messageTypeIder); !ok {
 	if _, ok := pb.(messageTypeIder); !ok {
-		return ErrNoMessageTypeId
+		return errNoMessageTypeID
 	}
 	}
 	return nil // TODO: return error instead?
 	return nil // TODO: return error instead?
 }
 }
 
 
-func (ms *MessageSet) Marshal(pb Message) error {
+func (ms *messageSet) Marshal(pb Message) error {
 	msg, err := Marshal(pb)
 	msg, err := Marshal(pb)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
@@ -130,7 +123,7 @@ func (ms *MessageSet) Marshal(pb Message) error {
 
 
 	mti, ok := pb.(messageTypeIder)
 	mti, ok := pb.(messageTypeIder)
 	if !ok {
 	if !ok {
-		return ErrNoMessageTypeId
+		return errNoMessageTypeID
 	}
 	}
 
 
 	mtid := mti.MessageTypeId()
 	mtid := mti.MessageTypeId()
@@ -141,9 +134,9 @@ func (ms *MessageSet) Marshal(pb Message) error {
 	return nil
 	return nil
 }
 }
 
 
-func (ms *MessageSet) Reset()         { *ms = MessageSet{} }
-func (ms *MessageSet) String() string { return CompactTextString(ms) }
-func (*MessageSet) ProtoMessage()     {}
+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.
 // Support for the message_set_wire_format message option.
 
 
@@ -169,7 +162,7 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
 	}
 	}
 	sort.Ints(ids)
 	sort.Ints(ids)
 
 
-	ms := &MessageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
+	ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
 	for _, id := range ids {
 	for _, id := range ids {
 		e := m[int32(id)]
 		e := m[int32(id)]
 		// Remove the wire type and field number varint, as well as the length varint.
 		// Remove the wire type and field number varint, as well as the length varint.
@@ -186,7 +179,7 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
 // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
 // 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.
 // 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 {
 func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
-	ms := new(MessageSet)
+	ms := new(messageSet)
 	if err := Unmarshal(buf, ms); err != nil {
 	if err := Unmarshal(buf, ms); err != nil {
 		return err
 		return err
 	}
 	}

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

@@ -38,7 +38,7 @@ import (
 
 
 func TestUnmarshalMessageSetWithDuplicate(t *testing.T) {
 func TestUnmarshalMessageSetWithDuplicate(t *testing.T) {
 	// Check that a repeated message set entry will be concatenated.
 	// Check that a repeated message set entry will be concatenated.
-	in := &MessageSet{
+	in := &messageSet{
 		Item: []*_MessageSet_Item{
 		Item: []*_MessageSet_Item{
 			{TypeId: Int32(12345), Message: []byte("hoo")},
 			{TypeId: Int32(12345), Message: []byte("hoo")},
 			{TypeId: Int32(12345), Message: []byte("hah")},
 			{TypeId: Int32(12345), Message: []byte("hah")},

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

@@ -144,8 +144,8 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
 	return structPointer_ifield(p, f).(*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 {
+// NewAt returns the reflect.Value for a pointer to a field in the struct.
+func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
 	return structPointer_field(p, f).Addr()
 	return structPointer_field(p, f).Addr()
 }
 }
 
 

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

@@ -130,8 +130,8 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
 	return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
 	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 {
+// NewAt returns the reflect.Value for a pointer to a field in the struct.
+func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
 	return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
 	return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
 }
 }
 
 

+ 125 - 7
Godeps/_workspace/src/github.com/golang/protobuf/proto/properties.go

@@ -37,6 +37,7 @@ package proto
 
 
 import (
 import (
 	"fmt"
 	"fmt"
+	"log"
 	"os"
 	"os"
 	"reflect"
 	"reflect"
 	"sort"
 	"sort"
@@ -84,6 +85,15 @@ type decoder func(p *Buffer, prop *Properties, base structPointer) error
 // A valueDecoder decodes a single integer in a particular encoding.
 // A valueDecoder decodes a single integer in a particular encoding.
 type valueDecoder func(o *Buffer) (x uint64, err error)
 type valueDecoder func(o *Buffer) (x uint64, err error)
 
 
+// A oneofMarshaler does the marshaling for all oneof fields in a message.
+type oneofMarshaler func(Message, *Buffer) error
+
+// A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
+type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error)
+
+// A oneofSizer does the sizing for all oneof fields in a message.
+type oneofSizer func(Message) int
+
 // tagMap is an optimization over map[int]int for typical protocol buffer
 // 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
 // use-cases. Encoded protocol buffers are often in tag order with small tag
 // numbers.
 // numbers.
@@ -132,6 +142,22 @@ type StructProperties struct {
 	order            []int          // list of struct field numbers in tag order
 	order            []int          // list of struct field numbers in tag order
 	unrecField       field          // field id of the XXX_unrecognized []byte field
 	unrecField       field          // field id of the XXX_unrecognized []byte field
 	extendable       bool           // is this an extendable proto
 	extendable       bool           // is this an extendable proto
+
+	oneofMarshaler   oneofMarshaler
+	oneofUnmarshaler oneofUnmarshaler
+	oneofSizer       oneofSizer
+	stype            reflect.Type
+
+	// OneofTypes contains information about the oneof fields in this message.
+	// It is keyed by the original name of a field.
+	OneofTypes map[string]*OneofProperties
+}
+
+// OneofProperties represents information about a specific field in a oneof.
+type OneofProperties struct {
+	Type  reflect.Type // pointer to generated struct type for this oneof field
+	Field int          // struct field number of the containing oneof in the message
+	Prop  *Properties
 }
 }
 
 
 // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
 // Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec.
@@ -156,6 +182,7 @@ type Properties struct {
 	Packed   bool   // relevant for repeated primitives only
 	Packed   bool   // relevant for repeated primitives only
 	Enum     string // set for enum types only
 	Enum     string // set for enum types only
 	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
 	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
+	oneof    bool   // whether this is a oneof field
 
 
 	Default    string // default value
 	Default    string // default value
 	HasDefault bool   // whether an explicit default was provided
 	HasDefault bool   // whether an explicit default was provided
@@ -208,6 +235,9 @@ func (p *Properties) String() string {
 	if p.proto3 {
 	if p.proto3 {
 		s += ",proto3"
 		s += ",proto3"
 	}
 	}
+	if p.oneof {
+		s += ",oneof"
+	}
 	if len(p.Enum) > 0 {
 	if len(p.Enum) > 0 {
 		s += ",enum=" + p.Enum
 		s += ",enum=" + p.Enum
 	}
 	}
@@ -284,6 +314,8 @@ func (p *Properties) Parse(s string) {
 			p.Enum = f[5:]
 			p.Enum = f[5:]
 		case f == "proto3":
 		case f == "proto3":
 			p.proto3 = true
 			p.proto3 = true
+		case f == "oneof":
+			p.oneof = true
 		case strings.HasPrefix(f, "def="):
 		case strings.HasPrefix(f, "def="):
 			p.HasDefault = true
 			p.HasDefault = true
 			p.Default = f[4:] // rest of string
 			p.Default = f[4:] // rest of string
@@ -440,7 +472,12 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock
 			p.enc = (*Buffer).enc_slice_byte
 			p.enc = (*Buffer).enc_slice_byte
 			p.dec = (*Buffer).dec_slice_byte
 			p.dec = (*Buffer).dec_slice_byte
 			p.size = size_slice_byte
 			p.size = size_slice_byte
-			if p.proto3 {
+			// This is a []byte, which is either a bytes field,
+			// or the value of a map field. In the latter case,
+			// we always encode an empty []byte, so we should not
+			// use the proto3 enc/size funcs.
+			// f == nil iff this is the key/value of a map field.
+			if p.proto3 && f != nil {
 				p.enc = (*Buffer).enc_proto3_slice_byte
 				p.enc = (*Buffer).enc_proto3_slice_byte
 				p.size = size_proto3_slice_byte
 				p.size = size_proto3_slice_byte
 			}
 			}
@@ -595,7 +632,7 @@ func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructF
 }
 }
 
 
 var (
 var (
-	mutex         sync.Mutex
+	propertiesMu  sync.RWMutex
 	propertiesMap = make(map[reflect.Type]*StructProperties)
 	propertiesMap = make(map[reflect.Type]*StructProperties)
 )
 )
 
 
@@ -605,13 +642,26 @@ func GetProperties(t reflect.Type) *StructProperties {
 	if t.Kind() != reflect.Struct {
 	if t.Kind() != reflect.Struct {
 		panic("proto: type must have kind struct")
 		panic("proto: type must have kind struct")
 	}
 	}
-	mutex.Lock()
-	sprop := getPropertiesLocked(t)
-	mutex.Unlock()
+
+	// Most calls to GetProperties in a long-running program will be
+	// retrieving details for types we have seen before.
+	propertiesMu.RLock()
+	sprop, ok := propertiesMap[t]
+	propertiesMu.RUnlock()
+	if ok {
+		if collectStats {
+			stats.Chit++
+		}
+		return sprop
+	}
+
+	propertiesMu.Lock()
+	sprop = getPropertiesLocked(t)
+	propertiesMu.Unlock()
 	return sprop
 	return sprop
 }
 }
 
 
-// getPropertiesLocked requires that mutex is held.
+// getPropertiesLocked requires that propertiesMu is held.
 func getPropertiesLocked(t reflect.Type) *StructProperties {
 func getPropertiesLocked(t reflect.Type) *StructProperties {
 	if prop, ok := propertiesMap[t]; ok {
 	if prop, ok := propertiesMap[t]; ok {
 		if collectStats {
 		if collectStats {
@@ -647,6 +697,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 		if f.Name == "XXX_unrecognized" { // special case
 		if f.Name == "XXX_unrecognized" { // special case
 			prop.unrecField = toField(&f)
 			prop.unrecField = toField(&f)
 		}
 		}
+		oneof := f.Tag.Get("protobuf_oneof") != "" // special case
 		prop.Prop[i] = p
 		prop.Prop[i] = p
 		prop.order[i] = i
 		prop.order[i] = i
 		if debug {
 		if debug {
@@ -656,7 +707,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 			}
 			}
 			print("\n")
 			print("\n")
 		}
 		}
-		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") {
+		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && !oneof {
 			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
 			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
 		}
 		}
 	}
 	}
@@ -664,6 +715,41 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 	// Re-order prop.order.
 	// Re-order prop.order.
 	sort.Sort(prop)
 	sort.Sort(prop)
 
 
+	type oneofMessage interface {
+		XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
+	}
+	if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok {
+		var oots []interface{}
+		prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
+		prop.stype = t
+
+		// Interpret oneof metadata.
+		prop.OneofTypes = make(map[string]*OneofProperties)
+		for _, oot := range oots {
+			oop := &OneofProperties{
+				Type: reflect.ValueOf(oot).Type(), // *T
+				Prop: new(Properties),
+			}
+			sft := oop.Type.Elem().Field(0)
+			oop.Prop.Name = sft.Name
+			oop.Prop.Parse(sft.Tag.Get("protobuf"))
+			// There will be exactly one interface field that
+			// this new value is assignable to.
+			for i := 0; i < t.NumField(); i++ {
+				f := t.Field(i)
+				if f.Type.Kind() != reflect.Interface {
+					continue
+				}
+				if !oop.Type.AssignableTo(f.Type) {
+					continue
+				}
+				oop.Field = i
+				break
+			}
+			prop.OneofTypes[oop.Prop.OrigName] = oop
+		}
+	}
+
 	// build required counts
 	// build required counts
 	// build tags
 	// build tags
 	reqCount := 0
 	reqCount := 0
@@ -722,3 +808,35 @@ func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[
 	}
 	}
 	enumValueMaps[typeName] = valueMap
 	enumValueMaps[typeName] = valueMap
 }
 }
+
+// EnumValueMap returns the mapping from names to integers of the
+// enum type enumType, or a nil if not found.
+func EnumValueMap(enumType string) map[string]int32 {
+	return enumValueMaps[enumType]
+}
+
+// A registry of all linked message types.
+// The string is a fully-qualified proto name ("pkg.Message").
+var (
+	protoTypes    = make(map[string]reflect.Type)
+	revProtoTypes = make(map[reflect.Type]string)
+)
+
+// RegisterType is called from generated code and maps from the fully qualified
+// proto name to the type (pointer to struct) of the protocol buffer.
+func RegisterType(x Message, name string) {
+	if _, ok := protoTypes[name]; ok {
+		// TODO: Some day, make this a panic.
+		log.Printf("proto: duplicate proto type registered: %s", name)
+		return
+	}
+	t := reflect.TypeOf(x)
+	protoTypes[name] = t
+	revProtoTypes[t] = name
+}
+
+// MessageName returns the fully-qualified proto name for the given message type.
+func MessageName(x Message) string { return revProtoTypes[reflect.TypeOf(x)] }
+
+// MessageType returns the message type (pointer to struct) for a named message.
+func MessageType(name string) reflect.Type { return protoTypes[name] }

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

@@ -1,44 +0,0 @@
-# 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

+ 122 - 0
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto/proto3.pb.go

@@ -0,0 +1,122 @@
+// Code generated by protoc-gen-go.
+// source: proto3_proto/proto3.proto
+// DO NOT EDIT!
+
+/*
+Package proto3_proto is a generated protocol buffer package.
+
+It is generated from these files:
+	proto3_proto/proto3.proto
+
+It has these top-level messages:
+	Message
+	Nested
+	MessageWithMap
+*/
+package proto3_proto
+
+import proto "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+import testdata "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata"
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+
+type Message_Humour int32
+
+const (
+	Message_UNKNOWN     Message_Humour = 0
+	Message_PUNS        Message_Humour = 1
+	Message_SLAPSTICK   Message_Humour = 2
+	Message_BILL_BAILEY Message_Humour = 3
+)
+
+var Message_Humour_name = map[int32]string{
+	0: "UNKNOWN",
+	1: "PUNS",
+	2: "SLAPSTICK",
+	3: "BILL_BAILEY",
+}
+var Message_Humour_value = map[string]int32{
+	"UNKNOWN":     0,
+	"PUNS":        1,
+	"SLAPSTICK":   2,
+	"BILL_BAILEY": 3,
+}
+
+func (x Message_Humour) String() string {
+	return proto.EnumName(Message_Humour_name, int32(x))
+}
+
+type Message struct {
+	Name         string                           `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	Hilarity     Message_Humour                   `protobuf:"varint,2,opt,name=hilarity,enum=proto3_proto.Message_Humour" json:"hilarity,omitempty"`
+	HeightInCm   uint32                           `protobuf:"varint,3,opt,name=height_in_cm" json:"height_in_cm,omitempty"`
+	Data         []byte                           `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"`
+	ResultCount  int64                            `protobuf:"varint,7,opt,name=result_count" json:"result_count,omitempty"`
+	TrueScotsman bool                             `protobuf:"varint,8,opt,name=true_scotsman" json:"true_scotsman,omitempty"`
+	Score        float32                          `protobuf:"fixed32,9,opt,name=score" json:"score,omitempty"`
+	Key          []uint64                         `protobuf:"varint,5,rep,name=key" json:"key,omitempty"`
+	Nested       *Nested                          `protobuf:"bytes,6,opt,name=nested" json:"nested,omitempty"`
+	Terrain      map[string]*Nested               `protobuf:"bytes,10,rep,name=terrain" json:"terrain,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+	Proto2Field  *testdata.SubDefaults            `protobuf:"bytes,11,opt,name=proto2_field" json:"proto2_field,omitempty"`
+	Proto2Value  map[string]*testdata.SubDefaults `protobuf:"bytes,13,rep,name=proto2_value" json:"proto2_value,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"`
+}
+
+func (m *Message) Reset()         { *m = Message{} }
+func (m *Message) String() string { return proto.CompactTextString(m) }
+func (*Message) ProtoMessage()    {}
+
+func (m *Message) GetNested() *Nested {
+	if m != nil {
+		return m.Nested
+	}
+	return nil
+}
+
+func (m *Message) GetTerrain() map[string]*Nested {
+	if m != nil {
+		return m.Terrain
+	}
+	return nil
+}
+
+func (m *Message) GetProto2Field() *testdata.SubDefaults {
+	if m != nil {
+		return m.Proto2Field
+	}
+	return nil
+}
+
+func (m *Message) GetProto2Value() map[string]*testdata.SubDefaults {
+	if m != nil {
+		return m.Proto2Value
+	}
+	return nil
+}
+
+type Nested struct {
+	Bunny string `protobuf:"bytes,1,opt,name=bunny" json:"bunny,omitempty"`
+}
+
+func (m *Nested) Reset()         { *m = Nested{} }
+func (m *Nested) String() string { return proto.CompactTextString(m) }
+func (*Nested) ProtoMessage()    {}
+
+type MessageWithMap struct {
+	ByteMapping map[bool][]byte `protobuf:"bytes,1,rep,name=byte_mapping" json:"byte_mapping,omitempty" protobuf_key:"varint,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (m *MessageWithMap) Reset()         { *m = MessageWithMap{} }
+func (m *MessageWithMap) String() string { return proto.CompactTextString(m) }
+func (*MessageWithMap) ProtoMessage()    {}
+
+func (m *MessageWithMap) GetByteMapping() map[bool][]byte {
+	if m != nil {
+		return m.ByteMapping
+	}
+	return nil
+}
+
+func init() {
+	proto.RegisterEnum("proto3_proto.Message_Humour", Message_Humour_name, Message_Humour_value)
+}

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

@@ -31,6 +31,8 @@
 
 
 syntax = "proto3";
 syntax = "proto3";
 
 
+import "testdata/test.proto";
+
 package proto3_proto;
 package proto3_proto;
 
 
 message Message {
 message Message {
@@ -51,8 +53,16 @@ message Message {
 
 
   repeated uint64 key = 5;
   repeated uint64 key = 5;
   Nested nested = 6;
   Nested nested = 6;
+
+  map<string, Nested> terrain = 10;
+  testdata.SubDefaults proto2_field = 11;
+  map<string, testdata.SubDefaults> proto2_value = 13;
 }
 }
 
 
 message Nested {
 message Nested {
   string bunny = 1;
   string bunny = 1;
 }
 }
+
+message MessageWithMap {
+  map<bool, bytes> byte_mapping = 1;
+}

+ 33 - 1
Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_test.go

@@ -34,8 +34,9 @@ package proto_test
 import (
 import (
 	"testing"
 	"testing"
 
 
-	pb "./proto3_proto"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+	pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto"
+	tpb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata"
 )
 )
 
 
 func TestProto3ZeroValues(t *testing.T) {
 func TestProto3ZeroValues(t *testing.T) {
@@ -91,3 +92,34 @@ func TestRoundTripProto3(t *testing.T) {
 		t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2)
 		t.Errorf("proto.Equal returned false:\n m: %v\nm2: %v", m, m2)
 	}
 	}
 }
 }
+
+func TestProto3SetDefaults(t *testing.T) {
+	in := &pb.Message{
+		Terrain: map[string]*pb.Nested{
+			"meadow": new(pb.Nested),
+		},
+		Proto2Field: new(tpb.SubDefaults),
+		Proto2Value: map[string]*tpb.SubDefaults{
+			"badlands": new(tpb.SubDefaults),
+		},
+	}
+
+	got := proto.Clone(in).(*pb.Message)
+	proto.SetDefaults(got)
+
+	// There are no defaults in proto3.  Everything should be the zero value, but
+	// we need to remember to set defaults for nested proto2 messages.
+	want := &pb.Message{
+		Terrain: map[string]*pb.Nested{
+			"meadow": new(pb.Nested),
+		},
+		Proto2Field: &tpb.SubDefaults{N: proto.Int64(7)},
+		Proto2Value: map[string]*tpb.SubDefaults{
+			"badlands": &tpb.SubDefaults{N: proto.Int64(7)},
+		},
+	}
+
+	if !proto.Equal(got, want) {
+		t.Errorf("with in = %v\nproto.SetDefaults(in) =>\ngot %v\nwant %v", in, got, want)
+	}
+}

+ 31 - 2
Godeps/_workspace/src/github.com/golang/protobuf/proto/size_test.go

@@ -33,11 +33,12 @@ package proto_test
 
 
 import (
 import (
 	"log"
 	"log"
+	"strings"
 	"testing"
 	"testing"
 
 
-	proto3pb "./proto3_proto"
-	pb "./testdata"
 	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
 	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+	proto3pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto"
+	pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata"
 )
 )
 
 
 var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)}
 var messageWithExtension1 = &pb.MyMessage{Count: Int32(7)}
@@ -113,10 +114,38 @@ var SizeTests = []struct {
 	{"proto3 bytes", &proto3pb.Message{Data: []byte("wowsa")}},
 	{"proto3 bytes", &proto3pb.Message{Data: []byte("wowsa")}},
 	{"proto3 bytes, empty", &proto3pb.Message{Data: []byte{}}},
 	{"proto3 bytes, empty", &proto3pb.Message{Data: []byte{}}},
 	{"proto3 enum", &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
 	{"proto3 enum", &proto3pb.Message{Hilarity: proto3pb.Message_PUNS}},
+	{"proto3 map field with empty bytes", &proto3pb.MessageWithMap{ByteMapping: map[bool][]byte{false: []byte{}}}},
 
 
 	{"map field", &pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob", 7: "Andrew"}}},
 	{"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 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")}}},
 	{"map field with bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte("this time for sure")}}},
+	{"map field with empty bytes", &pb.MessageWithMap{ByteMapping: map[bool][]byte{true: []byte{}}}},
+
+	{"map field with big entry", &pb.MessageWithMap{NameMapping: map[int32]string{8: strings.Repeat("x", 125)}}},
+	{"map field with big key and val", &pb.MessageWithMap{StrToStr: map[string]string{strings.Repeat("x", 70): strings.Repeat("y", 70)}}},
+	{"map field with big numeric key", &pb.MessageWithMap{NameMapping: map[int32]string{0xf00d: "om nom nom"}}},
+
+	{"oneof not set", &pb.Oneof{}},
+	{"oneof bool", &pb.Oneof{Union: &pb.Oneof_F_Bool{true}}},
+	{"oneof zero int32", &pb.Oneof{Union: &pb.Oneof_F_Int32{0}}},
+	{"oneof big int32", &pb.Oneof{Union: &pb.Oneof_F_Int32{1 << 20}}},
+	{"oneof int64", &pb.Oneof{Union: &pb.Oneof_F_Int64{42}}},
+	{"oneof fixed32", &pb.Oneof{Union: &pb.Oneof_F_Fixed32{43}}},
+	{"oneof fixed64", &pb.Oneof{Union: &pb.Oneof_F_Fixed64{44}}},
+	{"oneof uint32", &pb.Oneof{Union: &pb.Oneof_F_Uint32{45}}},
+	{"oneof uint64", &pb.Oneof{Union: &pb.Oneof_F_Uint64{46}}},
+	{"oneof float", &pb.Oneof{Union: &pb.Oneof_F_Float{47.1}}},
+	{"oneof double", &pb.Oneof{Union: &pb.Oneof_F_Double{48.9}}},
+	{"oneof string", &pb.Oneof{Union: &pb.Oneof_F_String{"Rhythmic Fman"}}},
+	{"oneof bytes", &pb.Oneof{Union: &pb.Oneof_F_Bytes{[]byte("let go")}}},
+	{"oneof sint32", &pb.Oneof{Union: &pb.Oneof_F_Sint32{50}}},
+	{"oneof sint64", &pb.Oneof{Union: &pb.Oneof_F_Sint64{51}}},
+	{"oneof enum", &pb.Oneof{Union: &pb.Oneof_F_Enum{pb.MyMessage_BLUE}}},
+	{"message for oneof", &pb.GoTestField{Label: String("k"), Type: String("v")}},
+	{"oneof message", &pb.Oneof{Union: &pb.Oneof_F_Message{&pb.GoTestField{Label: String("k"), Type: String("v")}}}},
+	{"oneof group", &pb.Oneof{Union: &pb.Oneof_FGroup{&pb.Oneof_F_Group{X: Int32(52)}}}},
+	{"oneof largest tag", &pb.Oneof{Union: &pb.Oneof_F_Largest_Tag{1}}},
+	{"multiple oneofs", &pb.Oneof{Union: &pb.Oneof_F_Int32{1}, Tormato: &pb.Oneof_Value{2}}},
 }
 }
 
 
 func TestSize(t *testing.T) {
 func TestSize(t *testing.T) {

File diff suppressed because it is too large
+ 1095 - 118
Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata/test.pb.go


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

@@ -233,6 +233,8 @@ message OtherMessage {
   optional bytes value = 2;
   optional bytes value = 2;
   optional float weight = 3;
   optional float weight = 3;
   optional InnerMessage inner = 4;
   optional InnerMessage inner = 4;
+
+  extensions 100 to max;
 }
 }
 
 
 message MyMessage {
 message MyMessage {
@@ -277,6 +279,62 @@ extend MyMessage {
   repeated string greeting = 106;
   repeated string greeting = 106;
 }
 }
 
 
+message ComplexExtension {
+  optional int32 first = 1;
+  optional int32 second = 2;
+  repeated int32 third = 3;
+}
+
+extend OtherMessage {
+  optional ComplexExtension complex = 200;
+  repeated ComplexExtension r_complex = 201;
+}
+
+message DefaultsMessage {
+  enum DefaultsEnum {
+    ZERO = 0;
+    ONE = 1;
+    TWO = 2;
+  };
+  extensions 100 to max;
+}
+
+extend DefaultsMessage {
+  optional double no_default_double = 101;
+  optional float no_default_float = 102;
+  optional int32 no_default_int32 = 103;
+  optional int64 no_default_int64 = 104;
+  optional uint32 no_default_uint32 = 105;
+  optional uint64 no_default_uint64 = 106;
+  optional sint32 no_default_sint32 = 107;
+  optional sint64 no_default_sint64 = 108;
+  optional fixed32 no_default_fixed32 = 109;
+  optional fixed64 no_default_fixed64 = 110;
+  optional sfixed32 no_default_sfixed32 = 111;
+  optional sfixed64 no_default_sfixed64 = 112;
+  optional bool no_default_bool = 113;
+  optional string no_default_string = 114;
+  optional bytes no_default_bytes = 115;
+  optional DefaultsMessage.DefaultsEnum no_default_enum = 116;
+
+  optional double default_double = 201 [default = 3.1415];
+  optional float default_float = 202 [default = 3.14];
+  optional int32 default_int32 = 203 [default = 42];
+  optional int64 default_int64 = 204 [default = 43];
+  optional uint32 default_uint32 = 205 [default = 44];
+  optional uint64 default_uint64 = 206 [default = 45];
+  optional sint32 default_sint32 = 207 [default = 46];
+  optional sint64 default_sint64 = 208 [default = 47];
+  optional fixed32 default_fixed32 = 209 [default = 48];
+  optional fixed64 default_fixed64 = 210 [default = 49];
+  optional sfixed32 default_sfixed32 = 211 [default = 50];
+  optional sfixed64 default_sfixed64 = 212 [default = 51];
+  optional bool default_bool = 213 [default = true];
+  optional string default_string = 214 [default = "Hello, string"];
+  optional bytes default_bytes = 215 [default = "Hello, bytes"];
+  optional DefaultsMessage.DefaultsEnum default_enum = 216 [default = ONE];
+}
+
 message MyMessageSet {
 message MyMessageSet {
   option message_set_wire_format = true;
   option message_set_wire_format = true;
   extensions 100 to max;
   extensions 100 to max;
@@ -431,4 +489,47 @@ message MessageWithMap {
   map<int32, string> name_mapping = 1;
   map<int32, string> name_mapping = 1;
   map<sint64, FloatingPoint> msg_mapping = 2;
   map<sint64, FloatingPoint> msg_mapping = 2;
   map<bool, bytes> byte_mapping = 3;
   map<bool, bytes> byte_mapping = 3;
+  map<string, string> str_to_str = 4;
+}
+
+message Oneof {
+  oneof union {
+    bool F_Bool = 1;
+    int32 F_Int32 = 2;
+    int64 F_Int64 = 3;
+    fixed32 F_Fixed32 = 4;
+    fixed64 F_Fixed64 = 5;
+    uint32 F_Uint32 = 6;
+    uint64 F_Uint64 = 7;
+    float F_Float = 8;
+    double F_Double = 9;
+    string F_String = 10;
+    bytes F_Bytes = 11;
+    sint32 F_Sint32 = 12;
+    sint64 F_Sint64 = 13;
+    MyMessage.Color F_Enum = 14;
+    GoTestField F_Message = 15;
+    group F_Group = 16 {
+      optional int32 x = 17;
+    }
+    int32 F_Largest_Tag = 536870911;
+  }
+
+  oneof tormato {
+    int32 value = 100;
+  }
+}
+
+message Communique {
+  optional bool make_me_cry = 1;
+
+  // This is a oneof, called "union".
+  oneof union {
+    int32 number = 5;
+    string name = 6;
+    bytes data = 7;
+    double temp_c = 8;
+    MyMessage.Color col = 9;
+    Strings msg = 10;
+  }
 }
 }

+ 44 - 82
Godeps/_workspace/src/github.com/golang/protobuf/proto/text.go

@@ -37,11 +37,11 @@ import (
 	"bufio"
 	"bufio"
 	"bytes"
 	"bytes"
 	"encoding"
 	"encoding"
+	"errors"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
 	"log"
 	"log"
 	"math"
 	"math"
-	"os"
 	"reflect"
 	"reflect"
 	"sort"
 	"sort"
 	"strings"
 	"strings"
@@ -170,20 +170,12 @@ func writeName(w *textWriter, props *Properties) error {
 	return nil
 	return nil
 }
 }
 
 
-var (
-	messageSetType = reflect.TypeOf((*MessageSet)(nil)).Elem()
-)
-
 // raw is the interface satisfied by RawMessage.
 // raw is the interface satisfied by RawMessage.
 type raw interface {
 type raw interface {
 	Bytes() []byte
 	Bytes() []byte
 }
 }
 
 
 func writeStruct(w *textWriter, sv reflect.Value) error {
 func writeStruct(w *textWriter, sv reflect.Value) error {
-	if sv.Type() == messageSetType {
-		return writeMessageSet(w, sv.Addr().Interface().(*MessageSet))
-	}
-
 	st := sv.Type()
 	st := sv.Type()
 	sprops := GetProperties(st)
 	sprops := GetProperties(st)
 	for i := 0; i < sv.NumField(); i++ {
 	for i := 0; i < sv.NumField(); i++ {
@@ -246,7 +238,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
 		}
 		}
 		if fv.Kind() == reflect.Map {
 		if fv.Kind() == reflect.Map {
 			// Map fields are rendered as a repeated struct with key/value fields.
 			// Map fields are rendered as a repeated struct with key/value fields.
-			keys := fv.MapKeys() // TODO: should we sort these for deterministic output?
+			keys := fv.MapKeys()
 			sort.Sort(mapKeys(keys))
 			sort.Sort(mapKeys(keys))
 			for _, key := range keys {
 			for _, key := range keys {
 				val := fv.MapIndex(key)
 				val := fv.MapIndex(key)
@@ -283,20 +275,23 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
 				if err := w.WriteByte('\n'); err != nil {
 				if err := w.WriteByte('\n'); err != nil {
 					return err
 					return err
 				}
 				}
-				// value
-				if _, err := w.WriteString("value:"); err != nil {
-					return err
-				}
-				if !w.compact {
-					if err := w.WriteByte(' '); err != nil {
+				// nil values aren't legal, but we can avoid panicking because of them.
+				if val.Kind() != reflect.Ptr || !val.IsNil() {
+					// 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
 						return err
 					}
 					}
-				}
-				if err := writeAny(w, val, props.mvalprop); err != nil {
-					return err
-				}
-				if err := w.WriteByte('\n'); err != nil {
-					return err
 				}
 				}
 				// close struct
 				// close struct
 				w.unindent()
 				w.unindent()
@@ -315,26 +310,34 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
 		}
 		}
 		if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
 		if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
 			// proto3 non-repeated scalar field; skip if zero value
 			// 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 {
+			if isProto3Zero(fv) {
+				continue
+			}
+		}
+
+		if fv.Kind() == reflect.Interface {
+			// Check if it is a oneof.
+			if st.Field(i).Tag.Get("protobuf_oneof") != "" {
+				// fv is nil, or holds a pointer to generated struct.
+				// That generated struct has exactly one field,
+				// which has a protobuf struct tag.
+				if fv.IsNil() {
 					continue
 					continue
 				}
 				}
-			case reflect.Float32, reflect.Float64:
-				if fv.Float() == 0 {
-					continue
-				}
-			case reflect.String:
-				if fv.String() == "" {
-					continue
+				inner := fv.Elem().Elem() // interface -> *T -> T
+				tag := inner.Type().Field(0).Tag.Get("protobuf")
+				props = new(Properties) // Overwrite the outer props var, but not its pointee.
+				props.Parse(tag)
+				// Write the value in the oneof, not the oneof itself.
+				fv = inner.Field(0)
+
+				// Special case to cope with malformed messages gracefully:
+				// If the value in the oneof is a nil pointer, don't panic
+				// in writeAny.
+				if fv.Kind() == reflect.Ptr && fv.IsNil() {
+					// Use errors.New so writeAny won't render quotes.
+					msg := errors.New("/* nil */")
+					fv = reflect.ValueOf(&msg).Elem()
 				}
 				}
 			}
 			}
 		}
 		}
@@ -514,44 +517,6 @@ func writeString(w *textWriter, s string) error {
 	return w.WriteByte('"')
 	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) {
 func writeUnknownStruct(w *textWriter, data []byte) (err error) {
 	if !w.compact {
 	if !w.compact {
 		if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
 		if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
@@ -666,10 +631,7 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
 
 
 		pb, err := GetExtension(ep, desc)
 		pb, err := GetExtension(ep, desc)
 		if err != nil {
 		if err != nil {
-			if _, err := fmt.Fprintln(os.Stderr, "proto: failed getting extension: ", err); err != nil {
-				return err
-			}
-			continue
+			return fmt.Errorf("failed getting extension: %v", err)
 		}
 		}
 
 
 		// Repeated extensions will appear as a slice.
 		// Repeated extensions will appear as a slice.

+ 135 - 94
Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser.go

@@ -174,7 +174,7 @@ func (p *textParser) advance() {
 		}
 		}
 		unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
 		unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
 		if err != nil {
 		if err != nil {
-			p.errorf("invalid quoted string %v", p.s[0:i+1])
+			p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err)
 			return
 			return
 		}
 		}
 		p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
 		p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
@@ -385,8 +385,7 @@ func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSet
 }
 }
 
 
 // Returns the index in the struct for the named field, as well as the parsed tag properties.
 // 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)
+func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) {
 	i, ok := sprops.decoderOrigNames[name]
 	i, ok := sprops.decoderOrigNames[name]
 	if ok {
 	if ok {
 		return i, sprops.Prop[i], true
 		return i, sprops.Prop[i], true
@@ -438,7 +437,8 @@ func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseEr
 
 
 func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 	st := sv.Type()
 	st := sv.Type()
-	reqCount := GetProperties(st).reqCount
+	sprops := GetProperties(st)
+	reqCount := sprops.reqCount
 	var reqFieldErr error
 	var reqFieldErr error
 	fieldSet := make(map[string]bool)
 	fieldSet := make(map[string]bool)
 	// A struct is a sequence of "name: value", terminated by one of
 	// A struct is a sequence of "name: value", terminated by one of
@@ -520,99 +520,113 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 				sl = reflect.Append(sl, ext)
 				sl = reflect.Append(sl, ext)
 				SetExtension(ep, desc, sl.Interface())
 				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)
+			if err := p.consumeOptionalSeparator(); err != nil {
+				return err
 			}
 			}
+			continue
+		}
 
 
-			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
-				}
+		// This is a normal, non-extension field.
+		name := tok.value
+		var dst reflect.Value
+		fi, props, ok := structFieldByName(sprops, name)
+		if ok {
+			dst = sv.Field(fi)
+		} else if oop, ok := sprops.OneofTypes[name]; ok {
+			// It is a oneof.
+			props = oop.Prop
+			nv := reflect.New(oop.Type.Elem())
+			dst = nv.Elem().Field(0)
+			sv.Field(oop.Field).Set(nv)
+		}
+		if !dst.IsValid() {
+			return p.errorf("unknown field name %q in %v", name, st)
+		}
 
 
-				dst.SetMapIndex(key, val)
-				continue
+		if dst.Kind() == reflect.Map {
+			// Consume any colon.
+			if err := p.checkForColon(props, dst.Type()); err != nil {
+				return err
 			}
 			}
 
 
-			// 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)
+			// Construct the map if it doesn't already exist.
+			if dst.IsNil() {
+				dst.Set(reflect.MakeMap(dst.Type()))
 			}
 			}
-
-			if err := p.checkForColon(props, st.Field(fi).Type); err != nil {
+			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
 				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--
+			if err := p.consumeToken(":"); err != nil {
+				return err
+			}
+			if err := p.readAny(key, props.mkeyprop); err != nil {
+				return err
+			}
+			if err := p.consumeOptionalSeparator(); 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.consumeOptionalSeparator(); err != nil {
+				return err
+			}
+			if err := p.consumeToken(terminator); err != nil {
+				return err
 			}
 			}
+
+			dst.SetMapIndex(key, val)
+			continue
 		}
 		}
 
 
-		// For backward compatibility, permit a semicolon or comma after a field.
-		tok = p.next()
-		if tok.err != nil {
-			return tok.err
+		// 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, dst.Type()); err != nil {
+			return err
 		}
 		}
-		if tok.value != ";" && tok.value != "," {
-			p.back()
+
+		// 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--
+		}
+
+		if err := p.consumeOptionalSeparator(); err != nil {
+			return err
 		}
 		}
+
 	}
 	}
 
 
 	if reqCount > 0 {
 	if reqCount > 0 {
@@ -621,6 +635,19 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 	return reqFieldErr
 	return reqFieldErr
 }
 }
 
 
+// consumeOptionalSeparator consumes an optional semicolon or comma.
+// It is used in readStruct to provide backward compatibility.
+func (p *textParser) consumeOptionalSeparator() error {
+	tok := p.next()
+	if tok.err != nil {
+		return tok.err
+	}
+	if tok.value != ";" && tok.value != "," {
+		p.back()
+	}
+	return nil
+}
+
 func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 	tok := p.next()
 	tok := p.next()
 	if tok.err != nil {
 	if tok.err != nil {
@@ -645,18 +672,32 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 			fv.Set(reflect.ValueOf(bytes))
 			fv.Set(reflect.ValueOf(bytes))
 			return nil
 			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)
+		// Repeated field.
+		if tok.value == "[" {
+			// Repeated field with list notation, like [1,2,3].
+			for {
+				fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
+				err := p.readAny(fv.Index(fv.Len()-1), props)
+				if err != nil {
+					return err
+				}
+				tok := p.next()
+				if tok.err != nil {
+					return tok.err
+				}
+				if tok.value == "]" {
+					break
+				}
+				if tok.value != "," {
+					return p.errorf("Expected ']' or ',' found %q", tok.value)
+				}
+			}
+			return nil
 		}
 		}
-		fv.SetLen(flen + 1)
-
-		// Read one.
+		// One value of the repeated field.
 		p.back()
 		p.back()
-		return p.readAny(fv.Index(flen), props)
+		fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
+		return p.readAny(fv.Index(fv.Len()-1), props)
 	case reflect.Bool:
 	case reflect.Bool:
 		// Either "true", "false", 1 or 0.
 		// Either "true", "false", 1 or 0.
 		switch tok.value {
 		switch tok.value {

+ 25 - 4
Godeps/_workspace/src/github.com/golang/protobuf/proto/text_parser_test.go

@@ -36,9 +36,9 @@ import (
 	"reflect"
 	"reflect"
 	"testing"
 	"testing"
 
 
-	proto3pb "./proto3_proto"
-	. "./testdata"
 	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
 	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
+	proto3pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto"
+	. "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata"
 )
 )
 
 
 type UnmarshalTextTest struct {
 type UnmarshalTextTest struct {
@@ -152,7 +152,7 @@ var unMarshalTextTests = []UnmarshalTextTest{
 	// Bad quoted string
 	// Bad quoted string
 	{
 	{
 		in:  `inner: < host: "\0" >` + "\n",
 		in:  `inner: < host: "\0" >` + "\n",
-		err: `line 1.15: invalid quoted string "\0"`,
+		err: `line 1.15: invalid quoted string "\0": \0 requires 2 following digits`,
 	},
 	},
 
 
 	// Number too large for int64
 	// Number too large for int64
@@ -256,6 +256,15 @@ var unMarshalTextTests = []UnmarshalTextTest{
 		},
 		},
 	},
 	},
 
 
+	// Repeated field with list notation
+	{
+		in: `count:42 pet: ["horsey", "bunny"]`,
+		out: &MyMessage{
+			Count: Int32(42),
+			Pet:   []string{"horsey", "bunny"},
+		},
+	},
+
 	// Repeated message with/without colon and <>/{}
 	// Repeated message with/without colon and <>/{}
 	{
 	{
 		in: `count:42 others:{} others{} others:<> others:{}`,
 		in: `count:42 others:{} others{} others:<> others:{}`,
@@ -462,7 +471,7 @@ func TestProto3TextParsing(t *testing.T) {
 func TestMapParsing(t *testing.T) {
 func TestMapParsing(t *testing.T) {
 	m := new(MessageWithMap)
 	m := new(MessageWithMap)
 	const in = `name_mapping:<key:1234 value:"Feist"> name_mapping:<key:1 value:"Beatles">` +
 	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:-4, value:<f: 2.0>,>` + // separating commas are okay
 		`msg_mapping<key:-2 value<f: 4.0>>` + // no colon after "value"
 		`msg_mapping<key:-2 value<f: 4.0>>` + // no colon after "value"
 		`byte_mapping:<key:true value:"so be it">`
 		`byte_mapping:<key:true value:"so be it">`
 	want := &MessageWithMap{
 	want := &MessageWithMap{
@@ -486,6 +495,18 @@ func TestMapParsing(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestOneofParsing(t *testing.T) {
+	const in = `name:"Shrek"`
+	m := new(Communique)
+	want := &Communique{Union: &Communique_Name{"Shrek"}}
+	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
 var benchInput string
 
 
 func init() {
 func init() {

+ 43 - 5
Godeps/_workspace/src/github.com/golang/protobuf/proto/text_test.go

@@ -41,8 +41,8 @@ import (
 
 
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
 	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto"
 
 
-	proto3pb "./proto3_proto"
-	pb "./testdata"
+	proto3pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/proto3_proto"
+	pb "github.com/coreos/etcd/Godeps/_workspace/src/github.com/golang/protobuf/proto/testdata"
 )
 )
 
 
 // textMessage implements the methods that allow it to marshal and unmarshal
 // textMessage implements the methods that allow it to marshal and unmarshal
@@ -208,6 +208,30 @@ func TestMarshalTextUnknownEnum(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestTextOneof(t *testing.T) {
+	tests := []struct {
+		m    proto.Message
+		want string
+	}{
+		// zero message
+		{&pb.Communique{}, ``},
+		// scalar field
+		{&pb.Communique{Union: &pb.Communique_Number{4}}, `number:4`},
+		// message field
+		{&pb.Communique{Union: &pb.Communique_Msg{
+			&pb.Strings{StringField: proto.String("why hello!")},
+		}}, `msg:<string_field:"why hello!" >`},
+		// bad oneof (should not panic)
+		{&pb.Communique{Union: &pb.Communique_Msg{nil}}, `msg:/* nil */`},
+	}
+	for _, test := range tests {
+		got := strings.TrimSpace(test.m.String())
+		if got != test.want {
+			t.Errorf("\n got %s\nwant %s", got, test.want)
+		}
+	}
+}
+
 func BenchmarkMarshalTextBuffered(b *testing.B) {
 func BenchmarkMarshalTextBuffered(b *testing.B) {
 	buf := new(bytes.Buffer)
 	buf := new(bytes.Buffer)
 	m := newTestMessage()
 	m := newTestMessage()
@@ -421,10 +445,24 @@ func TestProto3Text(t *testing.T) {
 		{&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`},
 		{&proto3pb.Message{Name: "Rob", HeightInCm: 175}, `name:"Rob" height_in_cm:175`},
 		// empty map
 		// empty map
 		{&pb.MessageWithMap{}, ``},
 		{&pb.MessageWithMap{}, ``},
-		// non-empty map; current map format is the same as a repeated struct
+		// non-empty map; map format is the same as a repeated struct,
+		// and they are sorted by key (numerically for numeric keys).
+		{
+			&pb.MessageWithMap{NameMapping: map[int32]string{
+				-1:      "Negatory",
+				7:       "Lucky",
+				1234:    "Feist",
+				6345789: "Otis",
+			}},
+			`name_mapping:<key:-1 value:"Negatory" > ` +
+				`name_mapping:<key:7 value:"Lucky" > ` +
+				`name_mapping:<key:1234 value:"Feist" > ` +
+				`name_mapping:<key:6345789 value:"Otis" >`,
+		},
+		// map with nil value; not well-defined, but we shouldn't crash
 		{
 		{
-			&pb.MessageWithMap{NameMapping: map[int32]string{1234: "Feist"}},
-			`name_mapping:<key:1234 value:"Feist" >`,
+			&pb.MessageWithMap{MsgMapping: map[int64]*pb.FloatingPoint{7: nil}},
+			`msg_mapping:<key:7 >`,
 		},
 		},
 	}
 	}
 	for _, test := range tests {
 	for _, test := range tests {

+ 1 - 1
Godeps/_workspace/src/golang.org/x/oauth2/LICENSE → Godeps/_workspace/src/golang.org/x/net/LICENSE

@@ -1,4 +1,4 @@
-Copyright (c) 2009 The oauth2 Authors. All rights reserved.
+Copyright (c) 2009 The Go Authors. All rights reserved.
 
 
 Redistribution and use in source and binary forms, with or without
 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions are
 modification, are permitted provided that the following conditions are

+ 22 - 0
Godeps/_workspace/src/golang.org/x/net/PATENTS

@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go.  This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation.  If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.

+ 1 - 1
Godeps/_workspace/src/golang.org/x/net/context/context.go

@@ -189,7 +189,7 @@ func Background() Context {
 }
 }
 
 
 // TODO returns a non-nil, empty Context.  Code should use context.TODO when
 // TODO returns a non-nil, empty Context.  Code should use context.TODO when
-// it's unclear which Context to use or it's is not yet available (because the
+// it's unclear which Context to use or it is not yet available (because the
 // surrounding function has not yet been extended to accept a Context
 // surrounding function has not yet been extended to accept a Context
 // parameter).  TODO is recognized by static analysis tools that determine
 // parameter).  TODO is recognized by static analysis tools that determine
 // whether Contexts are propagated correctly in a program.
 // whether Contexts are propagated correctly in a program.

+ 2 - 2
Godeps/_workspace/src/golang.org/x/net/context/context_test.go

@@ -375,7 +375,7 @@ func TestAllocs(t *testing.T) {
 				<-c.Done()
 				<-c.Done()
 			},
 			},
 			limit:      8,
 			limit:      8,
-			gccgoLimit: 13,
+			gccgoLimit: 15,
 		},
 		},
 		{
 		{
 			desc: "WithCancel(bg)",
 			desc: "WithCancel(bg)",
@@ -536,7 +536,7 @@ func testLayers(t *testing.T, seed int64, testTimeout bool) {
 	if testTimeout {
 	if testTimeout {
 		select {
 		select {
 		case <-ctx.Done():
 		case <-ctx.Done():
-		case <-time.After(timeout + timeout/10):
+		case <-time.After(timeout + 100*time.Millisecond):
 			errorf("ctx should have timed out")
 			errorf("ctx should have timed out")
 		}
 		}
 		checkValues("after timeout")
 		checkValues("after timeout")

+ 19 - 0
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq.go

@@ -0,0 +1,19 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.5
+
+package ctxhttp
+
+import "net/http"
+
+func canceler(client *http.Client, req *http.Request) func() {
+	// TODO(djd): Respect any existing value of req.Cancel.
+	ch := make(chan struct{})
+	req.Cancel = ch
+
+	return func() {
+		close(ch)
+	}
+}

+ 23 - 0
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/cancelreq_go14.go

@@ -0,0 +1,23 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.5
+
+package ctxhttp
+
+import "net/http"
+
+type requestCanceler interface {
+	CancelRequest(*http.Request)
+}
+
+func canceler(client *http.Client, req *http.Request) func() {
+	rc, ok := client.Transport.(requestCanceler)
+	if !ok {
+		return func() {}
+	}
+	return func() {
+		rc.CancelRequest(req)
+	}
+}

+ 140 - 0
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp.go

@@ -0,0 +1,140 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package ctxhttp provides helper functions for performing context-aware HTTP requests.
+package ctxhttp
+
+import (
+	"io"
+	"net/http"
+	"net/url"
+	"strings"
+
+	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
+)
+
+func nop() {}
+
+var (
+	testHookContextDoneBeforeHeaders = nop
+	testHookDoReturned               = nop
+	testHookDidBodyClose             = nop
+)
+
+// Do sends an HTTP request with the provided http.Client and returns an HTTP response.
+// If the client is nil, http.DefaultClient is used.
+// If the context is canceled or times out, ctx.Err() will be returned.
+func Do(ctx context.Context, client *http.Client, req *http.Request) (*http.Response, error) {
+	if client == nil {
+		client = http.DefaultClient
+	}
+
+	// Request cancelation changed in Go 1.5, see cancelreq.go and cancelreq_go14.go.
+	cancel := canceler(client, req)
+
+	type responseAndError struct {
+		resp *http.Response
+		err  error
+	}
+	result := make(chan responseAndError, 1)
+
+	go func() {
+		resp, err := client.Do(req)
+		testHookDoReturned()
+		result <- responseAndError{resp, err}
+	}()
+
+	var resp *http.Response
+
+	select {
+	case <-ctx.Done():
+		testHookContextDoneBeforeHeaders()
+		cancel()
+		// Clean up after the goroutine calling client.Do:
+		go func() {
+			if r := <-result; r.resp != nil {
+				testHookDidBodyClose()
+				r.resp.Body.Close()
+			}
+		}()
+		return nil, ctx.Err()
+	case r := <-result:
+		var err error
+		resp, err = r.resp, r.err
+		if err != nil {
+			return resp, err
+		}
+	}
+
+	c := make(chan struct{})
+	go func() {
+		select {
+		case <-ctx.Done():
+			cancel()
+		case <-c:
+			// The response's Body is closed.
+		}
+	}()
+	resp.Body = &notifyingReader{resp.Body, c}
+
+	return resp, nil
+}
+
+// Get issues a GET request via the Do function.
+func Get(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
+	req, err := http.NewRequest("GET", url, nil)
+	if err != nil {
+		return nil, err
+	}
+	return Do(ctx, client, req)
+}
+
+// Head issues a HEAD request via the Do function.
+func Head(ctx context.Context, client *http.Client, url string) (*http.Response, error) {
+	req, err := http.NewRequest("HEAD", url, nil)
+	if err != nil {
+		return nil, err
+	}
+	return Do(ctx, client, req)
+}
+
+// Post issues a POST request via the Do function.
+func Post(ctx context.Context, client *http.Client, url string, bodyType string, body io.Reader) (*http.Response, error) {
+	req, err := http.NewRequest("POST", url, body)
+	if err != nil {
+		return nil, err
+	}
+	req.Header.Set("Content-Type", bodyType)
+	return Do(ctx, client, req)
+}
+
+// PostForm issues a POST request via the Do function.
+func PostForm(ctx context.Context, client *http.Client, url string, data url.Values) (*http.Response, error) {
+	return Post(ctx, client, url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
+}
+
+// notifyingReader is an io.ReadCloser that closes the notify channel after
+// Close is called or a Read fails on the underlying ReadCloser.
+type notifyingReader struct {
+	io.ReadCloser
+	notify chan<- struct{}
+}
+
+func (r *notifyingReader) Read(p []byte) (int, error) {
+	n, err := r.ReadCloser.Read(p)
+	if err != nil && r.notify != nil {
+		close(r.notify)
+		r.notify = nil
+	}
+	return n, err
+}
+
+func (r *notifyingReader) Close() error {
+	err := r.ReadCloser.Close()
+	if r.notify != nil {
+		close(r.notify)
+		r.notify = nil
+	}
+	return err
+}

+ 176 - 0
Godeps/_workspace/src/golang.org/x/net/context/ctxhttp/ctxhttp_test.go

@@ -0,0 +1,176 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !plan9
+
+package ctxhttp
+
+import (
+	"io/ioutil"
+	"net"
+	"net/http"
+	"net/http/httptest"
+	"sync"
+	"testing"
+	"time"
+
+	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
+)
+
+const (
+	requestDuration = 100 * time.Millisecond
+	requestBody     = "ok"
+)
+
+func TestNoTimeout(t *testing.T) {
+	ctx := context.Background()
+	resp, err := doRequest(ctx)
+
+	if resp == nil || err != nil {
+		t.Fatalf("error received from client: %v %v", err, resp)
+	}
+}
+
+func TestCancel(t *testing.T) {
+	ctx, cancel := context.WithCancel(context.Background())
+	go func() {
+		time.Sleep(requestDuration / 2)
+		cancel()
+	}()
+
+	resp, err := doRequest(ctx)
+
+	if resp != nil || err == nil {
+		t.Fatalf("expected error, didn't get one. resp: %v", resp)
+	}
+	if err != ctx.Err() {
+		t.Fatalf("expected error from context but got: %v", err)
+	}
+}
+
+func TestCancelAfterRequest(t *testing.T) {
+	ctx, cancel := context.WithCancel(context.Background())
+
+	resp, err := doRequest(ctx)
+
+	// Cancel before reading the body.
+	// Request.Body should still be readable after the context is canceled.
+	cancel()
+
+	b, err := ioutil.ReadAll(resp.Body)
+	if err != nil || string(b) != requestBody {
+		t.Fatalf("could not read body: %q %v", b, err)
+	}
+}
+
+func TestCancelAfterHangingRequest(t *testing.T) {
+	handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		w.WriteHeader(http.StatusOK)
+		w.(http.Flusher).Flush()
+		<-w.(http.CloseNotifier).CloseNotify()
+	})
+
+	serv := httptest.NewServer(handler)
+	defer serv.Close()
+
+	ctx, cancel := context.WithCancel(context.Background())
+	resp, err := Get(ctx, nil, serv.URL)
+	if err != nil {
+		t.Fatalf("unexpected error in Get: %v", err)
+	}
+
+	// Cancel befer reading the body.
+	// Reading Request.Body should fail, since the request was
+	// canceled before anything was written.
+	cancel()
+
+	done := make(chan struct{})
+
+	go func() {
+		b, err := ioutil.ReadAll(resp.Body)
+		if len(b) != 0 || err == nil {
+			t.Errorf(`Read got (%q, %v); want ("", error)`, b, err)
+		}
+		close(done)
+	}()
+
+	select {
+	case <-time.After(1 * time.Second):
+		t.Errorf("Test timed out")
+	case <-done:
+	}
+}
+
+func doRequest(ctx context.Context) (*http.Response, error) {
+	var okHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+		time.Sleep(requestDuration)
+		w.Write([]byte(requestBody))
+	})
+
+	serv := httptest.NewServer(okHandler)
+	defer serv.Close()
+
+	return Get(ctx, nil, serv.URL)
+}
+
+// golang.org/issue/14065
+func TestClosesResponseBodyOnCancel(t *testing.T) {
+	defer func() { testHookContextDoneBeforeHeaders = nop }()
+	defer func() { testHookDoReturned = nop }()
+	defer func() { testHookDidBodyClose = nop }()
+
+	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
+	defer ts.Close()
+
+	ctx, cancel := context.WithCancel(context.Background())
+
+	// closed when Do enters select case <-ctx.Done()
+	enteredDonePath := make(chan struct{})
+
+	testHookContextDoneBeforeHeaders = func() {
+		close(enteredDonePath)
+	}
+
+	testHookDoReturned = func() {
+		// We now have the result (the Flush'd headers) at least,
+		// so we can cancel the request.
+		cancel()
+
+		// But block the client.Do goroutine from sending
+		// until Do enters into the <-ctx.Done() path, since
+		// otherwise if both channels are readable, select
+		// picks a random one.
+		<-enteredDonePath
+	}
+
+	sawBodyClose := make(chan struct{})
+	testHookDidBodyClose = func() { close(sawBodyClose) }
+
+	tr := &http.Transport{}
+	defer tr.CloseIdleConnections()
+	c := &http.Client{Transport: tr}
+	req, _ := http.NewRequest("GET", ts.URL, nil)
+	_, doErr := Do(ctx, c, req)
+
+	select {
+	case <-sawBodyClose:
+	case <-time.After(5 * time.Second):
+		t.Fatal("timeout waiting for body to close")
+	}
+
+	if doErr != ctx.Err() {
+		t.Errorf("Do error = %v; want %v", doErr, ctx.Err())
+	}
+}
+
+type noteCloseConn struct {
+	net.Conn
+	onceClose sync.Once
+	closefn   func()
+}
+
+func (c *noteCloseConn) Close() error {
+	c.onceClose.Do(c.closefn)
+	return c.Conn.Close()
+}

+ 2 - 0
Godeps/_workspace/src/golang.org/x/net/http2/.gitignore

@@ -0,0 +1,2 @@
+*~
+h2i/h2i

+ 11 - 4
Godeps/_workspace/src/github.com/bradfitz/http2/Dockerfile → Godeps/_workspace/src/golang.org/x/net/http2/Dockerfile

@@ -17,8 +17,15 @@ RUN apt-get install -y --no-install-recommends \
        libcunit1-dev libssl-dev libxml2-dev libevent-dev \
        libcunit1-dev libssl-dev libxml2-dev libevent-dev \
        automake autoconf
        automake autoconf
 
 
+# The list of packages nghttp2 recommends for h2load:
+RUN apt-get install -y --no-install-recommends make binutils \
+        autoconf automake autotools-dev \
+        libtool pkg-config zlib1g-dev libcunit1-dev libssl-dev libxml2-dev \
+        libev-dev libevent-dev libjansson-dev libjemalloc-dev \
+        cython python3.4-dev python-setuptools
+
 # Note: setting NGHTTP2_VER before the git clone, so an old git clone isn't cached:
 # Note: setting NGHTTP2_VER before the git clone, so an old git clone isn't cached:
-ENV NGHTTP2_VER af24f8394e43f4
+ENV NGHTTP2_VER 895da9a
 RUN cd /root && git clone https://github.com/tatsuhiro-t/nghttp2.git
 RUN cd /root && git clone https://github.com/tatsuhiro-t/nghttp2.git
 
 
 WORKDIR /root/nghttp2
 WORKDIR /root/nghttp2
@@ -31,9 +38,9 @@ RUN make
 RUN make install
 RUN make install
 
 
 WORKDIR /root
 WORKDIR /root
-RUN wget http://curl.haxx.se/download/curl-7.40.0.tar.gz
-RUN tar -zxvf curl-7.40.0.tar.gz
-WORKDIR /root/curl-7.40.0
+RUN wget http://curl.haxx.se/download/curl-7.45.0.tar.gz
+RUN tar -zxvf curl-7.45.0.tar.gz
+WORKDIR /root/curl-7.45.0
 RUN ./configure --with-ssl --with-nghttp2=/usr/local
 RUN ./configure --with-ssl --with-nghttp2=/usr/local
 RUN make
 RUN make
 RUN make install
 RUN make install

+ 0 - 0
Godeps/_workspace/src/github.com/bradfitz/http2/Makefile → Godeps/_workspace/src/golang.org/x/net/http2/Makefile


+ 5 - 2
Godeps/_workspace/src/github.com/bradfitz/http2/README → Godeps/_workspace/src/golang.org/x/net/http2/README

@@ -10,8 +10,11 @@ Status:
 * The client work has just started but shares a lot of code
 * The client work has just started but shares a lot of code
   is coming along much quicker.
   is coming along much quicker.
 
 
-Docs are at https://godoc.org/github.com/bradfitz/http2
+Docs are at https://godoc.org/golang.org/x/net/http2
 
 
 Demo test server at https://http2.golang.org/
 Demo test server at https://http2.golang.org/
 
 
-Help & bug reports welcome.
+Help & bug reports welcome!
+
+Contributing: https://golang.org/doc/contribute.html
+Bugs:         https://golang.org/issue/new?title=x/net/http2:+

+ 225 - 0
Godeps/_workspace/src/golang.org/x/net/http2/client_conn_pool.go

@@ -0,0 +1,225 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Transport code's client connection pooling.
+
+package http2
+
+import (
+	"crypto/tls"
+	"net/http"
+	"sync"
+)
+
+// ClientConnPool manages a pool of HTTP/2 client connections.
+type ClientConnPool interface {
+	GetClientConn(req *http.Request, addr string) (*ClientConn, error)
+	MarkDead(*ClientConn)
+}
+
+// TODO: use singleflight for dialing and addConnCalls?
+type clientConnPool struct {
+	t *Transport
+
+	mu sync.Mutex // TODO: maybe switch to RWMutex
+	// TODO: add support for sharing conns based on cert names
+	// (e.g. share conn for googleapis.com and appspot.com)
+	conns        map[string][]*ClientConn // key is host:port
+	dialing      map[string]*dialCall     // currently in-flight dials
+	keys         map[*ClientConn][]string
+	addConnCalls map[string]*addConnCall // in-flight addConnIfNeede calls
+}
+
+func (p *clientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
+	return p.getClientConn(req, addr, dialOnMiss)
+}
+
+const (
+	dialOnMiss   = true
+	noDialOnMiss = false
+)
+
+func (p *clientConnPool) getClientConn(_ *http.Request, addr string, dialOnMiss bool) (*ClientConn, error) {
+	p.mu.Lock()
+	for _, cc := range p.conns[addr] {
+		if cc.CanTakeNewRequest() {
+			p.mu.Unlock()
+			return cc, nil
+		}
+	}
+	if !dialOnMiss {
+		p.mu.Unlock()
+		return nil, ErrNoCachedConn
+	}
+	call := p.getStartDialLocked(addr)
+	p.mu.Unlock()
+	<-call.done
+	return call.res, call.err
+}
+
+// dialCall is an in-flight Transport dial call to a host.
+type dialCall struct {
+	p    *clientConnPool
+	done chan struct{} // closed when done
+	res  *ClientConn   // valid after done is closed
+	err  error         // valid after done is closed
+}
+
+// requires p.mu is held.
+func (p *clientConnPool) getStartDialLocked(addr string) *dialCall {
+	if call, ok := p.dialing[addr]; ok {
+		// A dial is already in-flight. Don't start another.
+		return call
+	}
+	call := &dialCall{p: p, done: make(chan struct{})}
+	if p.dialing == nil {
+		p.dialing = make(map[string]*dialCall)
+	}
+	p.dialing[addr] = call
+	go call.dial(addr)
+	return call
+}
+
+// run in its own goroutine.
+func (c *dialCall) dial(addr string) {
+	c.res, c.err = c.p.t.dialClientConn(addr)
+	close(c.done)
+
+	c.p.mu.Lock()
+	delete(c.p.dialing, addr)
+	if c.err == nil {
+		c.p.addConnLocked(addr, c.res)
+	}
+	c.p.mu.Unlock()
+}
+
+// addConnIfNeeded makes a NewClientConn out of c if a connection for key doesn't
+// already exist. It coalesces concurrent calls with the same key.
+// This is used by the http1 Transport code when it creates a new connection. Because
+// the http1 Transport doesn't de-dup TCP dials to outbound hosts (because it doesn't know
+// the protocol), it can get into a situation where it has multiple TLS connections.
+// This code decides which ones live or die.
+// The return value used is whether c was used.
+// c is never closed.
+func (p *clientConnPool) addConnIfNeeded(key string, t *Transport, c *tls.Conn) (used bool, err error) {
+	p.mu.Lock()
+	for _, cc := range p.conns[key] {
+		if cc.CanTakeNewRequest() {
+			p.mu.Unlock()
+			return false, nil
+		}
+	}
+	call, dup := p.addConnCalls[key]
+	if !dup {
+		if p.addConnCalls == nil {
+			p.addConnCalls = make(map[string]*addConnCall)
+		}
+		call = &addConnCall{
+			p:    p,
+			done: make(chan struct{}),
+		}
+		p.addConnCalls[key] = call
+		go call.run(t, key, c)
+	}
+	p.mu.Unlock()
+
+	<-call.done
+	if call.err != nil {
+		return false, call.err
+	}
+	return !dup, nil
+}
+
+type addConnCall struct {
+	p    *clientConnPool
+	done chan struct{} // closed when done
+	err  error
+}
+
+func (c *addConnCall) run(t *Transport, key string, tc *tls.Conn) {
+	cc, err := t.NewClientConn(tc)
+
+	p := c.p
+	p.mu.Lock()
+	if err != nil {
+		c.err = err
+	} else {
+		p.addConnLocked(key, cc)
+	}
+	delete(p.addConnCalls, key)
+	p.mu.Unlock()
+	close(c.done)
+}
+
+func (p *clientConnPool) addConn(key string, cc *ClientConn) {
+	p.mu.Lock()
+	p.addConnLocked(key, cc)
+	p.mu.Unlock()
+}
+
+// p.mu must be held
+func (p *clientConnPool) addConnLocked(key string, cc *ClientConn) {
+	for _, v := range p.conns[key] {
+		if v == cc {
+			return
+		}
+	}
+	if p.conns == nil {
+		p.conns = make(map[string][]*ClientConn)
+	}
+	if p.keys == nil {
+		p.keys = make(map[*ClientConn][]string)
+	}
+	p.conns[key] = append(p.conns[key], cc)
+	p.keys[cc] = append(p.keys[cc], key)
+}
+
+func (p *clientConnPool) MarkDead(cc *ClientConn) {
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	for _, key := range p.keys[cc] {
+		vv, ok := p.conns[key]
+		if !ok {
+			continue
+		}
+		newList := filterOutClientConn(vv, cc)
+		if len(newList) > 0 {
+			p.conns[key] = newList
+		} else {
+			delete(p.conns, key)
+		}
+	}
+	delete(p.keys, cc)
+}
+
+func (p *clientConnPool) closeIdleConnections() {
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	// TODO: don't close a cc if it was just added to the pool
+	// milliseconds ago and has never been used. There's currently
+	// a small race window with the HTTP/1 Transport's integration
+	// where it can add an idle conn just before using it, and
+	// somebody else can concurrently call CloseIdleConns and
+	// break some caller's RoundTrip.
+	for _, vv := range p.conns {
+		for _, cc := range vv {
+			cc.closeIfIdle()
+		}
+	}
+}
+
+func filterOutClientConn(in []*ClientConn, exclude *ClientConn) []*ClientConn {
+	out := in[:0]
+	for _, v := range in {
+		if v != exclude {
+			out = append(out, v)
+		}
+	}
+	// If we filtered it out, zero out the last item to prevent
+	// the GC from seeing it.
+	if len(in) != len(out) {
+		in[len(in)-1] = nil
+	}
+	return out
+}

+ 89 - 0
Godeps/_workspace/src/golang.org/x/net/http2/configure_transport.go

@@ -0,0 +1,89 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.6
+
+package http2
+
+import (
+	"crypto/tls"
+	"fmt"
+	"net/http"
+)
+
+func configureTransport(t1 *http.Transport) (*Transport, error) {
+	connPool := new(clientConnPool)
+	t2 := &Transport{
+		ConnPool: noDialClientConnPool{connPool},
+		t1:       t1,
+	}
+	connPool.t = t2
+	if err := registerHTTPSProtocol(t1, noDialH2RoundTripper{t2}); err != nil {
+		return nil, err
+	}
+	if t1.TLSClientConfig == nil {
+		t1.TLSClientConfig = new(tls.Config)
+	}
+	if !strSliceContains(t1.TLSClientConfig.NextProtos, "h2") {
+		t1.TLSClientConfig.NextProtos = append([]string{"h2"}, t1.TLSClientConfig.NextProtos...)
+	}
+	if !strSliceContains(t1.TLSClientConfig.NextProtos, "http/1.1") {
+		t1.TLSClientConfig.NextProtos = append(t1.TLSClientConfig.NextProtos, "http/1.1")
+	}
+	upgradeFn := func(authority string, c *tls.Conn) http.RoundTripper {
+		addr := authorityAddr(authority)
+		if used, err := connPool.addConnIfNeeded(addr, t2, c); err != nil {
+			go c.Close()
+			return erringRoundTripper{err}
+		} else if !used {
+			// Turns out we don't need this c.
+			// For example, two goroutines made requests to the same host
+			// at the same time, both kicking off TCP dials. (since protocol
+			// was unknown)
+			go c.Close()
+		}
+		return t2
+	}
+	if m := t1.TLSNextProto; len(m) == 0 {
+		t1.TLSNextProto = map[string]func(string, *tls.Conn) http.RoundTripper{
+			"h2": upgradeFn,
+		}
+	} else {
+		m["h2"] = upgradeFn
+	}
+	return t2, nil
+}
+
+// registerHTTPSProtocol calls Transport.RegisterProtocol but
+// convering panics into errors.
+func registerHTTPSProtocol(t *http.Transport, rt http.RoundTripper) (err error) {
+	defer func() {
+		if e := recover(); e != nil {
+			err = fmt.Errorf("%v", e)
+		}
+	}()
+	t.RegisterProtocol("https", rt)
+	return nil
+}
+
+// noDialClientConnPool is an implementation of http2.ClientConnPool
+// which never dials.  We let the HTTP/1.1 client dial and use its TLS
+// connection instead.
+type noDialClientConnPool struct{ *clientConnPool }
+
+func (p noDialClientConnPool) GetClientConn(req *http.Request, addr string) (*ClientConn, error) {
+	return p.getClientConn(req, addr, noDialOnMiss)
+}
+
+// noDialH2RoundTripper is a RoundTripper which only tries to complete the request
+// if there's already has a cached connection to the host.
+type noDialH2RoundTripper struct{ t *Transport }
+
+func (rt noDialH2RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
+	res, err := rt.t.RoundTrip(req)
+	if err == ErrNoCachedConn {
+		return nil, http.ErrSkipAltProtocol
+	}
+	return res, err
+}

+ 16 - 4
Godeps/_workspace/src/github.com/bradfitz/http2/errors.go → Godeps/_workspace/src/golang.org/x/net/http2/errors.go

@@ -1,7 +1,6 @@
-// Copyright 2014 The Go Authors.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 
 package http2
 package http2
 
 
@@ -76,3 +75,16 @@ func (e StreamError) Error() string {
 type goAwayFlowError struct{}
 type goAwayFlowError struct{}
 
 
 func (goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
 func (goAwayFlowError) Error() string { return "connection exceeded flow control window size" }
+
+// connErrorReason wraps a ConnectionError with an informative error about why it occurs.
+
+// Errors of this type are only returned by the frame parser functions
+// and converted into ConnectionError(ErrCodeProtocol).
+type connError struct {
+	Code   ErrCode
+	Reason string
+}
+
+func (e connError) Error() string {
+	return fmt.Sprintf("http2: connection error: %v: %v", e.Code, e.Reason)
+}

+ 0 - 3
Godeps/_workspace/src/github.com/bradfitz/http2/errors_test.go → Godeps/_workspace/src/golang.org/x/net/http2/errors_test.go

@@ -1,9 +1,6 @@
 // Copyright 2014 The Go Authors. All rights reserved.
 // Copyright 2014 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
 
 
 package http2
 package http2
 
 

+ 60 - 0
Godeps/_workspace/src/golang.org/x/net/http2/fixed_buffer.go

@@ -0,0 +1,60 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http2
+
+import (
+	"errors"
+)
+
+// fixedBuffer is an io.ReadWriter backed by a fixed size buffer.
+// It never allocates, but moves old data as new data is written.
+type fixedBuffer struct {
+	buf  []byte
+	r, w int
+}
+
+var (
+	errReadEmpty = errors.New("read from empty fixedBuffer")
+	errWriteFull = errors.New("write on full fixedBuffer")
+)
+
+// Read copies bytes from the buffer into p.
+// It is an error to read when no data is available.
+func (b *fixedBuffer) Read(p []byte) (n int, err error) {
+	if b.r == b.w {
+		return 0, errReadEmpty
+	}
+	n = copy(p, b.buf[b.r:b.w])
+	b.r += n
+	if b.r == b.w {
+		b.r = 0
+		b.w = 0
+	}
+	return n, nil
+}
+
+// Len returns the number of bytes of the unread portion of the buffer.
+func (b *fixedBuffer) Len() int {
+	return b.w - b.r
+}
+
+// Write copies bytes from p into the buffer.
+// It is an error to write more data than the buffer can hold.
+func (b *fixedBuffer) Write(p []byte) (n int, err error) {
+	// Slide existing data to beginning.
+	if b.r > 0 && len(p) > len(b.buf)-b.w {
+		copy(b.buf, b.buf[b.r:b.w])
+		b.w -= b.r
+		b.r = 0
+	}
+
+	// Write new data.
+	n = copy(b.buf[b.w:], p)
+	b.w += n
+	if n < len(p) {
+		err = errWriteFull
+	}
+	return n, err
+}

+ 128 - 0
Godeps/_workspace/src/golang.org/x/net/http2/fixed_buffer_test.go

@@ -0,0 +1,128 @@
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package http2
+
+import (
+	"reflect"
+	"testing"
+)
+
+var bufferReadTests = []struct {
+	buf      fixedBuffer
+	read, wn int
+	werr     error
+	wp       []byte
+	wbuf     fixedBuffer
+}{
+	{
+		fixedBuffer{[]byte{'a', 0}, 0, 1},
+		5, 1, nil, []byte{'a'},
+		fixedBuffer{[]byte{'a', 0}, 0, 0},
+	},
+	{
+		fixedBuffer{[]byte{0, 'a'}, 1, 2},
+		5, 1, nil, []byte{'a'},
+		fixedBuffer{[]byte{0, 'a'}, 0, 0},
+	},
+	{
+		fixedBuffer{[]byte{'a', 'b'}, 0, 2},
+		1, 1, nil, []byte{'a'},
+		fixedBuffer{[]byte{'a', 'b'}, 1, 2},
+	},
+	{
+		fixedBuffer{[]byte{}, 0, 0},
+		5, 0, errReadEmpty, []byte{},
+		fixedBuffer{[]byte{}, 0, 0},
+	},
+}
+
+func TestBufferRead(t *testing.T) {
+	for i, tt := range bufferReadTests {
+		read := make([]byte, tt.read)
+		n, err := tt.buf.Read(read)
+		if n != tt.wn {
+			t.Errorf("#%d: wn = %d want %d", i, n, tt.wn)
+			continue
+		}
+		if err != tt.werr {
+			t.Errorf("#%d: werr = %v want %v", i, err, tt.werr)
+			continue
+		}
+		read = read[:n]
+		if !reflect.DeepEqual(read, tt.wp) {
+			t.Errorf("#%d: read = %+v want %+v", i, read, tt.wp)
+		}
+		if !reflect.DeepEqual(tt.buf, tt.wbuf) {
+			t.Errorf("#%d: buf = %+v want %+v", i, tt.buf, tt.wbuf)
+		}
+	}
+}
+
+var bufferWriteTests = []struct {
+	buf       fixedBuffer
+	write, wn int
+	werr      error
+	wbuf      fixedBuffer
+}{
+	{
+		buf: fixedBuffer{
+			buf: []byte{},
+		},
+		wbuf: fixedBuffer{
+			buf: []byte{},
+		},
+	},
+	{
+		buf: fixedBuffer{
+			buf: []byte{1, 'a'},
+		},
+		write: 1,
+		wn:    1,
+		wbuf: fixedBuffer{
+			buf: []byte{0, 'a'},
+			w:   1,
+		},
+	},
+	{
+		buf: fixedBuffer{
+			buf: []byte{'a', 1},
+			r:   1,
+			w:   1,
+		},
+		write: 2,
+		wn:    2,
+		wbuf: fixedBuffer{
+			buf: []byte{0, 0},
+			w:   2,
+		},
+	},
+	{
+		buf: fixedBuffer{
+			buf: []byte{},
+		},
+		write: 5,
+		werr:  errWriteFull,
+		wbuf: fixedBuffer{
+			buf: []byte{},
+		},
+	},
+}
+
+func TestBufferWrite(t *testing.T) {
+	for i, tt := range bufferWriteTests {
+		n, err := tt.buf.Write(make([]byte, tt.write))
+		if n != tt.wn {
+			t.Errorf("#%d: wrote %d bytes; want %d", i, n, tt.wn)
+			continue
+		}
+		if err != tt.werr {
+			t.Errorf("#%d: error = %v; want %v", i, err, tt.werr)
+			continue
+		}
+		if !reflect.DeepEqual(tt.buf, tt.wbuf) {
+			t.Errorf("#%d: buf = %+v; want %+v", i, tt.buf, tt.wbuf)
+		}
+	}
+}

+ 3 - 4
Godeps/_workspace/src/github.com/bradfitz/http2/flow.go → Godeps/_workspace/src/golang.org/x/net/http2/flow.go

@@ -1,7 +1,6 @@
-// Copyright 2014 The Go Authors.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 
 // Flow control
 // Flow control
 
 

+ 3 - 4
Godeps/_workspace/src/github.com/bradfitz/http2/flow_test.go → Godeps/_workspace/src/golang.org/x/net/http2/flow_test.go

@@ -1,7 +1,6 @@
-// Copyright 2014 The Go Authors.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 
 package http2
 package http2
 
 

+ 182 - 26
Godeps/_workspace/src/github.com/bradfitz/http2/frame.go → Godeps/_workspace/src/golang.org/x/net/http2/frame.go

@@ -1,7 +1,6 @@
-// Copyright 2014 The Go Authors.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 
 package http2
 package http2
 
 
@@ -11,6 +10,7 @@ import (
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
 	"io"
 	"io"
+	"log"
 	"sync"
 	"sync"
 )
 )
 
 
@@ -85,8 +85,8 @@ const (
 	// Continuation Frame
 	// Continuation Frame
 	FlagContinuationEndHeaders Flags = 0x4
 	FlagContinuationEndHeaders Flags = 0x4
 
 
-	FlagPushPromiseEndHeaders = 0x4
-	FlagPushPromisePadded     = 0x8
+	FlagPushPromiseEndHeaders Flags = 0x4
+	FlagPushPromisePadded     Flags = 0x8
 )
 )
 
 
 var flagName = map[FrameType]map[Flags]string{
 var flagName = map[FrameType]map[Flags]string{
@@ -172,6 +172,12 @@ func (h FrameHeader) Header() FrameHeader { return h }
 func (h FrameHeader) String() string {
 func (h FrameHeader) String() string {
 	var buf bytes.Buffer
 	var buf bytes.Buffer
 	buf.WriteString("[FrameHeader ")
 	buf.WriteString("[FrameHeader ")
+	h.writeDebug(&buf)
+	buf.WriteByte(']')
+	return buf.String()
+}
+
+func (h FrameHeader) writeDebug(buf *bytes.Buffer) {
 	buf.WriteString(h.Type.String())
 	buf.WriteString(h.Type.String())
 	if h.Flags != 0 {
 	if h.Flags != 0 {
 		buf.WriteString(" flags=")
 		buf.WriteString(" flags=")
@@ -188,15 +194,14 @@ func (h FrameHeader) String() string {
 			if name != "" {
 			if name != "" {
 				buf.WriteString(name)
 				buf.WriteString(name)
 			} else {
 			} else {
-				fmt.Fprintf(&buf, "0x%x", 1<<i)
+				fmt.Fprintf(buf, "0x%x", 1<<i)
 			}
 			}
 		}
 		}
 	}
 	}
 	if h.StreamID != 0 {
 	if h.StreamID != 0 {
-		fmt.Fprintf(&buf, " stream=%d", h.StreamID)
+		fmt.Fprintf(buf, " stream=%d", h.StreamID)
 	}
 	}
-	fmt.Fprintf(&buf, " len=%d]", h.Length)
-	return buf.String()
+	fmt.Fprintf(buf, " len=%d", h.Length)
 }
 }
 
 
 func (h *FrameHeader) checkValid() {
 func (h *FrameHeader) checkValid() {
@@ -256,6 +261,11 @@ type Frame interface {
 type Framer struct {
 type Framer struct {
 	r         io.Reader
 	r         io.Reader
 	lastFrame Frame
 	lastFrame Frame
+	errReason string
+
+	// lastHeaderStream is non-zero if the last frame was an
+	// unfinished HEADERS/CONTINUATION.
+	lastHeaderStream uint32
 
 
 	maxReadSize uint32
 	maxReadSize uint32
 	headerBuf   [frameHeaderLen]byte
 	headerBuf   [frameHeaderLen]byte
@@ -272,18 +282,29 @@ type Framer struct {
 	wbuf []byte
 	wbuf []byte
 
 
 	// AllowIllegalWrites permits the Framer's Write methods to
 	// AllowIllegalWrites permits the Framer's Write methods to
-	// write frames that do not conform to the HTTP/2 spec.  This
+	// write frames that do not conform to the HTTP/2 spec. This
 	// permits using the Framer to test other HTTP/2
 	// permits using the Framer to test other HTTP/2
 	// implementations' conformance to the spec.
 	// implementations' conformance to the spec.
 	// If false, the Write methods will prefer to return an error
 	// If false, the Write methods will prefer to return an error
 	// rather than comply.
 	// rather than comply.
 	AllowIllegalWrites bool
 	AllowIllegalWrites bool
 
 
+	// AllowIllegalReads permits the Framer's ReadFrame method
+	// to return non-compliant frames or frame orders.
+	// This is for testing and permits using the Framer to test
+	// other HTTP/2 implementations' conformance to the spec.
+	AllowIllegalReads bool
+
 	// TODO: track which type of frame & with which flags was sent
 	// TODO: track which type of frame & with which flags was sent
 	// last.  Then return an error (unless AllowIllegalWrites) if
 	// last.  Then return an error (unless AllowIllegalWrites) if
 	// we're in the middle of a header block and a
 	// we're in the middle of a header block and a
 	// non-Continuation or Continuation on a different stream is
 	// non-Continuation or Continuation on a different stream is
 	// attempted to be written.
 	// attempted to be written.
+
+	logReads bool
+
+	debugFramer    *Framer // only use for logging written writes
+	debugFramerBuf *bytes.Buffer
 }
 }
 
 
 func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
 func (f *Framer) startWrite(ftype FrameType, flags Flags, streamID uint32) {
@@ -311,6 +332,10 @@ func (f *Framer) endWrite() error {
 		byte(length>>16),
 		byte(length>>16),
 		byte(length>>8),
 		byte(length>>8),
 		byte(length))
 		byte(length))
+	if logFrameWrites {
+		f.logWrite()
+	}
+
 	n, err := f.w.Write(f.wbuf)
 	n, err := f.w.Write(f.wbuf)
 	if err == nil && n != len(f.wbuf) {
 	if err == nil && n != len(f.wbuf) {
 		err = io.ErrShortWrite
 		err = io.ErrShortWrite
@@ -318,6 +343,24 @@ func (f *Framer) endWrite() error {
 	return err
 	return err
 }
 }
 
 
+func (f *Framer) logWrite() {
+	if f.debugFramer == nil {
+		f.debugFramerBuf = new(bytes.Buffer)
+		f.debugFramer = NewFramer(nil, f.debugFramerBuf)
+		f.debugFramer.logReads = false // we log it ourselves, saying "wrote" below
+		// Let us read anything, even if we accidentally wrote it
+		// in the wrong order:
+		f.debugFramer.AllowIllegalReads = true
+	}
+	f.debugFramerBuf.Write(f.wbuf)
+	fr, err := f.debugFramer.ReadFrame()
+	if err != nil {
+		log.Printf("http2: Framer %p: failed to decode just-written frame", f)
+		return
+	}
+	log.Printf("http2: Framer %p: wrote %v", f, summarizeFrame(fr))
+}
+
 func (f *Framer) writeByte(v byte)     { f.wbuf = append(f.wbuf, v) }
 func (f *Framer) writeByte(v byte)     { f.wbuf = append(f.wbuf, v) }
 func (f *Framer) writeBytes(v []byte)  { f.wbuf = append(f.wbuf, v...) }
 func (f *Framer) writeBytes(v []byte)  { f.wbuf = append(f.wbuf, v...) }
 func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
 func (f *Framer) writeUint16(v uint16) { f.wbuf = append(f.wbuf, byte(v>>8), byte(v)) }
@@ -333,8 +376,9 @@ const (
 // NewFramer returns a Framer that writes frames to w and reads them from r.
 // NewFramer returns a Framer that writes frames to w and reads them from r.
 func NewFramer(w io.Writer, r io.Reader) *Framer {
 func NewFramer(w io.Writer, r io.Reader) *Framer {
 	fr := &Framer{
 	fr := &Framer{
-		w: w,
-		r: r,
+		w:        w,
+		r:        r,
+		logReads: logFrameReads,
 	}
 	}
 	fr.getReadBuf = func(size uint32) []byte {
 	fr.getReadBuf = func(size uint32) []byte {
 		if cap(fr.readBuf) >= int(size) {
 		if cap(fr.readBuf) >= int(size) {
@@ -362,10 +406,22 @@ func (fr *Framer) SetMaxReadFrameSize(v uint32) {
 // sends a frame that is larger than declared with SetMaxReadFrameSize.
 // sends a frame that is larger than declared with SetMaxReadFrameSize.
 var ErrFrameTooLarge = errors.New("http2: frame too large")
 var ErrFrameTooLarge = errors.New("http2: frame too large")
 
 
+// terminalReadFrameError reports whether err is an unrecoverable
+// error from ReadFrame and no other frames should be read.
+func terminalReadFrameError(err error) bool {
+	if _, ok := err.(StreamError); ok {
+		return false
+	}
+	return err != nil
+}
+
 // ReadFrame reads a single frame. The returned Frame is only valid
 // ReadFrame reads a single frame. The returned Frame is only valid
 // until the next call to ReadFrame.
 // until the next call to ReadFrame.
-// If the frame is larger than previously set with SetMaxReadFrameSize,
-// the returned error is ErrFrameTooLarge.
+//
+// If the frame is larger than previously set with SetMaxReadFrameSize, the
+// returned error is ErrFrameTooLarge. Other errors may be of type
+// ConnectionError, StreamError, or anything else from from the underlying
+// reader.
 func (fr *Framer) ReadFrame() (Frame, error) {
 func (fr *Framer) ReadFrame() (Frame, error) {
 	if fr.lastFrame != nil {
 	if fr.lastFrame != nil {
 		fr.lastFrame.invalidate()
 		fr.lastFrame.invalidate()
@@ -383,12 +439,68 @@ func (fr *Framer) ReadFrame() (Frame, error) {
 	}
 	}
 	f, err := typeFrameParser(fh.Type)(fh, payload)
 	f, err := typeFrameParser(fh.Type)(fh, payload)
 	if err != nil {
 	if err != nil {
+		if ce, ok := err.(connError); ok {
+			return nil, fr.connError(ce.Code, ce.Reason)
+		}
 		return nil, err
 		return nil, err
 	}
 	}
-	fr.lastFrame = f
+	if err := fr.checkFrameOrder(f); err != nil {
+		return nil, err
+	}
+	if fr.logReads {
+		log.Printf("http2: Framer %p: read %v", fr, summarizeFrame(f))
+	}
 	return f, nil
 	return f, nil
 }
 }
 
 
+// connError returns ConnectionError(code) but first
+// stashes away a public reason to the caller can optionally relay it
+// to the peer before hanging up on them. This might help others debug
+// their implementations.
+func (fr *Framer) connError(code ErrCode, reason string) error {
+	fr.errReason = reason
+	return ConnectionError(code)
+}
+
+// checkFrameOrder reports an error if f is an invalid frame to return
+// next from ReadFrame. Mostly it checks whether HEADERS and
+// CONTINUATION frames are contiguous.
+func (fr *Framer) checkFrameOrder(f Frame) error {
+	last := fr.lastFrame
+	fr.lastFrame = f
+	if fr.AllowIllegalReads {
+		return nil
+	}
+
+	fh := f.Header()
+	if fr.lastHeaderStream != 0 {
+		if fh.Type != FrameContinuation {
+			return fr.connError(ErrCodeProtocol,
+				fmt.Sprintf("got %s for stream %d; expected CONTINUATION following %s for stream %d",
+					fh.Type, fh.StreamID,
+					last.Header().Type, fr.lastHeaderStream))
+		}
+		if fh.StreamID != fr.lastHeaderStream {
+			return fr.connError(ErrCodeProtocol,
+				fmt.Sprintf("got CONTINUATION for stream %d; expected stream %d",
+					fh.StreamID, fr.lastHeaderStream))
+		}
+	} else if fh.Type == FrameContinuation {
+		return fr.connError(ErrCodeProtocol, fmt.Sprintf("unexpected CONTINUATION for stream %d", fh.StreamID))
+	}
+
+	switch fh.Type {
+	case FrameHeaders, FrameContinuation:
+		if fh.Flags.Has(FlagHeadersEndHeaders) {
+			fr.lastHeaderStream = 0
+		} else {
+			fr.lastHeaderStream = fh.StreamID
+		}
+	}
+
+	return nil
+}
+
 // A DataFrame conveys arbitrary, variable-length sequences of octets
 // A DataFrame conveys arbitrary, variable-length sequences of octets
 // associated with a stream.
 // associated with a stream.
 // See http://http2.github.io/http2-spec/#rfc.section.6.1
 // See http://http2.github.io/http2-spec/#rfc.section.6.1
@@ -417,7 +529,7 @@ func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) {
 		// field is 0x0, the recipient MUST respond with a
 		// field is 0x0, the recipient MUST respond with a
 		// connection error (Section 5.4.1) of type
 		// connection error (Section 5.4.1) of type
 		// PROTOCOL_ERROR.
 		// PROTOCOL_ERROR.
-		return nil, ConnectionError(ErrCodeProtocol)
+		return nil, connError{ErrCodeProtocol, "DATA frame with stream ID 0"}
 	}
 	}
 	f := &DataFrame{
 	f := &DataFrame{
 		FrameHeader: fh,
 		FrameHeader: fh,
@@ -435,7 +547,7 @@ func parseDataFrame(fh FrameHeader, payload []byte) (Frame, error) {
 		// length of the frame payload, the recipient MUST
 		// length of the frame payload, the recipient MUST
 		// treat this as a connection error.
 		// treat this as a connection error.
 		// Filed: https://github.com/http2/http2-spec/issues/610
 		// Filed: https://github.com/http2/http2-spec/issues/610
-		return nil, ConnectionError(ErrCodeProtocol)
+		return nil, connError{ErrCodeProtocol, "pad size larger than data payload"}
 	}
 	}
 	f.data = payload[:len(payload)-int(padSize)]
 	f.data = payload[:len(payload)-int(padSize)]
 	return f, nil
 	return f, nil
@@ -575,6 +687,8 @@ type PingFrame struct {
 	Data [8]byte
 	Data [8]byte
 }
 }
 
 
+func (f *PingFrame) IsAck() bool { return f.Flags.Has(FlagPingAck) }
+
 func parsePingFrame(fh FrameHeader, payload []byte) (Frame, error) {
 func parsePingFrame(fh FrameHeader, payload []byte) (Frame, error) {
 	if len(payload) != 8 {
 	if len(payload) != 8 {
 		return nil, ConnectionError(ErrCodeFrameSize)
 		return nil, ConnectionError(ErrCodeFrameSize)
@@ -663,7 +777,7 @@ func parseUnknownFrame(fh FrameHeader, p []byte) (Frame, error) {
 // See http://http2.github.io/http2-spec/#rfc.section.6.9
 // See http://http2.github.io/http2-spec/#rfc.section.6.9
 type WindowUpdateFrame struct {
 type WindowUpdateFrame struct {
 	FrameHeader
 	FrameHeader
-	Increment uint32
+	Increment uint32 // never read with high bit set
 }
 }
 
 
 func parseWindowUpdateFrame(fh FrameHeader, p []byte) (Frame, error) {
 func parseWindowUpdateFrame(fh FrameHeader, p []byte) (Frame, error) {
@@ -740,7 +854,7 @@ func parseHeadersFrame(fh FrameHeader, p []byte) (_ Frame, err error) {
 		// is received whose stream identifier field is 0x0, the recipient MUST
 		// is received whose stream identifier field is 0x0, the recipient MUST
 		// respond with a connection error (Section 5.4.1) of type
 		// respond with a connection error (Section 5.4.1) of type
 		// PROTOCOL_ERROR.
 		// PROTOCOL_ERROR.
-		return nil, ConnectionError(ErrCodeProtocol)
+		return nil, connError{ErrCodeProtocol, "HEADERS frame with stream ID 0"}
 	}
 	}
 	var padLength uint8
 	var padLength uint8
 	if fh.Flags.Has(FlagHeadersPadded) {
 	if fh.Flags.Has(FlagHeadersPadded) {
@@ -870,10 +984,10 @@ func (p PriorityParam) IsZero() bool {
 
 
 func parsePriorityFrame(fh FrameHeader, payload []byte) (Frame, error) {
 func parsePriorityFrame(fh FrameHeader, payload []byte) (Frame, error) {
 	if fh.StreamID == 0 {
 	if fh.StreamID == 0 {
-		return nil, ConnectionError(ErrCodeProtocol)
+		return nil, connError{ErrCodeProtocol, "PRIORITY frame with stream ID 0"}
 	}
 	}
 	if len(payload) != 5 {
 	if len(payload) != 5 {
-		return nil, ConnectionError(ErrCodeFrameSize)
+		return nil, connError{ErrCodeFrameSize, fmt.Sprintf("PRIORITY frame payload size was %d; want 5", len(payload))}
 	}
 	}
 	v := binary.BigEndian.Uint32(payload[:4])
 	v := binary.BigEndian.Uint32(payload[:4])
 	streamID := v & 0x7fffffff // mask off high bit
 	streamID := v & 0x7fffffff // mask off high bit
@@ -943,13 +1057,12 @@ type ContinuationFrame struct {
 }
 }
 
 
 func parseContinuationFrame(fh FrameHeader, p []byte) (Frame, error) {
 func parseContinuationFrame(fh FrameHeader, p []byte) (Frame, error) {
+	if fh.StreamID == 0 {
+		return nil, connError{ErrCodeProtocol, "CONTINUATION frame with stream ID 0"}
+	}
 	return &ContinuationFrame{fh, p}, nil
 	return &ContinuationFrame{fh, p}, nil
 }
 }
 
 
-func (f *ContinuationFrame) StreamEnded() bool {
-	return f.FrameHeader.Flags.Has(FlagDataEndStream)
-}
-
 func (f *ContinuationFrame) HeaderBlockFragment() []byte {
 func (f *ContinuationFrame) HeaderBlockFragment() []byte {
 	f.checkValid()
 	f.checkValid()
 	return f.headerFragBuf
 	return f.headerFragBuf
@@ -1111,3 +1224,46 @@ type streamEnder interface {
 type headersEnder interface {
 type headersEnder interface {
 	HeadersEnded() bool
 	HeadersEnded() bool
 }
 }
+
+func summarizeFrame(f Frame) string {
+	var buf bytes.Buffer
+	f.Header().writeDebug(&buf)
+	switch f := f.(type) {
+	case *SettingsFrame:
+		n := 0
+		f.ForeachSetting(func(s Setting) error {
+			n++
+			if n == 1 {
+				buf.WriteString(", settings:")
+			}
+			fmt.Fprintf(&buf, " %v=%v,", s.ID, s.Val)
+			return nil
+		})
+		if n > 0 {
+			buf.Truncate(buf.Len() - 1) // remove trailing comma
+		}
+	case *DataFrame:
+		data := f.Data()
+		const max = 256
+		if len(data) > max {
+			data = data[:max]
+		}
+		fmt.Fprintf(&buf, " data=%q", data)
+		if len(f.Data()) > max {
+			fmt.Fprintf(&buf, " (%d bytes omitted)", len(f.Data())-max)
+		}
+	case *WindowUpdateFrame:
+		if f.StreamID == 0 {
+			buf.WriteString(" (conn)")
+		}
+		fmt.Fprintf(&buf, " incr=%v", f.Increment)
+	case *PingFrame:
+		fmt.Fprintf(&buf, " ping=%q", f.Data[:])
+	case *GoAwayFrame:
+		fmt.Fprintf(&buf, " LastStreamID=%v ErrCode=%v Debug=%q",
+			f.LastStreamID, f.ErrCode, f.debugData)
+	case *RSTStreamFrame:
+		fmt.Fprintf(&buf, " ErrCode=%v", f.ErrCode)
+	}
+	return buf.String()
+}

+ 157 - 0
Godeps/_workspace/src/github.com/bradfitz/http2/frame_test.go → Godeps/_workspace/src/golang.org/x/net/http2/frame_test.go

@@ -6,6 +6,8 @@ package http2
 
 
 import (
 import (
 	"bytes"
 	"bytes"
+	"fmt"
+	"io"
 	"reflect"
 	"reflect"
 	"strings"
 	"strings"
 	"testing"
 	"testing"
@@ -24,6 +26,25 @@ func TestFrameSizes(t *testing.T) {
 	}
 	}
 }
 }
 
 
+func TestFrameTypeString(t *testing.T) {
+	tests := []struct {
+		ft   FrameType
+		want string
+	}{
+		{FrameData, "DATA"},
+		{FramePing, "PING"},
+		{FrameGoAway, "GOAWAY"},
+		{0xf, "UNKNOWN_FRAME_TYPE_15"},
+	}
+
+	for i, tt := range tests {
+		got := tt.ft.String()
+		if got != tt.want {
+			t.Errorf("%d. String(FrameType %d) = %q; want %q", i, int(tt.ft), got, tt.want)
+		}
+	}
+}
+
 func TestWriteRST(t *testing.T) {
 func TestWriteRST(t *testing.T) {
 	fr, buf := testFramer()
 	fr, buf := testFramer()
 	var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
 	var streamID uint32 = 1<<24 + 2<<16 + 3<<8 + 4
@@ -245,6 +266,7 @@ func TestWriteContinuation(t *testing.T) {
 			t.Errorf("test %q: %v", tt.name, err)
 			t.Errorf("test %q: %v", tt.name, err)
 			continue
 			continue
 		}
 		}
+		fr.AllowIllegalReads = true
 		f, err := fr.ReadFrame()
 		f, err := fr.ReadFrame()
 		if err != nil {
 		if err != nil {
 			t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
 			t.Errorf("test %q: failed to read the frame back: %v", tt.name, err)
@@ -576,3 +598,138 @@ func TestWritePushPromise(t *testing.T) {
 		t.Fatalf("parsed back:\n%#v\nwant:\n%#v", f, want)
 		t.Fatalf("parsed back:\n%#v\nwant:\n%#v", f, want)
 	}
 	}
 }
 }
+
+// test checkFrameOrder and that HEADERS and CONTINUATION frames can't be intermingled.
+func TestReadFrameOrder(t *testing.T) {
+	head := func(f *Framer, id uint32, end bool) {
+		f.WriteHeaders(HeadersFrameParam{
+			StreamID:      id,
+			BlockFragment: []byte("foo"), // unused, but non-empty
+			EndHeaders:    end,
+		})
+	}
+	cont := func(f *Framer, id uint32, end bool) {
+		f.WriteContinuation(id, end, []byte("foo"))
+	}
+
+	tests := [...]struct {
+		name    string
+		w       func(*Framer)
+		atLeast int
+		wantErr string
+	}{
+		0: {
+			w: func(f *Framer) {
+				head(f, 1, true)
+			},
+		},
+		1: {
+			w: func(f *Framer) {
+				head(f, 1, true)
+				head(f, 2, true)
+			},
+		},
+		2: {
+			wantErr: "got HEADERS for stream 2; expected CONTINUATION following HEADERS for stream 1",
+			w: func(f *Framer) {
+				head(f, 1, false)
+				head(f, 2, true)
+			},
+		},
+		3: {
+			wantErr: "got DATA for stream 1; expected CONTINUATION following HEADERS for stream 1",
+			w: func(f *Framer) {
+				head(f, 1, false)
+			},
+		},
+		4: {
+			w: func(f *Framer) {
+				head(f, 1, false)
+				cont(f, 1, true)
+				head(f, 2, true)
+			},
+		},
+		5: {
+			wantErr: "got CONTINUATION for stream 2; expected stream 1",
+			w: func(f *Framer) {
+				head(f, 1, false)
+				cont(f, 2, true)
+				head(f, 2, true)
+			},
+		},
+		6: {
+			wantErr: "unexpected CONTINUATION for stream 1",
+			w: func(f *Framer) {
+				cont(f, 1, true)
+			},
+		},
+		7: {
+			wantErr: "unexpected CONTINUATION for stream 1",
+			w: func(f *Framer) {
+				cont(f, 1, false)
+			},
+		},
+		8: {
+			wantErr: "HEADERS frame with stream ID 0",
+			w: func(f *Framer) {
+				head(f, 0, true)
+			},
+		},
+		9: {
+			wantErr: "CONTINUATION frame with stream ID 0",
+			w: func(f *Framer) {
+				cont(f, 0, true)
+			},
+		},
+		10: {
+			wantErr: "unexpected CONTINUATION for stream 1",
+			atLeast: 5,
+			w: func(f *Framer) {
+				head(f, 1, false)
+				cont(f, 1, false)
+				cont(f, 1, false)
+				cont(f, 1, false)
+				cont(f, 1, true)
+				cont(f, 1, false)
+			},
+		},
+	}
+	for i, tt := range tests {
+		buf := new(bytes.Buffer)
+		f := NewFramer(buf, buf)
+		f.AllowIllegalWrites = true
+		tt.w(f)
+		f.WriteData(1, true, nil) // to test transition away from last step
+
+		var err error
+		n := 0
+		var log bytes.Buffer
+		for {
+			var got Frame
+			got, err = f.ReadFrame()
+			fmt.Fprintf(&log, "  read %v, %v\n", got, err)
+			if err != nil {
+				break
+			}
+			n++
+		}
+		if err == io.EOF {
+			err = nil
+		}
+		ok := tt.wantErr == ""
+		if ok && err != nil {
+			t.Errorf("%d. after %d good frames, ReadFrame = %v; want success\n%s", i, n, err, log.Bytes())
+			continue
+		}
+		if !ok && err != ConnectionError(ErrCodeProtocol) {
+			t.Errorf("%d. after %d good frames, ReadFrame = %v; want ConnectionError(ErrCodeProtocol)\n%s", i, n, err, log.Bytes())
+			continue
+		}
+		if f.errReason != tt.wantErr {
+			t.Errorf("%d. framer eror = %q; want %q\n%s", i, f.errReason, tt.wantErr, log.Bytes())
+		}
+		if n < tt.atLeast {
+			t.Errorf("%d. framer only read %d frames; want at least %d\n%s", i, n, tt.atLeast, log.Bytes())
+		}
+	}
+}

+ 11 - 0
Godeps/_workspace/src/golang.org/x/net/http2/go15.go

@@ -0,0 +1,11 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.5
+
+package http2
+
+import "net/http"
+
+func requestCancel(req *http.Request) <-chan struct{} { return req.Cancel }

+ 5 - 4
Godeps/_workspace/src/github.com/bradfitz/http2/gotrack.go → Godeps/_workspace/src/golang.org/x/net/http2/gotrack.go

@@ -1,9 +1,6 @@
 // Copyright 2014 The Go Authors. All rights reserved.
 // Copyright 2014 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
 
 
 // Defensive debug-only utility to track that functions run on the
 // Defensive debug-only utility to track that functions run on the
 // goroutine that they're supposed to.
 // goroutine that they're supposed to.
@@ -14,16 +11,20 @@ import (
 	"bytes"
 	"bytes"
 	"errors"
 	"errors"
 	"fmt"
 	"fmt"
+	"os"
 	"runtime"
 	"runtime"
 	"strconv"
 	"strconv"
 	"sync"
 	"sync"
 )
 )
 
 
-var DebugGoroutines = false
+var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
 
 
 type goroutineLock uint64
 type goroutineLock uint64
 
 
 func newGoroutineLock() goroutineLock {
 func newGoroutineLock() goroutineLock {
+	if !DebugGoroutines {
+		return 0
+	}
 	return goroutineLock(curGoroutineID())
 	return goroutineLock(curGoroutineID())
 }
 }
 
 

+ 3 - 3
Godeps/_workspace/src/github.com/bradfitz/http2/gotrack_test.go → Godeps/_workspace/src/golang.org/x/net/http2/gotrack_test.go

@@ -1,9 +1,6 @@
 // Copyright 2014 The Go Authors. All rights reserved.
 // Copyright 2014 The Go Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
 
 
 package http2
 package http2
 
 
@@ -14,7 +11,10 @@ import (
 )
 )
 
 
 func TestGoroutineLock(t *testing.T) {
 func TestGoroutineLock(t *testing.T) {
+	oldDebug := DebugGoroutines
 	DebugGoroutines = true
 	DebugGoroutines = true
+	defer func() { DebugGoroutines = oldDebug }()
+
 	g := newGoroutineLock()
 	g := newGoroutineLock()
 	g.check()
 	g.check()
 
 

+ 0 - 0
Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/.gitignore → Godeps/_workspace/src/golang.org/x/net/http2/h2demo/.gitignore


+ 8 - 0
Godeps/_workspace/src/golang.org/x/net/http2/h2demo/Makefile

@@ -0,0 +1,8 @@
+h2demo.linux: h2demo.go
+	GOOS=linux go build --tags=h2demo -o h2demo.linux .
+
+FORCE:
+
+upload: FORCE
+	go install golang.org/x/build/cmd/upload
+	upload --verbose --osarch=linux-amd64 --tags=h2demo --file=go:golang.org/x/net/http2/h2demo --public http2-demo-server-tls/h2demo

+ 0 - 0
Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/README → Godeps/_workspace/src/golang.org/x/net/http2/h2demo/README


+ 78 - 32
Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/h2demo.go → Godeps/_workspace/src/golang.org/x/net/http2/h2demo/h2demo.go

@@ -1,7 +1,6 @@
-// Copyright 2014 The Go Authors.
-// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
-// Licensed under the same terms as Go itself:
-// https://code.google.com/p/go/source/browse/LICENSE
+// Copyright 2014 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
 
 // +build h2demo
 // +build h2demo
 
 
@@ -20,7 +19,6 @@ import (
 	"log"
 	"log"
 	"net"
 	"net"
 	"net/http"
 	"net/http"
-	"os/exec"
 	"path"
 	"path"
 	"regexp"
 	"regexp"
 	"runtime"
 	"runtime"
@@ -31,14 +29,17 @@ import (
 
 
 	"camlistore.org/pkg/googlestorage"
 	"camlistore.org/pkg/googlestorage"
 	"camlistore.org/pkg/singleflight"
 	"camlistore.org/pkg/singleflight"
-	"github.com/coreos/etcd/Godeps/_workspace/src/github.com/bradfitz/http2"
+	"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/http2"
 )
 )
 
 
 var (
 var (
-	openFirefox = flag.Bool("openff", false, "Open Firefox")
-	addr        = flag.String("addr", "localhost:4430", "TLS address to listen on")
-	httpAddr    = flag.String("httpaddr", "", "If non-empty, address to listen for regular HTTP on")
-	prod        = flag.Bool("prod", false, "Whether to configure itself to be the production http2.golang.org server.")
+	prod = flag.Bool("prod", false, "Whether to configure itself to be the production http2.golang.org server.")
+
+	httpsAddr = flag.String("https_addr", "localhost:4430", "TLS address to listen on ('host:port' or ':port'). Required.")
+	httpAddr  = flag.String("http_addr", "", "Plain HTTP address to listen on ('host:port', or ':port'). Empty means no HTTP.")
+
+	hostHTTP  = flag.String("http_host", "", "Optional host or host:port to use for http:// links to this service. By default, this is implied from -http_addr.")
+	hostHTTPS = flag.String("https_host", "", "Optional host or host:port to use for http:// links to this service. By default, this is implied from -https_addr.")
 )
 )
 
 
 func homeOldHTTP(w http.ResponseWriter, r *http.Request) {
 func homeOldHTTP(w http.ResponseWriter, r *http.Request) {
@@ -51,7 +52,7 @@ func homeOldHTTP(w http.ResponseWriter, r *http.Request) {
    <li>Use Firefox Nightly or go to <b>about:config</b> and enable "network.http.spdy.enabled.http2draft"</li>
    <li>Use Firefox Nightly or go to <b>about:config</b> and enable "network.http.spdy.enabled.http2draft"</li>
    <li>Use Google Chrome Canary and/or go to <b>chrome://flags/#enable-spdy4</b> to <i>Enable SPDY/4</i> (Chrome's name for HTTP/2)</li>
    <li>Use Google Chrome Canary and/or go to <b>chrome://flags/#enable-spdy4</b> to <i>Enable SPDY/4</i> (Chrome's name for HTTP/2)</li>
 </ul>
 </ul>
-<p>See code & instructions for connecting at <a href="https://github.com/bradfitz/http2">https://github.com/bradfitz/http2</a>.</p>
+<p>See code & instructions for connecting at <a href="https://github.com/golang/net/tree/master/http2">https://github.com/golang/net/tree/master/http2</a>.</p>
 
 
 </body></html>`)
 </body></html>`)
 }
 }
@@ -72,13 +73,13 @@ href="https://http2.github.io/">HTTP/2</a> demo & interop server.</p>
 
 
 <p>This server exists for others in the HTTP/2 community to test their HTTP/2 client implementations and point out flaws in our server.</p>
 <p>This server exists for others in the HTTP/2 community to test their HTTP/2 client implementations and point out flaws in our server.</p>
 
 
-<p> The code is currently at <a
-href="https://github.com/bradfitz/http2">github.com/bradfitz/http2</a>
-but will move to the Go standard library at some point in the future
-(enabled by default, without users needing to change their code).</p>
+<p>
+The code is at <a href="https://golang.org/x/net/http2">golang.org/x/net/http2</a> and
+is used transparently by the Go standard library from Go 1.6 and later.
+</p>
 
 
 <p>Contact info: <i>bradfitz@golang.org</i>, or <a
 <p>Contact info: <i>bradfitz@golang.org</i>, or <a
-href="https://github.com/bradfitz/http2/issues">file a bug</a>.</p>
+href="https://golang.org/issues">file a bug</a>.</p>
 
 
 <h2>Handlers for testing</h2>
 <h2>Handlers for testing</h2>
 <ul>
 <ul>
@@ -90,6 +91,7 @@ href="https://github.com/bradfitz/http2/issues">file a bug</a>.</p>
   <li>GET <a href="/redirect">/redirect</a> to redirect back to / (this page)</li>
   <li>GET <a href="/redirect">/redirect</a> to redirect back to / (this page)</li>
   <li>GET <a href="/goroutines">/goroutines</a> to see all active goroutines in this server</li>
   <li>GET <a href="/goroutines">/goroutines</a> to see all active goroutines in this server</li>
   <li>PUT something to <a href="/crc32">/crc32</a> to get a count of number of bytes and its CRC-32</li>
   <li>PUT something to <a href="/crc32">/crc32</a> to get a count of number of bytes and its CRC-32</li>
+  <li>PUT something to <a href="/ECHO">/ECHO</a> and it will be streamed back to you capitalized</li>
 </ul>
 </ul>
 
 
 </body></html>`)
 </body></html>`)
@@ -123,6 +125,40 @@ func crcHandler(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 }
 }
 
 
+type capitalizeReader struct {
+	r io.Reader
+}
+
+func (cr capitalizeReader) Read(p []byte) (n int, err error) {
+	n, err = cr.r.Read(p)
+	for i, b := range p[:n] {
+		if b >= 'a' && b <= 'z' {
+			p[i] = b - ('a' - 'A')
+		}
+	}
+	return
+}
+
+type flushWriter struct {
+	w io.Writer
+}
+
+func (fw flushWriter) Write(p []byte) (n int, err error) {
+	n, err = fw.w.Write(p)
+	if f, ok := fw.w.(http.Flusher); ok {
+		f.Flush()
+	}
+	return
+}
+
+func echoCapitalHandler(w http.ResponseWriter, r *http.Request) {
+	if r.Method != "PUT" {
+		http.Error(w, "PUT required.", 400)
+		return
+	}
+	io.Copy(flushWriter{w}, capitalizeReader{r.Body})
+}
+
 var (
 var (
 	fsGrp   singleflight.Group
 	fsGrp   singleflight.Group
 	fsMu    sync.Mutex // guards fsCache
 	fsMu    sync.Mutex // guards fsCache
@@ -198,7 +234,7 @@ func registerHandlers() {
 				tiles.ServeHTTP(w, r)
 				tiles.ServeHTTP(w, r)
 				return
 				return
 			}
 			}
-			http.Redirect(w, r, "https://http2.golang.org/", http.StatusFound)
+			http.Redirect(w, r, "https://"+httpsHost()+"/", http.StatusFound)
 			return
 			return
 		}
 		}
 		if r.ProtoMajor == 1 {
 		if r.ProtoMajor == 1 {
@@ -216,6 +252,7 @@ func registerHandlers() {
 	mux2.Handle("/file/go.src.tar.gz", fileServer("https://storage.googleapis.com/golang/go1.4.1.src.tar.gz"))
 	mux2.Handle("/file/go.src.tar.gz", fileServer("https://storage.googleapis.com/golang/go1.4.1.src.tar.gz"))
 	mux2.HandleFunc("/reqinfo", reqInfoHandler)
 	mux2.HandleFunc("/reqinfo", reqInfoHandler)
 	mux2.HandleFunc("/crc32", crcHandler)
 	mux2.HandleFunc("/crc32", crcHandler)
+	mux2.HandleFunc("/ECHO", echoCapitalHandler)
 	mux2.HandleFunc("/clockstream", clockStreamHandler)
 	mux2.HandleFunc("/clockstream", clockStreamHandler)
 	mux2.Handle("/gophertiles", tiles)
 	mux2.Handle("/gophertiles", tiles)
 	mux2.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) {
 	mux2.HandleFunc("/redirect", func(w http.ResponseWriter, r *http.Request) {
@@ -287,7 +324,7 @@ func newGopherTilesHandler() http.Handler {
 				return
 				return
 			}
 			}
 		}
 		}
-		io.WriteString(w, "<html><body>")
+		io.WriteString(w, "<html><body onload='showtimes()'>")
 		fmt.Fprintf(w, "A grid of %d tiled images is below. Compare:<p>", xt*yt)
 		fmt.Fprintf(w, "A grid of %d tiled images is below. Compare:<p>", xt*yt)
 		for _, ms := range []int{0, 30, 200, 1000} {
 		for _, ms := range []int{0, 30, 200, 1000} {
 			d := time.Duration(ms) * nanosPerMilli
 			d := time.Duration(ms) * nanosPerMilli
@@ -305,15 +342,24 @@ func newGopherTilesHandler() http.Handler {
 			}
 			}
 			io.WriteString(w, "<br/>\n")
 			io.WriteString(w, "<br/>\n")
 		}
 		}
-		io.WriteString(w, "<hr><a href='/'>&lt;&lt Back to Go HTTP/2 demo server</a></body></html>")
+		io.WriteString(w, `<p><div id='loadtimes'></div></p>
+<script>
+function showtimes() {
+	var times = 'Times from connection start:<br>'
+	times += 'DOM loaded: ' + (window.performance.timing.domContentLoadedEventEnd - window.performance.timing.connectStart) + 'ms<br>'
+	times += 'DOM complete (images loaded): ' + (window.performance.timing.domComplete - window.performance.timing.connectStart) + 'ms<br>'
+	document.getElementById('loadtimes').innerHTML = times
+}
+</script>
+<hr><a href='/'>&lt;&lt Back to Go HTTP/2 demo server</a></body></html>`)
 	})
 	})
 }
 }
 
 
 func httpsHost() string {
 func httpsHost() string {
-	if *prod {
-		return "http2.golang.org"
+	if *hostHTTPS != "" {
+		return *hostHTTPS
 	}
 	}
-	if v := *addr; strings.HasPrefix(v, ":") {
+	if v := *httpsAddr; strings.HasPrefix(v, ":") {
 		return "localhost" + v
 		return "localhost" + v
 	} else {
 	} else {
 		return v
 		return v
@@ -321,8 +367,8 @@ func httpsHost() string {
 }
 }
 
 
 func httpHost() string {
 func httpHost() string {
-	if *prod {
-		return "http2.golang.org"
+	if *hostHTTP != "" {
+		return *hostHTTP
 	}
 	}
 	if v := *httpAddr; strings.HasPrefix(v, ":") {
 	if v := *httpAddr; strings.HasPrefix(v, ":") {
 		return "localhost" + v
 		return "localhost" + v
@@ -398,29 +444,29 @@ func main() {
 	var srv http.Server
 	var srv http.Server
 	flag.BoolVar(&http2.VerboseLogs, "verbose", false, "Verbose HTTP/2 debugging.")
 	flag.BoolVar(&http2.VerboseLogs, "verbose", false, "Verbose HTTP/2 debugging.")
 	flag.Parse()
 	flag.Parse()
-	srv.Addr = *addr
+	srv.Addr = *httpsAddr
 
 
 	registerHandlers()
 	registerHandlers()
 
 
 	if *prod {
 	if *prod {
-		*httpAddr = "http2.golang.org"
+		*hostHTTP = "http2.golang.org"
+		*hostHTTPS = "http2.golang.org"
 		log.Fatal(serveProd())
 		log.Fatal(serveProd())
 	}
 	}
 
 
-	url := "https://" + *addr + "/"
+	url := "https://" + httpsHost() + "/"
 	log.Printf("Listening on " + url)
 	log.Printf("Listening on " + url)
 	http2.ConfigureServer(&srv, &http2.Server{})
 	http2.ConfigureServer(&srv, &http2.Server{})
 
 
 	if *httpAddr != "" {
 	if *httpAddr != "" {
-		go func() { log.Fatal(http.ListenAndServe(*httpAddr, nil)) }()
+		go func() {
+			log.Printf("Listening on http://" + httpHost() + "/ (for unencrypted HTTP/1)")
+			log.Fatal(http.ListenAndServe(*httpAddr, nil))
+		}()
 	}
 	}
 
 
 	go func() {
 	go func() {
 		log.Fatal(srv.ListenAndServeTLS("server.crt", "server.key"))
 		log.Fatal(srv.ListenAndServeTLS("server.crt", "server.key"))
 	}()
 	}()
-	if *openFirefox && runtime.GOOS == "darwin" {
-		time.Sleep(250 * time.Millisecond)
-		exec.Command("open", "-b", "org.mozilla.nightly", "https://localhost:4430/").Run()
-	}
 	select {}
 	select {}
 }
 }

+ 45 - 22
Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/launch.go → Godeps/_workspace/src/golang.org/x/net/http2/h2demo/launch.go

@@ -20,8 +20,9 @@ import (
 	"strings"
 	"strings"
 	"time"
 	"time"
 
 
-	"code.google.com/p/goauth2/oauth"
-	compute "code.google.com/p/google-api-go-client/compute/v1"
+	"golang.org/x/oauth2"
+	"golang.org/x/oauth2/google"
+	compute "google.golang.org/api/compute/v1"
 )
 )
 
 
 var (
 var (
@@ -44,19 +45,18 @@ func readFile(v string) string {
 	return strings.TrimSpace(string(slurp))
 	return strings.TrimSpace(string(slurp))
 }
 }
 
 
-var config = &oauth.Config{
+var config = &oauth2.Config{
 	// The client-id and secret should be for an "Installed Application" when using
 	// The client-id and secret should be for an "Installed Application" when using
 	// the CLI. Later we'll use a web application with a callback.
 	// the CLI. Later we'll use a web application with a callback.
-	ClientId:     readFile("client-id.dat"),
+	ClientID:     readFile("client-id.dat"),
 	ClientSecret: readFile("client-secret.dat"),
 	ClientSecret: readFile("client-secret.dat"),
-	Scope: strings.Join([]string{
-		compute.DevstorageFull_controlScope,
+	Endpoint:     google.Endpoint,
+	Scopes: []string{
+		compute.DevstorageFullControlScope,
 		compute.ComputeScope,
 		compute.ComputeScope,
 		"https://www.googleapis.com/auth/sqlservice",
 		"https://www.googleapis.com/auth/sqlservice",
 		"https://www.googleapis.com/auth/sqlservice.admin",
 		"https://www.googleapis.com/auth/sqlservice.admin",
-	}, " "),
-	AuthURL:     "https://accounts.google.com/o/oauth2/auth",
-	TokenURL:    "https://accounts.google.com/o/oauth2/token",
+	},
 	RedirectURL: "urn:ietf:wg:oauth:2.0:oob",
 	RedirectURL: "urn:ietf:wg:oauth:2.0:oob",
 }
 }
 
 
@@ -88,31 +88,32 @@ func main() {
 	prefix := "https://www.googleapis.com/compute/v1/projects/" + *proj
 	prefix := "https://www.googleapis.com/compute/v1/projects/" + *proj
 	machType := prefix + "/zones/" + *zone + "/machineTypes/" + *mach
 	machType := prefix + "/zones/" + *zone + "/machineTypes/" + *mach
 
 
-	tr := &oauth.Transport{
-		Config: config,
-	}
-
-	tokenCache := oauth.CacheFile("token.dat")
-	token, err := tokenCache.Token()
+	const tokenFileName = "token.dat"
+	tokenFile := tokenCacheFile(tokenFileName)
+	tokenSource := oauth2.ReuseTokenSource(nil, tokenFile)
+	token, err := tokenSource.Token()
 	if err != nil {
 	if err != nil {
 		if *writeObject != "" {
 		if *writeObject != "" {
 			log.Fatalf("Can't use --write_object without a valid token.dat file already cached.")
 			log.Fatalf("Can't use --write_object without a valid token.dat file already cached.")
 		}
 		}
-		log.Printf("Error getting token from %s: %v", string(tokenCache), err)
+		log.Printf("Error getting token from %s: %v", tokenFileName, err)
 		log.Printf("Get auth code from %v", config.AuthCodeURL("my-state"))
 		log.Printf("Get auth code from %v", config.AuthCodeURL("my-state"))
 		fmt.Print("\nEnter auth code: ")
 		fmt.Print("\nEnter auth code: ")
 		sc := bufio.NewScanner(os.Stdin)
 		sc := bufio.NewScanner(os.Stdin)
 		sc.Scan()
 		sc.Scan()
 		authCode := strings.TrimSpace(sc.Text())
 		authCode := strings.TrimSpace(sc.Text())
-		token, err = tr.Exchange(authCode)
+		token, err = config.Exchange(oauth2.NoContext, authCode)
 		if err != nil {
 		if err != nil {
 			log.Fatalf("Error exchanging auth code for a token: %v", err)
 			log.Fatalf("Error exchanging auth code for a token: %v", err)
 		}
 		}
-		tokenCache.PutToken(token)
+		if err := tokenFile.WriteToken(token); err != nil {
+			log.Fatalf("Error writing to %s: %v", tokenFileName, err)
+		}
+		tokenSource = oauth2.ReuseTokenSource(token, nil)
 	}
 	}
 
 
-	tr.Token = token
-	oauthClient := &http.Client{Transport: tr}
+	oauthClient := oauth2.NewClient(oauth2.NoContext, tokenSource)
+
 	if *writeObject != "" {
 	if *writeObject != "" {
 		writeCloudStorageObject(oauthClient)
 		writeCloudStorageObject(oauthClient)
 		return
 		return
@@ -164,7 +165,7 @@ func main() {
 			Items: []*compute.MetadataItems{
 			Items: []*compute.MetadataItems{
 				{
 				{
 					Key:   "user-data",
 					Key:   "user-data",
-					Value: cloudConfig,
+					Value: &cloudConfig,
 				},
 				},
 			},
 			},
 		},
 		},
@@ -184,7 +185,7 @@ func main() {
 			{
 			{
 				Email: "default",
 				Email: "default",
 				Scopes: []string{
 				Scopes: []string{
-					compute.DevstorageFull_controlScope,
+					compute.DevstorageFullControlScope,
 					compute.ComputeScope,
 					compute.ComputeScope,
 				},
 				},
 			},
 			},
@@ -277,3 +278,25 @@ func writeCloudStorageObject(httpClient *http.Client) {
 	log.Printf("Success.")
 	log.Printf("Success.")
 	os.Exit(0)
 	os.Exit(0)
 }
 }
+
+type tokenCacheFile string
+
+func (f tokenCacheFile) Token() (*oauth2.Token, error) {
+	slurp, err := ioutil.ReadFile(string(f))
+	if err != nil {
+		return nil, err
+	}
+	t := new(oauth2.Token)
+	if err := json.Unmarshal(slurp, t); err != nil {
+		return nil, err
+	}
+	return t, nil
+}
+
+func (f tokenCacheFile) WriteToken(t *oauth2.Token) error {
+	jt, err := json.Marshal(t)
+	if err != nil {
+		return err
+	}
+	return ioutil.WriteFile(string(f), jt, 0600)
+}

+ 0 - 0
Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/rootCA.key → Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.key


+ 0 - 0
Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/rootCA.pem → Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.pem


+ 0 - 0
Godeps/_workspace/src/github.com/bradfitz/http2/h2demo/rootCA.srl → Godeps/_workspace/src/golang.org/x/net/http2/h2demo/rootCA.srl


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