Browse Source

Vendor updated grpc, protobuf

Signed-off-by: Tonis Tiigi <tonistiigi@gmail.com>
Tonis Tiigi 9 years ago
parent
commit
14299daaca
25 changed files with 1315 additions and 605 deletions
  1. 2 2
      hack/vendor.sh
  2. 1 1
      vendor/src/github.com/golang/protobuf/proto/Makefile
  3. 33 7
      vendor/src/github.com/golang/protobuf/proto/clone.go
  4. 49 3
      vendor/src/github.com/golang/protobuf/proto/decode.go
  5. 56 17
      vendor/src/github.com/golang/protobuf/proto/encode.go
  6. 11 1
      vendor/src/github.com/golang/protobuf/proto/equal.go
  7. 41 4
      vendor/src/github.com/golang/protobuf/proto/extensions.go
  8. 385 261
      vendor/src/github.com/golang/protobuf/proto/lib.go
  9. 17 24
      vendor/src/github.com/golang/protobuf/proto/message_set.go
  10. 2 2
      vendor/src/github.com/golang/protobuf/proto/pointer_reflect.go
  11. 2 2
      vendor/src/github.com/golang/protobuf/proto/pointer_unsafe.go
  12. 107 2
      vendor/src/github.com/golang/protobuf/proto/properties.go
  13. 44 82
      vendor/src/github.com/golang/protobuf/proto/text.go
  14. 135 94
      vendor/src/github.com/golang/protobuf/proto/text_parser.go
  15. 1 1
      vendor/src/google.golang.org/grpc/Makefile
  16. 77 34
      vendor/src/google.golang.org/grpc/clientconn.go
  17. 40 0
      vendor/src/google.golang.org/grpc/coverage.sh
  18. 6 18
      vendor/src/google.golang.org/grpc/metadata/metadata.go
  19. 73 0
      vendor/src/google.golang.org/grpc/naming/naming.go
  20. 160 10
      vendor/src/google.golang.org/grpc/picker.go
  21. 40 7
      vendor/src/google.golang.org/grpc/server.go
  22. 1 1
      vendor/src/google.golang.org/grpc/stream.go
  23. 2 1
      vendor/src/google.golang.org/grpc/transport/control.go
  24. 5 5
      vendor/src/google.golang.org/grpc/transport/http2_client.go
  25. 25 26
      vendor/src/google.golang.org/grpc/transport/http2_server.go

+ 2 - 2
hack/vendor.sh

@@ -54,7 +54,7 @@ clone git github.com/vbatts/tar-split v0.9.11
 # get desired notary commit, might also need to be updated in Dockerfile
 clone git github.com/docker/notary v0.2.0
 
-clone git google.golang.org/grpc 174192fc93efcb188fc8f46ca447f0da606b6885 https://github.com/grpc/grpc-go.git
+clone git google.golang.org/grpc a22b6611561e9f0a3e0919690dd2caf48f14c517 https://github.com/grpc/grpc-go.git
 clone git github.com/miekg/pkcs11 df8ae6ca730422dba20c768ff38ef7d79077a59f
 clone git github.com/docker/go v1.5.1-1-1-gbaf439e
 clone git github.com/agl/ed25519 d2b94fd789ea21d12fac1a4443dd3a3f79cda72c
@@ -65,7 +65,7 @@ clone git github.com/seccomp/libseccomp-golang 1b506fc7c24eec5a3693cdcbed40d9c22
 clone git github.com/coreos/go-systemd v4
 clone git github.com/godbus/dbus v3
 clone git github.com/syndtr/gocapability 2c00daeb6c3b45114c80ac44119e7b8801fdd852
-clone git github.com/golang/protobuf f7137ae6b19afbfd61a94b746fda3b3fe0491874
+clone git github.com/golang/protobuf 68415e7123da32b07eab49c96d2c4d6158360e9b
 
 # gelf logging driver deps
 clone git github.com/Graylog2/go-gelf aab2f594e4585d43468ac57287b0dece9d806883

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

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

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

@@ -30,7 +30,7 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Protocol buffer deep copy and merge.
-// TODO: MessageSet and RawMessage.
+// TODO: RawMessage.
 
 package proto
 
@@ -75,12 +75,13 @@ func Merge(dst, src Message) {
 }
 
 func mergeStruct(out, in reflect.Value) {
+	sprop := GetProperties(in.Type())
 	for i := 0; i < in.NumField(); i++ {
 		f := in.Type().Field(i)
 		if strings.HasPrefix(f.Name, "XXX_") {
 			continue
 		}
-		mergeAny(out.Field(i), in.Field(i))
+		mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i])
 	}
 
 	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.IsNil() {
 			if out.IsNil() {
@@ -112,7 +116,21 @@ func mergeAny(out, in reflect.Value) {
 	switch in.Kind() {
 	case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
 		reflect.String, reflect.Uint32, reflect.Uint64:
+		if !viaPtr && isProto3Zero(in) {
+			return
+		}
 		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:
 		if in.Len() == 0 {
 			return
@@ -127,7 +145,7 @@ func mergeAny(out, in reflect.Value) {
 			switch elemKind {
 			case reflect.Ptr:
 				val = reflect.New(in.Type().Elem().Elem())
-				mergeAny(val, in.MapIndex(key))
+				mergeAny(val, in.MapIndex(key), false, nil)
 			case reflect.Slice:
 				val = in.MapIndex(key)
 				val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
@@ -143,13 +161,21 @@ func mergeAny(out, in reflect.Value) {
 		if out.IsNil() {
 			out.Set(reflect.New(in.Elem().Type()))
 		}
-		mergeAny(out.Elem(), in.Elem())
+		mergeAny(out.Elem(), in.Elem(), true, nil)
 	case reflect.Slice:
 		if in.IsNil() {
 			return
 		}
 		if in.Type().Elem().Kind() == reflect.Uint8 {
 			// []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.
 			// Append to []byte{} instead of []byte(nil) so that we never end up
 			// with a nil result.
@@ -167,7 +193,7 @@ func mergeAny(out, in reflect.Value) {
 		default:
 			for i := 0; i < n; i++ {
 				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))
 			}
 		}
@@ -184,7 +210,7 @@ func mergeExtension(out, in map[int32]Extension) {
 		eOut := Extension{desc: eIn.desc}
 		if eIn.value != nil {
 			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()
 		}
 		if eIn.enc != nil {

+ 49 - 3
vendor/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.
 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.
 // Those that take integer types all return uint64 and are
 // therefore of type valueDecoder.
@@ -314,6 +318,24 @@ func UnmarshalMerge(buf []byte, pb Message) error {
 	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
 // 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
@@ -377,6 +399,20 @@ func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group
 					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)
 			continue
 		}
@@ -561,9 +597,13 @@ func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error
 		return err
 	}
 	nb := int(nn) // number of bytes of encoded bools
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
 
 	y := *v
-	for i := 0; i < nb; i++ {
+	for o.index < fin {
 		u, err := p.valDec(o)
 		if err != nil {
 			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
 	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() {
 		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])
 		}
 	}
+	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
 }
 

+ 56 - 17
vendor/src/github.com/golang/protobuf/proto/encode.go

@@ -105,6 +105,11 @@ func (p *Buffer) EncodeVarint(x uint64) error {
 	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) {
 	for {
 		n++
@@ -228,6 +233,20 @@ func Marshal(pb Message) ([]byte, error) {
 	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
 // and encodes it into the wire format, writing the result to the
 // Buffer.
@@ -318,7 +337,7 @@ func size_bool(p *Properties, base structPointer) int {
 
 func size_proto3_bool(p *Properties, base structPointer) int {
 	v := *structPointer_BoolVal(base, p.field)
-	if !v {
+	if !v && !p.oneof {
 		return 0
 	}
 	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) {
 	v := structPointer_Word32Val(base, p.field)
 	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 	}
 	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) {
 	v := structPointer_Word32Val(base, p.field)
 	x := word32Val_Get(v)
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 	}
 	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) {
 	v := structPointer_Word64Val(base, p.field)
 	x := word64Val_Get(v)
-	if x == 0 {
+	if x == 0 && !p.oneof {
 		return 0
 	}
 	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) {
 	v := *structPointer_StringVal(base, p.field)
-	if v == "" {
+	if v == "" && !p.oneof {
 		return 0
 	}
 	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.EncodeRawBytes(data)
-		return nil
+		return state.err
 	}
 
 	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) {
 	s := *structPointer_Bytes(base, p.field)
-	if s == nil {
+	if s == nil && !p.oneof {
 		return 0
 	}
 	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) {
 	s := *structPointer_Bytes(base, p.field)
-	if len(s) == 0 {
+	if len(s) == 0 && !p.oneof {
 		return 0
 	}
 	n += len(p.tagcode)
@@ -1084,7 +1103,7 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
 			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 {
 		return nil
 	}
@@ -1101,11 +1120,15 @@ func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
 		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)
 
+		// 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)
 		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 {
-	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)
 
@@ -1128,10 +1151,12 @@ func size_new_map(p *Properties, base structPointer) int {
 		keycopy.Set(key)
 		valcopy.Set(val)
 
-		// Tag codes are two bytes per map entry.
-		n += 2
-		n += p.mkeyprop.size(p.mkeyprop, keybase)
-		n += p.mvalprop.size(p.mvalprop, valbase)
+		// 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
 }
@@ -1194,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.
 	if prop.unrecField.IsValid() {
 		v := *structPointer_Bytes(base, prop.unrecField)
@@ -1219,6 +1252,12 @@ func size_struct(prop *StructProperties, base structPointer) (n int) {
 		n += len(v)
 	}
 
+	// Factor in any oneof fields.
+	if prop.oneofSizer != nil {
+		m := structPointer_Interface(base, prop.stype).(Message)
+		n += prop.oneofSizer(m)
+	}
+
 	return
 }
 

+ 11 - 1
vendor/src/github.com/golang/protobuf/proto/equal.go

@@ -30,7 +30,6 @@
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // Protocol buffer comparison.
-// TODO: MessageSet.
 
 package proto
 
@@ -154,6 +153,17 @@ func equalAny(v1, v2 reflect.Value) bool {
 		return v1.Float() == v2.Float()
 	case reflect.Int32, reflect.Int64:
 		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:
 		if v1.Len() != v2.Len() {
 			return false

+ 41 - 4
vendor/src/github.com/golang/protobuf/proto/extensions.go

@@ -222,7 +222,7 @@ func ClearExtension(pb extendableProto, extension *ExtensionDesc) {
 }
 
 // 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) {
 	if err := checkExtensionTypes(pb, extension); err != nil {
 		return nil, err
@@ -231,8 +231,11 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
 	emap := pb.ExtensionMap()
 	e, ok := emap[extension.Field]
 	if !ok {
-		return nil, ErrMissingExtension
+		// defaultExtensionValue returns the default value or
+		// ErrMissingExtension if there is no default.
+		return defaultExtensionValue(extension)
 	}
+
 	if e.value != nil {
 		// Already decoded. Check the descriptor, though.
 		if e.desc != extension {
@@ -258,12 +261,46 @@ func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, er
 	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.
 func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
 	o := NewBuffer(b)
 
 	t := reflect.TypeOf(extension.ExtensionType)
-	rep := extension.repeated()
 
 	props := extensionProperties(extension)
 
@@ -285,7 +322,7 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
 			return nil, err
 		}
 
-		if !rep || o.index >= len(o.buf) {
+		if o.index >= len(o.buf) {
 			break
 		}
 	}

+ 385 - 261
vendor/src/github.com/golang/protobuf/proto/lib.go

@@ -30,179 +30,230 @@
 // 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.
+
+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),
+			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
 
@@ -211,6 +262,7 @@ import (
 	"fmt"
 	"log"
 	"reflect"
+	"sort"
 	"strconv"
 	"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
 // 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
 
-	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
 
 	fmt.Printf("\n--- %s ---\n", s)
@@ -402,12 +454,12 @@ out:
 			fmt.Print("  ")
 		}
 
-		index := o.index
-		if index == len(o.buf) {
+		index := p.index
+		if index == len(p.buf) {
 			break
 		}
 
-		op, err := o.DecodeVarint()
+		op, err := p.DecodeVarint()
 		if err != nil {
 			fmt.Printf("%3d: fetching op err %v\n", index, err)
 			break out
@@ -424,7 +476,7 @@ out:
 		case WireBytes:
 			var r []byte
 
-			r, err = o.DecodeRawBytes(false)
+			r, err = p.DecodeRawBytes(false)
 			if err != nil {
 				break out
 			}
@@ -445,7 +497,7 @@ out:
 			fmt.Printf("\n")
 
 		case WireFixed32:
-			u, err = o.DecodeFixed32()
+			u, err = p.DecodeFixed32()
 			if err != nil {
 				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
 				break out
@@ -453,16 +505,15 @@ out:
 			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
 
 		case WireFixed64:
-			u, err = o.DecodeFixed64()
+			u, err = p.DecodeFixed64()
 			if err != nil {
 				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
 				break out
 			}
 			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
-			break
 
 		case WireVarint:
-			u, err = o.DecodeVarint()
+			u, err = p.DecodeVarint()
 			if err != nil {
 				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
 				break out
@@ -470,30 +521,22 @@ out:
 			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
 
 		case WireStartGroup:
-			if err != nil {
-				fmt.Printf("%3d: t=%3d start err %v\n", index, tag, err)
-				break out
-			}
 			fmt.Printf("%3d: t=%3d start\n", index, tag)
 			depth++
 
 		case WireEndGroup:
 			depth--
-			if err != nil {
-				fmt.Printf("%3d: t=%3d end err %v\n", index, tag, err)
-				break out
-			}
 			fmt.Printf("%3d: t=%3d end\n", index, tag)
 		}
 	}
 
 	if depth != 0 {
-		fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth)
+		fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
 	}
 	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.
@@ -607,13 +650,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
 
 	for _, ni := range dm.nested {
 		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)
-		} else {
+
+		case reflect.Slice:
 			for i := 0; i < f.Len(); i++ {
 				e := f.Index(i)
 				if e.IsNil() {
@@ -621,6 +666,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
 				}
 				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 +700,6 @@ type scalarField struct {
 	value interface{}  // the proto-declared default value, or nil
 }
 
-func ptrToStruct(t reflect.Type) bool {
-	return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
-}
-
 // t is a struct type.
 func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
 	sprop := GetProperties(t)
@@ -661,88 +711,118 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
 		}
 		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)
-			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() {
-		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:
-			// []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.
@@ -750,10 +830,54 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
 // If this turns out to be inefficient we can always consider other options,
 // 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
+}
 
-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 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
vendor/src/github.com/golang/protobuf/proto/message_set.go

@@ -44,11 +44,11 @@ import (
 	"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.
-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:
 //   message MessageSet {
 //     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
 // because that would introduce a circular dependency between it and this package.
-//
-// When a proto1 proto has a field that looks like:
-//   optional message<MessageSet> info = 3;
-// the protocol compiler produces a field in the generated struct that looks like:
-//   Info *_proto_.MessageSet  `protobuf:"bytes,3,opt,name=info"`
-// The package is automatically inserted so there is no need for that proto file to
-// import this package.
 
 type _MessageSet_Item struct {
 	TypeId  *int32 `protobuf:"varint,2,req,name=type_id"`
 	Message []byte `protobuf:"bytes,3,req,name=message"`
 }
 
-type MessageSet struct {
+type messageSet struct {
 	Item             []*_MessageSet_Item `protobuf:"group,1,rep"`
 	XXX_unrecognized []byte
 	// TODO: caching?
 }
 
-// Make sure MessageSet is a Message.
-var _ Message = (*MessageSet)(nil)
+// Make sure messageSet is a Message.
+var _ Message = (*messageSet)(nil)
 
 // messageTypeIder is an interface satisfied by a protocol buffer type
 // that may be stored in a MessageSet.
@@ -86,7 +79,7 @@ type messageTypeIder interface {
 	MessageTypeId() int32
 }
 
-func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
+func (ms *messageSet) find(pb Message) *_MessageSet_Item {
 	mti, ok := pb.(messageTypeIder)
 	if !ok {
 		return nil
@@ -100,24 +93,24 @@ func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
 	return nil
 }
 
-func (ms *MessageSet) Has(pb Message) bool {
+func (ms *messageSet) Has(pb Message) bool {
 	if ms.find(pb) != nil {
 		return true
 	}
 	return false
 }
 
-func (ms *MessageSet) Unmarshal(pb Message) error {
+func (ms *messageSet) Unmarshal(pb Message) error {
 	if item := ms.find(pb); item != nil {
 		return Unmarshal(item.Message, pb)
 	}
 	if _, ok := pb.(messageTypeIder); !ok {
-		return ErrNoMessageTypeId
+		return errNoMessageTypeID
 	}
 	return nil // TODO: return error instead?
 }
 
-func (ms *MessageSet) Marshal(pb Message) error {
+func (ms *messageSet) Marshal(pb Message) error {
 	msg, err := Marshal(pb)
 	if err != nil {
 		return err
@@ -130,7 +123,7 @@ func (ms *MessageSet) Marshal(pb Message) error {
 
 	mti, ok := pb.(messageTypeIder)
 	if !ok {
-		return ErrNoMessageTypeId
+		return errNoMessageTypeID
 	}
 
 	mtid := mti.MessageTypeId()
@@ -141,9 +134,9 @@ func (ms *MessageSet) Marshal(pb Message) error {
 	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.
 
@@ -169,7 +162,7 @@ func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
 	}
 	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 {
 		e := m[int32(id)]
 		// 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.
 // It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
 func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
-	ms := new(MessageSet)
+	ms := new(messageSet)
 	if err := Unmarshal(buf, ms); err != nil {
 		return err
 	}

+ 2 - 2
vendor/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)
 }
 
-// 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()
 }
 

+ 2 - 2
vendor/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)))
 }
 
-// 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)))
 }
 

+ 107 - 2
vendor/src/github.com/golang/protobuf/proto/properties.go

@@ -37,6 +37,7 @@ package proto
 
 import (
 	"fmt"
+	"log"
 	"os"
 	"reflect"
 	"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.
 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
 // use-cases. Encoded protocol buffers are often in tag order with small tag
 // numbers.
@@ -132,6 +142,22 @@ type StructProperties struct {
 	order            []int          // list of struct field numbers in tag order
 	unrecField       field          // field id of the XXX_unrecognized []byte field
 	extendable       bool           // is this an extendable proto
+
+	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.
@@ -156,6 +182,7 @@ type Properties struct {
 	Packed   bool   // relevant for repeated primitives only
 	Enum     string // set for enum types only
 	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
+	oneof    bool   // whether this is a oneof field
 
 	Default    string // default value
 	HasDefault bool   // whether an explicit default was provided
@@ -208,6 +235,9 @@ func (p *Properties) String() string {
 	if p.proto3 {
 		s += ",proto3"
 	}
+	if p.oneof {
+		s += ",oneof"
+	}
 	if len(p.Enum) > 0 {
 		s += ",enum=" + p.Enum
 	}
@@ -284,6 +314,8 @@ func (p *Properties) Parse(s string) {
 			p.Enum = f[5:]
 		case f == "proto3":
 			p.proto3 = true
+		case f == "oneof":
+			p.oneof = true
 		case strings.HasPrefix(f, "def="):
 			p.HasDefault = true
 			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.dec = (*Buffer).dec_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.size = size_proto3_slice_byte
 			}
@@ -660,6 +697,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 		if f.Name == "XXX_unrecognized" { // special case
 			prop.unrecField = toField(&f)
 		}
+		oneof := f.Tag.Get("protobuf_oneof") != "" // special case
 		prop.Prop[i] = p
 		prop.order[i] = i
 		if debug {
@@ -669,7 +707,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 			}
 			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]")
 		}
 	}
@@ -677,6 +715,41 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 	// Re-order prop.order.
 	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 tags
 	reqCount := 0
@@ -735,3 +808,35 @@ func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[
 	}
 	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] }

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

@@ -37,11 +37,11 @@ import (
 	"bufio"
 	"bytes"
 	"encoding"
+	"errors"
 	"fmt"
 	"io"
 	"log"
 	"math"
-	"os"
 	"reflect"
 	"sort"
 	"strings"
@@ -170,20 +170,12 @@ func writeName(w *textWriter, props *Properties) error {
 	return nil
 }
 
-var (
-	messageSetType = reflect.TypeOf((*MessageSet)(nil)).Elem()
-)
-
 // raw is the interface satisfied by RawMessage.
 type raw interface {
 	Bytes() []byte
 }
 
 func writeStruct(w *textWriter, sv reflect.Value) error {
-	if sv.Type() == messageSetType {
-		return writeMessageSet(w, sv.Addr().Interface().(*MessageSet))
-	}
-
 	st := sv.Type()
 	sprops := GetProperties(st)
 	for i := 0; i < sv.NumField(); i++ {
@@ -246,7 +238,7 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
 		}
 		if fv.Kind() == reflect.Map {
 			// Map fields are rendered as a repeated struct with key/value fields.
-			keys := fv.MapKeys() // TODO: should we sort these for deterministic output?
+			keys := fv.MapKeys()
 			sort.Sort(mapKeys(keys))
 			for _, key := range keys {
 				val := fv.MapIndex(key)
@@ -283,20 +275,23 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
 				if err := w.WriteByte('\n'); err != nil {
 					return err
 				}
-				// value
-				if _, err := w.WriteString("value:"); err != nil {
-					return err
-				}
-				if !w.compact {
-					if err := w.WriteByte(' '); err != nil {
+				// 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
 					}
-				}
-				if err := writeAny(w, val, props.mvalprop); err != nil {
-					return err
-				}
-				if err := w.WriteByte('\n'); err != nil {
-					return err
 				}
 				// close struct
 				w.unindent()
@@ -315,26 +310,34 @@ func writeStruct(w *textWriter, sv reflect.Value) error {
 		}
 		if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice {
 			// proto3 non-repeated scalar field; skip if zero value
-			switch fv.Kind() {
-			case reflect.Bool:
-				if !fv.Bool() {
-					continue
-				}
-			case reflect.Int32, reflect.Int64:
-				if fv.Int() == 0 {
-					continue
-				}
-			case reflect.Uint32, reflect.Uint64:
-				if fv.Uint() == 0 {
+			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
 				}
-			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('"')
 }
 
-func writeMessageSet(w *textWriter, ms *MessageSet) error {
-	for _, item := range ms.Item {
-		id := *item.TypeId
-		if msd, ok := messageSetMap[id]; ok {
-			// Known message set type.
-			if _, err := fmt.Fprintf(w, "[%s]: <\n", msd.name); err != nil {
-				return err
-			}
-			w.indent()
-
-			pb := reflect.New(msd.t.Elem())
-			if err := Unmarshal(item.Message, pb.Interface().(Message)); err != nil {
-				if _, err := fmt.Fprintf(w, "/* bad message: %v */\n", err); err != nil {
-					return err
-				}
-			} else {
-				if err := writeStruct(w, pb.Elem()); err != nil {
-					return err
-				}
-			}
-		} else {
-			// Unknown type.
-			if _, err := fmt.Fprintf(w, "[%d]: <\n", id); err != nil {
-				return err
-			}
-			w.indent()
-			if err := writeUnknownStruct(w, item.Message); err != nil {
-				return err
-			}
-		}
-		w.unindent()
-		if _, err := w.Write(gtNewline); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
 func writeUnknownStruct(w *textWriter, data []byte) (err error) {
 	if !w.compact {
 		if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil {
@@ -666,10 +631,7 @@ func writeExtensions(w *textWriter, pv reflect.Value) error {
 
 		pb, err := GetExtension(ep, desc)
 		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.

+ 135 - 94
vendor/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]))
 		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
 		}
 		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.
-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]
 	if ok {
 		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 {
 	st := sv.Type()
-	reqCount := GetProperties(st).reqCount
+	sprops := GetProperties(st)
+	reqCount := sprops.reqCount
 	var reqFieldErr error
 	fieldSet := make(map[string]bool)
 	// 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)
 				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
 			}
-
-			// 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 {
@@ -621,6 +635,19 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 	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 {
 	tok := p.next()
 	if tok.err != nil {
@@ -645,18 +672,32 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 			fv.Set(reflect.ValueOf(bytes))
 			return nil
 		}
-		// Repeated field. May already exist.
-		flen := fv.Len()
-		if flen == fv.Cap() {
-			nav := reflect.MakeSlice(at, flen, 2*flen+1)
-			reflect.Copy(nav, fv)
-			fv.Set(nav)
+		// 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()
-		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:
 		// Either "true", "false", 1 or 0.
 		switch tok.value {

+ 1 - 1
vendor/src/google.golang.org/grpc/Makefile

@@ -47,4 +47,4 @@ clean:
 	go clean google.golang.org/grpc/...
 
 coverage: testdeps
-	goveralls -v google.golang.org/grpc/...
+	./coverage.sh --coveralls

+ 77 - 34
vendor/src/google.golang.org/grpc/clientconn.go

@@ -89,6 +89,12 @@ func WithCodec(c Codec) DialOption {
 	}
 }
 
+func WithPicker(p Picker) DialOption {
+	return func(o *dialOptions) {
+		o.picker = p
+	}
+}
+
 // WithBlock returns a DialOption which makes caller of Dial blocks until the underlying
 // connection is up. Without this, Dial returns immediately and connecting the server
 // happens in background.
@@ -154,7 +160,9 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) {
 		cc.dopts.codec = protoCodec{}
 	}
 	if cc.dopts.picker == nil {
-		cc.dopts.picker = &unicastPicker{}
+		cc.dopts.picker = &unicastPicker{
+			target: target,
+		}
 	}
 	if err := cc.dopts.picker.Init(cc); err != nil {
 		return nil, err
@@ -209,15 +217,15 @@ type ClientConn struct {
 
 // State returns the connectivity state of cc.
 // This is EXPERIMENTAL API.
-func (cc *ClientConn) State() ConnectivityState {
+func (cc *ClientConn) State() (ConnectivityState, error) {
 	return cc.dopts.picker.State()
 }
 
-// WaitForStateChange blocks until the state changes to something other than the sourceState
-// or timeout fires on cc. It returns false if timeout fires, and true otherwise.
+// WaitForStateChange blocks until the state changes to something other than the sourceState.
+// It returns the new state or error.
 // This is EXPERIMENTAL API.
-func (cc *ClientConn) WaitForStateChange(timeout time.Duration, sourceState ConnectivityState) bool {
-	return cc.dopts.picker.WaitForStateChange(timeout, sourceState)
+func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) {
+	return cc.dopts.picker.WaitForStateChange(ctx, sourceState)
 }
 
 // Close starts to tear down the ClientConn.
@@ -229,6 +237,7 @@ func (cc *ClientConn) Close() error {
 type Conn struct {
 	target       string
 	dopts        dialOptions
+	resetChan    chan int
 	shutdownChan chan struct{}
 	events       trace.EventLog
 
@@ -249,6 +258,7 @@ func NewConn(cc *ClientConn) (*Conn, error) {
 	c := &Conn{
 		target:       cc.target,
 		dopts:        cc.dopts,
+		resetChan:    make(chan int, 1),
 		shutdownChan: make(chan struct{}),
 	}
 	if EnableTracing {
@@ -317,26 +327,20 @@ func (cc *Conn) State() ConnectivityState {
 	return cc.state
 }
 
-// WaitForStateChange blocks until the state changes to something other than the sourceState
-// or timeout fires. It returns false if timeout fires and true otherwise.
-// TODO(zhaoq): Rewrite for complex Picker.
-func (cc *Conn) WaitForStateChange(timeout time.Duration, sourceState ConnectivityState) bool {
-	start := time.Now()
+// WaitForStateChange blocks until the state changes to something other than the sourceState.
+func (cc *Conn) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) {
 	cc.mu.Lock()
 	defer cc.mu.Unlock()
 	if sourceState != cc.state {
-		return true
-	}
-	expired := timeout <= time.Since(start)
-	if expired {
-		return false
+		return cc.state, nil
 	}
 	done := make(chan struct{})
+	var err error
 	go func() {
 		select {
-		case <-time.After(timeout - time.Since(start)):
+		case <-ctx.Done():
 			cc.mu.Lock()
-			expired = true
+			err = ctx.Err()
 			cc.stateCV.Broadcast()
 			cc.mu.Unlock()
 		case <-done:
@@ -345,11 +349,20 @@ func (cc *Conn) WaitForStateChange(timeout time.Duration, sourceState Connectivi
 	defer close(done)
 	for sourceState == cc.state {
 		cc.stateCV.Wait()
-		if expired {
-			return false
+		if err != nil {
+			return cc.state, err
 		}
 	}
-	return true
+	return cc.state, nil
+}
+
+// NotifyReset tries to signal the underlying transport needs to be reset due to
+// for example a name resolution change in flight.
+func (cc *Conn) NotifyReset() {
+	select {
+	case cc.resetChan <- 0:
+	default:
+	}
 }
 
 func (cc *Conn) resetTransport(closeTransport bool) error {
@@ -359,6 +372,7 @@ func (cc *Conn) resetTransport(closeTransport bool) error {
 		cc.mu.Lock()
 		cc.printf("connecting")
 		if cc.state == Shutdown {
+			// cc.Close() has been invoked.
 			cc.mu.Unlock()
 			return ErrClientConnClosing
 		}
@@ -390,9 +404,18 @@ func (cc *Conn) resetTransport(closeTransport bool) error {
 			copts.Timeout = timeout
 		}
 		connectTime := time.Now()
-		newTransport, err := transport.NewClientTransport(cc.target, &copts)
+		addr, err := cc.dopts.picker.PickAddr()
+		var newTransport transport.ClientTransport
+		if err == nil {
+			newTransport, err = transport.NewClientTransport(addr, &copts)
+		}
 		if err != nil {
 			cc.mu.Lock()
+			if cc.state == Shutdown {
+				// cc.Close() has been invoked.
+				cc.mu.Unlock()
+				return ErrClientConnClosing
+			}
 			cc.errorf("transient failure: %v", err)
 			cc.state = TransientFailure
 			cc.stateCV.Broadcast()
@@ -416,7 +439,7 @@ func (cc *Conn) resetTransport(closeTransport bool) error {
 			closeTransport = false
 			time.Sleep(sleepTime)
 			retries++
-			grpclog.Printf("grpc: ClientConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, cc.target)
+			grpclog.Printf("grpc: Conn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, cc.target)
 			continue
 		}
 		cc.mu.Lock()
@@ -439,6 +462,27 @@ func (cc *Conn) resetTransport(closeTransport bool) error {
 	}
 }
 
+func (cc *Conn) reconnect() bool {
+	cc.mu.Lock()
+	if cc.state == Shutdown {
+		// cc.Close() has been invoked.
+		cc.mu.Unlock()
+		return false
+	}
+	cc.state = TransientFailure
+	cc.stateCV.Broadcast()
+	cc.mu.Unlock()
+	if err := cc.resetTransport(true); err != nil {
+		// The ClientConn is closing.
+		cc.mu.Lock()
+		cc.printf("transport exiting: %v", err)
+		cc.mu.Unlock()
+		grpclog.Printf("grpc: Conn.transportMonitor exits due to: %v", err)
+		return false
+	}
+	return true
+}
+
 // Run in a goroutine to track the error in transport and create the
 // new transport if an error happens. It returns when the channel is closing.
 func (cc *Conn) transportMonitor() {
@@ -448,20 +492,19 @@ func (cc *Conn) transportMonitor() {
 		// the ClientConn is idle (i.e., no RPC in flight).
 		case <-cc.shutdownChan:
 			return
+		case <-cc.resetChan:
+			if !cc.reconnect() {
+				return
+			}
 		case <-cc.transport.Error():
-			cc.mu.Lock()
-			cc.state = TransientFailure
-			cc.stateCV.Broadcast()
-			cc.mu.Unlock()
-			if err := cc.resetTransport(true); err != nil {
-				// The ClientConn is closing.
-				cc.mu.Lock()
-				cc.printf("transport exiting: %v", err)
-				cc.mu.Unlock()
-				grpclog.Printf("grpc: ClientConn.transportMonitor exits due to: %v", err)
+			if !cc.reconnect() {
 				return
 			}
-			continue
+			// Tries to drain reset signal if there is any since it is out-dated.
+			select {
+			case <-cc.resetChan:
+			default:
+			}
 		}
 	}
 }

+ 40 - 0
vendor/src/google.golang.org/grpc/coverage.sh

@@ -0,0 +1,40 @@
+#!/bin/bash
+
+set -e
+
+workdir=.cover
+profile="$workdir/cover.out"
+mode=count
+
+generate_cover_data() {
+    rm -rf "$workdir"
+    mkdir "$workdir"
+
+    for pkg in "$@"; do
+        f="$workdir/$(echo $pkg | tr / -).cover"
+        go test -covermode="$mode" -coverprofile="$f" "$pkg"
+    done
+
+    echo "mode: $mode" >"$profile"
+    grep -h -v "^mode:" "$workdir"/*.cover >>"$profile"
+}
+
+show_cover_report() {
+    go tool cover -${1}="$profile"
+}
+
+push_to_coveralls() {
+    goveralls -coverprofile="$profile"
+}
+
+generate_cover_data $(go list ./...)
+show_cover_report func
+case "$1" in
+"")
+    ;;
+--coveralls)
+    push_to_coveralls ;;
+*)
+    echo >&2 "error: invalid option: $1" ;;
+esac
+rm -rf "$workdir"

+ 6 - 18
vendor/src/google.golang.org/grpc/metadata/metadata.go

@@ -46,27 +46,16 @@ const (
 	binHdrSuffix = "-bin"
 )
 
-// grpc-http2 requires ASCII header key and value (more detail can be found in
-// "Requests" subsection in go/grpc-http2).
-func isASCII(s string) bool {
-	for _, c := range s {
-		if c > 127 {
-			return false
-		}
-	}
-	return true
-}
-
 // encodeKeyValue encodes key and value qualified for transmission via gRPC.
 // Transmitting binary headers violates HTTP/2 spec.
 // TODO(zhaoq): Maybe check if k is ASCII also.
 func encodeKeyValue(k, v string) (string, string) {
-	if isASCII(v) {
-		return k, v
+	k = strings.ToLower(k)
+	if strings.HasSuffix(k, binHdrSuffix) {
+		val := base64.StdEncoding.EncodeToString([]byte(v))
+		v = string(val)
 	}
-	key := strings.ToLower(k + binHdrSuffix)
-	val := base64.StdEncoding.EncodeToString([]byte(v))
-	return key, string(val)
+	return k, v
 }
 
 // DecodeKeyValue returns the original key and value corresponding to the
@@ -75,12 +64,11 @@ func DecodeKeyValue(k, v string) (string, string, error) {
 	if !strings.HasSuffix(k, binHdrSuffix) {
 		return k, v, nil
 	}
-	key := k[:len(k)-len(binHdrSuffix)]
 	val, err := base64.StdEncoding.DecodeString(v)
 	if err != nil {
 		return "", "", err
 	}
-	return key, string(val), nil
+	return k, string(val), nil
 }
 
 // MD is a mapping from metadata keys to values. Users should use the following

+ 73 - 0
vendor/src/google.golang.org/grpc/naming/naming.go

@@ -0,0 +1,73 @@
+/*
+ *
+ * Copyright 2014, Google Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+// Package naming defines the naming API and related data structures for gRPC.
+// The interface is EXPERIMENTAL and may be suject to change.
+package naming
+
+// Operation defines the corresponding operations for a name resolution change.
+type Operation uint8
+
+const (
+	// Add indicates a new address is added.
+	Add Operation = iota
+	// Delete indicates an exisiting address is deleted.
+	Delete
+)
+
+// Update defines a name resolution update. Notice that it is not valid having both
+// empty string Addr and nil Metadata in an Update.
+type Update struct {
+	// Op indicates the operation of the update.
+	Op Operation
+	// Addr is the updated address. It is empty string if there is no address update.
+	Addr string
+	// Metadata is the updated metadata. It is nil if there is no metadata update.
+	// Metadata is not required for a custom naming implementation.
+	Metadata interface{}
+}
+
+// Resolver creates a Watcher for a target to track its resolution changes.
+type Resolver interface {
+	// Resolve creates a Watcher for target.
+	Resolve(target string) (Watcher, error)
+}
+
+// Watcher watches for the updates on the specified target.
+type Watcher interface {
+	// Next blocks until an update or error happens. It may return one or more
+	// updates. The first call should get the full set of the results.
+	Next() ([]*Update, error)
+	// Close closes the Watcher.
+	Close()
+}

+ 160 - 10
vendor/src/google.golang.org/grpc/picker.go

@@ -34,9 +34,13 @@
 package grpc
 
 import (
-	"time"
+	"container/list"
+	"fmt"
+	"sync"
 
 	"golang.org/x/net/context"
+	"google.golang.org/grpc/grpclog"
+	"google.golang.org/grpc/naming"
 	"google.golang.org/grpc/transport"
 )
 
@@ -48,12 +52,14 @@ type Picker interface {
 	// Pick blocks until either a transport.ClientTransport is ready for the upcoming RPC
 	// or some error happens.
 	Pick(ctx context.Context) (transport.ClientTransport, error)
+	// PickAddr picks a peer address for connecting. This will be called repeated for
+	// connecting/reconnecting.
+	PickAddr() (string, error)
 	// State returns the connectivity state of the underlying connections.
-	State() ConnectivityState
+	State() (ConnectivityState, error)
 	// WaitForStateChange blocks until the state changes to something other than
-	// the sourceState or timeout fires on cc. It returns false if timeout fires,
-	// and true otherwise.
-	WaitForStateChange(timeout time.Duration, sourceState ConnectivityState) bool
+	// the sourceState. It returns the new state or error.
+	WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error)
 	// Close closes all the Conn's owned by this Picker.
 	Close() error
 }
@@ -61,7 +67,8 @@ type Picker interface {
 // unicastPicker is the default Picker which is used when there is no custom Picker
 // specified by users. It always picks the same Conn.
 type unicastPicker struct {
-	conn *Conn
+	target string
+	conn   *Conn
 }
 
 func (p *unicastPicker) Init(cc *ClientConn) error {
@@ -77,12 +84,16 @@ func (p *unicastPicker) Pick(ctx context.Context) (transport.ClientTransport, er
 	return p.conn.Wait(ctx)
 }
 
-func (p *unicastPicker) State() ConnectivityState {
-	return p.conn.State()
+func (p *unicastPicker) PickAddr() (string, error) {
+	return p.target, nil
 }
 
-func (p *unicastPicker) WaitForStateChange(timeout time.Duration, sourceState ConnectivityState) bool {
-	return p.conn.WaitForStateChange(timeout, sourceState)
+func (p *unicastPicker) State() (ConnectivityState, error) {
+	return p.conn.State(), nil
+}
+
+func (p *unicastPicker) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) {
+	return p.conn.WaitForStateChange(ctx, sourceState)
 }
 
 func (p *unicastPicker) Close() error {
@@ -91,3 +102,142 @@ func (p *unicastPicker) Close() error {
 	}
 	return nil
 }
+
+// unicastNamingPicker picks an address from a name resolver to set up the connection.
+type unicastNamingPicker struct {
+	cc       *ClientConn
+	resolver naming.Resolver
+	watcher  naming.Watcher
+	mu       sync.Mutex
+	// The list of the addresses are obtained from watcher.
+	addrs *list.List
+	// It tracks the current picked addr by PickAddr(). The next PickAddr may
+	// push it forward on addrs.
+	pickedAddr *list.Element
+	conn       *Conn
+}
+
+// NewUnicastNamingPicker creates a Picker to pick addresses from a name resolver
+// to connect.
+func NewUnicastNamingPicker(r naming.Resolver) Picker {
+	return &unicastNamingPicker{
+		resolver: r,
+		addrs:    list.New(),
+	}
+}
+
+type addrInfo struct {
+	addr string
+	// Set to true if this addrInfo needs to be deleted in the next PickAddrr() call.
+	deleting bool
+}
+
+// processUpdates calls Watcher.Next() once and processes the obtained updates.
+func (p *unicastNamingPicker) processUpdates() error {
+	updates, err := p.watcher.Next()
+	if err != nil {
+		return err
+	}
+	for _, update := range updates {
+		switch update.Op {
+		case naming.Add:
+			p.mu.Lock()
+			p.addrs.PushBack(&addrInfo{
+				addr: update.Addr,
+			})
+			p.mu.Unlock()
+			// Initial connection setup
+			if p.conn == nil {
+				conn, err := NewConn(p.cc)
+				if err != nil {
+					return err
+				}
+				p.conn = conn
+			}
+		case naming.Delete:
+			p.mu.Lock()
+			for e := p.addrs.Front(); e != nil; e = e.Next() {
+				if update.Addr == e.Value.(*addrInfo).addr {
+					if e == p.pickedAddr {
+						// Do not remove the element now if it is the current picked
+						// one. We leave the deletion to the next PickAddr() call.
+						e.Value.(*addrInfo).deleting = true
+						// Notify Conn to close it. All the live RPCs on this connection
+						// will be aborted.
+						p.conn.NotifyReset()
+					} else {
+						p.addrs.Remove(e)
+					}
+				}
+			}
+			p.mu.Unlock()
+		default:
+			grpclog.Println("Unknown update.Op %d", update.Op)
+		}
+	}
+	return nil
+}
+
+// monitor runs in a standalone goroutine to keep watching name resolution updates until the watcher
+// is closed.
+func (p *unicastNamingPicker) monitor() {
+	for {
+		if err := p.processUpdates(); err != nil {
+			return
+		}
+	}
+}
+
+func (p *unicastNamingPicker) Init(cc *ClientConn) error {
+	w, err := p.resolver.Resolve(cc.target)
+	if err != nil {
+		return err
+	}
+	p.watcher = w
+	p.cc = cc
+	// Get the initial name resolution.
+	if err := p.processUpdates(); err != nil {
+		return err
+	}
+	go p.monitor()
+	return nil
+}
+
+func (p *unicastNamingPicker) Pick(ctx context.Context) (transport.ClientTransport, error) {
+	return p.conn.Wait(ctx)
+}
+
+func (p *unicastNamingPicker) PickAddr() (string, error) {
+	p.mu.Lock()
+	defer p.mu.Unlock()
+	if p.pickedAddr == nil {
+		p.pickedAddr = p.addrs.Front()
+	} else {
+		pa := p.pickedAddr
+		p.pickedAddr = pa.Next()
+		if pa.Value.(*addrInfo).deleting {
+			p.addrs.Remove(pa)
+		}
+		if p.pickedAddr == nil {
+			p.pickedAddr = p.addrs.Front()
+		}
+	}
+	if p.pickedAddr == nil {
+		return "", fmt.Errorf("there is no address available to pick")
+	}
+	return p.pickedAddr.Value.(*addrInfo).addr, nil
+}
+
+func (p *unicastNamingPicker) State() (ConnectivityState, error) {
+	return 0, fmt.Errorf("State() is not supported for unicastNamingPicker")
+}
+
+func (p *unicastNamingPicker) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) {
+	return 0, fmt.Errorf("WaitForStateChange is not supported for unicastNamingPciker")
+}
+
+func (p *unicastNamingPicker) Close() error {
+	p.watcher.Close()
+	p.conn.Close()
+	return nil
+}

+ 40 - 7
vendor/src/google.golang.org/grpc/server.go

@@ -410,11 +410,11 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
 		defer func() {
 			ss.mu.Lock()
 			if err != nil && err != io.EOF {
-				trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
-				trInfo.tr.SetError()
+				ss.trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
+				ss.trInfo.tr.SetError()
 			}
-			trInfo.tr.Finish()
-			trInfo.tr = nil
+			ss.trInfo.tr.Finish()
+			ss.trInfo.tr = nil
 			ss.mu.Unlock()
 		}()
 	}
@@ -430,10 +430,10 @@ func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transp
 	if trInfo != nil {
 		ss.mu.Lock()
 		if ss.statusCode != codes.OK {
-			trInfo.tr.LazyLog(stringer(ss.statusDesc), true)
-			trInfo.tr.SetError()
+			ss.trInfo.tr.LazyLog(stringer(ss.statusDesc), true)
+			ss.trInfo.tr.SetError()
 		} else {
-			trInfo.tr.LazyLog(stringer("OK"), false)
+			ss.trInfo.tr.LazyLog(stringer("OK"), false)
 		}
 		ss.mu.Unlock()
 	}
@@ -448,18 +448,40 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
 	}
 	pos := strings.LastIndex(sm, "/")
 	if pos == -1 {
+		if trInfo != nil {
+			trInfo.tr.LazyLog(&fmtStringer{"Malformed method name %q", []interface{}{sm}}, true)
+			trInfo.tr.SetError()
+		}
 		if err := t.WriteStatus(stream, codes.InvalidArgument, fmt.Sprintf("malformed method name: %q", stream.Method())); err != nil {
+			if trInfo != nil {
+				trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
+				trInfo.tr.SetError()
+			}
 			grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err)
 		}
+		if trInfo != nil {
+			trInfo.tr.Finish()
+		}
 		return
 	}
 	service := sm[:pos]
 	method := sm[pos+1:]
 	srv, ok := s.m[service]
 	if !ok {
+		if trInfo != nil {
+			trInfo.tr.LazyLog(&fmtStringer{"Unknown service %v", []interface{}{service}}, true)
+			trInfo.tr.SetError()
+		}
 		if err := t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown service %v", service)); err != nil {
+			if trInfo != nil {
+				trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
+				trInfo.tr.SetError()
+			}
 			grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err)
 		}
+		if trInfo != nil {
+			trInfo.tr.Finish()
+		}
 		return
 	}
 	// Unary RPC or Streaming RPC?
@@ -471,9 +493,20 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
 		s.processStreamingRPC(t, stream, srv, sd, trInfo)
 		return
 	}
+	if trInfo != nil {
+		trInfo.tr.LazyLog(&fmtStringer{"Unknown method %v", []interface{}{method}}, true)
+		trInfo.tr.SetError()
+	}
 	if err := t.WriteStatus(stream, codes.Unimplemented, fmt.Sprintf("unknown method %v", method)); err != nil {
+		if trInfo != nil {
+			trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
+			trInfo.tr.SetError()
+		}
 		grpclog.Printf("grpc: Server.handleStream failed to write status: %v", err)
 	}
+	if trInfo != nil {
+		trInfo.tr.Finish()
+	}
 }
 
 // Stop stops the gRPC server. Once Stop returns, the server stops accepting

+ 1 - 1
vendor/src/google.golang.org/grpc/stream.go

@@ -149,7 +149,7 @@ type clientStream struct {
 
 	tracing bool // set to EnableTracing when the clientStream is created.
 
-	mu sync.Mutex
+	mu     sync.Mutex
 	closed bool
 	// trInfo.tr is set when the clientStream is created (if EnableTracing is true),
 	// and is set to nil when the clientStream's finish method is called.

+ 2 - 1
vendor/src/google.golang.org/grpc/transport/control.go

@@ -86,7 +86,8 @@ func (flushIO) isItem() bool {
 }
 
 type ping struct {
-	ack bool
+	ack  bool
+	data [8]byte
 }
 
 func (ping) isItem() bool {

+ 5 - 5
vendor/src/google.golang.org/grpc/transport/http2_client.go

@@ -646,7 +646,9 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame) {
 }
 
 func (t *http2Client) handlePing(f *http2.PingFrame) {
-	t.controlBuf.put(&ping{true})
+	pingAck := &ping{ack: true}
+	copy(pingAck.data[:], f.Data[:])
+	t.controlBuf.put(pingAck)
 }
 
 func (t *http2Client) handleGoAway(f *http2.GoAwayFrame) {
@@ -751,7 +753,7 @@ func (t *http2Client) reader() {
 			endStream := frame.Header().Flags.Has(http2.FlagHeadersEndStream)
 			curStream = t.operateHeaders(hDec, curStream, frame, endStream)
 		case *http2.ContinuationFrame:
-			curStream = t.operateHeaders(hDec, curStream, frame, false)
+			curStream = t.operateHeaders(hDec, curStream, frame, frame.HeadersEnded())
 		case *http2.DataFrame:
 			t.handleData(frame)
 		case *http2.RSTStreamFrame:
@@ -827,9 +829,7 @@ func (t *http2Client) controller() {
 				case *flushIO:
 					t.framer.flushWrite()
 				case *ping:
-					// TODO(zhaoq): Ack with all-0 data now. will change to some
-					// meaningful content when this is actually in use.
-					t.framer.writePing(true, i.ack, [8]byte{})
+					t.framer.writePing(true, i.ack, i.data)
 				default:
 					grpclog.Printf("transport: http2Client.controller got unexpected item type %v\n", i)
 				}

+ 25 - 26
vendor/src/google.golang.org/grpc/transport/http2_server.go

@@ -163,22 +163,6 @@ func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame header
 	if !endHeaders {
 		return s
 	}
-	t.mu.Lock()
-	if t.state != reachable {
-		t.mu.Unlock()
-		return nil
-	}
-	if uint32(len(t.activeStreams)) >= t.maxStreams {
-		t.mu.Unlock()
-		t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream})
-		return nil
-	}
-	s.sendQuotaPool = newQuotaPool(int(t.streamSendQuota))
-	t.activeStreams[s.id] = s
-	t.mu.Unlock()
-	s.windowHandler = func(n int) {
-		t.updateWindow(s, uint32(n))
-	}
 	if hDec.state.timeoutSet {
 		s.ctx, s.cancel = context.WithTimeout(context.TODO(), hDec.state.timeout)
 	} else {
@@ -202,6 +186,22 @@ func (t *http2Server) operateHeaders(hDec *hpackDecoder, s *Stream, frame header
 		recv: s.buf,
 	}
 	s.method = hDec.state.method
+	t.mu.Lock()
+	if t.state != reachable {
+		t.mu.Unlock()
+		return nil
+	}
+	if uint32(len(t.activeStreams)) >= t.maxStreams {
+		t.mu.Unlock()
+		t.controlBuf.put(&resetStream{s.id, http2.ErrCodeRefusedStream})
+		return nil
+	}
+	s.sendQuotaPool = newQuotaPool(int(t.streamSendQuota))
+	t.activeStreams[s.id] = s
+	t.mu.Unlock()
+	s.windowHandler = func(n int) {
+		t.updateWindow(s, uint32(n))
+	}
 	handle(s)
 	return nil
 }
@@ -268,7 +268,7 @@ func (t *http2Server) HandleStreams(handle func(*Stream)) {
 			endStream := frame.Header().Flags.Has(http2.FlagHeadersEndStream)
 			curStream = t.operateHeaders(hDec, curStream, frame, endStream, handle)
 		case *http2.ContinuationFrame:
-			curStream = t.operateHeaders(hDec, curStream, frame, false, handle)
+			curStream = t.operateHeaders(hDec, curStream, frame, frame.HeadersEnded(), handle)
 		case *http2.DataFrame:
 			t.handleData(frame)
 		case *http2.RSTStreamFrame:
@@ -377,7 +377,9 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) {
 }
 
 func (t *http2Server) handlePing(f *http2.PingFrame) {
-	t.controlBuf.put(&ping{true})
+	pingAck := &ping{ack: true}
+	copy(pingAck.data[:], f.Data[:])
+	t.controlBuf.put(pingAck)
 }
 
 func (t *http2Server) handleWindowUpdate(f *http2.WindowUpdateFrame) {
@@ -628,9 +630,7 @@ func (t *http2Server) controller() {
 				case *flushIO:
 					t.framer.flushWrite()
 				case *ping:
-					// TODO(zhaoq): Ack with all-0 data now. will change to some
-					// meaningful content when this is actually in use.
-					t.framer.writePing(true, i.ack, [8]byte{})
+					t.framer.writePing(true, i.ack, i.data)
 				default:
 					grpclog.Printf("transport: http2Server.controller got unexpected item type %v\n", i)
 				}
@@ -660,9 +660,9 @@ func (t *http2Server) Close() (err error) {
 	t.mu.Unlock()
 	close(t.shutdownChan)
 	err = t.conn.Close()
-	// Notify all active streams.
+	// Cancel all active streams.
 	for _, s := range streams {
-		s.write(recvMsg{err: ErrConnClosing})
+		s.cancel()
 	}
 	return
 }
@@ -684,9 +684,8 @@ func (t *http2Server) closeStream(s *Stream) {
 	s.state = streamDone
 	s.mu.Unlock()
 	// In case stream sending and receiving are invoked in separate
-	// goroutines (e.g., bi-directional streaming), the caller needs
-	// to call cancel on the stream to interrupt the blocking on
-	// other goroutines.
+	// goroutines (e.g., bi-directional streaming), cancel needs to be
+	// called to interrupt the potential blocking on other goroutines.
 	s.cancel()
 }