Repository: moby/moby (language: go)

Issue:
Add make target (and verify step) to regenerate protobufs
The repository contains some code that was generated from `.proto` files, but we don't have a make target, nor a step in CI to check if those files need to be regenerated (for example when updating versions of gogo/protobuf or go/protobuf); see https://github.com/moby/moby/pull/40077#discussion_r336258155

We should add a make target to make it easy to regenerated those files, and a step in CI to verify the generated files 


Discussion / hints:

Fix patch:
diff --git a/Makefile b/Makefile
index 7d7f5404c25f6..dc95ad7eacf2a 100644
--- a/Makefile
+++ b/Makefile
@@ -214,6 +214,11 @@ test-unit: build ## run the unit tests
 validate: build ## validate DCO, Seccomp profile generation, gofmt,\n./pkg/ isolation, golint, tests, tomls, go vet and vendor
 	$(DOCKER_RUN_DOCKER) hack/validate/all
 
+validate-generate-files:
+	$(BUILD_CMD) --target "validate" \
+		--output "type=cacheonly" \
+		--file "./hack/dockerfiles/generate-files.Dockerfile" .
+
 validate-%: build ## validate specific check
 	$(DOCKER_RUN_DOCKER) hack/validate/$*
 
@@ -235,3 +240,12 @@ swagger-docs: ## preview the API documentation
 		-e 'REDOC_OPTIONS=hide-hostname="true" lazy-rendering' \
 		-p $(SWAGGER_DOCS_PORT):80 \
 		bfirsh/redoc:1.14.0
+
+.PHONY: generate-files
+generate-files:
+	$(eval $@_TMP_OUT := $(shell mktemp -d -t moby-output.XXXXXXXXXX))
+	$(BUILD_CMD) --target "update" \
+		--output "type=local,dest=$($@_TMP_OUT)" \
+		--file "./hack/dockerfiles/generate-files.Dockerfile" .
+	cp -R "$($@_TMP_OUT)"/. .
+	rm -rf "$($@_TMP_OUT)"/*
diff --git a/api/types/plugins/logdriver/entry.pb.go b/api/types/plugins/logdriver/entry.pb.go
index 5ced16895c6b9..167d1d5f88cd2 100644
--- a/api/types/plugins/logdriver/entry.pb.go
+++ b/api/types/plugins/logdriver/entry.pb.go
@@ -1,24 +1,15 @@
-// Code generated by protoc-gen-gogo.
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
 // source: entry.proto
-// DO NOT EDIT!
 
-/*
-	Package logdriver is a generated protocol buffer package.
-
-	It is generated from these files:
-		entry.proto
-
-	It has these top-level messages:
-		LogEntry
-		PartialLogEntryMetadata
-*/
 package logdriver
 
-import proto "github.com/gogo/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-import io "io"
+import (
+	fmt "fmt"
+	proto "github.com/gogo/protobuf/proto"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+)
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -29,20 +20,48 @@ var _ = math.Inf
 // is compatible with the proto package it is being compiled against.
 // A compilation error at this line likely means your copy of the
 // proto package needs to be updated.
-const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 
 type LogEntry struct {
 	Source             string                   `protobuf:"bytes,1,opt,name=source,proto3" json:"source,omitempty"`
 	TimeNano           int64                    `protobuf:"varint,2,opt,name=time_nano,json=timeNano,proto3" json:"time_nano,omitempty"`
 	Line               []byte                   `protobuf:"bytes,3,opt,name=line,proto3" json:"line,omitempty"`
 	Partial            bool                     `protobuf:"varint,4,opt,name=partial,proto3" json:"partial,omitempty"`
-	PartialLogMetadata *PartialLogEntryMetadata `protobuf:"bytes,5,opt,name=partial_log_metadata,json=partialLogMetadata" json:"partial_log_metadata,omitempty"`
+	PartialLogMetadata *PartialLogEntryMetadata `protobuf:"bytes,5,opt,name=partial_log_metadata,json=partialLogMetadata,proto3" json:"partial_log_metadata,omitempty"`
+}
+
+func (m *LogEntry) Reset()         { *m = LogEntry{} }
+func (m *LogEntry) String() string { return proto.CompactTextString(m) }
+func (*LogEntry) ProtoMessage()    {}
+func (*LogEntry) Descriptor() ([]byte, []int) {
+	return fileDescriptor_daa6c5b6c627940f, []int{0}
+}
+func (m *LogEntry) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *LogEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_LogEntry.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *LogEntry) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_LogEntry.Merge(m, src)
+}
+func (m *LogEntry) XXX_Size() int {
+	return m.Size()
+}
+func (m *LogEntry) XXX_DiscardUnknown() {
+	xxx_messageInfo_LogEntry.DiscardUnknown(m)
 }
 
-func (m *LogEntry) Reset()                    { *m = LogEntry{} }
-func (m *LogEntry) String() string            { return proto.CompactTextString(m) }
-func (*LogEntry) ProtoMessage()               {}
-func (*LogEntry) Descriptor() ([]byte, []int) { return fileDescriptorEntry, []int{0} }
+var xxx_messageInfo_LogEntry proto.InternalMessageInfo
 
 func (m *LogEntry) GetSource() string {
 	if m != nil {
@@ -85,10 +104,38 @@ type PartialLogEntryMetadata struct {
 	Ordinal int32  `protobuf:"varint,3,opt,name=ordinal,proto3" json:"ordinal,omitempty"`
 }
 
-func (m *PartialLogEntryMetadata) Reset()                    { *m = PartialLogEntryMetadata{} }
-func (m *PartialLogEntryMetadata) String() string            { return proto.CompactTextString(m) }
-func (*PartialLogEntryMetadata) ProtoMessage()               {}
-func (*PartialLogEntryMetadata) Descriptor() ([]byte, []int) { return fileDescriptorEntry, []int{1} }
+func (m *PartialLogEntryMetadata) Reset()         { *m = PartialLogEntryMetadata{} }
+func (m *PartialLogEntryMetadata) String() string { return proto.CompactTextString(m) }
+func (*PartialLogEntryMetadata) ProtoMessage()    {}
+func (*PartialLogEntryMetadata) Descriptor() ([]byte, []int) {
+	return fileDescriptor_daa6c5b6c627940f, []int{1}
+}
+func (m *PartialLogEntryMetadata) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *PartialLogEntryMetadata) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_PartialLogEntryMetadata.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *PartialLogEntryMetadata) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PartialLogEntryMetadata.Merge(m, src)
+}
+func (m *PartialLogEntryMetadata) XXX_Size() int {
+	return m.Size()
+}
+func (m *PartialLogEntryMetadata) XXX_DiscardUnknown() {
+	xxx_messageInfo_PartialLogEntryMetadata.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PartialLogEntryMetadata proto.InternalMessageInfo
 
 func (m *PartialLogEntryMetadata) GetLast() bool {
 	if m != nil {
@@ -115,10 +162,33 @@ func init() {
 	proto.RegisterType((*LogEntry)(nil), "LogEntry")
 	proto.RegisterType((*PartialLogEntryMetadata)(nil), "PartialLogEntryMetadata")
 }
+
+func init() { proto.RegisterFile("entry.proto", fileDescriptor_daa6c5b6c627940f) }
+
+var fileDescriptor_daa6c5b6c627940f = []byte{
+	// 250 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x90, 0xbd, 0x4a, 0x04, 0x31,
+	0x14, 0x85, 0xe7, 0xce, 0xfe, 0x38, 0x73, 0x57, 0x2c, 0x82, 0x68, 0x40, 0x08, 0x61, 0xab, 0x54,
+	0x5b, 0xe8, 0x1b, 0x08, 0x36, 0xa2, 0x22, 0x69, 0x2c, 0x87, 0xab, 0x13, 0x96, 0xc0, 0x6c, 0x32,
+	0x64, 0x63, 0xe1, 0x5b, 0xf8, 0x3a, 0xbe, 0x81, 0xe5, 0x96, 0x96, 0x32, 0xf3, 0x22, 0x32, 0x71,
+	0xc6, 0xce, 0xee, 0x9c, 0xf3, 0xa5, 0xf8, 0x72, 0x71, 0x65, 0x5c, 0x0c, 0x6f, 0x9b, 0x36, 0xf8,
+	0xe8, 0xd7, 0x1f, 0x80, 0xc5, 0x9d, 0xdf, 0xde, 0x0c, 0x13, 0x3b, 0xc3, 0xe5, 0xde, 0xbf, 0x86,
+	0x17, 0xc3, 0x41, 0x82, 0x2a, 0xf5, 0xd8, 0xd8, 0x05, 0x96, 0xd1, 0xee, 0x4c, 0xe5, 0xc8, 0x79,
+	0x9e, 0x4b, 0x50, 0x33, 0x5d, 0x0c, 0xc3, 0x03, 0x39, 0xcf, 0x18, 0xce, 0x1b, 0xeb, 0x0c, 0x9f,
+	0x49, 0x50, 0xc7, 0x3a, 0x65, 0xc6, 0xf1, 0xa8, 0xa5, 0x10, 0x2d, 0x35, 0x7c, 0x2e, 0x41, 0x15,
+	0x7a, 0xaa, 0xec, 0x16, 0x4f, 0xc7, 0x58, 0x35, 0x7e, 0x5b, 0xed, 0x4c, 0xa4, 0x9a, 0x22, 0xf1,
+	0x85, 0x04, 0xb5, 0xba, 0xe4, 0x9b, 0xc7, 0x5f, 0x38, 0x29, 0xdd, 0x8f, 0x5c, 0xb3, 0xf6, 0x0f,
+	0x4c, 0xdb, 0xfa, 0x09, 0xcf, 0xff, 0x79, 0x9e, 0xa4, 0x68, 0x1f, 0xd3, 0x3f, 0x0a, 0x9d, 0x32,
+	0x3b, 0xc1, 0xdc, 0xd6, 0x49, 0xbf, 0xd4, 0xb9, 0xad, 0x07, 0x49, 0x1f, 0x6a, 0xeb, 0xa8, 0x49,
+	0xee, 0x0b, 0x3d, 0xd5, 0x6b, 0xfe, 0xd9, 0x09, 0x38, 0x74, 0x02, 0xbe, 0x3b, 0x01, 0xef, 0xbd,
+	0xc8, 0x0e, 0xbd, 0xc8, 0xbe, 0x7a, 0x91, 0x3d, 0x2f, 0xd3, 0xd5, 0xae, 0x7e, 0x02, 0x00, 0x00,
+	0xff, 0xff, 0xbb, 0x82, 0x62, 0xd5, 0x44, 0x01, 0x00, 0x00,
+}
+
 func (m *LogEntry) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -126,54 +196,63 @@ func (m *LogEntry) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *LogEntry) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *LogEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if len(m.Source) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintEntry(dAtA, i, uint64(len(m.Source)))
-		i += copy(dAtA[i:], m.Source)
-	}
-	if m.TimeNano != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintEntry(dAtA, i, uint64(m.TimeNano))
-	}
-	if len(m.Line) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintEntry(dAtA, i, uint64(len(m.Line)))
-		i += copy(dAtA[i:], m.Line)
+	if m.PartialLogMetadata != nil {
+		{
+			size, err := m.PartialLogMetadata.MarshalToSizedBuffer(dAtA[:i])
+			if err != nil {
+				return 0, err
+			}
+			i -= size
+			i = encodeVarintEntry(dAtA, i, uint64(size))
+		}
+		i--
+		dAtA[i] = 0x2a
 	}
 	if m.Partial {
-		dAtA[i] = 0x20
-		i++
+		i--
 		if m.Partial {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
-		i++
+		i--
+		dAtA[i] = 0x20
 	}
-	if m.PartialLogMetadata != nil {
-		dAtA[i] = 0x2a
-		i++
-		i = encodeVarintEntry(dAtA, i, uint64(m.PartialLogMetadata.Size()))
-		n1, err := m.PartialLogMetadata.MarshalTo(dAtA[i:])
-		if err != nil {
-			return 0, err
-		}
-		i += n1
+	if len(m.Line) > 0 {
+		i -= len(m.Line)
+		copy(dAtA[i:], m.Line)
+		i = encodeVarintEntry(dAtA, i, uint64(len(m.Line)))
+		i--
+		dAtA[i] = 0x1a
+	}
+	if m.TimeNano != 0 {
+		i = encodeVarintEntry(dAtA, i, uint64(m.TimeNano))
+		i--
+		dAtA[i] = 0x10
+	}
+	if len(m.Source) > 0 {
+		i -= len(m.Source)
+		copy(dAtA[i:], m.Source)
+		i = encodeVarintEntry(dAtA, i, uint64(len(m.Source)))
+		i--
+		dAtA[i] = 0xa
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func (m *PartialLogEntryMetadata) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -181,62 +260,55 @@ func (m *PartialLogEntryMetadata) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *PartialLogEntryMetadata) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *PartialLogEntryMetadata) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
+	if m.Ordinal != 0 {
+		i = encodeVarintEntry(dAtA, i, uint64(m.Ordinal))
+		i--
+		dAtA[i] = 0x18
+	}
+	if len(m.Id) > 0 {
+		i -= len(m.Id)
+		copy(dAtA[i:], m.Id)
+		i = encodeVarintEntry(dAtA, i, uint64(len(m.Id)))
+		i--
+		dAtA[i] = 0x12
+	}
 	if m.Last {
-		dAtA[i] = 0x8
-		i++
+		i--
 		if m.Last {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
-		i++
-	}
-	if len(m.Id) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintEntry(dAtA, i, uint64(len(m.Id)))
-		i += copy(dAtA[i:], m.Id)
-	}
-	if m.Ordinal != 0 {
-		dAtA[i] = 0x18
-		i++
-		i = encodeVarintEntry(dAtA, i, uint64(m.Ordinal))
+		i--
+		dAtA[i] = 0x8
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
-func encodeFixed64Entry(dAtA []byte, offset int, v uint64) int {
-	dAtA[offset] = uint8(v)
-	dAtA[offset+1] = uint8(v >> 8)
-	dAtA[offset+2] = uint8(v >> 16)
-	dAtA[offset+3] = uint8(v >> 24)
-	dAtA[offset+4] = uint8(v >> 32)
-	dAtA[offset+5] = uint8(v >> 40)
-	dAtA[offset+6] = uint8(v >> 48)
-	dAtA[offset+7] = uint8(v >> 56)
-	return offset + 8
-}
-func encodeFixed32Entry(dAtA []byte, offset int, v uint32) int {
-	dAtA[offset] = uint8(v)
-	dAtA[offset+1] = uint8(v >> 8)
-	dAtA[offset+2] = uint8(v >> 16)
-	dAtA[offset+3] = uint8(v >> 24)
-	return offset + 4
-}
 func encodeVarintEntry(dAtA []byte, offset int, v uint64) int {
+	offset -= sovEntry(v)
+	base := offset
 	for v >= 1<<7 {
 		dAtA[offset] = uint8(v&0x7f | 0x80)
 		v >>= 7
 		offset++
 	}
 	dAtA[offset] = uint8(v)
-	return offset + 1
+	return base
 }
 func (m *LogEntry) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	l = len(m.Source)
@@ -261,6 +333,9 @@ func (m *LogEntry) Size() (n int) {
 }
 
 func (m *PartialLogEntryMetadata) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	if m.Last {
@@ -277,14 +352,7 @@ func (m *PartialLogEntryMetadata) Size() (n int) {
 }
 
 func sovEntry(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
+	return (math_bits.Len64(x|1) + 6) / 7
 }
 func sozEntry(x uint64) (n int) {
 	return sovEntry(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -304,7 +372,7 @@ func (m *LogEntry) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -332,7 +400,7 @@ func (m *LogEntry) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -342,6 +410,9 @@ func (m *LogEntry) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthEntry
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthEntry
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -361,7 +432,7 @@ func (m *LogEntry) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.TimeNano |= (int64(b) & 0x7F) << shift
+				m.TimeNano |= int64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -380,7 +451,7 @@ func (m *LogEntry) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
+				byteLen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -389,6 +460,9 @@ func (m *LogEntry) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthEntry
 			}
 			postIndex := iNdEx + byteLen
+			if postIndex < 0 {
+				return ErrInvalidLengthEntry
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -411,7 +485,7 @@ func (m *LogEntry) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= (int(b) & 0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -431,7 +505,7 @@ func (m *LogEntry) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
+				msglen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -440,6 +514,9 @@ func (m *LogEntry) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthEntry
 			}
 			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthEntry
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -456,7 +533,7 @@ func (m *LogEntry) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthEntry
 			}
 			if (iNdEx + skippy) > l {
@@ -486,7 +563,7 @@ func (m *PartialLogEntryMetadata) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -514,7 +591,7 @@ func (m *PartialLogEntryMetadata) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= (int(b) & 0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -534,7 +611,7 @@ func (m *PartialLogEntryMetadata) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -544,6 +621,9 @@ func (m *PartialLogEntryMetadata) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthEntry
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthEntry
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -563,7 +643,7 @@ func (m *PartialLogEntryMetadata) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.Ordinal |= (int32(b) & 0x7F) << shift
+				m.Ordinal |= int32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -574,7 +654,7 @@ func (m *PartialLogEntryMetadata) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthEntry
 			}
 			if (iNdEx + skippy) > l {
@@ -592,6 +672,7 @@ func (m *PartialLogEntryMetadata) Unmarshal(dAtA []byte) error {
 func skipEntry(dAtA []byte) (n int, err error) {
 	l := len(dAtA)
 	iNdEx := 0
+	depth := 0
 	for iNdEx < l {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
@@ -623,10 +704,8 @@ func skipEntry(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			return iNdEx, nil
 		case 1:
 			iNdEx += 8
-			return iNdEx, nil
 		case 2:
 			var length int
 			for shift := uint(0); ; shift += 7 {
@@ -643,74 +722,34 @@ func skipEntry(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			iNdEx += length
 			if length < 0 {
 				return 0, ErrInvalidLengthEntry
 			}
-			return iNdEx, nil
+			iNdEx += length
 		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowEntry
-					}
-					if iNdEx >= l {
-						return 0, io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					innerWire |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				innerWireType := int(innerWire & 0x7)
-				if innerWireType == 4 {
-					break
-				}
-				next, err := skipEntry(dAtA[start:])
-				if err != nil {
-					return 0, err
-				}
-				iNdEx = start + next
-			}
-			return iNdEx, nil
+			depth++
 		case 4:
-			return iNdEx, nil
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupEntry
+			}
+			depth--
 		case 5:
 			iNdEx += 4
-			return iNdEx, nil
 		default:
 			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
 		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthEntry
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
 	}
-	panic("unreachable")
+	return 0, io.ErrUnexpectedEOF
 }
 
 var (
-	ErrInvalidLengthEntry = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowEntry   = fmt.Errorf("proto: integer overflow")
+	ErrInvalidLengthEntry        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowEntry          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupEntry = fmt.Errorf("proto: unexpected end of group")
 )
-
-func init() { proto.RegisterFile("entry.proto", fileDescriptorEntry) }
-
-var fileDescriptorEntry = []byte{
-	// 237 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x74, 0x90, 0xbd, 0x4a, 0x04, 0x31,
-	0x14, 0x85, 0xb9, 0xb3, 0x3f, 0xce, 0xdc, 0x5d, 0x2c, 0x82, 0x68, 0x40, 0x18, 0xc2, 0x56, 0xa9,
-	0xb6, 0xd0, 0x37, 0x10, 0x6c, 0x44, 0x45, 0xd2, 0x58, 0x0e, 0x57, 0x27, 0x2c, 0x81, 0xd9, 0xdc,
-	0x21, 0x13, 0x0b, 0x1f, 0xcd, 0x37, 0xb0, 0xf4, 0x11, 0x64, 0x9e, 0x44, 0x26, 0x4e, 0xec, 0xec,
-	0xce, 0x39, 0x5f, 0x8a, 0x2f, 0x17, 0x37, 0xd6, 0xc7, 0xf0, 0xbe, 0xef, 0x03, 0x47, 0xde, 0x7d,
-	0x00, 0x96, 0xf7, 0x7c, 0xb8, 0x9d, 0x26, 0x71, 0x8e, 0xeb, 0x81, 0xdf, 0xc2, 0xab, 0x95, 0xa0,
-	0x40, 0x57, 0x66, 0x6e, 0xe2, 0x12, 0xab, 0xe8, 0x8e, 0xb6, 0xf1, 0xe4, 0x59, 0x16, 0x0a, 0xf4,
-	0xc2, 0x94, 0xd3, 0xf0, 0x48, 0x9e, 0x85, 0xc0, 0x65, 0xe7, 0xbc, 0x95, 0x0b, 0x05, 0x7a, 0x6b,
-	0x52, 0x16, 0x12, 0x4f, 0x7a, 0x0a, 0xd1, 0x51, 0x27, 0x97, 0x0a, 0x74, 0x69, 0x72, 0x15, 0x77,
-	0x78, 0x36, 0xc7, 0xa6, 0xe3, 0x43, 0x73, 0xb4, 0x91, 0x5a, 0x8a, 0x24, 0x57, 0x0a, 0xf4, 0xe6,
-	0x4a, 0xee, 0x9f, 0x7e, 0x61, 0x56, 0x7a, 0x98, 0xb9, 0x11, 0xfd, 0x1f, 0xc8, 0xdb, 0xee, 0x19,
-	0x2f, 0xfe, 0x79, 0x9e, 0xa4, 0x68, 0x88, 0xe9, 0x1f, 0xa5, 0x49, 0x59, 0x9c, 0x62, 0xe1, 0xda,
-	0xa4, 0x5f, 0x99, 0xc2, 0xb5, 0x93, 0x24, 0x87, 0xd6, 0x79, 0xea, 0x92, 0xfb, 0xca, 0xe4, 0x7a,
-	0xb3, 0xfd, 0x1c, 0x6b, 0xf8, 0x1a, 0x6b, 0xf8, 0x1e, 0x6b, 0x78, 0x59, 0xa7, 0x4b, 0x5d, 0xff,
-	0x04, 0x00, 0x00, 0xff, 0xff, 0x8f, 0xed, 0x9f, 0xb6, 0x38, 0x01, 0x00, 0x00,
-}
diff --git a/api/types/plugins/logdriver/gen.go b/api/types/plugins/logdriver/gen.go
index e5f10b5e0d8df..04d39c2f95039 100644
--- a/api/types/plugins/logdriver/gen.go
+++ b/api/types/plugins/logdriver/gen.go
@@ -1,3 +1,3 @@
-//go:generate protoc --gogofast_out=import_path=github.com/docker/docker/api/types/plugins/logdriver:. entry.proto
+//go:generate protoc --gogofaster_out=import_path=github.com/docker/docker/api/types/plugins/logdriver:. entry.proto
 
 package logdriver // import "github.com/docker/docker/api/types/plugins/logdriver"
diff --git a/api/types/swarm/runtime/gen.go b/api/types/swarm/runtime/gen.go
index 98c2806c31dc4..292bd7afc8d76 100644
--- a/api/types/swarm/runtime/gen.go
+++ b/api/types/swarm/runtime/gen.go
@@ -1,3 +1,3 @@
-//go:generate protoc -I . --gogofast_out=import_path=github.com/docker/docker/api/types/swarm/runtime:. plugin.proto
+//go:generate protoc --gogofaster_out=import_path=github.com/docker/docker/api/types/swarm/runtime:. plugin.proto
 
 package runtime // import "github.com/docker/docker/api/types/swarm/runtime"
diff --git a/api/types/swarm/runtime/plugin.pb.go b/api/types/swarm/runtime/plugin.pb.go
index e45045866a6ea..32aaf0d519904 100644
--- a/api/types/swarm/runtime/plugin.pb.go
+++ b/api/types/swarm/runtime/plugin.pb.go
@@ -1,23 +1,15 @@
 // Code generated by protoc-gen-gogo. DO NOT EDIT.
 // source: plugin.proto
 
-/*
-	Package runtime is a generated protocol buffer package.
-
-	It is generated from these files:
-		plugin.proto
-
-	It has these top-level messages:
-		PluginSpec
-		PluginPrivilege
-*/
 package runtime
 
-import proto "github.com/gogo/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-import io "io"
+import (
+	fmt "fmt"
+	proto "github.com/gogo/protobuf/proto"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+)
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -28,22 +20,50 @@ var _ = math.Inf
 // is compatible with the proto package it is being compiled against.
 // A compilation error at this line likely means your copy of the
 // proto package needs to be updated.
-const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 
 // PluginSpec defines the base payload which clients can specify for creating
 // a service with the plugin runtime.
 type PluginSpec struct {
 	Name       string             `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
 	Remote     string             `protobuf:"bytes,2,opt,name=remote,proto3" json:"remote,omitempty"`
-	Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges" json:"privileges,omitempty"`
+	Privileges []*PluginPrivilege `protobuf:"bytes,3,rep,name=privileges,proto3" json:"privileges,omitempty"`
 	Disabled   bool               `protobuf:"varint,4,opt,name=disabled,proto3" json:"disabled,omitempty"`
-	Env        []string           `protobuf:"bytes,5,rep,name=env" json:"env,omitempty"`
+	Env        []string           `protobuf:"bytes,5,rep,name=env,proto3" json:"env,omitempty"`
+}
+
+func (m *PluginSpec) Reset()         { *m = PluginSpec{} }
+func (m *PluginSpec) String() string { return proto.CompactTextString(m) }
+func (*PluginSpec) ProtoMessage()    {}
+func (*PluginSpec) Descriptor() ([]byte, []int) {
+	return fileDescriptor_22a625af4bc1cc87, []int{0}
+}
+func (m *PluginSpec) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *PluginSpec) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_PluginSpec.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *PluginSpec) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PluginSpec.Merge(m, src)
+}
+func (m *PluginSpec) XXX_Size() int {
+	return m.Size()
+}
+func (m *PluginSpec) XXX_DiscardUnknown() {
+	xxx_messageInfo_PluginSpec.DiscardUnknown(m)
 }
 
-func (m *PluginSpec) Reset()                    { *m = PluginSpec{} }
-func (m *PluginSpec) String() string            { return proto.CompactTextString(m) }
-func (*PluginSpec) ProtoMessage()               {}
-func (*PluginSpec) Descriptor() ([]byte, []int) { return fileDescriptorPlugin, []int{0} }
+var xxx_messageInfo_PluginSpec proto.InternalMessageInfo
 
 func (m *PluginSpec) GetName() string {
 	if m != nil {
@@ -85,13 +105,41 @@ func (m *PluginSpec) GetEnv() []string {
 type PluginPrivilege struct {
 	Name        string   `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
 	Description string   `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
-	Value       []string `protobuf:"bytes,3,rep,name=value" json:"value,omitempty"`
+	Value       []string `protobuf:"bytes,3,rep,name=value,proto3" json:"value,omitempty"`
 }
 
-func (m *PluginPrivilege) Reset()                    { *m = PluginPrivilege{} }
-func (m *PluginPrivilege) String() string            { return proto.CompactTextString(m) }
-func (*PluginPrivilege) ProtoMessage()               {}
-func (*PluginPrivilege) Descriptor() ([]byte, []int) { return fileDescriptorPlugin, []int{1} }
+func (m *PluginPrivilege) Reset()         { *m = PluginPrivilege{} }
+func (m *PluginPrivilege) String() string { return proto.CompactTextString(m) }
+func (*PluginPrivilege) ProtoMessage()    {}
+func (*PluginPrivilege) Descriptor() ([]byte, []int) {
+	return fileDescriptor_22a625af4bc1cc87, []int{1}
+}
+func (m *PluginPrivilege) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *PluginPrivilege) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_PluginPrivilege.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *PluginPrivilege) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PluginPrivilege.Merge(m, src)
+}
+func (m *PluginPrivilege) XXX_Size() int {
+	return m.Size()
+}
+func (m *PluginPrivilege) XXX_DiscardUnknown() {
+	xxx_messageInfo_PluginPrivilege.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PluginPrivilege proto.InternalMessageInfo
 
 func (m *PluginPrivilege) GetName() string {
 	if m != nil {
@@ -118,10 +166,32 @@ func init() {
 	proto.RegisterType((*PluginSpec)(nil), "PluginSpec")
 	proto.RegisterType((*PluginPrivilege)(nil), "PluginPrivilege")
 }
+
+func init() { proto.RegisterFile("plugin.proto", fileDescriptor_22a625af4bc1cc87) }
+
+var fileDescriptor_22a625af4bc1cc87 = []byte{
+	// 225 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0xc8, 0x29, 0x4d,
+	0xcf, 0xcc, 0xd3, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x57, 0x9a, 0xc1, 0xc8, 0xc5, 0x15, 0x00, 0x16,
+	0x08, 0x2e, 0x48, 0x4d, 0x16, 0x12, 0xe2, 0x62, 0xc9, 0x4b, 0xcc, 0x4d, 0x95, 0x60, 0x54, 0x60,
+	0xd4, 0xe0, 0x0c, 0x02, 0xb3, 0x85, 0xc4, 0xb8, 0xd8, 0x8a, 0x52, 0x73, 0xf3, 0x4b, 0x52, 0x25,
+	0x98, 0xc0, 0xa2, 0x50, 0x9e, 0x90, 0x01, 0x17, 0x57, 0x41, 0x51, 0x66, 0x59, 0x66, 0x4e, 0x6a,
+	0x7a, 0x6a, 0xb1, 0x04, 0xb3, 0x02, 0xb3, 0x06, 0xb7, 0x91, 0x80, 0x1e, 0xc4, 0xb0, 0x00, 0x98,
+	0x44, 0x10, 0x92, 0x1a, 0x21, 0x29, 0x2e, 0x8e, 0x94, 0xcc, 0xe2, 0xc4, 0xa4, 0x9c, 0xd4, 0x14,
+	0x09, 0x16, 0x05, 0x46, 0x0d, 0x8e, 0x20, 0x38, 0x5f, 0x48, 0x80, 0x8b, 0x39, 0x35, 0xaf, 0x4c,
+	0x82, 0x55, 0x81, 0x59, 0x83, 0x33, 0x08, 0xc4, 0x54, 0x8a, 0xe5, 0xe2, 0x47, 0x33, 0x0c, 0xab,
+	0xf3, 0x14, 0xb8, 0xb8, 0x53, 0x52, 0x8b, 0x93, 0x8b, 0x32, 0x0b, 0x4a, 0x32, 0xf3, 0xf3, 0xa0,
+	0x6e, 0x44, 0x16, 0x12, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d, 0x05, 0xbb, 0x91, 0x33,
+	0x08, 0xc2, 0x71, 0x92, 0x38, 0xf1, 0x48, 0x8e, 0xf1, 0xc2, 0x23, 0x39, 0xc6, 0x07, 0x8f, 0xe4,
+	0x18, 0x27, 0x3c, 0x96, 0x63, 0xb8, 0xf0, 0x58, 0x8e, 0xe1, 0xc6, 0x63, 0x39, 0x86, 0x24, 0x36,
+	0x70, 0xd0, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x37, 0xea, 0xe2, 0xca, 0x2a, 0x01, 0x00,
+	0x00,
+}
+
 func (m *PluginSpec) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -129,66 +199,69 @@ func (m *PluginSpec) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *PluginSpec) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *PluginSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintPlugin(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if len(m.Remote) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintPlugin(dAtA, i, uint64(len(m.Remote)))
-		i += copy(dAtA[i:], m.Remote)
-	}
-	if len(m.Privileges) > 0 {
-		for _, msg := range m.Privileges {
-			dAtA[i] = 0x1a
-			i++
-			i = encodeVarintPlugin(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
+	if len(m.Env) > 0 {
+		for iNdEx := len(m.Env) - 1; iNdEx >= 0; iNdEx-- {
+			i -= len(m.Env[iNdEx])
+			copy(dAtA[i:], m.Env[iNdEx])
+			i = encodeVarintPlugin(dAtA, i, uint64(len(m.Env[iNdEx])))
+			i--
+			dAtA[i] = 0x2a
 		}
 	}
 	if m.Disabled {
-		dAtA[i] = 0x20
-		i++
+		i--
 		if m.Disabled {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
-		i++
+		i--
+		dAtA[i] = 0x20
 	}
-	if len(m.Env) > 0 {
-		for _, s := range m.Env {
-			dAtA[i] = 0x2a
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
+	if len(m.Privileges) > 0 {
+		for iNdEx := len(m.Privileges) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.Privileges[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintPlugin(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x1a
 		}
 	}
-	return i, nil
+	if len(m.Remote) > 0 {
+		i -= len(m.Remote)
+		copy(dAtA[i:], m.Remote)
+		i = encodeVarintPlugin(dAtA, i, uint64(len(m.Remote)))
+		i--
+		dAtA[i] = 0x12
+	}
+	if len(m.Name) > 0 {
+		i -= len(m.Name)
+		copy(dAtA[i:], m.Name)
+		i = encodeVarintPlugin(dAtA, i, uint64(len(m.Name)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
 }
 
 func (m *PluginPrivilege) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -196,50 +269,56 @@ func (m *PluginPrivilege) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *PluginPrivilege) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *PluginPrivilege) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintPlugin(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
+	if len(m.Value) > 0 {
+		for iNdEx := len(m.Value) - 1; iNdEx >= 0; iNdEx-- {
+			i -= len(m.Value[iNdEx])
+			copy(dAtA[i:], m.Value[iNdEx])
+			i = encodeVarintPlugin(dAtA, i, uint64(len(m.Value[iNdEx])))
+			i--
+			dAtA[i] = 0x1a
+		}
 	}
 	if len(m.Description) > 0 {
-		dAtA[i] = 0x12
-		i++
+		i -= len(m.Description)
+		copy(dAtA[i:], m.Description)
 		i = encodeVarintPlugin(dAtA, i, uint64(len(m.Description)))
-		i += copy(dAtA[i:], m.Description)
+		i--
+		dAtA[i] = 0x12
 	}
-	if len(m.Value) > 0 {
-		for _, s := range m.Value {
-			dAtA[i] = 0x1a
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
+	if len(m.Name) > 0 {
+		i -= len(m.Name)
+		copy(dAtA[i:], m.Name)
+		i = encodeVarintPlugin(dAtA, i, uint64(len(m.Name)))
+		i--
+		dAtA[i] = 0xa
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func encodeVarintPlugin(dAtA []byte, offset int, v uint64) int {
+	offset -= sovPlugin(v)
+	base := offset
 	for v >= 1<<7 {
 		dAtA[offset] = uint8(v&0x7f | 0x80)
 		v >>= 7
 		offset++
 	}
 	dAtA[offset] = uint8(v)
-	return offset + 1
+	return base
 }
 func (m *PluginSpec) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	l = len(m.Name)
@@ -269,6 +348,9 @@ func (m *PluginSpec) Size() (n int) {
 }
 
 func (m *PluginPrivilege) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	l = len(m.Name)
@@ -289,14 +371,7 @@ func (m *PluginPrivilege) Size() (n int) {
 }
 
 func sovPlugin(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
+	return (math_bits.Len64(x|1) + 6) / 7
 }
 func sozPlugin(x uint64) (n int) {
 	return sovPlugin(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -316,7 +391,7 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -344,7 +419,7 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -354,6 +429,9 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthPlugin
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthPlugin
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -373,7 +451,7 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -383,6 +461,9 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthPlugin
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthPlugin
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -402,7 +483,7 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
+				msglen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -411,6 +492,9 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthPlugin
 			}
 			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthPlugin
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -433,7 +517,7 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= (int(b) & 0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -453,7 +537,7 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -463,6 +547,9 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthPlugin
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthPlugin
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -474,7 +561,7 @@ func (m *PluginSpec) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthPlugin
 			}
 			if (iNdEx + skippy) > l {
@@ -504,7 +591,7 @@ func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -532,7 +619,7 @@ func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -542,6 +629,9 @@ func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthPlugin
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthPlugin
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -561,7 +651,7 @@ func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -571,6 +661,9 @@ func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthPlugin
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthPlugin
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -590,7 +683,7 @@ func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -600,6 +693,9 @@ func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthPlugin
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthPlugin
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -611,7 +707,7 @@ func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthPlugin
 			}
 			if (iNdEx + skippy) > l {
@@ -629,6 +725,7 @@ func (m *PluginPrivilege) Unmarshal(dAtA []byte) error {
 func skipPlugin(dAtA []byte) (n int, err error) {
 	l := len(dAtA)
 	iNdEx := 0
+	depth := 0
 	for iNdEx < l {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
@@ -660,10 +757,8 @@ func skipPlugin(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			return iNdEx, nil
 		case 1:
 			iNdEx += 8
-			return iNdEx, nil
 		case 2:
 			var length int
 			for shift := uint(0); ; shift += 7 {
@@ -680,75 +775,34 @@ func skipPlugin(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			iNdEx += length
 			if length < 0 {
 				return 0, ErrInvalidLengthPlugin
 			}
-			return iNdEx, nil
+			iNdEx += length
 		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowPlugin
-					}
-					if iNdEx >= l {
-						return 0, io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					innerWire |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				innerWireType := int(innerWire & 0x7)
-				if innerWireType == 4 {
-					break
-				}
-				next, err := skipPlugin(dAtA[start:])
-				if err != nil {
-					return 0, err
-				}
-				iNdEx = start + next
-			}
-			return iNdEx, nil
+			depth++
 		case 4:
-			return iNdEx, nil
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupPlugin
+			}
+			depth--
 		case 5:
 			iNdEx += 4
-			return iNdEx, nil
 		default:
 			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
 		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthPlugin
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
 	}
-	panic("unreachable")
+	return 0, io.ErrUnexpectedEOF
 }
 
 var (
-	ErrInvalidLengthPlugin = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowPlugin   = fmt.Errorf("proto: integer overflow")
+	ErrInvalidLengthPlugin        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowPlugin          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupPlugin = fmt.Errorf("proto: unexpected end of group")
 )
-
-func init() { proto.RegisterFile("plugin.proto", fileDescriptorPlugin) }
-
-var fileDescriptorPlugin = []byte{
-	// 256 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x90, 0x4d, 0x4b, 0xc3, 0x30,
-	0x18, 0xc7, 0x89, 0xdd, 0xc6, 0xfa, 0x4c, 0x70, 0x04, 0x91, 0xe2, 0xa1, 0x94, 0x9d, 0x7a, 0x6a,
-	0x45, 0x2f, 0x82, 0x37, 0x0f, 0x9e, 0x47, 0xbc, 0x09, 0x1e, 0xd2, 0xf6, 0xa1, 0x06, 0x9b, 0x17,
-	0x92, 0xb4, 0xe2, 0x37, 0xf1, 0x23, 0x79, 0xf4, 0x23, 0x48, 0x3f, 0x89, 0x98, 0x75, 0x32, 0x64,
-	0xa7, 0xff, 0x4b, 0xc2, 0x9f, 0x1f, 0x0f, 0x9c, 0x9a, 0xae, 0x6f, 0x85, 0x2a, 0x8c, 0xd5, 0x5e,
-	0x6f, 0x3e, 0x08, 0xc0, 0x36, 0x14, 0x8f, 0x06, 0x6b, 0x4a, 0x61, 0xa6, 0xb8, 0xc4, 0x84, 0x64,
-	0x24, 0x8f, 0x59, 0xf0, 0xf4, 0x02, 0x16, 0x16, 0xa5, 0xf6, 0x98, 0x9c, 0x84, 0x76, 0x4a, 0xf4,
-	0x0a, 0xc0, 0x58, 0x31, 0x88, 0x0e, 0x5b, 0x74, 0x49, 0x94, 0x45, 0xf9, 0xea, 0x7a, 0x5d, 0xec,
-	0xc6, 0xb6, 0xfb, 0x07, 0x76, 0xf0, 0x87, 0x5e, 0xc2, 0xb2, 0x11, 0x8e, 0x57, 0x1d, 0x36, 0xc9,
-	0x2c, 0x23, 0xf9, 0x92, 0xfd, 0x65, 0xba, 0x86, 0x08, 0xd5, 0x90, 0xcc, 0xb3, 0x28, 0x8f, 0xd9,
-	0xaf, 0xdd, 0x3c, 0xc3, 0xd9, 0xbf, 0xb1, 0xa3, 0x78, 0x19, 0xac, 0x1a, 0x74, 0xb5, 0x15, 0xc6,
-	0x0b, 0xad, 0x26, 0xc6, 0xc3, 0x8a, 0x9e, 0xc3, 0x7c, 0xe0, 0x5d, 0x8f, 0x81, 0x31, 0x66, 0xbb,
-	0x70, 0xff, 0xf0, 0x39, 0xa6, 0xe4, 0x6b, 0x4c, 0xc9, 0xf7, 0x98, 0x92, 0xa7, 0xdb, 0x56, 0xf8,
-	0x97, 0xbe, 0x2a, 0x6a, 0x2d, 0xcb, 0x46, 0xd7, 0xaf, 0x68, 0xf7, 0xc2, 0x8d, 0x28, 0xfd, 0xbb,
-	0x41, 0x57, 0xba, 0x37, 0x6e, 0x65, 0x69, 0x7b, 0xe5, 0x85, 0xc4, 0xbb, 0x49, 0xab, 0x45, 0x38,
-	0xe4, 0xcd, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x99, 0xa8, 0xd9, 0x9b, 0x58, 0x01, 0x00, 0x00,
-}
diff --git a/api/types/swarm/runtime/plugin.proto b/api/types/swarm/runtime/plugin.proto
index 9ef169046b4fa..e311b36ba2cf5 100644
--- a/api/types/swarm/runtime/plugin.proto
+++ b/api/types/swarm/runtime/plugin.proto
@@ -1,7 +1,5 @@
 syntax = "proto3";
 
-option go_package = "github.com/docker/docker/api/types/swarm/runtime;runtime";
-
 // PluginSpec defines the base payload which clients can specify for creating
 // a service with the plugin runtime.
 message PluginSpec {
diff --git a/builder/remotecontext/tarsum.pb.go b/builder/remotecontext/tarsum.pb.go
index 1d23bbe65b13f..d41e6677d40fe 100644
--- a/builder/remotecontext/tarsum.pb.go
+++ b/builder/remotecontext/tarsum.pb.go
@@ -1,27 +1,18 @@
-// Code generated by protoc-gen-gogo.
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
 // source: tarsum.proto
-// DO NOT EDIT!
 
-/*
-Package remotecontext is a generated protocol buffer package.
-
-It is generated from these files:
-	tarsum.proto
-
-It has these top-level messages:
-	TarsumBackup
-*/
 package remotecontext
 
-import proto "github.com/gogo/protobuf/proto"
-import fmt "fmt"
-import math "math"
-
-import strings "strings"
-import reflect "reflect"
-import github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys"
-
-import io "io"
+import (
+	fmt "fmt"
+	proto "github.com/gogo/protobuf/proto"
+	github_com_gogo_protobuf_sortkeys "github.com/gogo/protobuf/sortkeys"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+	reflect "reflect"
+	strings "strings"
+)
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -32,15 +23,43 @@ var _ = math.Inf
 // is compatible with the proto package it is being compiled against.
 // A compilation error at this line likely means your copy of the
 // proto package needs to be updated.
-const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 
 type TarsumBackup struct {
-	Hashes map[string]string `protobuf:"bytes,1,rep,name=Hashes" json:"Hashes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+	Hashes map[string]string `protobuf:"bytes,1,rep,name=Hashes,proto3" json:"Hashes,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"`
+}
+
+func (m *TarsumBackup) Reset()      { *m = TarsumBackup{} }
+func (*TarsumBackup) ProtoMessage() {}
+func (*TarsumBackup) Descriptor() ([]byte, []int) {
+	return fileDescriptor_375be7466b474c4d, []int{0}
+}
+func (m *TarsumBackup) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *TarsumBackup) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_TarsumBackup.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *TarsumBackup) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TarsumBackup.Merge(m, src)
+}
+func (m *TarsumBackup) XXX_Size() int {
+	return m.Size()
+}
+func (m *TarsumBackup) XXX_DiscardUnknown() {
+	xxx_messageInfo_TarsumBackup.DiscardUnknown(m)
 }
 
-func (m *TarsumBackup) Reset()                    { *m = TarsumBackup{} }
-func (*TarsumBackup) ProtoMessage()               {}
-func (*TarsumBackup) Descriptor() ([]byte, []int) { return fileDescriptorTarsum, []int{0} }
+var xxx_messageInfo_TarsumBackup proto.InternalMessageInfo
 
 func (m *TarsumBackup) GetHashes() map[string]string {
 	if m != nil {
@@ -51,13 +70,31 @@ func (m *TarsumBackup) GetHashes() map[string]string {
 
 func init() {
 	proto.RegisterType((*TarsumBackup)(nil), "remotecontext.TarsumBackup")
+	proto.RegisterMapType((map[string]string)(nil), "remotecontext.TarsumBackup.HashesEntry")
+}
+
+func init() { proto.RegisterFile("tarsum.proto", fileDescriptor_375be7466b474c4d) }
+
+var fileDescriptor_375be7466b474c4d = []byte{
+	// 205 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x49, 0x2c, 0x2a,
+	0x2e, 0xcd, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x2d, 0x4a, 0xcd, 0xcd, 0x2f, 0x49,
+	0x4d, 0xce, 0xcf, 0x2b, 0x49, 0xad, 0x28, 0x51, 0xea, 0x62, 0xe4, 0xe2, 0x09, 0x01, 0xcb, 0x3b,
+	0x25, 0x26, 0x67, 0x97, 0x16, 0x08, 0xd9, 0x73, 0xb1, 0x79, 0x24, 0x16, 0x67, 0xa4, 0x16, 0x4b,
+	0x30, 0x2a, 0x30, 0x6b, 0x70, 0x1b, 0xa9, 0xeb, 0xa1, 0x68, 0xd0, 0x43, 0x56, 0xac, 0x07, 0x51,
+	0xe9, 0x9a, 0x57, 0x52, 0x54, 0x19, 0x04, 0xd5, 0x26, 0x65, 0xc9, 0xc5, 0x8d, 0x24, 0x2c, 0x24,
+	0xc0, 0xc5, 0x9c, 0x9d, 0x5a, 0x29, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x19, 0x04, 0x62, 0x0a, 0x89,
+	0x70, 0xb1, 0x96, 0x25, 0xe6, 0x94, 0xa6, 0x4a, 0x30, 0x81, 0xc5, 0x20, 0x1c, 0x2b, 0x26, 0x0b,
+	0x46, 0x27, 0x93, 0x0b, 0x0f, 0xe5, 0x18, 0x6e, 0x3c, 0x94, 0x63, 0xf8, 0xf0, 0x50, 0x8e, 0xb1,
+	0xe1, 0x91, 0x1c, 0xe3, 0x8a, 0x47, 0x72, 0x8c, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7,
+	0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x8b, 0x47, 0x72, 0x0c, 0x1f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c,
+	0xc7, 0x70, 0xe1, 0xb1, 0x1c, 0xc3, 0x8d, 0xc7, 0x72, 0x0c, 0x49, 0x6c, 0x60, 0x8f, 0x19, 0x03,
+	0x02, 0x00, 0x00, 0xff, 0xff, 0x9e, 0xc6, 0xaf, 0xd0, 0xe8, 0x00, 0x00, 0x00,
 }
+
 func (this *TarsumBackup) Equal(that interface{}) bool {
 	if that == nil {
-		if this == nil {
-			return true
-		}
-		return false
+		return this == nil
 	}
 
 	that1, ok := that.(*TarsumBackup)
@@ -70,10 +107,7 @@ func (this *TarsumBackup) Equal(that interface{}) bool {
 		}
 	}
 	if that1 == nil {
-		if this == nil {
-			return true
-		}
-		return false
+		return this == nil
 	} else if this == nil {
 		return false
 	}
@@ -94,7 +128,7 @@ func (this *TarsumBackup) GoString() string {
 	s := make([]string, 0, 5)
 	s = append(s, "&remotecontext.TarsumBackup{")
 	keysForHashes := make([]string, 0, len(this.Hashes))
-	for k := range this.Hashes {
+	for k, _ := range this.Hashes {
 		keysForHashes = append(keysForHashes, k)
 	}
 	github_com_gogo_protobuf_sortkeys.Strings(keysForHashes)
@@ -120,7 +154,7 @@ func valueToGoStringTarsum(v interface{}, typ string) string {
 func (m *TarsumBackup) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -128,58 +162,52 @@ func (m *TarsumBackup) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *TarsumBackup) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *TarsumBackup) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
 	if len(m.Hashes) > 0 {
 		for k := range m.Hashes {
-			dAtA[i] = 0xa
-			i++
 			v := m.Hashes[k]
-			mapSize := 1 + len(k) + sovTarsum(uint64(len(k))) + 1 + len(v) + sovTarsum(uint64(len(v)))
-			i = encodeVarintTarsum(dAtA, i, uint64(mapSize))
-			dAtA[i] = 0xa
-			i++
-			i = encodeVarintTarsum(dAtA, i, uint64(len(k)))
-			i += copy(dAtA[i:], k)
-			dAtA[i] = 0x12
-			i++
+			baseI := i
+			i -= len(v)
+			copy(dAtA[i:], v)
 			i = encodeVarintTarsum(dAtA, i, uint64(len(v)))
-			i += copy(dAtA[i:], v)
+			i--
+			dAtA[i] = 0x12
+			i -= len(k)
+			copy(dAtA[i:], k)
+			i = encodeVarintTarsum(dAtA, i, uint64(len(k)))
+			i--
+			dAtA[i] = 0xa
+			i = encodeVarintTarsum(dAtA, i, uint64(baseI-i))
+			i--
+			dAtA[i] = 0xa
 		}
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
-func encodeFixed64Tarsum(dAtA []byte, offset int, v uint64) int {
-	dAtA[offset] = uint8(v)
-	dAtA[offset+1] = uint8(v >> 8)
-	dAtA[offset+2] = uint8(v >> 16)
-	dAtA[offset+3] = uint8(v >> 24)
-	dAtA[offset+4] = uint8(v >> 32)
-	dAtA[offset+5] = uint8(v >> 40)
-	dAtA[offset+6] = uint8(v >> 48)
-	dAtA[offset+7] = uint8(v >> 56)
-	return offset + 8
-}
-func encodeFixed32Tarsum(dAtA []byte, offset int, v uint32) int {
-	dAtA[offset] = uint8(v)
-	dAtA[offset+1] = uint8(v >> 8)
-	dAtA[offset+2] = uint8(v >> 16)
-	dAtA[offset+3] = uint8(v >> 24)
-	return offset + 4
-}
 func encodeVarintTarsum(dAtA []byte, offset int, v uint64) int {
+	offset -= sovTarsum(v)
+	base := offset
 	for v >= 1<<7 {
 		dAtA[offset] = uint8(v&0x7f | 0x80)
 		v >>= 7
 		offset++
 	}
 	dAtA[offset] = uint8(v)
-	return offset + 1
+	return base
 }
 func (m *TarsumBackup) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	if len(m.Hashes) > 0 {
@@ -194,14 +222,7 @@ func (m *TarsumBackup) Size() (n int) {
 }
 
 func sovTarsum(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
+	return (math_bits.Len64(x|1) + 6) / 7
 }
 func sozTarsum(x uint64) (n int) {
 	return sovTarsum(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -211,7 +232,7 @@ func (this *TarsumBackup) String() string {
 		return "nil"
 	}
 	keysForHashes := make([]string, 0, len(this.Hashes))
-	for k := range this.Hashes {
+	for k, _ := range this.Hashes {
 		keysForHashes = append(keysForHashes, k)
 	}
 	github_com_gogo_protobuf_sortkeys.Strings(keysForHashes)
@@ -249,7 +270,7 @@ func (m *TarsumBackup) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -277,7 +298,7 @@ func (m *TarsumBackup) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
+				msglen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -286,54 +307,20 @@ func (m *TarsumBackup) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthTarsum
 			}
 			postIndex := iNdEx + msglen
-			if postIndex > l {
-				return io.ErrUnexpectedEOF
-			}
-			var keykey uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowTarsum
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				keykey |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			var stringLenmapkey uint64
-			for shift := uint(0); ; shift += 7 {
-				if shift >= 64 {
-					return ErrIntOverflowTarsum
-				}
-				if iNdEx >= l {
-					return io.ErrUnexpectedEOF
-				}
-				b := dAtA[iNdEx]
-				iNdEx++
-				stringLenmapkey |= (uint64(b) & 0x7F) << shift
-				if b < 0x80 {
-					break
-				}
-			}
-			intStringLenmapkey := int(stringLenmapkey)
-			if intStringLenmapkey < 0 {
+			if postIndex < 0 {
 				return ErrInvalidLengthTarsum
 			}
-			postStringIndexmapkey := iNdEx + intStringLenmapkey
-			if postStringIndexmapkey > l {
+			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
-			mapkey := string(dAtA[iNdEx:postStringIndexmapkey])
-			iNdEx = postStringIndexmapkey
 			if m.Hashes == nil {
 				m.Hashes = make(map[string]string)
 			}
-			if iNdEx < postIndex {
-				var valuekey uint64
+			var mapkey string
+			var mapvalue string
+			for iNdEx < postIndex {
+				entryPreIndex := iNdEx
+				var wire uint64
 				for shift := uint(0); ; shift += 7 {
 					if shift >= 64 {
 						return ErrIntOverflowTarsum
@@ -343,41 +330,86 @@ func (m *TarsumBackup) Unmarshal(dAtA []byte) error {
 					}
 					b := dAtA[iNdEx]
 					iNdEx++
-					valuekey |= (uint64(b) & 0x7F) << shift
+					wire |= uint64(b&0x7F) << shift
 					if b < 0x80 {
 						break
 					}
 				}
-				var stringLenmapvalue uint64
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return ErrIntOverflowTarsum
+				fieldNum := int32(wire >> 3)
+				if fieldNum == 1 {
+					var stringLenmapkey uint64
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowTarsum
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						stringLenmapkey |= uint64(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
 					}
-					if iNdEx >= l {
+					intStringLenmapkey := int(stringLenmapkey)
+					if intStringLenmapkey < 0 {
+						return ErrInvalidLengthTarsum
+					}
+					postStringIndexmapkey := iNdEx + intStringLenmapkey
+					if postStringIndexmapkey < 0 {
+						return ErrInvalidLengthTarsum
+					}
+					if postStringIndexmapkey > l {
 						return io.ErrUnexpectedEOF
 					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					stringLenmapvalue |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
+					mapkey = string(dAtA[iNdEx:postStringIndexmapkey])
+					iNdEx = postStringIndexmapkey
+				} else if fieldNum == 2 {
+					var stringLenmapvalue uint64
+					for shift := uint(0); ; shift += 7 {
+						if shift >= 64 {
+							return ErrIntOverflowTarsum
+						}
+						if iNdEx >= l {
+							return io.ErrUnexpectedEOF
+						}
+						b := dAtA[iNdEx]
+						iNdEx++
+						stringLenmapvalue |= uint64(b&0x7F) << shift
+						if b < 0x80 {
+							break
+						}
 					}
+					intStringLenmapvalue := int(stringLenmapvalue)
+					if intStringLenmapvalue < 0 {
+						return ErrInvalidLengthTarsum
+					}
+					postStringIndexmapvalue := iNdEx + intStringLenmapvalue
+					if postStringIndexmapvalue < 0 {
+						return ErrInvalidLengthTarsum
+					}
+					if postStringIndexmapvalue > l {
+						return io.ErrUnexpectedEOF
+					}
+					mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue])
+					iNdEx = postStringIndexmapvalue
+				} else {
+					iNdEx = entryPreIndex
+					skippy, err := skipTarsum(dAtA[iNdEx:])
+					if err != nil {
+						return err
+					}
+					if (skippy < 0) || (iNdEx+skippy) < 0 {
+						return ErrInvalidLengthTarsum
+					}
+					if (iNdEx + skippy) > postIndex {
+						return io.ErrUnexpectedEOF
+					}
+					iNdEx += skippy
 				}
-				intStringLenmapvalue := int(stringLenmapvalue)
-				if intStringLenmapvalue < 0 {
-					return ErrInvalidLengthTarsum
-				}
-				postStringIndexmapvalue := iNdEx + intStringLenmapvalue
-				if postStringIndexmapvalue > l {
-					return io.ErrUnexpectedEOF
-				}
-				mapvalue := string(dAtA[iNdEx:postStringIndexmapvalue])
-				iNdEx = postStringIndexmapvalue
-				m.Hashes[mapkey] = mapvalue
-			} else {
-				var mapvalue string
-				m.Hashes[mapkey] = mapvalue
 			}
+			m.Hashes[mapkey] = mapvalue
 			iNdEx = postIndex
 		default:
 			iNdEx = preIndex
@@ -385,7 +417,7 @@ func (m *TarsumBackup) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthTarsum
 			}
 			if (iNdEx + skippy) > l {
@@ -403,6 +435,7 @@ func (m *TarsumBackup) Unmarshal(dAtA []byte) error {
 func skipTarsum(dAtA []byte) (n int, err error) {
 	l := len(dAtA)
 	iNdEx := 0
+	depth := 0
 	for iNdEx < l {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
@@ -434,10 +467,8 @@ func skipTarsum(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			return iNdEx, nil
 		case 1:
 			iNdEx += 8
-			return iNdEx, nil
 		case 2:
 			var length int
 			for shift := uint(0); ; shift += 7 {
@@ -454,72 +485,34 @@ func skipTarsum(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			iNdEx += length
 			if length < 0 {
 				return 0, ErrInvalidLengthTarsum
 			}
-			return iNdEx, nil
+			iNdEx += length
 		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowTarsum
-					}
-					if iNdEx >= l {
-						return 0, io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					innerWire |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				innerWireType := int(innerWire & 0x7)
-				if innerWireType == 4 {
-					break
-				}
-				next, err := skipTarsum(dAtA[start:])
-				if err != nil {
-					return 0, err
-				}
-				iNdEx = start + next
-			}
-			return iNdEx, nil
+			depth++
 		case 4:
-			return iNdEx, nil
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupTarsum
+			}
+			depth--
 		case 5:
 			iNdEx += 4
-			return iNdEx, nil
 		default:
 			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
 		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthTarsum
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
 	}
-	panic("unreachable")
+	return 0, io.ErrUnexpectedEOF
 }
 
 var (
-	ErrInvalidLengthTarsum = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowTarsum   = fmt.Errorf("proto: integer overflow")
+	ErrInvalidLengthTarsum        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowTarsum          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupTarsum = fmt.Errorf("proto: unexpected end of group")
 )
-
-func init() { proto.RegisterFile("tarsum.proto", fileDescriptorTarsum) }
-
-var fileDescriptorTarsum = []byte{
-	// 196 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xe2, 0xe2, 0x29, 0x49, 0x2c, 0x2a,
-	0x2e, 0xcd, 0xd5, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0xe2, 0x2d, 0x4a, 0xcd, 0xcd, 0x2f, 0x49,
-	0x4d, 0xce, 0xcf, 0x2b, 0x49, 0xad, 0x28, 0x51, 0xea, 0x62, 0xe4, 0xe2, 0x09, 0x01, 0xcb, 0x3b,
-	0x25, 0x26, 0x67, 0x97, 0x16, 0x08, 0xd9, 0x73, 0xb1, 0x79, 0x24, 0x16, 0x67, 0xa4, 0x16, 0x4b,
-	0x30, 0x2a, 0x30, 0x6b, 0x70, 0x1b, 0xa9, 0xeb, 0xa1, 0x68, 0xd0, 0x43, 0x56, 0xac, 0x07, 0x51,
-	0xe9, 0x9a, 0x57, 0x52, 0x54, 0x19, 0x04, 0xd5, 0x26, 0x65, 0xc9, 0xc5, 0x8d, 0x24, 0x2c, 0x24,
-	0xc0, 0xc5, 0x9c, 0x9d, 0x5a, 0x29, 0xc1, 0xa8, 0xc0, 0xa8, 0xc1, 0x19, 0x04, 0x62, 0x0a, 0x89,
-	0x70, 0xb1, 0x96, 0x25, 0xe6, 0x94, 0xa6, 0x4a, 0x30, 0x81, 0xc5, 0x20, 0x1c, 0x2b, 0x26, 0x0b,
-	0x46, 0x27, 0x9d, 0x0b, 0x0f, 0xe5, 0x18, 0x6e, 0x3c, 0x94, 0x63, 0xf8, 0xf0, 0x50, 0x8e, 0xb1,
-	0xe1, 0x91, 0x1c, 0xe3, 0x8a, 0x47, 0x72, 0x8c, 0x27, 0x1e, 0xc9, 0x31, 0x5e, 0x78, 0x24, 0xc7,
-	0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x8b, 0x47, 0x72, 0x0c, 0x1f, 0x1e, 0xc9, 0x31, 0x4e, 0x78, 0x2c,
-	0xc7, 0x90, 0xc4, 0x06, 0xf6, 0x90, 0x31, 0x20, 0x00, 0x00, 0xff, 0xff, 0x89, 0x57, 0x7d, 0x3f,
-	0xe0, 0x00, 0x00, 0x00,
-}
diff --git a/hack/dockerfiles/generate-files.Dockerfile b/hack/dockerfiles/generate-files.Dockerfile
new file mode 100644
index 0000000000000..6d3b76dc06bd6
--- /dev/null
+++ b/hack/dockerfiles/generate-files.Dockerfile
@@ -0,0 +1,73 @@
+# syntax=docker/dockerfile:1
+
+ARG GO_VERSION=1.20.4
+ARG BASE_DEBIAN_DISTRO="bullseye"
+ARG PROTOC_VERSION=3.11.4
+
+# protoc is dynamically linked to glibc so can't use alpine base
+FROM golang:${GO_VERSION}-${BASE_DEBIAN_DISTRO} AS base
+RUN apt-get update && apt-get --no-install-recommends install -y git unzip
+ARG PROTOC_VERSION
+ARG TARGETOS
+ARG TARGETARCH
+RUN <<EOT
+  set -e
+  arch=$(echo $TARGETARCH | sed -e s/amd64/x86_64/ -e s/arm64/aarch_64/)
+  wget -q https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-${TARGETOS}-${arch}.zip
+  unzip protoc-${PROTOC_VERSION}-${TARGETOS}-${arch}.zip -d /usr/local
+EOT
+WORKDIR /go/src/github.com/docker/docker
+
+FROM base AS src
+WORKDIR /out
+COPY . .
+RUN <<EOT
+  set -ex
+  git config --global user.email "moby@example.com"
+  git config --global user.name "moby"
+  git init .
+  git add .
+  git commit -m 'init'
+EOT
+
+FROM base AS tools
+RUN --mount=from=src,source=/out,target=.,rw \
+    --mount=type=cache,target=/root/.cache/go-build <<EOT
+  set -ex
+  ./hack/with-go-mod.sh go install -v -mod=vendor -modfile=vendor.mod \
+    github.com/gogo/protobuf/protoc-gen-gogo \
+    github.com/gogo/protobuf/protoc-gen-gogofaster \
+    github.com/gogo/protobuf/protoc-gen-gogoslick \
+    github.com/golang/protobuf/protoc-gen-go
+  ./hack/with-go-mod.sh go build -v -mod=vendor -modfile=vendor.mod \
+    -o /usr/bin/pluginrpc-gen \
+    ./pkg/plugins/pluginrpc-gen
+EOT
+
+FROM tools AS generated
+ENV GO111MODULE=off
+RUN --mount=from=src,source=/out,target=.,rw <<EOT
+  set -ex
+  go generate -v ./...
+  mkdir /out
+  git ls-files -m --others -- ':!vendor' 'profiles/seccomp/default.json' '**/*.pb.go' | tar -cf - --files-from - | tar -C /out -xf -
+EOT
+
+FROM scratch AS update
+COPY --from=generated /out /
+
+FROM base AS validate
+RUN --mount=from=src,source=/out,target=.,rw \
+    --mount=type=bind,from=generated,source=/out,target=/generated-files <<EOT
+  set -e
+  git add -A
+  if [ "$(ls -A /generated-files)" ]; then
+    cp -rf /generated-files/* .
+  fi
+  diff=$(git status --porcelain -- ':!vendor' 'profiles/seccomp/default.json' '**/*.pb.go')
+  if [ -n "$diff" ]; then
+    echo >&2 'ERROR: The result of "go generate" differs. Please update with "make generate-files"'
+    echo "$diff"
+    exit 1
+  fi
+EOT
diff --git a/internal/tools/tools.go b/internal/tools/tools.go
new file mode 100644
index 0000000000000..042824dfb6132
--- /dev/null
+++ b/internal/tools/tools.go
@@ -0,0 +1,15 @@
+//go:build tools
+// +build tools
+
+// Package tools tracks dependencies on binaries not referenced in this codebase.
+// https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module
+// Disclaimer: Avoid adding tools that don't need to be inferred from go.mod
+// like golangci-lint and check they don't import too many dependencies.
+package tools
+
+import (
+	_ "github.com/gogo/protobuf/protoc-gen-gogo"
+	_ "github.com/gogo/protobuf/protoc-gen-gogofaster"
+	_ "github.com/gogo/protobuf/protoc-gen-gogoslick"
+	_ "github.com/golang/protobuf/protoc-gen-go"
+)
diff --git a/libnetwork/agent.go b/libnetwork/agent.go
index 962dc57a59a8d..e655297339205 100644
--- a/libnetwork/agent.go
+++ b/libnetwork/agent.go
@@ -1,6 +1,6 @@
 package libnetwork
 
-//go:generate protoc -I.:Godeps/_workspace/src/github.com/gogo/protobuf  --gogo_out=import_path=github.com/docker/docker/libnetwork,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. agent.proto
+//go:generate protoc -I=. -I=../vendor/ --gogofaster_out=import_path=github.com/docker/docker/libnetwork:. agent.proto
 
 import (
 	"encoding/json"
diff --git a/libnetwork/agent.pb.go b/libnetwork/agent.pb.go
index 4092973c9be3c..f543d3e0c40a1 100644
--- a/libnetwork/agent.pb.go
+++ b/libnetwork/agent.pb.go
@@ -1,27 +1,18 @@
 // Code generated by protoc-gen-gogo. DO NOT EDIT.
 // source: agent.proto
 
-/*
-	Package libnetwork is a generated protocol buffer package.
-
-	It is generated from these files:
-		agent.proto
-
-	It has these top-level messages:
-		EndpointRecord
-		PortConfig
-*/
 package libnetwork
 
-import proto "github.com/gogo/protobuf/proto"
-import fmt "fmt"
-import math "math"
-import _ "github.com/gogo/protobuf/gogoproto"
-
-import strings "strings"
-import reflect "reflect"
-
-import io "io"
+import (
+	fmt "fmt"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+	reflect "reflect"
+	strings "strings"
+)
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -32,7 +23,7 @@ var _ = math.Inf
 // is compatible with the proto package it is being compiled against.
 // A compilation error at this line likely means your copy of the
 // proto package needs to be updated.
-const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 
 type PortConfig_Protocol int32
 
@@ -47,6 +38,7 @@ var PortConfig_Protocol_name = map[int32]string{
 	1: "UDP",
 	2: "SCTP",
 }
+
 var PortConfig_Protocol_value = map[string]int32{
 	"TCP":  0,
 	"UDP":  1,
@@ -56,7 +48,10 @@ var PortConfig_Protocol_value = map[string]int32{
 func (x PortConfig_Protocol) String() string {
 	return proto.EnumName(PortConfig_Protocol_name, int32(x))
 }
-func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) { return fileDescriptorAgent, []int{1, 0} }
+
+func (PortConfig_Protocol) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_56ede974c0020f77, []int{1, 0}
+}
 
 // EndpointRecord specifies all the endpoint specific information that
 // needs to gossiped to nodes participating in the network.
@@ -72,18 +67,46 @@ type EndpointRecord struct {
 	// IP assigned to this endpoint.
 	EndpointIP string `protobuf:"bytes,5,opt,name=endpoint_ip,json=endpointIp,proto3" json:"endpoint_ip,omitempty"`
 	// IngressPorts exposed by the service to which this endpoint belongs.
-	IngressPorts []*PortConfig `protobuf:"bytes,6,rep,name=ingress_ports,json=ingressPorts" json:"ingress_ports,omitempty"`
+	IngressPorts []*PortConfig `protobuf:"bytes,6,rep,name=ingress_ports,json=ingressPorts,proto3" json:"ingress_ports,omitempty"`
 	// A list of aliases which are alternate names for the service
-	Aliases []string `protobuf:"bytes,7,rep,name=aliases" json:"aliases,omitempty"`
+	Aliases []string `protobuf:"bytes,7,rep,name=aliases,proto3" json:"aliases,omitempty"`
 	// List of aliases task specific aliases
-	TaskAliases []string `protobuf:"bytes,8,rep,name=task_aliases,json=taskAliases" json:"task_aliases,omitempty"`
+	TaskAliases []string `protobuf:"bytes,8,rep,name=task_aliases,json=taskAliases,proto3" json:"task_aliases,omitempty"`
 	// Whether this enpoint's service has been disabled
 	ServiceDisabled bool `protobuf:"varint,9,opt,name=service_disabled,json=serviceDisabled,proto3" json:"service_disabled,omitempty"`
 }
 
-func (m *EndpointRecord) Reset()                    { *m = EndpointRecord{} }
-func (*EndpointRecord) ProtoMessage()               {}
-func (*EndpointRecord) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{0} }
+func (m *EndpointRecord) Reset()      { *m = EndpointRecord{} }
+func (*EndpointRecord) ProtoMessage() {}
+func (*EndpointRecord) Descriptor() ([]byte, []int) {
+	return fileDescriptor_56ede974c0020f77, []int{0}
+}
+func (m *EndpointRecord) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *EndpointRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_EndpointRecord.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *EndpointRecord) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_EndpointRecord.Merge(m, src)
+}
+func (m *EndpointRecord) XXX_Size() int {
+	return m.Size()
+}
+func (m *EndpointRecord) XXX_DiscardUnknown() {
+	xxx_messageInfo_EndpointRecord.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_EndpointRecord proto.InternalMessageInfo
 
 func (m *EndpointRecord) GetName() string {
 	if m != nil {
@@ -170,9 +193,37 @@ type PortConfig struct {
 	PublishedPort uint32 `protobuf:"varint,4,opt,name=published_port,json=publishedPort,proto3" json:"published_port,omitempty"`
 }
 
-func (m *PortConfig) Reset()                    { *m = PortConfig{} }
-func (*PortConfig) ProtoMessage()               {}
-func (*PortConfig) Descriptor() ([]byte, []int) { return fileDescriptorAgent, []int{1} }
+func (m *PortConfig) Reset()      { *m = PortConfig{} }
+func (*PortConfig) ProtoMessage() {}
+func (*PortConfig) Descriptor() ([]byte, []int) {
+	return fileDescriptor_56ede974c0020f77, []int{1}
+}
+func (m *PortConfig) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *PortConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_PortConfig.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *PortConfig) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PortConfig.Merge(m, src)
+}
+func (m *PortConfig) XXX_Size() int {
+	return m.Size()
+}
+func (m *PortConfig) XXX_DiscardUnknown() {
+	xxx_messageInfo_PortConfig.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PortConfig proto.InternalMessageInfo
 
 func (m *PortConfig) GetName() string {
 	if m != nil {
@@ -203,10 +254,48 @@ func (m *PortConfig) GetPublishedPort() uint32 {
 }
 
 func init() {
+	proto.RegisterEnum("libnetwork.PortConfig_Protocol", PortConfig_Protocol_name, PortConfig_Protocol_value)
 	proto.RegisterType((*EndpointRecord)(nil), "libnetwork.EndpointRecord")
 	proto.RegisterType((*PortConfig)(nil), "libnetwork.PortConfig")
-	proto.RegisterEnum("libnetwork.PortConfig_Protocol", PortConfig_Protocol_name, PortConfig_Protocol_value)
 }
+
+func init() { proto.RegisterFile("agent.proto", fileDescriptor_56ede974c0020f77) }
+
+var fileDescriptor_56ede974c0020f77 = []byte{
+	// 486 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x31, 0x6f, 0xd3, 0x40,
+	0x18, 0x86, 0xed, 0x24, 0xb4, 0xf1, 0xe7, 0x24, 0x8d, 0x6e, 0x40, 0x56, 0x86, 0x8b, 0x89, 0x40,
+	0x0a, 0x12, 0x38, 0x52, 0x19, 0x3b, 0xd1, 0x84, 0xc1, 0x0b, 0xb2, 0xae, 0x29, 0x6b, 0xb0, 0xe3,
+	0xab, 0x7b, 0xaa, 0xeb, 0xb3, 0x7c, 0x97, 0xb2, 0xb2, 0x81, 0x3a, 0xf1, 0x07, 0x3a, 0xf1, 0x67,
+	0x18, 0x3b, 0x76, 0xaa, 0xa8, 0xf3, 0x07, 0x58, 0xd9, 0xd0, 0x9d, 0xed, 0x46, 0x48, 0xdd, 0x7c,
+	0xcf, 0xfb, 0x7c, 0xd6, 0x77, 0xef, 0x81, 0x1d, 0x26, 0x34, 0x93, 0x5e, 0x5e, 0x70, 0xc9, 0x11,
+	0xa4, 0x2c, 0xca, 0xa8, 0xfc, 0xc2, 0x8b, 0x8b, 0xd1, 0xdb, 0x84, 0xc9, 0xf3, 0x4d, 0xe4, 0xad,
+	0xf9, 0xe5, 0x2c, 0xe1, 0x09, 0x9f, 0x69, 0x25, 0xda, 0x9c, 0xe9, 0x93, 0x3e, 0xe8, 0xaf, 0x6a,
+	0x74, 0xf2, 0xb7, 0x05, 0x83, 0x0f, 0x59, 0x9c, 0x73, 0x96, 0x49, 0x42, 0xd7, 0xbc, 0x88, 0x11,
+	0x82, 0x4e, 0x16, 0x5e, 0x52, 0xc7, 0x74, 0xcd, 0xa9, 0x45, 0xf4, 0x37, 0x7a, 0x01, 0x3d, 0x41,
+	0x8b, 0x2b, 0xb6, 0xa6, 0x2b, 0x9d, 0xb5, 0x74, 0x66, 0xd7, 0xec, 0xa3, 0x52, 0xde, 0x00, 0x34,
+	0x0a, 0x8b, 0x9d, 0xb6, 0x12, 0x8e, 0xfb, 0xe5, 0xfd, 0xd8, 0x3a, 0xa9, 0xa8, 0xbf, 0x20, 0x56,
+	0x2d, 0xf8, 0xb1, 0xb2, 0xaf, 0x58, 0x21, 0x37, 0x61, 0xba, 0x62, 0xb9, 0xd3, 0xd9, 0xd9, 0x9f,
+	0x2a, 0xea, 0x07, 0xc4, 0xaa, 0x05, 0x3f, 0x47, 0x33, 0xb0, 0x69, 0xbd, 0xa4, 0xd2, 0x9f, 0x69,
+	0x7d, 0x50, 0xde, 0x8f, 0xa1, 0xd9, 0xdd, 0x0f, 0x08, 0x34, 0x8a, 0x9f, 0xa3, 0x23, 0xe8, 0xb3,
+	0x2c, 0x29, 0xa8, 0x10, 0xab, 0x9c, 0x17, 0x52, 0x38, 0x7b, 0x6e, 0x7b, 0x6a, 0x1f, 0x3e, 0xf7,
+	0x76, 0x4d, 0x79, 0x01, 0x2f, 0xe4, 0x9c, 0x67, 0x67, 0x2c, 0x21, 0xbd, 0x5a, 0x56, 0x48, 0x20,
+	0x07, 0xf6, 0xc3, 0x94, 0x85, 0x82, 0x0a, 0x67, 0xdf, 0x6d, 0x4f, 0x2d, 0xd2, 0x1c, 0x55, 0x0d,
+	0x32, 0x14, 0x17, 0xab, 0x26, 0xee, 0xea, 0xd8, 0x56, 0xec, 0x7d, 0xad, 0xbc, 0x86, 0x61, 0x53,
+	0x43, 0xcc, 0x44, 0x18, 0xa5, 0x34, 0x76, 0x2c, 0xd7, 0x9c, 0x76, 0xc9, 0x41, 0xcd, 0x17, 0x35,
+	0x9e, 0x7c, 0x6b, 0x01, 0xec, 0x96, 0x78, 0xb2, 0xf7, 0x23, 0xe8, 0xea, 0x77, 0x5a, 0xf3, 0x54,
+	0x77, 0x3e, 0x38, 0x1c, 0x3f, 0x7d, 0x05, 0x2f, 0xa8, 0x35, 0xf2, 0x38, 0x80, 0xc6, 0x60, 0xcb,
+	0xb0, 0x48, 0xa8, 0xd4, 0x1d, 0xe8, 0x27, 0xe9, 0x13, 0xa8, 0x90, 0x9a, 0x44, 0xaf, 0x60, 0x90,
+	0x6f, 0xa2, 0x94, 0x89, 0x73, 0x1a, 0x57, 0x4e, 0x47, 0x3b, 0xfd, 0x47, 0xaa, 0xb4, 0xc9, 0x67,
+	0xe8, 0x36, 0x7f, 0x47, 0x0e, 0xb4, 0x97, 0xf3, 0x60, 0x68, 0x8c, 0x0e, 0xae, 0x6f, 0x5c, 0xbb,
+	0xc1, 0xcb, 0x79, 0xa0, 0x92, 0xd3, 0x45, 0x30, 0x34, 0xff, 0x4f, 0x4e, 0x17, 0x01, 0x1a, 0x41,
+	0xe7, 0x64, 0xbe, 0x0c, 0x86, 0xad, 0xd1, 0xf0, 0xfa, 0xc6, 0xed, 0x35, 0x91, 0x62, 0xa3, 0xce,
+	0xf7, 0x9f, 0xd8, 0x38, 0x7e, 0x79, 0xf7, 0x80, 0x8d, 0x3f, 0x0f, 0xd8, 0xfc, 0x5a, 0x62, 0xf3,
+	0x57, 0x89, 0xcd, 0xdb, 0x12, 0x9b, 0xbf, 0x4b, 0x6c, 0xfe, 0xd8, 0x62, 0xe3, 0x76, 0x8b, 0x8d,
+	0xbb, 0x2d, 0x36, 0xa2, 0x3d, 0x7d, 0xb3, 0x77, 0xff, 0x02, 0x00, 0x00, 0xff, 0xff, 0xc0, 0xc6,
+	0x3a, 0x88, 0xfc, 0x02, 0x00, 0x00,
+}
+
 func (this *EndpointRecord) GoString() string {
 	if this == nil {
 		return "nil"
@@ -251,7 +340,7 @@ func valueToGoStringAgent(v interface{}, typ string) string {
 func (m *EndpointRecord) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -259,99 +348,99 @@ func (m *EndpointRecord) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *EndpointRecord) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *EndpointRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintAgent(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
+	if m.ServiceDisabled {
+		i--
+		if m.ServiceDisabled {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
+		}
+		i--
+		dAtA[i] = 0x48
 	}
-	if len(m.ServiceName) > 0 {
-		dAtA[i] = 0x12
-		i++
-		i = encodeVarintAgent(dAtA, i, uint64(len(m.ServiceName)))
-		i += copy(dAtA[i:], m.ServiceName)
+	if len(m.TaskAliases) > 0 {
+		for iNdEx := len(m.TaskAliases) - 1; iNdEx >= 0; iNdEx-- {
+			i -= len(m.TaskAliases[iNdEx])
+			copy(dAtA[i:], m.TaskAliases[iNdEx])
+			i = encodeVarintAgent(dAtA, i, uint64(len(m.TaskAliases[iNdEx])))
+			i--
+			dAtA[i] = 0x42
+		}
 	}
-	if len(m.ServiceID) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintAgent(dAtA, i, uint64(len(m.ServiceID)))
-		i += copy(dAtA[i:], m.ServiceID)
+	if len(m.Aliases) > 0 {
+		for iNdEx := len(m.Aliases) - 1; iNdEx >= 0; iNdEx-- {
+			i -= len(m.Aliases[iNdEx])
+			copy(dAtA[i:], m.Aliases[iNdEx])
+			i = encodeVarintAgent(dAtA, i, uint64(len(m.Aliases[iNdEx])))
+			i--
+			dAtA[i] = 0x3a
+		}
 	}
-	if len(m.VirtualIP) > 0 {
-		dAtA[i] = 0x22
-		i++
-		i = encodeVarintAgent(dAtA, i, uint64(len(m.VirtualIP)))
-		i += copy(dAtA[i:], m.VirtualIP)
+	if len(m.IngressPorts) > 0 {
+		for iNdEx := len(m.IngressPorts) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.IngressPorts[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintAgent(dAtA, i, uint64(size))
+			}
+			i--
+			dAtA[i] = 0x32
+		}
 	}
 	if len(m.EndpointIP) > 0 {
-		dAtA[i] = 0x2a
-		i++
+		i -= len(m.EndpointIP)
+		copy(dAtA[i:], m.EndpointIP)
 		i = encodeVarintAgent(dAtA, i, uint64(len(m.EndpointIP)))
-		i += copy(dAtA[i:], m.EndpointIP)
+		i--
+		dAtA[i] = 0x2a
 	}
-	if len(m.IngressPorts) > 0 {
-		for _, msg := range m.IngressPorts {
-			dAtA[i] = 0x32
-			i++
-			i = encodeVarintAgent(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
-			}
-			i += n
-		}
+	if len(m.VirtualIP) > 0 {
+		i -= len(m.VirtualIP)
+		copy(dAtA[i:], m.VirtualIP)
+		i = encodeVarintAgent(dAtA, i, uint64(len(m.VirtualIP)))
+		i--
+		dAtA[i] = 0x22
 	}
-	if len(m.Aliases) > 0 {
-		for _, s := range m.Aliases {
-			dAtA[i] = 0x3a
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
+	if len(m.ServiceID) > 0 {
+		i -= len(m.ServiceID)
+		copy(dAtA[i:], m.ServiceID)
+		i = encodeVarintAgent(dAtA, i, uint64(len(m.ServiceID)))
+		i--
+		dAtA[i] = 0x1a
 	}
-	if len(m.TaskAliases) > 0 {
-		for _, s := range m.TaskAliases {
-			dAtA[i] = 0x42
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
-		}
+	if len(m.ServiceName) > 0 {
+		i -= len(m.ServiceName)
+		copy(dAtA[i:], m.ServiceName)
+		i = encodeVarintAgent(dAtA, i, uint64(len(m.ServiceName)))
+		i--
+		dAtA[i] = 0x12
 	}
-	if m.ServiceDisabled {
-		dAtA[i] = 0x48
-		i++
-		if m.ServiceDisabled {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
-		}
-		i++
+	if len(m.Name) > 0 {
+		i -= len(m.Name)
+		copy(dAtA[i:], m.Name)
+		i = encodeVarintAgent(dAtA, i, uint64(len(m.Name)))
+		i--
+		dAtA[i] = 0xa
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func (m *PortConfig) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -359,44 +448,55 @@ func (m *PortConfig) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *PortConfig) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *PortConfig) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if len(m.Name) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintAgent(dAtA, i, uint64(len(m.Name)))
-		i += copy(dAtA[i:], m.Name)
-	}
-	if m.Protocol != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintAgent(dAtA, i, uint64(m.Protocol))
+	if m.PublishedPort != 0 {
+		i = encodeVarintAgent(dAtA, i, uint64(m.PublishedPort))
+		i--
+		dAtA[i] = 0x20
 	}
 	if m.TargetPort != 0 {
-		dAtA[i] = 0x18
-		i++
 		i = encodeVarintAgent(dAtA, i, uint64(m.TargetPort))
+		i--
+		dAtA[i] = 0x18
 	}
-	if m.PublishedPort != 0 {
-		dAtA[i] = 0x20
-		i++
-		i = encodeVarintAgent(dAtA, i, uint64(m.PublishedPort))
+	if m.Protocol != 0 {
+		i = encodeVarintAgent(dAtA, i, uint64(m.Protocol))
+		i--
+		dAtA[i] = 0x10
 	}
-	return i, nil
+	if len(m.Name) > 0 {
+		i -= len(m.Name)
+		copy(dAtA[i:], m.Name)
+		i = encodeVarintAgent(dAtA, i, uint64(len(m.Name)))
+		i--
+		dAtA[i] = 0xa
+	}
+	return len(dAtA) - i, nil
 }
 
 func encodeVarintAgent(dAtA []byte, offset int, v uint64) int {
+	offset -= sovAgent(v)
+	base := offset
 	for v >= 1<<7 {
 		dAtA[offset] = uint8(v&0x7f | 0x80)
 		v >>= 7
 		offset++
 	}
 	dAtA[offset] = uint8(v)
-	return offset + 1
+	return base
 }
 func (m *EndpointRecord) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	l = len(m.Name)
@@ -444,6 +544,9 @@ func (m *EndpointRecord) Size() (n int) {
 }
 
 func (m *PortConfig) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	l = len(m.Name)
@@ -463,14 +566,7 @@ func (m *PortConfig) Size() (n int) {
 }
 
 func sovAgent(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
+	return (math_bits.Len64(x|1) + 6) / 7
 }
 func sozAgent(x uint64) (n int) {
 	return sovAgent(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -479,13 +575,18 @@ func (this *EndpointRecord) String() string {
 	if this == nil {
 		return "nil"
 	}
+	repeatedStringForIngressPorts := "[]*PortConfig{"
+	for _, f := range this.IngressPorts {
+		repeatedStringForIngressPorts += strings.Replace(f.String(), "PortConfig", "PortConfig", 1) + ","
+	}
+	repeatedStringForIngressPorts += "}"
 	s := strings.Join([]string{`&EndpointRecord{`,
 		`Name:` + fmt.Sprintf("%v", this.Name) + `,`,
 		`ServiceName:` + fmt.Sprintf("%v", this.ServiceName) + `,`,
 		`ServiceID:` + fmt.Sprintf("%v", this.ServiceID) + `,`,
 		`VirtualIP:` + fmt.Sprintf("%v", this.VirtualIP) + `,`,
 		`EndpointIP:` + fmt.Sprintf("%v", this.EndpointIP) + `,`,
-		`IngressPorts:` + strings.Replace(fmt.Sprintf("%v", this.IngressPorts), "PortConfig", "PortConfig", 1) + `,`,
+		`IngressPorts:` + repeatedStringForIngressPorts + `,`,
 		`Aliases:` + fmt.Sprintf("%v", this.Aliases) + `,`,
 		`TaskAliases:` + fmt.Sprintf("%v", this.TaskAliases) + `,`,
 		`ServiceDisabled:` + fmt.Sprintf("%v", this.ServiceDisabled) + `,`,
@@ -529,7 +630,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -557,7 +658,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -567,6 +668,9 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthAgent
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthAgent
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -586,7 +690,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -596,6 +700,9 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthAgent
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthAgent
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -615,7 +722,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -625,6 +732,9 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthAgent
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthAgent
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -644,7 +754,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -654,6 +764,9 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthAgent
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthAgent
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -673,7 +786,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -683,6 +796,9 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthAgent
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthAgent
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -702,7 +818,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
+				msglen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -711,6 +827,9 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthAgent
 			}
 			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthAgent
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -733,7 +852,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -743,6 +862,9 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthAgent
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthAgent
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -762,7 +884,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -772,6 +894,9 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthAgent
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthAgent
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -791,7 +916,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= (int(b) & 0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -803,7 +928,7 @@ func (m *EndpointRecord) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthAgent
 			}
 			if (iNdEx + skippy) > l {
@@ -833,7 +958,7 @@ func (m *PortConfig) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -861,7 +986,7 @@ func (m *PortConfig) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -871,6 +996,9 @@ func (m *PortConfig) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthAgent
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthAgent
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -890,7 +1018,7 @@ func (m *PortConfig) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.Protocol |= (PortConfig_Protocol(b) & 0x7F) << shift
+				m.Protocol |= PortConfig_Protocol(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -909,7 +1037,7 @@ func (m *PortConfig) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.TargetPort |= (uint32(b) & 0x7F) << shift
+				m.TargetPort |= uint32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -928,7 +1056,7 @@ func (m *PortConfig) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.PublishedPort |= (uint32(b) & 0x7F) << shift
+				m.PublishedPort |= uint32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -939,7 +1067,7 @@ func (m *PortConfig) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthAgent
 			}
 			if (iNdEx + skippy) > l {
@@ -957,6 +1085,7 @@ func (m *PortConfig) Unmarshal(dAtA []byte) error {
 func skipAgent(dAtA []byte) (n int, err error) {
 	l := len(dAtA)
 	iNdEx := 0
+	depth := 0
 	for iNdEx < l {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
@@ -988,10 +1117,8 @@ func skipAgent(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			return iNdEx, nil
 		case 1:
 			iNdEx += 8
-			return iNdEx, nil
 		case 2:
 			var length int
 			for shift := uint(0); ; shift += 7 {
@@ -1008,88 +1135,34 @@ func skipAgent(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			iNdEx += length
 			if length < 0 {
 				return 0, ErrInvalidLengthAgent
 			}
-			return iNdEx, nil
+			iNdEx += length
 		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowAgent
-					}
-					if iNdEx >= l {
-						return 0, io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					innerWire |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				innerWireType := int(innerWire & 0x7)
-				if innerWireType == 4 {
-					break
-				}
-				next, err := skipAgent(dAtA[start:])
-				if err != nil {
-					return 0, err
-				}
-				iNdEx = start + next
-			}
-			return iNdEx, nil
+			depth++
 		case 4:
-			return iNdEx, nil
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupAgent
+			}
+			depth--
 		case 5:
 			iNdEx += 4
-			return iNdEx, nil
 		default:
 			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
 		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthAgent
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
 	}
-	panic("unreachable")
+	return 0, io.ErrUnexpectedEOF
 }
 
 var (
-	ErrInvalidLengthAgent = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowAgent   = fmt.Errorf("proto: integer overflow")
+	ErrInvalidLengthAgent        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowAgent          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupAgent = fmt.Errorf("proto: unexpected end of group")
 )
-
-func init() { proto.RegisterFile("agent.proto", fileDescriptorAgent) }
-
-var fileDescriptorAgent = []byte{
-	// 459 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x6c, 0x91, 0x31, 0x6f, 0xd3, 0x4c,
-	0x18, 0xc7, 0xe3, 0xc4, 0x6f, 0x1b, 0x3f, 0x4e, 0x52, 0xeb, 0xf4, 0x0a, 0x59, 0x1e, 0x1c, 0x13,
-	0x09, 0x29, 0x48, 0x28, 0x95, 0xca, 0xd8, 0x89, 0x26, 0x0c, 0x5e, 0x90, 0x75, 0x4d, 0x59, 0x83,
-	0x13, 0x1f, 0xe6, 0x54, 0xe3, 0xb3, 0xee, 0xae, 0x65, 0x65, 0x03, 0xf5, 0x3b, 0x74, 0xe2, 0xcb,
-	0x30, 0x32, 0x32, 0x55, 0xd4, 0x9f, 0x80, 0x95, 0x0d, 0xdd, 0xf9, 0xae, 0x11, 0x52, 0xb7, 0xf3,
-	0xef, 0xff, 0x3b, 0xeb, 0xb9, 0xff, 0x03, 0x7e, 0x5e, 0x92, 0x5a, 0x2e, 0x1a, 0xce, 0x24, 0x43,
-	0x50, 0xd1, 0x6d, 0x4d, 0xe4, 0x27, 0xc6, 0x2f, 0xa3, 0xff, 0x4b, 0x56, 0x32, 0x8d, 0x8f, 0xd5,
-	0xa9, 0x33, 0x66, 0x7f, 0xfa, 0x30, 0x79, 0x5d, 0x17, 0x0d, 0xa3, 0xb5, 0xc4, 0x64, 0xc7, 0x78,
-	0x81, 0x10, 0xb8, 0x75, 0xfe, 0x91, 0x84, 0x4e, 0xe2, 0xcc, 0x3d, 0xac, 0xcf, 0xe8, 0x29, 0x8c,
-	0x04, 0xe1, 0xd7, 0x74, 0x47, 0x36, 0x3a, 0xeb, 0xeb, 0xcc, 0x37, 0xec, 0x8d, 0x52, 0x5e, 0x00,
-	0x58, 0x85, 0x16, 0xe1, 0x40, 0x09, 0x67, 0xe3, 0xf6, 0x6e, 0xea, 0x9d, 0x77, 0x34, 0x5d, 0x61,
-	0xcf, 0x08, 0x69, 0xa1, 0xec, 0x6b, 0xca, 0xe5, 0x55, 0x5e, 0x6d, 0x68, 0x13, 0xba, 0x7b, 0xfb,
-	0x6d, 0x47, 0xd3, 0x0c, 0x7b, 0x46, 0x48, 0x1b, 0x74, 0x0c, 0x3e, 0x31, 0x43, 0x2a, 0xfd, 0x3f,
-	0xad, 0x4f, 0xda, 0xbb, 0x29, 0xd8, 0xd9, 0xd3, 0x0c, 0x83, 0x55, 0xd2, 0x06, 0x9d, 0xc2, 0x98,
-	0xd6, 0x25, 0x27, 0x42, 0x6c, 0x1a, 0xc6, 0xa5, 0x08, 0x0f, 0x92, 0xc1, 0xdc, 0x3f, 0x79, 0xb2,
-	0xd8, 0x17, 0xb2, 0xc8, 0x18, 0x97, 0x4b, 0x56, 0xbf, 0xa7, 0x25, 0x1e, 0x19, 0x59, 0x21, 0x81,
-	0x42, 0x38, 0xcc, 0x2b, 0x9a, 0x0b, 0x22, 0xc2, 0xc3, 0x64, 0x30, 0xf7, 0xb0, 0xfd, 0x54, 0x35,
-	0xc8, 0x5c, 0x5c, 0x6e, 0x6c, 0x3c, 0xd4, 0xb1, 0xaf, 0xd8, 0x2b, 0xa3, 0x3c, 0x87, 0xc0, 0xd6,
-	0x50, 0x50, 0x91, 0x6f, 0x2b, 0x52, 0x84, 0x5e, 0xe2, 0xcc, 0x87, 0xf8, 0xc8, 0xf0, 0x95, 0xc1,
-	0xb3, 0x2f, 0x7d, 0x80, 0xfd, 0x10, 0x8f, 0xf6, 0x7e, 0x0a, 0x43, 0xbd, 0xa7, 0x1d, 0xab, 0x74,
-	0xe7, 0x93, 0x93, 0xe9, 0xe3, 0x4f, 0x58, 0x64, 0x46, 0xc3, 0x0f, 0x17, 0xd0, 0x14, 0x7c, 0x99,
-	0xf3, 0x92, 0x48, 0xdd, 0x81, 0x5e, 0xc9, 0x18, 0x43, 0x87, 0xd4, 0x4d, 0xf4, 0x0c, 0x26, 0xcd,
-	0xd5, 0xb6, 0xa2, 0xe2, 0x03, 0x29, 0x3a, 0xc7, 0xd5, 0xce, 0xf8, 0x81, 0x2a, 0x6d, 0xf6, 0x0e,
-	0x86, 0xf6, 0xef, 0x28, 0x84, 0xc1, 0x7a, 0x99, 0x05, 0xbd, 0xe8, 0xe8, 0xe6, 0x36, 0xf1, 0x2d,
-	0x5e, 0x2f, 0x33, 0x95, 0x5c, 0xac, 0xb2, 0xc0, 0xf9, 0x37, 0xb9, 0x58, 0x65, 0x28, 0x02, 0xf7,
-	0x7c, 0xb9, 0xce, 0x82, 0x7e, 0x14, 0xdc, 0xdc, 0x26, 0x23, 0x1b, 0x29, 0x16, 0xb9, 0x5f, 0xbf,
-	0xc5, 0xbd, 0xb3, 0xf0, 0xe7, 0x7d, 0xdc, 0xfb, 0x7d, 0x1f, 0x3b, 0x9f, 0xdb, 0xd8, 0xf9, 0xde,
-	0xc6, 0xce, 0x8f, 0x36, 0x76, 0x7e, 0xb5, 0xb1, 0xb3, 0x3d, 0xd0, 0xaf, 0x79, 0xf9, 0x37, 0x00,
-	0x00, 0xff, 0xff, 0x55, 0x29, 0x75, 0x5c, 0xd7, 0x02, 0x00, 0x00,
-}
diff --git a/libnetwork/agent.proto b/libnetwork/agent.proto
index f9c46c7a9836c..05c6419c14b41 100644
--- a/libnetwork/agent.proto
+++ b/libnetwork/agent.proto
@@ -1,6 +1,6 @@
 syntax = "proto3";
 
-import "gogoproto/gogo.proto";
+import "github.com/gogo/protobuf/gogoproto/gogo.proto";
 
 package libnetwork;
 
diff --git a/libnetwork/drivers/overlay/overlay.go b/libnetwork/drivers/overlay/overlay.go
index ab77a714e886d..4422cef8c7734 100644
--- a/libnetwork/drivers/overlay/overlay.go
+++ b/libnetwork/drivers/overlay/overlay.go
@@ -2,7 +2,7 @@
 
 package overlay
 
-//go:generate protoc -I.:../../Godeps/_workspace/src/github.com/gogo/protobuf  --gogo_out=import_path=github.com/docker/docker/libnetwork/drivers/overlay,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. overlay.proto
+//go:generate protoc -I=. -I=../../../vendor/ --gogofaster_out=import_path=github.com/docker/docker/libnetwork/drivers/overlay:. overlay.proto
 
 import (
 	"fmt"
diff --git a/libnetwork/drivers/overlay/overlay.pb.go b/libnetwork/drivers/overlay/overlay.pb.go
index 243c196541a7e..6426a3c6a5ba9 100644
--- a/libnetwork/drivers/overlay/overlay.pb.go
+++ b/libnetwork/drivers/overlay/overlay.pb.go
@@ -1,26 +1,18 @@
 // Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: drivers/overlay/overlay.proto
+// source: overlay.proto
 
-/*
-	Package overlay is a generated protocol buffer package.
-
-	It is generated from these files:
-		drivers/overlay/overlay.proto
-
-	It has these top-level messages:
-		PeerRecord
-*/
 package overlay
 
-import proto "github.com/gogo/protobuf/proto"
-import fmt "fmt"
-import math "math"
-import _ "github.com/gogo/protobuf/gogoproto"
-
-import strings "strings"
-import reflect "reflect"
-
-import io "io"
+import (
+	fmt "fmt"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+	reflect "reflect"
+	strings "strings"
+)
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -31,7 +23,7 @@ var _ = math.Inf
 // is compatible with the proto package it is being compiled against.
 // A compilation error at this line likely means your copy of the
 // proto package needs to be updated.
-const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 
 // PeerRecord defines the information corresponding to a peer
 // container in the overlay network.
@@ -48,9 +40,37 @@ type PeerRecord struct {
 	TunnelEndpointIP string `protobuf:"bytes,3,opt,name=tunnel_endpoint_ip,json=tunnelEndpointIp,proto3" json:"tunnel_endpoint_ip,omitempty"`
 }
 
-func (m *PeerRecord) Reset()                    { *m = PeerRecord{} }
-func (*PeerRecord) ProtoMessage()               {}
-func (*PeerRecord) Descriptor() ([]byte, []int) { return fileDescriptorOverlay, []int{0} }
+func (m *PeerRecord) Reset()      { *m = PeerRecord{} }
+func (*PeerRecord) ProtoMessage() {}
+func (*PeerRecord) Descriptor() ([]byte, []int) {
+	return fileDescriptor_61fc82527fbe24ad, []int{0}
+}
+func (m *PeerRecord) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *PeerRecord) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_PeerRecord.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *PeerRecord) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_PeerRecord.Merge(m, src)
+}
+func (m *PeerRecord) XXX_Size() int {
+	return m.Size()
+}
+func (m *PeerRecord) XXX_DiscardUnknown() {
+	xxx_messageInfo_PeerRecord.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_PeerRecord proto.InternalMessageInfo
 
 func (m *PeerRecord) GetEndpointIP() string {
 	if m != nil {
@@ -76,6 +96,28 @@ func (m *PeerRecord) GetTunnelEndpointIP() string {
 func init() {
 	proto.RegisterType((*PeerRecord)(nil), "overlay.PeerRecord")
 }
+
+func init() { proto.RegisterFile("overlay.proto", fileDescriptor_61fc82527fbe24ad) }
+
+var fileDescriptor_61fc82527fbe24ad = []byte{
+	// 233 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xcd, 0x2f, 0x4b, 0x2d,
+	0xca, 0x49, 0xac, 0xd4, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x87, 0x72, 0xa5, 0x74, 0xd3,
+	0x33, 0x4b, 0x32, 0x4a, 0x93, 0xf4, 0x92, 0xf3, 0x73, 0xf5, 0xd3, 0xf3, 0xd3, 0xf3, 0xf5, 0xc1,
+	0xf2, 0x49, 0xa5, 0x69, 0x60, 0x1e, 0x98, 0x03, 0x66, 0x41, 0xf4, 0x29, 0x6d, 0x65, 0xe4, 0xe2,
+	0x0a, 0x48, 0x4d, 0x2d, 0x0a, 0x4a, 0x4d, 0xce, 0x2f, 0x4a, 0x11, 0xd2, 0xe7, 0xe2, 0x4e, 0xcd,
+	0x4b, 0x29, 0xc8, 0xcf, 0xcc, 0x2b, 0x89, 0xcf, 0x2c, 0x90, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x74,
+	0xe2, 0x7b, 0x74, 0x4f, 0x9e, 0xcb, 0x15, 0x2a, 0xec, 0x19, 0x10, 0xc4, 0x05, 0x53, 0xe2, 0x59,
+	0x20, 0x64, 0xc4, 0xc5, 0x03, 0xd7, 0x90, 0x9b, 0x98, 0x2c, 0xc1, 0x04, 0xd6, 0xc1, 0xff, 0xe8,
+	0x9e, 0x3c, 0x37, 0x4c, 0x87, 0xaf, 0xa3, 0x73, 0x10, 0xdc, 0x54, 0xdf, 0xc4, 0x64, 0x21, 0x27,
+	0x2e, 0xa1, 0x92, 0xd2, 0xbc, 0xbc, 0xd4, 0x9c, 0x78, 0x64, 0xbb, 0x98, 0xc1, 0x3a, 0x45, 0x1e,
+	0xdd, 0x93, 0x17, 0x08, 0x01, 0xcb, 0x22, 0xd9, 0x28, 0x50, 0x82, 0x2a, 0x52, 0xe0, 0xa4, 0x72,
+	0xe3, 0xa1, 0x1c, 0xc3, 0x87, 0x87, 0x72, 0x8c, 0x0d, 0x8f, 0xe4, 0x18, 0x4f, 0x3c, 0x92, 0x63,
+	0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39, 0xc6, 0x09, 0x8f, 0xe5, 0x18, 0x2e, 0x3c, 0x96,
+	0x63, 0xb8, 0xf1, 0x58, 0x8e, 0x21, 0x89, 0x0d, 0xec, 0x49, 0x63, 0x40, 0x00, 0x00, 0x00, 0xff,
+	0xff, 0xd4, 0x37, 0x59, 0xc8, 0x2d, 0x01, 0x00, 0x00,
+}
+
 func (this *PeerRecord) GoString() string {
 	if this == nil {
 		return "nil"
@@ -99,7 +141,7 @@ func valueToGoStringOverlay(v interface{}, typ string) string {
 func (m *PeerRecord) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -107,41 +149,54 @@ func (m *PeerRecord) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *PeerRecord) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *PeerRecord) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if len(m.EndpointIP) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintOverlay(dAtA, i, uint64(len(m.EndpointIP)))
-		i += copy(dAtA[i:], m.EndpointIP)
+	if len(m.TunnelEndpointIP) > 0 {
+		i -= len(m.TunnelEndpointIP)
+		copy(dAtA[i:], m.TunnelEndpointIP)
+		i = encodeVarintOverlay(dAtA, i, uint64(len(m.TunnelEndpointIP)))
+		i--
+		dAtA[i] = 0x1a
 	}
 	if len(m.EndpointMAC) > 0 {
-		dAtA[i] = 0x12
-		i++
+		i -= len(m.EndpointMAC)
+		copy(dAtA[i:], m.EndpointMAC)
 		i = encodeVarintOverlay(dAtA, i, uint64(len(m.EndpointMAC)))
-		i += copy(dAtA[i:], m.EndpointMAC)
+		i--
+		dAtA[i] = 0x12
 	}
-	if len(m.TunnelEndpointIP) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintOverlay(dAtA, i, uint64(len(m.TunnelEndpointIP)))
-		i += copy(dAtA[i:], m.TunnelEndpointIP)
+	if len(m.EndpointIP) > 0 {
+		i -= len(m.EndpointIP)
+		copy(dAtA[i:], m.EndpointIP)
+		i = encodeVarintOverlay(dAtA, i, uint64(len(m.EndpointIP)))
+		i--
+		dAtA[i] = 0xa
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func encodeVarintOverlay(dAtA []byte, offset int, v uint64) int {
+	offset -= sovOverlay(v)
+	base := offset
 	for v >= 1<<7 {
 		dAtA[offset] = uint8(v&0x7f | 0x80)
 		v >>= 7
 		offset++
 	}
 	dAtA[offset] = uint8(v)
-	return offset + 1
+	return base
 }
 func (m *PeerRecord) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	l = len(m.EndpointIP)
@@ -160,14 +215,7 @@ func (m *PeerRecord) Size() (n int) {
 }
 
 func sovOverlay(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
+	return (math_bits.Len64(x|1) + 6) / 7
 }
 func sozOverlay(x uint64) (n int) {
 	return sovOverlay(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -207,7 +255,7 @@ func (m *PeerRecord) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -235,7 +283,7 @@ func (m *PeerRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -245,6 +293,9 @@ func (m *PeerRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthOverlay
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthOverlay
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -264,7 +315,7 @@ func (m *PeerRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -274,6 +325,9 @@ func (m *PeerRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthOverlay
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthOverlay
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -293,7 +347,7 @@ func (m *PeerRecord) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -303,6 +357,9 @@ func (m *PeerRecord) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthOverlay
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthOverlay
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -314,7 +371,7 @@ func (m *PeerRecord) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthOverlay
 			}
 			if (iNdEx + skippy) > l {
@@ -332,6 +389,7 @@ func (m *PeerRecord) Unmarshal(dAtA []byte) error {
 func skipOverlay(dAtA []byte) (n int, err error) {
 	l := len(dAtA)
 	iNdEx := 0
+	depth := 0
 	for iNdEx < l {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
@@ -363,10 +421,8 @@ func skipOverlay(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			return iNdEx, nil
 		case 1:
 			iNdEx += 8
-			return iNdEx, nil
 		case 2:
 			var length int
 			for shift := uint(0); ; shift += 7 {
@@ -383,73 +439,34 @@ func skipOverlay(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			iNdEx += length
 			if length < 0 {
 				return 0, ErrInvalidLengthOverlay
 			}
-			return iNdEx, nil
+			iNdEx += length
 		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowOverlay
-					}
-					if iNdEx >= l {
-						return 0, io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					innerWire |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				innerWireType := int(innerWire & 0x7)
-				if innerWireType == 4 {
-					break
-				}
-				next, err := skipOverlay(dAtA[start:])
-				if err != nil {
-					return 0, err
-				}
-				iNdEx = start + next
-			}
-			return iNdEx, nil
+			depth++
 		case 4:
-			return iNdEx, nil
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupOverlay
+			}
+			depth--
 		case 5:
 			iNdEx += 4
-			return iNdEx, nil
 		default:
 			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
 		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthOverlay
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
 	}
-	panic("unreachable")
+	return 0, io.ErrUnexpectedEOF
 }
 
 var (
-	ErrInvalidLengthOverlay = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowOverlay   = fmt.Errorf("proto: integer overflow")
+	ErrInvalidLengthOverlay        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowOverlay          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupOverlay = fmt.Errorf("proto: unexpected end of group")
 )
-
-func init() { proto.RegisterFile("drivers/overlay/overlay.proto", fileDescriptorOverlay) }
-
-var fileDescriptorOverlay = []byte{
-	// 212 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4d, 0x29, 0xca, 0x2c,
-	0x4b, 0x2d, 0x2a, 0xd6, 0xcf, 0x2f, 0x4b, 0x2d, 0xca, 0x49, 0xac, 0x84, 0xd1, 0x7a, 0x05, 0x45,
-	0xf9, 0x25, 0xf9, 0x42, 0xec, 0x50, 0xae, 0x94, 0x48, 0x7a, 0x7e, 0x7a, 0x3e, 0x58, 0x4c, 0x1f,
-	0xc4, 0x82, 0x48, 0x2b, 0x6d, 0x65, 0xe4, 0xe2, 0x0a, 0x48, 0x4d, 0x2d, 0x0a, 0x4a, 0x4d, 0xce,
-	0x2f, 0x4a, 0x11, 0xd2, 0xe7, 0xe2, 0x4e, 0xcd, 0x4b, 0x29, 0xc8, 0xcf, 0xcc, 0x2b, 0x89, 0xcf,
-	0x2c, 0x90, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x74, 0xe2, 0x7b, 0x74, 0x4f, 0x9e, 0xcb, 0x15, 0x2a,
-	0xec, 0x19, 0x10, 0xc4, 0x05, 0x53, 0xe2, 0x59, 0x20, 0x64, 0xc4, 0xc5, 0x03, 0xd7, 0x90, 0x9b,
-	0x98, 0x2c, 0xc1, 0x04, 0xd6, 0xc1, 0xff, 0xe8, 0x9e, 0x3c, 0x37, 0x4c, 0x87, 0xaf, 0xa3, 0x73,
-	0x10, 0xdc, 0x54, 0xdf, 0xc4, 0x64, 0x21, 0x27, 0x2e, 0xa1, 0x92, 0xd2, 0xbc, 0xbc, 0xd4, 0x9c,
-	0x78, 0x64, 0xbb, 0x98, 0xc1, 0x3a, 0x45, 0x1e, 0xdd, 0x93, 0x17, 0x08, 0x01, 0xcb, 0x22, 0xd9,
-	0x28, 0x50, 0x82, 0x2a, 0x52, 0xe0, 0x24, 0x71, 0xe3, 0xa1, 0x1c, 0xc3, 0x87, 0x87, 0x72, 0x8c,
-	0x0d, 0x8f, 0xe4, 0x18, 0x4f, 0x3c, 0x92, 0x63, 0xbc, 0xf0, 0x48, 0x8e, 0xf1, 0xc1, 0x23, 0x39,
-	0xc6, 0x24, 0x36, 0xb0, 0xc7, 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0x48, 0x07, 0xf6, 0xf3,
-	0x18, 0x01, 0x00, 0x00,
-}
diff --git a/libnetwork/drivers/overlay/overlay.proto b/libnetwork/drivers/overlay/overlay.proto
index 3133386e036c4..cfdf24285106d 100644
--- a/libnetwork/drivers/overlay/overlay.proto
+++ b/libnetwork/drivers/overlay/overlay.proto
@@ -1,6 +1,6 @@
 syntax = "proto3";
 
-import "gogoproto/gogo.proto";
+import "github.com/gogo/protobuf/gogoproto/gogo.proto";
 
 package overlay;
 
diff --git a/libnetwork/drivers/windows/overlay/overlay.proto b/libnetwork/drivers/windows/overlay/overlay.proto
index 45b8c9de7e8da..73f4a03d1e54d 100644
--- a/libnetwork/drivers/windows/overlay/overlay.proto
+++ b/libnetwork/drivers/windows/overlay/overlay.proto
@@ -1,6 +1,6 @@
 syntax = "proto3";
 
-import "gogoproto/gogo.proto";
+import "github.com/gogo/protobuf/gogoproto/gogo.proto";
 
 package overlay;
 
diff --git a/libnetwork/drivers/windows/overlay/overlay_windows.go b/libnetwork/drivers/windows/overlay/overlay_windows.go
index 19e11a25b657b..e44d2ea9ff60a 100644
--- a/libnetwork/drivers/windows/overlay/overlay_windows.go
+++ b/libnetwork/drivers/windows/overlay/overlay_windows.go
@@ -1,6 +1,6 @@
 package overlay
 
-//go:generate protoc -I.:../../Godeps/_workspace/src/github.com/gogo/protobuf  --gogo_out=import_path=github.com/docker/docker/libnetwork/drivers/overlay,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. overlay.proto
+//go:generate protoc -I=. -I=../../../../vendor/ --gogo_out=import_path=github.com/docker/docker/libnetwork/drivers/overlay:. overlay.proto
 
 import (
 	"encoding/json"
diff --git a/libnetwork/networkdb/networkdb.go b/libnetwork/networkdb/networkdb.go
index 9127eed8dbf91..9813c9f54778e 100644
--- a/libnetwork/networkdb/networkdb.go
+++ b/libnetwork/networkdb/networkdb.go
@@ -1,6 +1,6 @@
 package networkdb
 
-//go:generate protoc -I.:../vendor/github.com/gogo/protobuf --gogo_out=import_path=github.com/docker/docker/libnetwork/networkdb,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. networkdb.proto
+//go:generate protoc -I=. -I=../../vendor/ --gogofaster_out=import_path=github.com/docker/docker/libnetwork/networkdb:. networkdb.proto
 
 import (
 	"context"
diff --git a/libnetwork/networkdb/networkdb.pb.go b/libnetwork/networkdb/networkdb.pb.go
index 58faed98160bc..1ed69fae17aa1 100644
--- a/libnetwork/networkdb/networkdb.pb.go
+++ b/libnetwork/networkdb/networkdb.pb.go
@@ -1,35 +1,19 @@
 // Code generated by protoc-gen-gogo. DO NOT EDIT.
-// source: networkdb/networkdb.proto
-
-/*
-	Package networkdb is a generated protocol buffer package.
-
-	It is generated from these files:
-		networkdb/networkdb.proto
-
-	It has these top-level messages:
-		GossipMessage
-		NodeEvent
-		NetworkEvent
-		NetworkEntry
-		NetworkPushPull
-		TableEvent
-		BulkSyncMessage
-		CompoundMessage
-*/
-package networkdb
-
-import proto "github.com/gogo/protobuf/proto"
-import fmt "fmt"
-import math "math"
-import _ "github.com/gogo/protobuf/gogoproto"
+// source: networkdb.proto
 
-import github_com_hashicorp_serf_serf "github.com/hashicorp/serf/serf"
-
-import strings "strings"
-import reflect "reflect"
+package networkdb
 
-import io "io"
+import (
+	fmt "fmt"
+	_ "github.com/gogo/protobuf/gogoproto"
+	proto "github.com/gogo/protobuf/proto"
+	github_com_hashicorp_serf_serf "github.com/hashicorp/serf/serf"
+	io "io"
+	math "math"
+	math_bits "math/bits"
+	reflect "reflect"
+	strings "strings"
+)
 
 // Reference imports to suppress errors if they are not otherwise used.
 var _ = proto.Marshal
@@ -40,7 +24,7 @@ var _ = math.Inf
 // is compatible with the proto package it is being compiled against.
 // A compilation error at this line likely means your copy of the
 // proto package needs to be updated.
-const _ = proto.GoGoProtoPackageIsVersion2 // please upgrade the proto package
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
 
 // MessageType enum defines all the core message types that networkdb
 // uses to communicate to peers.
@@ -80,6 +64,7 @@ var MessageType_name = map[int32]string{
 	5: "COMPOUND",
 	6: "NODE_EVENT",
 }
+
 var MessageType_value = map[string]int32{
 	"INVALID":       0,
 	"NETWORK_EVENT": 1,
@@ -93,7 +78,10 @@ var MessageType_value = map[string]int32{
 func (x MessageType) String() string {
 	return proto.EnumName(MessageType_name, int32(x))
 }
-func (MessageType) EnumDescriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{0} }
+
+func (MessageType) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{0}
+}
 
 type NodeEvent_Type int32
 
@@ -110,6 +98,7 @@ var NodeEvent_Type_name = map[int32]string{
 	1: "JOIN",
 	2: "LEAVE",
 }
+
 var NodeEvent_Type_value = map[string]int32{
 	"INVALID": 0,
 	"JOIN":    1,
@@ -119,7 +108,10 @@ var NodeEvent_Type_value = map[string]int32{
 func (x NodeEvent_Type) String() string {
 	return proto.EnumName(NodeEvent_Type_name, int32(x))
 }
-func (NodeEvent_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{1, 0} }
+
+func (NodeEvent_Type) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{1, 0}
+}
 
 type NetworkEvent_Type int32
 
@@ -136,6 +128,7 @@ var NetworkEvent_Type_name = map[int32]string{
 	1: "JOIN",
 	2: "LEAVE",
 }
+
 var NetworkEvent_Type_value = map[string]int32{
 	"INVALID": 0,
 	"JOIN":    1,
@@ -145,8 +138,9 @@ var NetworkEvent_Type_value = map[string]int32{
 func (x NetworkEvent_Type) String() string {
 	return proto.EnumName(NetworkEvent_Type_name, int32(x))
 }
+
 func (NetworkEvent_Type) EnumDescriptor() ([]byte, []int) {
-	return fileDescriptorNetworkdb, []int{2, 0}
+	return fileDescriptor_51036566ca8c9782, []int{2, 0}
 }
 
 type TableEvent_Type int32
@@ -170,6 +164,7 @@ var TableEvent_Type_name = map[int32]string{
 	2: "UPDATE",
 	3: "DELETE",
 }
+
 var TableEvent_Type_value = map[string]int32{
 	"INVALID": 0,
 	"CREATE":  1,
@@ -180,7 +175,10 @@ var TableEvent_Type_value = map[string]int32{
 func (x TableEvent_Type) String() string {
 	return proto.EnumName(TableEvent_Type_name, int32(x))
 }
-func (TableEvent_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{5, 0} }
+
+func (TableEvent_Type) EnumDescriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{5, 0}
+}
 
 // GossipMessage is a basic message header used by all messages types.
 type GossipMessage struct {
@@ -188,9 +186,37 @@ type GossipMessage struct {
 	Data []byte      `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"`
 }
 
-func (m *GossipMessage) Reset()                    { *m = GossipMessage{} }
-func (*GossipMessage) ProtoMessage()               {}
-func (*GossipMessage) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{0} }
+func (m *GossipMessage) Reset()      { *m = GossipMessage{} }
+func (*GossipMessage) ProtoMessage() {}
+func (*GossipMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{0}
+}
+func (m *GossipMessage) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *GossipMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_GossipMessage.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *GossipMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_GossipMessage.Merge(m, src)
+}
+func (m *GossipMessage) XXX_Size() int {
+	return m.Size()
+}
+func (m *GossipMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_GossipMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_GossipMessage proto.InternalMessageInfo
 
 func (m *GossipMessage) GetType() MessageType {
 	if m != nil {
@@ -217,9 +243,37 @@ type NodeEvent struct {
 	NodeName string `protobuf:"bytes,3,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
 }
 
-func (m *NodeEvent) Reset()                    { *m = NodeEvent{} }
-func (*NodeEvent) ProtoMessage()               {}
-func (*NodeEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{1} }
+func (m *NodeEvent) Reset()      { *m = NodeEvent{} }
+func (*NodeEvent) ProtoMessage() {}
+func (*NodeEvent) Descriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{1}
+}
+func (m *NodeEvent) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *NodeEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_NodeEvent.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *NodeEvent) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_NodeEvent.Merge(m, src)
+}
+func (m *NodeEvent) XXX_Size() int {
+	return m.Size()
+}
+func (m *NodeEvent) XXX_DiscardUnknown() {
+	xxx_messageInfo_NodeEvent.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_NodeEvent proto.InternalMessageInfo
 
 func (m *NodeEvent) GetType() NodeEvent_Type {
 	if m != nil {
@@ -248,9 +302,37 @@ type NetworkEvent struct {
 	NetworkID string `protobuf:"bytes,4,opt,name=network_id,json=networkId,proto3" json:"network_id,omitempty"`
 }
 
-func (m *NetworkEvent) Reset()                    { *m = NetworkEvent{} }
-func (*NetworkEvent) ProtoMessage()               {}
-func (*NetworkEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{2} }
+func (m *NetworkEvent) Reset()      { *m = NetworkEvent{} }
+func (*NetworkEvent) ProtoMessage() {}
+func (*NetworkEvent) Descriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{2}
+}
+func (m *NetworkEvent) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *NetworkEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_NetworkEvent.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *NetworkEvent) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_NetworkEvent.Merge(m, src)
+}
+func (m *NetworkEvent) XXX_Size() int {
+	return m.Size()
+}
+func (m *NetworkEvent) XXX_DiscardUnknown() {
+	xxx_messageInfo_NetworkEvent.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_NetworkEvent proto.InternalMessageInfo
 
 func (m *NetworkEvent) GetType() NetworkEvent_Type {
 	if m != nil {
@@ -286,9 +368,37 @@ type NetworkEntry struct {
 	Leaving bool `protobuf:"varint,4,opt,name=leaving,proto3" json:"leaving,omitempty"`
 }
 
-func (m *NetworkEntry) Reset()                    { *m = NetworkEntry{} }
-func (*NetworkEntry) ProtoMessage()               {}
-func (*NetworkEntry) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{3} }
+func (m *NetworkEntry) Reset()      { *m = NetworkEntry{} }
+func (*NetworkEntry) ProtoMessage() {}
+func (*NetworkEntry) Descriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{3}
+}
+func (m *NetworkEntry) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *NetworkEntry) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_NetworkEntry.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *NetworkEntry) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_NetworkEntry.Merge(m, src)
+}
+func (m *NetworkEntry) XXX_Size() int {
+	return m.Size()
+}
+func (m *NetworkEntry) XXX_DiscardUnknown() {
+	xxx_messageInfo_NetworkEntry.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_NetworkEntry proto.InternalMessageInfo
 
 func (m *NetworkEntry) GetNetworkID() string {
 	if m != nil {
@@ -315,14 +425,42 @@ func (m *NetworkEntry) GetLeaving() bool {
 type NetworkPushPull struct {
 	// Lamport time when this push pull was initiated.
 	LTime    github_com_hashicorp_serf_serf.LamportTime `protobuf:"varint,1,opt,name=l_time,json=lTime,proto3,customtype=github.com/hashicorp/serf/serf.LamportTime" json:"l_time"`
-	Networks []*NetworkEntry                            `protobuf:"bytes,2,rep,name=networks" json:"networks,omitempty"`
+	Networks []*NetworkEntry                            `protobuf:"bytes,2,rep,name=networks,proto3" json:"networks,omitempty"`
 	// Name of the node sending this push pull payload.
 	NodeName string `protobuf:"bytes,3,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
 }
 
-func (m *NetworkPushPull) Reset()                    { *m = NetworkPushPull{} }
-func (*NetworkPushPull) ProtoMessage()               {}
-func (*NetworkPushPull) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{4} }
+func (m *NetworkPushPull) Reset()      { *m = NetworkPushPull{} }
+func (*NetworkPushPull) ProtoMessage() {}
+func (*NetworkPushPull) Descriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{4}
+}
+func (m *NetworkPushPull) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *NetworkPushPull) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_NetworkPushPull.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *NetworkPushPull) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_NetworkPushPull.Merge(m, src)
+}
+func (m *NetworkPushPull) XXX_Size() int {
+	return m.Size()
+}
+func (m *NetworkPushPull) XXX_DiscardUnknown() {
+	xxx_messageInfo_NetworkPushPull.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_NetworkPushPull proto.InternalMessageInfo
 
 func (m *NetworkPushPull) GetNetworks() []*NetworkEntry {
 	if m != nil {
@@ -357,9 +495,37 @@ type TableEvent struct {
 	ResidualReapTime int32 `protobuf:"varint,8,opt,name=residual_reap_time,json=residualReapTime,proto3" json:"residual_reap_time,omitempty"`
 }
 
-func (m *TableEvent) Reset()                    { *m = TableEvent{} }
-func (*TableEvent) ProtoMessage()               {}
-func (*TableEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{5} }
+func (m *TableEvent) Reset()      { *m = TableEvent{} }
+func (*TableEvent) ProtoMessage() {}
+func (*TableEvent) Descriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{5}
+}
+func (m *TableEvent) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *TableEvent) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_TableEvent.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *TableEvent) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_TableEvent.Merge(m, src)
+}
+func (m *TableEvent) XXX_Size() int {
+	return m.Size()
+}
+func (m *TableEvent) XXX_DiscardUnknown() {
+	xxx_messageInfo_TableEvent.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_TableEvent proto.InternalMessageInfo
 
 func (m *TableEvent) GetType() TableEvent_Type {
 	if m != nil {
@@ -421,14 +587,42 @@ type BulkSyncMessage struct {
 	NodeName string `protobuf:"bytes,3,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"`
 	// List of network names whose table entries are getting
 	// bulksynced as part of the bulksync.
-	Networks []string `protobuf:"bytes,4,rep,name=networks" json:"networks,omitempty"`
+	Networks []string `protobuf:"bytes,4,rep,name=networks,proto3" json:"networks,omitempty"`
 	// Bulksync payload
 	Payload []byte `protobuf:"bytes,5,opt,name=payload,proto3" json:"payload,omitempty"`
 }
 
-func (m *BulkSyncMessage) Reset()                    { *m = BulkSyncMessage{} }
-func (*BulkSyncMessage) ProtoMessage()               {}
-func (*BulkSyncMessage) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{6} }
+func (m *BulkSyncMessage) Reset()      { *m = BulkSyncMessage{} }
+func (*BulkSyncMessage) ProtoMessage() {}
+func (*BulkSyncMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{6}
+}
+func (m *BulkSyncMessage) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *BulkSyncMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_BulkSyncMessage.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *BulkSyncMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_BulkSyncMessage.Merge(m, src)
+}
+func (m *BulkSyncMessage) XXX_Size() int {
+	return m.Size()
+}
+func (m *BulkSyncMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_BulkSyncMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_BulkSyncMessage proto.InternalMessageInfo
 
 func (m *BulkSyncMessage) GetUnsolicited() bool {
 	if m != nil {
@@ -461,12 +655,40 @@ func (m *BulkSyncMessage) GetPayload() []byte {
 // Compound message payload definition.
 type CompoundMessage struct {
 	// A list of simple messages.
-	Messages []*CompoundMessage_SimpleMessage `protobuf:"bytes,1,rep,name=messages" json:"messages,omitempty"`
+	Messages []*CompoundMessage_SimpleMessage `protobuf:"bytes,1,rep,name=messages,proto3" json:"messages,omitempty"`
+}
+
+func (m *CompoundMessage) Reset()      { *m = CompoundMessage{} }
+func (*CompoundMessage) ProtoMessage() {}
+func (*CompoundMessage) Descriptor() ([]byte, []int) {
+	return fileDescriptor_51036566ca8c9782, []int{7}
+}
+func (m *CompoundMessage) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *CompoundMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_CompoundMessage.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *CompoundMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_CompoundMessage.Merge(m, src)
+}
+func (m *CompoundMessage) XXX_Size() int {
+	return m.Size()
+}
+func (m *CompoundMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_CompoundMessage.DiscardUnknown(m)
 }
 
-func (m *CompoundMessage) Reset()                    { *m = CompoundMessage{} }
-func (*CompoundMessage) ProtoMessage()               {}
-func (*CompoundMessage) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{7} }
+var xxx_messageInfo_CompoundMessage proto.InternalMessageInfo
 
 func (m *CompoundMessage) GetMessages() []*CompoundMessage_SimpleMessage {
 	if m != nil {
@@ -484,8 +706,34 @@ type CompoundMessage_SimpleMessage struct {
 func (m *CompoundMessage_SimpleMessage) Reset()      { *m = CompoundMessage_SimpleMessage{} }
 func (*CompoundMessage_SimpleMessage) ProtoMessage() {}
 func (*CompoundMessage_SimpleMessage) Descriptor() ([]byte, []int) {
-	return fileDescriptorNetworkdb, []int{7, 0}
+	return fileDescriptor_51036566ca8c9782, []int{7, 0}
+}
+func (m *CompoundMessage_SimpleMessage) XXX_Unmarshal(b []byte) error {
+	return m.Unmarshal(b)
+}
+func (m *CompoundMessage_SimpleMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	if deterministic {
+		return xxx_messageInfo_CompoundMessage_SimpleMessage.Marshal(b, m, deterministic)
+	} else {
+		b = b[:cap(b)]
+		n, err := m.MarshalToSizedBuffer(b)
+		if err != nil {
+			return nil, err
+		}
+		return b[:n], nil
+	}
+}
+func (m *CompoundMessage_SimpleMessage) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_CompoundMessage_SimpleMessage.Merge(m, src)
 }
+func (m *CompoundMessage_SimpleMessage) XXX_Size() int {
+	return m.Size()
+}
+func (m *CompoundMessage_SimpleMessage) XXX_DiscardUnknown() {
+	xxx_messageInfo_CompoundMessage_SimpleMessage.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CompoundMessage_SimpleMessage proto.InternalMessageInfo
 
 func (m *CompoundMessage_SimpleMessage) GetPayload() []byte {
 	if m != nil {
@@ -495,6 +743,10 @@ func (m *CompoundMessage_SimpleMessage) GetPayload() []byte {
 }
 
 func init() {
+	proto.RegisterEnum("networkdb.MessageType", MessageType_name, MessageType_value)
+	proto.RegisterEnum("networkdb.NodeEvent_Type", NodeEvent_Type_name, NodeEvent_Type_value)
+	proto.RegisterEnum("networkdb.NetworkEvent_Type", NetworkEvent_Type_name, NetworkEvent_Type_value)
+	proto.RegisterEnum("networkdb.TableEvent_Type", TableEvent_Type_name, TableEvent_Type_value)
 	proto.RegisterType((*GossipMessage)(nil), "networkdb.GossipMessage")
 	proto.RegisterType((*NodeEvent)(nil), "networkdb.NodeEvent")
 	proto.RegisterType((*NetworkEvent)(nil), "networkdb.NetworkEvent")
@@ -504,11 +756,75 @@ func init() {
 	proto.RegisterType((*BulkSyncMessage)(nil), "networkdb.BulkSyncMessage")
 	proto.RegisterType((*CompoundMessage)(nil), "networkdb.CompoundMessage")
 	proto.RegisterType((*CompoundMessage_SimpleMessage)(nil), "networkdb.CompoundMessage.SimpleMessage")
-	proto.RegisterEnum("networkdb.MessageType", MessageType_name, MessageType_value)
-	proto.RegisterEnum("networkdb.NodeEvent_Type", NodeEvent_Type_name, NodeEvent_Type_value)
-	proto.RegisterEnum("networkdb.NetworkEvent_Type", NetworkEvent_Type_name, NetworkEvent_Type_value)
-	proto.RegisterEnum("networkdb.TableEvent_Type", TableEvent_Type_name, TableEvent_Type_value)
 }
+
+func init() { proto.RegisterFile("networkdb.proto", fileDescriptor_51036566ca8c9782) }
+
+var fileDescriptor_51036566ca8c9782 = []byte{
+	// 975 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x56, 0xcd, 0x6e, 0xdb, 0x46,
+	0x10, 0xd6, 0xea, 0xcf, 0xd2, 0x58, 0xae, 0x59, 0xc6, 0x89, 0x19, 0xa6, 0xa5, 0x58, 0xd6, 0x31,
+	0x14, 0xa3, 0x91, 0x0b, 0xe7, 0x09, 0x2c, 0x89, 0x68, 0x95, 0x28, 0x94, 0x40, 0x4b, 0x2e, 0x7a,
+	0x12, 0x28, 0x73, 0x23, 0x13, 0xa6, 0x48, 0x82, 0xa4, 0x54, 0xe8, 0xd4, 0xa2, 0xa7, 0x40, 0x87,
+	0xa2, 0x2f, 0xa0, 0x53, 0x7a, 0xee, 0x03, 0x14, 0x3d, 0xf6, 0x90, 0x43, 0x0f, 0xe9, 0x2d, 0xe8,
+	0x41, 0xa8, 0xe5, 0x17, 0xe8, 0x23, 0x14, 0x5c, 0x92, 0xd2, 0x4a, 0x36, 0x02, 0x14, 0x35, 0xd0,
+	0x5c, 0xa4, 0x9d, 0x99, 0x8f, 0xb3, 0x33, 0x1f, 0xbf, 0xd9, 0x25, 0x6c, 0x5b, 0xd8, 0xff, 0xc6,
+	0x76, 0x2f, 0xf4, 0x5e, 0xd9, 0x71, 0x6d, 0xdf, 0x66, 0xf3, 0x0b, 0x07, 0xff, 0xb8, 0x6f, 0xf8,
+	0xe7, 0xc3, 0x5e, 0xf9, 0xcc, 0x1e, 0x1c, 0xf6, 0xed, 0xbe, 0x7d, 0x48, 0x10, 0xbd, 0xe1, 0x0b,
+	0x62, 0x11, 0x83, 0xac, 0xc2, 0x27, 0xa5, 0x26, 0x6c, 0x7d, 0x61, 0x7b, 0x9e, 0xe1, 0x3c, 0xc7,
+	0x9e, 0xa7, 0xf5, 0x31, 0x7b, 0x00, 0x69, 0x7f, 0xec, 0x60, 0x0e, 0x89, 0xa8, 0xf4, 0xc1, 0xd1,
+	0xbd, 0xf2, 0x72, 0xab, 0x08, 0xd1, 0x1e, 0x3b, 0x58, 0x25, 0x18, 0x96, 0x85, 0xb4, 0xae, 0xf9,
+	0x1a, 0x97, 0x14, 0x51, 0xa9, 0xa0, 0x92, 0xb5, 0xf4, 0x2a, 0x09, 0x79, 0xc5, 0xd6, 0xb1, 0x3c,
+	0xc2, 0x96, 0xcf, 0x3e, 0x5e, 0xc9, 0x76, 0x9f, 0xca, 0xb6, 0xc0, 0x94, 0xa9, 0x84, 0x75, 0xc8,
+	0x9a, 0x5d, 0xdf, 0x18, 0x60, 0x92, 0x32, 0x5d, 0x39, 0x7a, 0x3d, 0x2b, 0x26, 0xfe, 0x9c, 0x15,
+	0x0f, 0xa8, 0xa6, 0xce, 0x35, 0xef, 0xdc, 0x38, 0xb3, 0x5d, 0xe7, 0xd0, 0xc3, 0xee, 0x0b, 0xf2,
+	0x53, 0x6e, 0x68, 0x03, 0xc7, 0x76, 0xfd, 0xb6, 0x31, 0xc0, 0x6a, 0xc6, 0x0c, 0xfe, 0xd8, 0x07,
+	0x90, 0xb7, 0x6c, 0x1d, 0x77, 0x2d, 0x6d, 0x80, 0xb9, 0x94, 0x88, 0x4a, 0x79, 0x35, 0x17, 0x38,
+	0x14, 0x6d, 0x80, 0xa5, 0x6f, 0x21, 0x1d, 0xec, 0xca, 0x3e, 0x84, 0x8d, 0xba, 0x72, 0x7a, 0xdc,
+	0xa8, 0xd7, 0x98, 0x04, 0xcf, 0x4d, 0xa6, 0xe2, 0xce, 0xa2, 0xac, 0x20, 0x5e, 0xb7, 0x46, 0x9a,
+	0x69, 0xe8, 0x6c, 0x11, 0xd2, 0x4f, 0x9b, 0x75, 0x85, 0x41, 0xfc, 0xdd, 0xc9, 0x54, 0xfc, 0x70,
+	0x05, 0xf3, 0xd4, 0x36, 0x2c, 0xf6, 0x13, 0xc8, 0x34, 0xe4, 0xe3, 0x53, 0x99, 0x49, 0xf2, 0xf7,
+	0x26, 0x53, 0x91, 0x5d, 0x41, 0x34, 0xb0, 0x36, 0xc2, 0x7c, 0xe1, 0xe5, 0x2b, 0x21, 0xf1, 0xcb,
+	0x4f, 0x02, 0xd9, 0x58, 0xba, 0x4c, 0x42, 0x41, 0x09, 0xb9, 0x08, 0x89, 0xfa, 0x7c, 0x85, 0xa8,
+	0x8f, 0x68, 0xa2, 0x28, 0xd8, 0xff, 0xc0, 0x15, 0xfb, 0x19, 0x40, 0x54, 0x4c, 0xd7, 0xd0, 0xb9,
+	0x74, 0x10, 0xad, 0x6c, 0xcd, 0x67, 0xc5, 0x7c, 0x54, 0x58, 0xbd, 0xa6, 0xc6, 0xf2, 0xab, 0xeb,
+	0xd2, 0x4b, 0x14, 0x51, 0x5b, 0xa2, 0xa9, 0x7d, 0x30, 0x99, 0x8a, 0xbb, 0x74, 0x23, 0x34, 0xbb,
+	0xd2, 0x82, 0xdd, 0xf0, 0x0d, 0xac, 0xc1, 0x08, 0xc1, 0x7b, 0x4b, 0x82, 0xef, 0x4f, 0xa6, 0xe2,
+	0xdd, 0x75, 0xd0, 0x4d, 0x1c, 0xff, 0x8e, 0x96, 0x1c, 0x5b, 0xbe, 0x3b, 0x5e, 0xeb, 0x04, 0xbd,
+	0xbb, 0x93, 0xdb, 0xe4, 0xf7, 0xd1, 0x35, 0x7e, 0x2b, 0x85, 0xf9, 0xac, 0x98, 0x53, 0x22, 0x8e,
+	0x29, 0xb6, 0x39, 0xd8, 0x30, 0xb1, 0x36, 0x32, 0xac, 0x3e, 0xa1, 0x3a, 0xa7, 0xc6, 0xa6, 0xf4,
+	0x2b, 0x82, 0xed, 0xa8, 0xd0, 0xd6, 0xd0, 0x3b, 0x6f, 0x0d, 0x4d, 0x93, 0xaa, 0x11, 0xfd, 0xd7,
+	0x1a, 0x9f, 0x40, 0x2e, 0xea, 0xdd, 0xe3, 0x92, 0x62, 0xaa, 0xb4, 0x79, 0xb4, 0x7b, 0x83, 0x08,
+	0x03, 0x1e, 0xd5, 0x05, 0xf0, 0x5f, 0x34, 0x26, 0xfd, 0x90, 0x06, 0x68, 0x6b, 0x3d, 0x33, 0x3a,
+	0x18, 0xca, 0x2b, 0x7a, 0xe7, 0xa9, 0xad, 0x96, 0xa0, 0xf7, 0x5e, 0xed, 0xec, 0xc7, 0x00, 0x7e,
+	0x50, 0x6e, 0x98, 0x2b, 0x43, 0x72, 0xe5, 0x89, 0x87, 0x24, 0x63, 0x20, 0x75, 0x81, 0xc7, 0x5c,
+	0x96, 0xf8, 0x83, 0x25, 0xbb, 0x03, 0x99, 0x91, 0x66, 0x0e, 0x31, 0xb7, 0x41, 0x8e, 0xcc, 0xd0,
+	0x60, 0x2b, 0xc0, 0xba, 0xd8, 0x33, 0xf4, 0xa1, 0x66, 0x76, 0x5d, 0xac, 0x39, 0x61, 0xa3, 0x39,
+	0x11, 0x95, 0x32, 0x95, 0x9d, 0xf9, 0xac, 0xc8, 0xa8, 0x51, 0x54, 0xc5, 0x9a, 0x43, 0x5a, 0x61,
+	0xdc, 0x35, 0x8f, 0xf4, 0x73, 0x3c, 0x78, 0xfb, 0xf4, 0xe0, 0x91, 0x61, 0x59, 0x32, 0x4a, 0x8f,
+	0xdd, 0x1e, 0x64, 0xab, 0xaa, 0x7c, 0xdc, 0x96, 0xe3, 0xc1, 0x5b, 0x85, 0x55, 0x5d, 0xac, 0xf9,
+	0x38, 0x40, 0x75, 0x5a, 0xb5, 0x00, 0x95, 0xbc, 0x09, 0xd5, 0x71, 0xf4, 0x08, 0x55, 0x93, 0x1b,
+	0x72, 0x5b, 0x66, 0x52, 0x37, 0xa1, 0x6a, 0xd8, 0xc4, 0xfe, 0xfa, 0x78, 0xfe, 0x81, 0x60, 0xbb,
+	0x32, 0x34, 0x2f, 0x4e, 0xc6, 0xd6, 0x59, 0x7c, 0xf9, 0xdc, 0xa2, 0x9e, 0x45, 0xd8, 0x1c, 0x5a,
+	0x9e, 0x6d, 0x1a, 0x67, 0x86, 0x8f, 0x75, 0xa2, 0x9a, 0x9c, 0x4a, 0xbb, 0xde, 0xad, 0x03, 0x9e,
+	0x1a, 0x87, 0xb4, 0x98, 0x22, 0xb1, 0x58, 0xf5, 0x1c, 0x6c, 0x38, 0xda, 0xd8, 0xb4, 0x35, 0x9d,
+	0xbc, 0xf2, 0x82, 0x1a, 0x9b, 0xd2, 0xf7, 0x08, 0xb6, 0xab, 0xf6, 0xc0, 0xb1, 0x87, 0x96, 0x1e,
+	0xf7, 0x54, 0x83, 0xdc, 0x20, 0x5c, 0x7a, 0x1c, 0x22, 0x83, 0x55, 0xa2, 0xd4, 0xbe, 0x86, 0x2e,
+	0x9f, 0x18, 0x03, 0xc7, 0xc4, 0x91, 0xa5, 0x2e, 0x9e, 0xe4, 0x1f, 0xc1, 0xd6, 0x4a, 0x28, 0x28,
+	0xa2, 0x15, 0x15, 0x81, 0xc2, 0x22, 0x22, 0xf3, 0xe0, 0xb7, 0x24, 0x6c, 0x52, 0x77, 0x35, 0xfb,
+	0x29, 0x2d, 0x08, 0x72, 0x3d, 0x51, 0xd1, 0x58, 0x0d, 0x65, 0xd8, 0x52, 0xe4, 0xf6, 0x57, 0x4d,
+	0xf5, 0x59, 0x57, 0x3e, 0x95, 0x95, 0x36, 0x83, 0xc2, 0x43, 0x9b, 0x82, 0xae, 0xdc, 0x57, 0x07,
+	0xb0, 0xd9, 0x3e, 0xae, 0x34, 0xe4, 0x08, 0x1d, 0x1d, 0xcb, 0x14, 0x9a, 0x9a, 0xf5, 0x7d, 0xc8,
+	0xb7, 0x3a, 0x27, 0x5f, 0x76, 0x5b, 0x9d, 0x46, 0x83, 0x49, 0xf1, 0xbb, 0x93, 0xa9, 0x78, 0x87,
+	0x42, 0x2e, 0x4e, 0xb3, 0x7d, 0xc8, 0x57, 0x3a, 0x8d, 0x67, 0xdd, 0x93, 0xaf, 0x95, 0x2a, 0x93,
+	0xbe, 0x86, 0x8b, 0xc5, 0xc2, 0x3e, 0x84, 0x5c, 0xb5, 0xf9, 0xbc, 0xd5, 0xec, 0x28, 0x35, 0x26,
+	0x73, 0x0d, 0x16, 0x33, 0xca, 0x96, 0x00, 0x94, 0x66, 0x2d, 0xae, 0x30, 0x1b, 0x0a, 0x93, 0xee,
+	0x27, 0xbe, 0xa4, 0xf9, 0x3b, 0x91, 0x30, 0x69, 0xda, 0x2a, 0x7b, 0x6f, 0x2f, 0x85, 0xc4, 0xdf,
+	0x97, 0x02, 0xfa, 0x6e, 0x2e, 0xa0, 0xd7, 0x73, 0x01, 0xbd, 0x99, 0x0b, 0xe8, 0xaf, 0xb9, 0x80,
+	0x7e, 0xbc, 0x12, 0x12, 0x6f, 0xae, 0x84, 0xc4, 0xdb, 0x2b, 0x21, 0xd1, 0xcb, 0x92, 0xcf, 0xa8,
+	0x27, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x82, 0xf0, 0x4d, 0x63, 0x93, 0x09, 0x00, 0x00,
+}
+
 func (this *GossipMessage) GoString() string {
 	if this == nil {
 		return "nil"
@@ -636,7 +952,7 @@ func valueToGoStringNetworkdb(v interface{}, typ string) string {
 func (m *GossipMessage) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -644,28 +960,34 @@ func (m *GossipMessage) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *GossipMessage) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *GossipMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if m.Type != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
-	}
 	if len(m.Data) > 0 {
-		dAtA[i] = 0x12
-		i++
+		i -= len(m.Data)
+		copy(dAtA[i:], m.Data)
 		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Data)))
-		i += copy(dAtA[i:], m.Data)
+		i--
+		dAtA[i] = 0x12
+	}
+	if m.Type != 0 {
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
+		i--
+		dAtA[i] = 0x8
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func (m *NodeEvent) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -673,33 +995,39 @@ func (m *NodeEvent) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *NodeEvent) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *NodeEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if m.Type != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
+	if len(m.NodeName) > 0 {
+		i -= len(m.NodeName)
+		copy(dAtA[i:], m.NodeName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
+		i--
+		dAtA[i] = 0x1a
 	}
 	if m.LTime != 0 {
-		dAtA[i] = 0x10
-		i++
 		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
+		i--
+		dAtA[i] = 0x10
 	}
-	if len(m.NodeName) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
-		i += copy(dAtA[i:], m.NodeName)
+	if m.Type != 0 {
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
+		i--
+		dAtA[i] = 0x8
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func (m *NetworkEvent) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -707,39 +1035,46 @@ func (m *NetworkEvent) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *NetworkEvent) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *NetworkEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if m.Type != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
-	}
-	if m.LTime != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
+	if len(m.NetworkID) > 0 {
+		i -= len(m.NetworkID)
+		copy(dAtA[i:], m.NetworkID)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NetworkID)))
+		i--
+		dAtA[i] = 0x22
 	}
 	if len(m.NodeName) > 0 {
-		dAtA[i] = 0x1a
-		i++
+		i -= len(m.NodeName)
+		copy(dAtA[i:], m.NodeName)
 		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
-		i += copy(dAtA[i:], m.NodeName)
+		i--
+		dAtA[i] = 0x1a
 	}
-	if len(m.NetworkID) > 0 {
-		dAtA[i] = 0x22
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NetworkID)))
-		i += copy(dAtA[i:], m.NetworkID)
+	if m.LTime != 0 {
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
+		i--
+		dAtA[i] = 0x10
+	}
+	if m.Type != 0 {
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
+		i--
+		dAtA[i] = 0x8
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func (m *NetworkEntry) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -747,44 +1082,51 @@ func (m *NetworkEntry) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *NetworkEntry) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *NetworkEntry) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if len(m.NetworkID) > 0 {
-		dAtA[i] = 0xa
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NetworkID)))
-		i += copy(dAtA[i:], m.NetworkID)
-	}
-	if m.LTime != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
-	}
-	if len(m.NodeName) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
-		i += copy(dAtA[i:], m.NodeName)
-	}
 	if m.Leaving {
-		dAtA[i] = 0x20
-		i++
+		i--
 		if m.Leaving {
 			dAtA[i] = 1
 		} else {
 			dAtA[i] = 0
 		}
-		i++
+		i--
+		dAtA[i] = 0x20
+	}
+	if len(m.NodeName) > 0 {
+		i -= len(m.NodeName)
+		copy(dAtA[i:], m.NodeName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
+		i--
+		dAtA[i] = 0x1a
+	}
+	if m.LTime != 0 {
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
+		i--
+		dAtA[i] = 0x10
+	}
+	if len(m.NetworkID) > 0 {
+		i -= len(m.NetworkID)
+		copy(dAtA[i:], m.NetworkID)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NetworkID)))
+		i--
+		dAtA[i] = 0xa
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func (m *NetworkPushPull) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -792,40 +1134,48 @@ func (m *NetworkPushPull) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *NetworkPushPull) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *NetworkPushPull) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if m.LTime != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
+	if len(m.NodeName) > 0 {
+		i -= len(m.NodeName)
+		copy(dAtA[i:], m.NodeName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
+		i--
+		dAtA[i] = 0x1a
 	}
 	if len(m.Networks) > 0 {
-		for _, msg := range m.Networks {
-			dAtA[i] = 0x12
-			i++
-			i = encodeVarintNetworkdb(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
+		for iNdEx := len(m.Networks) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.Networks[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintNetworkdb(dAtA, i, uint64(size))
 			}
-			i += n
+			i--
+			dAtA[i] = 0x12
 		}
 	}
-	if len(m.NodeName) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
-		i += copy(dAtA[i:], m.NodeName)
+	if m.LTime != 0 {
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
+		i--
+		dAtA[i] = 0x8
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func (m *TableEvent) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -833,62 +1183,72 @@ func (m *TableEvent) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *TableEvent) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *TableEvent) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if m.Type != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
-	}
-	if m.LTime != 0 {
-		dAtA[i] = 0x10
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
+	if m.ResidualReapTime != 0 {
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.ResidualReapTime))
+		i--
+		dAtA[i] = 0x40
 	}
-	if len(m.NodeName) > 0 {
-		dAtA[i] = 0x1a
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
-		i += copy(dAtA[i:], m.NodeName)
+	if len(m.Value) > 0 {
+		i -= len(m.Value)
+		copy(dAtA[i:], m.Value)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Value)))
+		i--
+		dAtA[i] = 0x3a
 	}
-	if len(m.NetworkID) > 0 {
-		dAtA[i] = 0x22
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NetworkID)))
-		i += copy(dAtA[i:], m.NetworkID)
+	if len(m.Key) > 0 {
+		i -= len(m.Key)
+		copy(dAtA[i:], m.Key)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Key)))
+		i--
+		dAtA[i] = 0x32
 	}
 	if len(m.TableName) > 0 {
-		dAtA[i] = 0x2a
-		i++
+		i -= len(m.TableName)
+		copy(dAtA[i:], m.TableName)
 		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.TableName)))
-		i += copy(dAtA[i:], m.TableName)
+		i--
+		dAtA[i] = 0x2a
 	}
-	if len(m.Key) > 0 {
-		dAtA[i] = 0x32
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Key)))
-		i += copy(dAtA[i:], m.Key)
+	if len(m.NetworkID) > 0 {
+		i -= len(m.NetworkID)
+		copy(dAtA[i:], m.NetworkID)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NetworkID)))
+		i--
+		dAtA[i] = 0x22
 	}
-	if len(m.Value) > 0 {
-		dAtA[i] = 0x3a
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Value)))
-		i += copy(dAtA[i:], m.Value)
+	if len(m.NodeName) > 0 {
+		i -= len(m.NodeName)
+		copy(dAtA[i:], m.NodeName)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
+		i--
+		dAtA[i] = 0x1a
 	}
-	if m.ResidualReapTime != 0 {
-		dAtA[i] = 0x40
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(m.ResidualReapTime))
+	if m.LTime != 0 {
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
+		i--
+		dAtA[i] = 0x10
 	}
-	return i, nil
+	if m.Type != 0 {
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.Type))
+		i--
+		dAtA[i] = 0x8
+	}
+	return len(dAtA) - i, nil
 }
 
 func (m *BulkSyncMessage) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -896,59 +1256,60 @@ func (m *BulkSyncMessage) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *BulkSyncMessage) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *BulkSyncMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
-	if m.LTime != 0 {
-		dAtA[i] = 0x8
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
+	if len(m.Payload) > 0 {
+		i -= len(m.Payload)
+		copy(dAtA[i:], m.Payload)
+		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Payload)))
+		i--
+		dAtA[i] = 0x2a
 	}
-	if m.Unsolicited {
-		dAtA[i] = 0x10
-		i++
-		if m.Unsolicited {
-			dAtA[i] = 1
-		} else {
-			dAtA[i] = 0
+	if len(m.Networks) > 0 {
+		for iNdEx := len(m.Networks) - 1; iNdEx >= 0; iNdEx-- {
+			i -= len(m.Networks[iNdEx])
+			copy(dAtA[i:], m.Networks[iNdEx])
+			i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Networks[iNdEx])))
+			i--
+			dAtA[i] = 0x22
 		}
-		i++
 	}
 	if len(m.NodeName) > 0 {
-		dAtA[i] = 0x1a
-		i++
+		i -= len(m.NodeName)
+		copy(dAtA[i:], m.NodeName)
 		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.NodeName)))
-		i += copy(dAtA[i:], m.NodeName)
+		i--
+		dAtA[i] = 0x1a
 	}
-	if len(m.Networks) > 0 {
-		for _, s := range m.Networks {
-			dAtA[i] = 0x22
-			i++
-			l = len(s)
-			for l >= 1<<7 {
-				dAtA[i] = uint8(uint64(l)&0x7f | 0x80)
-				l >>= 7
-				i++
-			}
-			dAtA[i] = uint8(l)
-			i++
-			i += copy(dAtA[i:], s)
+	if m.Unsolicited {
+		i--
+		if m.Unsolicited {
+			dAtA[i] = 1
+		} else {
+			dAtA[i] = 0
 		}
+		i--
+		dAtA[i] = 0x10
 	}
-	if len(m.Payload) > 0 {
-		dAtA[i] = 0x2a
-		i++
-		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Payload)))
-		i += copy(dAtA[i:], m.Payload)
+	if m.LTime != 0 {
+		i = encodeVarintNetworkdb(dAtA, i, uint64(m.LTime))
+		i--
+		dAtA[i] = 0x8
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func (m *CompoundMessage) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -956,29 +1317,36 @@ func (m *CompoundMessage) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *CompoundMessage) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *CompoundMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
 	if len(m.Messages) > 0 {
-		for _, msg := range m.Messages {
-			dAtA[i] = 0xa
-			i++
-			i = encodeVarintNetworkdb(dAtA, i, uint64(msg.Size()))
-			n, err := msg.MarshalTo(dAtA[i:])
-			if err != nil {
-				return 0, err
+		for iNdEx := len(m.Messages) - 1; iNdEx >= 0; iNdEx-- {
+			{
+				size, err := m.Messages[iNdEx].MarshalToSizedBuffer(dAtA[:i])
+				if err != nil {
+					return 0, err
+				}
+				i -= size
+				i = encodeVarintNetworkdb(dAtA, i, uint64(size))
 			}
-			i += n
+			i--
+			dAtA[i] = 0xa
 		}
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func (m *CompoundMessage_SimpleMessage) Marshal() (dAtA []byte, err error) {
 	size := m.Size()
 	dAtA = make([]byte, size)
-	n, err := m.MarshalTo(dAtA)
+	n, err := m.MarshalToSizedBuffer(dAtA[:size])
 	if err != nil {
 		return nil, err
 	}
@@ -986,29 +1354,40 @@ func (m *CompoundMessage_SimpleMessage) Marshal() (dAtA []byte, err error) {
 }
 
 func (m *CompoundMessage_SimpleMessage) MarshalTo(dAtA []byte) (int, error) {
-	var i int
+	size := m.Size()
+	return m.MarshalToSizedBuffer(dAtA[:size])
+}
+
+func (m *CompoundMessage_SimpleMessage) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+	i := len(dAtA)
 	_ = i
 	var l int
 	_ = l
 	if len(m.Payload) > 0 {
-		dAtA[i] = 0xa
-		i++
+		i -= len(m.Payload)
+		copy(dAtA[i:], m.Payload)
 		i = encodeVarintNetworkdb(dAtA, i, uint64(len(m.Payload)))
-		i += copy(dAtA[i:], m.Payload)
+		i--
+		dAtA[i] = 0xa
 	}
-	return i, nil
+	return len(dAtA) - i, nil
 }
 
 func encodeVarintNetworkdb(dAtA []byte, offset int, v uint64) int {
+	offset -= sovNetworkdb(v)
+	base := offset
 	for v >= 1<<7 {
 		dAtA[offset] = uint8(v&0x7f | 0x80)
 		v >>= 7
 		offset++
 	}
 	dAtA[offset] = uint8(v)
-	return offset + 1
+	return base
 }
 func (m *GossipMessage) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	if m.Type != 0 {
@@ -1022,6 +1401,9 @@ func (m *GossipMessage) Size() (n int) {
 }
 
 func (m *NodeEvent) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	if m.Type != 0 {
@@ -1038,6 +1420,9 @@ func (m *NodeEvent) Size() (n int) {
 }
 
 func (m *NetworkEvent) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	if m.Type != 0 {
@@ -1058,6 +1443,9 @@ func (m *NetworkEvent) Size() (n int) {
 }
 
 func (m *NetworkEntry) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	l = len(m.NetworkID)
@@ -1078,6 +1466,9 @@ func (m *NetworkEntry) Size() (n int) {
 }
 
 func (m *NetworkPushPull) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	if m.LTime != 0 {
@@ -1097,6 +1488,9 @@ func (m *NetworkPushPull) Size() (n int) {
 }
 
 func (m *TableEvent) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	if m.Type != 0 {
@@ -1132,6 +1526,9 @@ func (m *TableEvent) Size() (n int) {
 }
 
 func (m *BulkSyncMessage) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	if m.LTime != 0 {
@@ -1158,6 +1555,9 @@ func (m *BulkSyncMessage) Size() (n int) {
 }
 
 func (m *CompoundMessage) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	if len(m.Messages) > 0 {
@@ -1170,6 +1570,9 @@ func (m *CompoundMessage) Size() (n int) {
 }
 
 func (m *CompoundMessage_SimpleMessage) Size() (n int) {
+	if m == nil {
+		return 0
+	}
 	var l int
 	_ = l
 	l = len(m.Payload)
@@ -1180,14 +1583,7 @@ func (m *CompoundMessage_SimpleMessage) Size() (n int) {
 }
 
 func sovNetworkdb(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
+	return (math_bits.Len64(x|1) + 6) / 7
 }
 func sozNetworkdb(x uint64) (n int) {
 	return sovNetworkdb(uint64((x << 1) ^ uint64((int64(x) >> 63))))
@@ -1245,9 +1641,14 @@ func (this *NetworkPushPull) String() string {
 	if this == nil {
 		return "nil"
 	}
+	repeatedStringForNetworks := "[]*NetworkEntry{"
+	for _, f := range this.Networks {
+		repeatedStringForNetworks += strings.Replace(f.String(), "NetworkEntry", "NetworkEntry", 1) + ","
+	}
+	repeatedStringForNetworks += "}"
 	s := strings.Join([]string{`&NetworkPushPull{`,
 		`LTime:` + fmt.Sprintf("%v", this.LTime) + `,`,
-		`Networks:` + strings.Replace(fmt.Sprintf("%v", this.Networks), "NetworkEntry", "NetworkEntry", 1) + `,`,
+		`Networks:` + repeatedStringForNetworks + `,`,
 		`NodeName:` + fmt.Sprintf("%v", this.NodeName) + `,`,
 		`}`,
 	}, "")
@@ -1288,8 +1689,13 @@ func (this *CompoundMessage) String() string {
 	if this == nil {
 		return "nil"
 	}
+	repeatedStringForMessages := "[]*CompoundMessage_SimpleMessage{"
+	for _, f := range this.Messages {
+		repeatedStringForMessages += strings.Replace(fmt.Sprintf("%v", f), "CompoundMessage_SimpleMessage", "CompoundMessage_SimpleMessage", 1) + ","
+	}
+	repeatedStringForMessages += "}"
 	s := strings.Join([]string{`&CompoundMessage{`,
-		`Messages:` + strings.Replace(fmt.Sprintf("%v", this.Messages), "CompoundMessage_SimpleMessage", "CompoundMessage_SimpleMessage", 1) + `,`,
+		`Messages:` + repeatedStringForMessages + `,`,
 		`}`,
 	}, "")
 	return s
@@ -1327,7 +1733,7 @@ func (m *GossipMessage) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -1355,7 +1761,7 @@ func (m *GossipMessage) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.Type |= (MessageType(b) & 0x7F) << shift
+				m.Type |= MessageType(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1374,7 +1780,7 @@ func (m *GossipMessage) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
+				byteLen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1383,6 +1789,9 @@ func (m *GossipMessage) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + byteLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -1397,7 +1806,7 @@ func (m *GossipMessage) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthNetworkdb
 			}
 			if (iNdEx + skippy) > l {
@@ -1427,7 +1836,7 @@ func (m *NodeEvent) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -1455,7 +1864,7 @@ func (m *NodeEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.Type |= (NodeEvent_Type(b) & 0x7F) << shift
+				m.Type |= NodeEvent_Type(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1474,7 +1883,7 @@ func (m *NodeEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
+				m.LTime |= github_com_hashicorp_serf_serf.LamportTime(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1493,7 +1902,7 @@ func (m *NodeEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1503,6 +1912,9 @@ func (m *NodeEvent) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -1514,7 +1926,7 @@ func (m *NodeEvent) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthNetworkdb
 			}
 			if (iNdEx + skippy) > l {
@@ -1544,7 +1956,7 @@ func (m *NetworkEvent) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -1572,7 +1984,7 @@ func (m *NetworkEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.Type |= (NetworkEvent_Type(b) & 0x7F) << shift
+				m.Type |= NetworkEvent_Type(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1591,7 +2003,7 @@ func (m *NetworkEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
+				m.LTime |= github_com_hashicorp_serf_serf.LamportTime(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1610,7 +2022,7 @@ func (m *NetworkEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1620,6 +2032,9 @@ func (m *NetworkEvent) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -1639,7 +2054,7 @@ func (m *NetworkEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1649,6 +2064,9 @@ func (m *NetworkEvent) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -1660,7 +2078,7 @@ func (m *NetworkEvent) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthNetworkdb
 			}
 			if (iNdEx + skippy) > l {
@@ -1690,7 +2108,7 @@ func (m *NetworkEntry) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -1718,7 +2136,7 @@ func (m *NetworkEntry) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1728,6 +2146,9 @@ func (m *NetworkEntry) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -1747,7 +2168,7 @@ func (m *NetworkEntry) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
+				m.LTime |= github_com_hashicorp_serf_serf.LamportTime(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1766,7 +2187,7 @@ func (m *NetworkEntry) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1776,6 +2197,9 @@ func (m *NetworkEntry) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -1795,7 +2219,7 @@ func (m *NetworkEntry) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= (int(b) & 0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1807,7 +2231,7 @@ func (m *NetworkEntry) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthNetworkdb
 			}
 			if (iNdEx + skippy) > l {
@@ -1837,7 +2261,7 @@ func (m *NetworkPushPull) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -1865,7 +2289,7 @@ func (m *NetworkPushPull) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
+				m.LTime |= github_com_hashicorp_serf_serf.LamportTime(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1884,7 +2308,7 @@ func (m *NetworkPushPull) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
+				msglen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1893,6 +2317,9 @@ func (m *NetworkPushPull) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -1915,7 +2342,7 @@ func (m *NetworkPushPull) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -1925,6 +2352,9 @@ func (m *NetworkPushPull) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -1936,7 +2366,7 @@ func (m *NetworkPushPull) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthNetworkdb
 			}
 			if (iNdEx + skippy) > l {
@@ -1966,7 +2396,7 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -1994,7 +2424,7 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.Type |= (TableEvent_Type(b) & 0x7F) << shift
+				m.Type |= TableEvent_Type(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2013,7 +2443,7 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
+				m.LTime |= github_com_hashicorp_serf_serf.LamportTime(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2032,7 +2462,7 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2042,6 +2472,9 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -2061,7 +2494,7 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2071,6 +2504,9 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -2090,7 +2526,7 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2100,6 +2536,9 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -2119,7 +2558,7 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2129,6 +2568,9 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -2148,7 +2590,7 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
+				byteLen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2157,6 +2599,9 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + byteLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -2179,7 +2624,7 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.ResidualReapTime |= (int32(b) & 0x7F) << shift
+				m.ResidualReapTime |= int32(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2190,7 +2635,7 @@ func (m *TableEvent) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthNetworkdb
 			}
 			if (iNdEx + skippy) > l {
@@ -2220,7 +2665,7 @@ func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -2248,7 +2693,7 @@ func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift
+				m.LTime |= github_com_hashicorp_serf_serf.LamportTime(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2267,7 +2712,7 @@ func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				v |= (int(b) & 0x7F) << shift
+				v |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2287,7 +2732,7 @@ func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2297,6 +2742,9 @@ func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -2316,7 +2764,7 @@ func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				stringLen |= (uint64(b) & 0x7F) << shift
+				stringLen |= uint64(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2326,6 +2774,9 @@ func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + intStringLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -2345,7 +2796,7 @@ func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
+				byteLen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2354,6 +2805,9 @@ func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + byteLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -2368,7 +2822,7 @@ func (m *BulkSyncMessage) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthNetworkdb
 			}
 			if (iNdEx + skippy) > l {
@@ -2398,7 +2852,7 @@ func (m *CompoundMessage) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -2426,7 +2880,7 @@ func (m *CompoundMessage) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				msglen |= (int(b) & 0x7F) << shift
+				msglen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2435,6 +2889,9 @@ func (m *CompoundMessage) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + msglen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -2449,7 +2906,7 @@ func (m *CompoundMessage) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthNetworkdb
 			}
 			if (iNdEx + skippy) > l {
@@ -2479,7 +2936,7 @@ func (m *CompoundMessage_SimpleMessage) Unmarshal(dAtA []byte) error {
 			}
 			b := dAtA[iNdEx]
 			iNdEx++
-			wire |= (uint64(b) & 0x7F) << shift
+			wire |= uint64(b&0x7F) << shift
 			if b < 0x80 {
 				break
 			}
@@ -2507,7 +2964,7 @@ func (m *CompoundMessage_SimpleMessage) Unmarshal(dAtA []byte) error {
 				}
 				b := dAtA[iNdEx]
 				iNdEx++
-				byteLen |= (int(b) & 0x7F) << shift
+				byteLen |= int(b&0x7F) << shift
 				if b < 0x80 {
 					break
 				}
@@ -2516,6 +2973,9 @@ func (m *CompoundMessage_SimpleMessage) Unmarshal(dAtA []byte) error {
 				return ErrInvalidLengthNetworkdb
 			}
 			postIndex := iNdEx + byteLen
+			if postIndex < 0 {
+				return ErrInvalidLengthNetworkdb
+			}
 			if postIndex > l {
 				return io.ErrUnexpectedEOF
 			}
@@ -2530,7 +2990,7 @@ func (m *CompoundMessage_SimpleMessage) Unmarshal(dAtA []byte) error {
 			if err != nil {
 				return err
 			}
-			if skippy < 0 {
+			if (skippy < 0) || (iNdEx+skippy) < 0 {
 				return ErrInvalidLengthNetworkdb
 			}
 			if (iNdEx + skippy) > l {
@@ -2548,6 +3008,7 @@ func (m *CompoundMessage_SimpleMessage) Unmarshal(dAtA []byte) error {
 func skipNetworkdb(dAtA []byte) (n int, err error) {
 	l := len(dAtA)
 	iNdEx := 0
+	depth := 0
 	for iNdEx < l {
 		var wire uint64
 		for shift := uint(0); ; shift += 7 {
@@ -2579,10 +3040,8 @@ func skipNetworkdb(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			return iNdEx, nil
 		case 1:
 			iNdEx += 8
-			return iNdEx, nil
 		case 2:
 			var length int
 			for shift := uint(0); ; shift += 7 {
@@ -2599,119 +3058,34 @@ func skipNetworkdb(dAtA []byte) (n int, err error) {
 					break
 				}
 			}
-			iNdEx += length
 			if length < 0 {
 				return 0, ErrInvalidLengthNetworkdb
 			}
-			return iNdEx, nil
+			iNdEx += length
 		case 3:
-			for {
-				var innerWire uint64
-				var start int = iNdEx
-				for shift := uint(0); ; shift += 7 {
-					if shift >= 64 {
-						return 0, ErrIntOverflowNetworkdb
-					}
-					if iNdEx >= l {
-						return 0, io.ErrUnexpectedEOF
-					}
-					b := dAtA[iNdEx]
-					iNdEx++
-					innerWire |= (uint64(b) & 0x7F) << shift
-					if b < 0x80 {
-						break
-					}
-				}
-				innerWireType := int(innerWire & 0x7)
-				if innerWireType == 4 {
-					break
-				}
-				next, err := skipNetworkdb(dAtA[start:])
-				if err != nil {
-					return 0, err
-				}
-				iNdEx = start + next
-			}
-			return iNdEx, nil
+			depth++
 		case 4:
-			return iNdEx, nil
+			if depth == 0 {
+				return 0, ErrUnexpectedEndOfGroupNetworkdb
+			}
+			depth--
 		case 5:
 			iNdEx += 4
-			return iNdEx, nil
 		default:
 			return 0, fmt.Errorf("proto: illegal wireType %d", wireType)
 		}
+		if iNdEx < 0 {
+			return 0, ErrInvalidLengthNetworkdb
+		}
+		if depth == 0 {
+			return iNdEx, nil
+		}
 	}
-	panic("unreachable")
+	return 0, io.ErrUnexpectedEOF
 }
 
 var (
-	ErrInvalidLengthNetworkdb = fmt.Errorf("proto: negative length found during unmarshaling")
-	ErrIntOverflowNetworkdb   = fmt.Errorf("proto: integer overflow")
+	ErrInvalidLengthNetworkdb        = fmt.Errorf("proto: negative length found during unmarshaling")
+	ErrIntOverflowNetworkdb          = fmt.Errorf("proto: integer overflow")
+	ErrUnexpectedEndOfGroupNetworkdb = fmt.Errorf("proto: unexpected end of group")
 )
-
-func init() { proto.RegisterFile("networkdb/networkdb.proto", fileDescriptorNetworkdb) }
-
-var fileDescriptorNetworkdb = []byte{
-	// 956 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x96, 0xcd, 0x6e, 0xe3, 0x54,
-	0x14, 0xc7, 0x7b, 0xf3, 0xd1, 0x26, 0xa7, 0x29, 0x35, 0x77, 0x3a, 0x53, 0xd7, 0x03, 0x89, 0x31,
-	0x33, 0x55, 0xa6, 0x82, 0x14, 0x75, 0x9e, 0xa0, 0x49, 0x2c, 0xc8, 0x4c, 0xc6, 0x89, 0xdc, 0xa4,
-	0x88, 0x55, 0x74, 0x5b, 0x5f, 0x52, 0xab, 0x8e, 0x6d, 0xd9, 0x4e, 0x50, 0x56, 0x20, 0x56, 0xa3,
-	0x2c, 0x78, 0x83, 0xac, 0x86, 0x35, 0x0f, 0x80, 0x58, 0xb2, 0x98, 0x05, 0x0b, 0xd8, 0x21, 0x16,
-	0x11, 0xcd, 0x13, 0xf0, 0x08, 0xc8, 0xd7, 0x76, 0x72, 0x93, 0x56, 0x23, 0x21, 0x46, 0x82, 0x4d,
-	0x72, 0x3f, 0x7e, 0x39, 0x3e, 0xe7, 0xef, 0xff, 0xb9, 0x37, 0x70, 0x60, 0xd3, 0xe0, 0x2b, 0xc7,
-	0xbb, 0x36, 0x2e, 0x8e, 0x17, 0xa3, 0x8a, 0xeb, 0x39, 0x81, 0x83, 0xf3, 0x8b, 0x05, 0x69, 0xaf,
-	0xef, 0xf4, 0x1d, 0xb6, 0x7a, 0x1c, 0x8e, 0x22, 0x40, 0x69, 0xc1, 0xce, 0xa7, 0x8e, 0xef, 0x9b,
-	0xee, 0x0b, 0xea, 0xfb, 0xa4, 0x4f, 0xf1, 0x11, 0x64, 0x82, 0xb1, 0x4b, 0x45, 0x24, 0xa3, 0xf2,
-	0x3b, 0x27, 0x0f, 0x2a, 0xcb, 0x88, 0x31, 0xd1, 0x19, 0xbb, 0x54, 0x67, 0x0c, 0xc6, 0x90, 0x31,
-	0x48, 0x40, 0xc4, 0x94, 0x8c, 0xca, 0x05, 0x9d, 0x8d, 0x95, 0x57, 0x29, 0xc8, 0x6b, 0x8e, 0x41,
-	0xd5, 0x11, 0xb5, 0x03, 0xfc, 0xf1, 0x4a, 0xb4, 0x03, 0x2e, 0xda, 0x82, 0xa9, 0x70, 0x01, 0x1b,
-	0xb0, 0x69, 0xf5, 0x02, 0x73, 0x40, 0x59, 0xc8, 0x4c, 0xf5, 0xe4, 0xf5, 0xac, 0xb4, 0xf1, 0xc7,
-	0xac, 0x74, 0xd4, 0x37, 0x83, 0xab, 0xe1, 0x45, 0xe5, 0xd2, 0x19, 0x1c, 0x5f, 0x11, 0xff, 0xca,
-	0xbc, 0x74, 0x3c, 0xf7, 0xd8, 0xa7, 0xde, 0x97, 0xec, 0xa3, 0xd2, 0x24, 0x03, 0xd7, 0xf1, 0x82,
-	0x8e, 0x39, 0xa0, 0x7a, 0xd6, 0x0a, 0xbf, 0xf0, 0x43, 0xc8, 0xdb, 0x8e, 0x41, 0x7b, 0x36, 0x19,
-	0x50, 0x31, 0x2d, 0xa3, 0x72, 0x5e, 0xcf, 0x85, 0x0b, 0x1a, 0x19, 0x50, 0xe5, 0x6b, 0xc8, 0x84,
-	0x4f, 0xc5, 0x8f, 0x61, 0xab, 0xa1, 0x9d, 0x9f, 0x36, 0x1b, 0x75, 0x61, 0x43, 0x12, 0x27, 0x53,
-	0x79, 0x6f, 0x91, 0x56, 0xb8, 0xdf, 0xb0, 0x47, 0xc4, 0x32, 0x0d, 0x5c, 0x82, 0xcc, 0xb3, 0x56,
-	0x43, 0x13, 0x90, 0x74, 0x7f, 0x32, 0x95, 0xdf, 0x5d, 0x61, 0x9e, 0x39, 0xa6, 0x8d, 0x3f, 0x80,
-	0x6c, 0x53, 0x3d, 0x3d, 0x57, 0x85, 0x94, 0xf4, 0x60, 0x32, 0x95, 0xf1, 0x0a, 0xd1, 0xa4, 0x64,
-	0x44, 0xa5, 0xc2, 0xcb, 0x57, 0xc5, 0x8d, 0x1f, 0xbf, 0x2f, 0xb2, 0x07, 0x2b, 0x37, 0x29, 0x28,
-	0x68, 0x91, 0x16, 0x91, 0x50, 0x9f, 0xac, 0x08, 0xf5, 0x1e, 0x2f, 0x14, 0x87, 0xfd, 0x07, 0x5a,
-	0xe1, 0x8f, 0x00, 0xe2, 0x64, 0x7a, 0xa6, 0x21, 0x66, 0xc2, 0xdd, 0xea, 0xce, 0x7c, 0x56, 0xca,
-	0xc7, 0x89, 0x35, 0xea, 0x7a, 0xe2, 0xb2, 0x86, 0xa1, 0xbc, 0x44, 0xb1, 0xb4, 0x65, 0x5e, 0xda,
-	0x87, 0x93, 0xa9, 0xbc, 0xcf, 0x17, 0xc2, 0xab, 0xab, 0x2c, 0xd4, 0x8d, 0xde, 0xc0, 0x1a, 0xc6,
-	0x04, 0x7e, 0xb4, 0x14, 0xf8, 0x60, 0x32, 0x95, 0xef, 0xaf, 0x43, 0x77, 0x69, 0xfc, 0x0b, 0x5a,
-	0x6a, 0x6c, 0x07, 0xde, 0x78, 0xad, 0x12, 0xf4, 0xe6, 0x4a, 0xde, 0xa6, 0xbe, 0x4f, 0x6e, 0xe9,
-	0x5b, 0x2d, 0xcc, 0x67, 0xa5, 0x9c, 0x16, 0x6b, 0xcc, 0xa9, 0x2d, 0xc2, 0x96, 0x45, 0xc9, 0xc8,
-	0xb4, 0xfb, 0x4c, 0xea, 0x9c, 0x9e, 0x4c, 0x95, 0x9f, 0x10, 0xec, 0xc6, 0x89, 0xb6, 0x87, 0xfe,
-	0x55, 0x7b, 0x68, 0x59, 0x5c, 0x8e, 0xe8, 0xdf, 0xe6, 0xf8, 0x14, 0x72, 0x71, 0xed, 0xbe, 0x98,
-	0x92, 0xd3, 0xe5, 0xed, 0x93, 0xfd, 0x3b, 0x4c, 0x18, 0xea, 0xa8, 0x2f, 0xc0, 0x7f, 0x50, 0x98,
-	0xf2, 0x5d, 0x06, 0xa0, 0x43, 0x2e, 0xac, 0xf8, 0x60, 0xa8, 0xac, 0xf8, 0x5d, 0xe2, 0x1e, 0xb5,
-	0x84, 0xfe, 0xf7, 0x6e, 0xc7, 0xef, 0x03, 0x04, 0x61, 0xba, 0x51, 0xac, 0x2c, 0x8b, 0x95, 0x67,
-	0x2b, 0x2c, 0x98, 0x00, 0xe9, 0x6b, 0x3a, 0x16, 0x37, 0xd9, 0x7a, 0x38, 0xc4, 0x7b, 0x90, 0x1d,
-	0x11, 0x6b, 0x48, 0xc5, 0x2d, 0x76, 0x64, 0x46, 0x13, 0x5c, 0x05, 0xec, 0x51, 0xdf, 0x34, 0x86,
-	0xc4, 0xea, 0x79, 0x94, 0xb8, 0x51, 0xa1, 0x39, 0x19, 0x95, 0xb3, 0xd5, 0xbd, 0xf9, 0xac, 0x24,
-	0xe8, 0xf1, 0xae, 0x4e, 0x89, 0xcb, 0x4a, 0x11, 0xbc, 0xb5, 0x15, 0xe5, 0x87, 0xa4, 0xf1, 0x0e,
-	0xf9, 0xc6, 0x63, 0xcd, 0xb2, 0x54, 0x94, 0x6f, 0xbb, 0x47, 0xb0, 0x59, 0xd3, 0xd5, 0xd3, 0x8e,
-	0x9a, 0x34, 0xde, 0x2a, 0x56, 0xf3, 0x28, 0x09, 0x68, 0x48, 0x75, 0xdb, 0xf5, 0x90, 0x4a, 0xdd,
-	0x45, 0x75, 0x5d, 0x23, 0xa6, 0xea, 0x6a, 0x53, 0xed, 0xa8, 0x42, 0xfa, 0x2e, 0xaa, 0x4e, 0x2d,
-	0x1a, 0xac, 0xb7, 0xe7, 0x6f, 0x08, 0x76, 0xab, 0x43, 0xeb, 0xfa, 0x6c, 0x6c, 0x5f, 0x26, 0x97,
-	0xcf, 0x5b, 0xf4, 0xb3, 0x0c, 0xdb, 0x43, 0xdb, 0x77, 0x2c, 0xf3, 0xd2, 0x0c, 0xa8, 0xc1, 0x5c,
-	0x93, 0xd3, 0xf9, 0xa5, 0x37, 0xfb, 0x40, 0xe2, 0xda, 0x21, 0x23, 0xa7, 0xd9, 0x5e, 0xe2, 0x7a,
-	0x11, 0xb6, 0x5c, 0x32, 0xb6, 0x1c, 0x62, 0xb0, 0x57, 0x5e, 0xd0, 0x93, 0xa9, 0xf2, 0x2d, 0x82,
-	0xdd, 0x9a, 0x33, 0x70, 0x9d, 0xa1, 0x6d, 0x24, 0x35, 0xd5, 0x21, 0x37, 0x88, 0x86, 0xbe, 0x88,
-	0x58, 0x63, 0x95, 0x39, 0xb7, 0xaf, 0xd1, 0x95, 0x33, 0x73, 0xe0, 0x5a, 0x34, 0x9e, 0xe9, 0x8b,
-	0x5f, 0x4a, 0x4f, 0x60, 0x67, 0x65, 0x2b, 0x4c, 0xa2, 0x1d, 0x27, 0x81, 0xa2, 0x24, 0xe2, 0xe9,
-	0xd1, 0xcf, 0x29, 0xd8, 0xe6, 0xee, 0x6a, 0xfc, 0x21, 0x6f, 0x08, 0x76, 0x3d, 0x71, 0xbb, 0x89,
-	0x1b, 0x2a, 0xb0, 0xa3, 0xa9, 0x9d, 0xcf, 0x5b, 0xfa, 0xf3, 0x9e, 0x7a, 0xae, 0x6a, 0x1d, 0x01,
-	0x45, 0x87, 0x36, 0x87, 0xae, 0xdc, 0x57, 0x47, 0xb0, 0xdd, 0x39, 0xad, 0x36, 0xd5, 0x98, 0x8e,
-	0x8f, 0x65, 0x8e, 0xe6, 0x7a, 0xfd, 0x10, 0xf2, 0xed, 0xee, 0xd9, 0x67, 0xbd, 0x76, 0xb7, 0xd9,
-	0x14, 0xd2, 0xd2, 0xfe, 0x64, 0x2a, 0xdf, 0xe3, 0xc8, 0xc5, 0x69, 0x76, 0x08, 0xf9, 0x6a, 0xb7,
-	0xf9, 0xbc, 0x77, 0xf6, 0x85, 0x56, 0x13, 0x32, 0xb7, 0xb8, 0xc4, 0x2c, 0xf8, 0x31, 0xe4, 0x6a,
-	0xad, 0x17, 0xed, 0x56, 0x57, 0xab, 0x0b, 0xd9, 0x5b, 0x58, 0xa2, 0x28, 0x2e, 0x03, 0x68, 0xad,
-	0x7a, 0x92, 0xe1, 0x66, 0x64, 0x4c, 0xbe, 0x9e, 0xe4, 0x92, 0x96, 0xee, 0xc5, 0xc6, 0xe4, 0x65,
-	0xab, 0x8a, 0xbf, 0xdf, 0x14, 0x37, 0xfe, 0xba, 0x29, 0xa2, 0x6f, 0xe6, 0x45, 0xf4, 0x7a, 0x5e,
-	0x44, 0xbf, 0xce, 0x8b, 0xe8, 0xcf, 0x79, 0x11, 0x5d, 0x6c, 0xb2, 0xbf, 0x4e, 0x4f, 0xff, 0x0e,
-	0x00, 0x00, 0xff, 0xff, 0x0b, 0x8d, 0x70, 0xa7, 0x78, 0x09, 0x00, 0x00,
-}
diff --git a/libnetwork/networkdb/networkdb.proto b/libnetwork/networkdb/networkdb.proto
index 4e1272eb89d8d..981ed8399d576 100644
--- a/libnetwork/networkdb/networkdb.proto
+++ b/libnetwork/networkdb/networkdb.proto
@@ -1,6 +1,6 @@
 syntax = "proto3";
 
-import "gogoproto/gogo.proto";
+import "github.com/gogo/protobuf/gogoproto/gogo.proto";
 
 package networkdb;
 
diff --git a/vendor.mod b/vendor.mod
index a969008ee10c4..4f0192033fb6e 100644
--- a/vendor.mod
+++ b/vendor.mod
@@ -44,6 +44,7 @@ require (
 	github.com/godbus/dbus/v5 v5.1.0
 	github.com/gogo/protobuf v1.3.2
 	github.com/golang/gddo v0.0.0-20190904175337-72a348e765d2
+	github.com/golang/protobuf v1.5.2
 	github.com/google/go-cmp v0.5.9
 	github.com/google/uuid v1.3.0
 	github.com/gorilla/mux v1.8.0
@@ -138,7 +139,6 @@ require (
 	github.com/gogo/googleapis v1.4.1 // indirect
 	github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
 	github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
-	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/google/btree v1.1.2 // indirect
 	github.com/google/certificate-transparency-go v1.1.4 // indirect
 	github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
diff --git a/vendor/github.com/gogo/protobuf/plugin/compare/compare.go b/vendor/github.com/gogo/protobuf/plugin/compare/compare.go
new file mode 100644
index 0000000000000..9ab40ef1508c1
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/compare/compare.go
@@ -0,0 +1,580 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 compare
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+	"github.com/gogo/protobuf/vanity"
+)
+
+type plugin struct {
+	*generator.Generator
+	generator.PluginImports
+	fmtPkg      generator.Single
+	bytesPkg    generator.Single
+	sortkeysPkg generator.Single
+	protoPkg    generator.Single
+}
+
+func NewPlugin() *plugin {
+	return &plugin{}
+}
+
+func (p *plugin) Name() string {
+	return "compare"
+}
+
+func (p *plugin) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *plugin) Generate(file *generator.FileDescriptor) {
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	p.fmtPkg = p.NewImport("fmt")
+	p.bytesPkg = p.NewImport("bytes")
+	p.sortkeysPkg = p.NewImport("github.com/gogo/protobuf/sortkeys")
+	p.protoPkg = p.NewImport("github.com/gogo/protobuf/proto")
+
+	for _, msg := range file.Messages() {
+		if msg.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		if gogoproto.HasCompare(file.FileDescriptorProto, msg.DescriptorProto) {
+			p.generateMessage(file, msg)
+		}
+	}
+}
+
+func (p *plugin) generateNullableField(fieldname string) {
+	p.P(`if this.`, fieldname, ` != nil && that1.`, fieldname, ` != nil {`)
+	p.In()
+	p.P(`if *this.`, fieldname, ` != *that1.`, fieldname, `{`)
+	p.In()
+	p.P(`if *this.`, fieldname, ` < *that1.`, fieldname, `{`)
+	p.In()
+	p.P(`return -1`)
+	p.Out()
+	p.P(`}`)
+	p.P(`return 1`)
+	p.Out()
+	p.P(`}`)
+	p.Out()
+	p.P(`} else if this.`, fieldname, ` != nil {`)
+	p.In()
+	p.P(`return 1`)
+	p.Out()
+	p.P(`} else if that1.`, fieldname, ` != nil {`)
+	p.In()
+	p.P(`return -1`)
+	p.Out()
+	p.P(`}`)
+}
+
+func (p *plugin) generateMsgNullAndTypeCheck(ccTypeName string) {
+	p.P(`if that == nil {`)
+	p.In()
+	p.P(`if this == nil {`)
+	p.In()
+	p.P(`return 0`)
+	p.Out()
+	p.P(`}`)
+	p.P(`return 1`)
+	p.Out()
+	p.P(`}`)
+	p.P(``)
+	p.P(`that1, ok := that.(*`, ccTypeName, `)`)
+	p.P(`if !ok {`)
+	p.In()
+	p.P(`that2, ok := that.(`, ccTypeName, `)`)
+	p.P(`if ok {`)
+	p.In()
+	p.P(`that1 = &that2`)
+	p.Out()
+	p.P(`} else {`)
+	p.In()
+	p.P(`return 1`)
+	p.Out()
+	p.P(`}`)
+	p.Out()
+	p.P(`}`)
+	p.P(`if that1 == nil {`)
+	p.In()
+	p.P(`if this == nil {`)
+	p.In()
+	p.P(`return 0`)
+	p.Out()
+	p.P(`}`)
+	p.P(`return 1`)
+	p.Out()
+	p.P(`} else if this == nil {`)
+	p.In()
+	p.P(`return -1`)
+	p.Out()
+	p.P(`}`)
+}
+
+func (p *plugin) generateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) {
+	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
+	fieldname := p.GetOneOfFieldName(message, field)
+	repeated := field.IsRepeated()
+	ctype := gogoproto.IsCustomType(field)
+	nullable := gogoproto.IsNullable(field)
+	// oneof := field.OneofIndex != nil
+	if !repeated {
+		if ctype {
+			if nullable {
+				p.P(`if that1.`, fieldname, ` == nil {`)
+				p.In()
+				p.P(`if this.`, fieldname, ` != nil {`)
+				p.In()
+				p.P(`return 1`)
+				p.Out()
+				p.P(`}`)
+				p.Out()
+				p.P(`} else if this.`, fieldname, ` == nil {`)
+				p.In()
+				p.P(`return -1`)
+				p.Out()
+				p.P(`} else if c := this.`, fieldname, `.Compare(*that1.`, fieldname, `); c != 0 {`)
+			} else {
+				p.P(`if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`)
+			}
+			p.In()
+			p.P(`return c`)
+			p.Out()
+			p.P(`}`)
+		} else {
+			if field.IsMessage() || p.IsGroup(field) {
+				if nullable {
+					p.P(`if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`)
+				} else {
+					p.P(`if c := this.`, fieldname, `.Compare(&that1.`, fieldname, `); c != 0 {`)
+				}
+				p.In()
+				p.P(`return c`)
+				p.Out()
+				p.P(`}`)
+			} else if field.IsBytes() {
+				p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `, that1.`, fieldname, `); c != 0 {`)
+				p.In()
+				p.P(`return c`)
+				p.Out()
+				p.P(`}`)
+			} else if field.IsString() {
+				if nullable && !proto3 {
+					p.generateNullableField(fieldname)
+				} else {
+					p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
+					p.In()
+					p.P(`if this.`, fieldname, ` < that1.`, fieldname, `{`)
+					p.In()
+					p.P(`return -1`)
+					p.Out()
+					p.P(`}`)
+					p.P(`return 1`)
+					p.Out()
+					p.P(`}`)
+				}
+			} else if field.IsBool() {
+				if nullable && !proto3 {
+					p.P(`if this.`, fieldname, ` != nil && that1.`, fieldname, ` != nil {`)
+					p.In()
+					p.P(`if *this.`, fieldname, ` != *that1.`, fieldname, `{`)
+					p.In()
+					p.P(`if !*this.`, fieldname, ` {`)
+					p.In()
+					p.P(`return -1`)
+					p.Out()
+					p.P(`}`)
+					p.P(`return 1`)
+					p.Out()
+					p.P(`}`)
+					p.Out()
+					p.P(`} else if this.`, fieldname, ` != nil {`)
+					p.In()
+					p.P(`return 1`)
+					p.Out()
+					p.P(`} else if that1.`, fieldname, ` != nil {`)
+					p.In()
+					p.P(`return -1`)
+					p.Out()
+					p.P(`}`)
+				} else {
+					p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
+					p.In()
+					p.P(`if !this.`, fieldname, ` {`)
+					p.In()
+					p.P(`return -1`)
+					p.Out()
+					p.P(`}`)
+					p.P(`return 1`)
+					p.Out()
+					p.P(`}`)
+				}
+			} else {
+				if nullable && !proto3 {
+					p.generateNullableField(fieldname)
+				} else {
+					p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
+					p.In()
+					p.P(`if this.`, fieldname, ` < that1.`, fieldname, `{`)
+					p.In()
+					p.P(`return -1`)
+					p.Out()
+					p.P(`}`)
+					p.P(`return 1`)
+					p.Out()
+					p.P(`}`)
+				}
+			}
+		}
+	} else {
+		p.P(`if len(this.`, fieldname, `) != len(that1.`, fieldname, `) {`)
+		p.In()
+		p.P(`if len(this.`, fieldname, `) < len(that1.`, fieldname, `) {`)
+		p.In()
+		p.P(`return -1`)
+		p.Out()
+		p.P(`}`)
+		p.P(`return 1`)
+		p.Out()
+		p.P(`}`)
+		p.P(`for i := range this.`, fieldname, ` {`)
+		p.In()
+		if ctype {
+			p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`)
+			p.In()
+			p.P(`return c`)
+			p.Out()
+			p.P(`}`)
+		} else {
+			if p.IsMap(field) {
+				m := p.GoMapType(nil, field)
+				valuegoTyp, _ := p.GoType(nil, m.ValueField)
+				valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField)
+				nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
+
+				mapValue := m.ValueAliasField
+				if mapValue.IsMessage() || p.IsGroup(mapValue) {
+					if nullable && valuegoTyp == valuegoAliasTyp {
+						p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`)
+					} else {
+						// Compare() has a pointer receiver, but map value is a value type
+						a := `this.` + fieldname + `[i]`
+						b := `that1.` + fieldname + `[i]`
+						if valuegoTyp != valuegoAliasTyp {
+							// cast back to the type that has the generated methods on it
+							a = `(` + valuegoTyp + `)(` + a + `)`
+							b = `(` + valuegoTyp + `)(` + b + `)`
+						}
+						p.P(`a := `, a)
+						p.P(`b := `, b)
+						if nullable {
+							p.P(`if c := a.Compare(b); c != 0 {`)
+						} else {
+							p.P(`if c := (&a).Compare(&b); c != 0 {`)
+						}
+					}
+					p.In()
+					p.P(`return c`)
+					p.Out()
+					p.P(`}`)
+				} else if mapValue.IsBytes() {
+					p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `[i], that1.`, fieldname, `[i]); c != 0 {`)
+					p.In()
+					p.P(`return c`)
+					p.Out()
+					p.P(`}`)
+				} else if mapValue.IsString() {
+					p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
+					p.In()
+					p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`)
+					p.In()
+					p.P(`return -1`)
+					p.Out()
+					p.P(`}`)
+					p.P(`return 1`)
+					p.Out()
+					p.P(`}`)
+				} else {
+					p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
+					p.In()
+					p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`)
+					p.In()
+					p.P(`return -1`)
+					p.Out()
+					p.P(`}`)
+					p.P(`return 1`)
+					p.Out()
+					p.P(`}`)
+				}
+			} else if field.IsMessage() || p.IsGroup(field) {
+				if nullable {
+					p.P(`if c := this.`, fieldname, `[i].Compare(that1.`, fieldname, `[i]); c != 0 {`)
+					p.In()
+					p.P(`return c`)
+					p.Out()
+					p.P(`}`)
+				} else {
+					p.P(`if c := this.`, fieldname, `[i].Compare(&that1.`, fieldname, `[i]); c != 0 {`)
+					p.In()
+					p.P(`return c`)
+					p.Out()
+					p.P(`}`)
+				}
+			} else if field.IsBytes() {
+				p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `[i], that1.`, fieldname, `[i]); c != 0 {`)
+				p.In()
+				p.P(`return c`)
+				p.Out()
+				p.P(`}`)
+			} else if field.IsString() {
+				p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
+				p.In()
+				p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`)
+				p.In()
+				p.P(`return -1`)
+				p.Out()
+				p.P(`}`)
+				p.P(`return 1`)
+				p.Out()
+				p.P(`}`)
+			} else if field.IsBool() {
+				p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
+				p.In()
+				p.P(`if !this.`, fieldname, `[i] {`)
+				p.In()
+				p.P(`return -1`)
+				p.Out()
+				p.P(`}`)
+				p.P(`return 1`)
+				p.Out()
+				p.P(`}`)
+			} else {
+				p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
+				p.In()
+				p.P(`if this.`, fieldname, `[i] < that1.`, fieldname, `[i] {`)
+				p.In()
+				p.P(`return -1`)
+				p.Out()
+				p.P(`}`)
+				p.P(`return 1`)
+				p.Out()
+				p.P(`}`)
+			}
+		}
+		p.Out()
+		p.P(`}`)
+	}
+}
+
+func (p *plugin) generateMessage(file *generator.FileDescriptor, message *generator.Descriptor) {
+	ccTypeName := generator.CamelCaseSlice(message.TypeName())
+	p.P(`func (this *`, ccTypeName, `) Compare(that interface{}) int {`)
+	p.In()
+	p.generateMsgNullAndTypeCheck(ccTypeName)
+	oneofs := make(map[string]struct{})
+
+	for _, field := range message.Field {
+		oneof := field.OneofIndex != nil
+		if oneof {
+			fieldname := p.GetFieldName(message, field)
+			if _, ok := oneofs[fieldname]; ok {
+				continue
+			} else {
+				oneofs[fieldname] = struct{}{}
+			}
+			p.P(`if that1.`, fieldname, ` == nil {`)
+			p.In()
+			p.P(`if this.`, fieldname, ` != nil {`)
+			p.In()
+			p.P(`return 1`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`} else if this.`, fieldname, ` == nil {`)
+			p.In()
+			p.P(`return -1`)
+			p.Out()
+			p.P(`} else {`)
+			p.In()
+
+			// Generate two type switches in order to compare the
+			// types of the oneofs. If they are of the same type
+			// call Compare, otherwise return 1 or -1.
+			p.P(`thisType := -1`)
+			p.P(`switch this.`, fieldname, `.(type) {`)
+			for i, subfield := range message.Field {
+				if *subfield.OneofIndex == *field.OneofIndex {
+					ccTypeName := p.OneOfTypeName(message, subfield)
+					p.P(`case *`, ccTypeName, `:`)
+					p.In()
+					p.P(`thisType = `, i)
+					p.Out()
+				}
+			}
+			p.P(`default:`)
+			p.In()
+			p.P(`panic(fmt.Sprintf("compare: unexpected type %T in oneof", this.`, fieldname, `))`)
+			p.Out()
+			p.P(`}`)
+
+			p.P(`that1Type := -1`)
+			p.P(`switch that1.`, fieldname, `.(type) {`)
+			for i, subfield := range message.Field {
+				if *subfield.OneofIndex == *field.OneofIndex {
+					ccTypeName := p.OneOfTypeName(message, subfield)
+					p.P(`case *`, ccTypeName, `:`)
+					p.In()
+					p.P(`that1Type = `, i)
+					p.Out()
+				}
+			}
+			p.P(`default:`)
+			p.In()
+			p.P(`panic(fmt.Sprintf("compare: unexpected type %T in oneof", that1.`, fieldname, `))`)
+			p.Out()
+			p.P(`}`)
+
+			p.P(`if thisType == that1Type {`)
+			p.In()
+			p.P(`if c := this.`, fieldname, `.Compare(that1.`, fieldname, `); c != 0 {`)
+			p.In()
+			p.P(`return c`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`} else if thisType < that1Type {`)
+			p.In()
+			p.P(`return -1`)
+			p.Out()
+			p.P(`} else if thisType > that1Type {`)
+			p.In()
+			p.P(`return 1`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+		} else {
+			p.generateField(file, message, field)
+		}
+	}
+	if message.DescriptorProto.HasExtension() {
+		if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
+			p.P(`thismap := `, p.protoPkg.Use(), `.GetUnsafeExtensionsMap(this)`)
+			p.P(`thatmap := `, p.protoPkg.Use(), `.GetUnsafeExtensionsMap(that1)`)
+			p.P(`extkeys := make([]int32, 0, len(thismap)+len(thatmap))`)
+			p.P(`for k, _ := range thismap {`)
+			p.In()
+			p.P(`extkeys = append(extkeys, k)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`for k, _ := range thatmap {`)
+			p.In()
+			p.P(`if _, ok := thismap[k]; !ok {`)
+			p.In()
+			p.P(`extkeys = append(extkeys, k)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+			p.P(p.sortkeysPkg.Use(), `.Int32s(extkeys)`)
+			p.P(`for _, k := range extkeys {`)
+			p.In()
+			p.P(`if v, ok := thismap[k]; ok {`)
+			p.In()
+			p.P(`if v2, ok := thatmap[k]; ok {`)
+			p.In()
+			p.P(`if c := v.Compare(&v2); c != 0 {`)
+			p.In()
+			p.P(`return c`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`} else  {`)
+			p.In()
+			p.P(`return 1`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`} else {`)
+			p.In()
+			p.P(`return -1`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+		} else {
+			fieldname := "XXX_extensions"
+			p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `, that1.`, fieldname, `); c != 0 {`)
+			p.In()
+			p.P(`return c`)
+			p.Out()
+			p.P(`}`)
+		}
+	}
+	if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
+		fieldname := "XXX_unrecognized"
+		p.P(`if c := `, p.bytesPkg.Use(), `.Compare(this.`, fieldname, `, that1.`, fieldname, `); c != 0 {`)
+		p.In()
+		p.P(`return c`)
+		p.Out()
+		p.P(`}`)
+	}
+	p.P(`return 0`)
+	p.Out()
+	p.P(`}`)
+
+	//Generate Compare methods for oneof fields
+	m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
+	for _, field := range m.Field {
+		oneof := field.OneofIndex != nil
+		if !oneof {
+			continue
+		}
+		ccTypeName := p.OneOfTypeName(message, field)
+		p.P(`func (this *`, ccTypeName, `) Compare(that interface{}) int {`)
+		p.In()
+
+		p.generateMsgNullAndTypeCheck(ccTypeName)
+		vanity.TurnOffNullableForNativeTypes(field)
+		p.generateField(file, message, field)
+
+		p.P(`return 0`)
+		p.Out()
+		p.P(`}`)
+	}
+}
+
+func init() {
+	generator.RegisterPlugin(NewPlugin())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/defaultcheck/defaultcheck.go b/vendor/github.com/gogo/protobuf/plugin/defaultcheck/defaultcheck.go
new file mode 100644
index 0000000000000..486f287719296
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/defaultcheck/defaultcheck.go
@@ -0,0 +1,133 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The defaultcheck plugin is used to check whether nullable is not used incorrectly.
+For instance:
+An error is caused if a nullable field:
+  - has a default value,
+  - is an enum which does not start at zero,
+  - is used for an extension,
+  - is used for a native proto3 type,
+  - is used for a repeated native type.
+
+An error is also caused if a field with a default value is used in a message:
+  - which is a face.
+  - without getters.
+
+It is enabled by the following extensions:
+
+  - nullable
+
+For incorrect usage of nullable with tests see:
+
+  github.com/gogo/protobuf/test/nullableconflict
+
+*/
+package defaultcheck
+
+import (
+	"fmt"
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+	"os"
+)
+
+type plugin struct {
+	*generator.Generator
+}
+
+func NewPlugin() *plugin {
+	return &plugin{}
+}
+
+func (p *plugin) Name() string {
+	return "defaultcheck"
+}
+
+func (p *plugin) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *plugin) Generate(file *generator.FileDescriptor) {
+	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
+	for _, msg := range file.Messages() {
+		getters := gogoproto.HasGoGetters(file.FileDescriptorProto, msg.DescriptorProto)
+		face := gogoproto.IsFace(file.FileDescriptorProto, msg.DescriptorProto)
+		for _, field := range msg.GetField() {
+			if len(field.GetDefaultValue()) > 0 {
+				if !getters {
+					fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot have a default value and not have a getter method", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
+					os.Exit(1)
+				}
+				if face {
+					fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot have a default value be in a face", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
+					os.Exit(1)
+				}
+			}
+			if gogoproto.IsNullable(field) {
+				continue
+			}
+			if len(field.GetDefaultValue()) > 0 {
+				fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be non-nullable and have a default value", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
+				os.Exit(1)
+			}
+			if !field.IsMessage() && !gogoproto.IsCustomType(field) {
+				if field.IsRepeated() {
+					fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is a repeated non-nullable native type, nullable=false has no effect\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
+				} else if proto3 {
+					fmt.Fprintf(os.Stderr, "ERROR: field %v.%v is a native type and in proto3 syntax with nullable=false there exists conflicting implementations when encoding zero values", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
+					os.Exit(1)
+				}
+				if field.IsBytes() {
+					fmt.Fprintf(os.Stderr, "WARNING: field %v.%v is a non-nullable bytes type, nullable=false has no effect\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
+				}
+			}
+			if !field.IsEnum() {
+				continue
+			}
+			enum := p.ObjectNamed(field.GetTypeName()).(*generator.EnumDescriptor)
+			if len(enum.Value) == 0 || enum.Value[0].GetNumber() != 0 {
+				fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be non-nullable and be an enum type %v which does not start with zero", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name), enum.GetName())
+				os.Exit(1)
+			}
+		}
+	}
+	for _, e := range file.GetExtension() {
+		if !gogoproto.IsNullable(e) {
+			fmt.Fprintf(os.Stderr, "ERROR: extended field %v cannot be nullable %v", generator.CamelCase(e.GetName()), generator.CamelCase(*e.Name))
+			os.Exit(1)
+		}
+	}
+}
+
+func (p *plugin) GenerateImports(*generator.FileDescriptor) {}
+
+func init() {
+	generator.RegisterPlugin(NewPlugin())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/description/description.go b/vendor/github.com/gogo/protobuf/plugin/description/description.go
new file mode 100644
index 0000000000000..f72efba612829
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/description/description.go
@@ -0,0 +1,201 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The description (experimental) plugin generates a Description method for each message.
+The Description method returns a populated google_protobuf.FileDescriptorSet struct.
+This contains the description of the files used to generate this message.
+
+It is enabled by the following extensions:
+
+  - description
+  - description_all
+
+The description plugin also generates a test given it is enabled using one of the following extensions:
+
+  - testgen
+  - testgen_all
+
+Let us look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+  message B {
+	option (gogoproto.description) = true;
+	optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
+	repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false];
+  }
+
+given to the description plugin, will generate the following code:
+
+  func (this *B) Description() (desc *google_protobuf.FileDescriptorSet) {
+	return ExampleDescription()
+  }
+
+and the following test code:
+
+  func TestDescription(t *testing9.T) {
+	ExampleDescription()
+  }
+
+The hope is to use this struct in some way instead of reflect.
+This package is subject to change, since a use has not been figured out yet.
+
+*/
+package description
+
+import (
+	"bytes"
+	"compress/gzip"
+	"fmt"
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type plugin struct {
+	*generator.Generator
+	generator.PluginImports
+}
+
+func NewPlugin() *plugin {
+	return &plugin{}
+}
+
+func (p *plugin) Name() string {
+	return "description"
+}
+
+func (p *plugin) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *plugin) Generate(file *generator.FileDescriptor) {
+	used := false
+	localName := generator.FileName(file)
+
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	descriptorPkg := p.NewImport("github.com/gogo/protobuf/protoc-gen-gogo/descriptor")
+	protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
+	gzipPkg := p.NewImport("compress/gzip")
+	bytesPkg := p.NewImport("bytes")
+	ioutilPkg := p.NewImport("io/ioutil")
+
+	for _, message := range file.Messages() {
+		if !gogoproto.HasDescription(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		used = true
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		p.P(`func (this *`, ccTypeName, `) Description() (desc *`, descriptorPkg.Use(), `.FileDescriptorSet) {`)
+		p.In()
+		p.P(`return `, localName, `Description()`)
+		p.Out()
+		p.P(`}`)
+	}
+
+	if used {
+
+		p.P(`func `, localName, `Description() (desc *`, descriptorPkg.Use(), `.FileDescriptorSet) {`)
+		p.In()
+		//Don't generate SourceCodeInfo, since it will create too much code.
+
+		ss := make([]*descriptor.SourceCodeInfo, 0)
+		for _, f := range p.Generator.AllFiles().GetFile() {
+			ss = append(ss, f.SourceCodeInfo)
+			f.SourceCodeInfo = nil
+		}
+		b, err := proto.Marshal(p.Generator.AllFiles())
+		if err != nil {
+			panic(err)
+		}
+		for i, f := range p.Generator.AllFiles().GetFile() {
+			f.SourceCodeInfo = ss[i]
+		}
+		p.P(`d := &`, descriptorPkg.Use(), `.FileDescriptorSet{}`)
+		var buf bytes.Buffer
+		w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
+		w.Write(b)
+		w.Close()
+		b = buf.Bytes()
+		p.P("var gzipped = []byte{")
+		p.In()
+		p.P("// ", len(b), " bytes of a gzipped FileDescriptorSet")
+		for len(b) > 0 {
+			n := 16
+			if n > len(b) {
+				n = len(b)
+			}
+
+			s := ""
+			for _, c := range b[:n] {
+				s += fmt.Sprintf("0x%02x,", c)
+			}
+			p.P(s)
+
+			b = b[n:]
+		}
+		p.Out()
+		p.P("}")
+		p.P(`r := `, bytesPkg.Use(), `.NewReader(gzipped)`)
+		p.P(`gzipr, err := `, gzipPkg.Use(), `.NewReader(r)`)
+		p.P(`if err != nil {`)
+		p.In()
+		p.P(`panic(err)`)
+		p.Out()
+		p.P(`}`)
+		p.P(`ungzipped, err := `, ioutilPkg.Use(), `.ReadAll(gzipr)`)
+		p.P(`if err != nil {`)
+		p.In()
+		p.P(`panic(err)`)
+		p.Out()
+		p.P(`}`)
+		p.P(`if err := `, protoPkg.Use(), `.Unmarshal(ungzipped, d); err != nil {`)
+		p.In()
+		p.P(`panic(err)`)
+		p.Out()
+		p.P(`}`)
+		p.P(`return d`)
+		p.Out()
+		p.P(`}`)
+	}
+}
+
+func init() {
+	generator.RegisterPlugin(NewPlugin())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/embedcheck/embedcheck.go b/vendor/github.com/gogo/protobuf/plugin/embedcheck/embedcheck.go
new file mode 100644
index 0000000000000..bc68efe12c7d4
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/embedcheck/embedcheck.go
@@ -0,0 +1,200 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The embedcheck plugin is used to check whether embed is not used incorrectly.
+For instance:
+An embedded message has a generated string method, but the is a member of a message which does not.
+This causes a warning.
+An error is caused by a namespace conflict.
+
+It is enabled by the following extensions:
+
+  - embed
+  - embed_all
+
+For incorrect usage of embed with tests see:
+
+  github.com/gogo/protobuf/test/embedconflict
+
+*/
+package embedcheck
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type plugin struct {
+	*generator.Generator
+}
+
+func NewPlugin() *plugin {
+	return &plugin{}
+}
+
+func (p *plugin) Name() string {
+	return "embedcheck"
+}
+
+func (p *plugin) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+var overwriters []map[string]gogoproto.EnableFunc = []map[string]gogoproto.EnableFunc{
+	{
+		"stringer": gogoproto.IsStringer,
+	},
+	{
+		"gostring": gogoproto.HasGoString,
+	},
+	{
+		"equal": gogoproto.HasEqual,
+	},
+	{
+		"verboseequal": gogoproto.HasVerboseEqual,
+	},
+	{
+		"size":       gogoproto.IsSizer,
+		"protosizer": gogoproto.IsProtoSizer,
+	},
+	{
+		"unmarshaler":        gogoproto.IsUnmarshaler,
+		"unsafe_unmarshaler": gogoproto.IsUnsafeUnmarshaler,
+	},
+	{
+		"marshaler":        gogoproto.IsMarshaler,
+		"unsafe_marshaler": gogoproto.IsUnsafeMarshaler,
+	},
+}
+
+func (p *plugin) Generate(file *generator.FileDescriptor) {
+	for _, msg := range file.Messages() {
+		for _, os := range overwriters {
+			possible := true
+			for _, overwriter := range os {
+				if overwriter(file.FileDescriptorProto, msg.DescriptorProto) {
+					possible = false
+				}
+			}
+			if possible {
+				p.checkOverwrite(msg, os)
+			}
+		}
+		p.checkNameSpace(msg)
+		for _, field := range msg.GetField() {
+			if gogoproto.IsEmbed(field) && gogoproto.IsCustomName(field) {
+				fmt.Fprintf(os.Stderr, "ERROR: field %v with custom name %v cannot be embedded", *field.Name, gogoproto.GetCustomName(field))
+				os.Exit(1)
+			}
+		}
+		p.checkRepeated(msg)
+	}
+	for _, e := range file.GetExtension() {
+		if gogoproto.IsEmbed(e) {
+			fmt.Fprintf(os.Stderr, "ERROR: extended field %v cannot be embedded", generator.CamelCase(*e.Name))
+			os.Exit(1)
+		}
+	}
+}
+
+func (p *plugin) checkNameSpace(message *generator.Descriptor) map[string]bool {
+	ccTypeName := generator.CamelCaseSlice(message.TypeName())
+	names := make(map[string]bool)
+	for _, field := range message.Field {
+		fieldname := generator.CamelCase(*field.Name)
+		if field.IsMessage() && gogoproto.IsEmbed(field) {
+			desc := p.ObjectNamed(field.GetTypeName())
+			moreNames := p.checkNameSpace(desc.(*generator.Descriptor))
+			for another := range moreNames {
+				if names[another] {
+					fmt.Fprintf(os.Stderr, "ERROR: duplicate embedded fieldname %v in type %v\n", fieldname, ccTypeName)
+					os.Exit(1)
+				}
+				names[another] = true
+			}
+		} else {
+			if names[fieldname] {
+				fmt.Fprintf(os.Stderr, "ERROR: duplicate embedded fieldname %v in type %v\n", fieldname, ccTypeName)
+				os.Exit(1)
+			}
+			names[fieldname] = true
+		}
+	}
+	return names
+}
+
+func (p *plugin) checkOverwrite(message *generator.Descriptor, enablers map[string]gogoproto.EnableFunc) {
+	ccTypeName := generator.CamelCaseSlice(message.TypeName())
+	names := []string{}
+	for name := range enablers {
+		names = append(names, name)
+	}
+	for _, field := range message.Field {
+		if field.IsMessage() && gogoproto.IsEmbed(field) {
+			fieldname := generator.CamelCase(*field.Name)
+			desc := p.ObjectNamed(field.GetTypeName())
+			msg := desc.(*generator.Descriptor)
+			for errStr, enabled := range enablers {
+				if enabled(msg.File().FileDescriptorProto, msg.DescriptorProto) {
+					fmt.Fprintf(os.Stderr, "WARNING: found non-%v %v with embedded %v %v\n", names, ccTypeName, errStr, fieldname)
+				}
+			}
+			p.checkOverwrite(msg, enablers)
+		}
+	}
+}
+
+func (p *plugin) checkRepeated(message *generator.Descriptor) {
+	ccTypeName := generator.CamelCaseSlice(message.TypeName())
+	for _, field := range message.Field {
+		if !gogoproto.IsEmbed(field) {
+			continue
+		}
+		if field.IsBytes() {
+			fieldname := generator.CamelCase(*field.Name)
+			fmt.Fprintf(os.Stderr, "ERROR: found embedded bytes field %s in message %s\n", fieldname, ccTypeName)
+			os.Exit(1)
+		}
+		if !field.IsRepeated() {
+			continue
+		}
+		fieldname := generator.CamelCase(*field.Name)
+		fmt.Fprintf(os.Stderr, "ERROR: found repeated embedded field %s in message %s\n", fieldname, ccTypeName)
+		os.Exit(1)
+	}
+}
+
+func (p *plugin) GenerateImports(*generator.FileDescriptor) {}
+
+func init() {
+	generator.RegisterPlugin(NewPlugin())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/enumstringer/enumstringer.go b/vendor/github.com/gogo/protobuf/plugin/enumstringer/enumstringer.go
new file mode 100644
index 0000000000000..04d6e547fc350
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/enumstringer/enumstringer.go
@@ -0,0 +1,104 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The enumstringer (experimental) plugin generates a String method for each enum.
+
+It is enabled by the following extensions:
+
+  - enum_stringer
+  - enum_stringer_all
+
+This package is subject to change.
+
+*/
+package enumstringer
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type enumstringer struct {
+	*generator.Generator
+	generator.PluginImports
+	atleastOne bool
+	localName  string
+}
+
+func NewEnumStringer() *enumstringer {
+	return &enumstringer{}
+}
+
+func (p *enumstringer) Name() string {
+	return "enumstringer"
+}
+
+func (p *enumstringer) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *enumstringer) Generate(file *generator.FileDescriptor) {
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	p.atleastOne = false
+
+	p.localName = generator.FileName(file)
+
+	strconvPkg := p.NewImport("strconv")
+
+	for _, enum := range file.Enums() {
+		if !gogoproto.IsEnumStringer(file.FileDescriptorProto, enum.EnumDescriptorProto) {
+			continue
+		}
+		if gogoproto.IsGoEnumStringer(file.FileDescriptorProto, enum.EnumDescriptorProto) {
+			panic("Go enum stringer conflicts with new enumstringer plugin: please use gogoproto.goproto_enum_stringer or gogoproto.goproto_enum_string_all and set it to false")
+		}
+		p.atleastOne = true
+		ccTypeName := generator.CamelCaseSlice(enum.TypeName())
+		p.P("func (x ", ccTypeName, ") String() string {")
+		p.In()
+		p.P(`s, ok := `, ccTypeName, `_name[int32(x)]`)
+		p.P(`if ok {`)
+		p.In()
+		p.P(`return s`)
+		p.Out()
+		p.P(`}`)
+		p.P(`return `, strconvPkg.Use(), `.Itoa(int(x))`)
+		p.Out()
+		p.P(`}`)
+	}
+
+	if !p.atleastOne {
+		return
+	}
+
+}
+
+func init() {
+	generator.RegisterPlugin(NewEnumStringer())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/equal/equal.go b/vendor/github.com/gogo/protobuf/plugin/equal/equal.go
new file mode 100644
index 0000000000000..6358fc99ad115
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/equal/equal.go
@@ -0,0 +1,694 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The equal plugin generates an Equal and a VerboseEqual method for each message.
+These equal methods are quite obvious.
+The only difference is that VerboseEqual returns a non nil error if it is not equal.
+This error contains more detail on exactly which part of the message was not equal to the other message.
+The idea is that this is useful for debugging.
+
+Equal is enabled using the following extensions:
+
+  - equal
+  - equal_all
+
+While VerboseEqual is enable dusing the following extensions:
+
+  - verbose_equal
+  - verbose_equal_all
+
+The equal plugin also generates a test given it is enabled using one of the following extensions:
+
+  - testgen
+  - testgen_all
+
+Let us look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+  option (gogoproto.equal_all) = true;
+  option (gogoproto.verbose_equal_all) = true;
+
+  message B {
+	optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
+	repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false];
+  }
+
+given to the equal plugin, will generate the following code:
+
+	func (this *B) VerboseEqual(that interface{}) error {
+		if that == nil {
+			if this == nil {
+				return nil
+			}
+			return fmt2.Errorf("that == nil && this != nil")
+		}
+
+		that1, ok := that.(*B)
+		if !ok {
+			return fmt2.Errorf("that is not of type *B")
+		}
+		if that1 == nil {
+			if this == nil {
+				return nil
+			}
+			return fmt2.Errorf("that is type *B but is nil && this != nil")
+		} else if this == nil {
+			return fmt2.Errorf("that is type *B but is not nil && this == nil")
+		}
+		if !this.A.Equal(&that1.A) {
+			return fmt2.Errorf("A this(%v) Not Equal that(%v)", this.A, that1.A)
+		}
+		if len(this.G) != len(that1.G) {
+			return fmt2.Errorf("G this(%v) Not Equal that(%v)", len(this.G), len(that1.G))
+		}
+		for i := range this.G {
+			if !this.G[i].Equal(that1.G[i]) {
+				return fmt2.Errorf("G this[%v](%v) Not Equal that[%v](%v)", i, this.G[i], i, that1.G[i])
+			}
+		}
+		if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+			return fmt2.Errorf("XXX_unrecognized this(%v) Not Equal that(%v)", this.XXX_unrecognized, that1.XXX_unrecognized)
+		}
+		return nil
+	}
+
+	func (this *B) Equal(that interface{}) bool {
+		if that == nil {
+			return this == nil
+		}
+
+		that1, ok := that.(*B)
+		if !ok {
+			return false
+		}
+		if that1 == nil {
+			return this == nil
+		} else if this == nil {
+			return false
+		}
+		if !this.A.Equal(&that1.A) {
+			return false
+		}
+		if len(this.G) != len(that1.G) {
+			return false
+		}
+		for i := range this.G {
+			if !this.G[i].Equal(that1.G[i]) {
+				return false
+			}
+		}
+		if !bytes.Equal(this.XXX_unrecognized, that1.XXX_unrecognized) {
+			return false
+		}
+		return true
+	}
+
+and the following test code:
+
+	func TestBVerboseEqual(t *testing8.T) {
+		popr := math_rand8.New(math_rand8.NewSource(time8.Now().UnixNano()))
+		p := NewPopulatedB(popr, false)
+		dAtA, err := github_com_gogo_protobuf_proto2.Marshal(p)
+		if err != nil {
+			panic(err)
+		}
+		msg := &B{}
+		if err := github_com_gogo_protobuf_proto2.Unmarshal(dAtA, msg); err != nil {
+			panic(err)
+		}
+		if err := p.VerboseEqual(msg); err != nil {
+			t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err)
+	}
+
+*/
+package equal
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+	"github.com/gogo/protobuf/vanity"
+)
+
+type plugin struct {
+	*generator.Generator
+	generator.PluginImports
+	fmtPkg   generator.Single
+	bytesPkg generator.Single
+	protoPkg generator.Single
+}
+
+func NewPlugin() *plugin {
+	return &plugin{}
+}
+
+func (p *plugin) Name() string {
+	return "equal"
+}
+
+func (p *plugin) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *plugin) Generate(file *generator.FileDescriptor) {
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	p.fmtPkg = p.NewImport("fmt")
+	p.bytesPkg = p.NewImport("bytes")
+	p.protoPkg = p.NewImport("github.com/gogo/protobuf/proto")
+
+	for _, msg := range file.Messages() {
+		if msg.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		if gogoproto.HasVerboseEqual(file.FileDescriptorProto, msg.DescriptorProto) {
+			p.generateMessage(file, msg, true)
+		}
+		if gogoproto.HasEqual(file.FileDescriptorProto, msg.DescriptorProto) {
+			p.generateMessage(file, msg, false)
+		}
+	}
+}
+
+func (p *plugin) generateNullableField(fieldname string, verbose bool) {
+	p.P(`if this.`, fieldname, ` != nil && that1.`, fieldname, ` != nil {`)
+	p.In()
+	p.P(`if *this.`, fieldname, ` != *that1.`, fieldname, `{`)
+	p.In()
+	if verbose {
+		p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", *this.`, fieldname, `, *that1.`, fieldname, `)`)
+	} else {
+		p.P(`return false`)
+	}
+	p.Out()
+	p.P(`}`)
+	p.Out()
+	p.P(`} else if this.`, fieldname, ` != nil {`)
+	p.In()
+	if verbose {
+		p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` == nil && that.`, fieldname, ` != nil")`)
+	} else {
+		p.P(`return false`)
+	}
+	p.Out()
+	p.P(`} else if that1.`, fieldname, ` != nil {`)
+}
+
+func (p *plugin) generateMsgNullAndTypeCheck(ccTypeName string, verbose bool) {
+	p.P(`if that == nil {`)
+	p.In()
+	if verbose {
+		p.P(`if this == nil {`)
+		p.In()
+		p.P(`return nil`)
+		p.Out()
+		p.P(`}`)
+		p.P(`return `, p.fmtPkg.Use(), `.Errorf("that == nil && this != nil")`)
+	} else {
+		p.P(`return this == nil`)
+	}
+	p.Out()
+	p.P(`}`)
+	p.P(``)
+	p.P(`that1, ok := that.(*`, ccTypeName, `)`)
+	p.P(`if !ok {`)
+	p.In()
+	p.P(`that2, ok := that.(`, ccTypeName, `)`)
+	p.P(`if ok {`)
+	p.In()
+	p.P(`that1 = &that2`)
+	p.Out()
+	p.P(`} else {`)
+	p.In()
+	if verbose {
+		p.P(`return `, p.fmtPkg.Use(), `.Errorf("that is not of type *`, ccTypeName, `")`)
+	} else {
+		p.P(`return false`)
+	}
+	p.Out()
+	p.P(`}`)
+	p.Out()
+	p.P(`}`)
+	p.P(`if that1 == nil {`)
+	p.In()
+	if verbose {
+		p.P(`if this == nil {`)
+		p.In()
+		p.P(`return nil`)
+		p.Out()
+		p.P(`}`)
+		p.P(`return `, p.fmtPkg.Use(), `.Errorf("that is type *`, ccTypeName, ` but is nil && this != nil")`)
+	} else {
+		p.P(`return this == nil`)
+	}
+	p.Out()
+	p.P(`} else if this == nil {`)
+	p.In()
+	if verbose {
+		p.P(`return `, p.fmtPkg.Use(), `.Errorf("that is type *`, ccTypeName, ` but is not nil && this == nil")`)
+	} else {
+		p.P(`return false`)
+	}
+	p.Out()
+	p.P(`}`)
+}
+
+func (p *plugin) generateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto, verbose bool) {
+	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
+	fieldname := p.GetOneOfFieldName(message, field)
+	repeated := field.IsRepeated()
+	ctype := gogoproto.IsCustomType(field)
+	nullable := gogoproto.IsNullable(field)
+	isNormal := (gogoproto.IsStdDuration(field) ||
+		gogoproto.IsStdDouble(field) ||
+		gogoproto.IsStdFloat(field) ||
+		gogoproto.IsStdInt64(field) ||
+		gogoproto.IsStdUInt64(field) ||
+		gogoproto.IsStdInt32(field) ||
+		gogoproto.IsStdUInt32(field) ||
+		gogoproto.IsStdBool(field) ||
+		gogoproto.IsStdString(field))
+	isBytes := gogoproto.IsStdBytes(field)
+	isTimestamp := gogoproto.IsStdTime(field)
+	// oneof := field.OneofIndex != nil
+	if !repeated {
+		if ctype || isTimestamp {
+			if nullable {
+				p.P(`if that1.`, fieldname, ` == nil {`)
+				p.In()
+				p.P(`if this.`, fieldname, ` != nil {`)
+				p.In()
+				if verbose {
+					p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` != nil && that1.`, fieldname, ` == nil")`)
+				} else {
+					p.P(`return false`)
+				}
+				p.Out()
+				p.P(`}`)
+				p.Out()
+				p.P(`} else if !this.`, fieldname, `.Equal(*that1.`, fieldname, `) {`)
+			} else {
+				p.P(`if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`)
+			}
+			p.In()
+			if verbose {
+				p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			p.P(`}`)
+		} else if isNormal {
+			if nullable {
+				p.generateNullableField(fieldname, verbose)
+			} else {
+				p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
+			}
+			p.In()
+			if verbose {
+				p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			p.P(`}`)
+		} else if isBytes {
+			if nullable {
+				p.P(`if that1.`, fieldname, ` == nil {`)
+				p.In()
+				p.P(`if this.`, fieldname, ` != nil {`)
+				p.In()
+				if verbose {
+					p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` != nil && that1.`, fieldname, ` == nil")`)
+				} else {
+					p.P(`return false`)
+				}
+				p.Out()
+				p.P(`}`)
+				p.Out()
+				p.P(`} else if !`, p.bytesPkg.Use(), `.Equal(*this.`, fieldname, `, *that1.`, fieldname, `) {`)
+			} else {
+				p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`)
+			}
+			p.In()
+			if verbose {
+				p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			p.P(`}`)
+		} else {
+			if field.IsMessage() || p.IsGroup(field) {
+				if nullable {
+					p.P(`if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`)
+				} else {
+					p.P(`if !this.`, fieldname, `.Equal(&that1.`, fieldname, `) {`)
+				}
+			} else if field.IsBytes() {
+				p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`)
+			} else if field.IsString() {
+				if nullable && !proto3 {
+					p.generateNullableField(fieldname, verbose)
+				} else {
+					p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
+				}
+			} else {
+				if nullable && !proto3 {
+					p.generateNullableField(fieldname, verbose)
+				} else {
+					p.P(`if this.`, fieldname, ` != that1.`, fieldname, `{`)
+				}
+			}
+			p.In()
+			if verbose {
+				p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			p.P(`}`)
+		}
+	} else {
+		p.P(`if len(this.`, fieldname, `) != len(that1.`, fieldname, `) {`)
+		p.In()
+		if verbose {
+			p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", len(this.`, fieldname, `), len(that1.`, fieldname, `))`)
+		} else {
+			p.P(`return false`)
+		}
+		p.Out()
+		p.P(`}`)
+		p.P(`for i := range this.`, fieldname, ` {`)
+		p.In()
+		if ctype && !p.IsMap(field) {
+			p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`)
+		} else if isTimestamp {
+			if nullable {
+				p.P(`if !this.`, fieldname, `[i].Equal(*that1.`, fieldname, `[i]) {`)
+			} else {
+				p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`)
+			}
+		} else if isNormal {
+			if nullable {
+				p.P(`if dthis, dthat := this.`, fieldname, `[i], that1.`, fieldname, `[i]; (dthis != nil && dthat != nil && *dthis != *dthat) || (dthis != nil && dthat == nil) || (dthis == nil && dthat != nil)  {`)
+			} else {
+				p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
+			}
+		} else if isBytes {
+			if nullable {
+				p.P(`if !`, p.bytesPkg.Use(), `.Equal(*this.`, fieldname, `[i], *that1.`, fieldname, `[i]) {`)
+			} else {
+				p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`)
+			}
+		} else {
+			if p.IsMap(field) {
+				m := p.GoMapType(nil, field)
+				valuegoTyp, _ := p.GoType(nil, m.ValueField)
+				valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField)
+				nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
+
+				mapValue := m.ValueAliasField
+				mapValueNormal := (gogoproto.IsStdDuration(mapValue) ||
+					gogoproto.IsStdDouble(mapValue) ||
+					gogoproto.IsStdFloat(mapValue) ||
+					gogoproto.IsStdInt64(mapValue) ||
+					gogoproto.IsStdUInt64(mapValue) ||
+					gogoproto.IsStdInt32(mapValue) ||
+					gogoproto.IsStdUInt32(mapValue) ||
+					gogoproto.IsStdBool(mapValue) ||
+					gogoproto.IsStdString(mapValue))
+				mapValueBytes := gogoproto.IsStdBytes(mapValue)
+				if mapValue.IsMessage() || p.IsGroup(mapValue) {
+					if nullable && valuegoTyp == valuegoAliasTyp {
+						p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`)
+					} else {
+						// Equal() has a pointer receiver, but map value is a value type
+						a := `this.` + fieldname + `[i]`
+						b := `that1.` + fieldname + `[i]`
+						if !mapValueNormal && !mapValueBytes && valuegoTyp != valuegoAliasTyp {
+							// cast back to the type that has the generated methods on it
+							a = `(` + valuegoTyp + `)(` + a + `)`
+							b = `(` + valuegoTyp + `)(` + b + `)`
+						}
+						p.P(`a := `, a)
+						p.P(`b := `, b)
+						if mapValueNormal {
+							if nullable {
+								p.P(`if *a != *b {`)
+							} else {
+								p.P(`if a != b {`)
+							}
+						} else if mapValueBytes {
+							if nullable {
+								p.P(`if !`, p.bytesPkg.Use(), `.Equal(*a, *b) {`)
+							} else {
+								p.P(`if !`, p.bytesPkg.Use(), `.Equal(a, b) {`)
+							}
+						} else if nullable {
+							p.P(`if !a.Equal(b) {`)
+						} else {
+							p.P(`if !(&a).Equal(&b) {`)
+						}
+					}
+				} else if mapValue.IsBytes() {
+					if ctype {
+						if nullable {
+							p.P(`if !this.`, fieldname, `[i].Equal(*that1.`, fieldname, `[i]) { //nullable`)
+						} else {
+							p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) { //not nullable`)
+						}
+					} else {
+						p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`)
+					}
+				} else if mapValue.IsString() {
+					p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
+				} else {
+					p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
+				}
+			} else if field.IsMessage() || p.IsGroup(field) {
+				if nullable {
+					p.P(`if !this.`, fieldname, `[i].Equal(that1.`, fieldname, `[i]) {`)
+				} else {
+					p.P(`if !this.`, fieldname, `[i].Equal(&that1.`, fieldname, `[i]) {`)
+				}
+			} else if field.IsBytes() {
+				p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `[i], that1.`, fieldname, `[i]) {`)
+			} else if field.IsString() {
+				p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
+			} else {
+				p.P(`if this.`, fieldname, `[i] != that1.`, fieldname, `[i] {`)
+			}
+		}
+		p.In()
+		if verbose {
+			p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this[%v](%v) Not Equal that[%v](%v)", i, this.`, fieldname, `[i], i, that1.`, fieldname, `[i])`)
+		} else {
+			p.P(`return false`)
+		}
+		p.Out()
+		p.P(`}`)
+		p.Out()
+		p.P(`}`)
+	}
+}
+
+func (p *plugin) generateMessage(file *generator.FileDescriptor, message *generator.Descriptor, verbose bool) {
+	ccTypeName := generator.CamelCaseSlice(message.TypeName())
+	if verbose {
+		p.P(`func (this *`, ccTypeName, `) VerboseEqual(that interface{}) error {`)
+	} else {
+		p.P(`func (this *`, ccTypeName, `) Equal(that interface{}) bool {`)
+	}
+	p.In()
+	p.generateMsgNullAndTypeCheck(ccTypeName, verbose)
+	oneofs := make(map[string]struct{})
+
+	for _, field := range message.Field {
+		oneof := field.OneofIndex != nil
+		if oneof {
+			fieldname := p.GetFieldName(message, field)
+			if _, ok := oneofs[fieldname]; ok {
+				continue
+			} else {
+				oneofs[fieldname] = struct{}{}
+			}
+			p.P(`if that1.`, fieldname, ` == nil {`)
+			p.In()
+			p.P(`if this.`, fieldname, ` != nil {`)
+			p.In()
+			if verbose {
+				p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` != nil && that1.`, fieldname, ` == nil")`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`} else if this.`, fieldname, ` == nil {`)
+			p.In()
+			if verbose {
+				p.P(`return `, p.fmtPkg.Use(), `.Errorf("this.`, fieldname, ` == nil && that1.`, fieldname, ` != nil")`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			if verbose {
+				p.P(`} else if err := this.`, fieldname, `.VerboseEqual(that1.`, fieldname, `); err != nil {`)
+			} else {
+				p.P(`} else if !this.`, fieldname, `.Equal(that1.`, fieldname, `) {`)
+			}
+			p.In()
+			if verbose {
+				p.P(`return err`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			p.P(`}`)
+		} else {
+			p.generateField(file, message, field, verbose)
+		}
+	}
+	if message.DescriptorProto.HasExtension() {
+		if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
+			fieldname := "XXX_InternalExtensions"
+			p.P(`thismap := `, p.protoPkg.Use(), `.GetUnsafeExtensionsMap(this)`)
+			p.P(`thatmap := `, p.protoPkg.Use(), `.GetUnsafeExtensionsMap(that1)`)
+			p.P(`for k, v := range thismap {`)
+			p.In()
+			p.P(`if v2, ok := thatmap[k]; ok {`)
+			p.In()
+			p.P(`if !v.Equal(&v2) {`)
+			p.In()
+			if verbose {
+				p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this[%v](%v) Not Equal that[%v](%v)", k, thismap[k], k, thatmap[k])`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`} else  {`)
+			p.In()
+			if verbose {
+				p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, `[%v] Not In that", k)`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+
+			p.P(`for k, _ := range thatmap {`)
+			p.In()
+			p.P(`if _, ok := thismap[k]; !ok {`)
+			p.In()
+			if verbose {
+				p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, `[%v] Not In this", k)`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+		} else {
+			fieldname := "XXX_extensions"
+			p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`)
+			p.In()
+			if verbose {
+				p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
+			} else {
+				p.P(`return false`)
+			}
+			p.Out()
+			p.P(`}`)
+		}
+	}
+	if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
+		fieldname := "XXX_unrecognized"
+		p.P(`if !`, p.bytesPkg.Use(), `.Equal(this.`, fieldname, `, that1.`, fieldname, `) {`)
+		p.In()
+		if verbose {
+			p.P(`return `, p.fmtPkg.Use(), `.Errorf("`, fieldname, ` this(%v) Not Equal that(%v)", this.`, fieldname, `, that1.`, fieldname, `)`)
+		} else {
+			p.P(`return false`)
+		}
+		p.Out()
+		p.P(`}`)
+	}
+	if verbose {
+		p.P(`return nil`)
+	} else {
+		p.P(`return true`)
+	}
+	p.Out()
+	p.P(`}`)
+
+	//Generate Equal methods for oneof fields
+	m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
+	for _, field := range m.Field {
+		oneof := field.OneofIndex != nil
+		if !oneof {
+			continue
+		}
+		ccTypeName := p.OneOfTypeName(message, field)
+		if verbose {
+			p.P(`func (this *`, ccTypeName, `) VerboseEqual(that interface{}) error {`)
+		} else {
+			p.P(`func (this *`, ccTypeName, `) Equal(that interface{}) bool {`)
+		}
+		p.In()
+
+		p.generateMsgNullAndTypeCheck(ccTypeName, verbose)
+		vanity.TurnOffNullableForNativeTypes(field)
+		p.generateField(file, message, field, verbose)
+
+		if verbose {
+			p.P(`return nil`)
+		} else {
+			p.P(`return true`)
+		}
+		p.Out()
+		p.P(`}`)
+	}
+}
+
+func init() {
+	generator.RegisterPlugin(NewPlugin())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/face/face.go b/vendor/github.com/gogo/protobuf/plugin/face/face.go
new file mode 100644
index 0000000000000..a029345265266
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/face/face.go
@@ -0,0 +1,233 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The face plugin generates a function will be generated which can convert a structure which satisfies an interface (face) to the specified structure.
+This interface contains getters for each of the fields in the struct.
+The specified struct is also generated with the getters.
+This means that getters should be turned off so as not to conflict with face getters.
+This allows it to satisfy its own face.
+
+It is enabled by the following extensions:
+
+  - face
+  - face_all
+
+Turn off getters by using the following extensions:
+
+  - getters
+  - getters_all
+
+The face plugin also generates a test given it is enabled using one of the following extensions:
+
+  - testgen
+  - testgen_all
+
+Let us look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+  message A {
+	option (gogoproto.face) = true;
+	option (gogoproto.goproto_getters) = false;
+	optional string Description = 1 [(gogoproto.nullable) = false];
+	optional int64 Number = 2 [(gogoproto.nullable) = false];
+	optional bytes Id = 3 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uuid", (gogoproto.nullable) = false];
+  }
+
+given to the face plugin, will generate the following code:
+
+	type AFace interface {
+		Proto() github_com_gogo_protobuf_proto.Message
+		GetDescription() string
+		GetNumber() int64
+		GetId() github_com_gogo_protobuf_test_custom.Uuid
+	}
+
+	func (this *A) Proto() github_com_gogo_protobuf_proto.Message {
+		return this
+	}
+
+	func (this *A) TestProto() github_com_gogo_protobuf_proto.Message {
+		return NewAFromFace(this)
+	}
+
+	func (this *A) GetDescription() string {
+		return this.Description
+	}
+
+	func (this *A) GetNumber() int64 {
+		return this.Number
+	}
+
+	func (this *A) GetId() github_com_gogo_protobuf_test_custom.Uuid {
+		return this.Id
+	}
+
+	func NewAFromFace(that AFace) *A {
+		this := &A{}
+		this.Description = that.GetDescription()
+		this.Number = that.GetNumber()
+		this.Id = that.GetId()
+		return this
+	}
+
+and the following test code:
+
+	func TestAFace(t *testing7.T) {
+		popr := math_rand7.New(math_rand7.NewSource(time7.Now().UnixNano()))
+		p := NewPopulatedA(popr, true)
+		msg := p.TestProto()
+		if !p.Equal(msg) {
+			t.Fatalf("%#v !Face Equal %#v", msg, p)
+		}
+	}
+
+The struct A, representing the message, will also be generated just like always.
+As you can see A satisfies its own Face, AFace.
+
+Creating another struct which satisfies AFace is very easy.
+Simply create all these methods specified in AFace.
+Implementing The Proto method is done with the helper function NewAFromFace:
+
+	func (this *MyStruct) Proto() proto.Message {
+	  return NewAFromFace(this)
+	}
+
+just the like TestProto method which is used to test the NewAFromFace function.
+
+*/
+package face
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type plugin struct {
+	*generator.Generator
+	generator.PluginImports
+}
+
+func NewPlugin() *plugin {
+	return &plugin{}
+}
+
+func (p *plugin) Name() string {
+	return "face"
+}
+
+func (p *plugin) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *plugin) Generate(file *generator.FileDescriptor) {
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		protoPkg = p.NewImport("github.com/golang/protobuf/proto")
+	}
+	for _, message := range file.Messages() {
+		if !gogoproto.IsFace(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		if message.DescriptorProto.HasExtension() {
+			panic("face does not support message with extensions")
+		}
+		if gogoproto.HasGoGetters(file.FileDescriptorProto, message.DescriptorProto) {
+			panic("face requires getters to be disabled please use gogoproto.getters or gogoproto.getters_all and set it to false")
+		}
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		p.P(`type `, ccTypeName, `Face interface{`)
+		p.In()
+		p.P(`Proto() `, protoPkg.Use(), `.Message`)
+		for _, field := range message.Field {
+			fieldname := p.GetFieldName(message, field)
+			goTyp, _ := p.GoType(message, field)
+			if p.IsMap(field) {
+				m := p.GoMapType(nil, field)
+				goTyp = m.GoType
+			}
+			p.P(`Get`, fieldname, `() `, goTyp)
+		}
+		p.Out()
+		p.P(`}`)
+		p.P(``)
+		p.P(`func (this *`, ccTypeName, `) Proto() `, protoPkg.Use(), `.Message {`)
+		p.In()
+		p.P(`return this`)
+		p.Out()
+		p.P(`}`)
+		p.P(``)
+		p.P(`func (this *`, ccTypeName, `) TestProto() `, protoPkg.Use(), `.Message {`)
+		p.In()
+		p.P(`return New`, ccTypeName, `FromFace(this)`)
+		p.Out()
+		p.P(`}`)
+		p.P(``)
+		for _, field := range message.Field {
+			fieldname := p.GetFieldName(message, field)
+			goTyp, _ := p.GoType(message, field)
+			if p.IsMap(field) {
+				m := p.GoMapType(nil, field)
+				goTyp = m.GoType
+			}
+			p.P(`func (this *`, ccTypeName, `) Get`, fieldname, `() `, goTyp, `{`)
+			p.In()
+			p.P(` return this.`, fieldname)
+			p.Out()
+			p.P(`}`)
+			p.P(``)
+		}
+		p.P(``)
+		p.P(`func New`, ccTypeName, `FromFace(that `, ccTypeName, `Face) *`, ccTypeName, ` {`)
+		p.In()
+		p.P(`this := &`, ccTypeName, `{}`)
+		for _, field := range message.Field {
+			fieldname := p.GetFieldName(message, field)
+			p.P(`this.`, fieldname, ` = that.Get`, fieldname, `()`)
+		}
+		p.P(`return this`)
+		p.Out()
+		p.P(`}`)
+		p.P(``)
+	}
+}
+
+func init() {
+	generator.RegisterPlugin(NewPlugin())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/gostring/gostring.go b/vendor/github.com/gogo/protobuf/plugin/gostring/gostring.go
new file mode 100644
index 0000000000000..bc89a7b871d06
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/gostring/gostring.go
@@ -0,0 +1,386 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The gostring plugin generates a GoString method for each message.
+The GoString method is called whenever you use a fmt.Printf as such:
+
+  fmt.Printf("%#v", mymessage)
+
+or whenever you actually call GoString()
+The output produced by the GoString method can be copied from the output into code and used to set a variable.
+It is totally valid Go Code and is populated exactly as the struct that was printed out.
+
+It is enabled by the following extensions:
+
+  - gostring
+  - gostring_all
+
+The gostring plugin also generates a test given it is enabled using one of the following extensions:
+
+  - testgen
+  - testgen_all
+
+Let us look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+  option (gogoproto.gostring_all) = true;
+
+  message A {
+	optional string Description = 1 [(gogoproto.nullable) = false];
+	optional int64 Number = 2 [(gogoproto.nullable) = false];
+	optional bytes Id = 3 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uuid", (gogoproto.nullable) = false];
+  }
+
+given to the gostring plugin, will generate the following code:
+
+  func (this *A) GoString() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings1.Join([]string{`&test.A{` + `Description:` + fmt1.Sprintf("%#v", this.Description), `Number:` + fmt1.Sprintf("%#v", this.Number), `Id:` + fmt1.Sprintf("%#v", this.Id), `XXX_unrecognized:` + fmt1.Sprintf("%#v", this.XXX_unrecognized) + `}`}, ", ")
+	return s
+  }
+
+and the following test code:
+
+	func TestAGoString(t *testing6.T) {
+		popr := math_rand6.New(math_rand6.NewSource(time6.Now().UnixNano()))
+		p := NewPopulatedA(popr, false)
+		s1 := p.GoString()
+		s2 := fmt2.Sprintf("%#v", p)
+		if s1 != s2 {
+			t.Fatalf("GoString want %v got %v", s1, s2)
+		}
+		_, err := go_parser.ParseExpr(s1)
+		if err != nil {
+			panic(err)
+		}
+	}
+
+Typically fmt.Printf("%#v") will stop to print when it reaches a pointer and
+not print their values, while the generated GoString method will always print all values, recursively.
+
+*/
+package gostring
+
+import (
+	"fmt"
+	"os"
+	"strconv"
+	"strings"
+
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type gostring struct {
+	*generator.Generator
+	generator.PluginImports
+	atleastOne bool
+	localName  string
+	overwrite  bool
+}
+
+func NewGoString() *gostring {
+	return &gostring{}
+}
+
+func (p *gostring) Name() string {
+	return "gostring"
+}
+
+func (p *gostring) Overwrite() {
+	p.overwrite = true
+}
+
+func (p *gostring) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *gostring) Generate(file *generator.FileDescriptor) {
+	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	p.atleastOne = false
+
+	p.localName = generator.FileName(file)
+
+	fmtPkg := p.NewImport("fmt")
+	stringsPkg := p.NewImport("strings")
+	protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		protoPkg = p.NewImport("github.com/golang/protobuf/proto")
+	}
+	sortPkg := p.NewImport("sort")
+	strconvPkg := p.NewImport("strconv")
+	reflectPkg := p.NewImport("reflect")
+	sortKeysPkg := p.NewImport("github.com/gogo/protobuf/sortkeys")
+
+	extensionToGoStringUsed := false
+	for _, message := range file.Messages() {
+		if !p.overwrite && !gogoproto.HasGoString(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		p.atleastOne = true
+		packageName := file.GoPackageName()
+
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		p.P(`func (this *`, ccTypeName, `) GoString() string {`)
+		p.In()
+		p.P(`if this == nil {`)
+		p.In()
+		p.P(`return "nil"`)
+		p.Out()
+		p.P(`}`)
+
+		p.P(`s := make([]string, 0, `, strconv.Itoa(len(message.Field)+4), `)`)
+		p.P(`s = append(s, "&`, packageName, ".", ccTypeName, `{")`)
+
+		oneofs := make(map[string]struct{})
+		for _, field := range message.Field {
+			nullable := gogoproto.IsNullable(field)
+			repeated := field.IsRepeated()
+			fieldname := p.GetFieldName(message, field)
+			oneof := field.OneofIndex != nil
+			if oneof {
+				if _, ok := oneofs[fieldname]; ok {
+					continue
+				} else {
+					oneofs[fieldname] = struct{}{}
+				}
+				p.P(`if this.`, fieldname, ` != nil {`)
+				p.In()
+				p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
+				p.Out()
+				p.P(`}`)
+			} else if p.IsMap(field) {
+				m := p.GoMapType(nil, field)
+				mapgoTyp, keyField, keyAliasField := m.GoType, m.KeyField, m.KeyAliasField
+				keysName := `keysFor` + fieldname
+				keygoTyp, _ := p.GoType(nil, keyField)
+				keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
+				keygoAliasTyp, _ := p.GoType(nil, keyAliasField)
+				keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
+				keyCapTyp := generator.CamelCase(keygoTyp)
+				p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(this.`, fieldname, `))`)
+				p.P(`for k, _ := range this.`, fieldname, ` {`)
+				p.In()
+				if keygoAliasTyp == keygoTyp {
+					p.P(keysName, ` = append(`, keysName, `, k)`)
+				} else {
+					p.P(keysName, ` = append(`, keysName, `, `, keygoTyp, `(k))`)
+				}
+				p.Out()
+				p.P(`}`)
+				p.P(sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`)
+				mapName := `mapStringFor` + fieldname
+				p.P(mapName, ` := "`, mapgoTyp, `{"`)
+				p.P(`for _, k := range `, keysName, ` {`)
+				p.In()
+				if keygoAliasTyp == keygoTyp {
+					p.P(mapName, ` += fmt.Sprintf("%#v: %#v,", k, this.`, fieldname, `[k])`)
+				} else {
+					p.P(mapName, ` += fmt.Sprintf("%#v: %#v,", k, this.`, fieldname, `[`, keygoAliasTyp, `(k)])`)
+				}
+				p.Out()
+				p.P(`}`)
+				p.P(mapName, ` += "}"`)
+				p.P(`if this.`, fieldname, ` != nil {`)
+				p.In()
+				p.P(`s = append(s, "`, fieldname, `: " + `, mapName, `+ ",\n")`)
+				p.Out()
+				p.P(`}`)
+			} else if (field.IsMessage() && !gogoproto.IsCustomType(field) && !gogoproto.IsStdType(field)) || p.IsGroup(field) {
+				if nullable || repeated {
+					p.P(`if this.`, fieldname, ` != nil {`)
+					p.In()
+				}
+				if nullable {
+					p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
+				} else if repeated {
+					if nullable {
+						p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
+					} else {
+						goTyp, _ := p.GoType(message, field)
+						goTyp = strings.Replace(goTyp, "[]", "", 1)
+						p.P("vs := make([]", goTyp, ", len(this.", fieldname, "))")
+						p.P("for i := range vs {")
+						p.In()
+						p.P("vs[i] = this.", fieldname, "[i]")
+						p.Out()
+						p.P("}")
+						p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", vs) + ",\n")`)
+					}
+				} else {
+					p.P(`s = append(s, "`, fieldname, `: " + `, stringsPkg.Use(), `.Replace(this.`, fieldname, `.GoString()`, ",`&`,``,1)", ` + ",\n")`)
+				}
+				if nullable || repeated {
+					p.Out()
+					p.P(`}`)
+				}
+			} else {
+				if !proto3 && (nullable || repeated) {
+					p.P(`if this.`, fieldname, ` != nil {`)
+					p.In()
+				}
+				if field.IsEnum() {
+					if nullable && !repeated && !proto3 {
+						goTyp, _ := p.GoType(message, field)
+						p.P(`s = append(s, "`, fieldname, `: " + valueToGoString`, p.localName, `(this.`, fieldname, `,"`, generator.GoTypeToName(goTyp), `"`, `) + ",\n")`)
+					} else {
+						p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
+					}
+				} else {
+					if nullable && !repeated && !proto3 {
+						goTyp, _ := p.GoType(message, field)
+						p.P(`s = append(s, "`, fieldname, `: " + valueToGoString`, p.localName, `(this.`, fieldname, `,"`, generator.GoTypeToName(goTyp), `"`, `) + ",\n")`)
+					} else {
+						p.P(`s = append(s, "`, fieldname, `: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `) + ",\n")`)
+					}
+				}
+				if !proto3 && (nullable || repeated) {
+					p.Out()
+					p.P(`}`)
+				}
+			}
+		}
+		if message.DescriptorProto.HasExtension() {
+			if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P(`s = append(s, "XXX_InternalExtensions: " + extensionToGoString`, p.localName, `(this) + ",\n")`)
+				extensionToGoStringUsed = true
+			} else {
+				p.P(`if this.XXX_extensions != nil {`)
+				p.In()
+				p.P(`s = append(s, "XXX_extensions: " + `, fmtPkg.Use(), `.Sprintf("%#v", this.XXX_extensions) + ",\n")`)
+				p.Out()
+				p.P(`}`)
+			}
+		}
+		if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
+			p.P(`if this.XXX_unrecognized != nil {`)
+			p.In()
+			p.P(`s = append(s, "XXX_unrecognized:" + `, fmtPkg.Use(), `.Sprintf("%#v", this.XXX_unrecognized) + ",\n")`)
+			p.Out()
+			p.P(`}`)
+		}
+
+		p.P(`s = append(s, "}")`)
+		p.P(`return `, stringsPkg.Use(), `.Join(s, "")`)
+		p.Out()
+		p.P(`}`)
+
+		//Generate GoString methods for oneof fields
+		for _, field := range message.Field {
+			oneof := field.OneofIndex != nil
+			if !oneof {
+				continue
+			}
+			ccTypeName := p.OneOfTypeName(message, field)
+			p.P(`func (this *`, ccTypeName, `) GoString() string {`)
+			p.In()
+			p.P(`if this == nil {`)
+			p.In()
+			p.P(`return "nil"`)
+			p.Out()
+			p.P(`}`)
+			fieldname := p.GetOneOfFieldName(message, field)
+			outStr := strings.Join([]string{
+				"s := ",
+				stringsPkg.Use(), ".Join([]string{`&", packageName, ".", ccTypeName, "{` + \n",
+				"`", fieldname, ":` + ", fmtPkg.Use(), `.Sprintf("%#v", this.`, fieldname, `)`,
+				" + `}`",
+				`}`,
+				`,", "`,
+				`)`}, "")
+			p.P(outStr)
+			p.P(`return s`)
+			p.Out()
+			p.P(`}`)
+		}
+	}
+
+	if !p.atleastOne {
+		return
+	}
+
+	p.P(`func valueToGoString`, p.localName, `(v interface{}, typ string) string {`)
+	p.In()
+	p.P(`rv := `, reflectPkg.Use(), `.ValueOf(v)`)
+	p.P(`if rv.IsNil() {`)
+	p.In()
+	p.P(`return "nil"`)
+	p.Out()
+	p.P(`}`)
+	p.P(`pv := `, reflectPkg.Use(), `.Indirect(rv).Interface()`)
+	p.P(`return `, fmtPkg.Use(), `.Sprintf("func(v %v) *%v { return &v } ( %#v )", typ, typ, pv)`)
+	p.Out()
+	p.P(`}`)
+
+	if extensionToGoStringUsed {
+		if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+			fmt.Fprintf(os.Stderr, "The GoString plugin for messages with extensions requires importing gogoprotobuf. Please see file %s", file.GetName())
+			os.Exit(1)
+		}
+		p.P(`func extensionToGoString`, p.localName, `(m `, protoPkg.Use(), `.Message) string {`)
+		p.In()
+		p.P(`e := `, protoPkg.Use(), `.GetUnsafeExtensionsMap(m)`)
+		p.P(`if e == nil { return "nil" }`)
+		p.P(`s := "proto.NewUnsafeXXX_InternalExtensions(map[int32]proto.Extension{"`)
+		p.P(`keys := make([]int, 0, len(e))`)
+		p.P(`for k := range e {`)
+		p.In()
+		p.P(`keys = append(keys, int(k))`)
+		p.Out()
+		p.P(`}`)
+		p.P(sortPkg.Use(), `.Ints(keys)`)
+		p.P(`ss := []string{}`)
+		p.P(`for _, k := range keys {`)
+		p.In()
+		p.P(`ss = append(ss, `, strconvPkg.Use(), `.Itoa(k) + ": " + e[int32(k)].GoString())`)
+		p.Out()
+		p.P(`}`)
+		p.P(`s+=`, stringsPkg.Use(), `.Join(ss, ",") + "})"`)
+		p.P(`return s`)
+		p.Out()
+		p.P(`}`)
+	}
+}
+
+func init() {
+	generator.RegisterPlugin(NewGoString())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/marshalto/marshalto.go b/vendor/github.com/gogo/protobuf/plugin/marshalto/marshalto.go
new file mode 100644
index 0000000000000..f82c28c281e69
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/marshalto/marshalto.go
@@ -0,0 +1,1140 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The marshalto plugin generates a Marshal and MarshalTo method for each message.
+The `Marshal() ([]byte, error)` method results in the fact that the message
+implements the Marshaler interface.
+This allows proto.Marshal to be faster by calling the generated Marshal method rather than using reflect to Marshal the struct.
+
+If is enabled by the following extensions:
+
+  - marshaler
+  - marshaler_all
+
+Or the following extensions:
+
+  - unsafe_marshaler
+  - unsafe_marshaler_all
+
+That is if you want to use the unsafe package in your generated code.
+The speed up using the unsafe package is not very significant.
+
+The generation of marshalling tests are enabled using one of the following extensions:
+
+  - testgen
+  - testgen_all
+
+And benchmarks given it is enabled using one of the following extensions:
+
+  - benchgen
+  - benchgen_all
+
+Let us look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+option (gogoproto.marshaler_all) = true;
+
+message B {
+	option (gogoproto.description) = true;
+	optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
+	repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false];
+}
+
+given to the marshalto plugin, will generate the following code:
+
+  func (m *B) Marshal() (dAtA []byte, err error) {
+          size := m.Size()
+          dAtA = make([]byte, size)
+          n, err := m.MarshalToSizedBuffer(dAtA[:size])
+          if err != nil {
+                  return nil, err
+          }
+          return dAtA[:n], nil
+  }
+
+  func (m *B) MarshalTo(dAtA []byte) (int, error) {
+          size := m.Size()
+          return m.MarshalToSizedBuffer(dAtA[:size])
+  }
+
+  func (m *B) MarshalToSizedBuffer(dAtA []byte) (int, error) {
+          i := len(dAtA)
+          _ = i
+          var l int
+          _ = l
+          if m.XXX_unrecognized != nil {
+                  i -= len(m.XXX_unrecognized)
+                  copy(dAtA[i:], m.XXX_unrecognized)
+          }
+          if len(m.G) > 0 {
+                  for iNdEx := len(m.G) - 1; iNdEx >= 0; iNdEx-- {
+                          {
+                                  size := m.G[iNdEx].Size()
+                                  i -= size
+                                  if _, err := m.G[iNdEx].MarshalTo(dAtA[i:]); err != nil {
+                                          return 0, err
+                                  }
+                                  i = encodeVarintExample(dAtA, i, uint64(size))
+                          }
+                          i--
+                          dAtA[i] = 0x12
+                  }
+          }
+          {
+                  size, err := m.A.MarshalToSizedBuffer(dAtA[:i])
+                  if err != nil {
+                          return 0, err
+                  }
+                  i -= size
+                  i = encodeVarintExample(dAtA, i, uint64(size))
+          }
+          i--
+          dAtA[i] = 0xa
+          return len(dAtA) - i, nil
+  }
+
+As shown above Marshal calculates the size of the not yet marshalled message
+and allocates the appropriate buffer.
+This is followed by calling the MarshalToSizedBuffer method which requires a preallocated buffer, and marshals backwards.
+The MarshalTo method allows a user to rather preallocated a reusable buffer.
+
+The Size method is generated using the size plugin and the gogoproto.sizer, gogoproto.sizer_all extensions.
+The user can also using the generated Size method to check that his reusable buffer is still big enough.
+
+The generated tests and benchmarks will keep you safe and show that this is really a significant speed improvement.
+
+An additional message-level option `stable_marshaler` (and the file-level
+option `stable_marshaler_all`) exists which causes the generated marshalling
+code to behave deterministically. Today, this only changes the serialization of
+maps; they are serialized in sort order.
+*/
+package marshalto
+
+import (
+	"fmt"
+	"sort"
+	"strconv"
+	"strings"
+
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+	"github.com/gogo/protobuf/vanity"
+)
+
+type NumGen interface {
+	Next() string
+	Current() string
+}
+
+type numGen struct {
+	index int
+}
+
+func NewNumGen() NumGen {
+	return &numGen{0}
+}
+
+func (this *numGen) Next() string {
+	this.index++
+	return this.Current()
+}
+
+func (this *numGen) Current() string {
+	return strconv.Itoa(this.index)
+}
+
+type marshalto struct {
+	*generator.Generator
+	generator.PluginImports
+	atleastOne  bool
+	errorsPkg   generator.Single
+	protoPkg    generator.Single
+	sortKeysPkg generator.Single
+	mathPkg     generator.Single
+	typesPkg    generator.Single
+	binaryPkg   generator.Single
+	localName   string
+}
+
+func NewMarshal() *marshalto {
+	return &marshalto{}
+}
+
+func (p *marshalto) Name() string {
+	return "marshalto"
+}
+
+func (p *marshalto) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *marshalto) callFixed64(varName ...string) {
+	p.P(`i -= 8`)
+	p.P(p.binaryPkg.Use(), `.LittleEndian.PutUint64(dAtA[i:], uint64(`, strings.Join(varName, ""), `))`)
+}
+
+func (p *marshalto) callFixed32(varName ...string) {
+	p.P(`i -= 4`)
+	p.P(p.binaryPkg.Use(), `.LittleEndian.PutUint32(dAtA[i:], uint32(`, strings.Join(varName, ""), `))`)
+}
+
+func (p *marshalto) callVarint(varName ...string) {
+	p.P(`i = encodeVarint`, p.localName, `(dAtA, i, uint64(`, strings.Join(varName, ""), `))`)
+}
+
+func (p *marshalto) encodeKey(fieldNumber int32, wireType int) {
+	x := uint32(fieldNumber)<<3 | uint32(wireType)
+	i := 0
+	keybuf := make([]byte, 0)
+	for i = 0; x > 127; i++ {
+		keybuf = append(keybuf, 0x80|uint8(x&0x7F))
+		x >>= 7
+	}
+	keybuf = append(keybuf, uint8(x))
+	for i = len(keybuf) - 1; i >= 0; i-- {
+		p.P(`i--`)
+		p.P(`dAtA[i] = `, fmt.Sprintf("%#v", keybuf[i]))
+	}
+}
+
+func keySize(fieldNumber int32, wireType int) int {
+	x := uint32(fieldNumber)<<3 | uint32(wireType)
+	size := 0
+	for size = 0; x > 127; size++ {
+		x >>= 7
+	}
+	size++
+	return size
+}
+
+func wireToType(wire string) int {
+	switch wire {
+	case "fixed64":
+		return proto.WireFixed64
+	case "fixed32":
+		return proto.WireFixed32
+	case "varint":
+		return proto.WireVarint
+	case "bytes":
+		return proto.WireBytes
+	case "group":
+		return proto.WireBytes
+	case "zigzag32":
+		return proto.WireVarint
+	case "zigzag64":
+		return proto.WireVarint
+	}
+	panic("unreachable")
+}
+
+func (p *marshalto) mapField(numGen NumGen, field *descriptor.FieldDescriptorProto, kvField *descriptor.FieldDescriptorProto, varName string, protoSizer bool) {
+	switch kvField.GetType() {
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+		p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(`, varName, `))`)
+	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+		p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(`, varName, `))`)
+	case descriptor.FieldDescriptorProto_TYPE_INT64,
+		descriptor.FieldDescriptorProto_TYPE_UINT64,
+		descriptor.FieldDescriptorProto_TYPE_INT32,
+		descriptor.FieldDescriptorProto_TYPE_UINT32,
+		descriptor.FieldDescriptorProto_TYPE_ENUM:
+		p.callVarint(varName)
+	case descriptor.FieldDescriptorProto_TYPE_FIXED64,
+		descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+		p.callFixed64(varName)
+	case descriptor.FieldDescriptorProto_TYPE_FIXED32,
+		descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+		p.callFixed32(varName)
+	case descriptor.FieldDescriptorProto_TYPE_BOOL:
+		p.P(`i--`)
+		p.P(`if `, varName, ` {`)
+		p.In()
+		p.P(`dAtA[i] = 1`)
+		p.Out()
+		p.P(`} else {`)
+		p.In()
+		p.P(`dAtA[i] = 0`)
+		p.Out()
+		p.P(`}`)
+	case descriptor.FieldDescriptorProto_TYPE_STRING,
+		descriptor.FieldDescriptorProto_TYPE_BYTES:
+		if gogoproto.IsCustomType(field) && kvField.IsBytes() {
+			p.forward(varName, true, protoSizer)
+		} else {
+			p.P(`i -= len(`, varName, `)`)
+			p.P(`copy(dAtA[i:], `, varName, `)`)
+			p.callVarint(`len(`, varName, `)`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_SINT32:
+		p.callVarint(`(uint32(`, varName, `) << 1) ^ uint32((`, varName, ` >> 31))`)
+	case descriptor.FieldDescriptorProto_TYPE_SINT64:
+		p.callVarint(`(uint64(`, varName, `) << 1) ^ uint64((`, varName, ` >> 63))`)
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		if !p.marshalAllSizeOf(kvField, `(*`+varName+`)`, numGen.Next()) {
+			if gogoproto.IsCustomType(field) {
+				p.forward(varName, true, protoSizer)
+			} else {
+				p.backward(varName, true)
+			}
+		}
+
+	}
+}
+
+type orderFields []*descriptor.FieldDescriptorProto
+
+func (this orderFields) Len() int {
+	return len(this)
+}
+
+func (this orderFields) Less(i, j int) bool {
+	return this[i].GetNumber() < this[j].GetNumber()
+}
+
+func (this orderFields) Swap(i, j int) {
+	this[i], this[j] = this[j], this[i]
+}
+
+func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) {
+	fieldname := p.GetOneOfFieldName(message, field)
+	nullable := gogoproto.IsNullable(field)
+	repeated := field.IsRepeated()
+	required := field.IsRequired()
+
+	protoSizer := gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto)
+	doNilCheck := gogoproto.NeedsNilCheck(proto3, field)
+	if required && nullable {
+		p.P(`if m.`, fieldname, `== nil {`)
+		p.In()
+		if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+			p.P(`return 0, new(`, p.protoPkg.Use(), `.RequiredNotSetError)`)
+		} else {
+			p.P(`return 0, `, p.protoPkg.Use(), `.NewRequiredNotSetError("`, field.GetName(), `")`)
+		}
+		p.Out()
+		p.P(`} else {`)
+	} else if repeated {
+		p.P(`if len(m.`, fieldname, `) > 0 {`)
+		p.In()
+	} else if doNilCheck {
+		p.P(`if m.`, fieldname, ` != nil {`)
+		p.In()
+	}
+	packed := field.IsPacked() || (proto3 && field.IsPacked3())
+	wireType := field.WireType()
+	fieldNumber := field.GetNumber()
+	if packed {
+		wireType = proto.WireBytes
+	}
+	switch *field.Type {
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+		if packed {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(`, val, `))`)
+			p.callFixed64("f" + numGen.Current())
+			p.Out()
+			p.P(`}`)
+			p.callVarint(`len(m.`, fieldname, `) * 8`)
+			p.encodeKey(fieldNumber, wireType)
+		} else if repeated {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(`, val, `))`)
+			p.callFixed64("f" + numGen.Current())
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if !nullable {
+			p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`)
+			p.encodeKey(fieldNumber, wireType)
+		} else {
+			p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(*m.`+fieldname, `))`)
+			p.encodeKey(fieldNumber, wireType)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+		if packed {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(`, val, `))`)
+			p.callFixed32("f" + numGen.Current())
+			p.Out()
+			p.P(`}`)
+			p.callVarint(`len(m.`, fieldname, `) * 4`)
+			p.encodeKey(fieldNumber, wireType)
+		} else if repeated {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(`, val, `))`)
+			p.callFixed32("f" + numGen.Current())
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if !nullable {
+			p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`)
+			p.encodeKey(fieldNumber, wireType)
+		} else {
+			p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(*m.`+fieldname, `))`)
+			p.encodeKey(fieldNumber, wireType)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_INT64,
+		descriptor.FieldDescriptorProto_TYPE_UINT64,
+		descriptor.FieldDescriptorProto_TYPE_INT32,
+		descriptor.FieldDescriptorProto_TYPE_UINT32,
+		descriptor.FieldDescriptorProto_TYPE_ENUM:
+		if packed {
+			jvar := "j" + numGen.Next()
+			p.P(`dAtA`, numGen.Next(), ` := make([]byte, len(m.`, fieldname, `)*10)`)
+			p.P(`var `, jvar, ` int`)
+			if *field.Type == descriptor.FieldDescriptorProto_TYPE_INT64 ||
+				*field.Type == descriptor.FieldDescriptorProto_TYPE_INT32 {
+				p.P(`for _, num1 := range m.`, fieldname, ` {`)
+				p.In()
+				p.P(`num := uint64(num1)`)
+			} else {
+				p.P(`for _, num := range m.`, fieldname, ` {`)
+				p.In()
+			}
+			p.P(`for num >= 1<<7 {`)
+			p.In()
+			p.P(`dAtA`, numGen.Current(), `[`, jvar, `] = uint8(uint64(num)&0x7f|0x80)`)
+			p.P(`num >>= 7`)
+			p.P(jvar, `++`)
+			p.Out()
+			p.P(`}`)
+			p.P(`dAtA`, numGen.Current(), `[`, jvar, `] = uint8(num)`)
+			p.P(jvar, `++`)
+			p.Out()
+			p.P(`}`)
+			p.P(`i -= `, jvar)
+			p.P(`copy(dAtA[i:], dAtA`, numGen.Current(), `[:`, jvar, `])`)
+			p.callVarint(jvar)
+			p.encodeKey(fieldNumber, wireType)
+		} else if repeated {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.callVarint(val)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.callVarint(`m.`, fieldname)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if !nullable {
+			p.callVarint(`m.`, fieldname)
+			p.encodeKey(fieldNumber, wireType)
+		} else {
+			p.callVarint(`*m.`, fieldname)
+			p.encodeKey(fieldNumber, wireType)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_FIXED64,
+		descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+		if packed {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.callFixed64(val)
+			p.Out()
+			p.P(`}`)
+			p.callVarint(`len(m.`, fieldname, `) * 8`)
+			p.encodeKey(fieldNumber, wireType)
+		} else if repeated {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.callFixed64(val)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.callFixed64("m." + fieldname)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if !nullable {
+			p.callFixed64("m." + fieldname)
+			p.encodeKey(fieldNumber, wireType)
+		} else {
+			p.callFixed64("*m." + fieldname)
+			p.encodeKey(fieldNumber, wireType)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_FIXED32,
+		descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+		if packed {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.callFixed32(val)
+			p.Out()
+			p.P(`}`)
+			p.callVarint(`len(m.`, fieldname, `) * 4`)
+			p.encodeKey(fieldNumber, wireType)
+		} else if repeated {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.callFixed32(val)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.callFixed32("m." + fieldname)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if !nullable {
+			p.callFixed32("m." + fieldname)
+			p.encodeKey(fieldNumber, wireType)
+		} else {
+			p.callFixed32("*m." + fieldname)
+			p.encodeKey(fieldNumber, wireType)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_BOOL:
+		if packed {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.P(`i--`)
+			p.P(`if `, val, ` {`)
+			p.In()
+			p.P(`dAtA[i] = 1`)
+			p.Out()
+			p.P(`} else {`)
+			p.In()
+			p.P(`dAtA[i] = 0`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+			p.callVarint(`len(m.`, fieldname, `)`)
+			p.encodeKey(fieldNumber, wireType)
+		} else if repeated {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.P(`i--`)
+			p.P(`if `, val, ` {`)
+			p.In()
+			p.P(`dAtA[i] = 1`)
+			p.Out()
+			p.P(`} else {`)
+			p.In()
+			p.P(`dAtA[i] = 0`)
+			p.Out()
+			p.P(`}`)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` {`)
+			p.In()
+			p.P(`i--`)
+			p.P(`if m.`, fieldname, ` {`)
+			p.In()
+			p.P(`dAtA[i] = 1`)
+			p.Out()
+			p.P(`} else {`)
+			p.In()
+			p.P(`dAtA[i] = 0`)
+			p.Out()
+			p.P(`}`)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if !nullable {
+			p.P(`i--`)
+			p.P(`if m.`, fieldname, ` {`)
+			p.In()
+			p.P(`dAtA[i] = 1`)
+			p.Out()
+			p.P(`} else {`)
+			p.In()
+			p.P(`dAtA[i] = 0`)
+			p.Out()
+			p.P(`}`)
+			p.encodeKey(fieldNumber, wireType)
+		} else {
+			p.P(`i--`)
+			p.P(`if *m.`, fieldname, ` {`)
+			p.In()
+			p.P(`dAtA[i] = 1`)
+			p.Out()
+			p.P(`} else {`)
+			p.In()
+			p.P(`dAtA[i] = 0`)
+			p.Out()
+			p.P(`}`)
+			p.encodeKey(fieldNumber, wireType)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_STRING:
+		if repeated {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.P(`i -= len(`, val, `)`)
+			p.P(`copy(dAtA[i:], `, val, `)`)
+			p.callVarint(`len(`, val, `)`)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if len(m.`, fieldname, `) > 0 {`)
+			p.In()
+			p.P(`i -= len(m.`, fieldname, `)`)
+			p.P(`copy(dAtA[i:], m.`, fieldname, `)`)
+			p.callVarint(`len(m.`, fieldname, `)`)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if !nullable {
+			p.P(`i -= len(m.`, fieldname, `)`)
+			p.P(`copy(dAtA[i:], m.`, fieldname, `)`)
+			p.callVarint(`len(m.`, fieldname, `)`)
+			p.encodeKey(fieldNumber, wireType)
+		} else {
+			p.P(`i -= len(*m.`, fieldname, `)`)
+			p.P(`copy(dAtA[i:], *m.`, fieldname, `)`)
+			p.callVarint(`len(*m.`, fieldname, `)`)
+			p.encodeKey(fieldNumber, wireType)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_GROUP:
+		panic(fmt.Errorf("marshaler does not support group %v", fieldname))
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		if p.IsMap(field) {
+			m := p.GoMapType(nil, field)
+			keygoTyp, keywire := p.GoType(nil, m.KeyField)
+			keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField)
+			// keys may not be pointers
+			keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
+			keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
+			keyCapTyp := generator.CamelCase(keygoTyp)
+			valuegoTyp, valuewire := p.GoType(nil, m.ValueField)
+			valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField)
+			nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
+			var val string
+			if gogoproto.IsStableMarshaler(file.FileDescriptorProto, message.DescriptorProto) {
+				keysName := `keysFor` + fieldname
+				p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(m.`, fieldname, `))`)
+				p.P(`for k := range m.`, fieldname, ` {`)
+				p.In()
+				p.P(keysName, ` = append(`, keysName, `, `, keygoTyp, `(k))`)
+				p.Out()
+				p.P(`}`)
+				p.P(p.sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`)
+				val = p.reverseListRange(keysName)
+			} else {
+				p.P(`for k := range m.`, fieldname, ` {`)
+				val = "k"
+				p.In()
+			}
+			if gogoproto.IsStableMarshaler(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P(`v := m.`, fieldname, `[`, keygoAliasTyp, `(`, val, `)]`)
+			} else {
+				p.P(`v := m.`, fieldname, `[`, val, `]`)
+			}
+			p.P(`baseI := i`)
+			accessor := `v`
+
+			if m.ValueField.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE {
+				if valuegoTyp != valuegoAliasTyp && !gogoproto.IsStdType(m.ValueAliasField) {
+					if nullable {
+						// cast back to the type that has the generated methods on it
+						accessor = `((` + valuegoTyp + `)(` + accessor + `))`
+					} else {
+						accessor = `((*` + valuegoTyp + `)(&` + accessor + `))`
+					}
+				} else if !nullable {
+					accessor = `(&v)`
+				}
+			}
+
+			nullableMsg := nullable && (m.ValueField.GetType() == descriptor.FieldDescriptorProto_TYPE_MESSAGE ||
+				gogoproto.IsCustomType(field) && m.ValueField.IsBytes())
+			plainBytes := m.ValueField.IsBytes() && !gogoproto.IsCustomType(field)
+			if nullableMsg {
+				p.P(`if `, accessor, ` != nil { `)
+				p.In()
+			} else if plainBytes {
+				if proto3 {
+					p.P(`if len(`, accessor, `) > 0 {`)
+				} else {
+					p.P(`if `, accessor, ` != nil {`)
+				}
+				p.In()
+			}
+			p.mapField(numGen, field, m.ValueAliasField, accessor, protoSizer)
+			p.encodeKey(2, wireToType(valuewire))
+			if nullableMsg || plainBytes {
+				p.Out()
+				p.P(`}`)
+			}
+
+			p.mapField(numGen, field, m.KeyField, val, protoSizer)
+			p.encodeKey(1, wireToType(keywire))
+
+			p.callVarint(`baseI - i`)
+
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if repeated {
+			val := p.reverseListRange(`m.`, fieldname)
+			sizeOfVarName := val
+			if gogoproto.IsNullable(field) {
+				sizeOfVarName = `*` + val
+			}
+			if !p.marshalAllSizeOf(field, sizeOfVarName, ``) {
+				if gogoproto.IsCustomType(field) {
+					p.forward(val, true, protoSizer)
+				} else {
+					p.backward(val, true)
+				}
+			}
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else {
+			sizeOfVarName := `m.` + fieldname
+			if gogoproto.IsNullable(field) {
+				sizeOfVarName = `*` + sizeOfVarName
+			}
+			if !p.marshalAllSizeOf(field, sizeOfVarName, numGen.Next()) {
+				if gogoproto.IsCustomType(field) {
+					p.forward(`m.`+fieldname, true, protoSizer)
+				} else {
+					p.backward(`m.`+fieldname, true)
+				}
+			}
+			p.encodeKey(fieldNumber, wireType)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_BYTES:
+		if !gogoproto.IsCustomType(field) {
+			if repeated {
+				val := p.reverseListRange(`m.`, fieldname)
+				p.P(`i -= len(`, val, `)`)
+				p.P(`copy(dAtA[i:], `, val, `)`)
+				p.callVarint(`len(`, val, `)`)
+				p.encodeKey(fieldNumber, wireType)
+				p.Out()
+				p.P(`}`)
+			} else if proto3 {
+				p.P(`if len(m.`, fieldname, `) > 0 {`)
+				p.In()
+				p.P(`i -= len(m.`, fieldname, `)`)
+				p.P(`copy(dAtA[i:], m.`, fieldname, `)`)
+				p.callVarint(`len(m.`, fieldname, `)`)
+				p.encodeKey(fieldNumber, wireType)
+				p.Out()
+				p.P(`}`)
+			} else {
+				p.P(`i -= len(m.`, fieldname, `)`)
+				p.P(`copy(dAtA[i:], m.`, fieldname, `)`)
+				p.callVarint(`len(m.`, fieldname, `)`)
+				p.encodeKey(fieldNumber, wireType)
+			}
+		} else {
+			if repeated {
+				val := p.reverseListRange(`m.`, fieldname)
+				p.forward(val, true, protoSizer)
+				p.encodeKey(fieldNumber, wireType)
+				p.Out()
+				p.P(`}`)
+			} else {
+				p.forward(`m.`+fieldname, true, protoSizer)
+				p.encodeKey(fieldNumber, wireType)
+			}
+		}
+	case descriptor.FieldDescriptorProto_TYPE_SINT32:
+		if packed {
+			datavar := "dAtA" + numGen.Next()
+			jvar := "j" + numGen.Next()
+			p.P(datavar, ` := make([]byte, len(m.`, fieldname, ")*5)")
+			p.P(`var `, jvar, ` int`)
+			p.P(`for _, num := range m.`, fieldname, ` {`)
+			p.In()
+			xvar := "x" + numGen.Next()
+			p.P(xvar, ` := (uint32(num) << 1) ^ uint32((num >> 31))`)
+			p.P(`for `, xvar, ` >= 1<<7 {`)
+			p.In()
+			p.P(datavar, `[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`)
+			p.P(jvar, `++`)
+			p.P(xvar, ` >>= 7`)
+			p.Out()
+			p.P(`}`)
+			p.P(datavar, `[`, jvar, `] = uint8(`, xvar, `)`)
+			p.P(jvar, `++`)
+			p.Out()
+			p.P(`}`)
+			p.P(`i -= `, jvar)
+			p.P(`copy(dAtA[i:], `, datavar, `[:`, jvar, `])`)
+			p.callVarint(jvar)
+			p.encodeKey(fieldNumber, wireType)
+		} else if repeated {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.P(`x`, numGen.Next(), ` := (uint32(`, val, `) << 1) ^ uint32((`, val, ` >> 31))`)
+			p.callVarint(`x`, numGen.Current())
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.callVarint(`(uint32(m.`, fieldname, `) << 1) ^ uint32((m.`, fieldname, ` >> 31))`)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if !nullable {
+			p.callVarint(`(uint32(m.`, fieldname, `) << 1) ^ uint32((m.`, fieldname, ` >> 31))`)
+			p.encodeKey(fieldNumber, wireType)
+		} else {
+			p.callVarint(`(uint32(*m.`, fieldname, `) << 1) ^ uint32((*m.`, fieldname, ` >> 31))`)
+			p.encodeKey(fieldNumber, wireType)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_SINT64:
+		if packed {
+			jvar := "j" + numGen.Next()
+			xvar := "x" + numGen.Next()
+			datavar := "dAtA" + numGen.Next()
+			p.P(`var `, jvar, ` int`)
+			p.P(datavar, ` := make([]byte, len(m.`, fieldname, `)*10)`)
+			p.P(`for _, num := range m.`, fieldname, ` {`)
+			p.In()
+			p.P(xvar, ` := (uint64(num) << 1) ^ uint64((num >> 63))`)
+			p.P(`for `, xvar, ` >= 1<<7 {`)
+			p.In()
+			p.P(datavar, `[`, jvar, `] = uint8(uint64(`, xvar, `)&0x7f|0x80)`)
+			p.P(jvar, `++`)
+			p.P(xvar, ` >>= 7`)
+			p.Out()
+			p.P(`}`)
+			p.P(datavar, `[`, jvar, `] = uint8(`, xvar, `)`)
+			p.P(jvar, `++`)
+			p.Out()
+			p.P(`}`)
+			p.P(`i -= `, jvar)
+			p.P(`copy(dAtA[i:], `, datavar, `[:`, jvar, `])`)
+			p.callVarint(jvar)
+			p.encodeKey(fieldNumber, wireType)
+		} else if repeated {
+			val := p.reverseListRange(`m.`, fieldname)
+			p.P(`x`, numGen.Next(), ` := (uint64(`, val, `) << 1) ^ uint64((`, val, ` >> 63))`)
+			p.callVarint("x" + numGen.Current())
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.callVarint(`(uint64(m.`, fieldname, `) << 1) ^ uint64((m.`, fieldname, ` >> 63))`)
+			p.encodeKey(fieldNumber, wireType)
+			p.Out()
+			p.P(`}`)
+		} else if !nullable {
+			p.callVarint(`(uint64(m.`, fieldname, `) << 1) ^ uint64((m.`, fieldname, ` >> 63))`)
+			p.encodeKey(fieldNumber, wireType)
+		} else {
+			p.callVarint(`(uint64(*m.`, fieldname, `) << 1) ^ uint64((*m.`, fieldname, ` >> 63))`)
+			p.encodeKey(fieldNumber, wireType)
+		}
+	default:
+		panic("not implemented")
+	}
+	if (required && nullable) || repeated || doNilCheck {
+		p.Out()
+		p.P(`}`)
+	}
+}
+
+func (p *marshalto) Generate(file *generator.FileDescriptor) {
+	numGen := NewNumGen()
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+
+	p.atleastOne = false
+	p.localName = generator.FileName(file)
+
+	p.mathPkg = p.NewImport("math")
+	p.sortKeysPkg = p.NewImport("github.com/gogo/protobuf/sortkeys")
+	p.protoPkg = p.NewImport("github.com/gogo/protobuf/proto")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		p.protoPkg = p.NewImport("github.com/golang/protobuf/proto")
+	}
+	p.errorsPkg = p.NewImport("errors")
+	p.binaryPkg = p.NewImport("encoding/binary")
+	p.typesPkg = p.NewImport("github.com/gogo/protobuf/types")
+
+	for _, message := range file.Messages() {
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		if !gogoproto.IsMarshaler(file.FileDescriptorProto, message.DescriptorProto) &&
+			!gogoproto.IsUnsafeMarshaler(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		p.atleastOne = true
+
+		p.P(`func (m *`, ccTypeName, `) Marshal() (dAtA []byte, err error) {`)
+		p.In()
+		if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
+			p.P(`size := m.ProtoSize()`)
+		} else {
+			p.P(`size := m.Size()`)
+		}
+		p.P(`dAtA = make([]byte, size)`)
+		p.P(`n, err := m.MarshalToSizedBuffer(dAtA[:size])`)
+		p.P(`if err != nil {`)
+		p.In()
+		p.P(`return nil, err`)
+		p.Out()
+		p.P(`}`)
+		p.P(`return dAtA[:n], nil`)
+		p.Out()
+		p.P(`}`)
+		p.P(``)
+		p.P(`func (m *`, ccTypeName, `) MarshalTo(dAtA []byte) (int, error) {`)
+		p.In()
+		if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
+			p.P(`size := m.ProtoSize()`)
+		} else {
+			p.P(`size := m.Size()`)
+		}
+		p.P(`return m.MarshalToSizedBuffer(dAtA[:size])`)
+		p.Out()
+		p.P(`}`)
+		p.P(``)
+		p.P(`func (m *`, ccTypeName, `) MarshalToSizedBuffer(dAtA []byte) (int, error) {`)
+		p.In()
+		p.P(`i := len(dAtA)`)
+		p.P(`_ = i`)
+		p.P(`var l int`)
+		p.P(`_ = l`)
+		if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
+			p.P(`if m.XXX_unrecognized != nil {`)
+			p.In()
+			p.P(`i -= len(m.XXX_unrecognized)`)
+			p.P(`copy(dAtA[i:], m.XXX_unrecognized)`)
+			p.Out()
+			p.P(`}`)
+		}
+		if message.DescriptorProto.HasExtension() {
+			if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P(`if n, err := `, p.protoPkg.Use(), `.EncodeInternalExtensionBackwards(m, dAtA[:i]); err != nil {`)
+				p.In()
+				p.P(`return 0, err`)
+				p.Out()
+				p.P(`} else {`)
+				p.In()
+				p.P(`i -= n`)
+				p.Out()
+				p.P(`}`)
+			} else {
+				p.P(`if m.XXX_extensions != nil {`)
+				p.In()
+				p.P(`i -= len(m.XXX_extensions)`)
+				p.P(`copy(dAtA[i:], m.XXX_extensions)`)
+				p.Out()
+				p.P(`}`)
+			}
+		}
+		fields := orderFields(message.GetField())
+		sort.Sort(fields)
+		oneofs := make(map[string]struct{})
+		for i := len(message.Field) - 1; i >= 0; i-- {
+			field := message.Field[i]
+			oneof := field.OneofIndex != nil
+			if !oneof {
+				proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
+				p.generateField(proto3, numGen, file, message, field)
+			} else {
+				fieldname := p.GetFieldName(message, field)
+				if _, ok := oneofs[fieldname]; !ok {
+					oneofs[fieldname] = struct{}{}
+					p.P(`if m.`, fieldname, ` != nil {`)
+					p.In()
+					p.forward(`m.`+fieldname, false, gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto))
+					p.Out()
+					p.P(`}`)
+				}
+			}
+		}
+		p.P(`return len(dAtA) - i, nil`)
+		p.Out()
+		p.P(`}`)
+		p.P()
+
+		//Generate MarshalTo methods for oneof fields
+		m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
+		for _, field := range m.Field {
+			oneof := field.OneofIndex != nil
+			if !oneof {
+				continue
+			}
+			ccTypeName := p.OneOfTypeName(message, field)
+			p.P(`func (m *`, ccTypeName, `) MarshalTo(dAtA []byte) (int, error) {`)
+			p.In()
+			if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P(`size := m.ProtoSize()`)
+			} else {
+				p.P(`size := m.Size()`)
+			}
+			p.P(`return m.MarshalToSizedBuffer(dAtA[:size])`)
+			p.Out()
+			p.P(`}`)
+			p.P(``)
+			p.P(`func (m *`, ccTypeName, `) MarshalToSizedBuffer(dAtA []byte) (int, error) {`)
+			p.In()
+			p.P(`i := len(dAtA)`)
+			vanity.TurnOffNullableForNativeTypes(field)
+			p.generateField(false, numGen, file, message, field)
+			p.P(`return len(dAtA) - i, nil`)
+			p.Out()
+			p.P(`}`)
+		}
+	}
+
+	if p.atleastOne {
+		p.P(`func encodeVarint`, p.localName, `(dAtA []byte, offset int, v uint64) int {`)
+		p.In()
+		p.P(`offset -= sov`, p.localName, `(v)`)
+		p.P(`base := offset`)
+		p.P(`for v >= 1<<7 {`)
+		p.In()
+		p.P(`dAtA[offset] = uint8(v&0x7f|0x80)`)
+		p.P(`v >>= 7`)
+		p.P(`offset++`)
+		p.Out()
+		p.P(`}`)
+		p.P(`dAtA[offset] = uint8(v)`)
+		p.P(`return base`)
+		p.Out()
+		p.P(`}`)
+	}
+
+}
+
+func (p *marshalto) reverseListRange(expression ...string) string {
+	exp := strings.Join(expression, "")
+	p.P(`for iNdEx := len(`, exp, `) - 1; iNdEx >= 0; iNdEx-- {`)
+	p.In()
+	return exp + `[iNdEx]`
+}
+
+func (p *marshalto) marshalAllSizeOf(field *descriptor.FieldDescriptorProto, varName, num string) bool {
+	if gogoproto.IsStdTime(field) {
+		p.marshalSizeOf(`StdTimeMarshalTo`, `SizeOfStdTime`, varName, num)
+	} else if gogoproto.IsStdDuration(field) {
+		p.marshalSizeOf(`StdDurationMarshalTo`, `SizeOfStdDuration`, varName, num)
+	} else if gogoproto.IsStdDouble(field) {
+		p.marshalSizeOf(`StdDoubleMarshalTo`, `SizeOfStdDouble`, varName, num)
+	} else if gogoproto.IsStdFloat(field) {
+		p.marshalSizeOf(`StdFloatMarshalTo`, `SizeOfStdFloat`, varName, num)
+	} else if gogoproto.IsStdInt64(field) {
+		p.marshalSizeOf(`StdInt64MarshalTo`, `SizeOfStdInt64`, varName, num)
+	} else if gogoproto.IsStdUInt64(field) {
+		p.marshalSizeOf(`StdUInt64MarshalTo`, `SizeOfStdUInt64`, varName, num)
+	} else if gogoproto.IsStdInt32(field) {
+		p.marshalSizeOf(`StdInt32MarshalTo`, `SizeOfStdInt32`, varName, num)
+	} else if gogoproto.IsStdUInt32(field) {
+		p.marshalSizeOf(`StdUInt32MarshalTo`, `SizeOfStdUInt32`, varName, num)
+	} else if gogoproto.IsStdBool(field) {
+		p.marshalSizeOf(`StdBoolMarshalTo`, `SizeOfStdBool`, varName, num)
+	} else if gogoproto.IsStdString(field) {
+		p.marshalSizeOf(`StdStringMarshalTo`, `SizeOfStdString`, varName, num)
+	} else if gogoproto.IsStdBytes(field) {
+		p.marshalSizeOf(`StdBytesMarshalTo`, `SizeOfStdBytes`, varName, num)
+	} else {
+		return false
+	}
+	return true
+}
+
+func (p *marshalto) marshalSizeOf(marshal, size, varName, num string) {
+	p.P(`n`, num, `, err`, num, ` := `, p.typesPkg.Use(), `.`, marshal, `(`, varName, `, dAtA[i-`, p.typesPkg.Use(), `.`, size, `(`, varName, `):])`)
+	p.P(`if err`, num, ` != nil {`)
+	p.In()
+	p.P(`return 0, err`, num)
+	p.Out()
+	p.P(`}`)
+	p.P(`i -= n`, num)
+	p.callVarint(`n`, num)
+}
+
+func (p *marshalto) backward(varName string, varInt bool) {
+	p.P(`{`)
+	p.In()
+	p.P(`size, err := `, varName, `.MarshalToSizedBuffer(dAtA[:i])`)
+	p.P(`if err != nil {`)
+	p.In()
+	p.P(`return 0, err`)
+	p.Out()
+	p.P(`}`)
+	p.P(`i -= size`)
+	if varInt {
+		p.callVarint(`size`)
+	}
+	p.Out()
+	p.P(`}`)
+}
+
+func (p *marshalto) forward(varName string, varInt, protoSizer bool) {
+	p.P(`{`)
+	p.In()
+	if protoSizer {
+		p.P(`size := `, varName, `.ProtoSize()`)
+	} else {
+		p.P(`size := `, varName, `.Size()`)
+	}
+	p.P(`i -= size`)
+	p.P(`if _, err := `, varName, `.MarshalTo(dAtA[i:]); err != nil {`)
+	p.In()
+	p.P(`return 0, err`)
+	p.Out()
+	p.P(`}`)
+	p.Out()
+	if varInt {
+		p.callVarint(`size`)
+	}
+	p.P(`}`)
+}
+
+func init() {
+	generator.RegisterPlugin(NewMarshal())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/oneofcheck/oneofcheck.go b/vendor/github.com/gogo/protobuf/plugin/oneofcheck/oneofcheck.go
new file mode 100644
index 0000000000000..0f822e8a8acdc
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/oneofcheck/oneofcheck.go
@@ -0,0 +1,93 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The oneofcheck plugin is used to check whether oneof is not used incorrectly.
+For instance:
+An error is caused if a oneof field:
+  - is used in a face
+  - is an embedded field
+
+*/
+package oneofcheck
+
+import (
+	"fmt"
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+	"os"
+)
+
+type plugin struct {
+	*generator.Generator
+}
+
+func NewPlugin() *plugin {
+	return &plugin{}
+}
+
+func (p *plugin) Name() string {
+	return "oneofcheck"
+}
+
+func (p *plugin) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *plugin) Generate(file *generator.FileDescriptor) {
+	for _, msg := range file.Messages() {
+		face := gogoproto.IsFace(file.FileDescriptorProto, msg.DescriptorProto)
+		for _, field := range msg.GetField() {
+			if field.OneofIndex == nil {
+				continue
+			}
+			if face {
+				fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in a face and oneof\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
+				os.Exit(1)
+			}
+			if gogoproto.IsEmbed(field) {
+				fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in an oneof and an embedded field\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
+				os.Exit(1)
+			}
+			if !gogoproto.IsNullable(field) {
+				fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in an oneof and a non-nullable field\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
+				os.Exit(1)
+			}
+			if gogoproto.IsUnion(file.FileDescriptorProto, msg.DescriptorProto) {
+				fmt.Fprintf(os.Stderr, "ERROR: field %v.%v cannot be in an oneof and in an union (deprecated)\n", generator.CamelCase(*msg.Name), generator.CamelCase(*field.Name))
+				os.Exit(1)
+			}
+		}
+	}
+}
+
+func (p *plugin) GenerateImports(*generator.FileDescriptor) {}
+
+func init() {
+	generator.RegisterPlugin(NewPlugin())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/populate/populate.go b/vendor/github.com/gogo/protobuf/plugin/populate/populate.go
new file mode 100644
index 0000000000000..da705945c330d
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/populate/populate.go
@@ -0,0 +1,815 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The populate plugin generates a NewPopulated function.
+This function returns a newly populated structure.
+
+It is enabled by the following extensions:
+
+  - populate
+  - populate_all
+
+Let us look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+  option (gogoproto.populate_all) = true;
+
+  message B {
+	optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
+	repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false];
+  }
+
+given to the populate plugin, will generate code the following code:
+
+  func NewPopulatedB(r randyExample, easy bool) *B {
+	this := &B{}
+	v2 := NewPopulatedA(r, easy)
+	this.A = *v2
+	if r.Intn(10) != 0 {
+		v3 := r.Intn(10)
+		this.G = make([]github_com_gogo_protobuf_test_custom.Uint128, v3)
+		for i := 0; i < v3; i++ {
+			v4 := github_com_gogo_protobuf_test_custom.NewPopulatedUint128(r)
+			this.G[i] = *v4
+		}
+	}
+	if !easy && r.Intn(10) != 0 {
+		this.XXX_unrecognized = randUnrecognizedExample(r, 3)
+	}
+	return this
+  }
+
+The idea that is useful for testing.
+Most of the other plugins' generated test code uses it.
+You will still be able to use the generated test code of other packages
+if you turn off the popluate plugin and write your own custom NewPopulated function.
+
+If the easy flag is not set the XXX_unrecognized and XXX_extensions fields are also populated.
+These have caused problems with JSON marshalling and unmarshalling tests.
+
+*/
+package populate
+
+import (
+	"fmt"
+	"math"
+	"strconv"
+	"strings"
+
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+	"github.com/gogo/protobuf/vanity"
+)
+
+type VarGen interface {
+	Next() string
+	Current() string
+}
+
+type varGen struct {
+	index int64
+}
+
+func NewVarGen() VarGen {
+	return &varGen{0}
+}
+
+func (this *varGen) Next() string {
+	this.index++
+	return fmt.Sprintf("v%d", this.index)
+}
+
+func (this *varGen) Current() string {
+	return fmt.Sprintf("v%d", this.index)
+}
+
+type plugin struct {
+	*generator.Generator
+	generator.PluginImports
+	varGen     VarGen
+	atleastOne bool
+	localName  string
+	typesPkg   generator.Single
+}
+
+func NewPlugin() *plugin {
+	return &plugin{}
+}
+
+func (p *plugin) Name() string {
+	return "populate"
+}
+
+func (p *plugin) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func value(typeName string, fieldType descriptor.FieldDescriptorProto_Type) string {
+	switch fieldType {
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+		return typeName + "(r.Float64())"
+	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+		return typeName + "(r.Float32())"
+	case descriptor.FieldDescriptorProto_TYPE_INT64,
+		descriptor.FieldDescriptorProto_TYPE_SFIXED64,
+		descriptor.FieldDescriptorProto_TYPE_SINT64:
+		return typeName + "(r.Int63())"
+	case descriptor.FieldDescriptorProto_TYPE_UINT64,
+		descriptor.FieldDescriptorProto_TYPE_FIXED64:
+		return typeName + "(uint64(r.Uint32()))"
+	case descriptor.FieldDescriptorProto_TYPE_INT32,
+		descriptor.FieldDescriptorProto_TYPE_SINT32,
+		descriptor.FieldDescriptorProto_TYPE_SFIXED32,
+		descriptor.FieldDescriptorProto_TYPE_ENUM:
+		return typeName + "(r.Int31())"
+	case descriptor.FieldDescriptorProto_TYPE_UINT32,
+		descriptor.FieldDescriptorProto_TYPE_FIXED32:
+		return typeName + "(r.Uint32())"
+	case descriptor.FieldDescriptorProto_TYPE_BOOL:
+		return typeName + `(bool(r.Intn(2) == 0))`
+	case descriptor.FieldDescriptorProto_TYPE_STRING,
+		descriptor.FieldDescriptorProto_TYPE_GROUP,
+		descriptor.FieldDescriptorProto_TYPE_MESSAGE,
+		descriptor.FieldDescriptorProto_TYPE_BYTES:
+	}
+	panic(fmt.Errorf("unexpected type %v", typeName))
+}
+
+func negative(fieldType descriptor.FieldDescriptorProto_Type) bool {
+	switch fieldType {
+	case descriptor.FieldDescriptorProto_TYPE_UINT64,
+		descriptor.FieldDescriptorProto_TYPE_FIXED64,
+		descriptor.FieldDescriptorProto_TYPE_UINT32,
+		descriptor.FieldDescriptorProto_TYPE_FIXED32,
+		descriptor.FieldDescriptorProto_TYPE_BOOL:
+		return false
+	}
+	return true
+}
+
+func (p *plugin) getFuncName(goTypName string, field *descriptor.FieldDescriptorProto) string {
+	funcName := "NewPopulated" + goTypName
+	goTypNames := strings.Split(goTypName, ".")
+	if len(goTypNames) == 2 {
+		funcName = goTypNames[0] + ".NewPopulated" + goTypNames[1]
+	} else if len(goTypNames) != 1 {
+		panic(fmt.Errorf("unreachable: too many dots in %v", goTypName))
+	}
+	if field != nil {
+		switch {
+		case gogoproto.IsStdTime(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdTime"
+		case gogoproto.IsStdDuration(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdDuration"
+		case gogoproto.IsStdDouble(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdDouble"
+		case gogoproto.IsStdFloat(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdFloat"
+		case gogoproto.IsStdInt64(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdInt64"
+		case gogoproto.IsStdUInt64(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdUInt64"
+		case gogoproto.IsStdInt32(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdInt32"
+		case gogoproto.IsStdUInt32(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdUInt32"
+		case gogoproto.IsStdBool(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdBool"
+		case gogoproto.IsStdString(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdString"
+		case gogoproto.IsStdBytes(field):
+			funcName = p.typesPkg.Use() + ".NewPopulatedStdBytes"
+		}
+	}
+	return funcName
+}
+
+func (p *plugin) getFuncCall(goTypName string, field *descriptor.FieldDescriptorProto) string {
+	funcName := p.getFuncName(goTypName, field)
+	funcCall := funcName + "(r, easy)"
+	return funcCall
+}
+
+func (p *plugin) getCustomFuncCall(goTypName string) string {
+	funcName := p.getFuncName(goTypName, nil)
+	funcCall := funcName + "(r)"
+	return funcCall
+}
+
+func (p *plugin) getEnumVal(field *descriptor.FieldDescriptorProto, goTyp string) string {
+	enum := p.ObjectNamed(field.GetTypeName()).(*generator.EnumDescriptor)
+	l := len(enum.Value)
+	values := make([]string, l)
+	for i := range enum.Value {
+		values[i] = strconv.Itoa(int(*enum.Value[i].Number))
+	}
+	arr := "[]int32{" + strings.Join(values, ",") + "}"
+	val := strings.Join([]string{generator.GoTypeToName(goTyp), `(`, arr, `[r.Intn(`, fmt.Sprintf("%d", l), `)])`}, "")
+	return val
+}
+
+func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) {
+	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
+	goTyp, _ := p.GoType(message, field)
+	fieldname := p.GetOneOfFieldName(message, field)
+	goTypName := generator.GoTypeToName(goTyp)
+	if p.IsMap(field) {
+		m := p.GoMapType(nil, field)
+		keygoTyp, _ := p.GoType(nil, m.KeyField)
+		keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
+		keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField)
+		keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
+
+		valuegoTyp, _ := p.GoType(nil, m.ValueField)
+		valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField)
+		keytypName := generator.GoTypeToName(keygoTyp)
+		keygoAliasTyp = generator.GoTypeToName(keygoAliasTyp)
+		valuetypAliasName := generator.GoTypeToName(valuegoAliasTyp)
+
+		nullable, valuegoTyp, valuegoAliasTyp := generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
+
+		p.P(p.varGen.Next(), ` := r.Intn(10)`)
+		p.P(`this.`, fieldname, ` = make(`, m.GoType, `)`)
+		p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
+		p.In()
+		keyval := ""
+		if m.KeyField.IsString() {
+			keyval = fmt.Sprintf("randString%v(r)", p.localName)
+		} else {
+			keyval = value(keytypName, m.KeyField.GetType())
+		}
+		if keygoAliasTyp != keygoTyp {
+			keyval = keygoAliasTyp + `(` + keyval + `)`
+		}
+		if m.ValueField.IsMessage() || p.IsGroup(field) ||
+			(m.ValueField.IsBytes() && gogoproto.IsCustomType(field)) {
+			s := `this.` + fieldname + `[` + keyval + `] = `
+			if gogoproto.IsStdType(field) {
+				valuegoTyp = valuegoAliasTyp
+			}
+			funcCall := p.getCustomFuncCall(goTypName)
+			if !gogoproto.IsCustomType(field) {
+				goTypName = generator.GoTypeToName(valuegoTyp)
+				funcCall = p.getFuncCall(goTypName, m.ValueAliasField)
+			}
+			if !nullable {
+				funcCall = `*` + funcCall
+			}
+			if valuegoTyp != valuegoAliasTyp {
+				funcCall = `(` + valuegoAliasTyp + `)(` + funcCall + `)`
+			}
+			s += funcCall
+			p.P(s)
+		} else if m.ValueField.IsEnum() {
+			s := `this.` + fieldname + `[` + keyval + `]` + ` = ` + p.getEnumVal(m.ValueField, valuegoTyp)
+			p.P(s)
+		} else if m.ValueField.IsBytes() {
+			count := p.varGen.Next()
+			p.P(count, ` := r.Intn(100)`)
+			p.P(p.varGen.Next(), ` := `, keyval)
+			p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] = make(`, valuegoTyp, `, `, count, `)`)
+			p.P(`for i := 0; i < `, count, `; i++ {`)
+			p.In()
+			p.P(`this.`, fieldname, `[`, p.varGen.Current(), `][i] = byte(r.Intn(256))`)
+			p.Out()
+			p.P(`}`)
+		} else if m.ValueField.IsString() {
+			s := `this.` + fieldname + `[` + keyval + `]` + ` = ` + fmt.Sprintf("randString%v(r)", p.localName)
+			p.P(s)
+		} else {
+			p.P(p.varGen.Next(), ` := `, keyval)
+			p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] = `, value(valuetypAliasName, m.ValueField.GetType()))
+			if negative(m.ValueField.GetType()) {
+				p.P(`if r.Intn(2) == 0 {`)
+				p.In()
+				p.P(`this.`, fieldname, `[`, p.varGen.Current(), `] *= -1`)
+				p.Out()
+				p.P(`}`)
+			}
+		}
+		p.Out()
+		p.P(`}`)
+	} else if gogoproto.IsCustomType(field) {
+		funcCall := p.getCustomFuncCall(goTypName)
+		if field.IsRepeated() {
+			p.P(p.varGen.Next(), ` := r.Intn(10)`)
+			p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
+			p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
+			p.In()
+			p.P(p.varGen.Next(), `:= `, funcCall)
+			p.P(`this.`, fieldname, `[i] = *`, p.varGen.Current())
+			p.Out()
+			p.P(`}`)
+		} else if gogoproto.IsNullable(field) {
+			p.P(`this.`, fieldname, ` = `, funcCall)
+		} else {
+			p.P(p.varGen.Next(), `:= `, funcCall)
+			p.P(`this.`, fieldname, ` = *`, p.varGen.Current())
+		}
+	} else if field.IsMessage() || p.IsGroup(field) {
+		funcCall := p.getFuncCall(goTypName, field)
+		if field.IsRepeated() {
+			p.P(p.varGen.Next(), ` := r.Intn(5)`)
+			p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
+			p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
+			p.In()
+			if gogoproto.IsNullable(field) {
+				p.P(`this.`, fieldname, `[i] = `, funcCall)
+			} else {
+				p.P(p.varGen.Next(), `:= `, funcCall)
+				p.P(`this.`, fieldname, `[i] = *`, p.varGen.Current())
+			}
+			p.Out()
+			p.P(`}`)
+		} else {
+			if gogoproto.IsNullable(field) {
+				p.P(`this.`, fieldname, ` = `, funcCall)
+			} else {
+				p.P(p.varGen.Next(), `:= `, funcCall)
+				p.P(`this.`, fieldname, ` = *`, p.varGen.Current())
+			}
+		}
+	} else {
+		if field.IsEnum() {
+			val := p.getEnumVal(field, goTyp)
+			if field.IsRepeated() {
+				p.P(p.varGen.Next(), ` := r.Intn(10)`)
+				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
+				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
+				p.In()
+				p.P(`this.`, fieldname, `[i] = `, val)
+				p.Out()
+				p.P(`}`)
+			} else if !gogoproto.IsNullable(field) || proto3 {
+				p.P(`this.`, fieldname, ` = `, val)
+			} else {
+				p.P(p.varGen.Next(), ` := `, val)
+				p.P(`this.`, fieldname, ` = &`, p.varGen.Current())
+			}
+		} else if field.IsBytes() {
+			if field.IsRepeated() {
+				p.P(p.varGen.Next(), ` := r.Intn(10)`)
+				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
+				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
+				p.In()
+				p.P(p.varGen.Next(), ` := r.Intn(100)`)
+				p.P(`this.`, fieldname, `[i] = make([]byte,`, p.varGen.Current(), `)`)
+				p.P(`for j := 0; j < `, p.varGen.Current(), `; j++ {`)
+				p.In()
+				p.P(`this.`, fieldname, `[i][j] = byte(r.Intn(256))`)
+				p.Out()
+				p.P(`}`)
+				p.Out()
+				p.P(`}`)
+			} else {
+				p.P(p.varGen.Next(), ` := r.Intn(100)`)
+				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
+				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
+				p.In()
+				p.P(`this.`, fieldname, `[i] = byte(r.Intn(256))`)
+				p.Out()
+				p.P(`}`)
+			}
+		} else if field.IsString() {
+			typName := generator.GoTypeToName(goTyp)
+			val := fmt.Sprintf("%s(randString%v(r))", typName, p.localName)
+			if field.IsRepeated() {
+				p.P(p.varGen.Next(), ` := r.Intn(10)`)
+				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
+				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
+				p.In()
+				p.P(`this.`, fieldname, `[i] = `, val)
+				p.Out()
+				p.P(`}`)
+			} else if !gogoproto.IsNullable(field) || proto3 {
+				p.P(`this.`, fieldname, ` = `, val)
+			} else {
+				p.P(p.varGen.Next(), `:= `, val)
+				p.P(`this.`, fieldname, ` = &`, p.varGen.Current())
+			}
+		} else {
+			typName := generator.GoTypeToName(goTyp)
+			if field.IsRepeated() {
+				p.P(p.varGen.Next(), ` := r.Intn(10)`)
+				p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
+				p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
+				p.In()
+				p.P(`this.`, fieldname, `[i] = `, value(typName, field.GetType()))
+				if negative(field.GetType()) {
+					p.P(`if r.Intn(2) == 0 {`)
+					p.In()
+					p.P(`this.`, fieldname, `[i] *= -1`)
+					p.Out()
+					p.P(`}`)
+				}
+				p.Out()
+				p.P(`}`)
+			} else if !gogoproto.IsNullable(field) || proto3 {
+				p.P(`this.`, fieldname, ` = `, value(typName, field.GetType()))
+				if negative(field.GetType()) {
+					p.P(`if r.Intn(2) == 0 {`)
+					p.In()
+					p.P(`this.`, fieldname, ` *= -1`)
+					p.Out()
+					p.P(`}`)
+				}
+			} else {
+				p.P(p.varGen.Next(), ` := `, value(typName, field.GetType()))
+				if negative(field.GetType()) {
+					p.P(`if r.Intn(2) == 0 {`)
+					p.In()
+					p.P(p.varGen.Current(), ` *= -1`)
+					p.Out()
+					p.P(`}`)
+				}
+				p.P(`this.`, fieldname, ` = &`, p.varGen.Current())
+			}
+		}
+	}
+}
+
+func (p *plugin) hasLoop(pkg string, field *descriptor.FieldDescriptorProto, visited []*generator.Descriptor, excludes []*generator.Descriptor) *generator.Descriptor {
+	if field.IsMessage() || p.IsGroup(field) || p.IsMap(field) {
+		var fieldMessage *generator.Descriptor
+		if p.IsMap(field) {
+			m := p.GoMapType(nil, field)
+			if !m.ValueField.IsMessage() {
+				return nil
+			}
+			fieldMessage = p.ObjectNamed(m.ValueField.GetTypeName()).(*generator.Descriptor)
+		} else {
+			fieldMessage = p.ObjectNamed(field.GetTypeName()).(*generator.Descriptor)
+		}
+		fieldTypeName := generator.CamelCaseSlice(fieldMessage.TypeName())
+		for _, message := range visited {
+			messageTypeName := generator.CamelCaseSlice(message.TypeName())
+			if fieldTypeName == messageTypeName {
+				for _, e := range excludes {
+					if fieldTypeName == generator.CamelCaseSlice(e.TypeName()) {
+						return nil
+					}
+				}
+				return fieldMessage
+			}
+		}
+
+		for _, f := range fieldMessage.Field {
+			if strings.HasPrefix(f.GetTypeName(), "."+pkg) {
+				visited = append(visited, fieldMessage)
+				loopTo := p.hasLoop(pkg, f, visited, excludes)
+				if loopTo != nil {
+					return loopTo
+				}
+			}
+		}
+	}
+	return nil
+}
+
+func (p *plugin) loops(pkg string, field *descriptor.FieldDescriptorProto, message *generator.Descriptor) int {
+	//fmt.Fprintf(os.Stderr, "loops %v %v\n", field.GetTypeName(), generator.CamelCaseSlice(message.TypeName()))
+	excludes := []*generator.Descriptor{}
+	loops := 0
+	for {
+		visited := []*generator.Descriptor{}
+		loopTo := p.hasLoop(pkg, field, visited, excludes)
+		if loopTo == nil {
+			break
+		}
+		//fmt.Fprintf(os.Stderr, "loopTo %v\n", generator.CamelCaseSlice(loopTo.TypeName()))
+		excludes = append(excludes, loopTo)
+		loops++
+	}
+	return loops
+}
+
+func (p *plugin) Generate(file *generator.FileDescriptor) {
+	p.atleastOne = false
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	p.varGen = NewVarGen()
+	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
+	p.typesPkg = p.NewImport("github.com/gogo/protobuf/types")
+	p.localName = generator.FileName(file)
+	protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		protoPkg = p.NewImport("github.com/golang/protobuf/proto")
+	}
+
+	for _, message := range file.Messages() {
+		if !gogoproto.HasPopulate(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		p.atleastOne = true
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		loopLevels := make([]int, len(message.Field))
+		maxLoopLevel := 0
+		for i, field := range message.Field {
+			loopLevels[i] = p.loops(file.GetPackage(), field, message)
+			if loopLevels[i] > maxLoopLevel {
+				maxLoopLevel = loopLevels[i]
+			}
+		}
+		ranTotal := 0
+		for i := range loopLevels {
+			ranTotal += int(math.Pow10(maxLoopLevel - loopLevels[i]))
+		}
+		p.P(`func NewPopulated`, ccTypeName, `(r randy`, p.localName, `, easy bool) *`, ccTypeName, ` {`)
+		p.In()
+		p.P(`this := &`, ccTypeName, `{}`)
+		if gogoproto.IsUnion(message.File().FileDescriptorProto, message.DescriptorProto) && len(message.Field) > 0 {
+			p.P(`fieldNum := r.Intn(`, fmt.Sprintf("%d", ranTotal), `)`)
+			p.P(`switch fieldNum {`)
+			k := 0
+			for i, field := range message.Field {
+				is := []string{}
+				ran := int(math.Pow10(maxLoopLevel - loopLevels[i]))
+				for j := 0; j < ran; j++ {
+					is = append(is, fmt.Sprintf("%d", j+k))
+				}
+				k += ran
+				p.P(`case `, strings.Join(is, ","), `:`)
+				p.In()
+				p.GenerateField(file, message, field)
+				p.Out()
+			}
+			p.P(`}`)
+		} else {
+			var maxFieldNumber int32
+			oneofs := make(map[string]struct{})
+			for fieldIndex, field := range message.Field {
+				if field.GetNumber() > maxFieldNumber {
+					maxFieldNumber = field.GetNumber()
+				}
+				oneof := field.OneofIndex != nil
+				if !oneof {
+					if field.IsRequired() || (!gogoproto.IsNullable(field) && !field.IsRepeated()) || (proto3 && !field.IsMessage()) {
+						p.GenerateField(file, message, field)
+					} else {
+						if loopLevels[fieldIndex] > 0 {
+							p.P(`if r.Intn(5) == 0 {`)
+						} else {
+							p.P(`if r.Intn(5) != 0 {`)
+						}
+						p.In()
+						p.GenerateField(file, message, field)
+						p.Out()
+						p.P(`}`)
+					}
+				} else {
+					fieldname := p.GetFieldName(message, field)
+					if _, ok := oneofs[fieldname]; ok {
+						continue
+					} else {
+						oneofs[fieldname] = struct{}{}
+					}
+					fieldNumbers := []int32{}
+					for _, f := range message.Field {
+						fname := p.GetFieldName(message, f)
+						if fname == fieldname {
+							fieldNumbers = append(fieldNumbers, f.GetNumber())
+						}
+					}
+
+					p.P(`oneofNumber_`, fieldname, ` := `, fmt.Sprintf("%#v", fieldNumbers), `[r.Intn(`, strconv.Itoa(len(fieldNumbers)), `)]`)
+					p.P(`switch oneofNumber_`, fieldname, ` {`)
+					for _, f := range message.Field {
+						fname := p.GetFieldName(message, f)
+						if fname != fieldname {
+							continue
+						}
+						p.P(`case `, strconv.Itoa(int(f.GetNumber())), `:`)
+						p.In()
+						ccTypeName := p.OneOfTypeName(message, f)
+						p.P(`this.`, fname, ` = NewPopulated`, ccTypeName, `(r, easy)`)
+						p.Out()
+					}
+					p.P(`}`)
+				}
+			}
+			if message.DescriptorProto.HasExtension() {
+				p.P(`if !easy && r.Intn(10) != 0 {`)
+				p.In()
+				p.P(`l := r.Intn(5)`)
+				p.P(`for i := 0; i < l; i++ {`)
+				p.In()
+				if len(message.DescriptorProto.GetExtensionRange()) > 1 {
+					p.P(`eIndex := r.Intn(`, strconv.Itoa(len(message.DescriptorProto.GetExtensionRange())), `)`)
+					p.P(`fieldNumber := 0`)
+					p.P(`switch eIndex {`)
+					for i, e := range message.DescriptorProto.GetExtensionRange() {
+						p.P(`case `, strconv.Itoa(i), `:`)
+						p.In()
+						p.P(`fieldNumber = r.Intn(`, strconv.Itoa(int(e.GetEnd()-e.GetStart())), `) + `, strconv.Itoa(int(e.GetStart())))
+						p.Out()
+						if e.GetEnd() > maxFieldNumber {
+							maxFieldNumber = e.GetEnd()
+						}
+					}
+					p.P(`}`)
+				} else {
+					e := message.DescriptorProto.GetExtensionRange()[0]
+					p.P(`fieldNumber := r.Intn(`, strconv.Itoa(int(e.GetEnd()-e.GetStart())), `) + `, strconv.Itoa(int(e.GetStart())))
+					if e.GetEnd() > maxFieldNumber {
+						maxFieldNumber = e.GetEnd()
+					}
+				}
+				p.P(`wire := r.Intn(4)`)
+				p.P(`if wire == 3 { wire = 5 }`)
+				p.P(`dAtA := randField`, p.localName, `(nil, r, fieldNumber, wire)`)
+				p.P(protoPkg.Use(), `.SetRawExtension(this, int32(fieldNumber), dAtA)`)
+				p.Out()
+				p.P(`}`)
+				p.Out()
+				p.P(`}`)
+			}
+
+			if maxFieldNumber < (1 << 10) {
+				p.P(`if !easy && r.Intn(10) != 0 {`)
+				p.In()
+				if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
+					p.P(`this.XXX_unrecognized = randUnrecognized`, p.localName, `(r, `, strconv.Itoa(int(maxFieldNumber+1)), `)`)
+				}
+				p.Out()
+				p.P(`}`)
+			}
+		}
+		p.P(`return this`)
+		p.Out()
+		p.P(`}`)
+		p.P(``)
+
+		//Generate NewPopulated functions for oneof fields
+		m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
+		for _, f := range m.Field {
+			oneof := f.OneofIndex != nil
+			if !oneof {
+				continue
+			}
+			ccTypeName := p.OneOfTypeName(message, f)
+			p.P(`func NewPopulated`, ccTypeName, `(r randy`, p.localName, `, easy bool) *`, ccTypeName, ` {`)
+			p.In()
+			p.P(`this := &`, ccTypeName, `{}`)
+			vanity.TurnOffNullableForNativeTypes(f)
+			p.GenerateField(file, message, f)
+			p.P(`return this`)
+			p.Out()
+			p.P(`}`)
+		}
+	}
+
+	if !p.atleastOne {
+		return
+	}
+
+	p.P(`type randy`, p.localName, ` interface {`)
+	p.In()
+	p.P(`Float32() float32`)
+	p.P(`Float64() float64`)
+	p.P(`Int63() int64`)
+	p.P(`Int31() int32`)
+	p.P(`Uint32() uint32`)
+	p.P(`Intn(n int) int`)
+	p.Out()
+	p.P(`}`)
+
+	p.P(`func randUTF8Rune`, p.localName, `(r randy`, p.localName, `) rune {`)
+	p.In()
+	p.P(`ru := r.Intn(62)`)
+	p.P(`if ru < 10 {`)
+	p.In()
+	p.P(`return rune(ru+48)`)
+	p.Out()
+	p.P(`} else if ru < 36 {`)
+	p.In()
+	p.P(`return rune(ru+55)`)
+	p.Out()
+	p.P(`}`)
+	p.P(`return rune(ru+61)`)
+	p.Out()
+	p.P(`}`)
+
+	p.P(`func randString`, p.localName, `(r randy`, p.localName, `) string {`)
+	p.In()
+	p.P(p.varGen.Next(), ` := r.Intn(100)`)
+	p.P(`tmps := make([]rune, `, p.varGen.Current(), `)`)
+	p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
+	p.In()
+	p.P(`tmps[i] = randUTF8Rune`, p.localName, `(r)`)
+	p.Out()
+	p.P(`}`)
+	p.P(`return string(tmps)`)
+	p.Out()
+	p.P(`}`)
+
+	p.P(`func randUnrecognized`, p.localName, `(r randy`, p.localName, `, maxFieldNumber int) (dAtA []byte) {`)
+	p.In()
+	p.P(`l := r.Intn(5)`)
+	p.P(`for i := 0; i < l; i++ {`)
+	p.In()
+	p.P(`wire := r.Intn(4)`)
+	p.P(`if wire == 3 { wire = 5 }`)
+	p.P(`fieldNumber := maxFieldNumber + r.Intn(100)`)
+	p.P(`dAtA = randField`, p.localName, `(dAtA, r, fieldNumber, wire)`)
+	p.Out()
+	p.P(`}`)
+	p.P(`return dAtA`)
+	p.Out()
+	p.P(`}`)
+
+	p.P(`func randField`, p.localName, `(dAtA []byte, r randy`, p.localName, `, fieldNumber int, wire int) []byte {`)
+	p.In()
+	p.P(`key := uint32(fieldNumber)<<3 | uint32(wire)`)
+	p.P(`switch wire {`)
+	p.P(`case 0:`)
+	p.In()
+	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
+	p.P(p.varGen.Next(), ` := r.Int63()`)
+	p.P(`if r.Intn(2) == 0 {`)
+	p.In()
+	p.P(p.varGen.Current(), ` *= -1`)
+	p.Out()
+	p.P(`}`)
+	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(`, p.varGen.Current(), `))`)
+	p.Out()
+	p.P(`case 1:`)
+	p.In()
+	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
+	p.P(`dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))`)
+	p.Out()
+	p.P(`case 2:`)
+	p.In()
+	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
+	p.P(`ll := r.Intn(100)`)
+	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(ll))`)
+	p.P(`for j := 0; j < ll; j++ {`)
+	p.In()
+	p.P(`dAtA = append(dAtA, byte(r.Intn(256)))`)
+	p.Out()
+	p.P(`}`)
+	p.Out()
+	p.P(`default:`)
+	p.In()
+	p.P(`dAtA = encodeVarintPopulate`, p.localName, `(dAtA, uint64(key))`)
+	p.P(`dAtA = append(dAtA, byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)), byte(r.Intn(256)))`)
+	p.Out()
+	p.P(`}`)
+	p.P(`return dAtA`)
+	p.Out()
+	p.P(`}`)
+
+	p.P(`func encodeVarintPopulate`, p.localName, `(dAtA []byte, v uint64) []byte {`)
+	p.In()
+	p.P(`for v >= 1<<7 {`)
+	p.In()
+	p.P(`dAtA = append(dAtA, uint8(uint64(v)&0x7f|0x80))`)
+	p.P(`v >>= 7`)
+	p.Out()
+	p.P(`}`)
+	p.P(`dAtA = append(dAtA, uint8(v))`)
+	p.P(`return dAtA`)
+	p.Out()
+	p.P(`}`)
+
+}
+
+func init() {
+	generator.RegisterPlugin(NewPlugin())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/size/size.go b/vendor/github.com/gogo/protobuf/plugin/size/size.go
new file mode 100644
index 0000000000000..1650b438751da
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/size/size.go
@@ -0,0 +1,696 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The size plugin generates a Size or ProtoSize method for each message.
+This is useful with the MarshalTo method generated by the marshalto plugin and the
+gogoproto.marshaler and gogoproto.marshaler_all extensions.
+
+It is enabled by the following extensions:
+
+  - sizer
+  - sizer_all
+  - protosizer
+  - protosizer_all
+
+The size plugin also generates a test given it is enabled using one of the following extensions:
+
+  - testgen
+  - testgen_all
+
+And a benchmark given it is enabled using one of the following extensions:
+
+  - benchgen
+  - benchgen_all
+
+Let us look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+  option (gogoproto.sizer_all) = true;
+
+  message B {
+	option (gogoproto.description) = true;
+	optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
+	repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false];
+  }
+
+given to the size plugin, will generate the following code:
+
+  func (m *B) Size() (n int) {
+	if m == nil {
+		return 0
+	}
+	var l int
+	_ = l
+	l = m.A.Size()
+	n += 1 + l + sovExample(uint64(l))
+	if len(m.G) > 0 {
+		for _, e := range m.G {
+			l = e.Size()
+			n += 1 + l + sovExample(uint64(l))
+		}
+	}
+	if m.XXX_unrecognized != nil {
+		n += len(m.XXX_unrecognized)
+	}
+	return n
+  }
+
+and the following test code:
+
+	func TestBSize(t *testing5.T) {
+		popr := math_rand5.New(math_rand5.NewSource(time5.Now().UnixNano()))
+		p := NewPopulatedB(popr, true)
+		dAtA, err := github_com_gogo_protobuf_proto2.Marshal(p)
+		if err != nil {
+			panic(err)
+		}
+		size := p.Size()
+		if len(dAtA) != size {
+			t.Fatalf("size %v != marshalled size %v", size, len(dAtA))
+		}
+	}
+
+	func BenchmarkBSize(b *testing5.B) {
+		popr := math_rand5.New(math_rand5.NewSource(616))
+		total := 0
+		pops := make([]*B, 1000)
+		for i := 0; i < 1000; i++ {
+			pops[i] = NewPopulatedB(popr, false)
+		}
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			total += pops[i%1000].Size()
+		}
+		b.SetBytes(int64(total / b.N))
+	}
+
+The sovExample function is a size of varint function for the example.pb.go file.
+
+*/
+package size
+
+import (
+	"fmt"
+	"os"
+	"strconv"
+	"strings"
+
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+	"github.com/gogo/protobuf/vanity"
+)
+
+type size struct {
+	*generator.Generator
+	generator.PluginImports
+	atleastOne bool
+	localName  string
+	typesPkg   generator.Single
+	bitsPkg    generator.Single
+}
+
+func NewSize() *size {
+	return &size{}
+}
+
+func (p *size) Name() string {
+	return "size"
+}
+
+func (p *size) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func wireToType(wire string) int {
+	switch wire {
+	case "fixed64":
+		return proto.WireFixed64
+	case "fixed32":
+		return proto.WireFixed32
+	case "varint":
+		return proto.WireVarint
+	case "bytes":
+		return proto.WireBytes
+	case "group":
+		return proto.WireBytes
+	case "zigzag32":
+		return proto.WireVarint
+	case "zigzag64":
+		return proto.WireVarint
+	}
+	panic("unreachable")
+}
+
+func keySize(fieldNumber int32, wireType int) int {
+	x := uint32(fieldNumber)<<3 | uint32(wireType)
+	size := 0
+	for size = 0; x > 127; size++ {
+		x >>= 7
+	}
+	size++
+	return size
+}
+
+func (p *size) sizeVarint() {
+	p.P(`
+	func sov`, p.localName, `(x uint64) (n int) {
+                return (`, p.bitsPkg.Use(), `.Len64(x | 1) + 6)/ 7
+	}`)
+}
+
+func (p *size) sizeZigZag() {
+	p.P(`func soz`, p.localName, `(x uint64) (n int) {
+		return sov`, p.localName, `(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+	}`)
+}
+
+func (p *size) std(field *descriptor.FieldDescriptorProto, name string) (string, bool) {
+	ptr := ""
+	if gogoproto.IsNullable(field) {
+		ptr = "*"
+	}
+	if gogoproto.IsStdTime(field) {
+		return p.typesPkg.Use() + `.SizeOfStdTime(` + ptr + name + `)`, true
+	} else if gogoproto.IsStdDuration(field) {
+		return p.typesPkg.Use() + `.SizeOfStdDuration(` + ptr + name + `)`, true
+	} else if gogoproto.IsStdDouble(field) {
+		return p.typesPkg.Use() + `.SizeOfStdDouble(` + ptr + name + `)`, true
+	} else if gogoproto.IsStdFloat(field) {
+		return p.typesPkg.Use() + `.SizeOfStdFloat(` + ptr + name + `)`, true
+	} else if gogoproto.IsStdInt64(field) {
+		return p.typesPkg.Use() + `.SizeOfStdInt64(` + ptr + name + `)`, true
+	} else if gogoproto.IsStdUInt64(field) {
+		return p.typesPkg.Use() + `.SizeOfStdUInt64(` + ptr + name + `)`, true
+	} else if gogoproto.IsStdInt32(field) {
+		return p.typesPkg.Use() + `.SizeOfStdInt32(` + ptr + name + `)`, true
+	} else if gogoproto.IsStdUInt32(field) {
+		return p.typesPkg.Use() + `.SizeOfStdUInt32(` + ptr + name + `)`, true
+	} else if gogoproto.IsStdBool(field) {
+		return p.typesPkg.Use() + `.SizeOfStdBool(` + ptr + name + `)`, true
+	} else if gogoproto.IsStdString(field) {
+		return p.typesPkg.Use() + `.SizeOfStdString(` + ptr + name + `)`, true
+	} else if gogoproto.IsStdBytes(field) {
+		return p.typesPkg.Use() + `.SizeOfStdBytes(` + ptr + name + `)`, true
+	}
+	return "", false
+}
+
+func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto, sizeName string) {
+	fieldname := p.GetOneOfFieldName(message, field)
+	nullable := gogoproto.IsNullable(field)
+	repeated := field.IsRepeated()
+	doNilCheck := gogoproto.NeedsNilCheck(proto3, field)
+	if repeated {
+		p.P(`if len(m.`, fieldname, `) > 0 {`)
+		p.In()
+	} else if doNilCheck {
+		p.P(`if m.`, fieldname, ` != nil {`)
+		p.In()
+	}
+	packed := field.IsPacked() || (proto3 && field.IsPacked3())
+	_, wire := p.GoType(message, field)
+	wireType := wireToType(wire)
+	fieldNumber := field.GetNumber()
+	if packed {
+		wireType = proto.WireBytes
+	}
+	key := keySize(fieldNumber, wireType)
+	switch *field.Type {
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
+		descriptor.FieldDescriptorProto_TYPE_FIXED64,
+		descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+		if packed {
+			p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(len(m.`, fieldname, `)*8))`, `+len(m.`, fieldname, `)*8`)
+		} else if repeated {
+			p.P(`n+=`, strconv.Itoa(key+8), `*len(m.`, fieldname, `)`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.P(`n+=`, strconv.Itoa(key+8))
+			p.Out()
+			p.P(`}`)
+		} else if nullable {
+			p.P(`n+=`, strconv.Itoa(key+8))
+		} else {
+			p.P(`n+=`, strconv.Itoa(key+8))
+		}
+	case descriptor.FieldDescriptorProto_TYPE_FLOAT,
+		descriptor.FieldDescriptorProto_TYPE_FIXED32,
+		descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+		if packed {
+			p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(len(m.`, fieldname, `)*4))`, `+len(m.`, fieldname, `)*4`)
+		} else if repeated {
+			p.P(`n+=`, strconv.Itoa(key+4), `*len(m.`, fieldname, `)`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.P(`n+=`, strconv.Itoa(key+4))
+			p.Out()
+			p.P(`}`)
+		} else if nullable {
+			p.P(`n+=`, strconv.Itoa(key+4))
+		} else {
+			p.P(`n+=`, strconv.Itoa(key+4))
+		}
+	case descriptor.FieldDescriptorProto_TYPE_INT64,
+		descriptor.FieldDescriptorProto_TYPE_UINT64,
+		descriptor.FieldDescriptorProto_TYPE_UINT32,
+		descriptor.FieldDescriptorProto_TYPE_ENUM,
+		descriptor.FieldDescriptorProto_TYPE_INT32:
+		if packed {
+			p.P(`l = 0`)
+			p.P(`for _, e := range m.`, fieldname, ` {`)
+			p.In()
+			p.P(`l+=sov`, p.localName, `(uint64(e))`)
+			p.Out()
+			p.P(`}`)
+			p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(l))+l`)
+		} else if repeated {
+			p.P(`for _, e := range m.`, fieldname, ` {`)
+			p.In()
+			p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(e))`)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(m.`, fieldname, `))`)
+			p.Out()
+			p.P(`}`)
+		} else if nullable {
+			p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(*m.`, fieldname, `))`)
+		} else {
+			p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(m.`, fieldname, `))`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_BOOL:
+		if packed {
+			p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(len(m.`, fieldname, `)))`, `+len(m.`, fieldname, `)*1`)
+		} else if repeated {
+			p.P(`n+=`, strconv.Itoa(key+1), `*len(m.`, fieldname, `)`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` {`)
+			p.In()
+			p.P(`n+=`, strconv.Itoa(key+1))
+			p.Out()
+			p.P(`}`)
+		} else if nullable {
+			p.P(`n+=`, strconv.Itoa(key+1))
+		} else {
+			p.P(`n+=`, strconv.Itoa(key+1))
+		}
+	case descriptor.FieldDescriptorProto_TYPE_STRING:
+		if repeated {
+			p.P(`for _, s := range m.`, fieldname, ` { `)
+			p.In()
+			p.P(`l = len(s)`)
+			p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`l=len(m.`, fieldname, `)`)
+			p.P(`if l > 0 {`)
+			p.In()
+			p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+			p.Out()
+			p.P(`}`)
+		} else if nullable {
+			p.P(`l=len(*m.`, fieldname, `)`)
+			p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+		} else {
+			p.P(`l=len(m.`, fieldname, `)`)
+			p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_GROUP:
+		panic(fmt.Errorf("size does not support group %v", fieldname))
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		if p.IsMap(field) {
+			m := p.GoMapType(nil, field)
+			_, keywire := p.GoType(nil, m.KeyAliasField)
+			valuegoTyp, _ := p.GoType(nil, m.ValueField)
+			valuegoAliasTyp, valuewire := p.GoType(nil, m.ValueAliasField)
+			_, fieldwire := p.GoType(nil, field)
+
+			nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
+
+			fieldKeySize := keySize(field.GetNumber(), wireToType(fieldwire))
+			keyKeySize := keySize(1, wireToType(keywire))
+			valueKeySize := keySize(2, wireToType(valuewire))
+			p.P(`for k, v := range m.`, fieldname, ` { `)
+			p.In()
+			p.P(`_ = k`)
+			p.P(`_ = v`)
+			sum := []string{strconv.Itoa(keyKeySize)}
+			switch m.KeyField.GetType() {
+			case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
+				descriptor.FieldDescriptorProto_TYPE_FIXED64,
+				descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+				sum = append(sum, `8`)
+			case descriptor.FieldDescriptorProto_TYPE_FLOAT,
+				descriptor.FieldDescriptorProto_TYPE_FIXED32,
+				descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+				sum = append(sum, `4`)
+			case descriptor.FieldDescriptorProto_TYPE_INT64,
+				descriptor.FieldDescriptorProto_TYPE_UINT64,
+				descriptor.FieldDescriptorProto_TYPE_UINT32,
+				descriptor.FieldDescriptorProto_TYPE_ENUM,
+				descriptor.FieldDescriptorProto_TYPE_INT32:
+				sum = append(sum, `sov`+p.localName+`(uint64(k))`)
+			case descriptor.FieldDescriptorProto_TYPE_BOOL:
+				sum = append(sum, `1`)
+			case descriptor.FieldDescriptorProto_TYPE_STRING,
+				descriptor.FieldDescriptorProto_TYPE_BYTES:
+				sum = append(sum, `len(k)+sov`+p.localName+`(uint64(len(k)))`)
+			case descriptor.FieldDescriptorProto_TYPE_SINT32,
+				descriptor.FieldDescriptorProto_TYPE_SINT64:
+				sum = append(sum, `soz`+p.localName+`(uint64(k))`)
+			}
+			switch m.ValueField.GetType() {
+			case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
+				descriptor.FieldDescriptorProto_TYPE_FIXED64,
+				descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+				sum = append(sum, strconv.Itoa(valueKeySize))
+				sum = append(sum, strconv.Itoa(8))
+			case descriptor.FieldDescriptorProto_TYPE_FLOAT,
+				descriptor.FieldDescriptorProto_TYPE_FIXED32,
+				descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+				sum = append(sum, strconv.Itoa(valueKeySize))
+				sum = append(sum, strconv.Itoa(4))
+			case descriptor.FieldDescriptorProto_TYPE_INT64,
+				descriptor.FieldDescriptorProto_TYPE_UINT64,
+				descriptor.FieldDescriptorProto_TYPE_UINT32,
+				descriptor.FieldDescriptorProto_TYPE_ENUM,
+				descriptor.FieldDescriptorProto_TYPE_INT32:
+				sum = append(sum, strconv.Itoa(valueKeySize))
+				sum = append(sum, `sov`+p.localName+`(uint64(v))`)
+			case descriptor.FieldDescriptorProto_TYPE_BOOL:
+				sum = append(sum, strconv.Itoa(valueKeySize))
+				sum = append(sum, `1`)
+			case descriptor.FieldDescriptorProto_TYPE_STRING:
+				sum = append(sum, strconv.Itoa(valueKeySize))
+				sum = append(sum, `len(v)+sov`+p.localName+`(uint64(len(v)))`)
+			case descriptor.FieldDescriptorProto_TYPE_BYTES:
+				if gogoproto.IsCustomType(field) {
+					p.P(`l = 0`)
+					if nullable {
+						p.P(`if v != nil {`)
+						p.In()
+					}
+					p.P(`l = v.`, sizeName, `()`)
+					p.P(`l += `, strconv.Itoa(valueKeySize), ` + sov`+p.localName+`(uint64(l))`)
+					if nullable {
+						p.Out()
+						p.P(`}`)
+					}
+					sum = append(sum, `l`)
+				} else {
+					p.P(`l = 0`)
+					if proto3 {
+						p.P(`if len(v) > 0 {`)
+					} else {
+						p.P(`if v != nil {`)
+					}
+					p.In()
+					p.P(`l = `, strconv.Itoa(valueKeySize), ` + len(v)+sov`+p.localName+`(uint64(len(v)))`)
+					p.Out()
+					p.P(`}`)
+					sum = append(sum, `l`)
+				}
+			case descriptor.FieldDescriptorProto_TYPE_SINT32,
+				descriptor.FieldDescriptorProto_TYPE_SINT64:
+				sum = append(sum, strconv.Itoa(valueKeySize))
+				sum = append(sum, `soz`+p.localName+`(uint64(v))`)
+			case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+				stdSizeCall, stdOk := p.std(m.ValueAliasField, "v")
+				if nullable {
+					p.P(`l = 0`)
+					p.P(`if v != nil {`)
+					p.In()
+					if stdOk {
+						p.P(`l = `, stdSizeCall)
+					} else if valuegoTyp != valuegoAliasTyp {
+						p.P(`l = ((`, valuegoTyp, `)(v)).`, sizeName, `()`)
+					} else {
+						p.P(`l = v.`, sizeName, `()`)
+					}
+					p.P(`l += `, strconv.Itoa(valueKeySize), ` + sov`+p.localName+`(uint64(l))`)
+					p.Out()
+					p.P(`}`)
+					sum = append(sum, `l`)
+				} else {
+					if stdOk {
+						p.P(`l = `, stdSizeCall)
+					} else if valuegoTyp != valuegoAliasTyp {
+						p.P(`l = ((*`, valuegoTyp, `)(&v)).`, sizeName, `()`)
+					} else {
+						p.P(`l = v.`, sizeName, `()`)
+					}
+					sum = append(sum, strconv.Itoa(valueKeySize))
+					sum = append(sum, `l+sov`+p.localName+`(uint64(l))`)
+				}
+			}
+			p.P(`mapEntrySize := `, strings.Join(sum, "+"))
+			p.P(`n+=mapEntrySize+`, fieldKeySize, `+sov`, p.localName, `(uint64(mapEntrySize))`)
+			p.Out()
+			p.P(`}`)
+		} else if repeated {
+			p.P(`for _, e := range m.`, fieldname, ` { `)
+			p.In()
+			stdSizeCall, stdOk := p.std(field, "e")
+			if stdOk {
+				p.P(`l=`, stdSizeCall)
+			} else {
+				p.P(`l=e.`, sizeName, `()`)
+			}
+			p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+			p.Out()
+			p.P(`}`)
+		} else {
+			stdSizeCall, stdOk := p.std(field, "m."+fieldname)
+			if stdOk {
+				p.P(`l=`, stdSizeCall)
+			} else {
+				p.P(`l=m.`, fieldname, `.`, sizeName, `()`)
+			}
+			p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_BYTES:
+		if !gogoproto.IsCustomType(field) {
+			if repeated {
+				p.P(`for _, b := range m.`, fieldname, ` { `)
+				p.In()
+				p.P(`l = len(b)`)
+				p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+				p.Out()
+				p.P(`}`)
+			} else if proto3 {
+				p.P(`l=len(m.`, fieldname, `)`)
+				p.P(`if l > 0 {`)
+				p.In()
+				p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+				p.Out()
+				p.P(`}`)
+			} else {
+				p.P(`l=len(m.`, fieldname, `)`)
+				p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+			}
+		} else {
+			if repeated {
+				p.P(`for _, e := range m.`, fieldname, ` { `)
+				p.In()
+				p.P(`l=e.`, sizeName, `()`)
+				p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+				p.Out()
+				p.P(`}`)
+			} else {
+				p.P(`l=m.`, fieldname, `.`, sizeName, `()`)
+				p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
+			}
+		}
+	case descriptor.FieldDescriptorProto_TYPE_SINT32,
+		descriptor.FieldDescriptorProto_TYPE_SINT64:
+		if packed {
+			p.P(`l = 0`)
+			p.P(`for _, e := range m.`, fieldname, ` {`)
+			p.In()
+			p.P(`l+=soz`, p.localName, `(uint64(e))`)
+			p.Out()
+			p.P(`}`)
+			p.P(`n+=`, strconv.Itoa(key), `+sov`, p.localName, `(uint64(l))+l`)
+		} else if repeated {
+			p.P(`for _, e := range m.`, fieldname, ` {`)
+			p.In()
+			p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(e))`)
+			p.Out()
+			p.P(`}`)
+		} else if proto3 {
+			p.P(`if m.`, fieldname, ` != 0 {`)
+			p.In()
+			p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(m.`, fieldname, `))`)
+			p.Out()
+			p.P(`}`)
+		} else if nullable {
+			p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(*m.`, fieldname, `))`)
+		} else {
+			p.P(`n+=`, strconv.Itoa(key), `+soz`, p.localName, `(uint64(m.`, fieldname, `))`)
+		}
+	default:
+		panic("not implemented")
+	}
+	if repeated || doNilCheck {
+		p.Out()
+		p.P(`}`)
+	}
+}
+
+func (p *size) Generate(file *generator.FileDescriptor) {
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	p.atleastOne = false
+	p.localName = generator.FileName(file)
+	p.typesPkg = p.NewImport("github.com/gogo/protobuf/types")
+	protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
+	p.bitsPkg = p.NewImport("math/bits")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		protoPkg = p.NewImport("github.com/golang/protobuf/proto")
+	}
+	for _, message := range file.Messages() {
+		sizeName := ""
+		if gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) && gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
+			fmt.Fprintf(os.Stderr, "ERROR: message %v cannot support both sizer and protosizer plugins\n", generator.CamelCase(*message.Name))
+			os.Exit(1)
+		}
+		if gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) {
+			sizeName = "Size"
+		} else if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
+			sizeName = "ProtoSize"
+		} else {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		p.atleastOne = true
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		p.P(`func (m *`, ccTypeName, `) `, sizeName, `() (n int) {`)
+		p.In()
+		p.P(`if m == nil {`)
+		p.In()
+		p.P(`return 0`)
+		p.Out()
+		p.P(`}`)
+		p.P(`var l int`)
+		p.P(`_ = l`)
+		oneofs := make(map[string]struct{})
+		for _, field := range message.Field {
+			oneof := field.OneofIndex != nil
+			if !oneof {
+				proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
+				p.generateField(proto3, file, message, field, sizeName)
+			} else {
+				fieldname := p.GetFieldName(message, field)
+				if _, ok := oneofs[fieldname]; ok {
+					continue
+				} else {
+					oneofs[fieldname] = struct{}{}
+				}
+				p.P(`if m.`, fieldname, ` != nil {`)
+				p.In()
+				p.P(`n+=m.`, fieldname, `.`, sizeName, `()`)
+				p.Out()
+				p.P(`}`)
+			}
+		}
+		if message.DescriptorProto.HasExtension() {
+			if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P(`n += `, protoPkg.Use(), `.SizeOfInternalExtension(m)`)
+			} else {
+				p.P(`if m.XXX_extensions != nil {`)
+				p.In()
+				p.P(`n+=len(m.XXX_extensions)`)
+				p.Out()
+				p.P(`}`)
+			}
+		}
+		if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
+			p.P(`if m.XXX_unrecognized != nil {`)
+			p.In()
+			p.P(`n+=len(m.XXX_unrecognized)`)
+			p.Out()
+			p.P(`}`)
+		}
+		p.P(`return n`)
+		p.Out()
+		p.P(`}`)
+		p.P()
+
+		//Generate Size methods for oneof fields
+		m := proto.Clone(message.DescriptorProto).(*descriptor.DescriptorProto)
+		for _, f := range m.Field {
+			oneof := f.OneofIndex != nil
+			if !oneof {
+				continue
+			}
+			ccTypeName := p.OneOfTypeName(message, f)
+			p.P(`func (m *`, ccTypeName, `) `, sizeName, `() (n int) {`)
+			p.In()
+			p.P(`if m == nil {`)
+			p.In()
+			p.P(`return 0`)
+			p.Out()
+			p.P(`}`)
+			p.P(`var l int`)
+			p.P(`_ = l`)
+			vanity.TurnOffNullableForNativeTypes(f)
+			p.generateField(false, file, message, f, sizeName)
+			p.P(`return n`)
+			p.Out()
+			p.P(`}`)
+		}
+	}
+
+	if !p.atleastOne {
+		return
+	}
+
+	p.sizeVarint()
+	p.sizeZigZag()
+
+}
+
+func init() {
+	generator.RegisterPlugin(NewSize())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/stringer/stringer.go b/vendor/github.com/gogo/protobuf/plugin/stringer/stringer.go
new file mode 100644
index 0000000000000..df9792c7c4f4d
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/stringer/stringer.go
@@ -0,0 +1,347 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The stringer plugin generates a String method for each message.
+
+It is enabled by the following extensions:
+
+  - stringer
+  - stringer_all
+
+The stringer plugin also generates a test given it is enabled using one of the following extensions:
+
+  - testgen
+  - testgen_all
+
+Let us look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+  option (gogoproto.goproto_stringer_all) = false;
+  option (gogoproto.stringer_all) =  true;
+
+  message A {
+	optional string Description = 1 [(gogoproto.nullable) = false];
+	optional int64 Number = 2 [(gogoproto.nullable) = false];
+	optional bytes Id = 3 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uuid", (gogoproto.nullable) = false];
+  }
+
+given to the stringer stringer, will generate the following code:
+
+  func (this *A) String() string {
+	if this == nil {
+		return "nil"
+	}
+	s := strings.Join([]string{`&A{`,
+		`Description:` + fmt.Sprintf("%v", this.Description) + `,`,
+		`Number:` + fmt.Sprintf("%v", this.Number) + `,`,
+		`Id:` + fmt.Sprintf("%v", this.Id) + `,`,
+		`XXX_unrecognized:` + fmt.Sprintf("%v", this.XXX_unrecognized) + `,`,
+		`}`,
+	}, "")
+	return s
+  }
+
+and the following test code:
+
+	func TestAStringer(t *testing4.T) {
+		popr := math_rand4.New(math_rand4.NewSource(time4.Now().UnixNano()))
+		p := NewPopulatedA(popr, false)
+		s1 := p.String()
+		s2 := fmt1.Sprintf("%v", p)
+		if s1 != s2 {
+			t.Fatalf("String want %v got %v", s1, s2)
+		}
+	}
+
+Typically fmt.Printf("%v") will stop to print when it reaches a pointer and
+not print their values, while the generated String method will always print all values, recursively.
+
+*/
+package stringer
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+	"strings"
+)
+
+type stringer struct {
+	*generator.Generator
+	generator.PluginImports
+	atleastOne bool
+	localName  string
+}
+
+func NewStringer() *stringer {
+	return &stringer{}
+}
+
+func (p *stringer) Name() string {
+	return "stringer"
+}
+
+func (p *stringer) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *stringer) Generate(file *generator.FileDescriptor) {
+	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	p.atleastOne = false
+
+	p.localName = generator.FileName(file)
+
+	fmtPkg := p.NewImport("fmt")
+	stringsPkg := p.NewImport("strings")
+	reflectPkg := p.NewImport("reflect")
+	sortKeysPkg := p.NewImport("github.com/gogo/protobuf/sortkeys")
+	protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
+	for _, message := range file.Messages() {
+		if !gogoproto.IsStringer(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if gogoproto.EnabledGoStringer(file.FileDescriptorProto, message.DescriptorProto) {
+			panic("old string method needs to be disabled, please use gogoproto.goproto_stringer or gogoproto.goproto_stringer_all and set it to false")
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		p.atleastOne = true
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		p.P(`func (this *`, ccTypeName, `) String() string {`)
+		p.In()
+		p.P(`if this == nil {`)
+		p.In()
+		p.P(`return "nil"`)
+		p.Out()
+		p.P(`}`)
+		for _, field := range message.Field {
+			if p.IsMap(field) || !field.IsRepeated() {
+				continue
+			}
+			if (field.IsMessage() && !gogoproto.IsCustomType(field)) || p.IsGroup(field) {
+				nullable := gogoproto.IsNullable(field)
+				desc := p.ObjectNamed(field.GetTypeName())
+				msgname := p.TypeName(desc)
+				msgnames := strings.Split(msgname, ".")
+				typeName := msgnames[len(msgnames)-1]
+				fieldMessageDesc := file.GetMessage(msgname)
+				gogoStringer := false
+				if fieldMessageDesc != nil {
+					gogoStringer = gogoproto.IsStringer(file.FileDescriptorProto, fieldMessageDesc)
+				}
+				fieldname := p.GetFieldName(message, field)
+				stringfunc := fmtPkg.Use() + `.Sprintf("%v", f)`
+				if gogoStringer {
+					stringfunc = `f.String()`
+				}
+				repeatedName := `repeatedStringFor` + fieldname
+				if nullable {
+					p.P(repeatedName, ` := "[]*`, typeName, `{"`)
+				} else {
+					p.P(repeatedName, ` := "[]`, typeName, `{"`)
+				}
+
+				p.P(`for _, f := range `, `this.`, fieldname, ` {`)
+				p.In()
+				if nullable {
+					p.P(repeatedName, " += ", stringsPkg.Use(), `.Replace(`, stringfunc, `, "`, typeName, `","`, msgname, `"`, ", 1)", ` + ","`)
+				} else if gogoStringer {
+					p.P(repeatedName, " += ", stringsPkg.Use(), `.Replace(`, stringsPkg.Use(), `.Replace(`, stringfunc, `, "`, typeName, `","`, msgname, `"`, ", 1),`&`,``,1)", ` + ","`)
+				} else {
+					p.P(repeatedName, " += ", stringfunc, ` + ","`)
+				}
+				p.Out()
+				p.P(`}`)
+				p.P(repeatedName, ` += "}"`)
+			}
+		}
+		for _, field := range message.Field {
+			if !p.IsMap(field) {
+				continue
+			}
+			fieldname := p.GetFieldName(message, field)
+
+			m := p.GoMapType(nil, field)
+			mapgoTyp, keyField, keyAliasField := m.GoType, m.KeyField, m.KeyAliasField
+			keysName := `keysFor` + fieldname
+			keygoTyp, _ := p.GoType(nil, keyField)
+			keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
+			keygoAliasTyp, _ := p.GoType(nil, keyAliasField)
+			keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
+			keyCapTyp := generator.CamelCase(keygoTyp)
+			p.P(keysName, ` := make([]`, keygoTyp, `, 0, len(this.`, fieldname, `))`)
+			p.P(`for k, _ := range this.`, fieldname, ` {`)
+			p.In()
+			if keygoAliasTyp == keygoTyp {
+				p.P(keysName, ` = append(`, keysName, `, k)`)
+			} else {
+				p.P(keysName, ` = append(`, keysName, `, `, keygoTyp, `(k))`)
+			}
+			p.Out()
+			p.P(`}`)
+			p.P(sortKeysPkg.Use(), `.`, keyCapTyp, `s(`, keysName, `)`)
+			mapName := `mapStringFor` + fieldname
+			p.P(mapName, ` := "`, mapgoTyp, `{"`)
+			p.P(`for _, k := range `, keysName, ` {`)
+			p.In()
+			if keygoAliasTyp == keygoTyp {
+				p.P(mapName, ` += fmt.Sprintf("%v: %v,", k, this.`, fieldname, `[k])`)
+			} else {
+				p.P(mapName, ` += fmt.Sprintf("%v: %v,", k, this.`, fieldname, `[`, keygoAliasTyp, `(k)])`)
+			}
+			p.Out()
+			p.P(`}`)
+			p.P(mapName, ` += "}"`)
+		}
+		p.P("s := ", stringsPkg.Use(), ".Join([]string{`&", ccTypeName, "{`,")
+		oneofs := make(map[string]struct{})
+		for _, field := range message.Field {
+			nullable := gogoproto.IsNullable(field)
+			repeated := field.IsRepeated()
+			fieldname := p.GetFieldName(message, field)
+			oneof := field.OneofIndex != nil
+			if oneof {
+				if _, ok := oneofs[fieldname]; ok {
+					continue
+				} else {
+					oneofs[fieldname] = struct{}{}
+				}
+				p.P("`", fieldname, ":`", ` + `, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, ") + `,", "`,")
+			} else if p.IsMap(field) {
+				mapName := `mapStringFor` + fieldname
+				p.P("`", fieldname, ":`", ` + `, mapName, " + `,", "`,")
+			} else if (field.IsMessage() && !gogoproto.IsCustomType(field)) || p.IsGroup(field) {
+				desc := p.ObjectNamed(field.GetTypeName())
+				msgname := p.TypeName(desc)
+				msgnames := strings.Split(msgname, ".")
+				typeName := msgnames[len(msgnames)-1]
+				fieldMessageDesc := file.GetMessage(msgname)
+				gogoStringer := false
+				if fieldMessageDesc != nil {
+					gogoStringer = gogoproto.IsStringer(file.FileDescriptorProto, fieldMessageDesc)
+				}
+				stringfunc := fmtPkg.Use() + `.Sprintf("%v", this.` + fieldname + `)`
+				if gogoStringer {
+					stringfunc = `this.` + fieldname + `.String()`
+				}
+				if nullable && !repeated {
+					p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, stringfunc, `, "`, typeName, `","`, msgname, `"`, ", 1) + `,", "`,")
+				} else if repeated {
+					repeatedName := `repeatedStringFor` + fieldname
+					p.P("`", fieldname, ":`", ` + `, repeatedName, " + `,", "`,")
+				} else {
+					p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, stringsPkg.Use(), `.Replace(`, stringfunc, `, "`, typeName, `","`, msgname, `"`, ", 1),`&`,``,1) + `,", "`,")
+				}
+			} else {
+				if nullable && !repeated && !proto3 {
+					p.P("`", fieldname, ":`", ` + valueToString`, p.localName, `(this.`, fieldname, ") + `,", "`,")
+				} else {
+					p.P("`", fieldname, ":`", ` + `, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, ") + `,", "`,")
+				}
+			}
+		}
+		if message.DescriptorProto.HasExtension() {
+			if gogoproto.HasExtensionsMap(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P("`XXX_InternalExtensions:` + ", protoPkg.Use(), ".StringFromInternalExtension(this) + `,`,")
+			} else {
+				p.P("`XXX_extensions:` + ", protoPkg.Use(), ".StringFromExtensionsBytes(this.XXX_extensions) + `,`,")
+			}
+		}
+		if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
+			p.P("`XXX_unrecognized:` + ", fmtPkg.Use(), `.Sprintf("%v", this.XXX_unrecognized) + `, "`,`,")
+		}
+		p.P("`}`,")
+		p.P(`}`, `,""`, ")")
+		p.P(`return s`)
+		p.Out()
+		p.P(`}`)
+
+		//Generate String methods for oneof fields
+		for _, field := range message.Field {
+			oneof := field.OneofIndex != nil
+			if !oneof {
+				continue
+			}
+			ccTypeName := p.OneOfTypeName(message, field)
+			p.P(`func (this *`, ccTypeName, `) String() string {`)
+			p.In()
+			p.P(`if this == nil {`)
+			p.In()
+			p.P(`return "nil"`)
+			p.Out()
+			p.P(`}`)
+			p.P("s := ", stringsPkg.Use(), ".Join([]string{`&", ccTypeName, "{`,")
+			fieldname := p.GetOneOfFieldName(message, field)
+			if field.IsMessage() || p.IsGroup(field) {
+				desc := p.ObjectNamed(field.GetTypeName())
+				msgname := p.TypeName(desc)
+				msgnames := strings.Split(msgname, ".")
+				typeName := msgnames[len(msgnames)-1]
+				p.P("`", fieldname, ":`", ` + `, stringsPkg.Use(), `.Replace(`, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, `), "`, typeName, `","`, msgname, `"`, ", 1) + `,", "`,")
+			} else {
+				p.P("`", fieldname, ":`", ` + `, fmtPkg.Use(), `.Sprintf("%v", this.`, fieldname, ") + `,", "`,")
+			}
+			p.P("`}`,")
+			p.P(`}`, `,""`, ")")
+			p.P(`return s`)
+			p.Out()
+			p.P(`}`)
+		}
+	}
+
+	if !p.atleastOne {
+		return
+	}
+
+	p.P(`func valueToString`, p.localName, `(v interface{}) string {`)
+	p.In()
+	p.P(`rv := `, reflectPkg.Use(), `.ValueOf(v)`)
+	p.P(`if rv.IsNil() {`)
+	p.In()
+	p.P(`return "nil"`)
+	p.Out()
+	p.P(`}`)
+	p.P(`pv := `, reflectPkg.Use(), `.Indirect(rv).Interface()`)
+	p.P(`return `, fmtPkg.Use(), `.Sprintf("*%v", pv)`)
+	p.Out()
+	p.P(`}`)
+
+}
+
+func init() {
+	generator.RegisterPlugin(NewStringer())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/union/union.go b/vendor/github.com/gogo/protobuf/plugin/union/union.go
new file mode 100644
index 0000000000000..90def721c9dc7
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/union/union.go
@@ -0,0 +1,209 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The onlyone plugin generates code for the onlyone extension.
+All fields must be nullable and only one of the fields may be set, like a union.
+Two methods are generated
+
+  GetValue() interface{}
+
+and
+
+  SetValue(v interface{}) (set bool)
+
+These provide easier interaction with a onlyone.
+
+The onlyone extension is not called union as this causes compile errors in the C++ generated code.
+There can only be one ;)
+
+It is enabled by the following extensions:
+
+  - onlyone
+  - onlyone_all
+
+The onlyone plugin also generates a test given it is enabled using one of the following extensions:
+
+  - testgen
+  - testgen_all
+
+Lets look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+  message U {
+	  option (gogoproto.onlyone) = true;
+	  optional A A = 1;
+	  optional B B = 2;
+  }
+
+given to the onlyone plugin, will generate code which looks a lot like this:
+
+	func (this *U) GetValue() interface{} {
+		if this.A != nil {
+			return this.A
+		}
+		if this.B != nil {
+			return this.B
+		}
+		return nil
+	}
+
+	func (this *U) SetValue(value interface{}) bool {
+		switch vt := value.(type) {
+		case *A:
+			this.A = vt
+		case *B:
+			this.B = vt
+		default:
+			return false
+		}
+		return true
+	}
+
+and the following test code:
+
+  func TestUUnion(t *testing.T) {
+	popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano()))
+	p := NewPopulatedU(popr)
+	v := p.GetValue()
+	msg := &U{}
+	if !msg.SetValue(v) {
+		t.Fatalf("Union: Could not set Value")
+	}
+	if !p.Equal(msg) {
+		t.Fatalf("%#v !Union Equal %#v", msg, p)
+	}
+  }
+
+*/
+package union
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type union struct {
+	*generator.Generator
+	generator.PluginImports
+}
+
+func NewUnion() *union {
+	return &union{}
+}
+
+func (p *union) Name() string {
+	return "union"
+}
+
+func (p *union) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *union) Generate(file *generator.FileDescriptor) {
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+
+	for _, message := range file.Messages() {
+		if !gogoproto.IsUnion(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.HasExtension() {
+			panic("onlyone does not currently support extensions")
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		p.P(`func (this *`, ccTypeName, `) GetValue() interface{} {`)
+		p.In()
+		for _, field := range message.Field {
+			fieldname := p.GetFieldName(message, field)
+			if fieldname == "Value" {
+				panic("cannot have a onlyone message " + ccTypeName + " with a field named Value")
+			}
+			p.P(`if this.`, fieldname, ` != nil {`)
+			p.In()
+			p.P(`return this.`, fieldname)
+			p.Out()
+			p.P(`}`)
+		}
+		p.P(`return nil`)
+		p.Out()
+		p.P(`}`)
+		p.P(``)
+		p.P(`func (this *`, ccTypeName, `) SetValue(value interface{}) bool {`)
+		p.In()
+		p.P(`switch vt := value.(type) {`)
+		p.In()
+		for _, field := range message.Field {
+			fieldname := p.GetFieldName(message, field)
+			goTyp, _ := p.GoType(message, field)
+			p.P(`case `, goTyp, `:`)
+			p.In()
+			p.P(`this.`, fieldname, ` = vt`)
+			p.Out()
+		}
+		p.P(`default:`)
+		p.In()
+		for _, field := range message.Field {
+			fieldname := p.GetFieldName(message, field)
+			if field.IsMessage() {
+				goTyp, _ := p.GoType(message, field)
+				obj := p.ObjectNamed(field.GetTypeName()).(*generator.Descriptor)
+
+				if gogoproto.IsUnion(obj.File().FileDescriptorProto, obj.DescriptorProto) {
+					p.P(`this.`, fieldname, ` = new(`, generator.GoTypeToName(goTyp), `)`)
+					p.P(`if set := this.`, fieldname, `.SetValue(value); set {`)
+					p.In()
+					p.P(`return true`)
+					p.Out()
+					p.P(`}`)
+					p.P(`this.`, fieldname, ` = nil`)
+				}
+			}
+		}
+		p.P(`return false`)
+		p.Out()
+		p.P(`}`)
+		p.P(`return true`)
+		p.Out()
+		p.P(`}`)
+	}
+}
+
+func init() {
+	generator.RegisterPlugin(NewUnion())
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go b/vendor/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go
new file mode 100644
index 0000000000000..fae67de4fd9b3
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/unmarshal/unmarshal.go
@@ -0,0 +1,1657 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The unmarshal plugin generates a Unmarshal method for each message.
+The `Unmarshal([]byte) error` method results in the fact that the message
+implements the Unmarshaler interface.
+The allows proto.Unmarshal to be faster by calling the generated Unmarshal method rather than using reflect.
+
+If is enabled by the following extensions:
+
+  - unmarshaler
+  - unmarshaler_all
+
+Or the following extensions:
+
+  - unsafe_unmarshaler
+  - unsafe_unmarshaler_all
+
+That is if you want to use the unsafe package in your generated code.
+The speed up using the unsafe package is not very significant.
+
+The generation of unmarshalling tests are enabled using one of the following extensions:
+
+  - testgen
+  - testgen_all
+
+And benchmarks given it is enabled using one of the following extensions:
+
+  - benchgen
+  - benchgen_all
+
+Let us look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+  option (gogoproto.unmarshaler_all) = true;
+
+  message B {
+	option (gogoproto.description) = true;
+	optional A A = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true];
+	repeated bytes G = 2 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uint128", (gogoproto.nullable) = false];
+  }
+
+given to the unmarshal plugin, will generate the following code:
+
+  func (m *B) Unmarshal(dAtA []byte) error {
+	l := len(dAtA)
+	iNdEx := 0
+	for iNdEx < l {
+		var wire uint64
+		for shift := uint(0); ; shift += 7 {
+			if iNdEx >= l {
+				return io.ErrUnexpectedEOF
+			}
+			b := dAtA[iNdEx]
+			iNdEx++
+			wire |= (uint64(b) & 0x7F) << shift
+			if b < 0x80 {
+				break
+			}
+		}
+		fieldNum := int32(wire >> 3)
+		wireType := int(wire & 0x7)
+		switch fieldNum {
+		case 1:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var msglen int
+			for shift := uint(0); ; shift += 7 {
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				msglen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := iNdEx + msglen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			if err := m.A.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		case 2:
+			if wireType != 2 {
+				return proto.ErrWrongType
+			}
+			var byteLen int
+			for shift := uint(0); ; shift += 7 {
+				if iNdEx >= l {
+					return io.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				byteLen |= (int(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			postIndex := iNdEx + byteLen
+			if postIndex > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.G = append(m.G, github_com_gogo_protobuf_test_custom.Uint128{})
+			if err := m.G[len(m.G)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {
+				return err
+			}
+			iNdEx = postIndex
+		default:
+			var sizeOfWire int
+			for {
+				sizeOfWire++
+				wire >>= 7
+				if wire == 0 {
+					break
+				}
+			}
+			iNdEx -= sizeOfWire
+			skippy, err := skip(dAtA[iNdEx:])
+			if err != nil {
+				return err
+			}
+			if (iNdEx + skippy) > l {
+				return io.ErrUnexpectedEOF
+			}
+			m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)
+			iNdEx += skippy
+		}
+	}
+	return nil
+  }
+
+Remember when using this code to call proto.Unmarshal.
+This will call m.Reset and invoke the generated Unmarshal method for you.
+If you call m.Unmarshal without m.Reset you could be merging protocol buffers.
+
+*/
+package unmarshal
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type unmarshal struct {
+	*generator.Generator
+	generator.PluginImports
+	atleastOne bool
+	ioPkg      generator.Single
+	mathPkg    generator.Single
+	typesPkg   generator.Single
+	binaryPkg  generator.Single
+	localName  string
+}
+
+func NewUnmarshal() *unmarshal {
+	return &unmarshal{}
+}
+
+func (p *unmarshal) Name() string {
+	return "unmarshal"
+}
+
+func (p *unmarshal) Init(g *generator.Generator) {
+	p.Generator = g
+}
+
+func (p *unmarshal) decodeVarint(varName string, typName string) {
+	p.P(`for shift := uint(0); ; shift += 7 {`)
+	p.In()
+	p.P(`if shift >= 64 {`)
+	p.In()
+	p.P(`return ErrIntOverflow` + p.localName)
+	p.Out()
+	p.P(`}`)
+	p.P(`if iNdEx >= l {`)
+	p.In()
+	p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+	p.Out()
+	p.P(`}`)
+	p.P(`b := dAtA[iNdEx]`)
+	p.P(`iNdEx++`)
+	p.P(varName, ` |= `, typName, `(b&0x7F) << shift`)
+	p.P(`if b < 0x80 {`)
+	p.In()
+	p.P(`break`)
+	p.Out()
+	p.P(`}`)
+	p.Out()
+	p.P(`}`)
+}
+
+func (p *unmarshal) decodeFixed32(varName string, typeName string) {
+	p.P(`if (iNdEx+4) > l {`)
+	p.In()
+	p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+	p.Out()
+	p.P(`}`)
+	p.P(varName, ` = `, typeName, `(`, p.binaryPkg.Use(), `.LittleEndian.Uint32(dAtA[iNdEx:]))`)
+	p.P(`iNdEx += 4`)
+}
+
+func (p *unmarshal) decodeFixed64(varName string, typeName string) {
+	p.P(`if (iNdEx+8) > l {`)
+	p.In()
+	p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+	p.Out()
+	p.P(`}`)
+	p.P(varName, ` = `, typeName, `(`, p.binaryPkg.Use(), `.LittleEndian.Uint64(dAtA[iNdEx:]))`)
+	p.P(`iNdEx += 8`)
+}
+
+func (p *unmarshal) declareMapField(varName string, nullable bool, customType bool, field *descriptor.FieldDescriptorProto) {
+	switch field.GetType() {
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+		p.P(`var `, varName, ` float64`)
+	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+		p.P(`var `, varName, ` float32`)
+	case descriptor.FieldDescriptorProto_TYPE_INT64:
+		p.P(`var `, varName, ` int64`)
+	case descriptor.FieldDescriptorProto_TYPE_UINT64:
+		p.P(`var `, varName, ` uint64`)
+	case descriptor.FieldDescriptorProto_TYPE_INT32:
+		p.P(`var `, varName, ` int32`)
+	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
+		p.P(`var `, varName, ` uint64`)
+	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
+		p.P(`var `, varName, ` uint32`)
+	case descriptor.FieldDescriptorProto_TYPE_BOOL:
+		p.P(`var `, varName, ` bool`)
+	case descriptor.FieldDescriptorProto_TYPE_STRING:
+		cast, _ := p.GoType(nil, field)
+		cast = strings.Replace(cast, "*", "", 1)
+		p.P(`var `, varName, ` `, cast)
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		if gogoproto.IsStdTime(field) {
+			p.P(varName, ` := new(time.Time)`)
+		} else if gogoproto.IsStdDuration(field) {
+			p.P(varName, ` := new(time.Duration)`)
+		} else if gogoproto.IsStdDouble(field) {
+			p.P(varName, ` := new(float64)`)
+		} else if gogoproto.IsStdFloat(field) {
+			p.P(varName, ` := new(float32)`)
+		} else if gogoproto.IsStdInt64(field) {
+			p.P(varName, ` := new(int64)`)
+		} else if gogoproto.IsStdUInt64(field) {
+			p.P(varName, ` := new(uint64)`)
+		} else if gogoproto.IsStdInt32(field) {
+			p.P(varName, ` := new(int32)`)
+		} else if gogoproto.IsStdUInt32(field) {
+			p.P(varName, ` := new(uint32)`)
+		} else if gogoproto.IsStdBool(field) {
+			p.P(varName, ` := new(bool)`)
+		} else if gogoproto.IsStdString(field) {
+			p.P(varName, ` := new(string)`)
+		} else if gogoproto.IsStdBytes(field) {
+			p.P(varName, ` := new([]byte)`)
+		} else {
+			desc := p.ObjectNamed(field.GetTypeName())
+			msgname := p.TypeName(desc)
+			if nullable {
+				p.P(`var `, varName, ` *`, msgname)
+			} else {
+				p.P(varName, ` := &`, msgname, `{}`)
+			}
+		}
+	case descriptor.FieldDescriptorProto_TYPE_BYTES:
+		if customType {
+			_, ctyp, err := generator.GetCustomType(field)
+			if err != nil {
+				panic(err)
+			}
+			p.P(`var `, varName, `1 `, ctyp)
+			p.P(`var `, varName, ` = &`, varName, `1`)
+		} else {
+			p.P(varName, ` := []byte{}`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_UINT32:
+		p.P(`var `, varName, ` uint32`)
+	case descriptor.FieldDescriptorProto_TYPE_ENUM:
+		typName := p.TypeName(p.ObjectNamed(field.GetTypeName()))
+		p.P(`var `, varName, ` `, typName)
+	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+		p.P(`var `, varName, ` int32`)
+	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+		p.P(`var `, varName, ` int64`)
+	case descriptor.FieldDescriptorProto_TYPE_SINT32:
+		p.P(`var `, varName, ` int32`)
+	case descriptor.FieldDescriptorProto_TYPE_SINT64:
+		p.P(`var `, varName, ` int64`)
+	}
+}
+
+func (p *unmarshal) mapField(varName string, customType bool, field *descriptor.FieldDescriptorProto) {
+	switch field.GetType() {
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+		p.P(`var `, varName, `temp uint64`)
+		p.decodeFixed64(varName+"temp", "uint64")
+		p.P(varName, ` = `, p.mathPkg.Use(), `.Float64frombits(`, varName, `temp)`)
+	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+		p.P(`var `, varName, `temp uint32`)
+		p.decodeFixed32(varName+"temp", "uint32")
+		p.P(varName, ` = `, p.mathPkg.Use(), `.Float32frombits(`, varName, `temp)`)
+	case descriptor.FieldDescriptorProto_TYPE_INT64:
+		p.decodeVarint(varName, "int64")
+	case descriptor.FieldDescriptorProto_TYPE_UINT64:
+		p.decodeVarint(varName, "uint64")
+	case descriptor.FieldDescriptorProto_TYPE_INT32:
+		p.decodeVarint(varName, "int32")
+	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
+		p.decodeFixed64(varName, "uint64")
+	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
+		p.decodeFixed32(varName, "uint32")
+	case descriptor.FieldDescriptorProto_TYPE_BOOL:
+		p.P(`var `, varName, `temp int`)
+		p.decodeVarint(varName+"temp", "int")
+		p.P(varName, ` = bool(`, varName, `temp != 0)`)
+	case descriptor.FieldDescriptorProto_TYPE_STRING:
+		p.P(`var stringLen`, varName, ` uint64`)
+		p.decodeVarint("stringLen"+varName, "uint64")
+		p.P(`intStringLen`, varName, ` := int(stringLen`, varName, `)`)
+		p.P(`if intStringLen`, varName, ` < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`postStringIndex`, varName, ` := iNdEx + intStringLen`, varName)
+		p.P(`if postStringIndex`, varName, ` < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`if postStringIndex`, varName, ` > l {`)
+		p.In()
+		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+		p.Out()
+		p.P(`}`)
+		cast, _ := p.GoType(nil, field)
+		cast = strings.Replace(cast, "*", "", 1)
+		p.P(varName, ` = `, cast, `(dAtA[iNdEx:postStringIndex`, varName, `])`)
+		p.P(`iNdEx = postStringIndex`, varName)
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		p.P(`var mapmsglen int`)
+		p.decodeVarint("mapmsglen", "int")
+		p.P(`if mapmsglen < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`postmsgIndex := iNdEx + mapmsglen`)
+		p.P(`if postmsgIndex < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`if postmsgIndex > l {`)
+		p.In()
+		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+		p.Out()
+		p.P(`}`)
+		buf := `dAtA[iNdEx:postmsgIndex]`
+		if gogoproto.IsStdTime(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else if gogoproto.IsStdDuration(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else if gogoproto.IsStdDouble(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else if gogoproto.IsStdFloat(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else if gogoproto.IsStdInt64(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else if gogoproto.IsStdUInt64(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else if gogoproto.IsStdInt32(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else if gogoproto.IsStdUInt32(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else if gogoproto.IsStdBool(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else if gogoproto.IsStdString(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else if gogoproto.IsStdBytes(field) {
+			p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(`, varName, `, `, buf, `); err != nil {`)
+		} else {
+			desc := p.ObjectNamed(field.GetTypeName())
+			msgname := p.TypeName(desc)
+			p.P(varName, ` = &`, msgname, `{}`)
+			p.P(`if err := `, varName, `.Unmarshal(`, buf, `); err != nil {`)
+		}
+		p.In()
+		p.P(`return err`)
+		p.Out()
+		p.P(`}`)
+		p.P(`iNdEx = postmsgIndex`)
+	case descriptor.FieldDescriptorProto_TYPE_BYTES:
+		p.P(`var mapbyteLen uint64`)
+		p.decodeVarint("mapbyteLen", "uint64")
+		p.P(`intMapbyteLen := int(mapbyteLen)`)
+		p.P(`if intMapbyteLen < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`postbytesIndex := iNdEx + intMapbyteLen`)
+		p.P(`if postbytesIndex < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`if postbytesIndex > l {`)
+		p.In()
+		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+		p.Out()
+		p.P(`}`)
+		if customType {
+			p.P(`if err := `, varName, `.Unmarshal(dAtA[iNdEx:postbytesIndex]); err != nil {`)
+			p.In()
+			p.P(`return err`)
+			p.Out()
+			p.P(`}`)
+		} else {
+			p.P(varName, ` = make([]byte, mapbyteLen)`)
+			p.P(`copy(`, varName, `, dAtA[iNdEx:postbytesIndex])`)
+		}
+		p.P(`iNdEx = postbytesIndex`)
+	case descriptor.FieldDescriptorProto_TYPE_UINT32:
+		p.decodeVarint(varName, "uint32")
+	case descriptor.FieldDescriptorProto_TYPE_ENUM:
+		typName := p.TypeName(p.ObjectNamed(field.GetTypeName()))
+		p.decodeVarint(varName, typName)
+	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+		p.decodeFixed32(varName, "int32")
+	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+		p.decodeFixed64(varName, "int64")
+	case descriptor.FieldDescriptorProto_TYPE_SINT32:
+		p.P(`var `, varName, `temp int32`)
+		p.decodeVarint(varName+"temp", "int32")
+		p.P(varName, `temp = int32((uint32(`, varName, `temp) >> 1) ^ uint32(((`, varName, `temp&1)<<31)>>31))`)
+		p.P(varName, ` = int32(`, varName, `temp)`)
+	case descriptor.FieldDescriptorProto_TYPE_SINT64:
+		p.P(`var `, varName, `temp uint64`)
+		p.decodeVarint(varName+"temp", "uint64")
+		p.P(varName, `temp = (`, varName, `temp >> 1) ^ uint64((int64(`, varName, `temp&1)<<63)>>63)`)
+		p.P(varName, ` = int64(`, varName, `temp)`)
+	}
+}
+
+func (p *unmarshal) noStarOrSliceType(msg *generator.Descriptor, field *descriptor.FieldDescriptorProto) string {
+	typ, _ := p.GoType(msg, field)
+	if typ[0] == '*' {
+		return typ[1:]
+	}
+	if typ[0] == '[' && typ[1] == ']' {
+		return typ[2:]
+	}
+	return typ
+}
+
+func (p *unmarshal) field(file *generator.FileDescriptor, msg *generator.Descriptor, field *descriptor.FieldDescriptorProto, fieldname string, proto3 bool) {
+	repeated := field.IsRepeated()
+	nullable := gogoproto.IsNullable(field)
+	typ := p.noStarOrSliceType(msg, field)
+	oneof := field.OneofIndex != nil
+	switch *field.Type {
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+		p.P(`var v uint64`)
+		p.decodeFixed64("v", "uint64")
+		if oneof {
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))}`)
+		} else if repeated {
+			p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))`)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v2)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = `, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))`)
+		} else {
+			p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float64frombits(v))`)
+			p.P(`m.`, fieldname, ` = &v2`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+		p.P(`var v uint32`)
+		p.decodeFixed32("v", "uint32")
+		if oneof {
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))}`)
+		} else if repeated {
+			p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))`)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v2)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = `, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))`)
+		} else {
+			p.P(`v2 := `, typ, "(", p.mathPkg.Use(), `.Float32frombits(v))`)
+			p.P(`m.`, fieldname, ` = &v2`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_INT64:
+		if oneof {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if repeated {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = 0`)
+			p.decodeVarint("m."+fieldname, typ)
+		} else {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = &v`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_UINT64:
+		if oneof {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if repeated {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = 0`)
+			p.decodeVarint("m."+fieldname, typ)
+		} else {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = &v`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_INT32:
+		if oneof {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if repeated {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = 0`)
+			p.decodeVarint("m."+fieldname, typ)
+		} else {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = &v`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
+		if oneof {
+			p.P(`var v `, typ)
+			p.decodeFixed64("v", typ)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if repeated {
+			p.P(`var v `, typ)
+			p.decodeFixed64("v", typ)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = 0`)
+			p.decodeFixed64("m."+fieldname, typ)
+		} else {
+			p.P(`var v `, typ)
+			p.decodeFixed64("v", typ)
+			p.P(`m.`, fieldname, ` = &v`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
+		if oneof {
+			p.P(`var v `, typ)
+			p.decodeFixed32("v", typ)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if repeated {
+			p.P(`var v `, typ)
+			p.decodeFixed32("v", typ)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = 0`)
+			p.decodeFixed32("m."+fieldname, typ)
+		} else {
+			p.P(`var v `, typ)
+			p.decodeFixed32("v", typ)
+			p.P(`m.`, fieldname, ` = &v`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_BOOL:
+		p.P(`var v int`)
+		p.decodeVarint("v", "int")
+		if oneof {
+			p.P(`b := `, typ, `(v != 0)`)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{b}`)
+		} else if repeated {
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, typ, `(v != 0))`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = `, typ, `(v != 0)`)
+		} else {
+			p.P(`b := `, typ, `(v != 0)`)
+			p.P(`m.`, fieldname, ` = &b`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_STRING:
+		p.P(`var stringLen uint64`)
+		p.decodeVarint("stringLen", "uint64")
+		p.P(`intStringLen := int(stringLen)`)
+		p.P(`if intStringLen < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`postIndex := iNdEx + intStringLen`)
+		p.P(`if postIndex < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`if postIndex > l {`)
+		p.In()
+		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+		p.Out()
+		p.P(`}`)
+		if oneof {
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, `(dAtA[iNdEx:postIndex])}`)
+		} else if repeated {
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, typ, `(dAtA[iNdEx:postIndex]))`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = `, typ, `(dAtA[iNdEx:postIndex])`)
+		} else {
+			p.P(`s := `, typ, `(dAtA[iNdEx:postIndex])`)
+			p.P(`m.`, fieldname, ` = &s`)
+		}
+		p.P(`iNdEx = postIndex`)
+	case descriptor.FieldDescriptorProto_TYPE_GROUP:
+		panic(fmt.Errorf("unmarshaler does not support group %v", fieldname))
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		desc := p.ObjectNamed(field.GetTypeName())
+		msgname := p.TypeName(desc)
+		p.P(`var msglen int`)
+		p.decodeVarint("msglen", "int")
+		p.P(`if msglen < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`postIndex := iNdEx + msglen`)
+		p.P(`if postIndex < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`if postIndex > l {`)
+		p.In()
+		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+		p.Out()
+		p.P(`}`)
+		if oneof {
+			buf := `dAtA[iNdEx:postIndex]`
+			if gogoproto.IsStdTime(field) {
+				if nullable {
+					p.P(`v := new(time.Time)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`v := time.Time{}`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdDuration(field) {
+				if nullable {
+					p.P(`v := new(time.Duration)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`v := time.Duration(0)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdDouble(field) {
+				if nullable {
+					p.P(`v := new(float64)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`v := 0`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdFloat(field) {
+				if nullable {
+					p.P(`v := new(float32)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`v := 0`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdInt64(field) {
+				if nullable {
+					p.P(`v := new(int64)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`v := 0`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdUInt64(field) {
+				if nullable {
+					p.P(`v := new(uint64)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`v := 0`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdInt32(field) {
+				if nullable {
+					p.P(`v := new(int32)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`v := 0`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdUInt32(field) {
+				if nullable {
+					p.P(`v := new(uint32)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`v := 0`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdBool(field) {
+				if nullable {
+					p.P(`v := new(bool)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`v := false`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdString(field) {
+				if nullable {
+					p.P(`v := new(string)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`v := ""`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdBytes(field) {
+				if nullable {
+					p.P(`v := new([]byte)`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(v, `, buf, `); err != nil {`)
+				} else {
+					p.P(`var v []byte`)
+					p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(&v, `, buf, `); err != nil {`)
+				}
+			} else {
+				p.P(`v := &`, msgname, `{}`)
+				p.P(`if err := v.Unmarshal(`, buf, `); err != nil {`)
+			}
+			p.In()
+			p.P(`return err`)
+			p.Out()
+			p.P(`}`)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if p.IsMap(field) {
+			m := p.GoMapType(nil, field)
+
+			keygoTyp, _ := p.GoType(nil, m.KeyField)
+			keygoAliasTyp, _ := p.GoType(nil, m.KeyAliasField)
+			// keys may not be pointers
+			keygoTyp = strings.Replace(keygoTyp, "*", "", 1)
+			keygoAliasTyp = strings.Replace(keygoAliasTyp, "*", "", 1)
+
+			valuegoTyp, _ := p.GoType(nil, m.ValueField)
+			valuegoAliasTyp, _ := p.GoType(nil, m.ValueAliasField)
+
+			// if the map type is an alias and key or values are aliases (type Foo map[Bar]Baz),
+			// we need to explicitly record their use here.
+			if gogoproto.IsCastKey(field) {
+				p.RecordTypeUse(m.KeyAliasField.GetTypeName())
+			}
+			if gogoproto.IsCastValue(field) {
+				p.RecordTypeUse(m.ValueAliasField.GetTypeName())
+			}
+
+			nullable, valuegoTyp, valuegoAliasTyp = generator.GoMapValueTypes(field, m.ValueField, valuegoTyp, valuegoAliasTyp)
+			if gogoproto.IsStdType(field) {
+				valuegoTyp = valuegoAliasTyp
+			}
+
+			p.P(`if m.`, fieldname, ` == nil {`)
+			p.In()
+			p.P(`m.`, fieldname, ` = make(`, m.GoType, `)`)
+			p.Out()
+			p.P(`}`)
+
+			p.declareMapField("mapkey", false, false, m.KeyAliasField)
+			p.declareMapField("mapvalue", nullable, gogoproto.IsCustomType(field), m.ValueAliasField)
+			p.P(`for iNdEx < postIndex {`)
+			p.In()
+
+			p.P(`entryPreIndex := iNdEx`)
+			p.P(`var wire uint64`)
+			p.decodeVarint("wire", "uint64")
+			p.P(`fieldNum := int32(wire >> 3)`)
+
+			p.P(`if fieldNum == 1 {`)
+			p.In()
+			p.mapField("mapkey", false, m.KeyAliasField)
+			p.Out()
+			p.P(`} else if fieldNum == 2 {`)
+			p.In()
+			p.mapField("mapvalue", gogoproto.IsCustomType(field), m.ValueAliasField)
+			p.Out()
+			p.P(`} else {`)
+			p.In()
+			p.P(`iNdEx = entryPreIndex`)
+			p.P(`skippy, err := skip`, p.localName, `(dAtA[iNdEx:])`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`return err`)
+			p.Out()
+			p.P(`}`)
+			p.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`)
+			p.In()
+			p.P(`return ErrInvalidLength`, p.localName)
+			p.Out()
+			p.P(`}`)
+			p.P(`if (iNdEx + skippy) > postIndex {`)
+			p.In()
+			p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+			p.Out()
+			p.P(`}`)
+			p.P(`iNdEx += skippy`)
+			p.Out()
+			p.P(`}`)
+
+			p.Out()
+			p.P(`}`)
+
+			s := `m.` + fieldname
+			if keygoTyp == keygoAliasTyp {
+				s += `[mapkey]`
+			} else {
+				s += `[` + keygoAliasTyp + `(mapkey)]`
+			}
+
+			v := `mapvalue`
+			if (m.ValueField.IsMessage() || gogoproto.IsCustomType(field)) && !nullable {
+				v = `*` + v
+			}
+			if valuegoTyp != valuegoAliasTyp {
+				v = `((` + valuegoAliasTyp + `)(` + v + `))`
+			}
+
+			p.P(s, ` = `, v)
+		} else if repeated {
+			if gogoproto.IsStdTime(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(time.Time))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, time.Time{})`)
+				}
+			} else if gogoproto.IsStdDuration(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(time.Duration))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, time.Duration(0))`)
+				}
+			} else if gogoproto.IsStdDouble(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(float64))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
+				}
+			} else if gogoproto.IsStdFloat(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(float32))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
+				}
+			} else if gogoproto.IsStdInt64(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(int64))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
+				}
+			} else if gogoproto.IsStdUInt64(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(uint64))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
+				}
+			} else if gogoproto.IsStdInt32(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(int32))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
+				}
+			} else if gogoproto.IsStdUInt32(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(uint32))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, 0)`)
+				}
+			} else if gogoproto.IsStdBool(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(bool))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, false)`)
+				}
+			} else if gogoproto.IsStdString(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new(string))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, "")`)
+				}
+			} else if gogoproto.IsStdBytes(field) {
+				if nullable {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, new([]byte))`)
+				} else {
+					p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, []byte{})`)
+				}
+			} else if nullable && !gogoproto.IsCustomType(field) {
+				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, &`, msgname, `{})`)
+			} else {
+				goType, _ := p.GoType(nil, field)
+				// remove the slice from the type, i.e. []*T -> *T
+				goType = goType[2:]
+				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, goType, `{})`)
+			}
+			varName := `m.` + fieldname + `[len(m.` + fieldname + `)-1]`
+			buf := `dAtA[iNdEx:postIndex]`
+			if gogoproto.IsStdTime(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdDuration(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdDouble(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdFloat(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdInt64(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdUInt64(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdInt32(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdUInt32(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdBool(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdString(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else if gogoproto.IsStdBytes(field) {
+				if nullable {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(`, varName, `,`, buf, `); err != nil {`)
+				} else {
+					p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(&(`, varName, `),`, buf, `); err != nil {`)
+				}
+			} else {
+				p.P(`if err := `, varName, `.Unmarshal(`, buf, `); err != nil {`)
+			}
+			p.In()
+			p.P(`return err`)
+			p.Out()
+			p.P(`}`)
+		} else if nullable {
+			p.P(`if m.`, fieldname, ` == nil {`)
+			p.In()
+			if gogoproto.IsStdTime(field) {
+				p.P(`m.`, fieldname, ` = new(time.Time)`)
+			} else if gogoproto.IsStdDuration(field) {
+				p.P(`m.`, fieldname, ` = new(time.Duration)`)
+			} else if gogoproto.IsStdDouble(field) {
+				p.P(`m.`, fieldname, ` = new(float64)`)
+			} else if gogoproto.IsStdFloat(field) {
+				p.P(`m.`, fieldname, ` = new(float32)`)
+			} else if gogoproto.IsStdInt64(field) {
+				p.P(`m.`, fieldname, ` = new(int64)`)
+			} else if gogoproto.IsStdUInt64(field) {
+				p.P(`m.`, fieldname, ` = new(uint64)`)
+			} else if gogoproto.IsStdInt32(field) {
+				p.P(`m.`, fieldname, ` = new(int32)`)
+			} else if gogoproto.IsStdUInt32(field) {
+				p.P(`m.`, fieldname, ` = new(uint32)`)
+			} else if gogoproto.IsStdBool(field) {
+				p.P(`m.`, fieldname, ` = new(bool)`)
+			} else if gogoproto.IsStdString(field) {
+				p.P(`m.`, fieldname, ` = new(string)`)
+			} else if gogoproto.IsStdBytes(field) {
+				p.P(`m.`, fieldname, ` = new([]byte)`)
+			} else {
+				goType, _ := p.GoType(nil, field)
+				// remove the star from the type
+				p.P(`m.`, fieldname, ` = &`, goType[1:], `{}`)
+			}
+			p.Out()
+			p.P(`}`)
+			if gogoproto.IsStdTime(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdDuration(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdDouble(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdFloat(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdInt64(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdUInt64(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdInt32(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdUInt32(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdBool(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdString(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdBytes(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else {
+				p.P(`if err := m.`, fieldname, `.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
+			}
+			p.In()
+			p.P(`return err`)
+			p.Out()
+			p.P(`}`)
+		} else {
+			if gogoproto.IsStdTime(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdTimeUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdDuration(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdDurationUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdDouble(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdDoubleUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdFloat(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdFloatUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdInt64(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdInt64Unmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdUInt64(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdUInt64Unmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdInt32(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdInt32Unmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdUInt32(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdUInt32Unmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdBool(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdBoolUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdString(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdStringUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else if gogoproto.IsStdBytes(field) {
+				p.P(`if err := `, p.typesPkg.Use(), `.StdBytesUnmarshal(&m.`, fieldname, `, dAtA[iNdEx:postIndex]); err != nil {`)
+			} else {
+				p.P(`if err := m.`, fieldname, `.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
+			}
+			p.In()
+			p.P(`return err`)
+			p.Out()
+			p.P(`}`)
+		}
+		p.P(`iNdEx = postIndex`)
+
+	case descriptor.FieldDescriptorProto_TYPE_BYTES:
+		p.P(`var byteLen int`)
+		p.decodeVarint("byteLen", "int")
+		p.P(`if byteLen < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`postIndex := iNdEx + byteLen`)
+		p.P(`if postIndex < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength` + p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`if postIndex > l {`)
+		p.In()
+		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+		p.Out()
+		p.P(`}`)
+		if !gogoproto.IsCustomType(field) {
+			if oneof {
+				p.P(`v := make([]byte, postIndex-iNdEx)`)
+				p.P(`copy(v, dAtA[iNdEx:postIndex])`)
+				p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+			} else if repeated {
+				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, make([]byte, postIndex-iNdEx))`)
+				p.P(`copy(m.`, fieldname, `[len(m.`, fieldname, `)-1], dAtA[iNdEx:postIndex])`)
+			} else {
+				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `[:0] , dAtA[iNdEx:postIndex]...)`)
+				p.P(`if m.`, fieldname, ` == nil {`)
+				p.In()
+				p.P(`m.`, fieldname, ` = []byte{}`)
+				p.Out()
+				p.P(`}`)
+			}
+		} else {
+			_, ctyp, err := generator.GetCustomType(field)
+			if err != nil {
+				panic(err)
+			}
+			if oneof {
+				p.P(`var vv `, ctyp)
+				p.P(`v := &vv`)
+				p.P(`if err := v.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
+				p.In()
+				p.P(`return err`)
+				p.Out()
+				p.P(`}`)
+				p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{*v}`)
+			} else if repeated {
+				p.P(`var v `, ctyp)
+				p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+				p.P(`if err := m.`, fieldname, `[len(m.`, fieldname, `)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
+				p.In()
+				p.P(`return err`)
+				p.Out()
+				p.P(`}`)
+			} else if nullable {
+				p.P(`var v `, ctyp)
+				p.P(`m.`, fieldname, ` = &v`)
+				p.P(`if err := m.`, fieldname, `.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
+				p.In()
+				p.P(`return err`)
+				p.Out()
+				p.P(`}`)
+			} else {
+				p.P(`if err := m.`, fieldname, `.Unmarshal(dAtA[iNdEx:postIndex]); err != nil {`)
+				p.In()
+				p.P(`return err`)
+				p.Out()
+				p.P(`}`)
+			}
+		}
+		p.P(`iNdEx = postIndex`)
+	case descriptor.FieldDescriptorProto_TYPE_UINT32:
+		if oneof {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if repeated {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = 0`)
+			p.decodeVarint("m."+fieldname, typ)
+		} else {
+			p.P(`var v `, typ)
+			p.decodeVarint("v", typ)
+			p.P(`m.`, fieldname, ` = &v`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_ENUM:
+		typName := p.TypeName(p.ObjectNamed(field.GetTypeName()))
+		if oneof {
+			p.P(`var v `, typName)
+			p.decodeVarint("v", typName)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if repeated {
+			p.P(`var v `, typName)
+			p.decodeVarint("v", typName)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = 0`)
+			p.decodeVarint("m."+fieldname, typName)
+		} else {
+			p.P(`var v `, typName)
+			p.decodeVarint("v", typName)
+			p.P(`m.`, fieldname, ` = &v`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+		if oneof {
+			p.P(`var v `, typ)
+			p.decodeFixed32("v", typ)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if repeated {
+			p.P(`var v `, typ)
+			p.decodeFixed32("v", typ)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = 0`)
+			p.decodeFixed32("m."+fieldname, typ)
+		} else {
+			p.P(`var v `, typ)
+			p.decodeFixed32("v", typ)
+			p.P(`m.`, fieldname, ` = &v`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+		if oneof {
+			p.P(`var v `, typ)
+			p.decodeFixed64("v", typ)
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if repeated {
+			p.P(`var v `, typ)
+			p.decodeFixed64("v", typ)
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = 0`)
+			p.decodeFixed64("m."+fieldname, typ)
+		} else {
+			p.P(`var v `, typ)
+			p.decodeFixed64("v", typ)
+			p.P(`m.`, fieldname, ` = &v`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_SINT32:
+		p.P(`var v `, typ)
+		p.decodeVarint("v", typ)
+		p.P(`v = `, typ, `((uint32(v) >> 1) ^ uint32(((v&1)<<31)>>31))`)
+		if oneof {
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
+		} else if repeated {
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, v)`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = v`)
+		} else {
+			p.P(`m.`, fieldname, ` = &v`)
+		}
+	case descriptor.FieldDescriptorProto_TYPE_SINT64:
+		p.P(`var v uint64`)
+		p.decodeVarint("v", "uint64")
+		p.P(`v = (v >> 1) ^ uint64((int64(v&1)<<63)>>63)`)
+		if oneof {
+			p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{`, typ, `(v)}`)
+		} else if repeated {
+			p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, `, typ, `(v))`)
+		} else if proto3 || !nullable {
+			p.P(`m.`, fieldname, ` = `, typ, `(v)`)
+		} else {
+			p.P(`v2 := `, typ, `(v)`)
+			p.P(`m.`, fieldname, ` = &v2`)
+		}
+	default:
+		panic("not implemented")
+	}
+}
+
+func (p *unmarshal) Generate(file *generator.FileDescriptor) {
+	proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	p.atleastOne = false
+	p.localName = generator.FileName(file)
+
+	p.ioPkg = p.NewImport("io")
+	p.mathPkg = p.NewImport("math")
+	p.typesPkg = p.NewImport("github.com/gogo/protobuf/types")
+	p.binaryPkg = p.NewImport("encoding/binary")
+	fmtPkg := p.NewImport("fmt")
+	protoPkg := p.NewImport("github.com/gogo/protobuf/proto")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		protoPkg = p.NewImport("github.com/golang/protobuf/proto")
+	}
+
+	for _, message := range file.Messages() {
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		if !gogoproto.IsUnmarshaler(file.FileDescriptorProto, message.DescriptorProto) &&
+			!gogoproto.IsUnsafeUnmarshaler(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		p.atleastOne = true
+
+		// build a map required field_id -> bitmask offset
+		rfMap := make(map[int32]uint)
+		rfNextId := uint(0)
+		for _, field := range message.Field {
+			if field.IsRequired() {
+				rfMap[field.GetNumber()] = rfNextId
+				rfNextId++
+			}
+		}
+		rfCount := len(rfMap)
+
+		p.P(`func (m *`, ccTypeName, `) Unmarshal(dAtA []byte) error {`)
+		p.In()
+		if rfCount > 0 {
+			p.P(`var hasFields [`, strconv.Itoa(1+(rfCount-1)/64), `]uint64`)
+		}
+		p.P(`l := len(dAtA)`)
+		p.P(`iNdEx := 0`)
+		p.P(`for iNdEx < l {`)
+		p.In()
+		p.P(`preIndex := iNdEx`)
+		p.P(`var wire uint64`)
+		p.decodeVarint("wire", "uint64")
+		p.P(`fieldNum := int32(wire >> 3)`)
+		if len(message.Field) > 0 || !message.IsGroup() {
+			p.P(`wireType := int(wire & 0x7)`)
+		}
+		if !message.IsGroup() {
+			p.P(`if wireType == `, strconv.Itoa(proto.WireEndGroup), ` {`)
+			p.In()
+			p.P(`return `, fmtPkg.Use(), `.Errorf("proto: `+message.GetName()+`: wiretype end group for non-group")`)
+			p.Out()
+			p.P(`}`)
+		}
+		p.P(`if fieldNum <= 0 {`)
+		p.In()
+		p.P(`return `, fmtPkg.Use(), `.Errorf("proto: `+message.GetName()+`: illegal tag %d (wire type %d)", fieldNum, wire)`)
+		p.Out()
+		p.P(`}`)
+		p.P(`switch fieldNum {`)
+		p.In()
+		for _, field := range message.Field {
+			fieldname := p.GetFieldName(message, field)
+			errFieldname := fieldname
+			if field.OneofIndex != nil {
+				errFieldname = p.GetOneOfFieldName(message, field)
+			}
+			possiblyPacked := field.IsScalar() && field.IsRepeated()
+			p.P(`case `, strconv.Itoa(int(field.GetNumber())), `:`)
+			p.In()
+			wireType := field.WireType()
+			if possiblyPacked {
+				p.P(`if wireType == `, strconv.Itoa(wireType), `{`)
+				p.In()
+				p.field(file, message, field, fieldname, false)
+				p.Out()
+				p.P(`} else if wireType == `, strconv.Itoa(proto.WireBytes), `{`)
+				p.In()
+				p.P(`var packedLen int`)
+				p.decodeVarint("packedLen", "int")
+				p.P(`if packedLen < 0 {`)
+				p.In()
+				p.P(`return ErrInvalidLength` + p.localName)
+				p.Out()
+				p.P(`}`)
+				p.P(`postIndex := iNdEx + packedLen`)
+				p.P(`if postIndex < 0 {`)
+				p.In()
+				p.P(`return ErrInvalidLength` + p.localName)
+				p.Out()
+				p.P(`}`)
+				p.P(`if postIndex > l {`)
+				p.In()
+				p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+				p.Out()
+				p.P(`}`)
+
+				p.P(`var elementCount int`)
+				switch *field.Type {
+				case descriptor.FieldDescriptorProto_TYPE_DOUBLE, descriptor.FieldDescriptorProto_TYPE_FIXED64, descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+					p.P(`elementCount = packedLen/`, 8)
+				case descriptor.FieldDescriptorProto_TYPE_FLOAT, descriptor.FieldDescriptorProto_TYPE_FIXED32, descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+					p.P(`elementCount = packedLen/`, 4)
+				case descriptor.FieldDescriptorProto_TYPE_INT64, descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_UINT32, descriptor.FieldDescriptorProto_TYPE_SINT32, descriptor.FieldDescriptorProto_TYPE_SINT64:
+					p.P(`var count int`)
+					p.P(`for _, integer := range dAtA[iNdEx:postIndex] {`)
+					p.In()
+					p.P(`if integer < 128 {`)
+					p.In()
+					p.P(`count++`)
+					p.Out()
+					p.P(`}`)
+					p.Out()
+					p.P(`}`)
+					p.P(`elementCount = count`)
+				case descriptor.FieldDescriptorProto_TYPE_BOOL:
+					p.P(`elementCount = packedLen`)
+				}
+				p.P(`if elementCount != 0 && len(m.`, fieldname, `) == 0 {`)
+				p.In()
+				p.P(`m.`, fieldname, ` = make([]`, p.noStarOrSliceType(message, field), `, 0, elementCount)`)
+				p.Out()
+				p.P(`}`)
+
+				p.P(`for iNdEx < postIndex {`)
+				p.In()
+				p.field(file, message, field, fieldname, false)
+				p.Out()
+				p.P(`}`)
+				p.Out()
+				p.P(`} else {`)
+				p.In()
+				p.P(`return ` + fmtPkg.Use() + `.Errorf("proto: wrong wireType = %d for field ` + errFieldname + `", wireType)`)
+				p.Out()
+				p.P(`}`)
+			} else {
+				p.P(`if wireType != `, strconv.Itoa(wireType), `{`)
+				p.In()
+				p.P(`return ` + fmtPkg.Use() + `.Errorf("proto: wrong wireType = %d for field ` + errFieldname + `", wireType)`)
+				p.Out()
+				p.P(`}`)
+				p.field(file, message, field, fieldname, proto3)
+			}
+
+			if field.IsRequired() {
+				fieldBit, ok := rfMap[field.GetNumber()]
+				if !ok {
+					panic("field is required, but no bit registered")
+				}
+				p.P(`hasFields[`, strconv.Itoa(int(fieldBit/64)), `] |= uint64(`, fmt.Sprintf("0x%08x", uint64(1)<<(fieldBit%64)), `)`)
+			}
+		}
+		p.Out()
+		p.P(`default:`)
+		p.In()
+		if message.DescriptorProto.HasExtension() {
+			c := []string{}
+			for _, erange := range message.GetExtensionRange() {
+				c = append(c, `((fieldNum >= `+strconv.Itoa(int(erange.GetStart()))+") && (fieldNum<"+strconv.Itoa(int(erange.GetEnd()))+`))`)
+			}
+			p.P(`if `, strings.Join(c, "||"), `{`)
+			p.In()
+			p.P(`var sizeOfWire int`)
+			p.P(`for {`)
+			p.In()
+			p.P(`sizeOfWire++`)
+			p.P(`wire >>= 7`)
+			p.P(`if wire == 0 {`)
+			p.In()
+			p.P(`break`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+			p.P(`iNdEx-=sizeOfWire`)
+			p.P(`skippy, err := skip`, p.localName+`(dAtA[iNdEx:])`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`return err`)
+			p.Out()
+			p.P(`}`)
+			p.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`)
+			p.In()
+			p.P(`return ErrInvalidLength`, p.localName)
+			p.Out()
+			p.P(`}`)
+			p.P(`if (iNdEx + skippy) > l {`)
+			p.In()
+			p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+			p.Out()
+			p.P(`}`)
+			p.P(protoPkg.Use(), `.AppendExtension(m, int32(fieldNum), dAtA[iNdEx:iNdEx+skippy])`)
+			p.P(`iNdEx += skippy`)
+			p.Out()
+			p.P(`} else {`)
+			p.In()
+		}
+		p.P(`iNdEx=preIndex`)
+		p.P(`skippy, err := skip`, p.localName, `(dAtA[iNdEx:])`)
+		p.P(`if err != nil {`)
+		p.In()
+		p.P(`return err`)
+		p.Out()
+		p.P(`}`)
+		p.P(`if (skippy < 0) || (iNdEx + skippy) < 0 {`)
+		p.In()
+		p.P(`return ErrInvalidLength`, p.localName)
+		p.Out()
+		p.P(`}`)
+		p.P(`if (iNdEx + skippy) > l {`)
+		p.In()
+		p.P(`return `, p.ioPkg.Use(), `.ErrUnexpectedEOF`)
+		p.Out()
+		p.P(`}`)
+		if gogoproto.HasUnrecognized(file.FileDescriptorProto, message.DescriptorProto) {
+			p.P(`m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...)`)
+		}
+		p.P(`iNdEx += skippy`)
+		p.Out()
+		if message.DescriptorProto.HasExtension() {
+			p.Out()
+			p.P(`}`)
+		}
+		p.Out()
+		p.P(`}`)
+		p.Out()
+		p.P(`}`)
+
+		for _, field := range message.Field {
+			if !field.IsRequired() {
+				continue
+			}
+
+			fieldBit, ok := rfMap[field.GetNumber()]
+			if !ok {
+				panic("field is required, but no bit registered")
+			}
+
+			p.P(`if hasFields[`, strconv.Itoa(int(fieldBit/64)), `] & uint64(`, fmt.Sprintf("0x%08x", uint64(1)<<(fieldBit%64)), `) == 0 {`)
+			p.In()
+			if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+				p.P(`return new(`, protoPkg.Use(), `.RequiredNotSetError)`)
+			} else {
+				p.P(`return `, protoPkg.Use(), `.NewRequiredNotSetError("`, field.GetName(), `")`)
+			}
+			p.Out()
+			p.P(`}`)
+		}
+		p.P()
+		p.P(`if iNdEx > l {`)
+		p.In()
+		p.P(`return ` + p.ioPkg.Use() + `.ErrUnexpectedEOF`)
+		p.Out()
+		p.P(`}`)
+		p.P(`return nil`)
+		p.Out()
+		p.P(`}`)
+	}
+	if !p.atleastOne {
+		return
+	}
+
+	p.P(`func skip` + p.localName + `(dAtA []byte) (n int, err error) {
+		l := len(dAtA)
+		iNdEx := 0
+		depth := 0
+		for iNdEx < l {
+			var wire uint64
+			for shift := uint(0); ; shift += 7 {
+				if shift >= 64 {
+					return 0, ErrIntOverflow` + p.localName + `
+				}
+				if iNdEx >= l {
+					return 0, ` + p.ioPkg.Use() + `.ErrUnexpectedEOF
+				}
+				b := dAtA[iNdEx]
+				iNdEx++
+				wire |= (uint64(b) & 0x7F) << shift
+				if b < 0x80 {
+					break
+				}
+			}
+			wireType := int(wire & 0x7)
+			switch wireType {
+			case 0:
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflow` + p.localName + `
+					}
+					if iNdEx >= l {
+						return 0, ` + p.ioPkg.Use() + `.ErrUnexpectedEOF
+					}
+					iNdEx++
+					if dAtA[iNdEx-1] < 0x80 {
+						break
+					}
+				}
+			case 1:
+				iNdEx += 8
+			case 2:
+				var length int
+				for shift := uint(0); ; shift += 7 {
+					if shift >= 64 {
+						return 0, ErrIntOverflow` + p.localName + `
+					}
+					if iNdEx >= l {
+						return 0, ` + p.ioPkg.Use() + `.ErrUnexpectedEOF
+					}
+					b := dAtA[iNdEx]
+					iNdEx++
+					length |= (int(b) & 0x7F) << shift
+					if b < 0x80 {
+						break
+					}
+				}
+				if length < 0 {
+					return 0, ErrInvalidLength` + p.localName + `
+				}
+				iNdEx += length
+			case 3:
+				depth++
+			case 4:
+				if depth == 0 {
+					return 0, ErrUnexpectedEndOfGroup` + p.localName + `
+				}
+				depth--
+			case 5:
+				iNdEx += 4
+			default:
+				return 0, ` + fmtPkg.Use() + `.Errorf("proto: illegal wireType %d", wireType)
+			}
+			if iNdEx < 0 {
+				return 0, ErrInvalidLength` + p.localName + `
+			}
+			if depth == 0 {
+				return iNdEx, nil
+			}
+		}
+		return 0, ` + p.ioPkg.Use() + `.ErrUnexpectedEOF
+	}
+
+	var (
+		ErrInvalidLength` + p.localName + ` = ` + fmtPkg.Use() + `.Errorf("proto: negative length found during unmarshaling")
+		ErrIntOverflow` + p.localName + ` = ` + fmtPkg.Use() + `.Errorf("proto: integer overflow")
+		ErrUnexpectedEndOfGroup` + p.localName + ` = ` + fmtPkg.Use() + `.Errorf("proto: unexpected end of group")
+	)
+	`)
+}
+
+func init() {
+	generator.RegisterPlugin(NewUnmarshal())
+}
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/Makefile b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/Makefile
new file mode 100644
index 0000000000000..52e2d4e70471d
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/Makefile
@@ -0,0 +1,41 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  All rights reserved.
+# https://github.com/golang/protobuf
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+all: test
+
+test:
+	go test
+	make -C testdata test
+
+regenerate:
+	go test --regenerate
+	make -C descriptor regenerate
+	make -C plugin regenerate
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/doc.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/doc.go
new file mode 100644
index 0000000000000..15c7cf43c282c
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/doc.go
@@ -0,0 +1,51 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+	A plugin for the Google protocol buffer compiler to generate Go code.
+	Run it by building this program and putting it in your path with the name
+		protoc-gen-gogo
+	That word 'gogo' at the end becomes part of the option string set for the
+	protocol compiler, so once the protocol compiler (protoc) is installed
+	you can run
+		protoc --gogo_out=output_directory input_directory/file.proto
+	to generate Go bindings for the protocol defined by file.proto.
+	With that input, the output will be written to
+		output_directory/go_package/file.pb.go
+
+	The generated code is documented in the package comment for
+	the library.
+
+	See the README and documentation for protocol buffers to learn more:
+		https://developers.google.com/protocol-buffers/
+
+*/
+package documentation
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go
new file mode 100644
index 0000000000000..ab07ed61ef030
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/generator.go
@@ -0,0 +1,3444 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+	The code generator for the plugin for the Google protocol buffer compiler.
+	It generates Go code from the protocol buffer description files read by the
+	main routine.
+*/
+package generator
+
+import (
+	"bufio"
+	"bytes"
+	"compress/gzip"
+	"crypto/sha256"
+	"encoding/hex"
+	"fmt"
+	"go/ast"
+	"go/build"
+	"go/parser"
+	"go/printer"
+	"go/token"
+	"log"
+	"os"
+	"path"
+	"sort"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator/internal/remap"
+	plugin "github.com/gogo/protobuf/protoc-gen-gogo/plugin"
+)
+
+// generatedCodeVersion indicates a version of the generated code.
+// It is incremented whenever an incompatibility between the generated code and
+// proto package is introduced; the generated code references
+// a constant, proto.ProtoPackageIsVersionN (where N is generatedCodeVersion).
+const generatedCodeVersion = 3
+
+// A Plugin provides functionality to add to the output during Go code generation,
+// such as to produce RPC stubs.
+type Plugin interface {
+	// Name identifies the plugin.
+	Name() string
+	// Init is called once after data structures are built but before
+	// code generation begins.
+	Init(g *Generator)
+	// Generate produces the code generated by the plugin for this file,
+	// except for the imports, by calling the generator's methods P, In, and Out.
+	Generate(file *FileDescriptor)
+	// GenerateImports produces the import declarations for this file.
+	// It is called after Generate.
+	GenerateImports(file *FileDescriptor)
+}
+
+type pluginSlice []Plugin
+
+func (ps pluginSlice) Len() int {
+	return len(ps)
+}
+
+func (ps pluginSlice) Less(i, j int) bool {
+	return ps[i].Name() < ps[j].Name()
+}
+
+func (ps pluginSlice) Swap(i, j int) {
+	ps[i], ps[j] = ps[j], ps[i]
+}
+
+var plugins pluginSlice
+
+// RegisterPlugin installs a (second-order) plugin to be run when the Go output is generated.
+// It is typically called during initialization.
+func RegisterPlugin(p Plugin) {
+	plugins = append(plugins, p)
+}
+
+// A GoImportPath is the import path of a Go package. e.g., "google.golang.org/genproto/protobuf".
+type GoImportPath string
+
+func (p GoImportPath) String() string { return strconv.Quote(string(p)) }
+
+// A GoPackageName is the name of a Go package. e.g., "protobuf".
+type GoPackageName string
+
+// Each type we import as a protocol buffer (other than FileDescriptorProto) needs
+// a pointer to the FileDescriptorProto that represents it.  These types achieve that
+// wrapping by placing each Proto inside a struct with the pointer to its File. The
+// structs have the same names as their contents, with "Proto" removed.
+// FileDescriptor is used to store the things that it points to.
+
+// The file and package name method are common to messages and enums.
+type common struct {
+	file *FileDescriptor // File this object comes from.
+}
+
+// GoImportPath is the import path of the Go package containing the type.
+func (c *common) GoImportPath() GoImportPath {
+	return c.file.importPath
+}
+
+func (c *common) File() *FileDescriptor { return c.file }
+
+func fileIsProto3(file *descriptor.FileDescriptorProto) bool {
+	return file.GetSyntax() == "proto3"
+}
+
+func (c *common) proto3() bool { return fileIsProto3(c.file.FileDescriptorProto) }
+
+// Descriptor represents a protocol buffer message.
+type Descriptor struct {
+	common
+	*descriptor.DescriptorProto
+	parent   *Descriptor            // The containing message, if any.
+	nested   []*Descriptor          // Inner messages, if any.
+	enums    []*EnumDescriptor      // Inner enums, if any.
+	ext      []*ExtensionDescriptor // Extensions, if any.
+	typename []string               // Cached typename vector.
+	index    int                    // The index into the container, whether the file or another message.
+	path     string                 // The SourceCodeInfo path as comma-separated integers.
+	group    bool
+}
+
+// TypeName returns the elements of the dotted type name.
+// The package name is not part of this name.
+func (d *Descriptor) TypeName() []string {
+	if d.typename != nil {
+		return d.typename
+	}
+	n := 0
+	for parent := d; parent != nil; parent = parent.parent {
+		n++
+	}
+	s := make([]string, n)
+	for parent := d; parent != nil; parent = parent.parent {
+		n--
+		s[n] = parent.GetName()
+	}
+	d.typename = s
+	return s
+}
+
+func (d *Descriptor) allowOneof() bool {
+	return true
+}
+
+// EnumDescriptor describes an enum. If it's at top level, its parent will be nil.
+// Otherwise it will be the descriptor of the message in which it is defined.
+type EnumDescriptor struct {
+	common
+	*descriptor.EnumDescriptorProto
+	parent   *Descriptor // The containing message, if any.
+	typename []string    // Cached typename vector.
+	index    int         // The index into the container, whether the file or a message.
+	path     string      // The SourceCodeInfo path as comma-separated integers.
+}
+
+// TypeName returns the elements of the dotted type name.
+// The package name is not part of this name.
+func (e *EnumDescriptor) TypeName() (s []string) {
+	if e.typename != nil {
+		return e.typename
+	}
+	name := e.GetName()
+	if e.parent == nil {
+		s = make([]string, 1)
+	} else {
+		pname := e.parent.TypeName()
+		s = make([]string, len(pname)+1)
+		copy(s, pname)
+	}
+	s[len(s)-1] = name
+	e.typename = s
+	return s
+}
+
+// alias provides the TypeName corrected for the application of any naming
+// extensions on the enum type. It should be used for generating references to
+// the Go types and for calculating prefixes.
+func (e *EnumDescriptor) alias() (s []string) {
+	s = e.TypeName()
+	if gogoproto.IsEnumCustomName(e.EnumDescriptorProto) {
+		s[len(s)-1] = gogoproto.GetEnumCustomName(e.EnumDescriptorProto)
+	}
+
+	return
+}
+
+// Everything but the last element of the full type name, CamelCased.
+// The values of type Foo.Bar are call Foo_value1... not Foo_Bar_value1... .
+func (e *EnumDescriptor) prefix() string {
+	typeName := e.alias()
+	if e.parent == nil {
+		// If the enum is not part of a message, the prefix is just the type name.
+		return CamelCase(typeName[len(typeName)-1]) + "_"
+	}
+	return CamelCaseSlice(typeName[0:len(typeName)-1]) + "_"
+}
+
+// The integer value of the named constant in this enumerated type.
+func (e *EnumDescriptor) integerValueAsString(name string) string {
+	for _, c := range e.Value {
+		if c.GetName() == name {
+			return fmt.Sprint(c.GetNumber())
+		}
+	}
+	log.Fatal("cannot find value for enum constant")
+	return ""
+}
+
+// ExtensionDescriptor describes an extension. If it's at top level, its parent will be nil.
+// Otherwise it will be the descriptor of the message in which it is defined.
+type ExtensionDescriptor struct {
+	common
+	*descriptor.FieldDescriptorProto
+	parent *Descriptor // The containing message, if any.
+}
+
+// TypeName returns the elements of the dotted type name.
+// The package name is not part of this name.
+func (e *ExtensionDescriptor) TypeName() (s []string) {
+	name := e.GetName()
+	if e.parent == nil {
+		// top-level extension
+		s = make([]string, 1)
+	} else {
+		pname := e.parent.TypeName()
+		s = make([]string, len(pname)+1)
+		copy(s, pname)
+	}
+	s[len(s)-1] = name
+	return s
+}
+
+// DescName returns the variable name used for the generated descriptor.
+func (e *ExtensionDescriptor) DescName() string {
+	// The full type name.
+	typeName := e.TypeName()
+	// Each scope of the extension is individually CamelCased, and all are joined with "_" with an "E_" prefix.
+	for i, s := range typeName {
+		typeName[i] = CamelCase(s)
+	}
+	return "E_" + strings.Join(typeName, "_")
+}
+
+// ImportedDescriptor describes a type that has been publicly imported from another file.
+type ImportedDescriptor struct {
+	common
+	o Object
+}
+
+func (id *ImportedDescriptor) TypeName() []string { return id.o.TypeName() }
+
+// FileDescriptor describes an protocol buffer descriptor file (.proto).
+// It includes slices of all the messages and enums defined within it.
+// Those slices are constructed by WrapTypes.
+type FileDescriptor struct {
+	*descriptor.FileDescriptorProto
+	desc []*Descriptor          // All the messages defined in this file.
+	enum []*EnumDescriptor      // All the enums defined in this file.
+	ext  []*ExtensionDescriptor // All the top-level extensions defined in this file.
+	imp  []*ImportedDescriptor  // All types defined in files publicly imported by this file.
+
+	// Comments, stored as a map of path (comma-separated integers) to the comment.
+	comments map[string]*descriptor.SourceCodeInfo_Location
+
+	// The full list of symbols that are exported,
+	// as a map from the exported object to its symbols.
+	// This is used for supporting public imports.
+	exported map[Object][]symbol
+
+	importPath  GoImportPath  // Import path of this file's package.
+	packageName GoPackageName // Name of this file's Go package.
+
+	proto3 bool // whether to generate proto3 code for this file
+}
+
+// VarName is the variable name we'll use in the generated code to refer
+// to the compressed bytes of this descriptor. It is not exported, so
+// it is only valid inside the generated package.
+func (d *FileDescriptor) VarName() string {
+	h := sha256.Sum256([]byte(d.GetName()))
+	return fmt.Sprintf("fileDescriptor_%s", hex.EncodeToString(h[:8]))
+}
+
+// goPackageOption interprets the file's go_package option.
+// If there is no go_package, it returns ("", "", false).
+// If there's a simple name, it returns ("", pkg, true).
+// If the option implies an import path, it returns (impPath, pkg, true).
+func (d *FileDescriptor) goPackageOption() (impPath GoImportPath, pkg GoPackageName, ok bool) {
+	opt := d.GetOptions().GetGoPackage()
+	if opt == "" {
+		return "", "", false
+	}
+	// A semicolon-delimited suffix delimits the import path and package name.
+	sc := strings.Index(opt, ";")
+	if sc >= 0 {
+		return GoImportPath(opt[:sc]), cleanPackageName(opt[sc+1:]), true
+	}
+	// The presence of a slash implies there's an import path.
+	slash := strings.LastIndex(opt, "/")
+	if slash >= 0 {
+		return GoImportPath(opt), cleanPackageName(opt[slash+1:]), true
+	}
+	return "", cleanPackageName(opt), true
+}
+
+// goFileName returns the output name for the generated Go file.
+func (d *FileDescriptor) goFileName(pathType pathType) string {
+	name := *d.Name
+	if ext := path.Ext(name); ext == ".proto" || ext == ".protodevel" {
+		name = name[:len(name)-len(ext)]
+	}
+	name += ".pb.go"
+
+	if pathType == pathTypeSourceRelative {
+		return name
+	}
+
+	// Does the file have a "go_package" option?
+	// If it does, it may override the filename.
+	if impPath, _, ok := d.goPackageOption(); ok && impPath != "" {
+		// Replace the existing dirname with the declared import path.
+		_, name = path.Split(name)
+		name = path.Join(string(impPath), name)
+		return name
+	}
+
+	return name
+}
+
+func (d *FileDescriptor) addExport(obj Object, sym symbol) {
+	d.exported[obj] = append(d.exported[obj], sym)
+}
+
+// symbol is an interface representing an exported Go symbol.
+type symbol interface {
+	// GenerateAlias should generate an appropriate alias
+	// for the symbol from the named package.
+	GenerateAlias(g *Generator, filename string, pkg GoPackageName)
+}
+
+type messageSymbol struct {
+	sym                         string
+	hasExtensions, isMessageSet bool
+	oneofTypes                  []string
+}
+
+type getterSymbol struct {
+	name     string
+	typ      string
+	typeName string // canonical name in proto world; empty for proto.Message and similar
+	genType  bool   // whether typ contains a generated type (message/group/enum)
+}
+
+func (ms *messageSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) {
+	g.P("// ", ms.sym, " from public import ", filename)
+	g.P("type ", ms.sym, " = ", pkg, ".", ms.sym)
+	for _, name := range ms.oneofTypes {
+		g.P("type ", name, " = ", pkg, ".", name)
+	}
+}
+
+type enumSymbol struct {
+	name   string
+	proto3 bool // Whether this came from a proto3 file.
+}
+
+func (es enumSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) {
+	s := es.name
+	g.P("// ", s, " from public import ", filename)
+	g.P("type ", s, " = ", pkg, ".", s)
+	g.P("var ", s, "_name = ", pkg, ".", s, "_name")
+	g.P("var ", s, "_value = ", pkg, ".", s, "_value")
+}
+
+type constOrVarSymbol struct {
+	sym  string
+	typ  string // either "const" or "var"
+	cast string // if non-empty, a type cast is required (used for enums)
+}
+
+func (cs constOrVarSymbol) GenerateAlias(g *Generator, filename string, pkg GoPackageName) {
+	v := string(pkg) + "." + cs.sym
+	if cs.cast != "" {
+		v = cs.cast + "(" + v + ")"
+	}
+	g.P(cs.typ, " ", cs.sym, " = ", v)
+}
+
+// Object is an interface abstracting the abilities shared by enums, messages, extensions and imported objects.
+type Object interface {
+	GoImportPath() GoImportPath
+	TypeName() []string
+	File() *FileDescriptor
+}
+
+// Generator is the type whose methods generate the output, stored in the associated response structure.
+type Generator struct {
+	*bytes.Buffer
+
+	Request  *plugin.CodeGeneratorRequest  // The input.
+	Response *plugin.CodeGeneratorResponse // The output.
+
+	Param             map[string]string // Command-line parameters.
+	PackageImportPath string            // Go import path of the package we're generating code for
+	ImportPrefix      string            // String to prefix to imported package file names.
+	ImportMap         map[string]string // Mapping from .proto file name to import path
+
+	Pkg map[string]string // The names under which we import support packages
+
+	outputImportPath GoImportPath                   // Package we're generating code for.
+	allFiles         []*FileDescriptor              // All files in the tree
+	allFilesByName   map[string]*FileDescriptor     // All files by filename.
+	genFiles         []*FileDescriptor              // Those files we will generate output for.
+	file             *FileDescriptor                // The file we are compiling now.
+	packageNames     map[GoImportPath]GoPackageName // Imported package names in the current file.
+	usedPackages     map[GoImportPath]bool          // Packages used in current file.
+	usedPackageNames map[GoPackageName]bool         // Package names used in the current file.
+	addedImports     map[GoImportPath]bool          // Additional imports to emit.`
+	typeNameToObject map[string]Object              // Key is a fully-qualified name in input syntax.
+	init             []string                       // Lines to emit in the init function.
+	indent           string
+	pathType         pathType // How to generate output filenames.
+	writeOutput      bool
+	annotateCode     bool                                       // whether to store annotations
+	annotations      []*descriptor.GeneratedCodeInfo_Annotation // annotations to store
+
+	customImports  []string
+	writtenImports map[string]bool // For de-duplicating written imports
+}
+
+type pathType int
+
+const (
+	pathTypeImport pathType = iota
+	pathTypeSourceRelative
+)
+
+// New creates a new generator and allocates the request and response protobufs.
+func New() *Generator {
+	g := new(Generator)
+	g.Buffer = new(bytes.Buffer)
+	g.Request = new(plugin.CodeGeneratorRequest)
+	g.Response = new(plugin.CodeGeneratorResponse)
+	g.writtenImports = make(map[string]bool)
+	g.addedImports = make(map[GoImportPath]bool)
+	return g
+}
+
+// Error reports a problem, including an error, and exits the program.
+func (g *Generator) Error(err error, msgs ...string) {
+	s := strings.Join(msgs, " ") + ":" + err.Error()
+	log.Print("protoc-gen-gogo: error:", s)
+	os.Exit(1)
+}
+
+// Fail reports a problem and exits the program.
+func (g *Generator) Fail(msgs ...string) {
+	s := strings.Join(msgs, " ")
+	log.Print("protoc-gen-gogo: error:", s)
+	os.Exit(1)
+}
+
+// CommandLineParameters breaks the comma-separated list of key=value pairs
+// in the parameter (a member of the request protobuf) into a key/value map.
+// It then sets file name mappings defined by those entries.
+func (g *Generator) CommandLineParameters(parameter string) {
+	g.Param = make(map[string]string)
+	for _, p := range strings.Split(parameter, ",") {
+		if i := strings.Index(p, "="); i < 0 {
+			g.Param[p] = ""
+		} else {
+			g.Param[p[0:i]] = p[i+1:]
+		}
+	}
+
+	g.ImportMap = make(map[string]string)
+	pluginList := "none" // Default list of plugin names to enable (empty means all).
+	for k, v := range g.Param {
+		switch k {
+		case "import_prefix":
+			g.ImportPrefix = v
+		case "import_path":
+			g.PackageImportPath = v
+		case "paths":
+			switch v {
+			case "import":
+				g.pathType = pathTypeImport
+			case "source_relative":
+				g.pathType = pathTypeSourceRelative
+			default:
+				g.Fail(fmt.Sprintf(`Unknown path type %q: want "import" or "source_relative".`, v))
+			}
+		case "plugins":
+			pluginList = v
+		case "annotate_code":
+			if v == "true" {
+				g.annotateCode = true
+			}
+		default:
+			if len(k) > 0 && k[0] == 'M' {
+				g.ImportMap[k[1:]] = v
+			}
+		}
+	}
+	if pluginList == "" {
+		return
+	}
+	if pluginList == "none" {
+		pluginList = ""
+	}
+	gogoPluginNames := []string{"unmarshal", "unsafeunmarshaler", "union", "stringer", "size", "protosizer", "populate", "marshalto", "unsafemarshaler", "gostring", "face", "equal", "enumstringer", "embedcheck", "description", "defaultcheck", "oneofcheck", "compare"}
+	pluginList = strings.Join(append(gogoPluginNames, pluginList), "+")
+	if pluginList != "" {
+		// Amend the set of plugins.
+		enabled := make(map[string]bool)
+		for _, name := range strings.Split(pluginList, "+") {
+			enabled[name] = true
+		}
+		var nplugins pluginSlice
+		for _, p := range plugins {
+			if enabled[p.Name()] {
+				nplugins = append(nplugins, p)
+			}
+		}
+		sort.Sort(nplugins)
+		plugins = nplugins
+	}
+}
+
+// DefaultPackageName returns the package name printed for the object.
+// If its file is in a different package, it returns the package name we're using for this file, plus ".".
+// Otherwise it returns the empty string.
+func (g *Generator) DefaultPackageName(obj Object) string {
+	importPath := obj.GoImportPath()
+	if importPath == g.outputImportPath {
+		return ""
+	}
+	return string(g.GoPackageName(importPath)) + "."
+}
+
+// GoPackageName returns the name used for a package.
+func (g *Generator) GoPackageName(importPath GoImportPath) GoPackageName {
+	if name, ok := g.packageNames[importPath]; ok {
+		return name
+	}
+	name := cleanPackageName(baseName(string(importPath)))
+	for i, orig := 1, name; g.usedPackageNames[name] || isGoPredeclaredIdentifier[string(name)]; i++ {
+		name = orig + GoPackageName(strconv.Itoa(i))
+	}
+	if g.packageNames == nil {
+		g.packageNames = make(map[GoImportPath]GoPackageName)
+	}
+	g.packageNames[importPath] = name
+	if g.usedPackageNames == nil {
+		g.usedPackageNames = make(map[GoPackageName]bool)
+	}
+	g.usedPackageNames[name] = true
+	return name
+}
+
+// AddImport adds a package to the generated file's import section.
+// It returns the name used for the package.
+func (g *Generator) AddImport(importPath GoImportPath) GoPackageName {
+	g.addedImports[importPath] = true
+	return g.GoPackageName(importPath)
+}
+
+var globalPackageNames = map[GoPackageName]bool{
+	"fmt":   true,
+	"math":  true,
+	"proto": true,
+}
+
+// Create and remember a guaranteed unique package name. Pkg is the candidate name.
+// The FileDescriptor parameter is unused.
+func RegisterUniquePackageName(pkg string, f *FileDescriptor) string {
+	name := cleanPackageName(pkg)
+	for i, orig := 1, name; globalPackageNames[name]; i++ {
+		name = orig + GoPackageName(strconv.Itoa(i))
+	}
+	globalPackageNames[name] = true
+	return string(name)
+}
+
+var isGoKeyword = map[string]bool{
+	"break":       true,
+	"case":        true,
+	"chan":        true,
+	"const":       true,
+	"continue":    true,
+	"default":     true,
+	"else":        true,
+	"defer":       true,
+	"fallthrough": true,
+	"for":         true,
+	"func":        true,
+	"go":          true,
+	"goto":        true,
+	"if":          true,
+	"import":      true,
+	"interface":   true,
+	"map":         true,
+	"package":     true,
+	"range":       true,
+	"return":      true,
+	"select":      true,
+	"struct":      true,
+	"switch":      true,
+	"type":        true,
+	"var":         true,
+}
+
+var isGoPredeclaredIdentifier = map[string]bool{
+	"append":     true,
+	"bool":       true,
+	"byte":       true,
+	"cap":        true,
+	"close":      true,
+	"complex":    true,
+	"complex128": true,
+	"complex64":  true,
+	"copy":       true,
+	"delete":     true,
+	"error":      true,
+	"false":      true,
+	"float32":    true,
+	"float64":    true,
+	"imag":       true,
+	"int":        true,
+	"int16":      true,
+	"int32":      true,
+	"int64":      true,
+	"int8":       true,
+	"iota":       true,
+	"len":        true,
+	"make":       true,
+	"new":        true,
+	"nil":        true,
+	"panic":      true,
+	"print":      true,
+	"println":    true,
+	"real":       true,
+	"recover":    true,
+	"rune":       true,
+	"string":     true,
+	"true":       true,
+	"uint":       true,
+	"uint16":     true,
+	"uint32":     true,
+	"uint64":     true,
+	"uint8":      true,
+	"uintptr":    true,
+}
+
+func cleanPackageName(name string) GoPackageName {
+	name = strings.Map(badToUnderscore, name)
+	// Identifier must not be keyword: insert _.
+	if isGoKeyword[name] {
+		name = "_" + name
+	}
+	// Identifier must not begin with digit: insert _.
+	if r, _ := utf8.DecodeRuneInString(name); unicode.IsDigit(r) {
+		name = "_" + name
+	}
+	return GoPackageName(name)
+}
+
+// defaultGoPackage returns the package name to use,
+// derived from the import path of the package we're building code for.
+func (g *Generator) defaultGoPackage() GoPackageName {
+	p := g.PackageImportPath
+	if i := strings.LastIndex(p, "/"); i >= 0 {
+		p = p[i+1:]
+	}
+	return cleanPackageName(p)
+}
+
+// SetPackageNames sets the package name for this run.
+// The package name must agree across all files being generated.
+// It also defines unique package names for all imported files.
+func (g *Generator) SetPackageNames() {
+	g.outputImportPath = g.genFiles[0].importPath
+
+	defaultPackageNames := make(map[GoImportPath]GoPackageName)
+	for _, f := range g.genFiles {
+		if _, p, ok := f.goPackageOption(); ok {
+			defaultPackageNames[f.importPath] = p
+		}
+	}
+	for _, f := range g.genFiles {
+		if _, p, ok := f.goPackageOption(); ok {
+			// Source file: option go_package = "quux/bar";
+			f.packageName = p
+		} else if p, ok := defaultPackageNames[f.importPath]; ok {
+			// A go_package option in another file in the same package.
+			//
+			// This is a poor choice in general, since every source file should
+			// contain a go_package option. Supported mainly for historical
+			// compatibility.
+			f.packageName = p
+		} else if p := g.defaultGoPackage(); p != "" {
+			// Command-line: import_path=quux/bar.
+			//
+			// The import_path flag sets a package name for files which don't
+			// contain a go_package option.
+			f.packageName = p
+		} else if p := f.GetPackage(); p != "" {
+			// Source file: package quux.bar;
+			f.packageName = cleanPackageName(p)
+		} else {
+			// Source filename.
+			f.packageName = cleanPackageName(baseName(f.GetName()))
+		}
+	}
+
+	// Check that all files have a consistent package name and import path.
+	for _, f := range g.genFiles[1:] {
+		if a, b := g.genFiles[0].importPath, f.importPath; a != b {
+			g.Fail(fmt.Sprintf("inconsistent package import paths: %v, %v", a, b))
+		}
+		if a, b := g.genFiles[0].packageName, f.packageName; a != b {
+			g.Fail(fmt.Sprintf("inconsistent package names: %v, %v", a, b))
+		}
+	}
+
+	// Names of support packages. These never vary (if there are conflicts,
+	// we rename the conflicting package), so this could be removed someday.
+	g.Pkg = map[string]string{
+		"fmt":          "fmt",
+		"math":         "math",
+		"proto":        "proto",
+		"golang_proto": "golang_proto",
+	}
+}
+
+// WrapTypes walks the incoming data, wrapping DescriptorProtos, EnumDescriptorProtos
+// and FileDescriptorProtos into file-referenced objects within the Generator.
+// It also creates the list of files to generate and so should be called before GenerateAllFiles.
+func (g *Generator) WrapTypes() {
+	g.allFiles = make([]*FileDescriptor, 0, len(g.Request.ProtoFile))
+	g.allFilesByName = make(map[string]*FileDescriptor, len(g.allFiles))
+	genFileNames := make(map[string]bool)
+	for _, n := range g.Request.FileToGenerate {
+		genFileNames[n] = true
+	}
+	for _, f := range g.Request.ProtoFile {
+		fd := &FileDescriptor{
+			FileDescriptorProto: f,
+			exported:            make(map[Object][]symbol),
+			proto3:              fileIsProto3(f),
+		}
+		// The import path may be set in a number of ways.
+		if substitution, ok := g.ImportMap[f.GetName()]; ok {
+			// Command-line: M=foo.proto=quux/bar.
+			//
+			// Explicit mapping of source file to import path.
+			fd.importPath = GoImportPath(substitution)
+		} else if genFileNames[f.GetName()] && g.PackageImportPath != "" {
+			// Command-line: import_path=quux/bar.
+			//
+			// The import_path flag sets the import path for every file that
+			// we generate code for.
+			fd.importPath = GoImportPath(g.PackageImportPath)
+		} else if p, _, _ := fd.goPackageOption(); p != "" {
+			// Source file: option go_package = "quux/bar";
+			//
+			// The go_package option sets the import path. Most users should use this.
+			fd.importPath = p
+		} else {
+			// Source filename.
+			//
+			// Last resort when nothing else is available.
+			fd.importPath = GoImportPath(path.Dir(f.GetName()))
+		}
+		// We must wrap the descriptors before we wrap the enums
+		fd.desc = wrapDescriptors(fd)
+		g.buildNestedDescriptors(fd.desc)
+		fd.enum = wrapEnumDescriptors(fd, fd.desc)
+		g.buildNestedEnums(fd.desc, fd.enum)
+		fd.ext = wrapExtensions(fd)
+		extractComments(fd)
+		g.allFiles = append(g.allFiles, fd)
+		g.allFilesByName[f.GetName()] = fd
+	}
+	for _, fd := range g.allFiles {
+		fd.imp = wrapImported(fd, g)
+	}
+
+	g.genFiles = make([]*FileDescriptor, 0, len(g.Request.FileToGenerate))
+	for _, fileName := range g.Request.FileToGenerate {
+		fd := g.allFilesByName[fileName]
+		if fd == nil {
+			g.Fail("could not find file named", fileName)
+		}
+		g.genFiles = append(g.genFiles, fd)
+	}
+}
+
+// Scan the descriptors in this file.  For each one, build the slice of nested descriptors
+func (g *Generator) buildNestedDescriptors(descs []*Descriptor) {
+	for _, desc := range descs {
+		if len(desc.NestedType) != 0 {
+			for _, nest := range descs {
+				if nest.parent == desc {
+					desc.nested = append(desc.nested, nest)
+				}
+			}
+			if len(desc.nested) != len(desc.NestedType) {
+				g.Fail("internal error: nesting failure for", desc.GetName())
+			}
+		}
+	}
+}
+
+func (g *Generator) buildNestedEnums(descs []*Descriptor, enums []*EnumDescriptor) {
+	for _, desc := range descs {
+		if len(desc.EnumType) != 0 {
+			for _, enum := range enums {
+				if enum.parent == desc {
+					desc.enums = append(desc.enums, enum)
+				}
+			}
+			if len(desc.enums) != len(desc.EnumType) {
+				g.Fail("internal error: enum nesting failure for", desc.GetName())
+			}
+		}
+	}
+}
+
+// Construct the Descriptor
+func newDescriptor(desc *descriptor.DescriptorProto, parent *Descriptor, file *FileDescriptor, index int) *Descriptor {
+	d := &Descriptor{
+		common:          common{file},
+		DescriptorProto: desc,
+		parent:          parent,
+		index:           index,
+	}
+	if parent == nil {
+		d.path = fmt.Sprintf("%d,%d", messagePath, index)
+	} else {
+		d.path = fmt.Sprintf("%s,%d,%d", parent.path, messageMessagePath, index)
+	}
+
+	// The only way to distinguish a group from a message is whether
+	// the containing message has a TYPE_GROUP field that matches.
+	if parent != nil {
+		parts := d.TypeName()
+		if file.Package != nil {
+			parts = append([]string{*file.Package}, parts...)
+		}
+		exp := "." + strings.Join(parts, ".")
+		for _, field := range parent.Field {
+			if field.GetType() == descriptor.FieldDescriptorProto_TYPE_GROUP && field.GetTypeName() == exp {
+				d.group = true
+				break
+			}
+		}
+	}
+
+	for _, field := range desc.Extension {
+		d.ext = append(d.ext, &ExtensionDescriptor{common{file}, field, d})
+	}
+
+	return d
+}
+
+// Return a slice of all the Descriptors defined within this file
+func wrapDescriptors(file *FileDescriptor) []*Descriptor {
+	sl := make([]*Descriptor, 0, len(file.MessageType)+10)
+	for i, desc := range file.MessageType {
+		sl = wrapThisDescriptor(sl, desc, nil, file, i)
+	}
+	return sl
+}
+
+// Wrap this Descriptor, recursively
+func wrapThisDescriptor(sl []*Descriptor, desc *descriptor.DescriptorProto, parent *Descriptor, file *FileDescriptor, index int) []*Descriptor {
+	sl = append(sl, newDescriptor(desc, parent, file, index))
+	me := sl[len(sl)-1]
+	for i, nested := range desc.NestedType {
+		sl = wrapThisDescriptor(sl, nested, me, file, i)
+	}
+	return sl
+}
+
+// Construct the EnumDescriptor
+func newEnumDescriptor(desc *descriptor.EnumDescriptorProto, parent *Descriptor, file *FileDescriptor, index int) *EnumDescriptor {
+	ed := &EnumDescriptor{
+		common:              common{file},
+		EnumDescriptorProto: desc,
+		parent:              parent,
+		index:               index,
+	}
+	if parent == nil {
+		ed.path = fmt.Sprintf("%d,%d", enumPath, index)
+	} else {
+		ed.path = fmt.Sprintf("%s,%d,%d", parent.path, messageEnumPath, index)
+	}
+	return ed
+}
+
+// Return a slice of all the EnumDescriptors defined within this file
+func wrapEnumDescriptors(file *FileDescriptor, descs []*Descriptor) []*EnumDescriptor {
+	sl := make([]*EnumDescriptor, 0, len(file.EnumType)+10)
+	// Top-level enums.
+	for i, enum := range file.EnumType {
+		sl = append(sl, newEnumDescriptor(enum, nil, file, i))
+	}
+	// Enums within messages. Enums within embedded messages appear in the outer-most message.
+	for _, nested := range descs {
+		for i, enum := range nested.EnumType {
+			sl = append(sl, newEnumDescriptor(enum, nested, file, i))
+		}
+	}
+	return sl
+}
+
+// Return a slice of all the top-level ExtensionDescriptors defined within this file.
+func wrapExtensions(file *FileDescriptor) []*ExtensionDescriptor {
+	var sl []*ExtensionDescriptor
+	for _, field := range file.Extension {
+		sl = append(sl, &ExtensionDescriptor{common{file}, field, nil})
+	}
+	return sl
+}
+
+// Return a slice of all the types that are publicly imported into this file.
+func wrapImported(file *FileDescriptor, g *Generator) (sl []*ImportedDescriptor) {
+	for _, index := range file.PublicDependency {
+		df := g.fileByName(file.Dependency[index])
+		for _, d := range df.desc {
+			if d.GetOptions().GetMapEntry() {
+				continue
+			}
+			sl = append(sl, &ImportedDescriptor{common{file}, d})
+		}
+		for _, e := range df.enum {
+			sl = append(sl, &ImportedDescriptor{common{file}, e})
+		}
+		for _, ext := range df.ext {
+			sl = append(sl, &ImportedDescriptor{common{file}, ext})
+		}
+	}
+	return
+}
+
+func extractComments(file *FileDescriptor) {
+	file.comments = make(map[string]*descriptor.SourceCodeInfo_Location)
+	for _, loc := range file.GetSourceCodeInfo().GetLocation() {
+		if loc.LeadingComments == nil {
+			continue
+		}
+		var p []string
+		for _, n := range loc.Path {
+			p = append(p, strconv.Itoa(int(n)))
+		}
+		file.comments[strings.Join(p, ",")] = loc
+	}
+}
+
+// BuildTypeNameMap builds the map from fully qualified type names to objects.
+// The key names for the map come from the input data, which puts a period at the beginning.
+// It should be called after SetPackageNames and before GenerateAllFiles.
+func (g *Generator) BuildTypeNameMap() {
+	g.typeNameToObject = make(map[string]Object)
+	for _, f := range g.allFiles {
+		// The names in this loop are defined by the proto world, not us, so the
+		// package name may be empty.  If so, the dotted package name of X will
+		// be ".X"; otherwise it will be ".pkg.X".
+		dottedPkg := "." + f.GetPackage()
+		if dottedPkg != "." {
+			dottedPkg += "."
+		}
+		for _, enum := range f.enum {
+			name := dottedPkg + dottedSlice(enum.TypeName())
+			g.typeNameToObject[name] = enum
+		}
+		for _, desc := range f.desc {
+			name := dottedPkg + dottedSlice(desc.TypeName())
+			g.typeNameToObject[name] = desc
+		}
+	}
+}
+
+// ObjectNamed, given a fully-qualified input type name as it appears in the input data,
+// returns the descriptor for the message or enum with that name.
+func (g *Generator) ObjectNamed(typeName string) Object {
+	o, ok := g.typeNameToObject[typeName]
+	if !ok {
+		g.Fail("can't find object with type", typeName)
+	}
+	return o
+}
+
+// AnnotatedAtoms is a list of atoms (as consumed by P) that records the file name and proto AST path from which they originated.
+type AnnotatedAtoms struct {
+	source string
+	path   string
+	atoms  []interface{}
+}
+
+// Annotate records the file name and proto AST path of a list of atoms
+// so that a later call to P can emit a link from each atom to its origin.
+func Annotate(file *FileDescriptor, path string, atoms ...interface{}) *AnnotatedAtoms {
+	return &AnnotatedAtoms{source: *file.Name, path: path, atoms: atoms}
+}
+
+// printAtom prints the (atomic, non-annotation) argument to the generated output.
+func (g *Generator) printAtom(v interface{}) {
+	switch v := v.(type) {
+	case string:
+		g.WriteString(v)
+	case *string:
+		g.WriteString(*v)
+	case bool:
+		fmt.Fprint(g, v)
+	case *bool:
+		fmt.Fprint(g, *v)
+	case int:
+		fmt.Fprint(g, v)
+	case *int32:
+		fmt.Fprint(g, *v)
+	case *int64:
+		fmt.Fprint(g, *v)
+	case float64:
+		fmt.Fprint(g, v)
+	case *float64:
+		fmt.Fprint(g, *v)
+	case GoPackageName:
+		g.WriteString(string(v))
+	case GoImportPath:
+		g.WriteString(strconv.Quote(string(v)))
+	default:
+		g.Fail(fmt.Sprintf("unknown type in printer: %T", v))
+	}
+}
+
+// P prints the arguments to the generated output.  It handles strings and int32s, plus
+// handling indirections because they may be *string, etc.  Any inputs of type AnnotatedAtoms may emit
+// annotations in a .meta file in addition to outputting the atoms themselves (if g.annotateCode
+// is true).
+func (g *Generator) P(str ...interface{}) {
+	if !g.writeOutput {
+		return
+	}
+	g.WriteString(g.indent)
+	for _, v := range str {
+		switch v := v.(type) {
+		case *AnnotatedAtoms:
+			begin := int32(g.Len())
+			for _, v := range v.atoms {
+				g.printAtom(v)
+			}
+			if g.annotateCode {
+				end := int32(g.Len())
+				var path []int32
+				for _, token := range strings.Split(v.path, ",") {
+					val, err := strconv.ParseInt(token, 10, 32)
+					if err != nil {
+						g.Fail("could not parse proto AST path: ", err.Error())
+					}
+					path = append(path, int32(val))
+				}
+				g.annotations = append(g.annotations, &descriptor.GeneratedCodeInfo_Annotation{
+					Path:       path,
+					SourceFile: &v.source,
+					Begin:      &begin,
+					End:        &end,
+				})
+			}
+		default:
+			g.printAtom(v)
+		}
+	}
+	g.WriteByte('\n')
+}
+
+// addInitf stores the given statement to be printed inside the file's init function.
+// The statement is given as a format specifier and arguments.
+func (g *Generator) addInitf(stmt string, a ...interface{}) {
+	g.init = append(g.init, fmt.Sprintf(stmt, a...))
+}
+
+func (g *Generator) PrintImport(alias GoPackageName, pkg GoImportPath) {
+	statement := string(alias) + " " + strconv.Quote(string(pkg))
+	if g.writtenImports[statement] {
+		return
+	}
+	g.P(statement)
+	g.writtenImports[statement] = true
+}
+
+// In Indents the output one tab stop.
+func (g *Generator) In() { g.indent += "\t" }
+
+// Out unindents the output one tab stop.
+func (g *Generator) Out() {
+	if len(g.indent) > 0 {
+		g.indent = g.indent[1:]
+	}
+}
+
+// GenerateAllFiles generates the output for all the files we're outputting.
+func (g *Generator) GenerateAllFiles() {
+	// Initialize the plugins
+	for _, p := range plugins {
+		p.Init(g)
+	}
+	// Generate the output. The generator runs for every file, even the files
+	// that we don't generate output for, so that we can collate the full list
+	// of exported symbols to support public imports.
+	genFileMap := make(map[*FileDescriptor]bool, len(g.genFiles))
+	for _, file := range g.genFiles {
+		genFileMap[file] = true
+	}
+	for _, file := range g.allFiles {
+		g.Reset()
+		g.annotations = nil
+		g.writeOutput = genFileMap[file]
+		g.generate(file)
+		if !g.writeOutput {
+			continue
+		}
+		fname := file.goFileName(g.pathType)
+		g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{
+			Name:    proto.String(fname),
+			Content: proto.String(g.String()),
+		})
+		if g.annotateCode {
+			// Store the generated code annotations in text, as the protoc plugin protocol requires that
+			// strings contain valid UTF-8.
+			g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{
+				Name:    proto.String(file.goFileName(g.pathType) + ".meta"),
+				Content: proto.String(proto.CompactTextString(&descriptor.GeneratedCodeInfo{Annotation: g.annotations})),
+			})
+		}
+	}
+}
+
+// Run all the plugins associated with the file.
+func (g *Generator) runPlugins(file *FileDescriptor) {
+	for _, p := range plugins {
+		p.Generate(file)
+	}
+}
+
+// Fill the response protocol buffer with the generated output for all the files we're
+// supposed to generate.
+func (g *Generator) generate(file *FileDescriptor) {
+	g.customImports = make([]string, 0)
+	g.file = file
+	g.usedPackages = make(map[GoImportPath]bool)
+	g.packageNames = make(map[GoImportPath]GoPackageName)
+	g.usedPackageNames = make(map[GoPackageName]bool)
+	g.addedImports = make(map[GoImportPath]bool)
+	for name := range globalPackageNames {
+		g.usedPackageNames[name] = true
+	}
+
+	g.P("// This is a compile-time assertion to ensure that this generated file")
+	g.P("// is compatible with the proto package it is being compiled against.")
+	g.P("// A compilation error at this line likely means your copy of the")
+	g.P("// proto package needs to be updated.")
+	if gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		g.P("const _ = ", g.Pkg["proto"], ".GoGoProtoPackageIsVersion", generatedCodeVersion, " // please upgrade the proto package")
+	} else {
+		g.P("const _ = ", g.Pkg["proto"], ".ProtoPackageIsVersion", generatedCodeVersion, " // please upgrade the proto package")
+	}
+	g.P()
+	// Reset on each file
+	g.writtenImports = make(map[string]bool)
+	for _, td := range g.file.imp {
+		g.generateImported(td)
+	}
+	for _, enum := range g.file.enum {
+		g.generateEnum(enum)
+	}
+	for _, desc := range g.file.desc {
+		// Don't generate virtual messages for maps.
+		if desc.GetOptions().GetMapEntry() {
+			continue
+		}
+		g.generateMessage(desc)
+	}
+	for _, ext := range g.file.ext {
+		g.generateExtension(ext)
+	}
+	g.generateInitFunction()
+	g.generateFileDescriptor(file)
+
+	// Run the plugins before the imports so we know which imports are necessary.
+	g.runPlugins(file)
+
+	// Generate header and imports last, though they appear first in the output.
+	rem := g.Buffer
+	remAnno := g.annotations
+	g.Buffer = new(bytes.Buffer)
+	g.annotations = nil
+	g.generateHeader()
+	g.generateImports()
+	if !g.writeOutput {
+		return
+	}
+	// Adjust the offsets for annotations displaced by the header and imports.
+	for _, anno := range remAnno {
+		*anno.Begin += int32(g.Len())
+		*anno.End += int32(g.Len())
+		g.annotations = append(g.annotations, anno)
+	}
+	g.Write(rem.Bytes())
+
+	// Reformat generated code and patch annotation locations.
+	fset := token.NewFileSet()
+	original := g.Bytes()
+	if g.annotateCode {
+		// make a copy independent of g; we'll need it after Reset.
+		original = append([]byte(nil), original...)
+	}
+	fileAST, err := parser.ParseFile(fset, "", original, parser.ParseComments)
+	if err != nil {
+		// Print out the bad code with line numbers.
+		// This should never happen in practice, but it can while changing generated code,
+		// so consider this a debugging aid.
+		var src bytes.Buffer
+		s := bufio.NewScanner(bytes.NewReader(original))
+		for line := 1; s.Scan(); line++ {
+			fmt.Fprintf(&src, "%5d\t%s\n", line, s.Bytes())
+		}
+		if serr := s.Err(); serr != nil {
+			g.Fail("bad Go source code was generated:", err.Error(), "\n"+string(original))
+		} else {
+			g.Fail("bad Go source code was generated:", err.Error(), "\n"+src.String())
+		}
+	}
+	ast.SortImports(fset, fileAST)
+	g.Reset()
+	err = (&printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}).Fprint(g, fset, fileAST)
+	if err != nil {
+		g.Fail("generated Go source code could not be reformatted:", err.Error())
+	}
+	if g.annotateCode {
+		m, err := remap.Compute(original, g.Bytes())
+		if err != nil {
+			g.Fail("formatted generated Go source code could not be mapped back to the original code:", err.Error())
+		}
+		for _, anno := range g.annotations {
+			new, ok := m.Find(int(*anno.Begin), int(*anno.End))
+			if !ok {
+				g.Fail("span in formatted generated Go source code could not be mapped back to the original code")
+			}
+			*anno.Begin = int32(new.Pos)
+			*anno.End = int32(new.End)
+		}
+	}
+}
+
+// Generate the header, including package definition
+func (g *Generator) generateHeader() {
+	g.P("// Code generated by protoc-gen-gogo. DO NOT EDIT.")
+	if g.file.GetOptions().GetDeprecated() {
+		g.P("// ", *g.file.Name, " is a deprecated file.")
+	} else {
+		g.P("// source: ", *g.file.Name)
+	}
+	g.P()
+	g.PrintComments(strconv.Itoa(packagePath))
+	g.P()
+	g.P("package ", g.file.packageName)
+	g.P()
+}
+
+// deprecationComment is the standard comment added to deprecated
+// messages, fields, enums, and enum values.
+var deprecationComment = "// Deprecated: Do not use."
+
+// PrintComments prints any comments from the source .proto file.
+// The path is a comma-separated list of integers.
+// It returns an indication of whether any comments were printed.
+// See descriptor.proto for its format.
+func (g *Generator) PrintComments(path string) bool {
+	if !g.writeOutput {
+		return false
+	}
+	if c, ok := g.makeComments(path); ok {
+		g.P(c)
+		return true
+	}
+	return false
+}
+
+// makeComments generates the comment string for the field, no "\n" at the end
+func (g *Generator) makeComments(path string) (string, bool) {
+	loc, ok := g.file.comments[path]
+	if !ok {
+		return "", false
+	}
+	w := new(bytes.Buffer)
+	nl := ""
+	for _, line := range strings.Split(strings.TrimSuffix(loc.GetLeadingComments(), "\n"), "\n") {
+		fmt.Fprintf(w, "%s//%s", nl, line)
+		nl = "\n"
+	}
+	return w.String(), true
+}
+
+// Comments returns any comments from the source .proto file and empty string if comments not found.
+// The path is a comma-separated list of intergers.
+// See descriptor.proto for its format.
+func (g *Generator) Comments(path string) string {
+	loc, ok := g.file.comments[path]
+	if !ok {
+		return ""
+	}
+	text := strings.TrimSuffix(loc.GetLeadingComments(), "\n")
+	return text
+}
+
+func (g *Generator) fileByName(filename string) *FileDescriptor {
+	return g.allFilesByName[filename]
+}
+
+// weak returns whether the ith import of the current file is a weak import.
+func (g *Generator) weak(i int32) bool {
+	for _, j := range g.file.WeakDependency {
+		if j == i {
+			return true
+		}
+	}
+	return false
+}
+
+// Generate the imports
+func (g *Generator) generateImports() {
+	imports := make(map[GoImportPath]GoPackageName)
+	for i, s := range g.file.Dependency {
+		fd := g.fileByName(s)
+		importPath := fd.importPath
+		// Do not import our own package.
+		if importPath == g.file.importPath {
+			continue
+		}
+		// Do not import weak imports.
+		if g.weak(int32(i)) {
+			continue
+		}
+		// Do not import a package twice.
+		if _, ok := imports[importPath]; ok {
+			continue
+		}
+		// We need to import all the dependencies, even if we don't reference them,
+		// because other code and tools depend on having the full transitive closure
+		// of protocol buffer types in the binary.
+		packageName := g.GoPackageName(importPath)
+		if _, ok := g.usedPackages[importPath]; !ok {
+			packageName = "_"
+		}
+		imports[importPath] = packageName
+	}
+	for importPath := range g.addedImports {
+		imports[importPath] = g.GoPackageName(importPath)
+	}
+	// We almost always need a proto import.  Rather than computing when we
+	// do, which is tricky when there's a plugin, just import it and
+	// reference it later. The same argument applies to the fmt and math packages.
+	g.P("import (")
+	g.PrintImport(GoPackageName(g.Pkg["fmt"]), "fmt")
+	g.PrintImport(GoPackageName(g.Pkg["math"]), "math")
+	if gogoproto.ImportsGoGoProto(g.file.FileDescriptorProto) {
+		g.PrintImport(GoPackageName(g.Pkg["proto"]), GoImportPath(g.ImportPrefix)+GoImportPath("github.com/gogo/protobuf/proto"))
+		if gogoproto.RegistersGolangProto(g.file.FileDescriptorProto) {
+			g.PrintImport(GoPackageName(g.Pkg["golang_proto"]), GoImportPath(g.ImportPrefix)+GoImportPath("github.com/golang/protobuf/proto"))
+		}
+	} else {
+		g.PrintImport(GoPackageName(g.Pkg["proto"]), GoImportPath(g.ImportPrefix)+GoImportPath("github.com/golang/protobuf/proto"))
+	}
+	for importPath, packageName := range imports {
+		g.P(packageName, " ", GoImportPath(g.ImportPrefix)+importPath)
+	}
+	// Custom gogo imports
+	for _, s := range g.customImports {
+		s1 := strings.Map(badToUnderscore, s)
+		g.PrintImport(GoPackageName(s1), GoImportPath(s))
+	}
+	// gogo plugin imports
+	// TODO: may need to worry about uniqueness across plugins and could change this
+	// to use the `addedImports` technique
+	for _, p := range plugins {
+		p.GenerateImports(g.file)
+	}
+	g.P(")")
+
+	g.P("// Reference imports to suppress errors if they are not otherwise used.")
+	g.P("var _ = ", g.Pkg["proto"], ".Marshal")
+	if gogoproto.ImportsGoGoProto(g.file.FileDescriptorProto) && gogoproto.RegistersGolangProto(g.file.FileDescriptorProto) {
+		g.P("var _ = ", g.Pkg["golang_proto"], ".Marshal")
+	}
+	g.P("var _ = ", g.Pkg["fmt"], ".Errorf")
+	g.P("var _ = ", g.Pkg["math"], ".Inf")
+	for _, cimport := range g.customImports {
+		if cimport == "time" {
+			g.P("var _ = time.Kitchen")
+			break
+		}
+	}
+	g.P()
+}
+
+func (g *Generator) generateImported(id *ImportedDescriptor) {
+	df := id.o.File()
+	filename := *df.Name
+	if df.importPath == g.file.importPath {
+		// Don't generate type aliases for files in the same Go package as this one.
+		return
+	}
+	if !supportTypeAliases {
+		g.Fail(fmt.Sprintf("%s: public imports require at least go1.9", filename))
+	}
+	g.usedPackages[df.importPath] = true
+
+	for _, sym := range df.exported[id.o] {
+		sym.GenerateAlias(g, filename, g.GoPackageName(df.importPath))
+	}
+	g.P()
+}
+
+// Generate the enum definitions for this EnumDescriptor.
+func (g *Generator) generateEnum(enum *EnumDescriptor) {
+	// The full type name
+	typeName := enum.alias()
+	// The full type name, CamelCased.
+	ccTypeName := CamelCaseSlice(typeName)
+	ccPrefix := enum.prefix()
+
+	deprecatedEnum := ""
+	if enum.GetOptions().GetDeprecated() {
+		deprecatedEnum = deprecationComment
+	}
+
+	g.PrintComments(enum.path)
+	if !gogoproto.EnabledGoEnumPrefix(enum.file.FileDescriptorProto, enum.EnumDescriptorProto) {
+		ccPrefix = ""
+	}
+
+	if gogoproto.HasEnumDecl(enum.file.FileDescriptorProto, enum.EnumDescriptorProto) {
+		g.P("type ", Annotate(enum.file, enum.path, ccTypeName), " int32", deprecatedEnum)
+		g.file.addExport(enum, enumSymbol{ccTypeName, enum.proto3()})
+		g.P("const (")
+		g.In()
+		for i, e := range enum.Value {
+			etorPath := fmt.Sprintf("%s,%d,%d", enum.path, enumValuePath, i)
+			g.PrintComments(etorPath)
+
+			deprecatedValue := ""
+			if e.GetOptions().GetDeprecated() {
+				deprecatedValue = deprecationComment
+			}
+			name := *e.Name
+			if gogoproto.IsEnumValueCustomName(e) {
+				name = gogoproto.GetEnumValueCustomName(e)
+			}
+			name = ccPrefix + name
+
+			g.P(Annotate(enum.file, etorPath, name), " ", ccTypeName, " = ", e.Number, " ", deprecatedValue)
+			g.file.addExport(enum, constOrVarSymbol{name, "const", ccTypeName})
+		}
+		g.Out()
+		g.P(")")
+	}
+	g.P()
+	g.P("var ", ccTypeName, "_name = map[int32]string{")
+	g.In()
+	generated := make(map[int32]bool) // avoid duplicate values
+	for _, e := range enum.Value {
+		duplicate := ""
+		if _, present := generated[*e.Number]; present {
+			duplicate = "// Duplicate value: "
+		}
+		g.P(duplicate, e.Number, ": ", strconv.Quote(*e.Name), ",")
+		generated[*e.Number] = true
+	}
+	g.Out()
+	g.P("}")
+	g.P()
+	g.P("var ", ccTypeName, "_value = map[string]int32{")
+	g.In()
+	for _, e := range enum.Value {
+		g.P(strconv.Quote(*e.Name), ": ", e.Number, ",")
+	}
+	g.Out()
+	g.P("}")
+	g.P()
+
+	if !enum.proto3() {
+		g.P("func (x ", ccTypeName, ") Enum() *", ccTypeName, " {")
+		g.In()
+		g.P("p := new(", ccTypeName, ")")
+		g.P("*p = x")
+		g.P("return p")
+		g.Out()
+		g.P("}")
+		g.P()
+	}
+
+	if gogoproto.IsGoEnumStringer(g.file.FileDescriptorProto, enum.EnumDescriptorProto) {
+		g.P("func (x ", ccTypeName, ") String() string {")
+		g.In()
+		g.P("return ", g.Pkg["proto"], ".EnumName(", ccTypeName, "_name, int32(x))")
+		g.Out()
+		g.P("}")
+		g.P()
+	}
+
+	if !enum.proto3() && !gogoproto.IsGoEnumStringer(g.file.FileDescriptorProto, enum.EnumDescriptorProto) {
+		g.P("func (x ", ccTypeName, ") MarshalJSON() ([]byte, error) {")
+		g.In()
+		g.P("return ", g.Pkg["proto"], ".MarshalJSONEnum(", ccTypeName, "_name, int32(x))")
+		g.Out()
+		g.P("}")
+		g.P()
+	}
+	if !enum.proto3() {
+		g.P("func (x *", ccTypeName, ") UnmarshalJSON(data []byte) error {")
+		g.In()
+		g.P("value, err := ", g.Pkg["proto"], ".UnmarshalJSONEnum(", ccTypeName, `_value, data, "`, ccTypeName, `")`)
+		g.P("if err != nil {")
+		g.In()
+		g.P("return err")
+		g.Out()
+		g.P("}")
+		g.P("*x = ", ccTypeName, "(value)")
+		g.P("return nil")
+		g.Out()
+		g.P("}")
+		g.P()
+	}
+
+	var indexes []string
+	for m := enum.parent; m != nil; m = m.parent {
+		// XXX: skip groups?
+		indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
+	}
+	indexes = append(indexes, strconv.Itoa(enum.index))
+	g.P("func (", ccTypeName, ") EnumDescriptor() ([]byte, []int) {")
+	g.In()
+	g.P("return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "}")
+	g.Out()
+	g.P("}")
+	g.P()
+	if enum.file.GetPackage() == "google.protobuf" && enum.GetName() == "NullValue" {
+		g.P("func (", ccTypeName, `) XXX_WellKnownType() string { return "`, enum.GetName(), `" }`)
+		g.P()
+	}
+
+	g.generateEnumRegistration(enum)
+}
+
+// The tag is a string like "varint,2,opt,name=fieldname,def=7" that
+// identifies details of the field for the protocol buffer marshaling and unmarshaling
+// code.  The fields are:
+//	wire encoding
+//	protocol tag number
+//	opt,req,rep for optional, required, or repeated
+//	packed whether the encoding is "packed" (optional; repeated primitives only)
+//	name= the original declared name
+//	enum= the name of the enum type if it is an enum-typed field.
+//	proto3 if this field is in a proto3 message
+//	def= string representation of the default value, if any.
+// The default value must be in a representation that can be used at run-time
+// to generate the default value. Thus bools become 0 and 1, for instance.
+func (g *Generator) goTag(message *Descriptor, field *descriptor.FieldDescriptorProto, wiretype string) string {
+	optrepreq := ""
+	switch {
+	case isOptional(field):
+		optrepreq = "opt"
+	case isRequired(field):
+		optrepreq = "req"
+	case isRepeated(field):
+		optrepreq = "rep"
+	}
+	var defaultValue string
+	if dv := field.DefaultValue; dv != nil { // set means an explicit default
+		defaultValue = *dv
+		// Some types need tweaking.
+		switch *field.Type {
+		case descriptor.FieldDescriptorProto_TYPE_BOOL:
+			if defaultValue == "true" {
+				defaultValue = "1"
+			} else {
+				defaultValue = "0"
+			}
+		case descriptor.FieldDescriptorProto_TYPE_STRING,
+			descriptor.FieldDescriptorProto_TYPE_BYTES:
+			// Nothing to do. Quoting is done for the whole tag.
+		case descriptor.FieldDescriptorProto_TYPE_ENUM:
+			// For enums we need to provide the integer constant.
+			obj := g.ObjectNamed(field.GetTypeName())
+			if id, ok := obj.(*ImportedDescriptor); ok {
+				// It is an enum that was publicly imported.
+				// We need the underlying type.
+				obj = id.o
+			}
+			enum, ok := obj.(*EnumDescriptor)
+			if !ok {
+				log.Printf("obj is a %T", obj)
+				if id, ok := obj.(*ImportedDescriptor); ok {
+					log.Printf("id.o is a %T", id.o)
+				}
+				g.Fail("unknown enum type", CamelCaseSlice(obj.TypeName()))
+			}
+			defaultValue = enum.integerValueAsString(defaultValue)
+		case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+			if def := defaultValue; def != "inf" && def != "-inf" && def != "nan" {
+				if f, err := strconv.ParseFloat(defaultValue, 32); err == nil {
+					defaultValue = fmt.Sprint(float32(f))
+				}
+			}
+		case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+			if def := defaultValue; def != "inf" && def != "-inf" && def != "nan" {
+				if f, err := strconv.ParseFloat(defaultValue, 64); err == nil {
+					defaultValue = fmt.Sprint(f)
+				}
+			}
+		}
+		defaultValue = ",def=" + defaultValue
+	}
+	enum := ""
+	if *field.Type == descriptor.FieldDescriptorProto_TYPE_ENUM {
+		// We avoid using obj.goPackageNamehe
+		// original (proto-world) package name.
+		obj := g.ObjectNamed(field.GetTypeName())
+		if id, ok := obj.(*ImportedDescriptor); ok {
+			obj = id.o
+		}
+		enum = ",enum="
+		if pkg := obj.File().GetPackage(); pkg != "" {
+			enum += pkg + "."
+		}
+		enum += CamelCaseSlice(obj.TypeName())
+	}
+	packed := ""
+	if (field.Options != nil && field.Options.GetPacked()) ||
+		// Per https://developers.google.com/protocol-buffers/docs/proto3#simple:
+		// "In proto3, repeated fields of scalar numeric types use packed encoding by default."
+		(message.proto3() && (field.Options == nil || field.Options.Packed == nil) &&
+			isRepeated(field) && IsScalar(field)) {
+		packed = ",packed"
+	}
+	fieldName := field.GetName()
+	name := fieldName
+	if *field.Type == descriptor.FieldDescriptorProto_TYPE_GROUP {
+		// We must use the type name for groups instead of
+		// the field name to preserve capitalization.
+		// type_name in FieldDescriptorProto is fully-qualified,
+		// but we only want the local part.
+		name = *field.TypeName
+		if i := strings.LastIndex(name, "."); i >= 0 {
+			name = name[i+1:]
+		}
+	}
+	if json := field.GetJsonName(); field.Extendee == nil && json != "" && json != name {
+		// TODO: escaping might be needed, in which case
+		// perhaps this should be in its own "json" tag.
+		name += ",json=" + json
+	}
+	name = ",name=" + name
+
+	embed := ""
+	if gogoproto.IsEmbed(field) {
+		embed = ",embedded=" + fieldName
+	}
+
+	ctype := ""
+	if gogoproto.IsCustomType(field) {
+		ctype = ",customtype=" + gogoproto.GetCustomType(field)
+	}
+
+	casttype := ""
+	if gogoproto.IsCastType(field) {
+		casttype = ",casttype=" + gogoproto.GetCastType(field)
+	}
+
+	castkey := ""
+	if gogoproto.IsCastKey(field) {
+		castkey = ",castkey=" + gogoproto.GetCastKey(field)
+	}
+
+	castvalue := ""
+	if gogoproto.IsCastValue(field) {
+		castvalue = ",castvalue=" + gogoproto.GetCastValue(field)
+		// record the original message type for jsonpb reconstruction
+		desc := g.ObjectNamed(field.GetTypeName())
+		if d, ok := desc.(*Descriptor); ok && d.GetOptions().GetMapEntry() {
+			valueField := d.Field[1]
+			if valueField.IsMessage() {
+				castvalue += ",castvaluetype=" + strings.TrimPrefix(valueField.GetTypeName(), ".")
+			}
+		}
+	}
+
+	if message.proto3() {
+		name += ",proto3"
+	}
+	oneof := ""
+	if field.OneofIndex != nil {
+		oneof = ",oneof"
+	}
+	stdtime := ""
+	if gogoproto.IsStdTime(field) {
+		stdtime = ",stdtime"
+	}
+	stdduration := ""
+	if gogoproto.IsStdDuration(field) {
+		stdduration = ",stdduration"
+	}
+	wktptr := ""
+	if gogoproto.IsWktPtr(field) {
+		wktptr = ",wktptr"
+	}
+	return strconv.Quote(fmt.Sprintf("%s,%d,%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+		wiretype,
+		field.GetNumber(),
+		optrepreq,
+		packed,
+		name,
+		enum,
+		oneof,
+		defaultValue,
+		embed,
+		ctype,
+		casttype,
+		castkey,
+		castvalue,
+		stdtime,
+		stdduration,
+		wktptr))
+}
+
+func needsStar(field *descriptor.FieldDescriptorProto, proto3 bool, allowOneOf bool) bool {
+	if isRepeated(field) &&
+		(*field.Type != descriptor.FieldDescriptorProto_TYPE_MESSAGE || gogoproto.IsCustomType(field)) &&
+		(*field.Type != descriptor.FieldDescriptorProto_TYPE_GROUP) {
+		return false
+	}
+	if *field.Type == descriptor.FieldDescriptorProto_TYPE_BYTES && !gogoproto.IsCustomType(field) {
+		return false
+	}
+	if !gogoproto.IsNullable(field) {
+		return false
+	}
+	if field.OneofIndex != nil && allowOneOf &&
+		(*field.Type != descriptor.FieldDescriptorProto_TYPE_MESSAGE) &&
+		(*field.Type != descriptor.FieldDescriptorProto_TYPE_GROUP) {
+		return false
+	}
+	if proto3 &&
+		(*field.Type != descriptor.FieldDescriptorProto_TYPE_MESSAGE) &&
+		(*field.Type != descriptor.FieldDescriptorProto_TYPE_GROUP) &&
+		!gogoproto.IsCustomType(field) {
+		return false
+	}
+	return true
+}
+
+// TypeName is the printed name appropriate for an item. If the object is in the current file,
+// TypeName drops the package name and underscores the rest.
+// Otherwise the object is from another package; and the result is the underscored
+// package name followed by the item name.
+// The result always has an initial capital.
+func (g *Generator) TypeName(obj Object) string {
+	return g.DefaultPackageName(obj) + CamelCaseSlice(obj.TypeName())
+}
+
+// GoType returns a string representing the type name, and the wire type
+func (g *Generator) GoType(message *Descriptor, field *descriptor.FieldDescriptorProto) (typ string, wire string) {
+	// TODO: Options.
+	switch *field.Type {
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+		typ, wire = "float64", "fixed64"
+	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+		typ, wire = "float32", "fixed32"
+	case descriptor.FieldDescriptorProto_TYPE_INT64:
+		typ, wire = "int64", "varint"
+	case descriptor.FieldDescriptorProto_TYPE_UINT64:
+		typ, wire = "uint64", "varint"
+	case descriptor.FieldDescriptorProto_TYPE_INT32:
+		typ, wire = "int32", "varint"
+	case descriptor.FieldDescriptorProto_TYPE_UINT32:
+		typ, wire = "uint32", "varint"
+	case descriptor.FieldDescriptorProto_TYPE_FIXED64:
+		typ, wire = "uint64", "fixed64"
+	case descriptor.FieldDescriptorProto_TYPE_FIXED32:
+		typ, wire = "uint32", "fixed32"
+	case descriptor.FieldDescriptorProto_TYPE_BOOL:
+		typ, wire = "bool", "varint"
+	case descriptor.FieldDescriptorProto_TYPE_STRING:
+		typ, wire = "string", "bytes"
+	case descriptor.FieldDescriptorProto_TYPE_GROUP:
+		desc := g.ObjectNamed(field.GetTypeName())
+		typ, wire = g.TypeName(desc), "group"
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		desc := g.ObjectNamed(field.GetTypeName())
+		typ, wire = g.TypeName(desc), "bytes"
+	case descriptor.FieldDescriptorProto_TYPE_BYTES:
+		typ, wire = "[]byte", "bytes"
+	case descriptor.FieldDescriptorProto_TYPE_ENUM:
+		desc := g.ObjectNamed(field.GetTypeName())
+		typ, wire = g.TypeName(desc), "varint"
+	case descriptor.FieldDescriptorProto_TYPE_SFIXED32:
+		typ, wire = "int32", "fixed32"
+	case descriptor.FieldDescriptorProto_TYPE_SFIXED64:
+		typ, wire = "int64", "fixed64"
+	case descriptor.FieldDescriptorProto_TYPE_SINT32:
+		typ, wire = "int32", "zigzag32"
+	case descriptor.FieldDescriptorProto_TYPE_SINT64:
+		typ, wire = "int64", "zigzag64"
+	default:
+		g.Fail("unknown type for", field.GetName())
+	}
+	switch {
+	case gogoproto.IsCustomType(field) && gogoproto.IsCastType(field):
+		g.Fail(field.GetName() + " cannot be custom type and cast type")
+	case gogoproto.IsCustomType(field):
+		var packageName string
+		var err error
+		packageName, typ, err = getCustomType(field)
+		if err != nil {
+			g.Fail(err.Error())
+		}
+		if len(packageName) > 0 {
+			g.customImports = append(g.customImports, packageName)
+		}
+	case gogoproto.IsCastType(field):
+		var packageName string
+		var err error
+		packageName, typ, err = getCastType(field)
+		if err != nil {
+			g.Fail(err.Error())
+		}
+		if len(packageName) > 0 {
+			g.customImports = append(g.customImports, packageName)
+		}
+	case gogoproto.IsStdTime(field):
+		g.customImports = append(g.customImports, "time")
+		typ = "time.Time"
+	case gogoproto.IsStdDuration(field):
+		g.customImports = append(g.customImports, "time")
+		typ = "time.Duration"
+	case gogoproto.IsStdDouble(field):
+		typ = "float64"
+	case gogoproto.IsStdFloat(field):
+		typ = "float32"
+	case gogoproto.IsStdInt64(field):
+		typ = "int64"
+	case gogoproto.IsStdUInt64(field):
+		typ = "uint64"
+	case gogoproto.IsStdInt32(field):
+		typ = "int32"
+	case gogoproto.IsStdUInt32(field):
+		typ = "uint32"
+	case gogoproto.IsStdBool(field):
+		typ = "bool"
+	case gogoproto.IsStdString(field):
+		typ = "string"
+	case gogoproto.IsStdBytes(field):
+		typ = "[]byte"
+	}
+	if needsStar(field, g.file.proto3 && field.Extendee == nil, message != nil && message.allowOneof()) {
+		typ = "*" + typ
+	}
+	if isRepeated(field) {
+		typ = "[]" + typ
+	}
+	return
+}
+
+// GoMapDescriptor is a full description of the map output struct.
+type GoMapDescriptor struct {
+	GoType string
+
+	KeyField      *descriptor.FieldDescriptorProto
+	KeyAliasField *descriptor.FieldDescriptorProto
+	KeyTag        string
+
+	ValueField      *descriptor.FieldDescriptorProto
+	ValueAliasField *descriptor.FieldDescriptorProto
+	ValueTag        string
+}
+
+func (g *Generator) GoMapType(d *Descriptor, field *descriptor.FieldDescriptorProto) *GoMapDescriptor {
+	if d == nil {
+		byName := g.ObjectNamed(field.GetTypeName())
+		desc, ok := byName.(*Descriptor)
+		if byName == nil || !ok || !desc.GetOptions().GetMapEntry() {
+			g.Fail(fmt.Sprintf("field %s is not a map", field.GetTypeName()))
+			return nil
+		}
+		d = desc
+	}
+
+	m := &GoMapDescriptor{
+		KeyField:   d.Field[0],
+		ValueField: d.Field[1],
+	}
+
+	// Figure out the Go types and tags for the key and value types.
+	m.KeyAliasField, m.ValueAliasField = g.GetMapKeyField(field, m.KeyField), g.GetMapValueField(field, m.ValueField)
+	keyType, keyWire := g.GoType(d, m.KeyAliasField)
+	valType, valWire := g.GoType(d, m.ValueAliasField)
+
+	m.KeyTag, m.ValueTag = g.goTag(d, m.KeyField, keyWire), g.goTag(d, m.ValueField, valWire)
+
+	if gogoproto.IsCastType(field) {
+		var packageName string
+		var err error
+		packageName, typ, err := getCastType(field)
+		if err != nil {
+			g.Fail(err.Error())
+		}
+		if len(packageName) > 0 {
+			g.customImports = append(g.customImports, packageName)
+		}
+		m.GoType = typ
+		return m
+	}
+
+	// We don't use stars, except for message-typed values.
+	// Message and enum types are the only two possibly foreign types used in maps,
+	// so record their use. They are not permitted as map keys.
+	keyType = strings.TrimPrefix(keyType, "*")
+	switch *m.ValueAliasField.Type {
+	case descriptor.FieldDescriptorProto_TYPE_ENUM:
+		valType = strings.TrimPrefix(valType, "*")
+		g.RecordTypeUse(m.ValueAliasField.GetTypeName())
+	case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		if !gogoproto.IsNullable(m.ValueAliasField) {
+			valType = strings.TrimPrefix(valType, "*")
+		}
+		if !gogoproto.IsStdType(m.ValueAliasField) && !gogoproto.IsCustomType(field) && !gogoproto.IsCastType(field) {
+			g.RecordTypeUse(m.ValueAliasField.GetTypeName())
+		}
+	default:
+		if gogoproto.IsCustomType(m.ValueAliasField) {
+			if !gogoproto.IsNullable(m.ValueAliasField) {
+				valType = strings.TrimPrefix(valType, "*")
+			}
+			if !gogoproto.IsStdType(field) {
+				g.RecordTypeUse(m.ValueAliasField.GetTypeName())
+			}
+		} else {
+			valType = strings.TrimPrefix(valType, "*")
+		}
+	}
+
+	m.GoType = fmt.Sprintf("map[%s]%s", keyType, valType)
+	return m
+}
+
+func (g *Generator) RecordTypeUse(t string) {
+	if _, ok := g.typeNameToObject[t]; !ok {
+		return
+	}
+	importPath := g.ObjectNamed(t).GoImportPath()
+	if importPath == g.outputImportPath {
+		// Don't record use of objects in our package.
+		return
+	}
+	g.AddImport(importPath)
+	g.usedPackages[importPath] = true
+}
+
+// Method names that may be generated.  Fields with these names get an
+// underscore appended. Any change to this set is a potential incompatible
+// API change because it changes generated field names.
+var methodNames = [...]string{
+	"Reset",
+	"String",
+	"ProtoMessage",
+	"Marshal",
+	"Unmarshal",
+	"ExtensionRangeArray",
+	"ExtensionMap",
+	"Descriptor",
+	"MarshalTo",
+	"Equal",
+	"VerboseEqual",
+	"GoString",
+	"ProtoSize",
+}
+
+// Names of messages in the `google.protobuf` package for which
+// we will generate XXX_WellKnownType methods.
+var wellKnownTypes = map[string]bool{
+	"Any":       true,
+	"Duration":  true,
+	"Empty":     true,
+	"Struct":    true,
+	"Timestamp": true,
+
+	"Value":       true,
+	"ListValue":   true,
+	"DoubleValue": true,
+	"FloatValue":  true,
+	"Int64Value":  true,
+	"UInt64Value": true,
+	"Int32Value":  true,
+	"UInt32Value": true,
+	"BoolValue":   true,
+	"StringValue": true,
+	"BytesValue":  true,
+}
+
+// getterDefault finds the default value for the field to return from a getter,
+// regardless of if it's a built in default or explicit from the source. Returns e.g. "nil", `""`, "Default_MessageType_FieldName"
+func (g *Generator) getterDefault(field *descriptor.FieldDescriptorProto, goMessageType, goTypeName string) string {
+	if isRepeated(field) {
+		return "nil"
+	}
+	if def := field.GetDefaultValue(); def != "" {
+		defaultConstant := g.defaultConstantName(goMessageType, field.GetName())
+		if *field.Type != descriptor.FieldDescriptorProto_TYPE_BYTES {
+			return defaultConstant
+		}
+		return "append([]byte(nil), " + defaultConstant + "...)"
+	}
+	switch *field.Type {
+	case descriptor.FieldDescriptorProto_TYPE_GROUP,
+		descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		if field.OneofIndex != nil {
+			return "nil"
+		} else {
+			if !gogoproto.IsNullable(field) && (gogoproto.IsStdDuration(field) ||
+				gogoproto.IsStdDouble(field) || gogoproto.IsStdFloat(field) ||
+				gogoproto.IsStdInt64(field) || gogoproto.IsStdUInt64(field) ||
+				gogoproto.IsStdInt32(field) || gogoproto.IsStdUInt32(field)) {
+				return "0"
+			} else if !gogoproto.IsNullable(field) && gogoproto.IsStdBool(field) {
+				return "false"
+			} else if !gogoproto.IsNullable(field) && gogoproto.IsStdString(field) {
+				return "\"\""
+			} else if !gogoproto.IsNullable(field) && gogoproto.IsStdBytes(field) {
+				return "[]byte{}"
+			} else {
+				return goTypeName + "{}"
+			}
+		}
+	case descriptor.FieldDescriptorProto_TYPE_BOOL:
+		return "false"
+	case descriptor.FieldDescriptorProto_TYPE_STRING:
+		return "\"\""
+	case descriptor.FieldDescriptorProto_TYPE_BYTES:
+		// This is only possible for oneof fields.
+		return "nil"
+	case descriptor.FieldDescriptorProto_TYPE_ENUM:
+		// The default default for an enum is the first value in the enum,
+		// not zero.
+		obj := g.ObjectNamed(field.GetTypeName())
+		var enum *EnumDescriptor
+		if id, ok := obj.(*ImportedDescriptor); ok {
+			// The enum type has been publicly imported.
+			enum, _ = id.o.(*EnumDescriptor)
+		} else {
+			enum, _ = obj.(*EnumDescriptor)
+		}
+		if enum == nil {
+			log.Printf("don't know how to generate getter for %s", field.GetName())
+			return "nil"
+		}
+		if len(enum.Value) == 0 {
+			return "0 // empty enum"
+		} else {
+			first := enum.Value[0].GetName()
+			if gogoproto.IsEnumValueCustomName(enum.Value[0]) {
+				first = gogoproto.GetEnumValueCustomName(enum.Value[0])
+			}
+			if gogoproto.EnabledGoEnumPrefix(enum.file.FileDescriptorProto, enum.EnumDescriptorProto) {
+				return g.DefaultPackageName(obj) + enum.prefix() + first
+			} else {
+				return g.DefaultPackageName(obj) + first
+			}
+		}
+	default:
+		return "0"
+	}
+}
+
+// defaultConstantName builds the name of the default constant from the message
+// type name and the untouched field name, e.g. "Default_MessageType_FieldName"
+func (g *Generator) defaultConstantName(goMessageType, protoFieldName string) string {
+	return "Default_" + goMessageType + "_" + CamelCase(protoFieldName)
+}
+
+// The different types of fields in a message and how to actually print them
+// Most of the logic for generateMessage is in the methods of these types.
+//
+// Note that the content of the field is irrelevant, a simpleField can contain
+// anything from a scalar to a group (which is just a message).
+//
+// Extension fields (and message sets) are however handled separately.
+//
+// simpleField - a field that is neiter weak nor oneof, possibly repeated
+// oneofField - field containing list of subfields:
+// - oneofSubField - a field within the oneof
+
+// msgCtx contains the context for the generator functions.
+type msgCtx struct {
+	goName  string      // Go struct name of the message, e.g. MessageName
+	message *Descriptor // The descriptor for the message
+}
+
+// fieldCommon contains data common to all types of fields.
+type fieldCommon struct {
+	goName     string                           // Go name of field, e.g. "FieldName" or "Descriptor_"
+	protoName  string                           // Name of field in proto language, e.g. "field_name" or "descriptor"
+	getterName string                           // Name of the getter, e.g. "GetFieldName" or "GetDescriptor_"
+	goType     string                           // The Go type as a string, e.g. "*int32" or "*OtherMessage"
+	tags       string                           // The tag string/annotation for the type, e.g. `protobuf:"varint,8,opt,name=region_id,json=regionId"`
+	fullPath   string                           // The full path of the field as used by Annotate etc, e.g. "4,0,2,0"
+	protoField *descriptor.FieldDescriptorProto // gogo. Passing in the fieldDescriptor in for gogo options. TODO rethink this, we might need a better way of getting options.
+}
+
+// getProtoName gets the proto name of a field, e.g. "field_name" or "descriptor".
+func (f *fieldCommon) getProtoName() string {
+	return f.protoName
+}
+
+// getGoType returns the go type of the field  as a string, e.g. "*int32".
+func (f *fieldCommon) getGoType() string {
+	return f.goType
+}
+
+// simpleField is not weak, not a oneof, not an extension. Can be required, optional or repeated.
+type simpleField struct {
+	fieldCommon
+	protoTypeName string                               // Proto type name, empty if primitive, e.g. ".google.protobuf.Duration"
+	protoType     descriptor.FieldDescriptorProto_Type // Actual type enum value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64
+	deprecated    string                               // Deprecation comment, if any, e.g. "// Deprecated: Do not use."
+	getterDef     string                               // Default for getters, e.g. "nil", `""` or "Default_MessageType_FieldName"
+	protoDef      string                               // Default value as defined in the proto file, e.g "yoshi" or "5"
+	comment       string                               // The full comment for the field, e.g. "// Useful information"
+}
+
+// decl prints the declaration of the field in the struct (if any).
+func (f *simpleField) decl(g *Generator, mc *msgCtx) {
+	g.P(f.comment, Annotate(mc.message.file, f.fullPath, f.goName), "\t", f.goType, "\t`", f.tags, "`", f.deprecated)
+}
+
+// getter prints the getter for the field.
+func (f *simpleField) getter(g *Generator, mc *msgCtx) {
+	oneof := false
+	if !oneof && !gogoproto.HasGoGetters(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+		return
+	}
+	if gogoproto.IsEmbed(f.protoField) || gogoproto.IsCustomType(f.protoField) {
+		return
+	}
+	if f.deprecated != "" {
+		g.P(f.deprecated)
+	}
+	g.generateGet(mc, f.protoField, f.protoType, false, f.goName, f.goType, "", "", f.fullPath, f.getterName, f.getterDef)
+}
+
+// setter prints the setter method of the field.
+func (f *simpleField) setter(g *Generator, mc *msgCtx) {
+	// No setter for regular fields yet
+}
+
+// getProtoDef returns the default value explicitly stated in the proto file, e.g "yoshi" or "5".
+func (f *simpleField) getProtoDef() string {
+	return f.protoDef
+}
+
+// getProtoTypeName returns the protobuf type name for the field as returned by field.GetTypeName(), e.g. ".google.protobuf.Duration".
+func (f *simpleField) getProtoTypeName() string {
+	return f.protoTypeName
+}
+
+// getProtoType returns the *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64.
+func (f *simpleField) getProtoType() descriptor.FieldDescriptorProto_Type {
+	return f.protoType
+}
+
+func (f *simpleField) getProto() *descriptor.FieldDescriptorProto {
+	return f.protoField
+}
+
+// oneofSubFields are kept slize held by each oneofField. They do not appear in the top level slize of fields for the message.
+type oneofSubField struct {
+	fieldCommon
+	protoTypeName string                               // Proto type name, empty if primitive, e.g. ".google.protobuf.Duration"
+	protoType     descriptor.FieldDescriptorProto_Type // Actual type enum value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64
+	oneofTypeName string                               // Type name of the enclosing struct, e.g. "MessageName_FieldName"
+	fieldNumber   int                                  // Actual field number, as defined in proto, e.g. 12
+	getterDef     string                               // Default for getters, e.g. "nil", `""` or "Default_MessageType_FieldName"
+	protoDef      string                               // Default value as defined in the proto file, e.g "yoshi" or "5"
+	deprecated    string                               // Deprecation comment, if any.
+}
+
+// typedNil prints a nil casted to the pointer to this field.
+// - for XXX_OneofWrappers
+func (f *oneofSubField) typedNil(g *Generator) {
+	g.P("(*", f.oneofTypeName, ")(nil),")
+}
+
+// getProtoDef returns the default value explicitly stated in the proto file, e.g "yoshi" or "5".
+func (f *oneofSubField) getProtoDef() string {
+	return f.protoDef
+}
+
+// getProtoTypeName returns the protobuf type name for the field as returned by field.GetTypeName(), e.g. ".google.protobuf.Duration".
+func (f *oneofSubField) getProtoTypeName() string {
+	return f.protoTypeName
+}
+
+// getProtoType returns the *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64.
+func (f *oneofSubField) getProtoType() descriptor.FieldDescriptorProto_Type {
+	return f.protoType
+}
+
+func (f *oneofSubField) getProto() *descriptor.FieldDescriptorProto {
+	return f.protoField
+}
+
+// oneofField represents the oneof on top level.
+// The alternative fields within the oneof are represented by oneofSubField.
+type oneofField struct {
+	fieldCommon
+	subFields []*oneofSubField // All the possible oneof fields
+	comment   string           // The full comment for the field, e.g. "// Types that are valid to be assigned to MyOneof:\n\\"
+}
+
+// decl prints the declaration of the field in the struct (if any).
+func (f *oneofField) decl(g *Generator, mc *msgCtx) {
+	comment := f.comment
+	for _, sf := range f.subFields {
+		comment += "//\t*" + sf.oneofTypeName + "\n"
+	}
+	g.P(comment, Annotate(mc.message.file, f.fullPath, f.goName), " ", f.goType, " `", f.tags, "`")
+}
+
+// getter for a oneof field will print additional discriminators and interfaces for the oneof,
+// also it prints all the getters for the sub fields.
+func (f *oneofField) getter(g *Generator, mc *msgCtx) {
+	oneof := true
+	if !oneof && !gogoproto.HasGoGetters(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+		return
+	}
+
+	for _, sf := range f.subFields {
+		if gogoproto.IsEmbed(sf.protoField) || gogoproto.IsCustomType(sf.protoField) {
+			continue
+		}
+		if sf.deprecated != "" {
+			g.P(sf.deprecated)
+		}
+		g.generateGet(mc, sf.protoField, sf.protoType, true, sf.goName, sf.goType, f.goName, sf.oneofTypeName, sf.fullPath, sf.getterName, sf.getterDef)
+	}
+}
+
+// setter prints the setter method of the field.
+func (f *oneofField) setter(g *Generator, mc *msgCtx) {
+	// No setters for oneof yet
+}
+
+// topLevelField interface implemented by all types of fields on the top level (not oneofSubField).
+type topLevelField interface {
+	decl(g *Generator, mc *msgCtx)   // print declaration within the struct
+	getter(g *Generator, mc *msgCtx) // print getter
+	setter(g *Generator, mc *msgCtx) // print setter if applicable
+}
+
+// defField interface implemented by all types of fields that can have defaults (not oneofField, but instead oneofSubField).
+type defField interface {
+	getProtoDef() string                                // default value explicitly stated in the proto file, e.g "yoshi" or "5"
+	getProtoName() string                               // proto name of a field, e.g. "field_name" or "descriptor"
+	getGoType() string                                  // go type of the field  as a string, e.g. "*int32"
+	getProtoTypeName() string                           // protobuf type name for the field, e.g. ".google.protobuf.Duration"
+	getProtoType() descriptor.FieldDescriptorProto_Type // *field.Type value, e.g. descriptor.FieldDescriptorProto_TYPE_FIXED64
+	getProto() *descriptor.FieldDescriptorProto
+}
+
+// generateDefaultConstants adds constants for default values if needed, which is only if the default value is.
+// explicit in the proto.
+func (g *Generator) generateDefaultConstants(mc *msgCtx, topLevelFields []topLevelField) {
+	// Collect fields that can have defaults
+	dFields := []defField{}
+	for _, pf := range topLevelFields {
+		if f, ok := pf.(*oneofField); ok {
+			for _, osf := range f.subFields {
+				dFields = append(dFields, osf)
+			}
+			continue
+		}
+		dFields = append(dFields, pf.(defField))
+	}
+	for _, df := range dFields {
+		def := df.getProtoDef()
+		if def == "" {
+			continue
+		}
+		if !gogoproto.IsNullable(df.getProto()) {
+			g.Fail("illegal default value: ", df.getProtoName(), " in ", mc.message.GetName(), " is not nullable and is thus not allowed to have a default value")
+		}
+		fieldname := g.defaultConstantName(mc.goName, df.getProtoName())
+		typename := df.getGoType()
+		if typename[0] == '*' {
+			typename = typename[1:]
+		}
+		kind := "const "
+		switch {
+		case typename == "bool":
+		case typename == "string":
+			def = strconv.Quote(def)
+		case typename == "[]byte":
+			def = "[]byte(" + strconv.Quote(unescape(def)) + ")"
+			kind = "var "
+		case def == "inf", def == "-inf", def == "nan":
+			// These names are known to, and defined by, the protocol language.
+			switch def {
+			case "inf":
+				def = "math.Inf(1)"
+			case "-inf":
+				def = "math.Inf(-1)"
+			case "nan":
+				def = "math.NaN()"
+			}
+			if df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_FLOAT {
+				def = "float32(" + def + ")"
+			}
+			kind = "var "
+		case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_FLOAT:
+			if f, err := strconv.ParseFloat(def, 32); err == nil {
+				def = fmt.Sprint(float32(f))
+			}
+		case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+			if f, err := strconv.ParseFloat(def, 64); err == nil {
+				def = fmt.Sprint(f)
+			}
+		case df.getProtoType() == descriptor.FieldDescriptorProto_TYPE_ENUM:
+			// Must be an enum.  Need to construct the prefixed name.
+			obj := g.ObjectNamed(df.getProtoTypeName())
+			var enum *EnumDescriptor
+			if id, ok := obj.(*ImportedDescriptor); ok {
+				// The enum type has been publicly imported.
+				enum, _ = id.o.(*EnumDescriptor)
+			} else {
+				enum, _ = obj.(*EnumDescriptor)
+			}
+			if enum == nil {
+				log.Printf("don't know how to generate constant for %s", fieldname)
+				continue
+			}
+
+			// hunt down the actual enum corresponding to the default
+			var enumValue *descriptor.EnumValueDescriptorProto
+			for _, ev := range enum.Value {
+				if def == ev.GetName() {
+					enumValue = ev
+				}
+			}
+
+			if enumValue != nil {
+				if gogoproto.IsEnumValueCustomName(enumValue) {
+					def = gogoproto.GetEnumValueCustomName(enumValue)
+				}
+			} else {
+				g.Fail(fmt.Sprintf("could not resolve default enum value for %v.%v", g.DefaultPackageName(obj), def))
+			}
+
+			if gogoproto.EnabledGoEnumPrefix(enum.file.FileDescriptorProto, enum.EnumDescriptorProto) {
+				def = g.DefaultPackageName(obj) + enum.prefix() + def
+			} else {
+				def = g.DefaultPackageName(obj) + def
+			}
+		}
+		g.P(kind, fieldname, " ", typename, " = ", def)
+		g.file.addExport(mc.message, constOrVarSymbol{fieldname, kind, ""})
+	}
+	g.P()
+}
+
+// generateGet generates the getter for both the simpleField and oneofSubField.
+// We did not want to duplicate the code since it is quite intricate so we came
+// up with this ugly method. At least the logic is in one place. This can be reworked.
+func (g *Generator) generateGet(mc *msgCtx, protoField *descriptor.FieldDescriptorProto, protoType descriptor.FieldDescriptorProto_Type,
+	oneof bool, fname, tname, uname, oneoftname, fullpath, gname, def string) {
+	star := ""
+	if (protoType != descriptor.FieldDescriptorProto_TYPE_MESSAGE) &&
+		(protoType != descriptor.FieldDescriptorProto_TYPE_GROUP) &&
+		needsStar(protoField, g.file.proto3, mc.message != nil && mc.message.allowOneof()) && tname[0] == '*' {
+		tname = tname[1:]
+		star = "*"
+	}
+	typeDefaultIsNil := false // whether this field type's default value is a literal nil unless specified
+	switch protoType {
+	case descriptor.FieldDescriptorProto_TYPE_BYTES:
+		typeDefaultIsNil = def == "nil"
+	case descriptor.FieldDescriptorProto_TYPE_GROUP, descriptor.FieldDescriptorProto_TYPE_MESSAGE:
+		typeDefaultIsNil = gogoproto.IsNullable(protoField)
+	}
+	if isRepeated(protoField) {
+		typeDefaultIsNil = true
+	}
+	g.P("func (m *", mc.goName, ") ", Annotate(mc.message.file, fullpath, gname), "() "+tname+" {")
+	if !oneof && typeDefaultIsNil {
+		// A bytes field with no explicit default needs less generated code,
+		// as does a message or group field, or a repeated field.
+		g.P("if m != nil {")
+		g.In()
+		g.P("return m." + fname)
+		g.Out()
+		g.P("}")
+		g.P("return nil")
+		g.Out()
+		g.P("}")
+		g.P()
+		return
+	}
+	if !gogoproto.IsNullable(protoField) {
+		g.P("if m != nil {")
+		g.In()
+		g.P("return m." + fname)
+		g.Out()
+		g.P("}")
+	} else if !oneof {
+		if mc.message.proto3() {
+			g.P("if m != nil {")
+		} else {
+			g.P("if m != nil && m." + fname + " != nil {")
+		}
+		g.In()
+		g.P("return " + star + "m." + fname)
+		g.Out()
+		g.P("}")
+	} else {
+		uname := uname
+		tname := oneoftname
+		g.P("if x, ok := m.Get", uname, "().(*", tname, "); ok {")
+		g.P("return x.", fname)
+		g.P("}")
+	}
+	g.P("return ", def)
+	g.Out()
+	g.P("}")
+	g.P()
+}
+
+// generateInternalStructFields just adds the XXX_<something> fields to the message struct.
+func (g *Generator) generateInternalStructFields(mc *msgCtx, topLevelFields []topLevelField) {
+	if gogoproto.HasUnkeyed(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+		g.P("XXX_NoUnkeyedLiteral\tstruct{} `json:\"-\"`") // prevent unkeyed struct literals
+	}
+	if len(mc.message.ExtensionRange) > 0 {
+		if gogoproto.HasExtensionsMap(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+			messageset := ""
+			if opts := mc.message.Options; opts != nil && opts.GetMessageSetWireFormat() {
+				messageset = "protobuf_messageset:\"1\" "
+			}
+			g.P(g.Pkg["proto"], ".XXX_InternalExtensions `", messageset, "json:\"-\"`")
+		} else {
+			g.P("XXX_extensions\t\t[]byte `protobuf:\"bytes,0,opt\" json:\"-\"`")
+		}
+	}
+	if gogoproto.HasUnrecognized(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+		g.P("XXX_unrecognized\t[]byte `json:\"-\"`")
+	}
+	if gogoproto.HasSizecache(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+		g.P("XXX_sizecache\tint32 `json:\"-\"`")
+	}
+}
+
+// generateOneofFuncs adds all the utility functions for oneof, including marshalling, unmarshalling and sizer.
+func (g *Generator) generateOneofFuncs(mc *msgCtx, topLevelFields []topLevelField) {
+	ofields := []*oneofField{}
+	for _, f := range topLevelFields {
+		if o, ok := f.(*oneofField); ok {
+			ofields = append(ofields, o)
+		}
+	}
+	if len(ofields) == 0 {
+		return
+	}
+
+	// OneofFuncs
+	g.P("// XXX_OneofWrappers is for the internal use of the proto package.")
+	g.P("func (*", mc.goName, ") XXX_OneofWrappers() []interface{} {")
+	g.P("return []interface{}{")
+	for _, of := range ofields {
+		for _, sf := range of.subFields {
+			sf.typedNil(g)
+		}
+	}
+	g.P("}")
+	g.P("}")
+	g.P()
+}
+
+func (g *Generator) generateOneofDecls(mc *msgCtx, topLevelFields []topLevelField) {
+	ofields := []*oneofField{}
+	for _, f := range topLevelFields {
+		if o, ok := f.(*oneofField); ok {
+			ofields = append(ofields, o)
+		}
+	}
+	if len(ofields) == 0 {
+		return
+	}
+	// Oneof per-field types, discriminants and getters.
+	// Generate unexported named types for the discriminant interfaces.
+	// We shouldn't have to do this, but there was (~19 Aug 2015) a compiler/linker bug
+	// that was triggered by using anonymous interfaces here.
+	// TODO: Revisit this and consider reverting back to anonymous interfaces.
+	// for oi := range message.OneofDecl {
+	for _, of := range ofields {
+		dname := of.goType
+		g.P("type ", dname, " interface {")
+		g.In()
+		g.P(dname, "()")
+		if gogoproto.HasEqual(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+			g.P(`Equal(interface{}) bool`)
+		}
+		if gogoproto.HasVerboseEqual(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+			g.P(`VerboseEqual(interface{}) error`)
+		}
+		if gogoproto.IsMarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto) ||
+			gogoproto.IsUnsafeMarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto) ||
+			gogoproto.IsStableMarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+			g.P(`MarshalTo([]byte) (int, error)`)
+		}
+		if gogoproto.IsSizer(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+			g.P(`Size() int`)
+		}
+		if gogoproto.IsProtoSizer(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+			g.P(`ProtoSize() int`)
+		}
+		if gogoproto.HasCompare(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+			g.P(`Compare(interface{}) int`)
+		}
+		g.Out()
+		g.P("}")
+	}
+	g.P()
+	for _, of := range ofields {
+		for i, sf := range of.subFields {
+			fieldFullPath := fmt.Sprintf("%s,%d,%d", mc.message.path, messageFieldPath, i)
+			g.P("type ", Annotate(mc.message.file, fieldFullPath, sf.oneofTypeName), " struct{ ", Annotate(mc.message.file, fieldFullPath, sf.goName), " ", sf.goType, " `", sf.tags, "` }")
+			if !gogoproto.IsStdType(sf.protoField) && !gogoproto.IsCustomType(sf.protoField) && !gogoproto.IsCastType(sf.protoField) {
+				g.RecordTypeUse(sf.protoField.GetTypeName())
+			}
+		}
+	}
+	g.P()
+	for _, of := range ofields {
+		for _, sf := range of.subFields {
+			g.P("func (*", sf.oneofTypeName, ") ", of.goType, "() {}")
+		}
+	}
+	g.P()
+	for _, of := range ofields {
+		fname := of.goName
+		g.P("func (m *", mc.goName, ") Get", fname, "() ", of.goType, " {")
+		g.P("if m != nil { return m.", fname, " }")
+		g.P("return nil")
+		g.P("}")
+	}
+	g.P()
+}
+
+// generateMessageStruct adds the actual struct with it's members (but not methods) to the output.
+func (g *Generator) generateMessageStruct(mc *msgCtx, topLevelFields []topLevelField) {
+	comments := g.PrintComments(mc.message.path)
+
+	// Guarantee deprecation comments appear after user-provided comments.
+	if mc.message.GetOptions().GetDeprecated() {
+		if comments {
+			// Convention: Separate deprecation comments from original
+			// comments with an empty line.
+			g.P("//")
+		}
+		g.P(deprecationComment)
+	}
+	g.P("type ", Annotate(mc.message.file, mc.message.path, mc.goName), " struct {")
+	for _, pf := range topLevelFields {
+		pf.decl(g, mc)
+	}
+	g.generateInternalStructFields(mc, topLevelFields)
+	g.P("}")
+}
+
+// generateGetters adds getters for all fields, including oneofs and weak fields when applicable.
+func (g *Generator) generateGetters(mc *msgCtx, topLevelFields []topLevelField) {
+	for _, pf := range topLevelFields {
+		pf.getter(g, mc)
+
+	}
+}
+
+// generateSetters add setters for all fields, including oneofs and weak fields when applicable.
+func (g *Generator) generateSetters(mc *msgCtx, topLevelFields []topLevelField) {
+	for _, pf := range topLevelFields {
+		pf.setter(g, mc)
+	}
+}
+
+// generateCommonMethods adds methods to the message that are not on a per field basis.
+func (g *Generator) generateCommonMethods(mc *msgCtx) {
+	// Reset, String and ProtoMessage methods.
+	g.P("func (m *", mc.goName, ") Reset() { *m = ", mc.goName, "{} }")
+	if gogoproto.EnabledGoStringer(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+		g.P("func (m *", mc.goName, ") String() string { return ", g.Pkg["proto"], ".CompactTextString(m) }")
+	}
+	g.P("func (*", mc.goName, ") ProtoMessage() {}")
+	var indexes []string
+	for m := mc.message; m != nil; m = m.parent {
+		indexes = append([]string{strconv.Itoa(m.index)}, indexes...)
+	}
+	g.P("func (*", mc.goName, ") Descriptor() ([]byte, []int) {")
+	g.P("return ", g.file.VarName(), ", []int{", strings.Join(indexes, ", "), "}")
+	g.P("}")
+	// TODO: Revisit the decision to use a XXX_WellKnownType method
+	// if we change proto.MessageName to work with multiple equivalents.
+	if mc.message.file.GetPackage() == "google.protobuf" && wellKnownTypes[mc.message.GetName()] {
+		g.P("func (*", mc.goName, `) XXX_WellKnownType() string { return "`, mc.message.GetName(), `" }`)
+	}
+
+	// Extension support methods
+	if len(mc.message.ExtensionRange) > 0 {
+		g.P()
+		g.P("var extRange_", mc.goName, " = []", g.Pkg["proto"], ".ExtensionRange{")
+		g.In()
+		for _, r := range mc.message.ExtensionRange {
+			end := fmt.Sprint(*r.End - 1) // make range inclusive on both ends
+			g.P("{Start: ", r.Start, ", End: ", end, "},")
+		}
+		g.Out()
+		g.P("}")
+		g.P("func (*", mc.goName, ") ExtensionRangeArray() []", g.Pkg["proto"], ".ExtensionRange {")
+		g.In()
+		g.P("return extRange_", mc.goName)
+		g.Out()
+		g.P("}")
+		g.P()
+		if !gogoproto.HasExtensionsMap(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+			g.P("func (m *", mc.goName, ") GetExtensions() *[]byte {")
+			g.In()
+			g.P("if m.XXX_extensions == nil {")
+			g.In()
+			g.P("m.XXX_extensions = make([]byte, 0)")
+			g.Out()
+			g.P("}")
+			g.P("return &m.XXX_extensions")
+			g.Out()
+			g.P("}")
+		}
+	}
+
+	// TODO: It does not scale to keep adding another method for every
+	// operation on protos that we want to switch over to using the
+	// table-driven approach. Instead, we should only add a single method
+	// that allows getting access to the *InternalMessageInfo struct and then
+	// calling Unmarshal, Marshal, Merge, Size, and Discard directly on that.
+
+	// Wrapper for table-driven marshaling and unmarshaling.
+	g.P("func (m *", mc.goName, ") XXX_Unmarshal(b []byte) error {")
+	g.In()
+	if gogoproto.IsUnmarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+		g.P("return m.Unmarshal(b)")
+	} else {
+		g.P("return xxx_messageInfo_", mc.goName, ".Unmarshal(m, b)")
+	}
+	g.Out()
+	g.P("}")
+
+	g.P("func (m *", mc.goName, ") XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {")
+	g.In()
+	if gogoproto.IsMarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto) ||
+		gogoproto.IsUnsafeMarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+		if gogoproto.IsStableMarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+			g.P("b = b[:cap(b)]")
+			g.P("n, err := m.MarshalToSizedBuffer(b)")
+			g.P("if err != nil {")
+			g.In()
+			g.P("return nil, err")
+			g.Out()
+			g.P("}")
+			g.P("return b[:n], nil")
+		} else {
+			g.P("if deterministic {")
+			g.In()
+			g.P("return xxx_messageInfo_", mc.goName, ".Marshal(b, m, deterministic)")
+			g.P("} else {")
+			g.In()
+			g.P("b = b[:cap(b)]")
+			g.P("n, err := m.MarshalToSizedBuffer(b)")
+			g.P("if err != nil {")
+			g.In()
+			g.P("return nil, err")
+			g.Out()
+			g.P("}")
+			g.Out()
+			g.P("return b[:n], nil")
+			g.Out()
+			g.P("}")
+		}
+	} else {
+		g.P("return xxx_messageInfo_", mc.goName, ".Marshal(b, m, deterministic)")
+	}
+	g.Out()
+	g.P("}")
+
+	g.P("func (m *", mc.goName, ") XXX_Merge(src ", g.Pkg["proto"], ".Message) {")
+	g.In()
+	g.P("xxx_messageInfo_", mc.goName, ".Merge(m, src)")
+	g.Out()
+	g.P("}")
+
+	g.P("func (m *", mc.goName, ") XXX_Size() int {") // avoid name clash with "Size" field in some message
+	g.In()
+	if (gogoproto.IsMarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto) ||
+		gogoproto.IsUnsafeMarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto)) &&
+		gogoproto.IsSizer(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+		g.P("return m.Size()")
+	} else if (gogoproto.IsMarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto) ||
+		gogoproto.IsUnsafeMarshaler(g.file.FileDescriptorProto, mc.message.DescriptorProto)) &&
+		gogoproto.IsProtoSizer(g.file.FileDescriptorProto, mc.message.DescriptorProto) {
+		g.P("return m.ProtoSize()")
+	} else {
+		g.P("return xxx_messageInfo_", mc.goName, ".Size(m)")
+	}
+	g.Out()
+	g.P("}")
+
+	g.P("func (m *", mc.goName, ") XXX_DiscardUnknown() {")
+	g.In()
+	g.P("xxx_messageInfo_", mc.goName, ".DiscardUnknown(m)")
+	g.Out()
+	g.P("}")
+
+	g.P("var xxx_messageInfo_", mc.goName, " ", g.Pkg["proto"], ".InternalMessageInfo")
+}
+
+// Generate the type and default constant definitions for this Descriptor.
+func (g *Generator) generateMessage(message *Descriptor) {
+	topLevelFields := []topLevelField{}
+	oFields := make(map[int32]*oneofField)
+	// The full type name
+	typeName := message.TypeName()
+	// The full type name, CamelCased.
+	goTypeName := CamelCaseSlice(typeName)
+
+	usedNames := make(map[string]bool)
+	for _, n := range methodNames {
+		usedNames[n] = true
+	}
+	if !gogoproto.IsProtoSizer(message.file.FileDescriptorProto, message.DescriptorProto) {
+		usedNames["Size"] = true
+	}
+
+	// allocNames finds a conflict-free variation of the given strings,
+	// consistently mutating their suffixes.
+	// It returns the same number of strings.
+	allocNames := func(ns ...string) []string {
+	Loop:
+		for {
+			for _, n := range ns {
+				if usedNames[n] {
+					for i := range ns {
+						ns[i] += "_"
+					}
+					continue Loop
+				}
+			}
+			for _, n := range ns {
+				usedNames[n] = true
+			}
+			return ns
+		}
+	}
+
+	mapFieldTypes := make(map[*descriptor.FieldDescriptorProto]string) // keep track of the map fields to be added later
+
+	for i, field := range message.Field {
+		// Allocate the getter and the field at the same time so name
+		// collisions create field/method consistent names.
+		// TODO: This allocation occurs based on the order of the fields
+		// in the proto file, meaning that a change in the field
+		// ordering can change generated Method/Field names.
+		base := CamelCase(*field.Name)
+		if gogoproto.IsCustomName(field) {
+			base = gogoproto.GetCustomName(field)
+		}
+		ns := allocNames(base, "Get"+base)
+		fieldName, fieldGetterName := ns[0], ns[1]
+
+		typename, wiretype := g.GoType(message, field)
+		jsonName := *field.Name
+		jsonTag := jsonName + ",omitempty"
+		repeatedNativeType := (!field.IsMessage() && !gogoproto.IsCustomType(field) && field.IsRepeated())
+		if !gogoproto.IsNullable(field) && !repeatedNativeType {
+			jsonTag = jsonName
+		}
+		gogoJsonTag := gogoproto.GetJsonTag(field)
+		if gogoJsonTag != nil {
+			jsonTag = *gogoJsonTag
+		}
+		gogoMoreTags := gogoproto.GetMoreTags(field)
+		moreTags := ""
+		if gogoMoreTags != nil {
+			moreTags = " " + *gogoMoreTags
+		}
+		tag := fmt.Sprintf("protobuf:%s json:%q%s", g.goTag(message, field, wiretype), jsonTag, moreTags)
+		if *field.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE && gogoproto.IsEmbed(field) {
+			fieldName = ""
+		}
+
+		oneof := field.OneofIndex != nil && message.allowOneof()
+		if oneof && oFields[*field.OneofIndex] == nil {
+			odp := message.OneofDecl[int(*field.OneofIndex)]
+			base := CamelCase(odp.GetName())
+			names := allocNames(base, "Get"+base)
+			fname, gname := names[0], names[1]
+
+			// This is the first field of a oneof we haven't seen before.
+			// Generate the union field.
+			oneofFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageOneofPath, *field.OneofIndex)
+			c, ok := g.makeComments(oneofFullPath)
+			if ok {
+				c += "\n//\n"
+			}
+			c += "// Types that are valid to be assigned to " + fname + ":\n"
+			// Generate the rest of this comment later,
+			// when we've computed any disambiguation.
+
+			dname := "is" + goTypeName + "_" + fname
+			oneOftag := `protobuf_oneof:"` + odp.GetName() + `"`
+			of := oneofField{
+				fieldCommon: fieldCommon{
+					goName:     fname,
+					getterName: gname,
+					goType:     dname,
+					tags:       oneOftag,
+					protoName:  odp.GetName(),
+					fullPath:   oneofFullPath,
+					protoField: field,
+				},
+				comment: c,
+			}
+			topLevelFields = append(topLevelFields, &of)
+			oFields[*field.OneofIndex] = &of
+		}
+
+		if *field.Type == descriptor.FieldDescriptorProto_TYPE_MESSAGE {
+			desc := g.ObjectNamed(field.GetTypeName())
+			if d, ok := desc.(*Descriptor); ok && d.GetOptions().GetMapEntry() {
+				m := g.GoMapType(d, field)
+				typename = m.GoType
+				mapFieldTypes[field] = typename // record for the getter generation
+
+				tag += fmt.Sprintf(" protobuf_key:%s protobuf_val:%s", m.KeyTag, m.ValueTag)
+			}
+		}
+		goTyp, _ := g.GoType(message, field)
+		fieldDeprecated := ""
+		if field.GetOptions().GetDeprecated() {
+			fieldDeprecated = deprecationComment
+		}
+		dvalue := g.getterDefault(field, goTypeName, GoTypeToName(goTyp))
+		if oneof {
+			tname := goTypeName + "_" + fieldName
+			// It is possible for this to collide with a message or enum
+			// nested in this message. Check for collisions.
+			for {
+				ok := true
+				for _, desc := range message.nested {
+					if CamelCaseSlice(desc.TypeName()) == tname {
+						ok = false
+						break
+					}
+				}
+				for _, enum := range message.enums {
+					if CamelCaseSlice(enum.TypeName()) == tname {
+						ok = false
+						break
+					}
+				}
+				if !ok {
+					tname += "_"
+					continue
+				}
+				break
+			}
+
+			oneofField := oFields[*field.OneofIndex]
+			sf := oneofSubField{
+				fieldCommon: fieldCommon{
+					goName:     fieldName,
+					getterName: fieldGetterName,
+					goType:     typename,
+					tags:       tag,
+					protoName:  field.GetName(),
+					fullPath:   fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i),
+					protoField: field,
+				},
+				protoTypeName: field.GetTypeName(),
+				fieldNumber:   int(*field.Number),
+				protoType:     *field.Type,
+				getterDef:     dvalue,
+				protoDef:      field.GetDefaultValue(),
+				oneofTypeName: tname,
+				deprecated:    fieldDeprecated,
+			}
+
+			oneofField.subFields = append(oneofField.subFields, &sf)
+			if !gogoproto.IsStdType(field) && !gogoproto.IsCustomType(field) && !gogoproto.IsCastType(field) {
+				g.RecordTypeUse(field.GetTypeName())
+			}
+			continue
+		}
+
+		fieldFullPath := fmt.Sprintf("%s,%d,%d", message.path, messageFieldPath, i)
+		c, ok := g.makeComments(fieldFullPath)
+		if ok {
+			c += "\n"
+		}
+		rf := simpleField{
+			fieldCommon: fieldCommon{
+				goName:     fieldName,
+				getterName: fieldGetterName,
+				goType:     typename,
+				tags:       tag,
+				protoName:  field.GetName(),
+				fullPath:   fieldFullPath,
+				protoField: field,
+			},
+			protoTypeName: field.GetTypeName(),
+			protoType:     *field.Type,
+			deprecated:    fieldDeprecated,
+			getterDef:     dvalue,
+			protoDef:      field.GetDefaultValue(),
+			comment:       c,
+		}
+		var pf topLevelField = &rf
+
+		topLevelFields = append(topLevelFields, pf)
+
+		if gogoproto.HasTypeDecl(message.file.FileDescriptorProto, message.DescriptorProto) {
+			if !gogoproto.IsStdType(field) && !gogoproto.IsCustomType(field) && !gogoproto.IsCastType(field) {
+				g.RecordTypeUse(field.GetTypeName())
+			}
+		} else {
+			// Even if the type does not need to be generated, we need to iterate
+			// over all its fields to be able to mark as used any imported types
+			// used by those fields.
+			for _, mfield := range message.Field {
+				if !gogoproto.IsStdType(mfield) && !gogoproto.IsCustomType(mfield) && !gogoproto.IsCastType(mfield) {
+					g.RecordTypeUse(mfield.GetTypeName())
+				}
+			}
+		}
+	}
+
+	mc := &msgCtx{
+		goName:  goTypeName,
+		message: message,
+	}
+
+	if gogoproto.HasTypeDecl(message.file.FileDescriptorProto, message.DescriptorProto) {
+		g.generateMessageStruct(mc, topLevelFields)
+		g.P()
+	}
+	g.generateCommonMethods(mc)
+	g.P()
+	g.generateDefaultConstants(mc, topLevelFields)
+	g.P()
+	g.generateOneofDecls(mc, topLevelFields)
+	g.P()
+	g.generateGetters(mc, topLevelFields)
+	g.P()
+	g.generateSetters(mc, topLevelFields)
+	g.P()
+	g.generateOneofFuncs(mc, topLevelFields)
+	g.P()
+
+	var oneofTypes []string
+	for _, f := range topLevelFields {
+		if of, ok := f.(*oneofField); ok {
+			for _, osf := range of.subFields {
+				oneofTypes = append(oneofTypes, osf.oneofTypeName)
+			}
+		}
+	}
+
+	opts := message.Options
+	ms := &messageSymbol{
+		sym:           goTypeName,
+		hasExtensions: len(message.ExtensionRange) > 0,
+		isMessageSet:  opts != nil && opts.GetMessageSetWireFormat(),
+		oneofTypes:    oneofTypes,
+	}
+	g.file.addExport(message, ms)
+
+	for _, ext := range message.ext {
+		g.generateExtension(ext)
+	}
+
+	fullName := strings.Join(message.TypeName(), ".")
+	if g.file.Package != nil {
+		fullName = *g.file.Package + "." + fullName
+	}
+
+	g.addInitf("%s.RegisterType((*%s)(nil), %q)", g.Pkg["proto"], goTypeName, fullName)
+	if gogoproto.ImportsGoGoProto(g.file.FileDescriptorProto) && gogoproto.RegistersGolangProto(g.file.FileDescriptorProto) {
+		g.addInitf("%s.RegisterType((*%s)(nil), %q)", g.Pkg["golang_proto"], goTypeName, fullName)
+	}
+	if gogoproto.HasMessageName(g.file.FileDescriptorProto, message.DescriptorProto) {
+		g.P("func (*", goTypeName, ") XXX_MessageName() string {")
+		g.In()
+		g.P("return ", strconv.Quote(fullName))
+		g.Out()
+		g.P("}")
+	}
+	// Register types for native map types.
+	for _, k := range mapFieldKeys(mapFieldTypes) {
+		fullName := strings.TrimPrefix(*k.TypeName, ".")
+		g.addInitf("%s.RegisterMapType((%s)(nil), %q)", g.Pkg["proto"], mapFieldTypes[k], fullName)
+		if gogoproto.ImportsGoGoProto(g.file.FileDescriptorProto) && gogoproto.RegistersGolangProto(g.file.FileDescriptorProto) {
+			g.addInitf("%s.RegisterMapType((%s)(nil), %q)", g.Pkg["golang_proto"], mapFieldTypes[k], fullName)
+		}
+	}
+}
+
+type byTypeName []*descriptor.FieldDescriptorProto
+
+func (a byTypeName) Len() int           { return len(a) }
+func (a byTypeName) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a byTypeName) Less(i, j int) bool { return *a[i].TypeName < *a[j].TypeName }
+
+// mapFieldKeys returns the keys of m in a consistent order.
+func mapFieldKeys(m map[*descriptor.FieldDescriptorProto]string) []*descriptor.FieldDescriptorProto {
+	keys := make([]*descriptor.FieldDescriptorProto, 0, len(m))
+	for k := range m {
+		keys = append(keys, k)
+	}
+	sort.Sort(byTypeName(keys))
+	return keys
+}
+
+var escapeChars = [256]byte{
+	'a': '\a', 'b': '\b', 'f': '\f', 'n': '\n', 'r': '\r', 't': '\t', 'v': '\v', '\\': '\\', '"': '"', '\'': '\'', '?': '?',
+}
+
+// unescape reverses the "C" escaping that protoc does for default values of bytes fields.
+// It is best effort in that it effectively ignores malformed input. Seemingly invalid escape
+// sequences are conveyed, unmodified, into the decoded result.
+func unescape(s string) string {
+	// NB: Sadly, we can't use strconv.Unquote because protoc will escape both
+	// single and double quotes, but strconv.Unquote only allows one or the
+	// other (based on actual surrounding quotes of its input argument).
+
+	var out []byte
+	for len(s) > 0 {
+		// regular character, or too short to be valid escape
+		if s[0] != '\\' || len(s) < 2 {
+			out = append(out, s[0])
+			s = s[1:]
+		} else if c := escapeChars[s[1]]; c != 0 {
+			// escape sequence
+			out = append(out, c)
+			s = s[2:]
+		} else if s[1] == 'x' || s[1] == 'X' {
+			// hex escape, e.g. "\x80
+			if len(s) < 4 {
+				// too short to be valid
+				out = append(out, s[:2]...)
+				s = s[2:]
+				continue
+			}
+			v, err := strconv.ParseUint(s[2:4], 16, 8)
+			if err != nil {
+				out = append(out, s[:4]...)
+			} else {
+				out = append(out, byte(v))
+			}
+			s = s[4:]
+		} else if '0' <= s[1] && s[1] <= '7' {
+			// octal escape, can vary from 1 to 3 octal digits; e.g., "\0" "\40" or "\164"
+			// so consume up to 2 more bytes or up to end-of-string
+			n := len(s[1:]) - len(strings.TrimLeft(s[1:], "01234567"))
+			if n > 3 {
+				n = 3
+			}
+			v, err := strconv.ParseUint(s[1:1+n], 8, 8)
+			if err != nil {
+				out = append(out, s[:1+n]...)
+			} else {
+				out = append(out, byte(v))
+			}
+			s = s[1+n:]
+		} else {
+			// bad escape, just propagate the slash as-is
+			out = append(out, s[0])
+			s = s[1:]
+		}
+	}
+
+	return string(out)
+}
+
+func (g *Generator) generateExtension(ext *ExtensionDescriptor) {
+	ccTypeName := ext.DescName()
+
+	extObj := g.ObjectNamed(*ext.Extendee)
+	var extDesc *Descriptor
+	if id, ok := extObj.(*ImportedDescriptor); ok {
+		// This is extending a publicly imported message.
+		// We need the underlying type for goTag.
+		extDesc = id.o.(*Descriptor)
+	} else {
+		extDesc = extObj.(*Descriptor)
+	}
+	extendedType := "*" + g.TypeName(extObj) // always use the original
+	field := ext.FieldDescriptorProto
+	fieldType, wireType := g.GoType(ext.parent, field)
+	tag := g.goTag(extDesc, field, wireType)
+	g.RecordTypeUse(*ext.Extendee)
+	if n := ext.FieldDescriptorProto.TypeName; n != nil {
+		// foreign extension type
+		g.RecordTypeUse(*n)
+	}
+
+	typeName := ext.TypeName()
+
+	// Special case for proto2 message sets: If this extension is extending
+	// proto2.bridge.MessageSet, and its final name component is "message_set_extension",
+	// then drop that last component.
+	//
+	// TODO: This should be implemented in the text formatter rather than the generator.
+	// In addition, the situation for when to apply this special case is implemented
+	// differently in other languages:
+	// https://github.com/google/protobuf/blob/aff10976/src/google/protobuf/text_format.cc#L1560
+	if extDesc.GetOptions().GetMessageSetWireFormat() && typeName[len(typeName)-1] == "message_set_extension" {
+		typeName = typeName[:len(typeName)-1]
+	}
+
+	// For text formatting, the package must be exactly what the .proto file declares,
+	// ignoring overrides such as the go_package option, and with no dot/underscore mapping.
+	extName := strings.Join(typeName, ".")
+	if g.file.Package != nil {
+		extName = *g.file.Package + "." + extName
+	}
+
+	g.P("var ", ccTypeName, " = &", g.Pkg["proto"], ".ExtensionDesc{")
+	g.In()
+	g.P("ExtendedType: (", extendedType, ")(nil),")
+	g.P("ExtensionType: (", fieldType, ")(nil),")
+	g.P("Field: ", field.Number, ",")
+	g.P(`Name: "`, extName, `",`)
+	g.P("Tag: ", tag, ",")
+	g.P(`Filename: "`, g.file.GetName(), `",`)
+
+	g.Out()
+	g.P("}")
+	g.P()
+
+	g.addInitf("%s.RegisterExtension(%s)", g.Pkg["proto"], ext.DescName())
+
+	g.file.addExport(ext, constOrVarSymbol{ccTypeName, "var", ""})
+}
+
+func (g *Generator) generateInitFunction() {
+	if len(g.init) == 0 {
+		return
+	}
+	g.P("func init() {")
+	g.In()
+	for _, l := range g.init {
+		g.P(l)
+	}
+	g.Out()
+	g.P("}")
+	g.init = nil
+}
+
+func (g *Generator) generateFileDescriptor(file *FileDescriptor) {
+	// Make a copy and trim source_code_info data.
+	// TODO: Trim this more when we know exactly what we need.
+	pb := proto.Clone(file.FileDescriptorProto).(*descriptor.FileDescriptorProto)
+	pb.SourceCodeInfo = nil
+
+	b, err := proto.Marshal(pb)
+	if err != nil {
+		g.Fail(err.Error())
+	}
+
+	var buf bytes.Buffer
+	w, _ := gzip.NewWriterLevel(&buf, gzip.BestCompression)
+	w.Write(b)
+	w.Close()
+	b = buf.Bytes()
+
+	v := file.VarName()
+	g.P()
+	g.P("func init() { ", g.Pkg["proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ") }")
+	if gogoproto.ImportsGoGoProto(g.file.FileDescriptorProto) && gogoproto.RegistersGolangProto(g.file.FileDescriptorProto) {
+		g.P("func init() { ", g.Pkg["golang_proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ") }")
+	}
+	g.P("var ", v, " = []byte{")
+	g.In()
+	g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto")
+	for len(b) > 0 {
+		n := 16
+		if n > len(b) {
+			n = len(b)
+		}
+
+		s := ""
+		for _, c := range b[:n] {
+			s += fmt.Sprintf("0x%02x,", c)
+		}
+		g.P(s)
+
+		b = b[n:]
+	}
+	g.Out()
+	g.P("}")
+}
+
+func (g *Generator) generateEnumRegistration(enum *EnumDescriptor) {
+	// // We always print the full (proto-world) package name here.
+	pkg := enum.File().GetPackage()
+	if pkg != "" {
+		pkg += "."
+	}
+	// The full type name
+	typeName := enum.TypeName()
+	// The full type name, CamelCased.
+	ccTypeName := CamelCaseSlice(typeName)
+	g.addInitf("%s.RegisterEnum(%q, %[3]s_name, %[3]s_value)", g.Pkg["proto"], pkg+ccTypeName, ccTypeName)
+	if gogoproto.ImportsGoGoProto(g.file.FileDescriptorProto) && gogoproto.RegistersGolangProto(g.file.FileDescriptorProto) {
+		g.addInitf("%s.RegisterEnum(%q, %[3]s_name, %[3]s_value)", g.Pkg["golang_proto"], pkg+ccTypeName, ccTypeName)
+	}
+}
+
+// And now lots of helper functions.
+
+// Is c an ASCII lower-case letter?
+func isASCIILower(c byte) bool {
+	return 'a' <= c && c <= 'z'
+}
+
+// Is c an ASCII digit?
+func isASCIIDigit(c byte) bool {
+	return '0' <= c && c <= '9'
+}
+
+// CamelCase returns the CamelCased name.
+// If there is an interior underscore followed by a lower case letter,
+// drop the underscore and convert the letter to upper case.
+// There is a remote possibility of this rewrite causing a name collision,
+// but it's so remote we're prepared to pretend it's nonexistent - since the
+// C++ generator lowercases names, it's extremely unlikely to have two fields
+// with different capitalizations.
+// In short, _my_field_name_2 becomes XMyFieldName_2.
+func CamelCase(s string) string {
+	if s == "" {
+		return ""
+	}
+	t := make([]byte, 0, 32)
+	i := 0
+	if s[0] == '_' {
+		// Need a capital letter; drop the '_'.
+		t = append(t, 'X')
+		i++
+	}
+	// Invariant: if the next letter is lower case, it must be converted
+	// to upper case.
+	// That is, we process a word at a time, where words are marked by _ or
+	// upper case letter. Digits are treated as words.
+	for ; i < len(s); i++ {
+		c := s[i]
+		if c == '_' && i+1 < len(s) && isASCIILower(s[i+1]) {
+			continue // Skip the underscore in s.
+		}
+		if isASCIIDigit(c) {
+			t = append(t, c)
+			continue
+		}
+		// Assume we have a letter now - if not, it's a bogus identifier.
+		// The next word is a sequence of characters that must start upper case.
+		if isASCIILower(c) {
+			c ^= ' ' // Make it a capital letter.
+		}
+		t = append(t, c) // Guaranteed not lower case.
+		// Accept lower case sequence that follows.
+		for i+1 < len(s) && isASCIILower(s[i+1]) {
+			i++
+			t = append(t, s[i])
+		}
+	}
+	return string(t)
+}
+
+// CamelCaseSlice is like CamelCase, but the argument is a slice of strings to
+// be joined with "_".
+func CamelCaseSlice(elem []string) string { return CamelCase(strings.Join(elem, "_")) }
+
+// dottedSlice turns a sliced name into a dotted name.
+func dottedSlice(elem []string) string { return strings.Join(elem, ".") }
+
+// Is this field optional?
+func isOptional(field *descriptor.FieldDescriptorProto) bool {
+	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_OPTIONAL
+}
+
+// Is this field required?
+func isRequired(field *descriptor.FieldDescriptorProto) bool {
+	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REQUIRED
+}
+
+// Is this field repeated?
+func isRepeated(field *descriptor.FieldDescriptorProto) bool {
+	return field.Label != nil && *field.Label == descriptor.FieldDescriptorProto_LABEL_REPEATED
+}
+
+// Is this field a scalar numeric type?
+func IsScalar(field *descriptor.FieldDescriptorProto) bool {
+	if field.Type == nil {
+		return false
+	}
+	switch *field.Type {
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE,
+		descriptor.FieldDescriptorProto_TYPE_FLOAT,
+		descriptor.FieldDescriptorProto_TYPE_INT64,
+		descriptor.FieldDescriptorProto_TYPE_UINT64,
+		descriptor.FieldDescriptorProto_TYPE_INT32,
+		descriptor.FieldDescriptorProto_TYPE_FIXED64,
+		descriptor.FieldDescriptorProto_TYPE_FIXED32,
+		descriptor.FieldDescriptorProto_TYPE_BOOL,
+		descriptor.FieldDescriptorProto_TYPE_UINT32,
+		descriptor.FieldDescriptorProto_TYPE_ENUM,
+		descriptor.FieldDescriptorProto_TYPE_SFIXED32,
+		descriptor.FieldDescriptorProto_TYPE_SFIXED64,
+		descriptor.FieldDescriptorProto_TYPE_SINT32,
+		descriptor.FieldDescriptorProto_TYPE_SINT64:
+		return true
+	default:
+		return false
+	}
+}
+
+// badToUnderscore is the mapping function used to generate Go names from package names,
+// which can be dotted in the input .proto file.  It replaces non-identifier characters such as
+// dot or dash with underscore.
+func badToUnderscore(r rune) rune {
+	if unicode.IsLetter(r) || unicode.IsDigit(r) || r == '_' {
+		return r
+	}
+	return '_'
+}
+
+// baseName returns the last path element of the name, with the last dotted suffix removed.
+func baseName(name string) string {
+	// First, find the last element
+	if i := strings.LastIndex(name, "/"); i >= 0 {
+		name = name[i+1:]
+	}
+	// Now drop the suffix
+	if i := strings.LastIndex(name, "."); i >= 0 {
+		name = name[0:i]
+	}
+	return name
+}
+
+// The SourceCodeInfo message describes the location of elements of a parsed
+// .proto file by way of a "path", which is a sequence of integers that
+// describe the route from a FileDescriptorProto to the relevant submessage.
+// The path alternates between a field number of a repeated field, and an index
+// into that repeated field. The constants below define the field numbers that
+// are used.
+//
+// See descriptor.proto for more information about this.
+const (
+	// tag numbers in FileDescriptorProto
+	packagePath = 2 // package
+	messagePath = 4 // message_type
+	enumPath    = 5 // enum_type
+	// tag numbers in DescriptorProto
+	messageFieldPath   = 2 // field
+	messageMessagePath = 3 // nested_type
+	messageEnumPath    = 4 // enum_type
+	messageOneofPath   = 8 // oneof_decl
+	// tag numbers in EnumDescriptorProto
+	enumValuePath = 2 // value
+)
+
+var supportTypeAliases bool
+
+func init() {
+	for _, tag := range build.Default.ReleaseTags {
+		if tag == "go1.9" {
+			supportTypeAliases = true
+			return
+		}
+	}
+}
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go
new file mode 100644
index 0000000000000..7091e281cb1ad
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/helper.go
@@ -0,0 +1,461 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 generator
+
+import (
+	"bytes"
+	"go/parser"
+	"go/printer"
+	"go/token"
+	"path"
+	"strings"
+
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	plugin "github.com/gogo/protobuf/protoc-gen-gogo/plugin"
+)
+
+func (d *FileDescriptor) Messages() []*Descriptor {
+	return d.desc
+}
+
+func (d *FileDescriptor) Enums() []*EnumDescriptor {
+	return d.enum
+}
+
+func (d *Descriptor) IsGroup() bool {
+	return d.group
+}
+
+func (g *Generator) IsGroup(field *descriptor.FieldDescriptorProto) bool {
+	if d, ok := g.typeNameToObject[field.GetTypeName()].(*Descriptor); ok {
+		return d.IsGroup()
+	}
+	return false
+}
+
+func (g *Generator) TypeNameByObject(typeName string) Object {
+	o, ok := g.typeNameToObject[typeName]
+	if !ok {
+		g.Fail("can't find object with type", typeName)
+	}
+	return o
+}
+
+func (g *Generator) OneOfTypeName(message *Descriptor, field *descriptor.FieldDescriptorProto) string {
+	typeName := message.TypeName()
+	ccTypeName := CamelCaseSlice(typeName)
+	fieldName := g.GetOneOfFieldName(message, field)
+	tname := ccTypeName + "_" + fieldName
+	// It is possible for this to collide with a message or enum
+	// nested in this message. Check for collisions.
+	ok := true
+	for _, desc := range message.nested {
+		if strings.Join(desc.TypeName(), "_") == tname {
+			ok = false
+			break
+		}
+	}
+	for _, enum := range message.enums {
+		if strings.Join(enum.TypeName(), "_") == tname {
+			ok = false
+			break
+		}
+	}
+	if !ok {
+		tname += "_"
+	}
+	return tname
+}
+
+type PluginImports interface {
+	NewImport(pkg string) Single
+	GenerateImports(file *FileDescriptor)
+}
+
+type pluginImports struct {
+	generator *Generator
+	singles   []Single
+}
+
+func NewPluginImports(generator *Generator) *pluginImports {
+	return &pluginImports{generator, make([]Single, 0)}
+}
+
+func (this *pluginImports) NewImport(pkg string) Single {
+	imp := newImportedPackage(this.generator.ImportPrefix, pkg)
+	this.singles = append(this.singles, imp)
+	return imp
+}
+
+func (this *pluginImports) GenerateImports(file *FileDescriptor) {
+	for _, s := range this.singles {
+		if s.IsUsed() {
+			this.generator.PrintImport(GoPackageName(s.Name()), GoImportPath(s.Location()))
+		}
+	}
+}
+
+type Single interface {
+	Use() string
+	IsUsed() bool
+	Name() string
+	Location() string
+}
+
+type importedPackage struct {
+	used         bool
+	pkg          string
+	name         string
+	importPrefix string
+}
+
+func newImportedPackage(importPrefix string, pkg string) *importedPackage {
+	return &importedPackage{
+		pkg:          pkg,
+		importPrefix: importPrefix,
+	}
+}
+
+func (this *importedPackage) Use() string {
+	if !this.used {
+		this.name = string(cleanPackageName(this.pkg))
+		this.used = true
+	}
+	return this.name
+}
+
+func (this *importedPackage) IsUsed() bool {
+	return this.used
+}
+
+func (this *importedPackage) Name() string {
+	return this.name
+}
+
+func (this *importedPackage) Location() string {
+	return this.importPrefix + this.pkg
+}
+
+func (g *Generator) GetFieldName(message *Descriptor, field *descriptor.FieldDescriptorProto) string {
+	goTyp, _ := g.GoType(message, field)
+	fieldname := CamelCase(*field.Name)
+	if gogoproto.IsCustomName(field) {
+		fieldname = gogoproto.GetCustomName(field)
+	}
+	if gogoproto.IsEmbed(field) {
+		fieldname = EmbedFieldName(goTyp)
+	}
+	if field.OneofIndex != nil {
+		fieldname = message.OneofDecl[int(*field.OneofIndex)].GetName()
+		fieldname = CamelCase(fieldname)
+	}
+	for _, f := range methodNames {
+		if f == fieldname {
+			return fieldname + "_"
+		}
+	}
+	if !gogoproto.IsProtoSizer(message.file.FileDescriptorProto, message.DescriptorProto) {
+		if fieldname == "Size" {
+			return fieldname + "_"
+		}
+	}
+	return fieldname
+}
+
+func (g *Generator) GetOneOfFieldName(message *Descriptor, field *descriptor.FieldDescriptorProto) string {
+	goTyp, _ := g.GoType(message, field)
+	fieldname := CamelCase(*field.Name)
+	if gogoproto.IsCustomName(field) {
+		fieldname = gogoproto.GetCustomName(field)
+	}
+	if gogoproto.IsEmbed(field) {
+		fieldname = EmbedFieldName(goTyp)
+	}
+	for _, f := range methodNames {
+		if f == fieldname {
+			return fieldname + "_"
+		}
+	}
+	if !gogoproto.IsProtoSizer(message.file.FileDescriptorProto, message.DescriptorProto) {
+		if fieldname == "Size" {
+			return fieldname + "_"
+		}
+	}
+	return fieldname
+}
+
+func (g *Generator) IsMap(field *descriptor.FieldDescriptorProto) bool {
+	if !field.IsMessage() {
+		return false
+	}
+	byName := g.ObjectNamed(field.GetTypeName())
+	desc, ok := byName.(*Descriptor)
+	if byName == nil || !ok || !desc.GetOptions().GetMapEntry() {
+		return false
+	}
+	return true
+}
+
+func (g *Generator) GetMapKeyField(field, keyField *descriptor.FieldDescriptorProto) *descriptor.FieldDescriptorProto {
+	if !gogoproto.IsCastKey(field) {
+		return keyField
+	}
+	keyField = proto.Clone(keyField).(*descriptor.FieldDescriptorProto)
+	if keyField.Options == nil {
+		keyField.Options = &descriptor.FieldOptions{}
+	}
+	keyType := gogoproto.GetCastKey(field)
+	if err := proto.SetExtension(keyField.Options, gogoproto.E_Casttype, &keyType); err != nil {
+		g.Fail(err.Error())
+	}
+	return keyField
+}
+
+func (g *Generator) GetMapValueField(field, valField *descriptor.FieldDescriptorProto) *descriptor.FieldDescriptorProto {
+	if gogoproto.IsCustomType(field) && gogoproto.IsCastValue(field) {
+		g.Fail("cannot have a customtype and casttype: ", field.String())
+	}
+	valField = proto.Clone(valField).(*descriptor.FieldDescriptorProto)
+	if valField.Options == nil {
+		valField.Options = &descriptor.FieldOptions{}
+	}
+
+	stdtime := gogoproto.IsStdTime(field)
+	if stdtime {
+		if err := proto.SetExtension(valField.Options, gogoproto.E_Stdtime, &stdtime); err != nil {
+			g.Fail(err.Error())
+		}
+	}
+
+	stddur := gogoproto.IsStdDuration(field)
+	if stddur {
+		if err := proto.SetExtension(valField.Options, gogoproto.E_Stdduration, &stddur); err != nil {
+			g.Fail(err.Error())
+		}
+	}
+
+	wktptr := gogoproto.IsWktPtr(field)
+	if wktptr {
+		if err := proto.SetExtension(valField.Options, gogoproto.E_Wktpointer, &wktptr); err != nil {
+			g.Fail(err.Error())
+		}
+	}
+
+	if valType := gogoproto.GetCastValue(field); len(valType) > 0 {
+		if err := proto.SetExtension(valField.Options, gogoproto.E_Casttype, &valType); err != nil {
+			g.Fail(err.Error())
+		}
+	}
+	if valType := gogoproto.GetCustomType(field); len(valType) > 0 {
+		if err := proto.SetExtension(valField.Options, gogoproto.E_Customtype, &valType); err != nil {
+			g.Fail(err.Error())
+		}
+	}
+
+	nullable := gogoproto.IsNullable(field)
+	if err := proto.SetExtension(valField.Options, gogoproto.E_Nullable, &nullable); err != nil {
+		g.Fail(err.Error())
+	}
+	return valField
+}
+
+// GoMapValueTypes returns the map value Go type and the alias map value Go type (for casting), taking into
+// account whether the map is nullable or the value is a message.
+func GoMapValueTypes(mapField, valueField *descriptor.FieldDescriptorProto, goValueType, goValueAliasType string) (nullable bool, outGoType string, outGoAliasType string) {
+	nullable = gogoproto.IsNullable(mapField) && (valueField.IsMessage() || gogoproto.IsCustomType(mapField))
+	if nullable {
+		// ensure the non-aliased Go value type is a pointer for consistency
+		if strings.HasPrefix(goValueType, "*") {
+			outGoType = goValueType
+		} else {
+			outGoType = "*" + goValueType
+		}
+		outGoAliasType = goValueAliasType
+	} else {
+		outGoType = strings.Replace(goValueType, "*", "", 1)
+		outGoAliasType = strings.Replace(goValueAliasType, "*", "", 1)
+	}
+	return
+}
+
+func GoTypeToName(goTyp string) string {
+	return strings.Replace(strings.Replace(goTyp, "*", "", -1), "[]", "", -1)
+}
+
+func EmbedFieldName(goTyp string) string {
+	goTyp = GoTypeToName(goTyp)
+	goTyps := strings.Split(goTyp, ".")
+	if len(goTyps) == 1 {
+		return goTyp
+	}
+	if len(goTyps) == 2 {
+		return goTyps[1]
+	}
+	panic("unreachable")
+}
+
+func (g *Generator) GeneratePlugin(p Plugin) {
+	plugins = []Plugin{p}
+	p.Init(g)
+	// Generate the output. The generator runs for every file, even the files
+	// that we don't generate output for, so that we can collate the full list
+	// of exported symbols to support public imports.
+	genFileMap := make(map[*FileDescriptor]bool, len(g.genFiles))
+	for _, file := range g.genFiles {
+		genFileMap[file] = true
+	}
+	for _, file := range g.allFiles {
+		g.Reset()
+		g.writeOutput = genFileMap[file]
+		g.generatePlugin(file, p)
+		if !g.writeOutput {
+			continue
+		}
+		g.Response.File = append(g.Response.File, &plugin.CodeGeneratorResponse_File{
+			Name:    proto.String(file.goFileName(g.pathType)),
+			Content: proto.String(g.String()),
+		})
+	}
+}
+
+func (g *Generator) SetFile(filename string) {
+	g.file = g.fileByName(filename)
+}
+
+func (g *Generator) generatePlugin(file *FileDescriptor, p Plugin) {
+	g.writtenImports = make(map[string]bool)
+	g.usedPackages = make(map[GoImportPath]bool)
+	g.packageNames = make(map[GoImportPath]GoPackageName)
+	g.usedPackageNames = make(map[GoPackageName]bool)
+	g.addedImports = make(map[GoImportPath]bool)
+	g.file = file
+
+	// Run the plugins before the imports so we know which imports are necessary.
+	p.Generate(file)
+
+	// Generate header and imports last, though they appear first in the output.
+	rem := g.Buffer
+	g.Buffer = new(bytes.Buffer)
+	g.generateHeader()
+	// p.GenerateImports(g.file)
+	g.generateImports()
+	if !g.writeOutput {
+		return
+	}
+	g.Write(rem.Bytes())
+
+	// Reformat generated code.
+	contents := string(g.Buffer.Bytes())
+	fset := token.NewFileSet()
+	ast, err := parser.ParseFile(fset, "", g, parser.ParseComments)
+	if err != nil {
+		g.Fail("bad Go source code was generated:", contents, err.Error())
+		return
+	}
+	g.Reset()
+	err = (&printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}).Fprint(g, fset, ast)
+	if err != nil {
+		g.Fail("generated Go source code could not be reformatted:", err.Error())
+	}
+}
+
+func GetCustomType(field *descriptor.FieldDescriptorProto) (packageName string, typ string, err error) {
+	return getCustomType(field)
+}
+
+func getCustomType(field *descriptor.FieldDescriptorProto) (packageName string, typ string, err error) {
+	if field.Options != nil {
+		var v interface{}
+		v, err = proto.GetExtension(field.Options, gogoproto.E_Customtype)
+		if err == nil && v.(*string) != nil {
+			ctype := *(v.(*string))
+			packageName, typ = splitCPackageType(ctype)
+			return packageName, typ, nil
+		}
+	}
+	return "", "", err
+}
+
+func splitCPackageType(ctype string) (packageName string, typ string) {
+	ss := strings.Split(ctype, ".")
+	if len(ss) == 1 {
+		return "", ctype
+	}
+	packageName = strings.Join(ss[0:len(ss)-1], ".")
+	typeName := ss[len(ss)-1]
+	importStr := strings.Map(badToUnderscore, packageName)
+	typ = importStr + "." + typeName
+	return packageName, typ
+}
+
+func getCastType(field *descriptor.FieldDescriptorProto) (packageName string, typ string, err error) {
+	if field.Options != nil {
+		var v interface{}
+		v, err = proto.GetExtension(field.Options, gogoproto.E_Casttype)
+		if err == nil && v.(*string) != nil {
+			ctype := *(v.(*string))
+			packageName, typ = splitCPackageType(ctype)
+			return packageName, typ, nil
+		}
+	}
+	return "", "", err
+}
+
+func FileName(file *FileDescriptor) string {
+	fname := path.Base(file.FileDescriptorProto.GetName())
+	fname = strings.Replace(fname, ".proto", "", -1)
+	fname = strings.Replace(fname, "-", "_", -1)
+	fname = strings.Replace(fname, ".", "_", -1)
+	return CamelCase(fname)
+}
+
+func (g *Generator) AllFiles() *descriptor.FileDescriptorSet {
+	set := &descriptor.FileDescriptorSet{}
+	set.File = make([]*descriptor.FileDescriptorProto, len(g.allFiles))
+	for i := range g.allFiles {
+		set.File[i] = g.allFiles[i].FileDescriptorProto
+	}
+	return set
+}
+
+func (d *Descriptor) Path() string {
+	return d.path
+}
+
+func (g *Generator) useTypes() string {
+	pkg := strings.Map(badToUnderscore, "github.com/gogo/protobuf/types")
+	g.customImports = append(g.customImports, "github.com/gogo/protobuf/types")
+	return pkg
+}
+
+func (d *FileDescriptor) GoPackageName() string {
+	return string(d.packageName)
+}
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/internal/remap/remap.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/internal/remap/remap.go
new file mode 100644
index 0000000000000..a9b61036cc0f2
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/generator/internal/remap/remap.go
@@ -0,0 +1,117 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2017 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+Package remap handles tracking the locations of Go tokens in a source text
+across a rewrite by the Go formatter.
+*/
+package remap
+
+import (
+	"fmt"
+	"go/scanner"
+	"go/token"
+)
+
+// A Location represents a span of byte offsets in the source text.
+type Location struct {
+	Pos, End int // End is exclusive
+}
+
+// A Map represents a mapping between token locations in an input source text
+// and locations in the correspnding output text.
+type Map map[Location]Location
+
+// Find reports whether the specified span is recorded by m, and if so returns
+// the new location it was mapped to. If the input span was not found, the
+// returned location is the same as the input.
+func (m Map) Find(pos, end int) (Location, bool) {
+	key := Location{
+		Pos: pos,
+		End: end,
+	}
+	if loc, ok := m[key]; ok {
+		return loc, true
+	}
+	return key, false
+}
+
+func (m Map) add(opos, oend, npos, nend int) {
+	m[Location{Pos: opos, End: oend}] = Location{Pos: npos, End: nend}
+}
+
+// Compute constructs a location mapping from input to output.  An error is
+// reported if any of the tokens of output cannot be mapped.
+func Compute(input, output []byte) (Map, error) {
+	itok := tokenize(input)
+	otok := tokenize(output)
+	if len(itok) != len(otok) {
+		return nil, fmt.Errorf("wrong number of tokens, %d ≠ %d", len(itok), len(otok))
+	}
+	m := make(Map)
+	for i, ti := range itok {
+		to := otok[i]
+		if ti.Token != to.Token {
+			return nil, fmt.Errorf("token %d type mismatch: %s ≠ %s", i+1, ti, to)
+		}
+		m.add(ti.pos, ti.end, to.pos, to.end)
+	}
+	return m, nil
+}
+
+// tokinfo records the span and type of a source token.
+type tokinfo struct {
+	pos, end int
+	token.Token
+}
+
+func tokenize(src []byte) []tokinfo {
+	fs := token.NewFileSet()
+	var s scanner.Scanner
+	s.Init(fs.AddFile("src", fs.Base(), len(src)), src, nil, scanner.ScanComments)
+	var info []tokinfo
+	for {
+		pos, next, lit := s.Scan()
+		switch next {
+		case token.SEMICOLON:
+			continue
+		}
+		info = append(info, tokinfo{
+			pos:   int(pos - 1),
+			end:   int(pos + token.Pos(len(lit)) - 1),
+			Token: next,
+		})
+		if next == token.EOF {
+			break
+		}
+	}
+	return info
+}
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/grpc/grpc.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/grpc/grpc.go
new file mode 100644
index 0000000000000..cf527f8e015ea
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/grpc/grpc.go
@@ -0,0 +1,536 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2015 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Package grpc outputs gRPC service descriptions in Go code.
+// It runs as a plugin for the Go protocol buffer compiler plugin.
+// It is linked in to protoc-gen-go.
+package grpc
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+
+	pb "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+// generatedCodeVersion indicates a version of the generated code.
+// It is incremented whenever an incompatibility between the generated code and
+// the grpc package is introduced; the generated code references
+// a constant, grpc.SupportPackageIsVersionN (where N is generatedCodeVersion).
+const generatedCodeVersion = 4
+
+// Paths for packages used by code generated in this file,
+// relative to the import_prefix of the generator.Generator.
+const (
+	contextPkgPath = "context"
+	grpcPkgPath    = "google.golang.org/grpc"
+	codePkgPath    = "google.golang.org/grpc/codes"
+	statusPkgPath  = "google.golang.org/grpc/status"
+)
+
+func init() {
+	generator.RegisterPlugin(new(grpc))
+}
+
+// grpc is an implementation of the Go protocol buffer compiler's
+// plugin architecture.  It generates bindings for gRPC support.
+type grpc struct {
+	gen *generator.Generator
+}
+
+// Name returns the name of this plugin, "grpc".
+func (g *grpc) Name() string {
+	return "grpc"
+}
+
+// The names for packages imported in the generated code.
+// They may vary from the final path component of the import path
+// if the name is used by other packages.
+var (
+	contextPkg string
+	grpcPkg    string
+)
+
+// Init initializes the plugin.
+func (g *grpc) Init(gen *generator.Generator) {
+	g.gen = gen
+}
+
+// Given a type name defined in a .proto, return its object.
+// Also record that we're using it, to guarantee the associated import.
+func (g *grpc) objectNamed(name string) generator.Object {
+	g.gen.RecordTypeUse(name)
+	return g.gen.ObjectNamed(name)
+}
+
+// Given a type name defined in a .proto, return its name as we will print it.
+func (g *grpc) typeName(str string) string {
+	return g.gen.TypeName(g.objectNamed(str))
+}
+
+// P forwards to g.gen.P.
+func (g *grpc) P(args ...interface{}) { g.gen.P(args...) }
+
+// Generate generates code for the services in the given file.
+func (g *grpc) Generate(file *generator.FileDescriptor) {
+	if len(file.FileDescriptorProto.Service) == 0 {
+		return
+	}
+
+	contextPkg = string(g.gen.AddImport(contextPkgPath))
+	grpcPkg = string(g.gen.AddImport(grpcPkgPath))
+
+	g.P("// Reference imports to suppress errors if they are not otherwise used.")
+	g.P("var _ ", contextPkg, ".Context")
+	g.P("var _ ", grpcPkg, ".ClientConn")
+	g.P()
+
+	// Assert version compatibility.
+	g.P("// This is a compile-time assertion to ensure that this generated file")
+	g.P("// is compatible with the grpc package it is being compiled against.")
+	g.P("const _ = ", grpcPkg, ".SupportPackageIsVersion", generatedCodeVersion)
+	g.P()
+
+	for i, service := range file.FileDescriptorProto.Service {
+		g.generateService(file, service, i)
+	}
+}
+
+// GenerateImports generates the import declaration for this file.
+func (g *grpc) GenerateImports(file *generator.FileDescriptor) {}
+
+// reservedClientName records whether a client name is reserved on the client side.
+var reservedClientName = map[string]bool{
+	// TODO: do we need any in gRPC?
+}
+
+func unexport(s string) string { return strings.ToLower(s[:1]) + s[1:] }
+
+// deprecationComment is the standard comment added to deprecated
+// messages, fields, enums, and enum values.
+var deprecationComment = "// Deprecated: Do not use."
+
+// generateService generates all the code for the named service.
+func (g *grpc) generateService(file *generator.FileDescriptor, service *pb.ServiceDescriptorProto, index int) {
+	path := fmt.Sprintf("6,%d", index) // 6 means service.
+
+	origServName := service.GetName()
+	fullServName := origServName
+	if pkg := file.GetPackage(); pkg != "" {
+		fullServName = pkg + "." + fullServName
+	}
+	servName := generator.CamelCase(origServName)
+	deprecated := service.GetOptions().GetDeprecated()
+
+	g.P()
+	g.P(fmt.Sprintf(`// %sClient is the client API for %s service.
+//
+// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.`, servName, servName))
+
+	// Client interface.
+	if deprecated {
+		g.P("//")
+		g.P(deprecationComment)
+	}
+	g.P("type ", servName, "Client interface {")
+	for i, method := range service.Method {
+		g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service.
+		g.P(g.generateClientSignature(servName, method))
+	}
+	g.P("}")
+	g.P()
+
+	// Client structure.
+	g.P("type ", unexport(servName), "Client struct {")
+	g.P("cc *", grpcPkg, ".ClientConn")
+	g.P("}")
+	g.P()
+
+	// NewClient factory.
+	if deprecated {
+		g.P(deprecationComment)
+	}
+	g.P("func New", servName, "Client (cc *", grpcPkg, ".ClientConn) ", servName, "Client {")
+	g.P("return &", unexport(servName), "Client{cc}")
+	g.P("}")
+	g.P()
+
+	var methodIndex, streamIndex int
+	serviceDescVar := "_" + servName + "_serviceDesc"
+	// Client method implementations.
+	for _, method := range service.Method {
+		var descExpr string
+		if !method.GetServerStreaming() && !method.GetClientStreaming() {
+			// Unary RPC method
+			descExpr = fmt.Sprintf("&%s.Methods[%d]", serviceDescVar, methodIndex)
+			methodIndex++
+		} else {
+			// Streaming RPC method
+			descExpr = fmt.Sprintf("&%s.Streams[%d]", serviceDescVar, streamIndex)
+			streamIndex++
+		}
+		g.generateClientMethod(servName, fullServName, serviceDescVar, method, descExpr)
+	}
+
+	// Server interface.
+	serverType := servName + "Server"
+	g.P("// ", serverType, " is the server API for ", servName, " service.")
+	if deprecated {
+		g.P("//")
+		g.P(deprecationComment)
+	}
+	g.P("type ", serverType, " interface {")
+	for i, method := range service.Method {
+		g.gen.PrintComments(fmt.Sprintf("%s,2,%d", path, i)) // 2 means method in a service.
+		g.P(g.generateServerSignature(servName, method))
+	}
+	g.P("}")
+	g.P()
+
+	// Server Unimplemented struct for forward compatability.
+	if deprecated {
+		g.P(deprecationComment)
+	}
+	g.generateUnimplementedServer(servName, service)
+
+	// Server registration.
+	if deprecated {
+		g.P(deprecationComment)
+	}
+	g.P("func Register", servName, "Server(s *", grpcPkg, ".Server, srv ", serverType, ") {")
+	g.P("s.RegisterService(&", serviceDescVar, `, srv)`)
+	g.P("}")
+	g.P()
+
+	// Server handler implementations.
+	var handlerNames []string
+	for _, method := range service.Method {
+		hname := g.generateServerMethod(servName, fullServName, method)
+		handlerNames = append(handlerNames, hname)
+	}
+
+	// Service descriptor.
+	g.P("var ", serviceDescVar, " = ", grpcPkg, ".ServiceDesc {")
+	g.P("ServiceName: ", strconv.Quote(fullServName), ",")
+	g.P("HandlerType: (*", serverType, ")(nil),")
+	g.P("Methods: []", grpcPkg, ".MethodDesc{")
+	for i, method := range service.Method {
+		if method.GetServerStreaming() || method.GetClientStreaming() {
+			continue
+		}
+		g.P("{")
+		g.P("MethodName: ", strconv.Quote(method.GetName()), ",")
+		g.P("Handler: ", handlerNames[i], ",")
+		g.P("},")
+	}
+	g.P("},")
+	g.P("Streams: []", grpcPkg, ".StreamDesc{")
+	for i, method := range service.Method {
+		if !method.GetServerStreaming() && !method.GetClientStreaming() {
+			continue
+		}
+		g.P("{")
+		g.P("StreamName: ", strconv.Quote(method.GetName()), ",")
+		g.P("Handler: ", handlerNames[i], ",")
+		if method.GetServerStreaming() {
+			g.P("ServerStreams: true,")
+		}
+		if method.GetClientStreaming() {
+			g.P("ClientStreams: true,")
+		}
+		g.P("},")
+	}
+	g.P("},")
+	g.P("Metadata: \"", file.GetName(), "\",")
+	g.P("}")
+	g.P()
+}
+
+// generateUnimplementedServer creates the unimplemented server struct
+func (g *grpc) generateUnimplementedServer(servName string, service *pb.ServiceDescriptorProto) {
+	serverType := servName + "Server"
+	g.P("// Unimplemented", serverType, " can be embedded to have forward compatible implementations.")
+	g.P("type Unimplemented", serverType, " struct {")
+	g.P("}")
+	g.P()
+	// Unimplemented<service_name>Server's concrete methods
+	for _, method := range service.Method {
+		g.generateServerMethodConcrete(servName, method)
+	}
+	g.P()
+}
+
+// generateServerMethodConcrete returns unimplemented methods which ensure forward compatibility
+func (g *grpc) generateServerMethodConcrete(servName string, method *pb.MethodDescriptorProto) {
+	header := g.generateServerSignatureWithParamNames(servName, method)
+	g.P("func (*Unimplemented", servName, "Server) ", header, " {")
+	var nilArg string
+	if !method.GetServerStreaming() && !method.GetClientStreaming() {
+		nilArg = "nil, "
+	}
+	methName := generator.CamelCase(method.GetName())
+	statusPkg := string(g.gen.AddImport(statusPkgPath))
+	codePkg := string(g.gen.AddImport(codePkgPath))
+	g.P("return ", nilArg, statusPkg, `.Errorf(`, codePkg, `.Unimplemented, "method `, methName, ` not implemented")`)
+	g.P("}")
+}
+
+// generateClientSignature returns the client-side signature for a method.
+func (g *grpc) generateClientSignature(servName string, method *pb.MethodDescriptorProto) string {
+	origMethName := method.GetName()
+	methName := generator.CamelCase(origMethName)
+	if reservedClientName[methName] {
+		methName += "_"
+	}
+	reqArg := ", in *" + g.typeName(method.GetInputType())
+	if method.GetClientStreaming() {
+		reqArg = ""
+	}
+	respName := "*" + g.typeName(method.GetOutputType())
+	if method.GetServerStreaming() || method.GetClientStreaming() {
+		respName = servName + "_" + generator.CamelCase(origMethName) + "Client"
+	}
+	return fmt.Sprintf("%s(ctx %s.Context%s, opts ...%s.CallOption) (%s, error)", methName, contextPkg, reqArg, grpcPkg, respName)
+}
+
+func (g *grpc) generateClientMethod(servName, fullServName, serviceDescVar string, method *pb.MethodDescriptorProto, descExpr string) {
+	sname := fmt.Sprintf("/%s/%s", fullServName, method.GetName())
+	methName := generator.CamelCase(method.GetName())
+	inType := g.typeName(method.GetInputType())
+	outType := g.typeName(method.GetOutputType())
+
+	if method.GetOptions().GetDeprecated() {
+		g.P(deprecationComment)
+	}
+	g.P("func (c *", unexport(servName), "Client) ", g.generateClientSignature(servName, method), "{")
+	if !method.GetServerStreaming() && !method.GetClientStreaming() {
+		g.P("out := new(", outType, ")")
+		// TODO: Pass descExpr to Invoke.
+		g.P(`err := c.cc.Invoke(ctx, "`, sname, `", in, out, opts...)`)
+		g.P("if err != nil { return nil, err }")
+		g.P("return out, nil")
+		g.P("}")
+		g.P()
+		return
+	}
+	streamType := unexport(servName) + methName + "Client"
+	g.P("stream, err := c.cc.NewStream(ctx, ", descExpr, `, "`, sname, `", opts...)`)
+	g.P("if err != nil { return nil, err }")
+	g.P("x := &", streamType, "{stream}")
+	if !method.GetClientStreaming() {
+		g.P("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }")
+		g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }")
+	}
+	g.P("return x, nil")
+	g.P("}")
+	g.P()
+
+	genSend := method.GetClientStreaming()
+	genRecv := method.GetServerStreaming()
+	genCloseAndRecv := !method.GetServerStreaming()
+
+	// Stream auxiliary types and methods.
+	g.P("type ", servName, "_", methName, "Client interface {")
+	if genSend {
+		g.P("Send(*", inType, ") error")
+	}
+	if genRecv {
+		g.P("Recv() (*", outType, ", error)")
+	}
+	if genCloseAndRecv {
+		g.P("CloseAndRecv() (*", outType, ", error)")
+	}
+	g.P(grpcPkg, ".ClientStream")
+	g.P("}")
+	g.P()
+
+	g.P("type ", streamType, " struct {")
+	g.P(grpcPkg, ".ClientStream")
+	g.P("}")
+	g.P()
+
+	if genSend {
+		g.P("func (x *", streamType, ") Send(m *", inType, ") error {")
+		g.P("return x.ClientStream.SendMsg(m)")
+		g.P("}")
+		g.P()
+	}
+	if genRecv {
+		g.P("func (x *", streamType, ") Recv() (*", outType, ", error) {")
+		g.P("m := new(", outType, ")")
+		g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }")
+		g.P("return m, nil")
+		g.P("}")
+		g.P()
+	}
+	if genCloseAndRecv {
+		g.P("func (x *", streamType, ") CloseAndRecv() (*", outType, ", error) {")
+		g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }")
+		g.P("m := new(", outType, ")")
+		g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }")
+		g.P("return m, nil")
+		g.P("}")
+		g.P()
+	}
+}
+
+// generateServerSignatureWithParamNames returns the server-side signature for a method with parameter names.
+func (g *grpc) generateServerSignatureWithParamNames(servName string, method *pb.MethodDescriptorProto) string {
+	origMethName := method.GetName()
+	methName := generator.CamelCase(origMethName)
+	if reservedClientName[methName] {
+		methName += "_"
+	}
+
+	var reqArgs []string
+	ret := "error"
+	if !method.GetServerStreaming() && !method.GetClientStreaming() {
+		reqArgs = append(reqArgs, "ctx "+contextPkg+".Context")
+		ret = "(*" + g.typeName(method.GetOutputType()) + ", error)"
+	}
+	if !method.GetClientStreaming() {
+		reqArgs = append(reqArgs, "req *"+g.typeName(method.GetInputType()))
+	}
+	if method.GetServerStreaming() || method.GetClientStreaming() {
+		reqArgs = append(reqArgs, "srv "+servName+"_"+generator.CamelCase(origMethName)+"Server")
+	}
+
+	return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret
+}
+
+// generateServerSignature returns the server-side signature for a method.
+func (g *grpc) generateServerSignature(servName string, method *pb.MethodDescriptorProto) string {
+	origMethName := method.GetName()
+	methName := generator.CamelCase(origMethName)
+	if reservedClientName[methName] {
+		methName += "_"
+	}
+
+	var reqArgs []string
+	ret := "error"
+	if !method.GetServerStreaming() && !method.GetClientStreaming() {
+		reqArgs = append(reqArgs, contextPkg+".Context")
+		ret = "(*" + g.typeName(method.GetOutputType()) + ", error)"
+	}
+	if !method.GetClientStreaming() {
+		reqArgs = append(reqArgs, "*"+g.typeName(method.GetInputType()))
+	}
+	if method.GetServerStreaming() || method.GetClientStreaming() {
+		reqArgs = append(reqArgs, servName+"_"+generator.CamelCase(origMethName)+"Server")
+	}
+
+	return methName + "(" + strings.Join(reqArgs, ", ") + ") " + ret
+}
+
+func (g *grpc) generateServerMethod(servName, fullServName string, method *pb.MethodDescriptorProto) string {
+	methName := generator.CamelCase(method.GetName())
+	hname := fmt.Sprintf("_%s_%s_Handler", servName, methName)
+	inType := g.typeName(method.GetInputType())
+	outType := g.typeName(method.GetOutputType())
+
+	if !method.GetServerStreaming() && !method.GetClientStreaming() {
+		g.P("func ", hname, "(srv interface{}, ctx ", contextPkg, ".Context, dec func(interface{}) error, interceptor ", grpcPkg, ".UnaryServerInterceptor) (interface{}, error) {")
+		g.P("in := new(", inType, ")")
+		g.P("if err := dec(in); err != nil { return nil, err }")
+		g.P("if interceptor == nil { return srv.(", servName, "Server).", methName, "(ctx, in) }")
+		g.P("info := &", grpcPkg, ".UnaryServerInfo{")
+		g.P("Server: srv,")
+		g.P("FullMethod: ", strconv.Quote(fmt.Sprintf("/%s/%s", fullServName, methName)), ",")
+		g.P("}")
+		g.P("handler := func(ctx ", contextPkg, ".Context, req interface{}) (interface{}, error) {")
+		g.P("return srv.(", servName, "Server).", methName, "(ctx, req.(*", inType, "))")
+		g.P("}")
+		g.P("return interceptor(ctx, in, info, handler)")
+		g.P("}")
+		g.P()
+		return hname
+	}
+	streamType := unexport(servName) + methName + "Server"
+	g.P("func ", hname, "(srv interface{}, stream ", grpcPkg, ".ServerStream) error {")
+	if !method.GetClientStreaming() {
+		g.P("m := new(", inType, ")")
+		g.P("if err := stream.RecvMsg(m); err != nil { return err }")
+		g.P("return srv.(", servName, "Server).", methName, "(m, &", streamType, "{stream})")
+	} else {
+		g.P("return srv.(", servName, "Server).", methName, "(&", streamType, "{stream})")
+	}
+	g.P("}")
+	g.P()
+
+	genSend := method.GetServerStreaming()
+	genSendAndClose := !method.GetServerStreaming()
+	genRecv := method.GetClientStreaming()
+
+	// Stream auxiliary types and methods.
+	g.P("type ", servName, "_", methName, "Server interface {")
+	if genSend {
+		g.P("Send(*", outType, ") error")
+	}
+	if genSendAndClose {
+		g.P("SendAndClose(*", outType, ") error")
+	}
+	if genRecv {
+		g.P("Recv() (*", inType, ", error)")
+	}
+	g.P(grpcPkg, ".ServerStream")
+	g.P("}")
+	g.P()
+
+	g.P("type ", streamType, " struct {")
+	g.P(grpcPkg, ".ServerStream")
+	g.P("}")
+	g.P()
+
+	if genSend {
+		g.P("func (x *", streamType, ") Send(m *", outType, ") error {")
+		g.P("return x.ServerStream.SendMsg(m)")
+		g.P("}")
+		g.P()
+	}
+	if genSendAndClose {
+		g.P("func (x *", streamType, ") SendAndClose(m *", outType, ") error {")
+		g.P("return x.ServerStream.SendMsg(m)")
+		g.P("}")
+		g.P()
+	}
+	if genRecv {
+		g.P("func (x *", streamType, ") Recv() (*", inType, ", error) {")
+		g.P("m := new(", inType, ")")
+		g.P("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }")
+		g.P("return m, nil")
+		g.P("}")
+		g.P()
+	}
+
+	return hname
+}
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/main.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/main.go
new file mode 100644
index 0000000000000..dd8e795030cbb
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/main.go
@@ -0,0 +1,57 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// protoc-gen-go is a plugin for the Google protocol buffer compiler to generate
+// Go code.  Run it by building this program and putting it in your path with
+// the name
+// 	protoc-gen-gogo
+// That word 'gogo' at the end becomes part of the option string set for the
+// protocol compiler, so once the protocol compiler (protoc) is installed
+// you can run
+// 	protoc --gogo_out=output_directory input_directory/file.proto
+// to generate Go bindings for the protocol defined by file.proto.
+// With that input, the output will be written to
+// 	output_directory/file.pb.go
+//
+// The generated code is documented in the package comment for
+// the library.
+//
+// See the README and documentation for protocol buffers to learn more:
+// 	https://developers.google.com/protocol-buffers/
+package main
+
+import (
+	"github.com/gogo/protobuf/vanity/command"
+)
+
+func main() {
+	command.Write(command.Generate(command.Read()))
+}
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin/Makefile b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin/Makefile
new file mode 100644
index 0000000000000..95234a75539b9
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin/Makefile
@@ -0,0 +1,37 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  All rights reserved.
+# https://github.com/golang/protobuf
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Not stored here, but plugin.proto is in https://github.com/google/protobuf/
+# at src/google/protobuf/compiler/plugin.proto
+# Also we need to fix an import.
+regenerate:
+	go install github.com/gogo/protobuf/protoc-gen-gogo
+	protoc --gogo_out=Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor:. -I=../../protobuf/google/protobuf/compiler/:../../protobuf/ ../../protobuf/google/protobuf/compiler/plugin.proto
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin/plugin.pb.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin/plugin.pb.go
new file mode 100644
index 0000000000000..8c9cb58b0dd8a
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogo/plugin/plugin.pb.go
@@ -0,0 +1,365 @@
+// Code generated by protoc-gen-gogo. DO NOT EDIT.
+// source: plugin.proto
+
+package plugin_go
+
+import (
+	fmt "fmt"
+	proto "github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+	math "math"
+)
+
+// Reference imports to suppress errors if they are not otherwise used.
+var _ = proto.Marshal
+var _ = fmt.Errorf
+var _ = math.Inf
+
+// This is a compile-time assertion to ensure that this generated file
+// is compatible with the proto package it is being compiled against.
+// A compilation error at this line likely means your copy of the
+// proto package needs to be updated.
+const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package
+
+// The version number of protocol compiler.
+type Version struct {
+	Major *int32 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"`
+	Minor *int32 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"`
+	Patch *int32 `protobuf:"varint,3,opt,name=patch" json:"patch,omitempty"`
+	// A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
+	// be empty for mainline stable releases.
+	Suffix               *string  `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *Version) Reset()         { *m = Version{} }
+func (m *Version) String() string { return proto.CompactTextString(m) }
+func (*Version) ProtoMessage()    {}
+func (*Version) Descriptor() ([]byte, []int) {
+	return fileDescriptor_22a625af4bc1cc87, []int{0}
+}
+func (m *Version) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_Version.Unmarshal(m, b)
+}
+func (m *Version) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_Version.Marshal(b, m, deterministic)
+}
+func (m *Version) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_Version.Merge(m, src)
+}
+func (m *Version) XXX_Size() int {
+	return xxx_messageInfo_Version.Size(m)
+}
+func (m *Version) XXX_DiscardUnknown() {
+	xxx_messageInfo_Version.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_Version proto.InternalMessageInfo
+
+func (m *Version) GetMajor() int32 {
+	if m != nil && m.Major != nil {
+		return *m.Major
+	}
+	return 0
+}
+
+func (m *Version) GetMinor() int32 {
+	if m != nil && m.Minor != nil {
+		return *m.Minor
+	}
+	return 0
+}
+
+func (m *Version) GetPatch() int32 {
+	if m != nil && m.Patch != nil {
+		return *m.Patch
+	}
+	return 0
+}
+
+func (m *Version) GetSuffix() string {
+	if m != nil && m.Suffix != nil {
+		return *m.Suffix
+	}
+	return ""
+}
+
+// An encoded CodeGeneratorRequest is written to the plugin's stdin.
+type CodeGeneratorRequest struct {
+	// The .proto files that were explicitly listed on the command-line.  The
+	// code generator should generate code only for these files.  Each file's
+	// descriptor will be included in proto_file, below.
+	FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate,json=fileToGenerate" json:"file_to_generate,omitempty"`
+	// The generator parameter passed on the command-line.
+	Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"`
+	// FileDescriptorProtos for all files in files_to_generate and everything
+	// they import.  The files will appear in topological order, so each file
+	// appears before any file that imports it.
+	//
+	// protoc guarantees that all proto_files will be written after
+	// the fields above, even though this is not technically guaranteed by the
+	// protobuf wire format.  This theoretically could allow a plugin to stream
+	// in the FileDescriptorProtos and handle them one by one rather than read
+	// the entire set into memory at once.  However, as of this writing, this
+	// is not similarly optimized on protoc's end -- it will store all fields in
+	// memory at once before sending them to the plugin.
+	//
+	// Type names of fields and extensions in the FileDescriptorProto are always
+	// fully qualified.
+	ProtoFile []*descriptor.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file,json=protoFile" json:"proto_file,omitempty"`
+	// The version number of protocol compiler.
+	CompilerVersion      *Version `protobuf:"bytes,3,opt,name=compiler_version,json=compilerVersion" json:"compiler_version,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *CodeGeneratorRequest) Reset()         { *m = CodeGeneratorRequest{} }
+func (m *CodeGeneratorRequest) String() string { return proto.CompactTextString(m) }
+func (*CodeGeneratorRequest) ProtoMessage()    {}
+func (*CodeGeneratorRequest) Descriptor() ([]byte, []int) {
+	return fileDescriptor_22a625af4bc1cc87, []int{1}
+}
+func (m *CodeGeneratorRequest) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_CodeGeneratorRequest.Unmarshal(m, b)
+}
+func (m *CodeGeneratorRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_CodeGeneratorRequest.Marshal(b, m, deterministic)
+}
+func (m *CodeGeneratorRequest) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_CodeGeneratorRequest.Merge(m, src)
+}
+func (m *CodeGeneratorRequest) XXX_Size() int {
+	return xxx_messageInfo_CodeGeneratorRequest.Size(m)
+}
+func (m *CodeGeneratorRequest) XXX_DiscardUnknown() {
+	xxx_messageInfo_CodeGeneratorRequest.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CodeGeneratorRequest proto.InternalMessageInfo
+
+func (m *CodeGeneratorRequest) GetFileToGenerate() []string {
+	if m != nil {
+		return m.FileToGenerate
+	}
+	return nil
+}
+
+func (m *CodeGeneratorRequest) GetParameter() string {
+	if m != nil && m.Parameter != nil {
+		return *m.Parameter
+	}
+	return ""
+}
+
+func (m *CodeGeneratorRequest) GetProtoFile() []*descriptor.FileDescriptorProto {
+	if m != nil {
+		return m.ProtoFile
+	}
+	return nil
+}
+
+func (m *CodeGeneratorRequest) GetCompilerVersion() *Version {
+	if m != nil {
+		return m.CompilerVersion
+	}
+	return nil
+}
+
+// The plugin writes an encoded CodeGeneratorResponse to stdout.
+type CodeGeneratorResponse struct {
+	// Error message.  If non-empty, code generation failed.  The plugin process
+	// should exit with status code zero even if it reports an error in this way.
+	//
+	// This should be used to indicate errors in .proto files which prevent the
+	// code generator from generating correct code.  Errors which indicate a
+	// problem in protoc itself -- such as the input CodeGeneratorRequest being
+	// unparseable -- should be reported by writing a message to stderr and
+	// exiting with a non-zero status code.
+	Error                *string                       `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"`
+	File                 []*CodeGeneratorResponse_File `protobuf:"bytes,15,rep,name=file" json:"file,omitempty"`
+	XXX_NoUnkeyedLiteral struct{}                      `json:"-"`
+	XXX_unrecognized     []byte                        `json:"-"`
+	XXX_sizecache        int32                         `json:"-"`
+}
+
+func (m *CodeGeneratorResponse) Reset()         { *m = CodeGeneratorResponse{} }
+func (m *CodeGeneratorResponse) String() string { return proto.CompactTextString(m) }
+func (*CodeGeneratorResponse) ProtoMessage()    {}
+func (*CodeGeneratorResponse) Descriptor() ([]byte, []int) {
+	return fileDescriptor_22a625af4bc1cc87, []int{2}
+}
+func (m *CodeGeneratorResponse) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_CodeGeneratorResponse.Unmarshal(m, b)
+}
+func (m *CodeGeneratorResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_CodeGeneratorResponse.Marshal(b, m, deterministic)
+}
+func (m *CodeGeneratorResponse) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_CodeGeneratorResponse.Merge(m, src)
+}
+func (m *CodeGeneratorResponse) XXX_Size() int {
+	return xxx_messageInfo_CodeGeneratorResponse.Size(m)
+}
+func (m *CodeGeneratorResponse) XXX_DiscardUnknown() {
+	xxx_messageInfo_CodeGeneratorResponse.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CodeGeneratorResponse proto.InternalMessageInfo
+
+func (m *CodeGeneratorResponse) GetError() string {
+	if m != nil && m.Error != nil {
+		return *m.Error
+	}
+	return ""
+}
+
+func (m *CodeGeneratorResponse) GetFile() []*CodeGeneratorResponse_File {
+	if m != nil {
+		return m.File
+	}
+	return nil
+}
+
+// Represents a single generated file.
+type CodeGeneratorResponse_File struct {
+	// The file name, relative to the output directory.  The name must not
+	// contain "." or ".." components and must be relative, not be absolute (so,
+	// the file cannot lie outside the output directory).  "/" must be used as
+	// the path separator, not "\".
+	//
+	// If the name is omitted, the content will be appended to the previous
+	// file.  This allows the generator to break large files into small chunks,
+	// and allows the generated text to be streamed back to protoc so that large
+	// files need not reside completely in memory at one time.  Note that as of
+	// this writing protoc does not optimize for this -- it will read the entire
+	// CodeGeneratorResponse before writing files to disk.
+	Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	// If non-empty, indicates that the named file should already exist, and the
+	// content here is to be inserted into that file at a defined insertion
+	// point.  This feature allows a code generator to extend the output
+	// produced by another code generator.  The original generator may provide
+	// insertion points by placing special annotations in the file that look
+	// like:
+	//   @@protoc_insertion_point(NAME)
+	// The annotation can have arbitrary text before and after it on the line,
+	// which allows it to be placed in a comment.  NAME should be replaced with
+	// an identifier naming the point -- this is what other generators will use
+	// as the insertion_point.  Code inserted at this point will be placed
+	// immediately above the line containing the insertion point (thus multiple
+	// insertions to the same point will come out in the order they were added).
+	// The double-@ is intended to make it unlikely that the generated code
+	// could contain things that look like insertion points by accident.
+	//
+	// For example, the C++ code generator places the following line in the
+	// .pb.h files that it generates:
+	//   // @@protoc_insertion_point(namespace_scope)
+	// This line appears within the scope of the file's package namespace, but
+	// outside of any particular class.  Another plugin can then specify the
+	// insertion_point "namespace_scope" to generate additional classes or
+	// other declarations that should be placed in this scope.
+	//
+	// Note that if the line containing the insertion point begins with
+	// whitespace, the same whitespace will be added to every line of the
+	// inserted text.  This is useful for languages like Python, where
+	// indentation matters.  In these languages, the insertion point comment
+	// should be indented the same amount as any inserted code will need to be
+	// in order to work correctly in that context.
+	//
+	// The code generator that generates the initial file and the one which
+	// inserts into it must both run as part of a single invocation of protoc.
+	// Code generators are executed in the order in which they appear on the
+	// command line.
+	//
+	// If |insertion_point| is present, |name| must also be present.
+	InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point,json=insertionPoint" json:"insertion_point,omitempty"`
+	// The file contents.
+	Content              *string  `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"`
+	XXX_NoUnkeyedLiteral struct{} `json:"-"`
+	XXX_unrecognized     []byte   `json:"-"`
+	XXX_sizecache        int32    `json:"-"`
+}
+
+func (m *CodeGeneratorResponse_File) Reset()         { *m = CodeGeneratorResponse_File{} }
+func (m *CodeGeneratorResponse_File) String() string { return proto.CompactTextString(m) }
+func (*CodeGeneratorResponse_File) ProtoMessage()    {}
+func (*CodeGeneratorResponse_File) Descriptor() ([]byte, []int) {
+	return fileDescriptor_22a625af4bc1cc87, []int{2, 0}
+}
+func (m *CodeGeneratorResponse_File) XXX_Unmarshal(b []byte) error {
+	return xxx_messageInfo_CodeGeneratorResponse_File.Unmarshal(m, b)
+}
+func (m *CodeGeneratorResponse_File) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
+	return xxx_messageInfo_CodeGeneratorResponse_File.Marshal(b, m, deterministic)
+}
+func (m *CodeGeneratorResponse_File) XXX_Merge(src proto.Message) {
+	xxx_messageInfo_CodeGeneratorResponse_File.Merge(m, src)
+}
+func (m *CodeGeneratorResponse_File) XXX_Size() int {
+	return xxx_messageInfo_CodeGeneratorResponse_File.Size(m)
+}
+func (m *CodeGeneratorResponse_File) XXX_DiscardUnknown() {
+	xxx_messageInfo_CodeGeneratorResponse_File.DiscardUnknown(m)
+}
+
+var xxx_messageInfo_CodeGeneratorResponse_File proto.InternalMessageInfo
+
+func (m *CodeGeneratorResponse_File) GetName() string {
+	if m != nil && m.Name != nil {
+		return *m.Name
+	}
+	return ""
+}
+
+func (m *CodeGeneratorResponse_File) GetInsertionPoint() string {
+	if m != nil && m.InsertionPoint != nil {
+		return *m.InsertionPoint
+	}
+	return ""
+}
+
+func (m *CodeGeneratorResponse_File) GetContent() string {
+	if m != nil && m.Content != nil {
+		return *m.Content
+	}
+	return ""
+}
+
+func init() {
+	proto.RegisterType((*Version)(nil), "google.protobuf.compiler.Version")
+	proto.RegisterType((*CodeGeneratorRequest)(nil), "google.protobuf.compiler.CodeGeneratorRequest")
+	proto.RegisterType((*CodeGeneratorResponse)(nil), "google.protobuf.compiler.CodeGeneratorResponse")
+	proto.RegisterType((*CodeGeneratorResponse_File)(nil), "google.protobuf.compiler.CodeGeneratorResponse.File")
+}
+
+func init() { proto.RegisterFile("plugin.proto", fileDescriptor_22a625af4bc1cc87) }
+
+var fileDescriptor_22a625af4bc1cc87 = []byte{
+	// 383 bytes of a gzipped FileDescriptorProto
+	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0xcd, 0x6a, 0xd5, 0x40,
+	0x14, 0xc7, 0x89, 0x37, 0xb5, 0xe4, 0xb4, 0x34, 0x65, 0xa8, 0x32, 0x94, 0x2e, 0xe2, 0x45, 0x30,
+	0xab, 0x14, 0x8a, 0xe0, 0xbe, 0x15, 0x75, 0xe1, 0xe2, 0x32, 0x88, 0x0b, 0x41, 0x42, 0x4c, 0x4f,
+	0xe2, 0x48, 0x32, 0x67, 0x9c, 0x99, 0x88, 0x4f, 0xea, 0x7b, 0xf8, 0x06, 0x32, 0x1f, 0xa9, 0x72,
+	0xf1, 0xee, 0xe6, 0xff, 0x3b, 0xf3, 0x71, 0xce, 0x8f, 0x81, 0x53, 0x3d, 0x2d, 0xa3, 0x54, 0x8d,
+	0x36, 0xe4, 0x88, 0xf1, 0x91, 0x68, 0x9c, 0x30, 0xa6, 0x2f, 0xcb, 0xd0, 0xf4, 0x34, 0x6b, 0x39,
+	0xa1, 0xb9, 0xac, 0x62, 0xe5, 0x7a, 0xad, 0x5c, 0xdf, 0xa3, 0xed, 0x8d, 0xd4, 0x8e, 0x4c, 0xdc,
+	0xbd, 0xed, 0xe1, 0xf8, 0x23, 0x1a, 0x2b, 0x49, 0xb1, 0x0b, 0x38, 0x9a, 0xbb, 0x6f, 0x64, 0x78,
+	0x56, 0x65, 0xf5, 0x91, 0x88, 0x21, 0x50, 0xa9, 0xc8, 0xf0, 0x47, 0x89, 0xfa, 0xe0, 0xa9, 0xee,
+	0x5c, 0xff, 0x95, 0x6f, 0x22, 0x0d, 0x81, 0x3d, 0x85, 0xc7, 0x76, 0x19, 0x06, 0xf9, 0x93, 0xe7,
+	0x55, 0x56, 0x17, 0x22, 0xa5, 0xed, 0xef, 0x0c, 0x2e, 0xee, 0xe8, 0x1e, 0xdf, 0xa2, 0x42, 0xd3,
+	0x39, 0x32, 0x02, 0xbf, 0x2f, 0x68, 0x1d, 0xab, 0xe1, 0x7c, 0x90, 0x13, 0xb6, 0x8e, 0xda, 0x31,
+	0xd6, 0x90, 0x67, 0xd5, 0xa6, 0x2e, 0xc4, 0x99, 0xe7, 0x1f, 0x28, 0x9d, 0x40, 0x76, 0x05, 0x85,
+	0xee, 0x4c, 0x37, 0xa3, 0xc3, 0xd8, 0x4a, 0x21, 0xfe, 0x02, 0x76, 0x07, 0x10, 0xc6, 0x69, 0xfd,
+	0x29, 0x5e, 0x56, 0x9b, 0xfa, 0xe4, 0xe6, 0x79, 0xb3, 0xaf, 0xe5, 0x8d, 0x9c, 0xf0, 0xf5, 0x83,
+	0x80, 0x9d, 0xc7, 0xa2, 0x08, 0x55, 0x5f, 0x61, 0xef, 0xe1, 0x7c, 0x15, 0xd7, 0xfe, 0x88, 0x4e,
+	0xc2, 0x78, 0x27, 0x37, 0xcf, 0x9a, 0x43, 0x86, 0x9b, 0x24, 0x4f, 0x94, 0x2b, 0x49, 0x60, 0xfb,
+	0x2b, 0x83, 0x27, 0x7b, 0x33, 0x5b, 0x4d, 0xca, 0xa2, 0x77, 0x87, 0xc6, 0x24, 0xcf, 0x85, 0x88,
+	0x81, 0xbd, 0x83, 0xfc, 0x9f, 0xe6, 0x5f, 0x1e, 0x7e, 0xf1, 0xbf, 0x97, 0x86, 0xd9, 0x44, 0xb8,
+	0xe1, 0xf2, 0x33, 0xe4, 0x61, 0x1e, 0x06, 0xb9, 0xea, 0x66, 0x4c, 0xcf, 0x84, 0x35, 0x7b, 0x01,
+	0xa5, 0x54, 0x16, 0x8d, 0x93, 0xa4, 0x5a, 0x4d, 0x52, 0xb9, 0x24, 0xf3, 0xec, 0x01, 0xef, 0x3c,
+	0x65, 0x1c, 0x8e, 0x7b, 0x52, 0x0e, 0x95, 0xe3, 0x65, 0xd8, 0xb0, 0xc6, 0xdb, 0x57, 0x70, 0xd5,
+	0xd3, 0x7c, 0xb0, 0xbf, 0xdb, 0xd3, 0x5d, 0xf8, 0x9b, 0x41, 0xaf, 0xfd, 0x54, 0xc4, 0x9f, 0xda,
+	0x8e, 0xf4, 0x27, 0x00, 0x00, 0xff, 0xff, 0x7a, 0x72, 0x3d, 0x18, 0xb5, 0x02, 0x00, 0x00,
+}
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogofaster/main.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogofaster/main.go
new file mode 100644
index 0000000000000..356fcfa0ac088
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogofaster/main.go
@@ -0,0 +1,52 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2015, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 main
+
+import (
+	"github.com/gogo/protobuf/vanity"
+	"github.com/gogo/protobuf/vanity/command"
+)
+
+func main() {
+	req := command.Read()
+	files := req.GetProtoFile()
+	files = vanity.FilterFiles(files, vanity.NotGoogleProtobufDescriptorProto)
+
+	vanity.ForEachFile(files, vanity.TurnOnMarshalerAll)
+	vanity.ForEachFile(files, vanity.TurnOnSizerAll)
+	vanity.ForEachFile(files, vanity.TurnOnUnmarshalerAll)
+
+	vanity.ForEachFieldInFilesExcludingExtensions(vanity.OnlyProto2(files), vanity.TurnOffNullableForNativeTypesWithoutDefaultsOnly)
+	vanity.ForEachFile(files, vanity.TurnOffGoUnrecognizedAll)
+	vanity.ForEachFile(files, vanity.TurnOffGoUnkeyedAll)
+	vanity.ForEachFile(files, vanity.TurnOffGoSizecacheAll)
+
+	resp := command.Generate(req)
+	command.Write(resp)
+}
diff --git a/vendor/github.com/gogo/protobuf/protoc-gen-gogoslick/main.go b/vendor/github.com/gogo/protobuf/protoc-gen-gogoslick/main.go
new file mode 100644
index 0000000000000..a5b988ed30810
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/protoc-gen-gogoslick/main.go
@@ -0,0 +1,61 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2015, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 main
+
+import (
+	"github.com/gogo/protobuf/vanity"
+	"github.com/gogo/protobuf/vanity/command"
+)
+
+func main() {
+	req := command.Read()
+	files := req.GetProtoFile()
+	files = vanity.FilterFiles(files, vanity.NotGoogleProtobufDescriptorProto)
+
+	vanity.ForEachFile(files, vanity.TurnOnMarshalerAll)
+	vanity.ForEachFile(files, vanity.TurnOnSizerAll)
+	vanity.ForEachFile(files, vanity.TurnOnUnmarshalerAll)
+
+	vanity.ForEachFieldInFilesExcludingExtensions(vanity.OnlyProto2(files), vanity.TurnOffNullableForNativeTypesWithoutDefaultsOnly)
+	vanity.ForEachFile(files, vanity.TurnOffGoUnrecognizedAll)
+	vanity.ForEachFile(files, vanity.TurnOffGoUnkeyedAll)
+	vanity.ForEachFile(files, vanity.TurnOffGoSizecacheAll)
+
+	vanity.ForEachFile(files, vanity.TurnOffGoEnumPrefixAll)
+	vanity.ForEachFile(files, vanity.TurnOffGoEnumStringerAll)
+	vanity.ForEachFile(files, vanity.TurnOnEnumStringerAll)
+
+	vanity.ForEachFile(files, vanity.TurnOnEqualAll)
+	vanity.ForEachFile(files, vanity.TurnOnGoStringAll)
+	vanity.ForEachFile(files, vanity.TurnOffGoStringerAll)
+	vanity.ForEachFile(files, vanity.TurnOnStringerAll)
+
+	resp := command.Generate(req)
+	command.Write(resp)
+}
diff --git a/vendor/github.com/gogo/protobuf/vanity/command/command.go b/vendor/github.com/gogo/protobuf/vanity/command/command.go
new file mode 100644
index 0000000000000..eeca42ba0d070
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/vanity/command/command.go
@@ -0,0 +1,161 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2015, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 command
+
+import (
+	"fmt"
+	"go/format"
+	"io/ioutil"
+	"os"
+	"strings"
+
+	_ "github.com/gogo/protobuf/plugin/compare"
+	_ "github.com/gogo/protobuf/plugin/defaultcheck"
+	_ "github.com/gogo/protobuf/plugin/description"
+	_ "github.com/gogo/protobuf/plugin/embedcheck"
+	_ "github.com/gogo/protobuf/plugin/enumstringer"
+	_ "github.com/gogo/protobuf/plugin/equal"
+	_ "github.com/gogo/protobuf/plugin/face"
+	_ "github.com/gogo/protobuf/plugin/gostring"
+	_ "github.com/gogo/protobuf/plugin/marshalto"
+	_ "github.com/gogo/protobuf/plugin/oneofcheck"
+	_ "github.com/gogo/protobuf/plugin/populate"
+	_ "github.com/gogo/protobuf/plugin/size"
+	_ "github.com/gogo/protobuf/plugin/stringer"
+	"github.com/gogo/protobuf/plugin/testgen"
+	_ "github.com/gogo/protobuf/plugin/union"
+	_ "github.com/gogo/protobuf/plugin/unmarshal"
+	"github.com/gogo/protobuf/proto"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+	_ "github.com/gogo/protobuf/protoc-gen-gogo/grpc"
+	plugin "github.com/gogo/protobuf/protoc-gen-gogo/plugin"
+)
+
+func Read() *plugin.CodeGeneratorRequest {
+	g := generator.New()
+	data, err := ioutil.ReadAll(os.Stdin)
+	if err != nil {
+		g.Error(err, "reading input")
+	}
+
+	if err := proto.Unmarshal(data, g.Request); err != nil {
+		g.Error(err, "parsing input proto")
+	}
+
+	if len(g.Request.FileToGenerate) == 0 {
+		g.Fail("no files to generate")
+	}
+	return g.Request
+}
+
+// filenameSuffix replaces the .pb.go at the end of each filename.
+func GeneratePlugin(req *plugin.CodeGeneratorRequest, p generator.Plugin, filenameSuffix string) *plugin.CodeGeneratorResponse {
+	g := generator.New()
+	g.Request = req
+	if len(g.Request.FileToGenerate) == 0 {
+		g.Fail("no files to generate")
+	}
+
+	g.CommandLineParameters(g.Request.GetParameter())
+
+	g.WrapTypes()
+	g.SetPackageNames()
+	g.BuildTypeNameMap()
+	g.GeneratePlugin(p)
+
+	for i := 0; i < len(g.Response.File); i++ {
+		g.Response.File[i].Name = proto.String(
+			strings.Replace(*g.Response.File[i].Name, ".pb.go", filenameSuffix, -1),
+		)
+	}
+	if err := goformat(g.Response); err != nil {
+		g.Error(err)
+	}
+	return g.Response
+}
+
+func goformat(resp *plugin.CodeGeneratorResponse) error {
+	for i := 0; i < len(resp.File); i++ {
+		formatted, err := format.Source([]byte(resp.File[i].GetContent()))
+		if err != nil {
+			return fmt.Errorf("go format error: %v", err)
+		}
+		fmts := string(formatted)
+		resp.File[i].Content = &fmts
+	}
+	return nil
+}
+
+func Generate(req *plugin.CodeGeneratorRequest) *plugin.CodeGeneratorResponse {
+	// Begin by allocating a generator. The request and response structures are stored there
+	// so we can do error handling easily - the response structure contains the field to
+	// report failure.
+	g := generator.New()
+	g.Request = req
+
+	g.CommandLineParameters(g.Request.GetParameter())
+
+	// Create a wrapped version of the Descriptors and EnumDescriptors that
+	// point to the file that defines them.
+	g.WrapTypes()
+
+	g.SetPackageNames()
+	g.BuildTypeNameMap()
+
+	g.GenerateAllFiles()
+
+	if err := goformat(g.Response); err != nil {
+		g.Error(err)
+	}
+
+	testReq := proto.Clone(req).(*plugin.CodeGeneratorRequest)
+
+	testResp := GeneratePlugin(testReq, testgen.NewPlugin(), "pb_test.go")
+
+	for i := 0; i < len(testResp.File); i++ {
+		if strings.Contains(*testResp.File[i].Content, `//These tests are generated by github.com/gogo/protobuf/plugin/testgen`) {
+			g.Response.File = append(g.Response.File, testResp.File[i])
+		}
+	}
+
+	return g.Response
+}
+
+func Write(resp *plugin.CodeGeneratorResponse) {
+	g := generator.New()
+	// Send back the results.
+	data, err := proto.Marshal(resp)
+	if err != nil {
+		g.Error(err, "failed to marshal output proto")
+	}
+	_, err = os.Stdout.Write(data)
+	if err != nil {
+		g.Error(err, "failed to write output proto")
+	}
+}
diff --git a/vendor/github.com/gogo/protobuf/vanity/enum.go b/vendor/github.com/gogo/protobuf/vanity/enum.go
new file mode 100644
index 0000000000000..466d07b54eb84
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/vanity/enum.go
@@ -0,0 +1,78 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2015, The GoGo Authors.  rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 vanity
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+)
+
+func EnumHasBoolExtension(enum *descriptor.EnumDescriptorProto, extension *proto.ExtensionDesc) bool {
+	if enum.Options == nil {
+		return false
+	}
+	value, err := proto.GetExtension(enum.Options, extension)
+	if err != nil {
+		return false
+	}
+	if value == nil {
+		return false
+	}
+	if value.(*bool) == nil {
+		return false
+	}
+	return true
+}
+
+func SetBoolEnumOption(extension *proto.ExtensionDesc, value bool) func(enum *descriptor.EnumDescriptorProto) {
+	return func(enum *descriptor.EnumDescriptorProto) {
+		if EnumHasBoolExtension(enum, extension) {
+			return
+		}
+		if enum.Options == nil {
+			enum.Options = &descriptor.EnumOptions{}
+		}
+		if err := proto.SetExtension(enum.Options, extension, &value); err != nil {
+			panic(err)
+		}
+	}
+}
+
+func TurnOffGoEnumPrefix(enum *descriptor.EnumDescriptorProto) {
+	SetBoolEnumOption(gogoproto.E_GoprotoEnumPrefix, false)(enum)
+}
+
+func TurnOffGoEnumStringer(enum *descriptor.EnumDescriptorProto) {
+	SetBoolEnumOption(gogoproto.E_GoprotoEnumStringer, false)(enum)
+}
+
+func TurnOnEnumStringer(enum *descriptor.EnumDescriptorProto) {
+	SetBoolEnumOption(gogoproto.E_EnumStringer, true)(enum)
+}
diff --git a/vendor/github.com/gogo/protobuf/vanity/field.go b/vendor/github.com/gogo/protobuf/vanity/field.go
new file mode 100644
index 0000000000000..62cdddfabb490
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/vanity/field.go
@@ -0,0 +1,90 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2015, The GoGo Authors.  rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 vanity
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+)
+
+func FieldHasBoolExtension(field *descriptor.FieldDescriptorProto, extension *proto.ExtensionDesc) bool {
+	if field.Options == nil {
+		return false
+	}
+	value, err := proto.GetExtension(field.Options, extension)
+	if err != nil {
+		return false
+	}
+	if value == nil {
+		return false
+	}
+	if value.(*bool) == nil {
+		return false
+	}
+	return true
+}
+
+func SetBoolFieldOption(extension *proto.ExtensionDesc, value bool) func(field *descriptor.FieldDescriptorProto) {
+	return func(field *descriptor.FieldDescriptorProto) {
+		if FieldHasBoolExtension(field, extension) {
+			return
+		}
+		if field.Options == nil {
+			field.Options = &descriptor.FieldOptions{}
+		}
+		if err := proto.SetExtension(field.Options, extension, &value); err != nil {
+			panic(err)
+		}
+	}
+}
+
+func TurnOffNullable(field *descriptor.FieldDescriptorProto) {
+	if field.IsRepeated() && !field.IsMessage() {
+		return
+	}
+	SetBoolFieldOption(gogoproto.E_Nullable, false)(field)
+}
+
+func TurnOffNullableForNativeTypes(field *descriptor.FieldDescriptorProto) {
+	if field.IsRepeated() || field.IsMessage() {
+		return
+	}
+	SetBoolFieldOption(gogoproto.E_Nullable, false)(field)
+}
+
+func TurnOffNullableForNativeTypesWithoutDefaultsOnly(field *descriptor.FieldDescriptorProto) {
+	if field.IsRepeated() || field.IsMessage() {
+		return
+	}
+	if field.DefaultValue != nil {
+		return
+	}
+	SetBoolFieldOption(gogoproto.E_Nullable, false)(field)
+}
diff --git a/vendor/github.com/gogo/protobuf/vanity/file.go b/vendor/github.com/gogo/protobuf/vanity/file.go
new file mode 100644
index 0000000000000..2055c66152e3d
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/vanity/file.go
@@ -0,0 +1,197 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2015, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 vanity
+
+import (
+	"path/filepath"
+
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+)
+
+func NotGoogleProtobufDescriptorProto(file *descriptor.FileDescriptorProto) bool {
+	// can not just check if file.GetName() == "google/protobuf/descriptor.proto" because we do not want to assume compile path
+	_, fileName := filepath.Split(file.GetName())
+	return !(file.GetPackage() == "google.protobuf" && fileName == "descriptor.proto")
+}
+
+func FilterFiles(files []*descriptor.FileDescriptorProto, f func(file *descriptor.FileDescriptorProto) bool) []*descriptor.FileDescriptorProto {
+	filtered := make([]*descriptor.FileDescriptorProto, 0, len(files))
+	for i := range files {
+		if !f(files[i]) {
+			continue
+		}
+		filtered = append(filtered, files[i])
+	}
+	return filtered
+}
+
+func FileHasBoolExtension(file *descriptor.FileDescriptorProto, extension *proto.ExtensionDesc) bool {
+	if file.Options == nil {
+		return false
+	}
+	value, err := proto.GetExtension(file.Options, extension)
+	if err != nil {
+		return false
+	}
+	if value == nil {
+		return false
+	}
+	if value.(*bool) == nil {
+		return false
+	}
+	return true
+}
+
+func SetBoolFileOption(extension *proto.ExtensionDesc, value bool) func(file *descriptor.FileDescriptorProto) {
+	return func(file *descriptor.FileDescriptorProto) {
+		if FileHasBoolExtension(file, extension) {
+			return
+		}
+		if file.Options == nil {
+			file.Options = &descriptor.FileOptions{}
+		}
+		if err := proto.SetExtension(file.Options, extension, &value); err != nil {
+			panic(err)
+		}
+	}
+}
+
+func TurnOffGoGettersAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GoprotoGettersAll, false)(file)
+}
+
+func TurnOffGoEnumPrefixAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GoprotoEnumPrefixAll, false)(file)
+}
+
+func TurnOffGoStringerAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GoprotoStringerAll, false)(file)
+}
+
+func TurnOnVerboseEqualAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_VerboseEqualAll, true)(file)
+}
+
+func TurnOnFaceAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_FaceAll, true)(file)
+}
+
+func TurnOnGoStringAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GostringAll, true)(file)
+}
+
+func TurnOnPopulateAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_PopulateAll, true)(file)
+}
+
+func TurnOnStringerAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_StringerAll, true)(file)
+}
+
+func TurnOnEqualAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_EqualAll, true)(file)
+}
+
+func TurnOnDescriptionAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_DescriptionAll, true)(file)
+}
+
+func TurnOnTestGenAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_TestgenAll, true)(file)
+}
+
+func TurnOnBenchGenAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_BenchgenAll, true)(file)
+}
+
+func TurnOnMarshalerAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_MarshalerAll, true)(file)
+}
+
+func TurnOnUnmarshalerAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_UnmarshalerAll, true)(file)
+}
+
+func TurnOnStable_MarshalerAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_StableMarshalerAll, true)(file)
+}
+
+func TurnOnSizerAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_SizerAll, true)(file)
+}
+
+func TurnOffGoEnumStringerAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GoprotoEnumStringerAll, false)(file)
+}
+
+func TurnOnEnumStringerAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_EnumStringerAll, true)(file)
+}
+
+func TurnOnUnsafeUnmarshalerAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_UnsafeUnmarshalerAll, true)(file)
+}
+
+func TurnOnUnsafeMarshalerAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_UnsafeMarshalerAll, true)(file)
+}
+
+func TurnOffGoExtensionsMapAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GoprotoExtensionsMapAll, false)(file)
+}
+
+func TurnOffGoUnrecognizedAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GoprotoUnrecognizedAll, false)(file)
+}
+
+func TurnOffGoUnkeyedAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GoprotoUnkeyedAll, false)(file)
+}
+
+func TurnOffGoSizecacheAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GoprotoSizecacheAll, false)(file)
+}
+
+func TurnOffGogoImport(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GogoprotoImport, false)(file)
+}
+
+func TurnOnCompareAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_CompareAll, true)(file)
+}
+
+func TurnOnMessageNameAll(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_MessagenameAll, true)(file)
+}
+
+func TurnOnGoRegistration(file *descriptor.FileDescriptorProto) {
+	SetBoolFileOption(gogoproto.E_GoprotoRegistration, true)(file)
+}
diff --git a/vendor/github.com/gogo/protobuf/vanity/foreach.go b/vendor/github.com/gogo/protobuf/vanity/foreach.go
new file mode 100644
index 0000000000000..888b6d04d5942
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/vanity/foreach.go
@@ -0,0 +1,125 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2015, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 vanity
+
+import descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+
+func ForEachFile(files []*descriptor.FileDescriptorProto, f func(file *descriptor.FileDescriptorProto)) {
+	for _, file := range files {
+		f(file)
+	}
+}
+
+func OnlyProto2(files []*descriptor.FileDescriptorProto) []*descriptor.FileDescriptorProto {
+	outs := make([]*descriptor.FileDescriptorProto, 0, len(files))
+	for i, file := range files {
+		if file.GetSyntax() == "proto3" {
+			continue
+		}
+		outs = append(outs, files[i])
+	}
+	return outs
+}
+
+func OnlyProto3(files []*descriptor.FileDescriptorProto) []*descriptor.FileDescriptorProto {
+	outs := make([]*descriptor.FileDescriptorProto, 0, len(files))
+	for i, file := range files {
+		if file.GetSyntax() != "proto3" {
+			continue
+		}
+		outs = append(outs, files[i])
+	}
+	return outs
+}
+
+func ForEachMessageInFiles(files []*descriptor.FileDescriptorProto, f func(msg *descriptor.DescriptorProto)) {
+	for _, file := range files {
+		ForEachMessage(file.MessageType, f)
+	}
+}
+
+func ForEachMessage(msgs []*descriptor.DescriptorProto, f func(msg *descriptor.DescriptorProto)) {
+	for _, msg := range msgs {
+		f(msg)
+		ForEachMessage(msg.NestedType, f)
+	}
+}
+
+func ForEachFieldInFilesExcludingExtensions(files []*descriptor.FileDescriptorProto, f func(field *descriptor.FieldDescriptorProto)) {
+	for _, file := range files {
+		ForEachFieldExcludingExtensions(file.MessageType, f)
+	}
+}
+
+func ForEachFieldInFiles(files []*descriptor.FileDescriptorProto, f func(field *descriptor.FieldDescriptorProto)) {
+	for _, file := range files {
+		for _, ext := range file.Extension {
+			f(ext)
+		}
+		ForEachField(file.MessageType, f)
+	}
+}
+
+func ForEachFieldExcludingExtensions(msgs []*descriptor.DescriptorProto, f func(field *descriptor.FieldDescriptorProto)) {
+	for _, msg := range msgs {
+		for _, field := range msg.Field {
+			f(field)
+		}
+		ForEachField(msg.NestedType, f)
+	}
+}
+
+func ForEachField(msgs []*descriptor.DescriptorProto, f func(field *descriptor.FieldDescriptorProto)) {
+	for _, msg := range msgs {
+		for _, field := range msg.Field {
+			f(field)
+		}
+		for _, ext := range msg.Extension {
+			f(ext)
+		}
+		ForEachField(msg.NestedType, f)
+	}
+}
+
+func ForEachEnumInFiles(files []*descriptor.FileDescriptorProto, f func(enum *descriptor.EnumDescriptorProto)) {
+	for _, file := range files {
+		for _, enum := range file.EnumType {
+			f(enum)
+		}
+	}
+}
+
+func ForEachEnum(msgs []*descriptor.DescriptorProto, f func(field *descriptor.EnumDescriptorProto)) {
+	for _, msg := range msgs {
+		for _, field := range msg.EnumType {
+			f(field)
+		}
+		ForEachEnum(msg.NestedType, f)
+	}
+}
diff --git a/vendor/github.com/gogo/protobuf/vanity/msg.go b/vendor/github.com/gogo/protobuf/vanity/msg.go
new file mode 100644
index 0000000000000..390ff5ad44f3b
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/vanity/msg.go
@@ -0,0 +1,154 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2015, The GoGo Authors.  rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 vanity
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/proto"
+	descriptor "github.com/gogo/protobuf/protoc-gen-gogo/descriptor"
+)
+
+func MessageHasBoolExtension(msg *descriptor.DescriptorProto, extension *proto.ExtensionDesc) bool {
+	if msg.Options == nil {
+		return false
+	}
+	value, err := proto.GetExtension(msg.Options, extension)
+	if err != nil {
+		return false
+	}
+	if value == nil {
+		return false
+	}
+	if value.(*bool) == nil {
+		return false
+	}
+	return true
+}
+
+func SetBoolMessageOption(extension *proto.ExtensionDesc, value bool) func(msg *descriptor.DescriptorProto) {
+	return func(msg *descriptor.DescriptorProto) {
+		if MessageHasBoolExtension(msg, extension) {
+			return
+		}
+		if msg.Options == nil {
+			msg.Options = &descriptor.MessageOptions{}
+		}
+		if err := proto.SetExtension(msg.Options, extension, &value); err != nil {
+			panic(err)
+		}
+	}
+}
+
+func TurnOffGoGetters(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_GoprotoGetters, false)(msg)
+}
+
+func TurnOffGoStringer(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_GoprotoStringer, false)(msg)
+}
+
+func TurnOnVerboseEqual(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_VerboseEqual, true)(msg)
+}
+
+func TurnOnFace(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Face, true)(msg)
+}
+
+func TurnOnGoString(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Face, true)(msg)
+}
+
+func TurnOnPopulate(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Populate, true)(msg)
+}
+
+func TurnOnStringer(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Stringer, true)(msg)
+}
+
+func TurnOnEqual(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Equal, true)(msg)
+}
+
+func TurnOnDescription(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Description, true)(msg)
+}
+
+func TurnOnTestGen(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Testgen, true)(msg)
+}
+
+func TurnOnBenchGen(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Benchgen, true)(msg)
+}
+
+func TurnOnMarshaler(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Marshaler, true)(msg)
+}
+
+func TurnOnUnmarshaler(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Unmarshaler, true)(msg)
+}
+
+func TurnOnSizer(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Sizer, true)(msg)
+}
+
+func TurnOnUnsafeUnmarshaler(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_UnsafeUnmarshaler, true)(msg)
+}
+
+func TurnOnUnsafeMarshaler(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_UnsafeMarshaler, true)(msg)
+}
+
+func TurnOffGoExtensionsMap(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_GoprotoExtensionsMap, false)(msg)
+}
+
+func TurnOffGoUnrecognized(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_GoprotoUnrecognized, false)(msg)
+}
+
+func TurnOffGoUnkeyed(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_GoprotoUnkeyed, false)(msg)
+}
+
+func TurnOffGoSizecache(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_GoprotoSizecache, false)(msg)
+}
+
+func TurnOnCompare(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Compare, true)(msg)
+}
+
+func TurnOnMessageName(msg *descriptor.DescriptorProto) {
+	SetBoolMessageOption(gogoproto.E_Messagename, true)(msg)
+}
diff --git a/vendor/github.com/golang/protobuf/internal/gengogrpc/grpc.go b/vendor/github.com/golang/protobuf/internal/gengogrpc/grpc.go
new file mode 100644
index 0000000000000..fd2f51d890119
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/internal/gengogrpc/grpc.go
@@ -0,0 +1,398 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package gengogrpc contains the gRPC code generator.
+package gengogrpc
+
+import (
+	"fmt"
+	"strconv"
+	"strings"
+
+	"google.golang.org/protobuf/compiler/protogen"
+
+	"google.golang.org/protobuf/types/descriptorpb"
+)
+
+const (
+	contextPackage = protogen.GoImportPath("context")
+	grpcPackage    = protogen.GoImportPath("google.golang.org/grpc")
+	codesPackage   = protogen.GoImportPath("google.golang.org/grpc/codes")
+	statusPackage  = protogen.GoImportPath("google.golang.org/grpc/status")
+)
+
+// GenerateFile generates a _grpc.pb.go file containing gRPC service definitions.
+func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.GeneratedFile {
+	if len(file.Services) == 0 {
+		return nil
+	}
+	filename := file.GeneratedFilenamePrefix + "_grpc.pb.go"
+	g := gen.NewGeneratedFile(filename, file.GoImportPath)
+	g.P("// Code generated by protoc-gen-go-grpc. DO NOT EDIT.")
+	g.P()
+	g.P("package ", file.GoPackageName)
+	g.P()
+	GenerateFileContent(gen, file, g)
+	return g
+}
+
+// GenerateFileContent generates the gRPC service definitions, excluding the package statement.
+func GenerateFileContent(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile) {
+	if len(file.Services) == 0 {
+		return
+	}
+
+	// TODO: Remove this. We don't need to include these references any more.
+	g.P("// Reference imports to suppress errors if they are not otherwise used.")
+	g.P("var _ ", contextPackage.Ident("Context"))
+	g.P("var _ ", grpcPackage.Ident("ClientConnInterface"))
+	g.P()
+
+	g.P("// This is a compile-time assertion to ensure that this generated file")
+	g.P("// is compatible with the grpc package it is being compiled against.")
+	g.P("const _ = ", grpcPackage.Ident("SupportPackageIsVersion6"))
+	g.P()
+	for _, service := range file.Services {
+		genService(gen, file, g, service)
+	}
+}
+
+func genService(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, service *protogen.Service) {
+	clientName := service.GoName + "Client"
+
+	g.P("// ", clientName, " is the client API for ", service.GoName, " service.")
+	g.P("//")
+	g.P("// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.")
+
+	// Client interface.
+	if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() {
+		g.P("//")
+		g.P(deprecationComment)
+	}
+	g.Annotate(clientName, service.Location)
+	g.P("type ", clientName, " interface {")
+	for _, method := range service.Methods {
+		g.Annotate(clientName+"."+method.GoName, method.Location)
+		if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() {
+			g.P(deprecationComment)
+		}
+		g.P(method.Comments.Leading,
+			clientSignature(g, method))
+	}
+	g.P("}")
+	g.P()
+
+	// Client structure.
+	g.P("type ", unexport(clientName), " struct {")
+	g.P("cc ", grpcPackage.Ident("ClientConnInterface"))
+	g.P("}")
+	g.P()
+
+	// NewClient factory.
+	if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() {
+		g.P(deprecationComment)
+	}
+	g.P("func New", clientName, " (cc ", grpcPackage.Ident("ClientConnInterface"), ") ", clientName, " {")
+	g.P("return &", unexport(clientName), "{cc}")
+	g.P("}")
+	g.P()
+
+	var methodIndex, streamIndex int
+	// Client method implementations.
+	for _, method := range service.Methods {
+		if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() {
+			// Unary RPC method
+			genClientMethod(gen, file, g, method, methodIndex)
+			methodIndex++
+		} else {
+			// Streaming RPC method
+			genClientMethod(gen, file, g, method, streamIndex)
+			streamIndex++
+		}
+	}
+
+	// Server interface.
+	serverType := service.GoName + "Server"
+	g.P("// ", serverType, " is the server API for ", service.GoName, " service.")
+	if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() {
+		g.P("//")
+		g.P(deprecationComment)
+	}
+	g.Annotate(serverType, service.Location)
+	g.P("type ", serverType, " interface {")
+	for _, method := range service.Methods {
+		g.Annotate(serverType+"."+method.GoName, method.Location)
+		if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() {
+			g.P(deprecationComment)
+		}
+		g.P(method.Comments.Leading,
+			serverSignature(g, method))
+	}
+	g.P("}")
+	g.P()
+
+	// Server Unimplemented struct for forward compatibility.
+	g.P("// Unimplemented", serverType, " can be embedded to have forward compatible implementations.")
+	g.P("type Unimplemented", serverType, " struct {")
+	g.P("}")
+	g.P()
+	for _, method := range service.Methods {
+		nilArg := ""
+		if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
+			nilArg = "nil,"
+		}
+		g.P("func (*Unimplemented", serverType, ") ", serverSignature(g, method), "{")
+		g.P("return ", nilArg, statusPackage.Ident("Errorf"), "(", codesPackage.Ident("Unimplemented"), `, "method `, method.GoName, ` not implemented")`)
+		g.P("}")
+	}
+	g.P()
+
+	// Server registration.
+	if service.Desc.Options().(*descriptorpb.ServiceOptions).GetDeprecated() {
+		g.P(deprecationComment)
+	}
+	serviceDescVar := "_" + service.GoName + "_serviceDesc"
+	g.P("func Register", service.GoName, "Server(s *", grpcPackage.Ident("Server"), ", srv ", serverType, ") {")
+	g.P("s.RegisterService(&", serviceDescVar, `, srv)`)
+	g.P("}")
+	g.P()
+
+	// Server handler implementations.
+	var handlerNames []string
+	for _, method := range service.Methods {
+		hname := genServerMethod(gen, file, g, method)
+		handlerNames = append(handlerNames, hname)
+	}
+
+	// Service descriptor.
+	g.P("var ", serviceDescVar, " = ", grpcPackage.Ident("ServiceDesc"), " {")
+	g.P("ServiceName: ", strconv.Quote(string(service.Desc.FullName())), ",")
+	g.P("HandlerType: (*", serverType, ")(nil),")
+	g.P("Methods: []", grpcPackage.Ident("MethodDesc"), "{")
+	for i, method := range service.Methods {
+		if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() {
+			continue
+		}
+		g.P("{")
+		g.P("MethodName: ", strconv.Quote(string(method.Desc.Name())), ",")
+		g.P("Handler: ", handlerNames[i], ",")
+		g.P("},")
+	}
+	g.P("},")
+	g.P("Streams: []", grpcPackage.Ident("StreamDesc"), "{")
+	for i, method := range service.Methods {
+		if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
+			continue
+		}
+		g.P("{")
+		g.P("StreamName: ", strconv.Quote(string(method.Desc.Name())), ",")
+		g.P("Handler: ", handlerNames[i], ",")
+		if method.Desc.IsStreamingServer() {
+			g.P("ServerStreams: true,")
+		}
+		if method.Desc.IsStreamingClient() {
+			g.P("ClientStreams: true,")
+		}
+		g.P("},")
+	}
+	g.P("},")
+	g.P("Metadata: \"", file.Desc.Path(), "\",")
+	g.P("}")
+	g.P()
+}
+
+func clientSignature(g *protogen.GeneratedFile, method *protogen.Method) string {
+	s := method.GoName + "(ctx " + g.QualifiedGoIdent(contextPackage.Ident("Context"))
+	if !method.Desc.IsStreamingClient() {
+		s += ", in *" + g.QualifiedGoIdent(method.Input.GoIdent)
+	}
+	s += ", opts ..." + g.QualifiedGoIdent(grpcPackage.Ident("CallOption")) + ") ("
+	if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
+		s += "*" + g.QualifiedGoIdent(method.Output.GoIdent)
+	} else {
+		s += method.Parent.GoName + "_" + method.GoName + "Client"
+	}
+	s += ", error)"
+	return s
+}
+
+func genClientMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, method *protogen.Method, index int) {
+	service := method.Parent
+	sname := fmt.Sprintf("/%s/%s", service.Desc.FullName(), method.Desc.Name())
+
+	if method.Desc.Options().(*descriptorpb.MethodOptions).GetDeprecated() {
+		g.P(deprecationComment)
+	}
+	g.P("func (c *", unexport(service.GoName), "Client) ", clientSignature(g, method), "{")
+	if !method.Desc.IsStreamingServer() && !method.Desc.IsStreamingClient() {
+		g.P("out := new(", method.Output.GoIdent, ")")
+		g.P(`err := c.cc.Invoke(ctx, "`, sname, `", in, out, opts...)`)
+		g.P("if err != nil { return nil, err }")
+		g.P("return out, nil")
+		g.P("}")
+		g.P()
+		return
+	}
+	streamType := unexport(service.GoName) + method.GoName + "Client"
+	serviceDescVar := "_" + service.GoName + "_serviceDesc"
+	g.P("stream, err := c.cc.NewStream(ctx, &", serviceDescVar, ".Streams[", index, `], "`, sname, `", opts...)`)
+	g.P("if err != nil { return nil, err }")
+	g.P("x := &", streamType, "{stream}")
+	if !method.Desc.IsStreamingClient() {
+		g.P("if err := x.ClientStream.SendMsg(in); err != nil { return nil, err }")
+		g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }")
+	}
+	g.P("return x, nil")
+	g.P("}")
+	g.P()
+
+	genSend := method.Desc.IsStreamingClient()
+	genRecv := method.Desc.IsStreamingServer()
+	genCloseAndRecv := !method.Desc.IsStreamingServer()
+
+	// Stream auxiliary types and methods.
+	g.P("type ", service.GoName, "_", method.GoName, "Client interface {")
+	if genSend {
+		g.P("Send(*", method.Input.GoIdent, ") error")
+	}
+	if genRecv {
+		g.P("Recv() (*", method.Output.GoIdent, ", error)")
+	}
+	if genCloseAndRecv {
+		g.P("CloseAndRecv() (*", method.Output.GoIdent, ", error)")
+	}
+	g.P(grpcPackage.Ident("ClientStream"))
+	g.P("}")
+	g.P()
+
+	g.P("type ", streamType, " struct {")
+	g.P(grpcPackage.Ident("ClientStream"))
+	g.P("}")
+	g.P()
+
+	if genSend {
+		g.P("func (x *", streamType, ") Send(m *", method.Input.GoIdent, ") error {")
+		g.P("return x.ClientStream.SendMsg(m)")
+		g.P("}")
+		g.P()
+	}
+	if genRecv {
+		g.P("func (x *", streamType, ") Recv() (*", method.Output.GoIdent, ", error) {")
+		g.P("m := new(", method.Output.GoIdent, ")")
+		g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }")
+		g.P("return m, nil")
+		g.P("}")
+		g.P()
+	}
+	if genCloseAndRecv {
+		g.P("func (x *", streamType, ") CloseAndRecv() (*", method.Output.GoIdent, ", error) {")
+		g.P("if err := x.ClientStream.CloseSend(); err != nil { return nil, err }")
+		g.P("m := new(", method.Output.GoIdent, ")")
+		g.P("if err := x.ClientStream.RecvMsg(m); err != nil { return nil, err }")
+		g.P("return m, nil")
+		g.P("}")
+		g.P()
+	}
+}
+
+func serverSignature(g *protogen.GeneratedFile, method *protogen.Method) string {
+	var reqArgs []string
+	ret := "error"
+	if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
+		reqArgs = append(reqArgs, g.QualifiedGoIdent(contextPackage.Ident("Context")))
+		ret = "(*" + g.QualifiedGoIdent(method.Output.GoIdent) + ", error)"
+	}
+	if !method.Desc.IsStreamingClient() {
+		reqArgs = append(reqArgs, "*"+g.QualifiedGoIdent(method.Input.GoIdent))
+	}
+	if method.Desc.IsStreamingClient() || method.Desc.IsStreamingServer() {
+		reqArgs = append(reqArgs, method.Parent.GoName+"_"+method.GoName+"Server")
+	}
+	return method.GoName + "(" + strings.Join(reqArgs, ", ") + ") " + ret
+}
+
+func genServerMethod(gen *protogen.Plugin, file *protogen.File, g *protogen.GeneratedFile, method *protogen.Method) string {
+	service := method.Parent
+	hname := fmt.Sprintf("_%s_%s_Handler", service.GoName, method.GoName)
+
+	if !method.Desc.IsStreamingClient() && !method.Desc.IsStreamingServer() {
+		g.P("func ", hname, "(srv interface{}, ctx ", contextPackage.Ident("Context"), ", dec func(interface{}) error, interceptor ", grpcPackage.Ident("UnaryServerInterceptor"), ") (interface{}, error) {")
+		g.P("in := new(", method.Input.GoIdent, ")")
+		g.P("if err := dec(in); err != nil { return nil, err }")
+		g.P("if interceptor == nil { return srv.(", service.GoName, "Server).", method.GoName, "(ctx, in) }")
+		g.P("info := &", grpcPackage.Ident("UnaryServerInfo"), "{")
+		g.P("Server: srv,")
+		g.P("FullMethod: ", strconv.Quote(fmt.Sprintf("/%s/%s", service.Desc.FullName(), method.GoName)), ",")
+		g.P("}")
+		g.P("handler := func(ctx ", contextPackage.Ident("Context"), ", req interface{}) (interface{}, error) {")
+		g.P("return srv.(", service.GoName, "Server).", method.GoName, "(ctx, req.(*", method.Input.GoIdent, "))")
+		g.P("}")
+		g.P("return interceptor(ctx, in, info, handler)")
+		g.P("}")
+		g.P()
+		return hname
+	}
+	streamType := unexport(service.GoName) + method.GoName + "Server"
+	g.P("func ", hname, "(srv interface{}, stream ", grpcPackage.Ident("ServerStream"), ") error {")
+	if !method.Desc.IsStreamingClient() {
+		g.P("m := new(", method.Input.GoIdent, ")")
+		g.P("if err := stream.RecvMsg(m); err != nil { return err }")
+		g.P("return srv.(", service.GoName, "Server).", method.GoName, "(m, &", streamType, "{stream})")
+	} else {
+		g.P("return srv.(", service.GoName, "Server).", method.GoName, "(&", streamType, "{stream})")
+	}
+	g.P("}")
+	g.P()
+
+	genSend := method.Desc.IsStreamingServer()
+	genSendAndClose := !method.Desc.IsStreamingServer()
+	genRecv := method.Desc.IsStreamingClient()
+
+	// Stream auxiliary types and methods.
+	g.P("type ", service.GoName, "_", method.GoName, "Server interface {")
+	if genSend {
+		g.P("Send(*", method.Output.GoIdent, ") error")
+	}
+	if genSendAndClose {
+		g.P("SendAndClose(*", method.Output.GoIdent, ") error")
+	}
+	if genRecv {
+		g.P("Recv() (*", method.Input.GoIdent, ", error)")
+	}
+	g.P(grpcPackage.Ident("ServerStream"))
+	g.P("}")
+	g.P()
+
+	g.P("type ", streamType, " struct {")
+	g.P(grpcPackage.Ident("ServerStream"))
+	g.P("}")
+	g.P()
+
+	if genSend {
+		g.P("func (x *", streamType, ") Send(m *", method.Output.GoIdent, ") error {")
+		g.P("return x.ServerStream.SendMsg(m)")
+		g.P("}")
+		g.P()
+	}
+	if genSendAndClose {
+		g.P("func (x *", streamType, ") SendAndClose(m *", method.Output.GoIdent, ") error {")
+		g.P("return x.ServerStream.SendMsg(m)")
+		g.P("}")
+		g.P()
+	}
+	if genRecv {
+		g.P("func (x *", streamType, ") Recv() (*", method.Input.GoIdent, ", error) {")
+		g.P("m := new(", method.Input.GoIdent, ")")
+		g.P("if err := x.ServerStream.RecvMsg(m); err != nil { return nil, err }")
+		g.P("return m, nil")
+		g.P("}")
+		g.P()
+	}
+
+	return hname
+}
+
+const deprecationComment = "// Deprecated: Do not use."
+
+func unexport(s string) string { return strings.ToLower(s[:1]) + s[1:] }
diff --git a/vendor/github.com/golang/protobuf/protoc-gen-go/main.go b/vendor/github.com/golang/protobuf/protoc-gen-go/main.go
new file mode 100644
index 0000000000000..d45b719d1c6ee
--- /dev/null
+++ b/vendor/github.com/golang/protobuf/protoc-gen-go/main.go
@@ -0,0 +1,74 @@
+// Copyright 2010 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// protoc-gen-go is a plugin for the Google protocol buffer compiler to generate
+// Go code. Install it by building this program and making it accessible within
+// your PATH with the name:
+//	protoc-gen-go
+//
+// The 'go' suffix becomes part of the argument for the protocol compiler,
+// such that it can be invoked as:
+//	protoc --go_out=paths=source_relative:. path/to/file.proto
+//
+// This generates Go bindings for the protocol buffer defined by file.proto.
+// With that input, the output will be written to:
+//	path/to/file.pb.go
+//
+// See the README and documentation for protocol buffers to learn more:
+//	https://developers.google.com/protocol-buffers/
+package main
+
+import (
+	"flag"
+	"fmt"
+	"strings"
+
+	"github.com/golang/protobuf/internal/gengogrpc"
+	gengo "google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo"
+	"google.golang.org/protobuf/compiler/protogen"
+)
+
+func main() {
+	var (
+		flags        flag.FlagSet
+		plugins      = flags.String("plugins", "", "list of plugins to enable (supported values: grpc)")
+		importPrefix = flags.String("import_prefix", "", "prefix to prepend to import paths")
+	)
+	importRewriteFunc := func(importPath protogen.GoImportPath) protogen.GoImportPath {
+		switch importPath {
+		case "context", "fmt", "math":
+			return importPath
+		}
+		if *importPrefix != "" {
+			return protogen.GoImportPath(*importPrefix) + importPath
+		}
+		return importPath
+	}
+	protogen.Options{
+		ParamFunc:         flags.Set,
+		ImportRewriteFunc: importRewriteFunc,
+	}.Run(func(gen *protogen.Plugin) error {
+		grpc := false
+		for _, plugin := range strings.Split(*plugins, ",") {
+			switch plugin {
+			case "grpc":
+				grpc = true
+			case "":
+			default:
+				return fmt.Errorf("protoc-gen-go: unknown plugin %q", plugin)
+			}
+		}
+		for _, f := range gen.Files {
+			if !f.Generate {
+				continue
+			}
+			g := gengo.GenerateFile(gen, f)
+			if grpc {
+				gengogrpc.GenerateFileContent(gen, f, g)
+			}
+		}
+		gen.SupportedFeatures = gengo.SupportedFeatures
+		return nil
+	})
+}
diff --git a/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/init.go b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/init.go
new file mode 100644
index 0000000000000..369df13da2747
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/init.go
@@ -0,0 +1,168 @@
+// Copyright 2019 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package internal_gengo
+
+import (
+	"unicode"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/compiler/protogen"
+	"google.golang.org/protobuf/encoding/protowire"
+
+	"google.golang.org/protobuf/types/descriptorpb"
+)
+
+type fileInfo struct {
+	*protogen.File
+
+	allEnums      []*enumInfo
+	allMessages   []*messageInfo
+	allExtensions []*extensionInfo
+
+	allEnumsByPtr         map[*enumInfo]int    // value is index into allEnums
+	allMessagesByPtr      map[*messageInfo]int // value is index into allMessages
+	allMessageFieldsByPtr map[*messageInfo]*structFields
+
+	// needRawDesc specifies whether the generator should emit logic to provide
+	// the legacy raw descriptor in GZIP'd form.
+	// This is updated by enum and message generation logic as necessary,
+	// and checked at the end of file generation.
+	needRawDesc bool
+}
+
+type structFields struct {
+	count      int
+	unexported map[int]string
+}
+
+func (sf *structFields) append(name string) {
+	if r, _ := utf8.DecodeRuneInString(name); !unicode.IsUpper(r) {
+		if sf.unexported == nil {
+			sf.unexported = make(map[int]string)
+		}
+		sf.unexported[sf.count] = name
+	}
+	sf.count++
+}
+
+func newFileInfo(file *protogen.File) *fileInfo {
+	f := &fileInfo{File: file}
+
+	// Collect all enums, messages, and extensions in "flattened ordering".
+	// See filetype.TypeBuilder.
+	var walkMessages func([]*protogen.Message, func(*protogen.Message))
+	walkMessages = func(messages []*protogen.Message, f func(*protogen.Message)) {
+		for _, m := range messages {
+			f(m)
+			walkMessages(m.Messages, f)
+		}
+	}
+	initEnumInfos := func(enums []*protogen.Enum) {
+		for _, enum := range enums {
+			f.allEnums = append(f.allEnums, newEnumInfo(f, enum))
+		}
+	}
+	initMessageInfos := func(messages []*protogen.Message) {
+		for _, message := range messages {
+			f.allMessages = append(f.allMessages, newMessageInfo(f, message))
+		}
+	}
+	initExtensionInfos := func(extensions []*protogen.Extension) {
+		for _, extension := range extensions {
+			f.allExtensions = append(f.allExtensions, newExtensionInfo(f, extension))
+		}
+	}
+	initEnumInfos(f.Enums)
+	initMessageInfos(f.Messages)
+	initExtensionInfos(f.Extensions)
+	walkMessages(f.Messages, func(m *protogen.Message) {
+		initEnumInfos(m.Enums)
+		initMessageInfos(m.Messages)
+		initExtensionInfos(m.Extensions)
+	})
+
+	// Derive a reverse mapping of enum and message pointers to their index
+	// in allEnums and allMessages.
+	if len(f.allEnums) > 0 {
+		f.allEnumsByPtr = make(map[*enumInfo]int)
+		for i, e := range f.allEnums {
+			f.allEnumsByPtr[e] = i
+		}
+	}
+	if len(f.allMessages) > 0 {
+		f.allMessagesByPtr = make(map[*messageInfo]int)
+		f.allMessageFieldsByPtr = make(map[*messageInfo]*structFields)
+		for i, m := range f.allMessages {
+			f.allMessagesByPtr[m] = i
+			f.allMessageFieldsByPtr[m] = new(structFields)
+		}
+	}
+
+	return f
+}
+
+type enumInfo struct {
+	*protogen.Enum
+
+	genJSONMethod    bool
+	genRawDescMethod bool
+}
+
+func newEnumInfo(f *fileInfo, enum *protogen.Enum) *enumInfo {
+	e := &enumInfo{Enum: enum}
+	e.genJSONMethod = true
+	e.genRawDescMethod = true
+	return e
+}
+
+type messageInfo struct {
+	*protogen.Message
+
+	genRawDescMethod  bool
+	genExtRangeMethod bool
+
+	isTracked bool
+	hasWeak   bool
+}
+
+func newMessageInfo(f *fileInfo, message *protogen.Message) *messageInfo {
+	m := &messageInfo{Message: message}
+	m.genRawDescMethod = true
+	m.genExtRangeMethod = true
+	m.isTracked = isTrackedMessage(m)
+	for _, field := range m.Fields {
+		m.hasWeak = m.hasWeak || field.Desc.IsWeak()
+	}
+	return m
+}
+
+// isTrackedMessage reports whether field tracking is enabled on the message.
+func isTrackedMessage(m *messageInfo) (tracked bool) {
+	const trackFieldUse_fieldNumber = 37383685
+
+	// Decode the option from unknown fields to avoid a dependency on the
+	// annotation proto from protoc-gen-go.
+	b := m.Desc.Options().(*descriptorpb.MessageOptions).ProtoReflect().GetUnknown()
+	for len(b) > 0 {
+		num, typ, n := protowire.ConsumeTag(b)
+		b = b[n:]
+		if num == trackFieldUse_fieldNumber && typ == protowire.VarintType {
+			v, _ := protowire.ConsumeVarint(b)
+			tracked = protowire.DecodeBool(v)
+		}
+		m := protowire.ConsumeFieldValue(num, typ, b)
+		b = b[m:]
+	}
+	return tracked
+}
+
+type extensionInfo struct {
+	*protogen.Extension
+}
+
+func newExtensionInfo(f *fileInfo, extension *protogen.Extension) *extensionInfo {
+	x := &extensionInfo{Extension: extension}
+	return x
+}
diff --git a/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go
new file mode 100644
index 0000000000000..d34efa9b1cf16
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/main.go
@@ -0,0 +1,884 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package internal_gengo is internal to the protobuf module.
+package internal_gengo
+
+import (
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/token"
+	"math"
+	"strconv"
+	"strings"
+	"unicode"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/compiler/protogen"
+	"google.golang.org/protobuf/internal/encoding/tag"
+	"google.golang.org/protobuf/internal/genid"
+	"google.golang.org/protobuf/internal/version"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/runtime/protoimpl"
+
+	"google.golang.org/protobuf/types/descriptorpb"
+	"google.golang.org/protobuf/types/pluginpb"
+)
+
+// SupportedFeatures reports the set of supported protobuf language features.
+var SupportedFeatures = uint64(pluginpb.CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL)
+
+// GenerateVersionMarkers specifies whether to generate version markers.
+var GenerateVersionMarkers = true
+
+// Standard library dependencies.
+const (
+	base64Package  = protogen.GoImportPath("encoding/base64")
+	mathPackage    = protogen.GoImportPath("math")
+	reflectPackage = protogen.GoImportPath("reflect")
+	sortPackage    = protogen.GoImportPath("sort")
+	stringsPackage = protogen.GoImportPath("strings")
+	syncPackage    = protogen.GoImportPath("sync")
+	timePackage    = protogen.GoImportPath("time")
+	utf8Package    = protogen.GoImportPath("unicode/utf8")
+)
+
+// Protobuf library dependencies.
+//
+// These are declared as an interface type so that they can be more easily
+// patched to support unique build environments that impose restrictions
+// on the dependencies of generated source code.
+var (
+	protoPackage         goImportPath = protogen.GoImportPath("google.golang.org/protobuf/proto")
+	protoifacePackage    goImportPath = protogen.GoImportPath("google.golang.org/protobuf/runtime/protoiface")
+	protoimplPackage     goImportPath = protogen.GoImportPath("google.golang.org/protobuf/runtime/protoimpl")
+	protojsonPackage     goImportPath = protogen.GoImportPath("google.golang.org/protobuf/encoding/protojson")
+	protoreflectPackage  goImportPath = protogen.GoImportPath("google.golang.org/protobuf/reflect/protoreflect")
+	protoregistryPackage goImportPath = protogen.GoImportPath("google.golang.org/protobuf/reflect/protoregistry")
+)
+
+type goImportPath interface {
+	String() string
+	Ident(string) protogen.GoIdent
+}
+
+// GenerateFile generates the contents of a .pb.go file.
+func GenerateFile(gen *protogen.Plugin, file *protogen.File) *protogen.GeneratedFile {
+	filename := file.GeneratedFilenamePrefix + ".pb.go"
+	g := gen.NewGeneratedFile(filename, file.GoImportPath)
+	f := newFileInfo(file)
+
+	genStandaloneComments(g, f, int32(genid.FileDescriptorProto_Syntax_field_number))
+	genGeneratedHeader(gen, g, f)
+	genStandaloneComments(g, f, int32(genid.FileDescriptorProto_Package_field_number))
+
+	packageDoc := genPackageKnownComment(f)
+	g.P(packageDoc, "package ", f.GoPackageName)
+	g.P()
+
+	// Emit a static check that enforces a minimum version of the proto package.
+	if GenerateVersionMarkers {
+		g.P("const (")
+		g.P("// Verify that this generated code is sufficiently up-to-date.")
+		g.P("_ = ", protoimplPackage.Ident("EnforceVersion"), "(", protoimpl.GenVersion, " - ", protoimplPackage.Ident("MinVersion"), ")")
+		g.P("// Verify that runtime/protoimpl is sufficiently up-to-date.")
+		g.P("_ = ", protoimplPackage.Ident("EnforceVersion"), "(", protoimplPackage.Ident("MaxVersion"), " - ", protoimpl.GenVersion, ")")
+		g.P(")")
+		g.P()
+	}
+
+	for i, imps := 0, f.Desc.Imports(); i < imps.Len(); i++ {
+		genImport(gen, g, f, imps.Get(i))
+	}
+	for _, enum := range f.allEnums {
+		genEnum(g, f, enum)
+	}
+	for _, message := range f.allMessages {
+		genMessage(g, f, message)
+	}
+	genExtensions(g, f)
+
+	genReflectFileDescriptor(gen, g, f)
+
+	return g
+}
+
+// genStandaloneComments prints all leading comments for a FileDescriptorProto
+// location identified by the field number n.
+func genStandaloneComments(g *protogen.GeneratedFile, f *fileInfo, n int32) {
+	loc := f.Desc.SourceLocations().ByPath(protoreflect.SourcePath{n})
+	for _, s := range loc.LeadingDetachedComments {
+		g.P(protogen.Comments(s))
+		g.P()
+	}
+	if s := loc.LeadingComments; s != "" {
+		g.P(protogen.Comments(s))
+		g.P()
+	}
+}
+
+func genGeneratedHeader(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo) {
+	g.P("// Code generated by protoc-gen-go. DO NOT EDIT.")
+
+	if GenerateVersionMarkers {
+		g.P("// versions:")
+		protocGenGoVersion := version.String()
+		protocVersion := "(unknown)"
+		if v := gen.Request.GetCompilerVersion(); v != nil {
+			protocVersion = fmt.Sprintf("v%v.%v.%v", v.GetMajor(), v.GetMinor(), v.GetPatch())
+			if s := v.GetSuffix(); s != "" {
+				protocVersion += "-" + s
+			}
+		}
+		g.P("// \tprotoc-gen-go ", protocGenGoVersion)
+		g.P("// \tprotoc        ", protocVersion)
+	}
+
+	if f.Proto.GetOptions().GetDeprecated() {
+		g.P("// ", f.Desc.Path(), " is a deprecated file.")
+	} else {
+		g.P("// source: ", f.Desc.Path())
+	}
+	g.P()
+}
+
+func genImport(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo, imp protoreflect.FileImport) {
+	impFile, ok := gen.FilesByPath[imp.Path()]
+	if !ok {
+		return
+	}
+	if impFile.GoImportPath == f.GoImportPath {
+		// Don't generate imports or aliases for types in the same Go package.
+		return
+	}
+	// Generate imports for all non-weak dependencies, even if they are not
+	// referenced, because other code and tools depend on having the
+	// full transitive closure of protocol buffer types in the binary.
+	if !imp.IsWeak {
+		g.Import(impFile.GoImportPath)
+	}
+	if !imp.IsPublic {
+		return
+	}
+
+	// Generate public imports by generating the imported file, parsing it,
+	// and extracting every symbol that should receive a forwarding declaration.
+	impGen := GenerateFile(gen, impFile)
+	impGen.Skip()
+	b, err := impGen.Content()
+	if err != nil {
+		gen.Error(err)
+		return
+	}
+	fset := token.NewFileSet()
+	astFile, err := parser.ParseFile(fset, "", b, parser.ParseComments)
+	if err != nil {
+		gen.Error(err)
+		return
+	}
+	genForward := func(tok token.Token, name string, expr ast.Expr) {
+		// Don't import unexported symbols.
+		r, _ := utf8.DecodeRuneInString(name)
+		if !unicode.IsUpper(r) {
+			return
+		}
+		// Don't import the FileDescriptor.
+		if name == impFile.GoDescriptorIdent.GoName {
+			return
+		}
+		// Don't import decls referencing a symbol defined in another package.
+		// i.e., don't import decls which are themselves public imports:
+		//
+		//	type T = somepackage.T
+		if _, ok := expr.(*ast.SelectorExpr); ok {
+			return
+		}
+		g.P(tok, " ", name, " = ", impFile.GoImportPath.Ident(name))
+	}
+	g.P("// Symbols defined in public import of ", imp.Path(), ".")
+	g.P()
+	for _, decl := range astFile.Decls {
+		switch decl := decl.(type) {
+		case *ast.GenDecl:
+			for _, spec := range decl.Specs {
+				switch spec := spec.(type) {
+				case *ast.TypeSpec:
+					genForward(decl.Tok, spec.Name.Name, spec.Type)
+				case *ast.ValueSpec:
+					for i, name := range spec.Names {
+						var expr ast.Expr
+						if i < len(spec.Values) {
+							expr = spec.Values[i]
+						}
+						genForward(decl.Tok, name.Name, expr)
+					}
+				case *ast.ImportSpec:
+				default:
+					panic(fmt.Sprintf("can't generate forward for spec type %T", spec))
+				}
+			}
+		}
+	}
+	g.P()
+}
+
+func genEnum(g *protogen.GeneratedFile, f *fileInfo, e *enumInfo) {
+	// Enum type declaration.
+	g.Annotate(e.GoIdent.GoName, e.Location)
+	leadingComments := appendDeprecationSuffix(e.Comments.Leading,
+		e.Desc.Options().(*descriptorpb.EnumOptions).GetDeprecated())
+	g.P(leadingComments,
+		"type ", e.GoIdent, " int32")
+
+	// Enum value constants.
+	g.P("const (")
+	for _, value := range e.Values {
+		g.Annotate(value.GoIdent.GoName, value.Location)
+		leadingComments := appendDeprecationSuffix(value.Comments.Leading,
+			value.Desc.Options().(*descriptorpb.EnumValueOptions).GetDeprecated())
+		g.P(leadingComments,
+			value.GoIdent, " ", e.GoIdent, " = ", value.Desc.Number(),
+			trailingComment(value.Comments.Trailing))
+	}
+	g.P(")")
+	g.P()
+
+	// Enum value maps.
+	g.P("// Enum value maps for ", e.GoIdent, ".")
+	g.P("var (")
+	g.P(e.GoIdent.GoName+"_name", " = map[int32]string{")
+	for _, value := range e.Values {
+		duplicate := ""
+		if value.Desc != e.Desc.Values().ByNumber(value.Desc.Number()) {
+			duplicate = "// Duplicate value: "
+		}
+		g.P(duplicate, value.Desc.Number(), ": ", strconv.Quote(string(value.Desc.Name())), ",")
+	}
+	g.P("}")
+	g.P(e.GoIdent.GoName+"_value", " = map[string]int32{")
+	for _, value := range e.Values {
+		g.P(strconv.Quote(string(value.Desc.Name())), ": ", value.Desc.Number(), ",")
+	}
+	g.P("}")
+	g.P(")")
+	g.P()
+
+	// Enum method.
+	//
+	// NOTE: A pointer value is needed to represent presence in proto2.
+	// Since a proto2 message can reference a proto3 enum, it is useful to
+	// always generate this method (even on proto3 enums) to support that case.
+	g.P("func (x ", e.GoIdent, ") Enum() *", e.GoIdent, " {")
+	g.P("p := new(", e.GoIdent, ")")
+	g.P("*p = x")
+	g.P("return p")
+	g.P("}")
+	g.P()
+
+	// String method.
+	g.P("func (x ", e.GoIdent, ") String() string {")
+	g.P("return ", protoimplPackage.Ident("X"), ".EnumStringOf(x.Descriptor(), ", protoreflectPackage.Ident("EnumNumber"), "(x))")
+	g.P("}")
+	g.P()
+
+	genEnumReflectMethods(g, f, e)
+
+	// UnmarshalJSON method.
+	if e.genJSONMethod && e.Desc.Syntax() == protoreflect.Proto2 {
+		g.P("// Deprecated: Do not use.")
+		g.P("func (x *", e.GoIdent, ") UnmarshalJSON(b []byte) error {")
+		g.P("num, err := ", protoimplPackage.Ident("X"), ".UnmarshalJSONEnum(x.Descriptor(), b)")
+		g.P("if err != nil {")
+		g.P("return err")
+		g.P("}")
+		g.P("*x = ", e.GoIdent, "(num)")
+		g.P("return nil")
+		g.P("}")
+		g.P()
+	}
+
+	// EnumDescriptor method.
+	if e.genRawDescMethod {
+		var indexes []string
+		for i := 1; i < len(e.Location.Path); i += 2 {
+			indexes = append(indexes, strconv.Itoa(int(e.Location.Path[i])))
+		}
+		g.P("// Deprecated: Use ", e.GoIdent, ".Descriptor instead.")
+		g.P("func (", e.GoIdent, ") EnumDescriptor() ([]byte, []int) {")
+		g.P("return ", rawDescVarName(f), "GZIP(), []int{", strings.Join(indexes, ","), "}")
+		g.P("}")
+		g.P()
+		f.needRawDesc = true
+	}
+}
+
+func genMessage(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
+	if m.Desc.IsMapEntry() {
+		return
+	}
+
+	// Message type declaration.
+	g.Annotate(m.GoIdent.GoName, m.Location)
+	leadingComments := appendDeprecationSuffix(m.Comments.Leading,
+		m.Desc.Options().(*descriptorpb.MessageOptions).GetDeprecated())
+	g.P(leadingComments,
+		"type ", m.GoIdent, " struct {")
+	genMessageFields(g, f, m)
+	g.P("}")
+	g.P()
+
+	genMessageKnownFunctions(g, f, m)
+	genMessageDefaultDecls(g, f, m)
+	genMessageMethods(g, f, m)
+	genMessageOneofWrapperTypes(g, f, m)
+}
+
+func genMessageFields(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
+	sf := f.allMessageFieldsByPtr[m]
+	genMessageInternalFields(g, f, m, sf)
+	for _, field := range m.Fields {
+		genMessageField(g, f, m, field, sf)
+	}
+}
+
+func genMessageInternalFields(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, sf *structFields) {
+	g.P(genid.State_goname, " ", protoimplPackage.Ident("MessageState"))
+	sf.append(genid.State_goname)
+	g.P(genid.SizeCache_goname, " ", protoimplPackage.Ident("SizeCache"))
+	sf.append(genid.SizeCache_goname)
+	if m.hasWeak {
+		g.P(genid.WeakFields_goname, " ", protoimplPackage.Ident("WeakFields"))
+		sf.append(genid.WeakFields_goname)
+	}
+	g.P(genid.UnknownFields_goname, " ", protoimplPackage.Ident("UnknownFields"))
+	sf.append(genid.UnknownFields_goname)
+	if m.Desc.ExtensionRanges().Len() > 0 {
+		g.P(genid.ExtensionFields_goname, " ", protoimplPackage.Ident("ExtensionFields"))
+		sf.append(genid.ExtensionFields_goname)
+	}
+	if sf.count > 0 {
+		g.P()
+	}
+}
+
+func genMessageField(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, field *protogen.Field, sf *structFields) {
+	if oneof := field.Oneof; oneof != nil && !oneof.Desc.IsSynthetic() {
+		// It would be a bit simpler to iterate over the oneofs below,
+		// but generating the field here keeps the contents of the Go
+		// struct in the same order as the contents of the source
+		// .proto file.
+		if oneof.Fields[0] != field {
+			return // only generate for first appearance
+		}
+
+		tags := structTags{
+			{"protobuf_oneof", string(oneof.Desc.Name())},
+		}
+		if m.isTracked {
+			tags = append(tags, gotrackTags...)
+		}
+
+		g.Annotate(m.GoIdent.GoName+"."+oneof.GoName, oneof.Location)
+		leadingComments := oneof.Comments.Leading
+		if leadingComments != "" {
+			leadingComments += "\n"
+		}
+		ss := []string{fmt.Sprintf(" Types that are assignable to %s:\n", oneof.GoName)}
+		for _, field := range oneof.Fields {
+			ss = append(ss, "\t*"+field.GoIdent.GoName+"\n")
+		}
+		leadingComments += protogen.Comments(strings.Join(ss, ""))
+		g.P(leadingComments,
+			oneof.GoName, " ", oneofInterfaceName(oneof), tags)
+		sf.append(oneof.GoName)
+		return
+	}
+	goType, pointer := fieldGoType(g, f, field)
+	if pointer {
+		goType = "*" + goType
+	}
+	tags := structTags{
+		{"protobuf", fieldProtobufTagValue(field)},
+		{"json", fieldJSONTagValue(field)},
+	}
+	if field.Desc.IsMap() {
+		key := field.Message.Fields[0]
+		val := field.Message.Fields[1]
+		tags = append(tags, structTags{
+			{"protobuf_key", fieldProtobufTagValue(key)},
+			{"protobuf_val", fieldProtobufTagValue(val)},
+		}...)
+	}
+	if m.isTracked {
+		tags = append(tags, gotrackTags...)
+	}
+
+	name := field.GoName
+	if field.Desc.IsWeak() {
+		name = genid.WeakFieldPrefix_goname + name
+	}
+	g.Annotate(m.GoIdent.GoName+"."+name, field.Location)
+	leadingComments := appendDeprecationSuffix(field.Comments.Leading,
+		field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
+	g.P(leadingComments,
+		name, " ", goType, tags,
+		trailingComment(field.Comments.Trailing))
+	sf.append(field.GoName)
+}
+
+// genMessageDefaultDecls generates consts and vars holding the default
+// values of fields.
+func genMessageDefaultDecls(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
+	var consts, vars []string
+	for _, field := range m.Fields {
+		if !field.Desc.HasDefault() {
+			continue
+		}
+		name := "Default_" + m.GoIdent.GoName + "_" + field.GoName
+		goType, _ := fieldGoType(g, f, field)
+		defVal := field.Desc.Default()
+		switch field.Desc.Kind() {
+		case protoreflect.StringKind:
+			consts = append(consts, fmt.Sprintf("%s = %s(%q)", name, goType, defVal.String()))
+		case protoreflect.BytesKind:
+			vars = append(vars, fmt.Sprintf("%s = %s(%q)", name, goType, defVal.Bytes()))
+		case protoreflect.EnumKind:
+			idx := field.Desc.DefaultEnumValue().Index()
+			val := field.Enum.Values[idx]
+			if val.GoIdent.GoImportPath == f.GoImportPath {
+				consts = append(consts, fmt.Sprintf("%s = %s", name, g.QualifiedGoIdent(val.GoIdent)))
+			} else {
+				// If the enum value is declared in a different Go package,
+				// reference it by number since the name may not be correct.
+				// See https://github.com/golang/protobuf/issues/513.
+				consts = append(consts, fmt.Sprintf("%s = %s(%d) // %s",
+					name, g.QualifiedGoIdent(field.Enum.GoIdent), val.Desc.Number(), g.QualifiedGoIdent(val.GoIdent)))
+			}
+		case protoreflect.FloatKind, protoreflect.DoubleKind:
+			if f := defVal.Float(); math.IsNaN(f) || math.IsInf(f, 0) {
+				var fn, arg string
+				switch f := defVal.Float(); {
+				case math.IsInf(f, -1):
+					fn, arg = g.QualifiedGoIdent(mathPackage.Ident("Inf")), "-1"
+				case math.IsInf(f, +1):
+					fn, arg = g.QualifiedGoIdent(mathPackage.Ident("Inf")), "+1"
+				case math.IsNaN(f):
+					fn, arg = g.QualifiedGoIdent(mathPackage.Ident("NaN")), ""
+				}
+				vars = append(vars, fmt.Sprintf("%s = %s(%s(%s))", name, goType, fn, arg))
+			} else {
+				consts = append(consts, fmt.Sprintf("%s = %s(%v)", name, goType, f))
+			}
+		default:
+			consts = append(consts, fmt.Sprintf("%s = %s(%v)", name, goType, defVal.Interface()))
+		}
+	}
+	if len(consts) > 0 {
+		g.P("// Default values for ", m.GoIdent, " fields.")
+		g.P("const (")
+		for _, s := range consts {
+			g.P(s)
+		}
+		g.P(")")
+	}
+	if len(vars) > 0 {
+		g.P("// Default values for ", m.GoIdent, " fields.")
+		g.P("var (")
+		for _, s := range vars {
+			g.P(s)
+		}
+		g.P(")")
+	}
+	g.P()
+}
+
+func genMessageMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
+	genMessageBaseMethods(g, f, m)
+	genMessageGetterMethods(g, f, m)
+	genMessageSetterMethods(g, f, m)
+}
+
+func genMessageBaseMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
+	// Reset method.
+	g.P("func (x *", m.GoIdent, ") Reset() {")
+	g.P("*x = ", m.GoIdent, "{}")
+	g.P("if ", protoimplPackage.Ident("UnsafeEnabled"), " {")
+	g.P("mi := &", messageTypesVarName(f), "[", f.allMessagesByPtr[m], "]")
+	g.P("ms := ", protoimplPackage.Ident("X"), ".MessageStateOf(", protoimplPackage.Ident("Pointer"), "(x))")
+	g.P("ms.StoreMessageInfo(mi)")
+	g.P("}")
+	g.P("}")
+	g.P()
+
+	// String method.
+	g.P("func (x *", m.GoIdent, ") String() string {")
+	g.P("return ", protoimplPackage.Ident("X"), ".MessageStringOf(x)")
+	g.P("}")
+	g.P()
+
+	// ProtoMessage method.
+	g.P("func (*", m.GoIdent, ") ProtoMessage() {}")
+	g.P()
+
+	// ProtoReflect method.
+	genMessageReflectMethods(g, f, m)
+
+	// Descriptor method.
+	if m.genRawDescMethod {
+		var indexes []string
+		for i := 1; i < len(m.Location.Path); i += 2 {
+			indexes = append(indexes, strconv.Itoa(int(m.Location.Path[i])))
+		}
+		g.P("// Deprecated: Use ", m.GoIdent, ".ProtoReflect.Descriptor instead.")
+		g.P("func (*", m.GoIdent, ") Descriptor() ([]byte, []int) {")
+		g.P("return ", rawDescVarName(f), "GZIP(), []int{", strings.Join(indexes, ","), "}")
+		g.P("}")
+		g.P()
+		f.needRawDesc = true
+	}
+}
+
+func genMessageGetterMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
+	for _, field := range m.Fields {
+		genNoInterfacePragma(g, m.isTracked)
+
+		// Getter for parent oneof.
+		if oneof := field.Oneof; oneof != nil && oneof.Fields[0] == field && !oneof.Desc.IsSynthetic() {
+			g.Annotate(m.GoIdent.GoName+".Get"+oneof.GoName, oneof.Location)
+			g.P("func (m *", m.GoIdent.GoName, ") Get", oneof.GoName, "() ", oneofInterfaceName(oneof), " {")
+			g.P("if m != nil {")
+			g.P("return m.", oneof.GoName)
+			g.P("}")
+			g.P("return nil")
+			g.P("}")
+			g.P()
+		}
+
+		// Getter for message field.
+		goType, pointer := fieldGoType(g, f, field)
+		defaultValue := fieldDefaultValue(g, f, m, field)
+		g.Annotate(m.GoIdent.GoName+".Get"+field.GoName, field.Location)
+		leadingComments := appendDeprecationSuffix("",
+			field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
+		switch {
+		case field.Desc.IsWeak():
+			g.P(leadingComments, "func (x *", m.GoIdent, ") Get", field.GoName, "() ", protoPackage.Ident("Message"), "{")
+			g.P("var w ", protoimplPackage.Ident("WeakFields"))
+			g.P("if x != nil {")
+			g.P("w = x.", genid.WeakFields_goname)
+			if m.isTracked {
+				g.P("_ = x.", genid.WeakFieldPrefix_goname+field.GoName)
+			}
+			g.P("}")
+			g.P("return ", protoimplPackage.Ident("X"), ".GetWeak(w, ", field.Desc.Number(), ", ", strconv.Quote(string(field.Message.Desc.FullName())), ")")
+			g.P("}")
+		case field.Oneof != nil && !field.Oneof.Desc.IsSynthetic():
+			g.P(leadingComments, "func (x *", m.GoIdent, ") Get", field.GoName, "() ", goType, " {")
+			g.P("if x, ok := x.Get", field.Oneof.GoName, "().(*", field.GoIdent, "); ok {")
+			g.P("return x.", field.GoName)
+			g.P("}")
+			g.P("return ", defaultValue)
+			g.P("}")
+		default:
+			g.P(leadingComments, "func (x *", m.GoIdent, ") Get", field.GoName, "() ", goType, " {")
+			if !field.Desc.HasPresence() || defaultValue == "nil" {
+				g.P("if x != nil {")
+			} else {
+				g.P("if x != nil && x.", field.GoName, " != nil {")
+			}
+			star := ""
+			if pointer {
+				star = "*"
+			}
+			g.P("return ", star, " x.", field.GoName)
+			g.P("}")
+			g.P("return ", defaultValue)
+			g.P("}")
+		}
+		g.P()
+	}
+}
+
+func genMessageSetterMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
+	for _, field := range m.Fields {
+		if !field.Desc.IsWeak() {
+			continue
+		}
+
+		genNoInterfacePragma(g, m.isTracked)
+
+		g.Annotate(m.GoIdent.GoName+".Set"+field.GoName, field.Location)
+		leadingComments := appendDeprecationSuffix("",
+			field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
+		g.P(leadingComments, "func (x *", m.GoIdent, ") Set", field.GoName, "(v ", protoPackage.Ident("Message"), ") {")
+		g.P("var w *", protoimplPackage.Ident("WeakFields"))
+		g.P("if x != nil {")
+		g.P("w = &x.", genid.WeakFields_goname)
+		if m.isTracked {
+			g.P("_ = x.", genid.WeakFieldPrefix_goname+field.GoName)
+		}
+		g.P("}")
+		g.P(protoimplPackage.Ident("X"), ".SetWeak(w, ", field.Desc.Number(), ", ", strconv.Quote(string(field.Message.Desc.FullName())), ", v)")
+		g.P("}")
+		g.P()
+	}
+}
+
+// fieldGoType returns the Go type used for a field.
+//
+// If it returns pointer=true, the struct field is a pointer to the type.
+func fieldGoType(g *protogen.GeneratedFile, f *fileInfo, field *protogen.Field) (goType string, pointer bool) {
+	if field.Desc.IsWeak() {
+		return "struct{}", false
+	}
+
+	pointer = field.Desc.HasPresence()
+	switch field.Desc.Kind() {
+	case protoreflect.BoolKind:
+		goType = "bool"
+	case protoreflect.EnumKind:
+		goType = g.QualifiedGoIdent(field.Enum.GoIdent)
+	case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind:
+		goType = "int32"
+	case protoreflect.Uint32Kind, protoreflect.Fixed32Kind:
+		goType = "uint32"
+	case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind:
+		goType = "int64"
+	case protoreflect.Uint64Kind, protoreflect.Fixed64Kind:
+		goType = "uint64"
+	case protoreflect.FloatKind:
+		goType = "float32"
+	case protoreflect.DoubleKind:
+		goType = "float64"
+	case protoreflect.StringKind:
+		goType = "string"
+	case protoreflect.BytesKind:
+		goType = "[]byte"
+		pointer = false // rely on nullability of slices for presence
+	case protoreflect.MessageKind, protoreflect.GroupKind:
+		goType = "*" + g.QualifiedGoIdent(field.Message.GoIdent)
+		pointer = false // pointer captured as part of the type
+	}
+	switch {
+	case field.Desc.IsList():
+		return "[]" + goType, false
+	case field.Desc.IsMap():
+		keyType, _ := fieldGoType(g, f, field.Message.Fields[0])
+		valType, _ := fieldGoType(g, f, field.Message.Fields[1])
+		return fmt.Sprintf("map[%v]%v", keyType, valType), false
+	}
+	return goType, pointer
+}
+
+func fieldProtobufTagValue(field *protogen.Field) string {
+	var enumName string
+	if field.Desc.Kind() == protoreflect.EnumKind {
+		enumName = protoimpl.X.LegacyEnumName(field.Enum.Desc)
+	}
+	return tag.Marshal(field.Desc, enumName)
+}
+
+func fieldDefaultValue(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo, field *protogen.Field) string {
+	if field.Desc.IsList() {
+		return "nil"
+	}
+	if field.Desc.HasDefault() {
+		defVarName := "Default_" + m.GoIdent.GoName + "_" + field.GoName
+		if field.Desc.Kind() == protoreflect.BytesKind {
+			return "append([]byte(nil), " + defVarName + "...)"
+		}
+		return defVarName
+	}
+	switch field.Desc.Kind() {
+	case protoreflect.BoolKind:
+		return "false"
+	case protoreflect.StringKind:
+		return `""`
+	case protoreflect.MessageKind, protoreflect.GroupKind, protoreflect.BytesKind:
+		return "nil"
+	case protoreflect.EnumKind:
+		val := field.Enum.Values[0]
+		if val.GoIdent.GoImportPath == f.GoImportPath {
+			return g.QualifiedGoIdent(val.GoIdent)
+		} else {
+			// If the enum value is declared in a different Go package,
+			// reference it by number since the name may not be correct.
+			// See https://github.com/golang/protobuf/issues/513.
+			return g.QualifiedGoIdent(field.Enum.GoIdent) + "(" + strconv.FormatInt(int64(val.Desc.Number()), 10) + ")"
+		}
+	default:
+		return "0"
+	}
+}
+
+func fieldJSONTagValue(field *protogen.Field) string {
+	return string(field.Desc.Name()) + ",omitempty"
+}
+
+func genExtensions(g *protogen.GeneratedFile, f *fileInfo) {
+	if len(f.allExtensions) == 0 {
+		return
+	}
+
+	g.P("var ", extensionTypesVarName(f), " = []", protoimplPackage.Ident("ExtensionInfo"), "{")
+	for _, x := range f.allExtensions {
+		g.P("{")
+		g.P("ExtendedType: (*", x.Extendee.GoIdent, ")(nil),")
+		goType, pointer := fieldGoType(g, f, x.Extension)
+		if pointer {
+			goType = "*" + goType
+		}
+		g.P("ExtensionType: (", goType, ")(nil),")
+		g.P("Field: ", x.Desc.Number(), ",")
+		g.P("Name: ", strconv.Quote(string(x.Desc.FullName())), ",")
+		g.P("Tag: ", strconv.Quote(fieldProtobufTagValue(x.Extension)), ",")
+		g.P("Filename: ", strconv.Quote(f.Desc.Path()), ",")
+		g.P("},")
+	}
+	g.P("}")
+	g.P()
+
+	// Group extensions by the target message.
+	var orderedTargets []protogen.GoIdent
+	allExtensionsByTarget := make(map[protogen.GoIdent][]*extensionInfo)
+	allExtensionsByPtr := make(map[*extensionInfo]int)
+	for i, x := range f.allExtensions {
+		target := x.Extendee.GoIdent
+		if len(allExtensionsByTarget[target]) == 0 {
+			orderedTargets = append(orderedTargets, target)
+		}
+		allExtensionsByTarget[target] = append(allExtensionsByTarget[target], x)
+		allExtensionsByPtr[x] = i
+	}
+	for _, target := range orderedTargets {
+		g.P("// Extension fields to ", target, ".")
+		g.P("var (")
+		for _, x := range allExtensionsByTarget[target] {
+			xd := x.Desc
+			typeName := xd.Kind().String()
+			switch xd.Kind() {
+			case protoreflect.EnumKind:
+				typeName = string(xd.Enum().FullName())
+			case protoreflect.MessageKind, protoreflect.GroupKind:
+				typeName = string(xd.Message().FullName())
+			}
+			fieldName := string(xd.Name())
+
+			leadingComments := x.Comments.Leading
+			if leadingComments != "" {
+				leadingComments += "\n"
+			}
+			leadingComments += protogen.Comments(fmt.Sprintf(" %v %v %v = %v;\n",
+				xd.Cardinality(), typeName, fieldName, xd.Number()))
+			leadingComments = appendDeprecationSuffix(leadingComments,
+				x.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
+			g.P(leadingComments,
+				"E_", x.GoIdent, " = &", extensionTypesVarName(f), "[", allExtensionsByPtr[x], "]",
+				trailingComment(x.Comments.Trailing))
+		}
+		g.P(")")
+		g.P()
+	}
+}
+
+// genMessageOneofWrapperTypes generates the oneof wrapper types and
+// associates the types with the parent message type.
+func genMessageOneofWrapperTypes(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
+	for _, oneof := range m.Oneofs {
+		if oneof.Desc.IsSynthetic() {
+			continue
+		}
+		ifName := oneofInterfaceName(oneof)
+		g.P("type ", ifName, " interface {")
+		g.P(ifName, "()")
+		g.P("}")
+		g.P()
+		for _, field := range oneof.Fields {
+			g.Annotate(field.GoIdent.GoName, field.Location)
+			g.Annotate(field.GoIdent.GoName+"."+field.GoName, field.Location)
+			g.P("type ", field.GoIdent, " struct {")
+			goType, _ := fieldGoType(g, f, field)
+			tags := structTags{
+				{"protobuf", fieldProtobufTagValue(field)},
+			}
+			if m.isTracked {
+				tags = append(tags, gotrackTags...)
+			}
+			leadingComments := appendDeprecationSuffix(field.Comments.Leading,
+				field.Desc.Options().(*descriptorpb.FieldOptions).GetDeprecated())
+			g.P(leadingComments,
+				field.GoName, " ", goType, tags,
+				trailingComment(field.Comments.Trailing))
+			g.P("}")
+			g.P()
+		}
+		for _, field := range oneof.Fields {
+			g.P("func (*", field.GoIdent, ") ", ifName, "() {}")
+			g.P()
+		}
+	}
+}
+
+// oneofInterfaceName returns the name of the interface type implemented by
+// the oneof field value types.
+func oneofInterfaceName(oneof *protogen.Oneof) string {
+	return "is" + oneof.GoIdent.GoName
+}
+
+// genNoInterfacePragma generates a standalone "nointerface" pragma to
+// decorate methods with field-tracking support.
+func genNoInterfacePragma(g *protogen.GeneratedFile, tracked bool) {
+	if tracked {
+		g.P("//go:nointerface")
+		g.P()
+	}
+}
+
+var gotrackTags = structTags{{"go", "track"}}
+
+// structTags is a data structure for build idiomatic Go struct tags.
+// Each [2]string is a key-value pair, where value is the unescaped string.
+//
+// Example: structTags{{"key", "value"}}.String() -> `key:"value"`
+type structTags [][2]string
+
+func (tags structTags) String() string {
+	if len(tags) == 0 {
+		return ""
+	}
+	var ss []string
+	for _, tag := range tags {
+		// NOTE: When quoting the value, we need to make sure the backtick
+		// character does not appear. Convert all cases to the escaped hex form.
+		key := tag[0]
+		val := strings.Replace(strconv.Quote(tag[1]), "`", `\x60`, -1)
+		ss = append(ss, fmt.Sprintf("%s:%s", key, val))
+	}
+	return "`" + strings.Join(ss, " ") + "`"
+}
+
+// appendDeprecationSuffix optionally appends a deprecation notice as a suffix.
+func appendDeprecationSuffix(prefix protogen.Comments, deprecated bool) protogen.Comments {
+	if !deprecated {
+		return prefix
+	}
+	if prefix != "" {
+		prefix += "\n"
+	}
+	return prefix + " Deprecated: Do not use.\n"
+}
+
+// trailingComment is like protogen.Comments, but lacks a trailing newline.
+type trailingComment protogen.Comments
+
+func (c trailingComment) String() string {
+	s := strings.TrimSuffix(protogen.Comments(c).String(), "\n")
+	if strings.Contains(s, "\n") {
+		// We don't support multi-lined trailing comments as it is unclear
+		// how to best render them in the generated code.
+		return ""
+	}
+	return s
+}
diff --git a/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/reflect.go b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/reflect.go
new file mode 100644
index 0000000000000..1319a12675076
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/reflect.go
@@ -0,0 +1,351 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package internal_gengo
+
+import (
+	"fmt"
+	"math"
+	"strings"
+	"unicode/utf8"
+
+	"google.golang.org/protobuf/compiler/protogen"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protoreflect"
+
+	"google.golang.org/protobuf/types/descriptorpb"
+)
+
+func genReflectFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo) {
+	g.P("var ", f.GoDescriptorIdent, " ", protoreflectPackage.Ident("FileDescriptor"))
+	g.P()
+
+	genFileDescriptor(gen, g, f)
+	if len(f.allEnums) > 0 {
+		g.P("var ", enumTypesVarName(f), " = make([]", protoimplPackage.Ident("EnumInfo"), ",", len(f.allEnums), ")")
+	}
+	if len(f.allMessages) > 0 {
+		g.P("var ", messageTypesVarName(f), " = make([]", protoimplPackage.Ident("MessageInfo"), ",", len(f.allMessages), ")")
+	}
+
+	// Generate a unique list of Go types for all declarations and dependencies,
+	// and the associated index into the type list for all dependencies.
+	var goTypes []string
+	var depIdxs []string
+	seen := map[protoreflect.FullName]int{}
+	genDep := func(name protoreflect.FullName, depSource string) {
+		if depSource != "" {
+			line := fmt.Sprintf("%d, // %d: %s -> %s", seen[name], len(depIdxs), depSource, name)
+			depIdxs = append(depIdxs, line)
+		}
+	}
+	genEnum := func(e *protogen.Enum, depSource string) {
+		if e != nil {
+			name := e.Desc.FullName()
+			if _, ok := seen[name]; !ok {
+				line := fmt.Sprintf("(%s)(0), // %d: %s", g.QualifiedGoIdent(e.GoIdent), len(goTypes), name)
+				goTypes = append(goTypes, line)
+				seen[name] = len(seen)
+			}
+			if depSource != "" {
+				genDep(name, depSource)
+			}
+		}
+	}
+	genMessage := func(m *protogen.Message, depSource string) {
+		if m != nil {
+			name := m.Desc.FullName()
+			if _, ok := seen[name]; !ok {
+				line := fmt.Sprintf("(*%s)(nil), // %d: %s", g.QualifiedGoIdent(m.GoIdent), len(goTypes), name)
+				if m.Desc.IsMapEntry() {
+					// Map entry messages have no associated Go type.
+					line = fmt.Sprintf("nil, // %d: %s", len(goTypes), name)
+				}
+				goTypes = append(goTypes, line)
+				seen[name] = len(seen)
+			}
+			if depSource != "" {
+				genDep(name, depSource)
+			}
+		}
+	}
+
+	// This ordering is significant.
+	// See filetype.TypeBuilder.DependencyIndexes.
+	type offsetEntry struct {
+		start int
+		name  string
+	}
+	var depOffsets []offsetEntry
+	for _, enum := range f.allEnums {
+		genEnum(enum.Enum, "")
+	}
+	for _, message := range f.allMessages {
+		genMessage(message.Message, "")
+	}
+	depOffsets = append(depOffsets, offsetEntry{len(depIdxs), "field type_name"})
+	for _, message := range f.allMessages {
+		for _, field := range message.Fields {
+			if field.Desc.IsWeak() {
+				continue
+			}
+			source := string(field.Desc.FullName())
+			genEnum(field.Enum, source+":type_name")
+			genMessage(field.Message, source+":type_name")
+		}
+	}
+	depOffsets = append(depOffsets, offsetEntry{len(depIdxs), "extension extendee"})
+	for _, extension := range f.allExtensions {
+		source := string(extension.Desc.FullName())
+		genMessage(extension.Extendee, source+":extendee")
+	}
+	depOffsets = append(depOffsets, offsetEntry{len(depIdxs), "extension type_name"})
+	for _, extension := range f.allExtensions {
+		source := string(extension.Desc.FullName())
+		genEnum(extension.Enum, source+":type_name")
+		genMessage(extension.Message, source+":type_name")
+	}
+	depOffsets = append(depOffsets, offsetEntry{len(depIdxs), "method input_type"})
+	for _, service := range f.Services {
+		for _, method := range service.Methods {
+			source := string(method.Desc.FullName())
+			genMessage(method.Input, source+":input_type")
+		}
+	}
+	depOffsets = append(depOffsets, offsetEntry{len(depIdxs), "method output_type"})
+	for _, service := range f.Services {
+		for _, method := range service.Methods {
+			source := string(method.Desc.FullName())
+			genMessage(method.Output, source+":output_type")
+		}
+	}
+	depOffsets = append(depOffsets, offsetEntry{len(depIdxs), ""})
+	for i := len(depOffsets) - 2; i >= 0; i-- {
+		curr, next := depOffsets[i], depOffsets[i+1]
+		depIdxs = append(depIdxs, fmt.Sprintf("%d, // [%d:%d] is the sub-list for %s",
+			curr.start, curr.start, next.start, curr.name))
+	}
+	if len(depIdxs) > math.MaxInt32 {
+		panic("too many dependencies") // sanity check
+	}
+
+	g.P("var ", goTypesVarName(f), " = []interface{}{")
+	for _, s := range goTypes {
+		g.P(s)
+	}
+	g.P("}")
+
+	g.P("var ", depIdxsVarName(f), " = []int32{")
+	for _, s := range depIdxs {
+		g.P(s)
+	}
+	g.P("}")
+
+	g.P("func init() { ", initFuncName(f.File), "() }")
+
+	g.P("func ", initFuncName(f.File), "() {")
+	g.P("if ", f.GoDescriptorIdent, " != nil {")
+	g.P("return")
+	g.P("}")
+
+	// Ensure that initialization functions for different files in the same Go
+	// package run in the correct order: Call the init funcs for every .proto file
+	// imported by this one that is in the same Go package.
+	for i, imps := 0, f.Desc.Imports(); i < imps.Len(); i++ {
+		impFile := gen.FilesByPath[imps.Get(i).Path()]
+		if impFile.GoImportPath != f.GoImportPath {
+			continue
+		}
+		g.P(initFuncName(impFile), "()")
+	}
+
+	if len(f.allMessages) > 0 {
+		// Populate MessageInfo.Exporters.
+		g.P("if !", protoimplPackage.Ident("UnsafeEnabled"), " {")
+		for _, message := range f.allMessages {
+			if sf := f.allMessageFieldsByPtr[message]; len(sf.unexported) > 0 {
+				idx := f.allMessagesByPtr[message]
+				typesVar := messageTypesVarName(f)
+
+				g.P(typesVar, "[", idx, "].Exporter = func(v interface{}, i int) interface{} {")
+				g.P("switch v := v.(*", message.GoIdent, "); i {")
+				for i := 0; i < sf.count; i++ {
+					if name := sf.unexported[i]; name != "" {
+						g.P("case ", i, ": return &v.", name)
+					}
+				}
+				g.P("default: return nil")
+				g.P("}")
+				g.P("}")
+			}
+		}
+		g.P("}")
+
+		// Populate MessageInfo.OneofWrappers.
+		for _, message := range f.allMessages {
+			if len(message.Oneofs) > 0 {
+				idx := f.allMessagesByPtr[message]
+				typesVar := messageTypesVarName(f)
+
+				// Associate the wrapper types by directly passing them to the MessageInfo.
+				g.P(typesVar, "[", idx, "].OneofWrappers = []interface{} {")
+				for _, oneof := range message.Oneofs {
+					if !oneof.Desc.IsSynthetic() {
+						for _, field := range oneof.Fields {
+							g.P("(*", field.GoIdent, ")(nil),")
+						}
+					}
+				}
+				g.P("}")
+			}
+		}
+	}
+
+	g.P("type x struct{}")
+	g.P("out := ", protoimplPackage.Ident("TypeBuilder"), "{")
+	g.P("File: ", protoimplPackage.Ident("DescBuilder"), "{")
+	g.P("GoPackagePath: ", reflectPackage.Ident("TypeOf"), "(x{}).PkgPath(),")
+	g.P("RawDescriptor: ", rawDescVarName(f), ",")
+	g.P("NumEnums: ", len(f.allEnums), ",")
+	g.P("NumMessages: ", len(f.allMessages), ",")
+	g.P("NumExtensions: ", len(f.allExtensions), ",")
+	g.P("NumServices: ", len(f.Services), ",")
+	g.P("},")
+	g.P("GoTypes: ", goTypesVarName(f), ",")
+	g.P("DependencyIndexes: ", depIdxsVarName(f), ",")
+	if len(f.allEnums) > 0 {
+		g.P("EnumInfos: ", enumTypesVarName(f), ",")
+	}
+	if len(f.allMessages) > 0 {
+		g.P("MessageInfos: ", messageTypesVarName(f), ",")
+	}
+	if len(f.allExtensions) > 0 {
+		g.P("ExtensionInfos: ", extensionTypesVarName(f), ",")
+	}
+	g.P("}.Build()")
+	g.P(f.GoDescriptorIdent, " = out.File")
+
+	// Set inputs to nil to allow GC to reclaim resources.
+	g.P(rawDescVarName(f), " = nil")
+	g.P(goTypesVarName(f), " = nil")
+	g.P(depIdxsVarName(f), " = nil")
+	g.P("}")
+}
+
+func genFileDescriptor(gen *protogen.Plugin, g *protogen.GeneratedFile, f *fileInfo) {
+	descProto := proto.Clone(f.Proto).(*descriptorpb.FileDescriptorProto)
+	descProto.SourceCodeInfo = nil // drop source code information
+
+	b, err := proto.MarshalOptions{AllowPartial: true, Deterministic: true}.Marshal(descProto)
+	if err != nil {
+		gen.Error(err)
+		return
+	}
+
+	g.P("var ", rawDescVarName(f), " = []byte{")
+	for len(b) > 0 {
+		n := 16
+		if n > len(b) {
+			n = len(b)
+		}
+
+		s := ""
+		for _, c := range b[:n] {
+			s += fmt.Sprintf("0x%02x,", c)
+		}
+		g.P(s)
+
+		b = b[n:]
+	}
+	g.P("}")
+	g.P()
+
+	if f.needRawDesc {
+		onceVar := rawDescVarName(f) + "Once"
+		dataVar := rawDescVarName(f) + "Data"
+		g.P("var (")
+		g.P(onceVar, " ", syncPackage.Ident("Once"))
+		g.P(dataVar, " = ", rawDescVarName(f))
+		g.P(")")
+		g.P()
+
+		g.P("func ", rawDescVarName(f), "GZIP() []byte {")
+		g.P(onceVar, ".Do(func() {")
+		g.P(dataVar, " = ", protoimplPackage.Ident("X"), ".CompressGZIP(", dataVar, ")")
+		g.P("})")
+		g.P("return ", dataVar)
+		g.P("}")
+		g.P()
+	}
+}
+
+func genEnumReflectMethods(g *protogen.GeneratedFile, f *fileInfo, e *enumInfo) {
+	idx := f.allEnumsByPtr[e]
+	typesVar := enumTypesVarName(f)
+
+	// Descriptor method.
+	g.P("func (", e.GoIdent, ") Descriptor() ", protoreflectPackage.Ident("EnumDescriptor"), " {")
+	g.P("return ", typesVar, "[", idx, "].Descriptor()")
+	g.P("}")
+	g.P()
+
+	// Type method.
+	g.P("func (", e.GoIdent, ") Type() ", protoreflectPackage.Ident("EnumType"), " {")
+	g.P("return &", typesVar, "[", idx, "]")
+	g.P("}")
+	g.P()
+
+	// Number method.
+	g.P("func (x ", e.GoIdent, ") Number() ", protoreflectPackage.Ident("EnumNumber"), " {")
+	g.P("return ", protoreflectPackage.Ident("EnumNumber"), "(x)")
+	g.P("}")
+	g.P()
+}
+
+func genMessageReflectMethods(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
+	idx := f.allMessagesByPtr[m]
+	typesVar := messageTypesVarName(f)
+
+	// ProtoReflect method.
+	g.P("func (x *", m.GoIdent, ") ProtoReflect() ", protoreflectPackage.Ident("Message"), " {")
+	g.P("mi := &", typesVar, "[", idx, "]")
+	g.P("if ", protoimplPackage.Ident("UnsafeEnabled"), " && x != nil {")
+	g.P("ms := ", protoimplPackage.Ident("X"), ".MessageStateOf(", protoimplPackage.Ident("Pointer"), "(x))")
+	g.P("if ms.LoadMessageInfo() == nil {")
+	g.P("ms.StoreMessageInfo(mi)")
+	g.P("}")
+	g.P("return ms")
+	g.P("}")
+	g.P("return mi.MessageOf(x)")
+	g.P("}")
+	g.P()
+}
+
+func fileVarName(f *protogen.File, suffix string) string {
+	prefix := f.GoDescriptorIdent.GoName
+	_, n := utf8.DecodeRuneInString(prefix)
+	prefix = strings.ToLower(prefix[:n]) + prefix[n:]
+	return prefix + "_" + suffix
+}
+func rawDescVarName(f *fileInfo) string {
+	return fileVarName(f.File, "rawDesc")
+}
+func goTypesVarName(f *fileInfo) string {
+	return fileVarName(f.File, "goTypes")
+}
+func depIdxsVarName(f *fileInfo) string {
+	return fileVarName(f.File, "depIdxs")
+}
+func enumTypesVarName(f *fileInfo) string {
+	return fileVarName(f.File, "enumTypes")
+}
+func messageTypesVarName(f *fileInfo) string {
+	return fileVarName(f.File, "msgTypes")
+}
+func extensionTypesVarName(f *fileInfo) string {
+	return fileVarName(f.File, "extTypes")
+}
+func initFuncName(f *protogen.File) string {
+	return fileVarName(f, "init")
+}
diff --git a/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/well_known_types.go b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/well_known_types.go
new file mode 100644
index 0000000000000..696dddb9f0600
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo/well_known_types.go
@@ -0,0 +1,1080 @@
+// Copyright 2020 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package internal_gengo
+
+import (
+	"strings"
+
+	"google.golang.org/protobuf/compiler/protogen"
+	"google.golang.org/protobuf/internal/genid"
+)
+
+// Specialized support for well-known types are hard-coded into the generator
+// as opposed to being injected in adjacent .go sources in the generated package
+// in order to support specialized build systems like Bazel that always generate
+// dynamically from the source .proto files.
+
+func genPackageKnownComment(f *fileInfo) protogen.Comments {
+	switch f.Desc.Path() {
+	case genid.File_google_protobuf_any_proto:
+		return ` Package anypb contains generated types for ` + genid.File_google_protobuf_any_proto + `.
+
+ The Any message is a dynamic representation of any other message value.
+ It is functionally a tuple of the full name of the remote message type and
+ the serialized bytes of the remote message value.
+
+
+ Constructing an Any
+
+ An Any message containing another message value is constructed using New:
+
+	any, err := anypb.New(m)
+	if err != nil {
+		... // handle error
+	}
+	... // make use of any
+
+
+ Unmarshaling an Any
+
+ With a populated Any message, the underlying message can be serialized into
+ a remote concrete message value in a few ways.
+
+ If the exact concrete type is known, then a new (or pre-existing) instance
+ of that message can be passed to the UnmarshalTo method:
+
+	m := new(foopb.MyMessage)
+	if err := any.UnmarshalTo(m); err != nil {
+		... // handle error
+	}
+	... // make use of m
+
+ If the exact concrete type is not known, then the UnmarshalNew method can be
+ used to unmarshal the contents into a new instance of the remote message type:
+
+	m, err := any.UnmarshalNew()
+	if err != nil {
+		... // handle error
+	}
+	... // make use of m
+
+ UnmarshalNew uses the global type registry to resolve the message type and
+ construct a new instance of that message to unmarshal into. In order for a
+ message type to appear in the global registry, the Go type representing that
+ protobuf message type must be linked into the Go binary. For messages
+ generated by protoc-gen-go, this is achieved through an import of the
+ generated Go package representing a .proto file.
+
+ A common pattern with UnmarshalNew is to use a type switch with the resulting
+ proto.Message value:
+
+	switch m := m.(type) {
+	case *foopb.MyMessage:
+		... // make use of m as a *foopb.MyMessage
+	case *barpb.OtherMessage:
+		... // make use of m as a *barpb.OtherMessage
+	case *bazpb.SomeMessage:
+		... // make use of m as a *bazpb.SomeMessage
+	}
+
+ This pattern ensures that the generated packages containing the message types
+ listed in the case clauses are linked into the Go binary and therefore also
+ registered in the global registry.
+
+
+ Type checking an Any
+
+ In order to type check whether an Any message represents some other message,
+ then use the MessageIs method:
+
+	if any.MessageIs((*foopb.MyMessage)(nil)) {
+		... // make use of any, knowing that it contains a foopb.MyMessage
+	}
+
+ The MessageIs method can also be used with an allocated instance of the target
+ message type if the intention is to unmarshal into it if the type matches:
+
+	m := new(foopb.MyMessage)
+	if any.MessageIs(m) {
+		if err := any.UnmarshalTo(m); err != nil {
+			... // handle error
+		}
+		... // make use of m
+	}
+
+`
+	case genid.File_google_protobuf_timestamp_proto:
+		return ` Package timestamppb contains generated types for ` + genid.File_google_protobuf_timestamp_proto + `.
+
+ The Timestamp message represents a timestamp,
+ an instant in time since the Unix epoch (January 1st, 1970).
+
+
+ Conversion to a Go Time
+
+ The AsTime method can be used to convert a Timestamp message to a
+ standard Go time.Time value in UTC:
+
+	t := ts.AsTime()
+	... // make use of t as a time.Time
+
+ Converting to a time.Time is a common operation so that the extensive
+ set of time-based operations provided by the time package can be leveraged.
+ See https://golang.org/pkg/time for more information.
+
+ The AsTime method performs the conversion on a best-effort basis. Timestamps
+ with denormal values (e.g., nanoseconds beyond 0 and 99999999, inclusive)
+ are normalized during the conversion to a time.Time. To manually check for
+ invalid Timestamps per the documented limitations in timestamp.proto,
+ additionally call the CheckValid method:
+
+	if err := ts.CheckValid(); err != nil {
+		... // handle error
+	}
+
+
+ Conversion from a Go Time
+
+ The timestamppb.New function can be used to construct a Timestamp message
+ from a standard Go time.Time value:
+
+	ts := timestamppb.New(t)
+	... // make use of ts as a *timestamppb.Timestamp
+
+ In order to construct a Timestamp representing the current time, use Now:
+
+	ts := timestamppb.Now()
+	... // make use of ts as a *timestamppb.Timestamp
+
+`
+	case genid.File_google_protobuf_duration_proto:
+		return ` Package durationpb contains generated types for ` + genid.File_google_protobuf_duration_proto + `.
+
+ The Duration message represents a signed span of time.
+
+
+ Conversion to a Go Duration
+
+ The AsDuration method can be used to convert a Duration message to a
+ standard Go time.Duration value:
+
+	d := dur.AsDuration()
+	... // make use of d as a time.Duration
+
+ Converting to a time.Duration is a common operation so that the extensive
+ set of time-based operations provided by the time package can be leveraged.
+ See https://golang.org/pkg/time for more information.
+
+ The AsDuration method performs the conversion on a best-effort basis.
+ Durations with denormal values (e.g., nanoseconds beyond -99999999 and
+ +99999999, inclusive; or seconds and nanoseconds with opposite signs)
+ are normalized during the conversion to a time.Duration. To manually check for
+ invalid Duration per the documented limitations in duration.proto,
+ additionally call the CheckValid method:
+
+	if err := dur.CheckValid(); err != nil {
+		... // handle error
+	}
+
+ Note that the documented limitations in duration.proto does not protect a
+ Duration from overflowing the representable range of a time.Duration in Go.
+ The AsDuration method uses saturation arithmetic such that an overflow clamps
+ the resulting value to the closest representable value (e.g., math.MaxInt64
+ for positive overflow and math.MinInt64 for negative overflow).
+
+
+ Conversion from a Go Duration
+
+ The durationpb.New function can be used to construct a Duration message
+ from a standard Go time.Duration value:
+
+	dur := durationpb.New(d)
+	... // make use of d as a *durationpb.Duration
+
+`
+	case genid.File_google_protobuf_struct_proto:
+		return ` Package structpb contains generated types for ` + genid.File_google_protobuf_struct_proto + `.
+
+ The messages (i.e., Value, Struct, and ListValue) defined in struct.proto are
+ used to represent arbitrary JSON. The Value message represents a JSON value,
+ the Struct message represents a JSON object, and the ListValue message
+ represents a JSON array. See https://json.org for more information.
+
+ The Value, Struct, and ListValue types have generated MarshalJSON and
+ UnmarshalJSON methods such that they serialize JSON equivalent to what the
+ messages themselves represent. Use of these types with the
+ "google.golang.org/protobuf/encoding/protojson" package
+ ensures that they will be serialized as their JSON equivalent.
+
+
+ Conversion to and from a Go interface
+
+ The standard Go "encoding/json" package has functionality to serialize
+ arbitrary types to a large degree. The Value.AsInterface, Struct.AsMap, and
+ ListValue.AsSlice methods can convert the protobuf message representation into
+ a form represented by interface{}, map[string]interface{}, and []interface{}.
+ This form can be used with other packages that operate on such data structures
+ and also directly with the standard json package.
+
+ In order to convert the interface{}, map[string]interface{}, and []interface{}
+ forms back as Value, Struct, and ListValue messages, use the NewStruct,
+ NewList, and NewValue constructor functions.
+
+
+ Example usage
+
+ Consider the following example JSON object:
+
+	{
+		"firstName": "John",
+		"lastName": "Smith",
+		"isAlive": true,
+		"age": 27,
+		"address": {
+			"streetAddress": "21 2nd Street",
+			"city": "New York",
+			"state": "NY",
+			"postalCode": "10021-3100"
+		},
+		"phoneNumbers": [
+			{
+				"type": "home",
+				"number": "212 555-1234"
+			},
+			{
+				"type": "office",
+				"number": "646 555-4567"
+			}
+		],
+		"children": [],
+		"spouse": null
+	}
+
+ To construct a Value message representing the above JSON object:
+
+	m, err := structpb.NewValue(map[string]interface{}{
+		"firstName": "John",
+		"lastName":  "Smith",
+		"isAlive":   true,
+		"age":       27,
+		"address": map[string]interface{}{
+			"streetAddress": "21 2nd Street",
+			"city":          "New York",
+			"state":         "NY",
+			"postalCode":    "10021-3100",
+		},
+		"phoneNumbers": []interface{}{
+			map[string]interface{}{
+				"type":   "home",
+				"number": "212 555-1234",
+			},
+			map[string]interface{}{
+				"type":   "office",
+				"number": "646 555-4567",
+			},
+		},
+		"children": []interface{}{},
+		"spouse":   nil,
+	})
+	if err != nil {
+		... // handle error
+	}
+	... // make use of m as a *structpb.Value
+
+`
+	case genid.File_google_protobuf_field_mask_proto:
+		return ` Package fieldmaskpb contains generated types for ` + genid.File_google_protobuf_field_mask_proto + `.
+
+ The FieldMask message represents a set of symbolic field paths.
+ The paths are specific to some target message type,
+ which is not stored within the FieldMask message itself.
+
+
+ Constructing a FieldMask
+
+ The New function is used construct a FieldMask:
+
+	var messageType *descriptorpb.DescriptorProto
+	fm, err := fieldmaskpb.New(messageType, "field.name", "field.number")
+	if err != nil {
+		... // handle error
+	}
+	... // make use of fm
+
+ The "field.name" and "field.number" paths are valid paths according to the
+ google.protobuf.DescriptorProto message. Use of a path that does not correlate
+ to valid fields reachable from DescriptorProto would result in an error.
+
+ Once a FieldMask message has been constructed,
+ the Append method can be used to insert additional paths to the path set:
+
+	var messageType *descriptorpb.DescriptorProto
+	if err := fm.Append(messageType, "options"); err != nil {
+		... // handle error
+	}
+
+
+ Type checking a FieldMask
+
+ In order to verify that a FieldMask represents a set of fields that are
+ reachable from some target message type, use the IsValid method:
+
+	var messageType *descriptorpb.DescriptorProto
+	if fm.IsValid(messageType) {
+		... // make use of fm
+	}
+
+ IsValid needs to be passed the target message type as an input since the
+ FieldMask message itself does not store the message type that the set of paths
+ are for.
+`
+	default:
+		return ""
+	}
+}
+
+func genMessageKnownFunctions(g *protogen.GeneratedFile, f *fileInfo, m *messageInfo) {
+	switch m.Desc.FullName() {
+	case genid.Any_message_fullname:
+		g.P("// New marshals src into a new Any instance.")
+		g.P("func New(src ", protoPackage.Ident("Message"), ") (*Any, error) {")
+		g.P("	dst := new(Any)")
+		g.P("	if err := dst.MarshalFrom(src); err != nil {")
+		g.P("		return nil, err")
+		g.P("	}")
+		g.P("	return dst, nil")
+		g.P("}")
+		g.P()
+
+		g.P("// MarshalFrom marshals src into dst as the underlying message")
+		g.P("// using the provided marshal options.")
+		g.P("//")
+		g.P("// If no options are specified, call dst.MarshalFrom instead.")
+		g.P("func MarshalFrom(dst *Any, src ", protoPackage.Ident("Message"), ", opts ", protoPackage.Ident("MarshalOptions"), ") error {")
+		g.P("	const urlPrefix = \"type.googleapis.com/\"")
+		g.P("	if src == nil {")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"invalid nil source message\")")
+		g.P("	}")
+		g.P("	b, err := opts.Marshal(src)")
+		g.P("	if err != nil {")
+		g.P("		return err")
+		g.P("	}")
+		g.P("	dst.TypeUrl = urlPrefix + string(src.ProtoReflect().Descriptor().FullName())")
+		g.P("	dst.Value = b")
+		g.P("	return nil")
+		g.P("}")
+		g.P()
+
+		g.P("// UnmarshalTo unmarshals the underlying message from src into dst")
+		g.P("// using the provided unmarshal options.")
+		g.P("// It reports an error if dst is not of the right message type.")
+		g.P("//")
+		g.P("// If no options are specified, call src.UnmarshalTo instead.")
+		g.P("func UnmarshalTo(src *Any, dst ", protoPackage.Ident("Message"), ", opts ", protoPackage.Ident("UnmarshalOptions"), ") error {")
+		g.P("	if src == nil {")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"invalid nil source message\")")
+		g.P("	}")
+		g.P("	if !src.MessageIs(dst) {")
+		g.P("		got := dst.ProtoReflect().Descriptor().FullName()")
+		g.P("		want := src.MessageName()")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"mismatched message type: got %q, want %q\", got, want)")
+		g.P("	}")
+		g.P("	return opts.Unmarshal(src.GetValue(), dst)")
+		g.P("}")
+		g.P()
+
+		g.P("// UnmarshalNew unmarshals the underlying message from src into dst,")
+		g.P("// which is newly created message using a type resolved from the type URL.")
+		g.P("// The message type is resolved according to opt.Resolver,")
+		g.P("// which should implement protoregistry.MessageTypeResolver.")
+		g.P("// It reports an error if the underlying message type could not be resolved.")
+		g.P("//")
+		g.P("// If no options are specified, call src.UnmarshalNew instead.")
+		g.P("func UnmarshalNew(src *Any, opts ", protoPackage.Ident("UnmarshalOptions"), ") (dst ", protoPackage.Ident("Message"), ", err error) {")
+		g.P("	if src.GetTypeUrl() == \"\" {")
+		g.P("		return nil, ", protoimplPackage.Ident("X"), ".NewError(\"invalid empty type URL\")")
+		g.P("	}")
+		g.P("	if opts.Resolver == nil {")
+		g.P("		opts.Resolver = ", protoregistryPackage.Ident("GlobalTypes"))
+		g.P("	}")
+		g.P("	r, ok := opts.Resolver.(", protoregistryPackage.Ident("MessageTypeResolver"), ")")
+		g.P("	if !ok {")
+		g.P("		return nil, ", protoregistryPackage.Ident("NotFound"))
+		g.P("	}")
+		g.P("	mt, err := r.FindMessageByURL(src.GetTypeUrl())")
+		g.P("	if err != nil {")
+		g.P("		if err == ", protoregistryPackage.Ident("NotFound"), " {")
+		g.P("			return nil, err")
+		g.P("		}")
+		g.P("		return nil, ", protoimplPackage.Ident("X"), ".NewError(\"could not resolve %q: %v\", src.GetTypeUrl(), err)")
+		g.P("	}")
+		g.P("	dst = mt.New().Interface()")
+		g.P("	return dst, opts.Unmarshal(src.GetValue(), dst)")
+		g.P("}")
+		g.P()
+
+		g.P("// MessageIs reports whether the underlying message is of the same type as m.")
+		g.P("func (x *Any) MessageIs(m ", protoPackage.Ident("Message"), ") bool {")
+		g.P("	if m == nil {")
+		g.P("		return false")
+		g.P("	}")
+		g.P("	url := x.GetTypeUrl()")
+		g.P("	name := string(m.ProtoReflect().Descriptor().FullName())")
+		g.P("	if !", stringsPackage.Ident("HasSuffix"), "(url, name) {")
+		g.P("		return false")
+		g.P("	}")
+		g.P("	return len(url) == len(name) || url[len(url)-len(name)-1] == '/'")
+		g.P("}")
+		g.P()
+
+		g.P("// MessageName reports the full name of the underlying message,")
+		g.P("// returning an empty string if invalid.")
+		g.P("func (x *Any) MessageName() ", protoreflectPackage.Ident("FullName"), " {")
+		g.P("	url := x.GetTypeUrl()")
+		g.P("	name := ", protoreflectPackage.Ident("FullName"), "(url)")
+		g.P("	if i := ", stringsPackage.Ident("LastIndexByte"), "(url, '/'); i >= 0 {")
+		g.P("		name = name[i+len(\"/\"):]")
+		g.P("	}")
+		g.P("	if !name.IsValid() {")
+		g.P("		return \"\"")
+		g.P("	}")
+		g.P("	return name")
+		g.P("}")
+		g.P()
+
+		g.P("// MarshalFrom marshals m into x as the underlying message.")
+		g.P("func (x *Any) MarshalFrom(m ", protoPackage.Ident("Message"), ") error {")
+		g.P("	return MarshalFrom(x, m, ", protoPackage.Ident("MarshalOptions"), "{})")
+		g.P("}")
+		g.P()
+
+		g.P("// UnmarshalTo unmarshals the contents of the underlying message of x into m.")
+		g.P("// It resets m before performing the unmarshal operation.")
+		g.P("// It reports an error if m is not of the right message type.")
+		g.P("func (x *Any) UnmarshalTo(m ", protoPackage.Ident("Message"), ") error {")
+		g.P("	return UnmarshalTo(x, m, ", protoPackage.Ident("UnmarshalOptions"), "{})")
+		g.P("}")
+		g.P()
+
+		g.P("// UnmarshalNew unmarshals the contents of the underlying message of x into")
+		g.P("// a newly allocated message of the specified type.")
+		g.P("// It reports an error if the underlying message type could not be resolved.")
+		g.P("func (x *Any) UnmarshalNew() (", protoPackage.Ident("Message"), ", error) {")
+		g.P("	return UnmarshalNew(x, ", protoPackage.Ident("UnmarshalOptions"), "{})")
+		g.P("}")
+		g.P()
+
+	case genid.Timestamp_message_fullname:
+		g.P("// Now constructs a new Timestamp from the current time.")
+		g.P("func Now() *Timestamp {")
+		g.P("	return New(", timePackage.Ident("Now"), "())")
+		g.P("}")
+		g.P()
+
+		g.P("// New constructs a new Timestamp from the provided time.Time.")
+		g.P("func New(t ", timePackage.Ident("Time"), ") *Timestamp {")
+		g.P("	return &Timestamp{Seconds: int64(t.Unix()), Nanos: int32(t.Nanosecond())}")
+		g.P("}")
+		g.P()
+
+		g.P("// AsTime converts x to a time.Time.")
+		g.P("func (x *Timestamp) AsTime() ", timePackage.Ident("Time"), " {")
+		g.P("	return ", timePackage.Ident("Unix"), "(int64(x.GetSeconds()), int64(x.GetNanos())).UTC()")
+		g.P("}")
+		g.P()
+
+		g.P("// IsValid reports whether the timestamp is valid.")
+		g.P("// It is equivalent to CheckValid == nil.")
+		g.P("func (x *Timestamp) IsValid() bool {")
+		g.P("	return x.check() == 0")
+		g.P("}")
+		g.P()
+
+		g.P("// CheckValid returns an error if the timestamp is invalid.")
+		g.P("// In particular, it checks whether the value represents a date that is")
+		g.P("// in the range of 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive.")
+		g.P("// An error is reported for a nil Timestamp.")
+		g.P("func (x *Timestamp) CheckValid() error {")
+		g.P("	switch x.check() {")
+		g.P("	case invalidNil:")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"invalid nil Timestamp\")")
+		g.P("	case invalidUnderflow:")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"timestamp (%v) before 0001-01-01\", x)")
+		g.P("	case invalidOverflow:")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"timestamp (%v) after 9999-12-31\", x)")
+		g.P("	case invalidNanos:")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"timestamp (%v) has out-of-range nanos\", x)")
+		g.P("	default:")
+		g.P("		return nil")
+		g.P("	}")
+		g.P("}")
+		g.P()
+
+		g.P("const (")
+		g.P("	_ = iota")
+		g.P("	invalidNil")
+		g.P("	invalidUnderflow")
+		g.P("	invalidOverflow")
+		g.P("	invalidNanos")
+		g.P(")")
+		g.P()
+
+		g.P("func (x *Timestamp) check() uint {")
+		g.P("	const minTimestamp = -62135596800  // Seconds between 1970-01-01T00:00:00Z and 0001-01-01T00:00:00Z, inclusive")
+		g.P("	const maxTimestamp = +253402300799 // Seconds between 1970-01-01T00:00:00Z and 9999-12-31T23:59:59Z, inclusive")
+		g.P("	secs := x.GetSeconds()")
+		g.P("	nanos := x.GetNanos()")
+		g.P("	switch {")
+		g.P("	case x == nil:")
+		g.P("		return invalidNil")
+		g.P("	case secs < minTimestamp:")
+		g.P("		return invalidUnderflow")
+		g.P("	case secs > maxTimestamp:")
+		g.P("		return invalidOverflow")
+		g.P("	case nanos < 0 || nanos >= 1e9:")
+		g.P("		return invalidNanos")
+		g.P("	default:")
+		g.P("		return 0")
+		g.P("	}")
+		g.P("}")
+		g.P()
+
+	case genid.Duration_message_fullname:
+		g.P("// New constructs a new Duration from the provided time.Duration.")
+		g.P("func New(d ", timePackage.Ident("Duration"), ") *Duration {")
+		g.P("	nanos := d.Nanoseconds()")
+		g.P("	secs := nanos / 1e9")
+		g.P("	nanos -= secs * 1e9")
+		g.P("	return &Duration{Seconds: int64(secs), Nanos: int32(nanos)}")
+		g.P("}")
+		g.P()
+
+		g.P("// AsDuration converts x to a time.Duration,")
+		g.P("// returning the closest duration value in the event of overflow.")
+		g.P("func (x *Duration) AsDuration() ", timePackage.Ident("Duration"), " {")
+		g.P("	secs := x.GetSeconds()")
+		g.P("	nanos := x.GetNanos()")
+		g.P("	d := ", timePackage.Ident("Duration"), "(secs) * ", timePackage.Ident("Second"))
+		g.P("	overflow := d/", timePackage.Ident("Second"), " != ", timePackage.Ident("Duration"), "(secs)")
+		g.P("	d += ", timePackage.Ident("Duration"), "(nanos) * ", timePackage.Ident("Nanosecond"))
+		g.P("	overflow = overflow || (secs < 0 && nanos < 0 && d > 0)")
+		g.P("	overflow = overflow || (secs > 0 && nanos > 0 && d < 0)")
+		g.P("	if overflow {")
+		g.P("		switch {")
+		g.P("		case secs < 0:")
+		g.P("			return ", timePackage.Ident("Duration"), "(", mathPackage.Ident("MinInt64"), ")")
+		g.P("		case secs > 0:")
+		g.P("			return ", timePackage.Ident("Duration"), "(", mathPackage.Ident("MaxInt64"), ")")
+		g.P("		}")
+		g.P("	}")
+		g.P("	return d")
+		g.P("}")
+		g.P()
+
+		g.P("// IsValid reports whether the duration is valid.")
+		g.P("// It is equivalent to CheckValid == nil.")
+		g.P("func (x *Duration) IsValid() bool {")
+		g.P("	return x.check() == 0")
+		g.P("}")
+		g.P()
+
+		g.P("// CheckValid returns an error if the duration is invalid.")
+		g.P("// In particular, it checks whether the value is within the range of")
+		g.P("// -10000 years to +10000 years inclusive.")
+		g.P("// An error is reported for a nil Duration.")
+		g.P("func (x *Duration) CheckValid() error {")
+		g.P("	switch x.check() {")
+		g.P("	case invalidNil:")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"invalid nil Duration\")")
+		g.P("	case invalidUnderflow:")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"duration (%v) exceeds -10000 years\", x)")
+		g.P("	case invalidOverflow:")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"duration (%v) exceeds +10000 years\", x)")
+		g.P("	case invalidNanosRange:")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"duration (%v) has out-of-range nanos\", x)")
+		g.P("	case invalidNanosSign:")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"duration (%v) has seconds and nanos with different signs\", x)")
+		g.P("	default:")
+		g.P("		return nil")
+		g.P("	}")
+		g.P("}")
+		g.P()
+
+		g.P("const (")
+		g.P("	_ = iota")
+		g.P("	invalidNil")
+		g.P("	invalidUnderflow")
+		g.P("	invalidOverflow")
+		g.P("	invalidNanosRange")
+		g.P("	invalidNanosSign")
+		g.P(")")
+		g.P()
+
+		g.P("func (x *Duration) check() uint {")
+		g.P("	const absDuration = 315576000000 // 10000yr * 365.25day/yr * 24hr/day * 60min/hr * 60sec/min")
+		g.P("	secs := x.GetSeconds()")
+		g.P("	nanos := x.GetNanos()")
+		g.P("	switch {")
+		g.P("	case x == nil:")
+		g.P("		return invalidNil")
+		g.P("	case secs < -absDuration:")
+		g.P("		return invalidUnderflow")
+		g.P("	case secs > +absDuration:")
+		g.P("		return invalidOverflow")
+		g.P("	case nanos <= -1e9 || nanos >= +1e9:")
+		g.P("		return invalidNanosRange")
+		g.P("	case (secs > 0 && nanos < 0) || (secs < 0 && nanos > 0):")
+		g.P("		return invalidNanosSign")
+		g.P("	default:")
+		g.P("		return 0")
+		g.P("	}")
+		g.P("}")
+		g.P()
+
+	case genid.Struct_message_fullname:
+		g.P("// NewStruct constructs a Struct from a general-purpose Go map.")
+		g.P("// The map keys must be valid UTF-8.")
+		g.P("// The map values are converted using NewValue.")
+		g.P("func NewStruct(v map[string]interface{}) (*Struct, error) {")
+		g.P("	x := &Struct{Fields: make(map[string]*Value, len(v))}")
+		g.P("	for k, v := range v {")
+		g.P("		if !", utf8Package.Ident("ValidString"), "(k) {")
+		g.P("			return nil, ", protoimplPackage.Ident("X"), ".NewError(\"invalid UTF-8 in string: %q\", k)")
+		g.P("		}")
+		g.P("		var err error")
+		g.P("		x.Fields[k], err = NewValue(v)")
+		g.P("		if err != nil {")
+		g.P("			return nil, err")
+		g.P("		}")
+		g.P("	}")
+		g.P("	return x, nil")
+		g.P("}")
+		g.P()
+
+		g.P("// AsMap converts x to a general-purpose Go map.")
+		g.P("// The map values are converted by calling Value.AsInterface.")
+		g.P("func (x *Struct) AsMap() map[string]interface{} {")
+		g.P("	vs := make(map[string]interface{})")
+		g.P("	for k, v := range x.GetFields() {")
+		g.P("		vs[k] = v.AsInterface()")
+		g.P("	}")
+		g.P("	return vs")
+		g.P("}")
+		g.P()
+
+		g.P("func (x *Struct) MarshalJSON() ([]byte, error) {")
+		g.P("	return ", protojsonPackage.Ident("Marshal"), "(x)")
+		g.P("}")
+		g.P()
+
+		g.P("func (x *Struct) UnmarshalJSON(b []byte) error {")
+		g.P("	return ", protojsonPackage.Ident("Unmarshal"), "(b, x)")
+		g.P("}")
+		g.P()
+
+	case genid.ListValue_message_fullname:
+		g.P("// NewList constructs a ListValue from a general-purpose Go slice.")
+		g.P("// The slice elements are converted using NewValue.")
+		g.P("func NewList(v []interface{}) (*ListValue, error) {")
+		g.P("	x := &ListValue{Values: make([]*Value, len(v))}")
+		g.P("	for i, v := range v {")
+		g.P("		var err error")
+		g.P("		x.Values[i], err = NewValue(v)")
+		g.P("		if err != nil {")
+		g.P("			return nil, err")
+		g.P("		}")
+		g.P("	}")
+		g.P("	return x, nil")
+		g.P("}")
+		g.P()
+
+		g.P("// AsSlice converts x to a general-purpose Go slice.")
+		g.P("// The slice elements are converted by calling Value.AsInterface.")
+		g.P("func (x *ListValue) AsSlice() []interface{} {")
+		g.P("	vs := make([]interface{}, len(x.GetValues()))")
+		g.P("	for i, v := range x.GetValues() {")
+		g.P("		vs[i] = v.AsInterface()")
+		g.P("	}")
+		g.P("	return vs")
+		g.P("}")
+		g.P()
+
+		g.P("func (x *ListValue) MarshalJSON() ([]byte, error) {")
+		g.P("	return ", protojsonPackage.Ident("Marshal"), "(x)")
+		g.P("}")
+		g.P()
+
+		g.P("func (x *ListValue) UnmarshalJSON(b []byte) error {")
+		g.P("	return ", protojsonPackage.Ident("Unmarshal"), "(b, x)")
+		g.P("}")
+		g.P()
+
+	case genid.Value_message_fullname:
+		g.P("// NewValue constructs a Value from a general-purpose Go interface.")
+		g.P("//")
+		g.P("//	╔════════════════════════╤════════════════════════════════════════════╗")
+		g.P("//	║ Go type                │ Conversion                                 ║")
+		g.P("//	╠════════════════════════╪════════════════════════════════════════════╣")
+		g.P("//	║ nil                    │ stored as NullValue                        ║")
+		g.P("//	║ bool                   │ stored as BoolValue                        ║")
+		g.P("//	║ int, int32, int64      │ stored as NumberValue                      ║")
+		g.P("//	║ uint, uint32, uint64   │ stored as NumberValue                      ║")
+		g.P("//	║ float32, float64       │ stored as NumberValue                      ║")
+		g.P("//	║ string                 │ stored as StringValue; must be valid UTF-8 ║")
+		g.P("//	║ []byte                 │ stored as StringValue; base64-encoded      ║")
+		g.P("//	║ map[string]interface{} │ stored as StructValue                      ║")
+		g.P("//	║ []interface{}          │ stored as ListValue                        ║")
+		g.P("//	╚════════════════════════╧════════════════════════════════════════════╝")
+		g.P("//")
+		g.P("// When converting an int64 or uint64 to a NumberValue, numeric precision loss")
+		g.P("// is possible since they are stored as a float64.")
+		g.P("func NewValue(v interface{}) (*Value, error) {")
+		g.P("	switch v := v.(type) {")
+		g.P("	case nil:")
+		g.P("		return NewNullValue(), nil")
+		g.P("	case bool:")
+		g.P("		return NewBoolValue(v), nil")
+		g.P("	case int:")
+		g.P("		return NewNumberValue(float64(v)), nil")
+		g.P("	case int32:")
+		g.P("		return NewNumberValue(float64(v)), nil")
+		g.P("	case int64:")
+		g.P("		return NewNumberValue(float64(v)), nil")
+		g.P("	case uint:")
+		g.P("		return NewNumberValue(float64(v)), nil")
+		g.P("	case uint32:")
+		g.P("		return NewNumberValue(float64(v)), nil")
+		g.P("	case uint64:")
+		g.P("		return NewNumberValue(float64(v)), nil")
+		g.P("	case float32:")
+		g.P("		return NewNumberValue(float64(v)), nil")
+		g.P("	case float64:")
+		g.P("		return NewNumberValue(float64(v)), nil")
+		g.P("	case string:")
+		g.P("		if !", utf8Package.Ident("ValidString"), "(v) {")
+		g.P("			return nil, ", protoimplPackage.Ident("X"), ".NewError(\"invalid UTF-8 in string: %q\", v)")
+		g.P("		}")
+		g.P("		return NewStringValue(v), nil")
+		g.P("	case []byte:")
+		g.P("		s := ", base64Package.Ident("StdEncoding"), ".EncodeToString(v)")
+		g.P("		return NewStringValue(s), nil")
+		g.P("	case map[string]interface{}:")
+		g.P("		v2, err := NewStruct(v)")
+		g.P("		if err != nil {")
+		g.P("			return nil, err")
+		g.P("		}")
+		g.P("		return NewStructValue(v2), nil")
+		g.P("	case []interface{}:")
+		g.P("		v2, err := NewList(v)")
+		g.P("		if err != nil {")
+		g.P("			return nil, err")
+		g.P("		}")
+		g.P("		return NewListValue(v2), nil")
+		g.P("	default:")
+		g.P("		return nil, ", protoimplPackage.Ident("X"), ".NewError(\"invalid type: %T\", v)")
+		g.P("	}")
+		g.P("}")
+		g.P()
+
+		g.P("// NewNullValue constructs a new null Value.")
+		g.P("func NewNullValue() *Value {")
+		g.P("	return &Value{Kind: &Value_NullValue{NullValue: NullValue_NULL_VALUE}}")
+		g.P("}")
+		g.P()
+
+		g.P("// NewBoolValue constructs a new boolean Value.")
+		g.P("func NewBoolValue(v bool) *Value {")
+		g.P("	return &Value{Kind: &Value_BoolValue{BoolValue: v}}")
+		g.P("}")
+		g.P()
+
+		g.P("// NewNumberValue constructs a new number Value.")
+		g.P("func NewNumberValue(v float64) *Value {")
+		g.P("	return &Value{Kind: &Value_NumberValue{NumberValue: v}}")
+		g.P("}")
+		g.P()
+
+		g.P("// NewStringValue constructs a new string Value.")
+		g.P("func NewStringValue(v string) *Value {")
+		g.P("	return &Value{Kind: &Value_StringValue{StringValue: v}}")
+		g.P("}")
+		g.P()
+
+		g.P("// NewStructValue constructs a new struct Value.")
+		g.P("func NewStructValue(v *Struct) *Value {")
+		g.P("	return &Value{Kind: &Value_StructValue{StructValue: v}}")
+		g.P("}")
+		g.P()
+
+		g.P("// NewListValue constructs a new list Value.")
+		g.P("func NewListValue(v *ListValue) *Value {")
+		g.P("	return &Value{Kind: &Value_ListValue{ListValue: v}}")
+		g.P("}")
+		g.P()
+
+		g.P("// AsInterface converts x to a general-purpose Go interface.")
+		g.P("//")
+		g.P("// Calling Value.MarshalJSON and \"encoding/json\".Marshal on this output produce")
+		g.P("// semantically equivalent JSON (assuming no errors occur).")
+		g.P("//")
+		g.P("// Floating-point values (i.e., \"NaN\", \"Infinity\", and \"-Infinity\") are")
+		g.P("// converted as strings to remain compatible with MarshalJSON.")
+		g.P("func (x *Value) AsInterface() interface{} {")
+		g.P("	switch v := x.GetKind().(type) {")
+		g.P("	case *Value_NumberValue:")
+		g.P("		if v != nil {")
+		g.P("			switch {")
+		g.P("			case ", mathPackage.Ident("IsNaN"), "(v.NumberValue):")
+		g.P("				return \"NaN\"")
+		g.P("			case ", mathPackage.Ident("IsInf"), "(v.NumberValue, +1):")
+		g.P("				return \"Infinity\"")
+		g.P("			case ", mathPackage.Ident("IsInf"), "(v.NumberValue, -1):")
+		g.P("				return \"-Infinity\"")
+		g.P("			default:")
+		g.P("				return v.NumberValue")
+		g.P("			}")
+		g.P("		}")
+		g.P("	case *Value_StringValue:")
+		g.P("		if v != nil {")
+		g.P("			return v.StringValue")
+		g.P("		}")
+		g.P("	case *Value_BoolValue:")
+		g.P("		if v != nil {")
+		g.P("			return v.BoolValue")
+		g.P("		}")
+		g.P("	case *Value_StructValue:")
+		g.P("		if v != nil {")
+		g.P("			return v.StructValue.AsMap()")
+		g.P("		}")
+		g.P("	case *Value_ListValue:")
+		g.P("		if v != nil {")
+		g.P("			return v.ListValue.AsSlice()")
+		g.P("		}")
+		g.P("	}")
+		g.P("	return nil")
+		g.P("}")
+		g.P()
+
+		g.P("func (x *Value) MarshalJSON() ([]byte, error) {")
+		g.P("	return ", protojsonPackage.Ident("Marshal"), "(x)")
+		g.P("}")
+		g.P()
+
+		g.P("func (x *Value) UnmarshalJSON(b []byte) error {")
+		g.P("	return ", protojsonPackage.Ident("Unmarshal"), "(b, x)")
+		g.P("}")
+		g.P()
+
+	case genid.FieldMask_message_fullname:
+		g.P("// New constructs a field mask from a list of paths and verifies that")
+		g.P("// each one is valid according to the specified message type.")
+		g.P("func New(m ", protoPackage.Ident("Message"), ", paths ...string) (*FieldMask, error) {")
+		g.P("	x := new(FieldMask)")
+		g.P("	return x, x.Append(m, paths...)")
+		g.P("}")
+		g.P()
+
+		g.P("// Union returns the union of all the paths in the input field masks.")
+		g.P("func Union(mx *FieldMask, my *FieldMask, ms ...*FieldMask) *FieldMask {")
+		g.P("	var out []string")
+		g.P("	out = append(out, mx.GetPaths()...)")
+		g.P("	out = append(out, my.GetPaths()...)")
+		g.P("	for _, m := range ms {")
+		g.P("		out = append(out, m.GetPaths()...)")
+		g.P("	}")
+		g.P("	return &FieldMask{Paths: normalizePaths(out)}")
+		g.P("}")
+		g.P()
+
+		g.P("// Intersect returns the intersection of all the paths in the input field masks.")
+		g.P("func Intersect(mx *FieldMask, my *FieldMask, ms ...*FieldMask) *FieldMask {")
+		g.P("	var ss1, ss2 []string // reused buffers for performance")
+		g.P("	intersect := func(out, in []string) []string {")
+		g.P("		ss1 = normalizePaths(append(ss1[:0], in...))")
+		g.P("		ss2 = normalizePaths(append(ss2[:0], out...))")
+		g.P("		out = out[:0]")
+		g.P("		for i1, i2 := 0, 0; i1 < len(ss1) && i2 < len(ss2); {")
+		g.P("			switch s1, s2 := ss1[i1], ss2[i2]; {")
+		g.P("			case hasPathPrefix(s1, s2):")
+		g.P("				out = append(out, s1)")
+		g.P("				i1++")
+		g.P("			case hasPathPrefix(s2, s1):")
+		g.P("				out = append(out, s2)")
+		g.P("				i2++")
+		g.P("			case lessPath(s1, s2):")
+		g.P("				i1++")
+		g.P("			case lessPath(s2, s1):")
+		g.P("				i2++")
+		g.P("			}")
+		g.P("		}")
+		g.P("		return out")
+		g.P("	}")
+		g.P()
+		g.P("	out := Union(mx, my, ms...).GetPaths()")
+		g.P("	out = intersect(out, mx.GetPaths())")
+		g.P("	out = intersect(out, my.GetPaths())")
+		g.P("	for _, m := range ms {")
+		g.P("		out = intersect(out, m.GetPaths())")
+		g.P("	}")
+		g.P("	return &FieldMask{Paths: normalizePaths(out)}")
+		g.P("}")
+		g.P()
+
+		g.P("// IsValid reports whether all the paths are syntactically valid and")
+		g.P("// refer to known fields in the specified message type.")
+		g.P("// It reports false for a nil FieldMask.")
+		g.P("func (x *FieldMask) IsValid(m ", protoPackage.Ident("Message"), ") bool {")
+		g.P("	paths := x.GetPaths()")
+		g.P("	return x != nil && numValidPaths(m, paths) == len(paths)")
+		g.P("}")
+		g.P()
+
+		g.P("// Append appends a list of paths to the mask and verifies that each one")
+		g.P("// is valid according to the specified message type.")
+		g.P("// An invalid path is not appended and breaks insertion of subsequent paths.")
+		g.P("func (x *FieldMask) Append(m ", protoPackage.Ident("Message"), ", paths ...string) error {")
+		g.P("	numValid := numValidPaths(m, paths)")
+		g.P("	x.Paths = append(x.Paths, paths[:numValid]...)")
+		g.P("	paths = paths[numValid:]")
+		g.P("	if len(paths) > 0 {")
+		g.P("		name := m.ProtoReflect().Descriptor().FullName()")
+		g.P("		return ", protoimplPackage.Ident("X"), ".NewError(\"invalid path %q for message %q\", paths[0], name)")
+		g.P("	}")
+		g.P("	return nil")
+		g.P("}")
+		g.P()
+
+		g.P("func numValidPaths(m ", protoPackage.Ident("Message"), ", paths []string) int {")
+		g.P("	md0 := m.ProtoReflect().Descriptor()")
+		g.P("	for i, path := range paths {")
+		g.P("		md := md0")
+		g.P("		if !rangeFields(path, func(field string) bool {")
+		g.P("			// Search the field within the message.")
+		g.P("			if md == nil {")
+		g.P("				return false // not within a message")
+		g.P("			}")
+		g.P("			fd := md.Fields().ByName(", protoreflectPackage.Ident("Name"), "(field))")
+		g.P("			// The real field name of a group is the message name.")
+		g.P("			if fd == nil {")
+		g.P("				gd := md.Fields().ByName(", protoreflectPackage.Ident("Name"), "(", stringsPackage.Ident("ToLower"), "(field)))")
+		g.P("				if gd != nil && gd.Kind() == ", protoreflectPackage.Ident("GroupKind"), " && string(gd.Message().Name()) == field {")
+		g.P("					fd = gd")
+		g.P("				}")
+		g.P("			} else if fd.Kind() == ", protoreflectPackage.Ident("GroupKind"), " && string(fd.Message().Name()) != field {")
+		g.P("				fd = nil")
+		g.P("			}")
+		g.P("			if fd == nil {")
+		g.P("				return false // message has does not have this field")
+		g.P("			}")
+		g.P()
+		g.P("			// Identify the next message to search within.")
+		g.P("			md = fd.Message() // may be nil")
+		g.P()
+		g.P("			// Repeated fields are only allowed at the last position.")
+		g.P("			if fd.IsList() || fd.IsMap() {")
+		g.P("				md = nil")
+		g.P("			}")
+		g.P()
+		g.P("			return true")
+		g.P("		}) {")
+		g.P("			return i")
+		g.P("		}")
+		g.P("	}")
+		g.P("	return len(paths)")
+		g.P("}")
+		g.P()
+
+		g.P("// Normalize converts the mask to its canonical form where all paths are sorted")
+		g.P("// and redundant paths are removed.")
+		g.P("func (x *FieldMask) Normalize() {")
+		g.P("	x.Paths = normalizePaths(x.Paths)")
+		g.P("}")
+		g.P()
+		g.P("func normalizePaths(paths []string) []string {")
+		g.P("	", sortPackage.Ident("Slice"), "(paths, func(i, j int) bool {")
+		g.P("		return lessPath(paths[i], paths[j])")
+		g.P("	})")
+		g.P()
+		g.P("	// Elide any path that is a prefix match on the previous.")
+		g.P("	out := paths[:0]")
+		g.P("	for _, path := range paths {")
+		g.P("		if len(out) > 0 && hasPathPrefix(path, out[len(out)-1]) {")
+		g.P("			continue")
+		g.P("		}")
+		g.P("		out = append(out, path)")
+		g.P("	}")
+		g.P("	return out")
+		g.P("}")
+		g.P()
+
+		g.P("// hasPathPrefix is like strings.HasPrefix, but further checks for either")
+		g.P("// an exact matche or that the prefix is delimited by a dot.")
+		g.P("func hasPathPrefix(path, prefix string) bool {")
+		g.P("	return ", stringsPackage.Ident("HasPrefix"), "(path, prefix) && (len(path) == len(prefix) || path[len(prefix)] == '.')")
+		g.P("}")
+		g.P()
+
+		g.P("// lessPath is a lexicographical comparison where dot is specially treated")
+		g.P("// as the smallest symbol.")
+		g.P("func lessPath(x, y string) bool {")
+		g.P("	for i := 0; i < len(x) && i < len(y); i++ {")
+		g.P("		if x[i] != y[i] {")
+		g.P("			return (x[i] - '.') < (y[i] - '.')")
+		g.P("		}")
+		g.P("	}")
+		g.P("	return len(x) < len(y)")
+		g.P("}")
+		g.P()
+
+		g.P("// rangeFields is like strings.Split(path, \".\"), but avoids allocations by")
+		g.P("// iterating over each field in place and calling a iterator function.")
+		g.P("func rangeFields(path string, f func(field string) bool) bool {")
+		g.P("	for {")
+		g.P("		var field string")
+		g.P("		if i := ", stringsPackage.Ident("IndexByte"), "(path, '.'); i >= 0 {")
+		g.P("			field, path = path[:i], path[i:]")
+		g.P("		} else {")
+		g.P("			field, path = path, \"\"")
+		g.P("		}")
+		g.P()
+		g.P("		if !f(field) {")
+		g.P("			return false")
+		g.P("		}")
+		g.P()
+		g.P("		if len(path) == 0 {")
+		g.P("			return true")
+		g.P("		}")
+		g.P("		path = ", stringsPackage.Ident("TrimPrefix"), "(path, \".\")")
+		g.P("	}")
+		g.P("}")
+		g.P()
+
+	case genid.BoolValue_message_fullname,
+		genid.Int32Value_message_fullname,
+		genid.Int64Value_message_fullname,
+		genid.UInt32Value_message_fullname,
+		genid.UInt64Value_message_fullname,
+		genid.FloatValue_message_fullname,
+		genid.DoubleValue_message_fullname,
+		genid.StringValue_message_fullname,
+		genid.BytesValue_message_fullname:
+		funcName := strings.TrimSuffix(m.GoIdent.GoName, "Value")
+		typeName := strings.ToLower(funcName)
+		switch typeName {
+		case "float":
+			typeName = "float32"
+		case "double":
+			typeName = "float64"
+		case "bytes":
+			typeName = "[]byte"
+		}
+
+		g.P("// ", funcName, " stores v in a new ", m.GoIdent, " and returns a pointer to it.")
+		g.P("func ", funcName, "(v ", typeName, ") *", m.GoIdent, " {")
+		g.P("	return &", m.GoIdent, "{Value: v}")
+		g.P("}")
+		g.P()
+	}
+}
diff --git a/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go b/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go
new file mode 100644
index 0000000000000..a475adfdd20b4
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/compiler/protogen/protogen.go
@@ -0,0 +1,1261 @@
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package protogen provides support for writing protoc plugins.
+//
+// Plugins for protoc, the Protocol Buffer compiler,
+// are programs which read a CodeGeneratorRequest message from standard input
+// and write a CodeGeneratorResponse message to standard output.
+// This package provides support for writing plugins which generate Go code.
+package protogen
+
+import (
+	"bufio"
+	"bytes"
+	"fmt"
+	"go/ast"
+	"go/parser"
+	"go/printer"
+	"go/token"
+	"go/types"
+	"io/ioutil"
+	"os"
+	"path"
+	"path/filepath"
+	"sort"
+	"strconv"
+	"strings"
+
+	"google.golang.org/protobuf/encoding/prototext"
+	"google.golang.org/protobuf/internal/genid"
+	"google.golang.org/protobuf/internal/strs"
+	"google.golang.org/protobuf/proto"
+	"google.golang.org/protobuf/reflect/protodesc"
+	"google.golang.org/protobuf/reflect/protoreflect"
+	"google.golang.org/protobuf/reflect/protoregistry"
+
+	"google.golang.org/protobuf/types/descriptorpb"
+	"google.golang.org/protobuf/types/pluginpb"
+)
+
+const goPackageDocURL = "https://developers.google.com/protocol-buffers/docs/reference/go-generated#package"
+
+// Run executes a function as a protoc plugin.
+//
+// It reads a CodeGeneratorRequest message from os.Stdin, invokes the plugin
+// function, and writes a CodeGeneratorResponse message to os.Stdout.
+//
+// If a failure occurs while reading or writing, Run prints an error to
+// os.Stderr and calls os.Exit(1).
+func (opts Options) Run(f func(*Plugin) error) {
+	if err := run(opts, f); err != nil {
+		fmt.Fprintf(os.Stderr, "%s: %v\n", filepath.Base(os.Args[0]), err)
+		os.Exit(1)
+	}
+}
+
+func run(opts Options, f func(*Plugin) error) error {
+	if len(os.Args) > 1 {
+		return fmt.Errorf("unknown argument %q (this program should be run by protoc, not directly)", os.Args[1])
+	}
+	in, err := ioutil.ReadAll(os.Stdin)
+	if err != nil {
+		return err
+	}
+	req := &pluginpb.CodeGeneratorRequest{}
+	if err := proto.Unmarshal(in, req); err != nil {
+		return err
+	}
+	gen, err := opts.New(req)
+	if err != nil {
+		return err
+	}
+	if err := f(gen); err != nil {
+		// Errors from the plugin function are reported by setting the
+		// error field in the CodeGeneratorResponse.
+		//
+		// In contrast, errors that indicate a problem in protoc
+		// itself (unparsable input, I/O errors, etc.) are reported
+		// to stderr.
+		gen.Error(err)
+	}
+	resp := gen.Response()
+	out, err := proto.Marshal(resp)
+	if err != nil {
+		return err
+	}
+	if _, err := os.Stdout.Write(out); err != nil {
+		return err
+	}
+	return nil
+}
+
+// A Plugin is a protoc plugin invocation.
+type Plugin struct {
+	// Request is the CodeGeneratorRequest provided by protoc.
+	Request *pluginpb.CodeGeneratorRequest
+
+	// Files is the set of files to generate and everything they import.
+	// Files appear in topological order, so each file appears before any
+	// file that imports it.
+	Files       []*File
+	FilesByPath map[string]*File
+
+	// SupportedFeatures is the set of protobuf language features supported by
+	// this generator plugin. See the documentation for
+	// google.protobuf.CodeGeneratorResponse.supported_features for details.
+	SupportedFeatures uint64
+
+	fileReg        *protoregistry.Files
+	enumsByName    map[protoreflect.FullName]*Enum
+	messagesByName map[protoreflect.FullName]*Message
+	annotateCode   bool
+	pathType       pathType
+	module         string
+	genFiles       []*GeneratedFile
+	opts           Options
+	err            error
+}
+
+type Options struct {
+	// If ParamFunc is non-nil, it will be called with each unknown
+	// generator parameter.
+	//
+	// Plugins for protoc can accept parameters from the command line,
+	// passed in the --<lang>_out protoc, separated from the output
+	// directory with a colon; e.g.,
+	//
+	//   --go_out=<param1>=<value1>,<param2>=<value2>:<output_directory>
+	//
+	// Parameters passed in this fashion as a comma-separated list of
+	// key=value pairs will be passed to the ParamFunc.
+	//
+	// The (flag.FlagSet).Set method matches this function signature,
+	// so parameters can be converted into flags as in the following:
+	//
+	//   var flags flag.FlagSet
+	//   value := flags.Bool("param", false, "")
+	//   opts := &protogen.Options{
+	//     ParamFunc: flags.Set,
+	//   }
+	//   protogen.Run(opts, func(p *protogen.Plugin) error {
+	//     if *value { ... }
+	//   })
+	ParamFunc func(name, value string) error
+
+	// ImportRewriteFunc is called with the import path of each package
+	// imported by a generated file. It returns the import path to use
+	// for this package.
+	ImportRewriteFunc func(GoImportPath) GoImportPath
+}
+
+// New returns a new Plugin.
+func (opts Options) New(req *pluginpb.CodeGeneratorRequest) (*Plugin, error) {
+	gen := &Plugin{
+		Request:        req,
+		FilesByPath:    make(map[string]*File),
+		fileReg:        new(protoregistry.Files),
+		enumsByName:    make(map[protoreflect.FullName]*Enum),
+		messagesByName: make(map[protoreflect.FullName]*Message),
+		opts:           opts,
+	}
+
+	packageNames := make(map[string]GoPackageName) // filename -> package name
+	importPaths := make(map[string]GoImportPath)   // filename -> import path
+	for _, param := range strings.Split(req.GetParameter(), ",") {
+		var value string
+		if i := strings.Index(param, "="); i >= 0 {
+			value = param[i+1:]
+			param = param[0:i]
+		}
+		switch param {
+		case "":
+			// Ignore.
+		case "module":
+			gen.module = value
+		case "paths":
+			switch value {
+			case "import":
+				gen.pathType = pathTypeImport
+			case "source_relative":
+				gen.pathType = pathTypeSourceRelative
+			default:
+				return nil, fmt.Errorf(`unknown path type %q: want "import" or "source_relative"`, value)
+			}
+		case "annotate_code":
+			switch value {
+			case "true", "":
+				gen.annotateCode = true
+			case "false":
+			default:
+				return nil, fmt.Errorf(`bad value for parameter %q: want "true" or "false"`, param)
+			}
+		default:
+			if param[0] == 'M' {
+				impPath, pkgName := splitImportPathAndPackageName(value)
+				if pkgName != "" {
+					packageNames[param[1:]] = pkgName
+				}
+				if impPath != "" {
+					importPaths[param[1:]] = impPath
+				}
+				continue
+			}
+			if opts.ParamFunc != nil {
+				if err := opts.ParamFunc(param, value); err != nil {
+					return nil, err
+				}
+			}
+		}
+	}
+	// When the module= option is provided, we strip the module name
+	// prefix from generated files. This only makes sense if generated
+	// filenames are based on the import path.
+	if gen.module != "" && gen.pathType == pathTypeSourceRelative {
+		return nil, fmt.Errorf("cannot use module= with paths=source_relative")
+	}
+
+	// Figure out the import path and package name for each file.
+	//
+	// The rules here are complicated and have grown organically over time.
+	// Interactions between different ways of specifying package information
+	// may be surprising.
+	//
+	// The recommended approach is to include a go_package option in every
+	// .proto source file specifying the full import path of the Go package
+	// associated with this file.
+	//
+	//     option go_package = "google.golang.org/protobuf/types/known/anypb";
+	//
+	// Alternatively, build systems which want to exert full control over
+	// import paths may specify M<filename>=<import_path> flags.
+	for _, fdesc := range gen.Request.ProtoFile {
+		// The "M" command-line flags take precedence over
+		// the "go_package" option in the .proto source file.
+		filename := fdesc.GetName()
+		impPath, pkgName := splitImportPathAndPackageName(fdesc.GetOptions().GetGoPackage())
+		if importPaths[filename] == "" && impPath != "" {
+			importPaths[filename] = impPath
+		}
+		if packageNames[filename] == "" && pkgName != "" {
+			packageNames[filename] = pkgName
+		}
+		switch {
+		case importPaths[filename] == "":
+			// The import path must be specified one way or another.
+			return nil, fmt.Errorf(
+				"unable to determine Go import path for %q\n\n"+
+					"Please specify either:\n"+
+					"\t• a \"go_package\" option in the .proto source file, or\n"+
+					"\t• a \"M\" argument on the command line.\n\n"+
+					"See %v for more information.\n",
+				fdesc.GetName(), goPackageDocURL)
+		case !strings.Contains(string(importPaths[filename]), ".") &&
+			!strings.Contains(string(importPaths[filename]), "/"):
+			// Check that import paths contain at least a dot or slash to avoid
+			// a common mistake where import path is confused with package name.
+			return nil, fmt.Errorf(
+				"invalid Go import path %q for %q\n\n"+
+					"The import path must contain at least one period ('.') or forward slash ('/') character.\n\n"+
+					"See %v for more information.\n",
+				string(importPaths[filename]), fdesc.GetName(), goPackageDocURL)
+		case packageNames[filename] == "":
+			// If the package name is not explicitly specified,
+			// then derive a reasonable package name from the import path.
+			//
+			// NOTE: The package name is derived first from the import path in
+			// the "go_package" option (if present) before trying the "M" flag.
+			// The inverted order for this is because the primary use of the "M"
+			// flag is by build systems that have full control over the
+			// import paths all packages, where it is generally expected that
+			// the Go package name still be identical for the Go toolchain and
+			// for custom build systems like Bazel.
+			if impPath == "" {
+				impPath = importPaths[filename]
+			}
+			packageNames[filename] = cleanPackageName(path.Base(string(impPath)))
+		}
+	}
+
+	// Consistency check: Every file with the same Go import path should have
+	// the same Go package name.
+	packageFiles := make(map[GoImportPath][]string)
+	for filename, importPath := range importPaths {
+		if _, ok := packageNames[filename]; !ok {
+			// Skip files mentioned in a M<file>=<import_path> parameter
+			// but which do not appear in the CodeGeneratorRequest.
+			continue
+		}
+		packageFiles[importPath] = append(packageFiles[importPath], filename)
+	}
+	for importPath, filenames := range packageFiles {
+		for i := 1; i < len(filenames); i++ {
+			if a, b := packageNames[filenames[0]], packageNames[filenames[i]]; a != b {
+				return nil, fmt.Errorf("Go package %v has inconsistent names %v (%v) and %v (%v)",
+					importPath, a, filenames[0], b, filenames[i])
+			}
+		}
+	}
+
+	for _, fdesc := range gen.Request.ProtoFile {
+		filename := fdesc.GetName()
+		if gen.FilesByPath[filename] != nil {
+			return nil, fmt.Errorf("duplicate file name: %q", filename)
+		}
+		f, err := newFile(gen, fdesc, packageNames[filename], importPaths[filename])
+		if err != nil {
+			return nil, err
+		}
+		gen.Files = append(gen.Files, f)
+		gen.FilesByPath[filename] = f
+	}
+	for _, filename := range gen.Request.FileToGenerate {
+		f, ok := gen.FilesByPath[filename]
+		if !ok {
+			return nil, fmt.Errorf("no descriptor for generated file: %v", filename)
+		}
+		f.Generate = true
+	}
+	return gen, nil
+}
+
+// Error records an error in code generation. The generator will report the
+// error back to protoc and will not produce output.
+func (gen *Plugin) Error(err error) {
+	if gen.err == nil {
+		gen.err = err
+	}
+}
+
+// Response returns the generator output.
+func (gen *Plugin) Response() *pluginpb.CodeGeneratorResponse {
+	resp := &pluginpb.CodeGeneratorResponse{}
+	if gen.err != nil {
+		resp.Error = proto.String(gen.err.Error())
+		return resp
+	}
+	for _, g := range gen.genFiles {
+		if g.skip {
+			continue
+		}
+		content, err := g.Content()
+		if err != nil {
+			return &pluginpb.CodeGeneratorResponse{
+				Error: proto.String(err.Error()),
+			}
+		}
+		filename := g.filename
+		if gen.module != "" {
+			trim := gen.module + "/"
+			if !strings.HasPrefix(filename, trim) {
+				return &pluginpb.CodeGeneratorResponse{
+					Error: proto.String(fmt.Sprintf("%v: generated file does not match prefix %q", filename, gen.module)),
+				}
+			}
+			filename = strings.TrimPrefix(filename, trim)
+		}
+		resp.File = append(resp.File, &pluginpb.CodeGeneratorResponse_File{
+			Name:    proto.String(filename),
+			Content: proto.String(string(content)),
+		})
+		if gen.annotateCode && strings.HasSuffix(g.filename, ".go") {
+			meta, err := g.metaFile(content)
+			if err != nil {
+				return &pluginpb.CodeGeneratorResponse{
+					Error: proto.String(err.Error()),
+				}
+			}
+			resp.File = append(resp.File, &pluginpb.CodeGeneratorResponse_File{
+				Name:    proto.String(filename + ".meta"),
+				Content: proto.String(meta),
+			})
+		}
+	}
+	if gen.SupportedFeatures > 0 {
+		resp.SupportedFeatures = proto.Uint64(gen.SupportedFeatures)
+	}
+	return resp
+}
+
+// A File describes a .proto source file.
+type File struct {
+	Desc  protoreflect.FileDescriptor
+	Proto *descriptorpb.FileDescriptorProto
+
+	GoDescriptorIdent GoIdent       // name of Go variable for the file descriptor
+	GoPackageName     GoPackageName // name of this file's Go package
+	GoImportPath      GoImportPath  // import path of this file's Go package
+
+	Enums      []*Enum      // top-level enum declarations
+	Messages   []*Message   // top-level message declarations
+	Extensions []*Extension // top-level extension declarations
+	Services   []*Service   // top-level service declarations
+
+	Generate bool // true if we should generate code for this file
+
+	// GeneratedFilenamePrefix is used to construct filenames for generated
+	// files associated with this source file.
+	//
+	// For example, the source file "dir/foo.proto" might have a filename prefix
+	// of "dir/foo". Appending ".pb.go" produces an output file of "dir/foo.pb.go".
+	GeneratedFilenamePrefix string
+
+	location Location
+}
+
+func newFile(gen *Plugin, p *descriptorpb.FileDescriptorProto, packageName GoPackageName, importPath GoImportPath) (*File, error) {
+	desc, err := protodesc.NewFile(p, gen.fileReg)
+	if err != nil {
+		return nil, fmt.Errorf("invalid FileDescriptorProto %q: %v", p.GetName(), err)
+	}
+	if err := gen.fileReg.RegisterFile(desc); err != nil {
+		return nil, fmt.Errorf("cannot register descriptor %q: %v", p.GetName(), err)
+	}
+	f := &File{
+		Desc:          desc,
+		Proto:         p,
+		GoPackageName: packageName,
+		GoImportPath:  importPath,
+		location:      Location{SourceFile: desc.Path()},
+	}
+
+	// Determine the prefix for generated Go files.
+	prefix := p.GetName()
+	if ext := path.Ext(prefix); ext == ".proto" || ext == ".protodevel" {
+		prefix = prefix[:len(prefix)-len(ext)]
+	}
+	switch gen.pathType {
+	case pathTypeImport:
+		// If paths=import, the output filename is derived from the Go import path.
+		prefix = path.Join(string(f.GoImportPath), path.Base(prefix))
+	case pathTypeSourceRelative:
+		// If paths=source_relative, the output filename is derived from
+		// the input filename.
+	}
+	f.GoDescriptorIdent = GoIdent{
+		GoName:       "File_" + strs.GoSanitized(p.GetName()),
+		GoImportPath: f.GoImportPath,
+	}
+	f.GeneratedFilenamePrefix = prefix
+
+	for i, eds := 0, desc.Enums(); i < eds.Len(); i++ {
+		f.Enums = append(f.Enums, newEnum(gen, f, nil, eds.Get(i)))
+	}
+	for i, mds := 0, desc.Messages(); i < mds.Len(); i++ {
+		f.Messages = append(f.Messages, newMessage(gen, f, nil, mds.Get(i)))
+	}
+	for i, xds := 0, desc.Extensions(); i < xds.Len(); i++ {
+		f.Extensions = append(f.Extensions, newField(gen, f, nil, xds.Get(i)))
+	}
+	for i, sds := 0, desc.Services(); i < sds.Len(); i++ {
+		f.Services = append(f.Services, newService(gen, f, sds.Get(i)))
+	}
+	for _, message := range f.Messages {
+		if err := message.resolveDependencies(gen); err != nil {
+			return nil, err
+		}
+	}
+	for _, extension := range f.Extensions {
+		if err := extension.resolveDependencies(gen); err != nil {
+			return nil, err
+		}
+	}
+	for _, service := range f.Services {
+		for _, method := range service.Methods {
+			if err := method.resolveDependencies(gen); err != nil {
+				return nil, err
+			}
+		}
+	}
+	return f, nil
+}
+
+// splitImportPathAndPackageName splits off the optional Go package name
+// from the Go import path when separated by a ';' delimiter.
+func splitImportPathAndPackageName(s string) (GoImportPath, GoPackageName) {
+	if i := strings.Index(s, ";"); i >= 0 {
+		return GoImportPath(s[:i]), GoPackageName(s[i+1:])
+	}
+	return GoImportPath(s), ""
+}
+
+// An Enum describes an enum.
+type Enum struct {
+	Desc protoreflect.EnumDescriptor
+
+	GoIdent GoIdent // name of the generated Go type
+
+	Values []*EnumValue // enum value declarations
+
+	Location Location   // location of this enum
+	Comments CommentSet // comments associated with this enum
+}
+
+func newEnum(gen *Plugin, f *File, parent *Message, desc protoreflect.EnumDescriptor) *Enum {
+	var loc Location
+	if parent != nil {
+		loc = parent.Location.appendPath(genid.DescriptorProto_EnumType_field_number, desc.Index())
+	} else {
+		loc = f.location.appendPath(genid.FileDescriptorProto_EnumType_field_number, desc.Index())
+	}
+	enum := &Enum{
+		Desc:     desc,
+		GoIdent:  newGoIdent(f, desc),
+		Location: loc,
+		Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
+	}
+	gen.enumsByName[desc.FullName()] = enum
+	for i, vds := 0, enum.Desc.Values(); i < vds.Len(); i++ {
+		enum.Values = append(enum.Values, newEnumValue(gen, f, parent, enum, vds.Get(i)))
+	}
+	return enum
+}
+
+// An EnumValue describes an enum value.
+type EnumValue struct {
+	Desc protoreflect.EnumValueDescriptor
+
+	GoIdent GoIdent // name of the generated Go declaration
+
+	Parent *Enum // enum in which this value is declared
+
+	Location Location   // location of this enum value
+	Comments CommentSet // comments associated with this enum value
+}
+
+func newEnumValue(gen *Plugin, f *File, message *Message, enum *Enum, desc protoreflect.EnumValueDescriptor) *EnumValue {
+	// A top-level enum value's name is: EnumName_ValueName
+	// An enum value contained in a message is: MessageName_ValueName
+	//
+	// For historical reasons, enum value names are not camel-cased.
+	parentIdent := enum.GoIdent
+	if message != nil {
+		parentIdent = message.GoIdent
+	}
+	name := parentIdent.GoName + "_" + string(desc.Name())
+	loc := enum.Location.appendPath(genid.EnumDescriptorProto_Value_field_number, desc.Index())
+	return &EnumValue{
+		Desc:     desc,
+		GoIdent:  f.GoImportPath.Ident(name),
+		Parent:   enum,
+		Location: loc,
+		Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
+	}
+}
+
+// A Message describes a message.
+type Message struct {
+	Desc protoreflect.MessageDescriptor
+
+	GoIdent GoIdent // name of the generated Go type
+
+	Fields []*Field // message field declarations
+	Oneofs []*Oneof // message oneof declarations
+
+	Enums      []*Enum      // nested enum declarations
+	Messages   []*Message   // nested message declarations
+	Extensions []*Extension // nested extension declarations
+
+	Location Location   // location of this message
+	Comments CommentSet // comments associated with this message
+}
+
+func newMessage(gen *Plugin, f *File, parent *Message, desc protoreflect.MessageDescriptor) *Message {
+	var loc Location
+	if parent != nil {
+		loc = parent.Location.appendPath(genid.DescriptorProto_NestedType_field_number, desc.Index())
+	} else {
+		loc = f.location.appendPath(genid.FileDescriptorProto_MessageType_field_number, desc.Index())
+	}
+	message := &Message{
+		Desc:     desc,
+		GoIdent:  newGoIdent(f, desc),
+		Location: loc,
+		Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
+	}
+	gen.messagesByName[desc.FullName()] = message
+	for i, eds := 0, desc.Enums(); i < eds.Len(); i++ {
+		message.Enums = append(message.Enums, newEnum(gen, f, message, eds.Get(i)))
+	}
+	for i, mds := 0, desc.Messages(); i < mds.Len(); i++ {
+		message.Messages = append(message.Messages, newMessage(gen, f, message, mds.Get(i)))
+	}
+	for i, fds := 0, desc.Fields(); i < fds.Len(); i++ {
+		message.Fields = append(message.Fields, newField(gen, f, message, fds.Get(i)))
+	}
+	for i, ods := 0, desc.Oneofs(); i < ods.Len(); i++ {
+		message.Oneofs = append(message.Oneofs, newOneof(gen, f, message, ods.Get(i)))
+	}
+	for i, xds := 0, desc.Extensions(); i < xds.Len(); i++ {
+		message.Extensions = append(message.Extensions, newField(gen, f, message, xds.Get(i)))
+	}
+
+	// Resolve local references between fields and oneofs.
+	for _, field := range message.Fields {
+		if od := field.Desc.ContainingOneof(); od != nil {
+			oneof := message.Oneofs[od.Index()]
+			field.Oneof = oneof
+			oneof.Fields = append(oneof.Fields, field)
+		}
+	}
+
+	// Field name conflict resolution.
+	//
+	// We assume well-known method names that may be attached to a generated
+	// message type, as well as a 'Get*' method for each field. For each
+	// field in turn, we add _s to its name until there are no conflicts.
+	//
+	// Any change to the following set of method names is a potential
+	// incompatible API change because it may change generated field names.
+	//
+	// TODO: If we ever support a 'go_name' option to set the Go name of a
+	// field, we should consider dropping this entirely. The conflict
+	// resolution algorithm is subtle and surprising (changing the order
+	// in which fields appear in the .proto source file can change the
+	// names of fields in generated code), and does not adapt well to
+	// adding new per-field methods such as setters.
+	usedNames := map[string]bool{
+		"Reset":               true,
+		"String":              true,
+		"ProtoMessage":        true,
+		"Marshal":             true,
+		"Unmarshal":           true,
+		"ExtensionRangeArray": true,
+		"ExtensionMap":        true,
+		"Descriptor":          true,
+	}
+	makeNameUnique := func(name string, hasGetter bool) string {
+		for usedNames[name] || (hasGetter && usedNames["Get"+name]) {
+			name += "_"
+		}
+		usedNames[name] = true
+		usedNames["Get"+name] = hasGetter
+		return name
+	}
+	for _, field := range message.Fields {
+		field.GoName = makeNameUnique(field.GoName, true)
+		field.GoIdent.GoName = message.GoIdent.GoName + "_" + field.GoName
+		if field.Oneof != nil && field.Oneof.Fields[0] == field {
+			// Make the name for a oneof unique as well. For historical reasons,
+			// this assumes that a getter method is not generated for oneofs.
+			// This is incorrect, but fixing it breaks existing code.
+			field.Oneof.GoName = makeNameUnique(field.Oneof.GoName, false)
+			field.Oneof.GoIdent.GoName = message.GoIdent.GoName + "_" + field.Oneof.GoName
+		}
+	}
+
+	// Oneof field name conflict resolution.
+	//
+	// This conflict resolution is incomplete as it does not consider collisions
+	// with other oneof field types, but fixing it breaks existing code.
+	for _, field := range message.Fields {
+		if field.Oneof != nil {
+		Loop:
+			for {
+				for _, nestedMessage := range message.Messages {
+					if nestedMessage.GoIdent == field.GoIdent {
+						field.GoIdent.GoName += "_"
+						continue Loop
+					}
+				}
+				for _, nestedEnum := range message.Enums {
+					if nestedEnum.GoIdent == field.GoIdent {
+						field.GoIdent.GoName += "_"
+						continue Loop
+					}
+				}
+				break Loop
+			}
+		}
+	}
+
+	return message
+}
+
+func (message *Message) resolveDependencies(gen *Plugin) error {
+	for _, field := range message.Fields {
+		if err := field.resolveDependencies(gen); err != nil {
+			return err
+		}
+	}
+	for _, message := range message.Messages {
+		if err := message.resolveDependencies(gen); err != nil {
+			return err
+		}
+	}
+	for _, extension := range message.Extensions {
+		if err := extension.resolveDependencies(gen); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+// A Field describes a message field.
+type Field struct {
+	Desc protoreflect.FieldDescriptor
+
+	// GoName is the base name of this field's Go field and methods.
+	// For code generated by protoc-gen-go, this means a field named
+	// '{{GoName}}' and a getter method named 'Get{{GoName}}'.
+	GoName string // e.g., "FieldName"
+
+	// GoIdent is the base name of a top-level declaration for this field.
+	// For code generated by protoc-gen-go, this means a wrapper type named
+	// '{{GoIdent}}' for members fields of a oneof, and a variable named
+	// 'E_{{GoIdent}}' for extension fields.
+	GoIdent GoIdent // e.g., "MessageName_FieldName"
+
+	Parent   *Message // message in which this field is declared; nil if top-level extension
+	Oneof    *Oneof   // containing oneof; nil if not part of a oneof
+	Extendee *Message // extended message for extension fields; nil otherwise
+
+	Enum    *Enum    // type for enum fields; nil otherwise
+	Message *Message // type for message or group fields; nil otherwise
+
+	Location Location   // location of this field
+	Comments CommentSet // comments associated with this field
+}
+
+func newField(gen *Plugin, f *File, message *Message, desc protoreflect.FieldDescriptor) *Field {
+	var loc Location
+	switch {
+	case desc.IsExtension() && message == nil:
+		loc = f.location.appendPath(genid.FileDescriptorProto_Extension_field_number, desc.Index())
+	case desc.IsExtension() && message != nil:
+		loc = message.Location.appendPath(genid.DescriptorProto_Extension_field_number, desc.Index())
+	default:
+		loc = message.Location.appendPath(genid.DescriptorProto_Field_field_number, desc.Index())
+	}
+	camelCased := strs.GoCamelCase(string(desc.Name()))
+	var parentPrefix string
+	if message != nil {
+		parentPrefix = message.GoIdent.GoName + "_"
+	}
+	field := &Field{
+		Desc:   desc,
+		GoName: camelCased,
+		GoIdent: GoIdent{
+			GoImportPath: f.GoImportPath,
+			GoName:       parentPrefix + camelCased,
+		},
+		Parent:   message,
+		Location: loc,
+		Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
+	}
+	return field
+}
+
+func (field *Field) resolveDependencies(gen *Plugin) error {
+	desc := field.Desc
+	switch desc.Kind() {
+	case protoreflect.EnumKind:
+		name := field.Desc.Enum().FullName()
+		enum, ok := gen.enumsByName[name]
+		if !ok {
+			return fmt.Errorf("field %v: no descriptor for enum %v", desc.FullName(), name)
+		}
+		field.Enum = enum
+	case protoreflect.MessageKind, protoreflect.GroupKind:
+		name := desc.Message().FullName()
+		message, ok := gen.messagesByName[name]
+		if !ok {
+			return fmt.Errorf("field %v: no descriptor for type %v", desc.FullName(), name)
+		}
+		field.Message = message
+	}
+	if desc.IsExtension() {
+		name := desc.ContainingMessage().FullName()
+		message, ok := gen.messagesByName[name]
+		if !ok {
+			return fmt.Errorf("field %v: no descriptor for type %v", desc.FullName(), name)
+		}
+		field.Extendee = message
+	}
+	return nil
+}
+
+// A Oneof describes a message oneof.
+type Oneof struct {
+	Desc protoreflect.OneofDescriptor
+
+	// GoName is the base name of this oneof's Go field and methods.
+	// For code generated by protoc-gen-go, this means a field named
+	// '{{GoName}}' and a getter method named 'Get{{GoName}}'.
+	GoName string // e.g., "OneofName"
+
+	// GoIdent is the base name of a top-level declaration for this oneof.
+	GoIdent GoIdent // e.g., "MessageName_OneofName"
+
+	Parent *Message // message in which this oneof is declared
+
+	Fields []*Field // fields that are part of this oneof
+
+	Location Location   // location of this oneof
+	Comments CommentSet // comments associated with this oneof
+}
+
+func newOneof(gen *Plugin, f *File, message *Message, desc protoreflect.OneofDescriptor) *Oneof {
+	loc := message.Location.appendPath(genid.DescriptorProto_OneofDecl_field_number, desc.Index())
+	camelCased := strs.GoCamelCase(string(desc.Name()))
+	parentPrefix := message.GoIdent.GoName + "_"
+	return &Oneof{
+		Desc:   desc,
+		Parent: message,
+		GoName: camelCased,
+		GoIdent: GoIdent{
+			GoImportPath: f.GoImportPath,
+			GoName:       parentPrefix + camelCased,
+		},
+		Location: loc,
+		Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
+	}
+}
+
+// Extension is an alias of Field for documentation.
+type Extension = Field
+
+// A Service describes a service.
+type Service struct {
+	Desc protoreflect.ServiceDescriptor
+
+	GoName string
+
+	Methods []*Method // service method declarations
+
+	Location Location   // location of this service
+	Comments CommentSet // comments associated with this service
+}
+
+func newService(gen *Plugin, f *File, desc protoreflect.ServiceDescriptor) *Service {
+	loc := f.location.appendPath(genid.FileDescriptorProto_Service_field_number, desc.Index())
+	service := &Service{
+		Desc:     desc,
+		GoName:   strs.GoCamelCase(string(desc.Name())),
+		Location: loc,
+		Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
+	}
+	for i, mds := 0, desc.Methods(); i < mds.Len(); i++ {
+		service.Methods = append(service.Methods, newMethod(gen, f, service, mds.Get(i)))
+	}
+	return service
+}
+
+// A Method describes a method in a service.
+type Method struct {
+	Desc protoreflect.MethodDescriptor
+
+	GoName string
+
+	Parent *Service // service in which this method is declared
+
+	Input  *Message
+	Output *Message
+
+	Location Location   // location of this method
+	Comments CommentSet // comments associated with this method
+}
+
+func newMethod(gen *Plugin, f *File, service *Service, desc protoreflect.MethodDescriptor) *Method {
+	loc := service.Location.appendPath(genid.ServiceDescriptorProto_Method_field_number, desc.Index())
+	method := &Method{
+		Desc:     desc,
+		GoName:   strs.GoCamelCase(string(desc.Name())),
+		Parent:   service,
+		Location: loc,
+		Comments: makeCommentSet(f.Desc.SourceLocations().ByDescriptor(desc)),
+	}
+	return method
+}
+
+func (method *Method) resolveDependencies(gen *Plugin) error {
+	desc := method.Desc
+
+	inName := desc.Input().FullName()
+	in, ok := gen.messagesByName[inName]
+	if !ok {
+		return fmt.Errorf("method %v: no descriptor for type %v", desc.FullName(), inName)
+	}
+	method.Input = in
+
+	outName := desc.Output().FullName()
+	out, ok := gen.messagesByName[outName]
+	if !ok {
+		return fmt.Errorf("method %v: no descriptor for type %v", desc.FullName(), outName)
+	}
+	method.Output = out
+
+	return nil
+}
+
+// A GeneratedFile is a generated file.
+type GeneratedFile struct {
+	gen              *Plugin
+	skip             bool
+	filename         string
+	goImportPath     GoImportPath
+	buf              bytes.Buffer
+	packageNames     map[GoImportPath]GoPackageName
+	usedPackageNames map[GoPackageName]bool
+	manualImports    map[GoImportPath]bool
+	annotations      map[string][]Location
+}
+
+// NewGeneratedFile creates a new generated file with the given filename
+// and import path.
+func (gen *Plugin) NewGeneratedFile(filename string, goImportPath GoImportPath) *GeneratedFile {
+	g := &GeneratedFile{
+		gen:              gen,
+		filename:         filename,
+		goImportPath:     goImportPath,
+		packageNames:     make(map[GoImportPath]GoPackageName),
+		usedPackageNames: make(map[GoPackageName]bool),
+		manualImports:    make(map[GoImportPath]bool),
+		annotations:      make(map[string][]Location),
+	}
+
+	// All predeclared identifiers in Go are already used.
+	for _, s := range types.Universe.Names() {
+		g.usedPackageNames[GoPackageName(s)] = true
+	}
+
+	gen.genFiles = append(gen.genFiles, g)
+	return g
+}
+
+// P prints a line to the generated output. It converts each parameter to a
+// string following the same rules as fmt.Print. It never inserts spaces
+// between parameters.
+func (g *GeneratedFile) P(v ...interface{}) {
+	for _, x := range v {
+		switch x := x.(type) {
+		case GoIdent:
+			fmt.Fprint(&g.buf, g.QualifiedGoIdent(x))
+		default:
+			fmt.Fprint(&g.buf, x)
+		}
+	}
+	fmt.Fprintln(&g.buf)
+}
+
+// QualifiedGoIdent returns the string to use for a Go identifier.
+//
+// If the identifier is from a different Go package than the generated file,
+// the returned name will be qualified (package.name) and an import statement
+// for the identifier's package will be included in the file.
+func (g *GeneratedFile) QualifiedGoIdent(ident GoIdent) string {
+	if ident.GoImportPath == g.goImportPath {
+		return ident.GoName
+	}
+	if packageName, ok := g.packageNames[ident.GoImportPath]; ok {
+		return string(packageName) + "." + ident.GoName
+	}
+	packageName := cleanPackageName(path.Base(string(ident.GoImportPath)))
+	for i, orig := 1, packageName; g.usedPackageNames[packageName]; i++ {
+		packageName = orig + GoPackageName(strconv.Itoa(i))
+	}
+	g.packageNames[ident.GoImportPath] = packageName
+	g.usedPackageNames[packageName] = true
+	return string(packageName) + "." + ident.GoName
+}
+
+// Import ensures a package is imported by the generated file.
+//
+// Packages referenced by QualifiedGoIdent are automatically imported.
+// Explicitly importing a package with Import is generally only necessary
+// when the import will be blank (import _ "package").
+func (g *GeneratedFile) Import(importPath GoImportPath) {
+	g.manualImports[importPath] = true
+}
+
+// Write implements io.Writer.
+func (g *GeneratedFile) Write(p []byte) (n int, err error) {
+	return g.buf.Write(p)
+}
+
+// Skip removes the generated file from the plugin output.
+func (g *GeneratedFile) Skip() {
+	g.skip = true
+}
+
+// Unskip reverts a previous call to Skip, re-including the generated file in
+// the plugin output.
+func (g *GeneratedFile) Unskip() {
+	g.skip = false
+}
+
+// Annotate associates a symbol in a generated Go file with a location in a
+// source .proto file.
+//
+// The symbol may refer to a type, constant, variable, function, method, or
+// struct field.  The "T.sel" syntax is used to identify the method or field
+// 'sel' on type 'T'.
+func (g *GeneratedFile) Annotate(symbol string, loc Location) {
+	g.annotations[symbol] = append(g.annotations[symbol], loc)
+}
+
+// Content returns the contents of the generated file.
+func (g *GeneratedFile) Content() ([]byte, error) {
+	if !strings.HasSuffix(g.filename, ".go") {
+		return g.buf.Bytes(), nil
+	}
+
+	// Reformat generated code.
+	original := g.buf.Bytes()
+	fset := token.NewFileSet()
+	file, err := parser.ParseFile(fset, "", original, parser.ParseComments)
+	if err != nil {
+		// Print out the bad code with line numbers.
+		// This should never happen in practice, but it can while changing generated code
+		// so consider this a debugging aid.
+		var src bytes.Buffer
+		s := bufio.NewScanner(bytes.NewReader(original))
+		for line := 1; s.Scan(); line++ {
+			fmt.Fprintf(&src, "%5d\t%s\n", line, s.Bytes())
+		}
+		return nil, fmt.Errorf("%v: unparsable Go source: %v\n%v", g.filename, err, src.String())
+	}
+
+	// Collect a sorted list of all imports.
+	var importPaths [][2]string
+	rewriteImport := func(importPath string) string {
+		if f := g.gen.opts.ImportRewriteFunc; f != nil {
+			return string(f(GoImportPath(importPath)))
+		}
+		return importPath
+	}
+	for importPath := range g.packageNames {
+		pkgName := string(g.packageNames[GoImportPath(importPath)])
+		pkgPath := rewriteImport(string(importPath))
+		importPaths = append(importPaths, [2]string{pkgName, pkgPath})
+	}
+	for importPath := range g.manualImports {
+		if _, ok := g.packageNames[importPath]; !ok {
+			pkgPath := rewriteImport(string(importPath))
+			importPaths = append(importPaths, [2]string{"_", pkgPath})
+		}
+	}
+	sort.Slice(importPaths, func(i, j int) bool {
+		return importPaths[i][1] < importPaths[j][1]
+	})
+
+	// Modify the AST to include a new import block.
+	if len(importPaths) > 0 {
+		// Insert block after package statement or
+		// possible comment attached to the end of the package statement.
+		pos := file.Package
+		tokFile := fset.File(file.Package)
+		pkgLine := tokFile.Line(file.Package)
+		for _, c := range file.Comments {
+			if tokFile.Line(c.Pos()) > pkgLine {
+				break
+			}
+			pos = c.End()
+		}
+
+		// Construct the import block.
+		impDecl := &ast.GenDecl{
+			Tok:    token.IMPORT,
+			TokPos: pos,
+			Lparen: pos,
+			Rparen: pos,
+		}
+		for _, importPath := range importPaths {
+			impDecl.Specs = append(impDecl.Specs, &ast.ImportSpec{
+				Name: &ast.Ident{
+					Name:    importPath[0],
+					NamePos: pos,
+				},
+				Path: &ast.BasicLit{
+					Kind:     token.STRING,
+					Value:    strconv.Quote(importPath[1]),
+					ValuePos: pos,
+				},
+				EndPos: pos,
+			})
+		}
+		file.Decls = append([]ast.Decl{impDecl}, file.Decls...)
+	}
+
+	var out bytes.Buffer
+	if err = (&printer.Config{Mode: printer.TabIndent | printer.UseSpaces, Tabwidth: 8}).Fprint(&out, fset, file); err != nil {
+		return nil, fmt.Errorf("%v: can not reformat Go source: %v", g.filename, err)
+	}
+	return out.Bytes(), nil
+}
+
+// metaFile returns the contents of the file's metadata file, which is a
+// text formatted string of the google.protobuf.GeneratedCodeInfo.
+func (g *GeneratedFile) metaFile(content []byte) (string, error) {
+	fset := token.NewFileSet()
+	astFile, err := parser.ParseFile(fset, "", content, 0)
+	if err != nil {
+		return "", err
+	}
+	info := &descriptorpb.GeneratedCodeInfo{}
+
+	seenAnnotations := make(map[string]bool)
+	annotate := func(s string, ident *ast.Ident) {
+		seenAnnotations[s] = true
+		for _, loc := range g.annotations[s] {
+			info.Annotation = append(info.Annotation, &descriptorpb.GeneratedCodeInfo_Annotation{
+				SourceFile: proto.String(loc.SourceFile),
+				Path:       loc.Path,
+				Begin:      proto.Int32(int32(fset.Position(ident.Pos()).Offset)),
+				End:        proto.Int32(int32(fset.Position(ident.End()).Offset)),
+			})
+		}
+	}
+	for _, decl := range astFile.Decls {
+		switch decl := decl.(type) {
+		case *ast.GenDecl:
+			for _, spec := range decl.Specs {
+				switch spec := spec.(type) {
+				case *ast.TypeSpec:
+					annotate(spec.Name.Name, spec.Name)
+					switch st := spec.Type.(type) {
+					case *ast.StructType:
+						for _, field := range st.Fields.List {
+							for _, name := range field.Names {
+								annotate(spec.Name.Name+"."+name.Name, name)
+							}
+						}
+					case *ast.InterfaceType:
+						for _, field := range st.Methods.List {
+							for _, name := range field.Names {
+								annotate(spec.Name.Name+"."+name.Name, name)
+							}
+						}
+					}
+				case *ast.ValueSpec:
+					for _, name := range spec.Names {
+						annotate(name.Name, name)
+					}
+				}
+			}
+		case *ast.FuncDecl:
+			if decl.Recv == nil {
+				annotate(decl.Name.Name, decl.Name)
+			} else {
+				recv := decl.Recv.List[0].Type
+				if s, ok := recv.(*ast.StarExpr); ok {
+					recv = s.X
+				}
+				if id, ok := recv.(*ast.Ident); ok {
+					annotate(id.Name+"."+decl.Name.Name, decl.Name)
+				}
+			}
+		}
+	}
+	for a := range g.annotations {
+		if !seenAnnotations[a] {
+			return "", fmt.Errorf("%v: no symbol matching annotation %q", g.filename, a)
+		}
+	}
+
+	b, err := prototext.Marshal(info)
+	if err != nil {
+		return "", err
+	}
+	return string(b), nil
+}
+
+// A GoIdent is a Go identifier, consisting of a name and import path.
+// The name is a single identifier and may not be a dot-qualified selector.
+type GoIdent struct {
+	GoName       string
+	GoImportPath GoImportPath
+}
+
+func (id GoIdent) String() string { return fmt.Sprintf("%q.%v", id.GoImportPath, id.GoName) }
+
+// newGoIdent returns the Go identifier for a descriptor.
+func newGoIdent(f *File, d protoreflect.Descriptor) GoIdent {
+	name := strings.TrimPrefix(string(d.FullName()), string(f.Desc.Package())+".")
+	return GoIdent{
+		GoName:       strs.GoCamelCase(name),
+		GoImportPath: f.GoImportPath,
+	}
+}
+
+// A GoImportPath is the import path of a Go package.
+// For example: "google.golang.org/protobuf/compiler/protogen"
+type GoImportPath string
+
+func (p GoImportPath) String() string { return strconv.Quote(string(p)) }
+
+// Ident returns a GoIdent with s as the GoName and p as the GoImportPath.
+func (p GoImportPath) Ident(s string) GoIdent {
+	return GoIdent{GoName: s, GoImportPath: p}
+}
+
+// A GoPackageName is the name of a Go package. e.g., "protobuf".
+type GoPackageName string
+
+// cleanPackageName converts a string to a valid Go package name.
+func cleanPackageName(name string) GoPackageName {
+	return GoPackageName(strs.GoSanitized(name))
+}
+
+type pathType int
+
+const (
+	pathTypeImport pathType = iota
+	pathTypeSourceRelative
+)
+
+// A Location is a location in a .proto source file.
+//
+// See the google.protobuf.SourceCodeInfo documentation in descriptor.proto
+// for details.
+type Location struct {
+	SourceFile string
+	Path       protoreflect.SourcePath
+}
+
+// appendPath add elements to a Location's path, returning a new Location.
+func (loc Location) appendPath(num protoreflect.FieldNumber, idx int) Location {
+	loc.Path = append(protoreflect.SourcePath(nil), loc.Path...) // make copy
+	loc.Path = append(loc.Path, int32(num), int32(idx))
+	return loc
+}
+
+// CommentSet is a set of leading and trailing comments associated
+// with a .proto descriptor declaration.
+type CommentSet struct {
+	LeadingDetached []Comments
+	Leading         Comments
+	Trailing        Comments
+}
+
+func makeCommentSet(loc protoreflect.SourceLocation) CommentSet {
+	var leadingDetached []Comments
+	for _, s := range loc.LeadingDetachedComments {
+		leadingDetached = append(leadingDetached, Comments(s))
+	}
+	return CommentSet{
+		LeadingDetached: leadingDetached,
+		Leading:         Comments(loc.LeadingComments),
+		Trailing:        Comments(loc.TrailingComments),
+	}
+}
+
+// Comments is a comments string as provided by protoc.
+type Comments string
+
+// String formats the comments by inserting // to the start of each line,
+// ensuring that there is a trailing newline.
+// An empty comment is formatted as an empty string.
+func (c Comments) String() string {
+	if c == "" {
+		return ""
+	}
+	var b []byte
+	for _, line := range strings.Split(strings.TrimSuffix(string(c), "\n"), "\n") {
+		b = append(b, "//"...)
+		b = append(b, line...)
+		b = append(b, "\n"...)
+	}
+	return string(b)
+}
diff --git a/vendor/google.golang.org/protobuf/types/pluginpb/plugin.pb.go b/vendor/google.golang.org/protobuf/types/pluginpb/plugin.pb.go
new file mode 100644
index 0000000000000..e511ad6f7fb9d
--- /dev/null
+++ b/vendor/google.golang.org/protobuf/types/pluginpb/plugin.pb.go
@@ -0,0 +1,653 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc.  All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// 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.
+
+// Author: kenton@google.com (Kenton Varda)
+//
+// WARNING:  The plugin interface is currently EXPERIMENTAL and is subject to
+//   change.
+//
+// protoc (aka the Protocol Compiler) can be extended via plugins.  A plugin is
+// just a program that reads a CodeGeneratorRequest from stdin and writes a
+// CodeGeneratorResponse to stdout.
+//
+// Plugins written using C++ can use google/protobuf/compiler/plugin.h instead
+// of dealing with the raw protocol defined here.
+//
+// A plugin executable needs only to be placed somewhere in the path.  The
+// plugin should be named "protoc-gen-$NAME", and will then be used when the
+// flag "--${NAME}_out" is passed to protoc.
+
+// Code generated by protoc-gen-go. DO NOT EDIT.
+// source: google/protobuf/compiler/plugin.proto
+
+package pluginpb
+
+import (
+	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
+	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
+	descriptorpb "google.golang.org/protobuf/types/descriptorpb"
+	reflect "reflect"
+	sync "sync"
+)
+
+// Sync with code_generator.h.
+type CodeGeneratorResponse_Feature int32
+
+const (
+	CodeGeneratorResponse_FEATURE_NONE            CodeGeneratorResponse_Feature = 0
+	CodeGeneratorResponse_FEATURE_PROTO3_OPTIONAL CodeGeneratorResponse_Feature = 1
+)
+
+// Enum value maps for CodeGeneratorResponse_Feature.
+var (
+	CodeGeneratorResponse_Feature_name = map[int32]string{
+		0: "FEATURE_NONE",
+		1: "FEATURE_PROTO3_OPTIONAL",
+	}
+	CodeGeneratorResponse_Feature_value = map[string]int32{
+		"FEATURE_NONE":            0,
+		"FEATURE_PROTO3_OPTIONAL": 1,
+	}
+)
+
+func (x CodeGeneratorResponse_Feature) Enum() *CodeGeneratorResponse_Feature {
+	p := new(CodeGeneratorResponse_Feature)
+	*p = x
+	return p
+}
+
+func (x CodeGeneratorResponse_Feature) String() string {
+	return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))
+}
+
+func (CodeGeneratorResponse_Feature) Descriptor() protoreflect.EnumDescriptor {
+	return file_google_protobuf_compiler_plugin_proto_enumTypes[0].Descriptor()
+}
+
+func (CodeGeneratorResponse_Feature) Type() protoreflect.EnumType {
+	return &file_google_protobuf_compiler_plugin_proto_enumTypes[0]
+}
+
+func (x CodeGeneratorResponse_Feature) Number() protoreflect.EnumNumber {
+	return protoreflect.EnumNumber(x)
+}
+
+// Deprecated: Do not use.
+func (x *CodeGeneratorResponse_Feature) UnmarshalJSON(b []byte) error {
+	num, err := protoimpl.X.UnmarshalJSONEnum(x.Descriptor(), b)
+	if err != nil {
+		return err
+	}
+	*x = CodeGeneratorResponse_Feature(num)
+	return nil
+}
+
+// Deprecated: Use CodeGeneratorResponse_Feature.Descriptor instead.
+func (CodeGeneratorResponse_Feature) EnumDescriptor() ([]byte, []int) {
+	return file_google_protobuf_compiler_plugin_proto_rawDescGZIP(), []int{2, 0}
+}
+
+// The version number of protocol compiler.
+type Version struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	Major *int32 `protobuf:"varint,1,opt,name=major" json:"major,omitempty"`
+	Minor *int32 `protobuf:"varint,2,opt,name=minor" json:"minor,omitempty"`
+	Patch *int32 `protobuf:"varint,3,opt,name=patch" json:"patch,omitempty"`
+	// A suffix for alpha, beta or rc release, e.g., "alpha-1", "rc2". It should
+	// be empty for mainline stable releases.
+	Suffix *string `protobuf:"bytes,4,opt,name=suffix" json:"suffix,omitempty"`
+}
+
+func (x *Version) Reset() {
+	*x = Version{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[0]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *Version) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*Version) ProtoMessage() {}
+
+func (x *Version) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[0]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use Version.ProtoReflect.Descriptor instead.
+func (*Version) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_compiler_plugin_proto_rawDescGZIP(), []int{0}
+}
+
+func (x *Version) GetMajor() int32 {
+	if x != nil && x.Major != nil {
+		return *x.Major
+	}
+	return 0
+}
+
+func (x *Version) GetMinor() int32 {
+	if x != nil && x.Minor != nil {
+		return *x.Minor
+	}
+	return 0
+}
+
+func (x *Version) GetPatch() int32 {
+	if x != nil && x.Patch != nil {
+		return *x.Patch
+	}
+	return 0
+}
+
+func (x *Version) GetSuffix() string {
+	if x != nil && x.Suffix != nil {
+		return *x.Suffix
+	}
+	return ""
+}
+
+// An encoded CodeGeneratorRequest is written to the plugin's stdin.
+type CodeGeneratorRequest struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The .proto files that were explicitly listed on the command-line.  The
+	// code generator should generate code only for these files.  Each file's
+	// descriptor will be included in proto_file, below.
+	FileToGenerate []string `protobuf:"bytes,1,rep,name=file_to_generate,json=fileToGenerate" json:"file_to_generate,omitempty"`
+	// The generator parameter passed on the command-line.
+	Parameter *string `protobuf:"bytes,2,opt,name=parameter" json:"parameter,omitempty"`
+	// FileDescriptorProtos for all files in files_to_generate and everything
+	// they import.  The files will appear in topological order, so each file
+	// appears before any file that imports it.
+	//
+	// protoc guarantees that all proto_files will be written after
+	// the fields above, even though this is not technically guaranteed by the
+	// protobuf wire format.  This theoretically could allow a plugin to stream
+	// in the FileDescriptorProtos and handle them one by one rather than read
+	// the entire set into memory at once.  However, as of this writing, this
+	// is not similarly optimized on protoc's end -- it will store all fields in
+	// memory at once before sending them to the plugin.
+	//
+	// Type names of fields and extensions in the FileDescriptorProto are always
+	// fully qualified.
+	ProtoFile []*descriptorpb.FileDescriptorProto `protobuf:"bytes,15,rep,name=proto_file,json=protoFile" json:"proto_file,omitempty"`
+	// The version number of protocol compiler.
+	CompilerVersion *Version `protobuf:"bytes,3,opt,name=compiler_version,json=compilerVersion" json:"compiler_version,omitempty"`
+}
+
+func (x *CodeGeneratorRequest) Reset() {
+	*x = CodeGeneratorRequest{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[1]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CodeGeneratorRequest) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CodeGeneratorRequest) ProtoMessage() {}
+
+func (x *CodeGeneratorRequest) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[1]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CodeGeneratorRequest.ProtoReflect.Descriptor instead.
+func (*CodeGeneratorRequest) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_compiler_plugin_proto_rawDescGZIP(), []int{1}
+}
+
+func (x *CodeGeneratorRequest) GetFileToGenerate() []string {
+	if x != nil {
+		return x.FileToGenerate
+	}
+	return nil
+}
+
+func (x *CodeGeneratorRequest) GetParameter() string {
+	if x != nil && x.Parameter != nil {
+		return *x.Parameter
+	}
+	return ""
+}
+
+func (x *CodeGeneratorRequest) GetProtoFile() []*descriptorpb.FileDescriptorProto {
+	if x != nil {
+		return x.ProtoFile
+	}
+	return nil
+}
+
+func (x *CodeGeneratorRequest) GetCompilerVersion() *Version {
+	if x != nil {
+		return x.CompilerVersion
+	}
+	return nil
+}
+
+// The plugin writes an encoded CodeGeneratorResponse to stdout.
+type CodeGeneratorResponse struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// Error message.  If non-empty, code generation failed.  The plugin process
+	// should exit with status code zero even if it reports an error in this way.
+	//
+	// This should be used to indicate errors in .proto files which prevent the
+	// code generator from generating correct code.  Errors which indicate a
+	// problem in protoc itself -- such as the input CodeGeneratorRequest being
+	// unparseable -- should be reported by writing a message to stderr and
+	// exiting with a non-zero status code.
+	Error *string `protobuf:"bytes,1,opt,name=error" json:"error,omitempty"`
+	// A bitmask of supported features that the code generator supports.
+	// This is a bitwise "or" of values from the Feature enum.
+	SupportedFeatures *uint64                       `protobuf:"varint,2,opt,name=supported_features,json=supportedFeatures" json:"supported_features,omitempty"`
+	File              []*CodeGeneratorResponse_File `protobuf:"bytes,15,rep,name=file" json:"file,omitempty"`
+}
+
+func (x *CodeGeneratorResponse) Reset() {
+	*x = CodeGeneratorResponse{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[2]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CodeGeneratorResponse) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CodeGeneratorResponse) ProtoMessage() {}
+
+func (x *CodeGeneratorResponse) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[2]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CodeGeneratorResponse.ProtoReflect.Descriptor instead.
+func (*CodeGeneratorResponse) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_compiler_plugin_proto_rawDescGZIP(), []int{2}
+}
+
+func (x *CodeGeneratorResponse) GetError() string {
+	if x != nil && x.Error != nil {
+		return *x.Error
+	}
+	return ""
+}
+
+func (x *CodeGeneratorResponse) GetSupportedFeatures() uint64 {
+	if x != nil && x.SupportedFeatures != nil {
+		return *x.SupportedFeatures
+	}
+	return 0
+}
+
+func (x *CodeGeneratorResponse) GetFile() []*CodeGeneratorResponse_File {
+	if x != nil {
+		return x.File
+	}
+	return nil
+}
+
+// Represents a single generated file.
+type CodeGeneratorResponse_File struct {
+	state         protoimpl.MessageState
+	sizeCache     protoimpl.SizeCache
+	unknownFields protoimpl.UnknownFields
+
+	// The file name, relative to the output directory.  The name must not
+	// contain "." or ".." components and must be relative, not be absolute (so,
+	// the file cannot lie outside the output directory).  "/" must be used as
+	// the path separator, not "\".
+	//
+	// If the name is omitted, the content will be appended to the previous
+	// file.  This allows the generator to break large files into small chunks,
+	// and allows the generated text to be streamed back to protoc so that large
+	// files need not reside completely in memory at one time.  Note that as of
+	// this writing protoc does not optimize for this -- it will read the entire
+	// CodeGeneratorResponse before writing files to disk.
+	Name *string `protobuf:"bytes,1,opt,name=name" json:"name,omitempty"`
+	// If non-empty, indicates that the named file should already exist, and the
+	// content here is to be inserted into that file at a defined insertion
+	// point.  This feature allows a code generator to extend the output
+	// produced by another code generator.  The original generator may provide
+	// insertion points by placing special annotations in the file that look
+	// like:
+	//   @@protoc_insertion_point(NAME)
+	// The annotation can have arbitrary text before and after it on the line,
+	// which allows it to be placed in a comment.  NAME should be replaced with
+	// an identifier naming the point -- this is what other generators will use
+	// as the insertion_point.  Code inserted at this point will be placed
+	// immediately above the line containing the insertion point (thus multiple
+	// insertions to the same point will come out in the order they were added).
+	// The double-@ is intended to make it unlikely that the generated code
+	// could contain things that look like insertion points by accident.
+	//
+	// For example, the C++ code generator places the following line in the
+	// .pb.h files that it generates:
+	//   // @@protoc_insertion_point(namespace_scope)
+	// This line appears within the scope of the file's package namespace, but
+	// outside of any particular class.  Another plugin can then specify the
+	// insertion_point "namespace_scope" to generate additional classes or
+	// other declarations that should be placed in this scope.
+	//
+	// Note that if the line containing the insertion point begins with
+	// whitespace, the same whitespace will be added to every line of the
+	// inserted text.  This is useful for languages like Python, where
+	// indentation matters.  In these languages, the insertion point comment
+	// should be indented the same amount as any inserted code will need to be
+	// in order to work correctly in that context.
+	//
+	// The code generator that generates the initial file and the one which
+	// inserts into it must both run as part of a single invocation of protoc.
+	// Code generators are executed in the order in which they appear on the
+	// command line.
+	//
+	// If |insertion_point| is present, |name| must also be present.
+	InsertionPoint *string `protobuf:"bytes,2,opt,name=insertion_point,json=insertionPoint" json:"insertion_point,omitempty"`
+	// The file contents.
+	Content *string `protobuf:"bytes,15,opt,name=content" json:"content,omitempty"`
+	// Information describing the file content being inserted. If an insertion
+	// point is used, this information will be appropriately offset and inserted
+	// into the code generation metadata for the generated files.
+	GeneratedCodeInfo *descriptorpb.GeneratedCodeInfo `protobuf:"bytes,16,opt,name=generated_code_info,json=generatedCodeInfo" json:"generated_code_info,omitempty"`
+}
+
+func (x *CodeGeneratorResponse_File) Reset() {
+	*x = CodeGeneratorResponse_File{}
+	if protoimpl.UnsafeEnabled {
+		mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[3]
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		ms.StoreMessageInfo(mi)
+	}
+}
+
+func (x *CodeGeneratorResponse_File) String() string {
+	return protoimpl.X.MessageStringOf(x)
+}
+
+func (*CodeGeneratorResponse_File) ProtoMessage() {}
+
+func (x *CodeGeneratorResponse_File) ProtoReflect() protoreflect.Message {
+	mi := &file_google_protobuf_compiler_plugin_proto_msgTypes[3]
+	if protoimpl.UnsafeEnabled && x != nil {
+		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+		if ms.LoadMessageInfo() == nil {
+			ms.StoreMessageInfo(mi)
+		}
+		return ms
+	}
+	return mi.MessageOf(x)
+}
+
+// Deprecated: Use CodeGeneratorResponse_File.ProtoReflect.Descriptor instead.
+func (*CodeGeneratorResponse_File) Descriptor() ([]byte, []int) {
+	return file_google_protobuf_compiler_plugin_proto_rawDescGZIP(), []int{2, 0}
+}
+
+func (x *CodeGeneratorResponse_File) GetName() string {
+	if x != nil && x.Name != nil {
+		return *x.Name
+	}
+	return ""
+}
+
+func (x *CodeGeneratorResponse_File) GetInsertionPoint() string {
+	if x != nil && x.InsertionPoint != nil {
+		return *x.InsertionPoint
+	}
+	return ""
+}
+
+func (x *CodeGeneratorResponse_File) GetContent() string {
+	if x != nil && x.Content != nil {
+		return *x.Content
+	}
+	return ""
+}
+
+func (x *CodeGeneratorResponse_File) GetGeneratedCodeInfo() *descriptorpb.GeneratedCodeInfo {
+	if x != nil {
+		return x.GeneratedCodeInfo
+	}
+	return nil
+}
+
+var File_google_protobuf_compiler_plugin_proto protoreflect.FileDescriptor
+
+var file_google_protobuf_compiler_plugin_proto_rawDesc = []byte{
+	0x0a, 0x25, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75,
+	0x66, 0x2f, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69,
+	0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x18, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
+	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65,
+	0x72, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x22, 0x63, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14,
+	0x0a, 0x05, 0x6d, 0x61, 0x6a, 0x6f, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6d,
+	0x61, 0x6a, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x18, 0x02, 0x20,
+	0x01, 0x28, 0x05, 0x52, 0x05, 0x6d, 0x69, 0x6e, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x70, 0x61,
+	0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x70, 0x61, 0x74, 0x63, 0x68,
+	0x12, 0x16, 0x0a, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x22, 0xf1, 0x01, 0x0a, 0x14, 0x43, 0x6f, 0x64,
+	0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x12, 0x28, 0x0a, 0x10, 0x66, 0x69, 0x6c, 0x65, 0x5f, 0x74, 0x6f, 0x5f, 0x67, 0x65, 0x6e,
+	0x65, 0x72, 0x61, 0x74, 0x65, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x0e, 0x66, 0x69, 0x6c,
+	0x65, 0x54, 0x6f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70,
+	0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
+	0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x12, 0x43, 0x0a, 0x0a, 0x70, 0x72, 0x6f,
+	0x74, 0x6f, 0x5f, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e,
+	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+	0x46, 0x69, 0x6c, 0x65, 0x44, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x50, 0x72,
+	0x6f, 0x74, 0x6f, 0x52, 0x09, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x4c,
+	0x0a, 0x10, 0x63, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69,
+	0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69,
+	0x6c, 0x65, 0x72, 0x2e, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0f, 0x63, 0x6f, 0x6d,
+	0x70, 0x69, 0x6c, 0x65, 0x72, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x94, 0x03, 0x0a,
+	0x15, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x6f, 0x72, 0x52, 0x65,
+	0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x2d, 0x0a, 0x12,
+	0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x65, 0x64, 0x5f, 0x66, 0x65, 0x61, 0x74, 0x75, 0x72,
+	0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72,
+	0x74, 0x65, 0x64, 0x46, 0x65, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x04, 0x66,
+	0x69, 0x6c, 0x65, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x67, 0x6f, 0x6f, 0x67,
+	0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x70,
+	0x69, 0x6c, 0x65, 0x72, 0x2e, 0x43, 0x6f, 0x64, 0x65, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
+	0x6f, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x52,
+	0x04, 0x66, 0x69, 0x6c, 0x65, 0x1a, 0xb1, 0x01, 0x0a, 0x04, 0x46, 0x69, 0x6c, 0x65, 0x12, 0x12,
+	0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
+	0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f, 0x69, 0x6e, 0x73, 0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
+	0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x6e, 0x73,
+	0x65, 0x72, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63,
+	0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x6f,
+	0x6e, 0x74, 0x65, 0x6e, 0x74, 0x12, 0x52, 0x0a, 0x13, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74,
+	0x65, 0x64, 0x5f, 0x63, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x10, 0x20, 0x01,
+	0x28, 0x0b, 0x32, 0x22, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
+	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x43, 0x6f,
+	0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65,
+	0x64, 0x43, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0x38, 0x0a, 0x07, 0x46, 0x65, 0x61,
+	0x74, 0x75, 0x72, 0x65, 0x12, 0x10, 0x0a, 0x0c, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52, 0x45, 0x5f,
+	0x4e, 0x4f, 0x4e, 0x45, 0x10, 0x00, 0x12, 0x1b, 0x0a, 0x17, 0x46, 0x45, 0x41, 0x54, 0x55, 0x52,
+	0x45, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x33, 0x5f, 0x4f, 0x50, 0x54, 0x49, 0x4f, 0x4e, 0x41,
+	0x4c, 0x10, 0x01, 0x42, 0x57, 0x0a, 0x1c, 0x63, 0x6f, 0x6d, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x63, 0x6f, 0x6d, 0x70, 0x69,
+	0x6c, 0x65, 0x72, 0x42, 0x0c, 0x50, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f,
+	0x73, 0x5a, 0x29, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67,
+	0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x79,
+	0x70, 0x65, 0x73, 0x2f, 0x70, 0x6c, 0x75, 0x67, 0x69, 0x6e, 0x70, 0x62,
+}
+
+var (
+	file_google_protobuf_compiler_plugin_proto_rawDescOnce sync.Once
+	file_google_protobuf_compiler_plugin_proto_rawDescData = file_google_protobuf_compiler_plugin_proto_rawDesc
+)
+
+func file_google_protobuf_compiler_plugin_proto_rawDescGZIP() []byte {
+	file_google_protobuf_compiler_plugin_proto_rawDescOnce.Do(func() {
+		file_google_protobuf_compiler_plugin_proto_rawDescData = protoimpl.X.CompressGZIP(file_google_protobuf_compiler_plugin_proto_rawDescData)
+	})
+	return file_google_protobuf_compiler_plugin_proto_rawDescData
+}
+
+var file_google_protobuf_compiler_plugin_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
+var file_google_protobuf_compiler_plugin_proto_msgTypes = make([]protoimpl.MessageInfo, 4)
+var file_google_protobuf_compiler_plugin_proto_goTypes = []interface{}{
+	(CodeGeneratorResponse_Feature)(0),       // 0: google.protobuf.compiler.CodeGeneratorResponse.Feature
+	(*Version)(nil),                          // 1: google.protobuf.compiler.Version
+	(*CodeGeneratorRequest)(nil),             // 2: google.protobuf.compiler.CodeGeneratorRequest
+	(*CodeGeneratorResponse)(nil),            // 3: google.protobuf.compiler.CodeGeneratorResponse
+	(*CodeGeneratorResponse_File)(nil),       // 4: google.protobuf.compiler.CodeGeneratorResponse.File
+	(*descriptorpb.FileDescriptorProto)(nil), // 5: google.protobuf.FileDescriptorProto
+	(*descriptorpb.GeneratedCodeInfo)(nil),   // 6: google.protobuf.GeneratedCodeInfo
+}
+var file_google_protobuf_compiler_plugin_proto_depIdxs = []int32{
+	5, // 0: google.protobuf.compiler.CodeGeneratorRequest.proto_file:type_name -> google.protobuf.FileDescriptorProto
+	1, // 1: google.protobuf.compiler.CodeGeneratorRequest.compiler_version:type_name -> google.protobuf.compiler.Version
+	4, // 2: google.protobuf.compiler.CodeGeneratorResponse.file:type_name -> google.protobuf.compiler.CodeGeneratorResponse.File
+	6, // 3: google.protobuf.compiler.CodeGeneratorResponse.File.generated_code_info:type_name -> google.protobuf.GeneratedCodeInfo
+	4, // [4:4] is the sub-list for method output_type
+	4, // [4:4] is the sub-list for method input_type
+	4, // [4:4] is the sub-list for extension type_name
+	4, // [4:4] is the sub-list for extension extendee
+	0, // [0:4] is the sub-list for field type_name
+}
+
+func init() { file_google_protobuf_compiler_plugin_proto_init() }
+func file_google_protobuf_compiler_plugin_proto_init() {
+	if File_google_protobuf_compiler_plugin_proto != nil {
+		return
+	}
+	if !protoimpl.UnsafeEnabled {
+		file_google_protobuf_compiler_plugin_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*Version); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_compiler_plugin_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CodeGeneratorRequest); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_compiler_plugin_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CodeGeneratorResponse); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+		file_google_protobuf_compiler_plugin_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
+			switch v := v.(*CodeGeneratorResponse_File); i {
+			case 0:
+				return &v.state
+			case 1:
+				return &v.sizeCache
+			case 2:
+				return &v.unknownFields
+			default:
+				return nil
+			}
+		}
+	}
+	type x struct{}
+	out := protoimpl.TypeBuilder{
+		File: protoimpl.DescBuilder{
+			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
+			RawDescriptor: file_google_protobuf_compiler_plugin_proto_rawDesc,
+			NumEnums:      1,
+			NumMessages:   4,
+			NumExtensions: 0,
+			NumServices:   0,
+		},
+		GoTypes:           file_google_protobuf_compiler_plugin_proto_goTypes,
+		DependencyIndexes: file_google_protobuf_compiler_plugin_proto_depIdxs,
+		EnumInfos:         file_google_protobuf_compiler_plugin_proto_enumTypes,
+		MessageInfos:      file_google_protobuf_compiler_plugin_proto_msgTypes,
+	}.Build()
+	File_google_protobuf_compiler_plugin_proto = out.File
+	file_google_protobuf_compiler_plugin_proto_rawDesc = nil
+	file_google_protobuf_compiler_plugin_proto_goTypes = nil
+	file_google_protobuf_compiler_plugin_proto_depIdxs = nil
+}
diff --git a/vendor/modules.txt b/vendor/modules.txt
index 17e76e32965a5..3f0cc4880695b 100644
--- a/vendor/modules.txt
+++ b/vendor/modules.txt
@@ -446,10 +446,35 @@ github.com/gogo/googleapis/google/rpc
 ## explicit; go 1.15
 github.com/gogo/protobuf/gogoproto
 github.com/gogo/protobuf/io
+github.com/gogo/protobuf/plugin/compare
+github.com/gogo/protobuf/plugin/defaultcheck
+github.com/gogo/protobuf/plugin/description
+github.com/gogo/protobuf/plugin/embedcheck
+github.com/gogo/protobuf/plugin/enumstringer
+github.com/gogo/protobuf/plugin/equal
+github.com/gogo/protobuf/plugin/face
+github.com/gogo/protobuf/plugin/gostring
+github.com/gogo/protobuf/plugin/marshalto
+github.com/gogo/protobuf/plugin/oneofcheck
+github.com/gogo/protobuf/plugin/populate
+github.com/gogo/protobuf/plugin/size
+github.com/gogo/protobuf/plugin/stringer
+github.com/gogo/protobuf/plugin/testgen
+github.com/gogo/protobuf/plugin/union
+github.com/gogo/protobuf/plugin/unmarshal
 github.com/gogo/protobuf/proto
+github.com/gogo/protobuf/protoc-gen-gogo
 github.com/gogo/protobuf/protoc-gen-gogo/descriptor
+github.com/gogo/protobuf/protoc-gen-gogo/generator
+github.com/gogo/protobuf/protoc-gen-gogo/generator/internal/remap
+github.com/gogo/protobuf/protoc-gen-gogo/grpc
+github.com/gogo/protobuf/protoc-gen-gogo/plugin
+github.com/gogo/protobuf/protoc-gen-gogofaster
+github.com/gogo/protobuf/protoc-gen-gogoslick
 github.com/gogo/protobuf/sortkeys
 github.com/gogo/protobuf/types
+github.com/gogo/protobuf/vanity
+github.com/gogo/protobuf/vanity/command
 # github.com/golang-jwt/jwt/v4 v4.4.2
 ## explicit; go 1.16
 github.com/golang-jwt/jwt/v4
@@ -463,8 +488,10 @@ github.com/golang/groupcache/lru
 # github.com/golang/protobuf v1.5.2
 ## explicit; go 1.9
 github.com/golang/protobuf/descriptor
+github.com/golang/protobuf/internal/gengogrpc
 github.com/golang/protobuf/jsonpb
 github.com/golang/protobuf/proto
+github.com/golang/protobuf/protoc-gen-go
 github.com/golang/protobuf/protoc-gen-go/descriptor
 github.com/golang/protobuf/ptypes
 github.com/golang/protobuf/ptypes/any
@@ -1272,6 +1299,8 @@ google.golang.org/grpc/status
 google.golang.org/grpc/tap
 # google.golang.org/protobuf v1.28.1
 ## explicit; go 1.11
+google.golang.org/protobuf/cmd/protoc-gen-go/internal_gengo
+google.golang.org/protobuf/compiler/protogen
 google.golang.org/protobuf/encoding/protojson
 google.golang.org/protobuf/encoding/prototext
 google.golang.org/protobuf/encoding/protowire
@@ -1308,6 +1337,7 @@ google.golang.org/protobuf/types/known/fieldmaskpb
 google.golang.org/protobuf/types/known/structpb
 google.golang.org/protobuf/types/known/timestamppb
 google.golang.org/protobuf/types/known/wrapperspb
+google.golang.org/protobuf/types/pluginpb
 # gopkg.in/yaml.v2 v2.4.0
 ## explicit; go 1.15
 gopkg.in/yaml.v2


Test patch:
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index ec9e4e68862d8..23efe285a6c85 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -73,7 +73,7 @@ jobs:
         name: Create matrix
         id: scripts
         run: |
-          scripts=$(jq -ncR '[inputs]' <<< "$(ls -I .validate -I all -I default -I dco -I golangci-lint.yml -I yamllint.yaml -A ./hack/validate/)")
+          scripts=$(cd ./hack/validate && jq -nc '$ARGS.positional - ["all", "default", "dco"] | map(select(test("[.]")|not)) + ["generate-files"]' --args *)
           echo "matrix=$scripts" >> $GITHUB_OUTPUT
       -
         name: Show matrix
diff --git a/vendor/github.com/gogo/protobuf/plugin/compare/comparetest.go b/vendor/github.com/gogo/protobuf/plugin/compare/comparetest.go
new file mode 100644
index 0000000000000..4fbdbc633cd45
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/compare/comparetest.go
@@ -0,0 +1,118 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 compare
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/plugin/testgen"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type test struct {
+	*generator.Generator
+}
+
+func NewTest(g *generator.Generator) testgen.TestPlugin {
+	return &test{g}
+}
+
+func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	randPkg := imports.NewImport("math/rand")
+	timePkg := imports.NewImport("time")
+	testingPkg := imports.NewImport("testing")
+	protoPkg := imports.NewImport("github.com/gogo/protobuf/proto")
+	unsafePkg := imports.NewImport("unsafe")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		protoPkg = imports.NewImport("github.com/golang/protobuf/proto")
+	}
+	for _, message := range file.Messages() {
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		if !gogoproto.HasCompare(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+
+		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+			hasUnsafe := gogoproto.IsUnsafeMarshaler(file.FileDescriptorProto, message.DescriptorProto) ||
+				gogoproto.IsUnsafeUnmarshaler(file.FileDescriptorProto, message.DescriptorProto)
+			p.P(`func Test`, ccTypeName, `Compare(t *`, testingPkg.Use(), `.T) {`)
+			p.In()
+			if hasUnsafe {
+				p.P(`var bigendian uint32 = 0x01020304`)
+				p.P(`if *(*byte)(`, unsafePkg.Use(), `.Pointer(&bigendian)) == 1 {`)
+				p.In()
+				p.P(`t.Skip("unsafe does not work on big endian architectures")`)
+				p.Out()
+				p.P(`}`)
+			}
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
+			p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
+			p.P(`dAtA, err := `, protoPkg.Use(), `.Marshal(p)`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`panic(err)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`msg := &`, ccTypeName, `{}`)
+			p.P(`if err := `, protoPkg.Use(), `.Unmarshal(dAtA, msg); err != nil {`)
+			p.In()
+			p.P(`panic(err)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`if c := p.Compare(msg); c != 0 {`)
+			p.In()
+			p.P(`t.Fatalf("%#v !Compare %#v, since %d", msg, p, c)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`p2 := NewPopulated`, ccTypeName, `(popr, false)`)
+			p.P(`c := p.Compare(p2)`)
+			p.P(`c2 := p2.Compare(p)`)
+			p.P(`if c != (-1 * c2) {`)
+			p.In()
+			p.P(`t.Errorf("p.Compare(p2) = %d", c)`)
+			p.P(`t.Errorf("p2.Compare(p) = %d", c2)`)
+			p.P(`t.Errorf("p = %#v", p)`)
+			p.P(`t.Errorf("p2 = %#v", p2)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+		}
+
+	}
+	return used
+}
+
+func init() {
+	testgen.RegisterTestPlugin(NewTest)
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/description/descriptiontest.go b/vendor/github.com/gogo/protobuf/plugin/description/descriptiontest.go
new file mode 100644
index 0000000000000..babcd311da42b
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/description/descriptiontest.go
@@ -0,0 +1,73 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 description
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/plugin/testgen"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type test struct {
+	*generator.Generator
+}
+
+func NewTest(g *generator.Generator) testgen.TestPlugin {
+	return &test{g}
+}
+
+func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	testingPkg := imports.NewImport("testing")
+	for _, message := range file.Messages() {
+		if !gogoproto.HasDescription(file.FileDescriptorProto, message.DescriptorProto) ||
+			!gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		used = true
+	}
+
+	if used {
+		localName := generator.FileName(file)
+		p.P(`func Test`, localName, `Description(t *`, testingPkg.Use(), `.T) {`)
+		p.In()
+		p.P(localName, `Description()`)
+		p.Out()
+		p.P(`}`)
+
+	}
+	return used
+}
+
+func init() {
+	testgen.RegisterTestPlugin(NewTest)
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/equal/equaltest.go b/vendor/github.com/gogo/protobuf/plugin/equal/equaltest.go
new file mode 100644
index 0000000000000..1233647a56dd0
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/equal/equaltest.go
@@ -0,0 +1,109 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 equal
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/plugin/testgen"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type test struct {
+	*generator.Generator
+}
+
+func NewTest(g *generator.Generator) testgen.TestPlugin {
+	return &test{g}
+}
+
+func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	randPkg := imports.NewImport("math/rand")
+	timePkg := imports.NewImport("time")
+	testingPkg := imports.NewImport("testing")
+	protoPkg := imports.NewImport("github.com/gogo/protobuf/proto")
+	unsafePkg := imports.NewImport("unsafe")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		protoPkg = imports.NewImport("github.com/golang/protobuf/proto")
+	}
+	for _, message := range file.Messages() {
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		if !gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+
+		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+			hasUnsafe := gogoproto.IsUnsafeMarshaler(file.FileDescriptorProto, message.DescriptorProto) ||
+				gogoproto.IsUnsafeUnmarshaler(file.FileDescriptorProto, message.DescriptorProto)
+			p.P(`func Test`, ccTypeName, `VerboseEqual(t *`, testingPkg.Use(), `.T) {`)
+			p.In()
+			if hasUnsafe {
+				if hasUnsafe {
+					p.P(`var bigendian uint32 = 0x01020304`)
+					p.P(`if *(*byte)(`, unsafePkg.Use(), `.Pointer(&bigendian)) == 1 {`)
+					p.In()
+					p.P(`t.Skip("unsafe does not work on big endian architectures")`)
+					p.Out()
+					p.P(`}`)
+				}
+			}
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
+			p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
+			p.P(`dAtA, err := `, protoPkg.Use(), `.Marshal(p)`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`panic(err)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`msg := &`, ccTypeName, `{}`)
+			p.P(`if err := `, protoPkg.Use(), `.Unmarshal(dAtA, msg); err != nil {`)
+			p.In()
+			p.P(`panic(err)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`if err := p.VerboseEqual(msg); err != nil {`)
+			p.In()
+			p.P(`t.Fatalf("%#v !VerboseEqual %#v, since %v", msg, p, err)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+		}
+
+	}
+	return used
+}
+
+func init() {
+	testgen.RegisterTestPlugin(NewTest)
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/face/facetest.go b/vendor/github.com/gogo/protobuf/plugin/face/facetest.go
new file mode 100644
index 0000000000000..467cc0a6640df
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/face/facetest.go
@@ -0,0 +1,82 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 face
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/plugin/testgen"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type test struct {
+	*generator.Generator
+}
+
+func NewTest(g *generator.Generator) testgen.TestPlugin {
+	return &test{g}
+}
+
+func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	randPkg := imports.NewImport("math/rand")
+	timePkg := imports.NewImport("time")
+	testingPkg := imports.NewImport("testing")
+	for _, message := range file.Messages() {
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		if !gogoproto.IsFace(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+
+		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+
+			p.P(`func Test`, ccTypeName, `Face(t *`, testingPkg.Use(), `.T) {`)
+			p.In()
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
+			p.P(`p := NewPopulated`, ccTypeName, `(popr, true)`)
+			p.P(`msg := p.TestProto()`)
+			p.P(`if !p.Equal(msg) {`)
+			p.In()
+			p.P(`t.Fatalf("%#v !Face Equal %#v", msg, p)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+		}
+
+	}
+	return used
+}
+
+func init() {
+	testgen.RegisterTestPlugin(NewTest)
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/gostring/gostringtest.go b/vendor/github.com/gogo/protobuf/plugin/gostring/gostringtest.go
new file mode 100644
index 0000000000000..c790e59088004
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/gostring/gostringtest.go
@@ -0,0 +1,90 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 gostring
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/plugin/testgen"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type test struct {
+	*generator.Generator
+}
+
+func NewTest(g *generator.Generator) testgen.TestPlugin {
+	return &test{g}
+}
+
+func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	randPkg := imports.NewImport("math/rand")
+	timePkg := imports.NewImport("time")
+	testingPkg := imports.NewImport("testing")
+	fmtPkg := imports.NewImport("fmt")
+	parserPkg := imports.NewImport("go/parser")
+	for _, message := range file.Messages() {
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		if !gogoproto.HasGoString(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+
+		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+			p.P(`func Test`, ccTypeName, `GoString(t *`, testingPkg.Use(), `.T) {`)
+			p.In()
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
+			p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
+			p.P(`s1 := p.GoString()`)
+			p.P(`s2 := `, fmtPkg.Use(), `.Sprintf("%#v", p)`)
+			p.P(`if s1 != s2 {`)
+			p.In()
+			p.P(`t.Fatalf("GoString want %v got %v", s1, s2)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`_, err := `, parserPkg.Use(), `.ParseExpr(s1)`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`t.Fatal(err)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+		}
+
+	}
+	return used
+}
+
+func init() {
+	testgen.RegisterTestPlugin(NewTest)
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/size/sizetest.go b/vendor/github.com/gogo/protobuf/plugin/size/sizetest.go
new file mode 100644
index 0000000000000..1df987300075f
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/size/sizetest.go
@@ -0,0 +1,134 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 size
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/plugin/testgen"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type test struct {
+	*generator.Generator
+}
+
+func NewTest(g *generator.Generator) testgen.TestPlugin {
+	return &test{g}
+}
+
+func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	randPkg := imports.NewImport("math/rand")
+	timePkg := imports.NewImport("time")
+	testingPkg := imports.NewImport("testing")
+	protoPkg := imports.NewImport("github.com/gogo/protobuf/proto")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		protoPkg = imports.NewImport("github.com/golang/protobuf/proto")
+	}
+	for _, message := range file.Messages() {
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		sizeName := ""
+		if gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) {
+			sizeName = "Size"
+		} else if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
+			sizeName = "ProtoSize"
+		} else {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+
+		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+			p.P(`func Test`, ccTypeName, sizeName, `(t *`, testingPkg.Use(), `.T) {`)
+			p.In()
+			p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`)
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`)
+			p.P(`p := NewPopulated`, ccTypeName, `(popr, true)`)
+			p.P(`size2 := `, protoPkg.Use(), `.Size(p)`)
+			p.P(`dAtA, err := `, protoPkg.Use(), `.Marshal(p)`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`size := p.`, sizeName, `()`)
+			p.P(`if len(dAtA) != size {`)
+			p.In()
+			p.P(`t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(dAtA))`)
+			p.Out()
+			p.P(`}`)
+			p.P(`if size2 != size {`)
+			p.In()
+			p.P(`t.Errorf("seed = %d, size %v != before marshal proto.Size %v", seed, size, size2)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`size3 := `, protoPkg.Use(), `.Size(p)`)
+			p.P(`if size3 != size {`)
+			p.In()
+			p.P(`t.Errorf("seed = %d, size %v != after marshal proto.Size %v", seed, size, size3)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+			p.P()
+		}
+
+		if gogoproto.HasBenchGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+			p.P(`func Benchmark`, ccTypeName, sizeName, `(b *`, testingPkg.Use(), `.B) {`)
+			p.In()
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(616))`)
+			p.P(`total := 0`)
+			p.P(`pops := make([]*`, ccTypeName, `, 1000)`)
+			p.P(`for i := 0; i < 1000; i++ {`)
+			p.In()
+			p.P(`pops[i] = NewPopulated`, ccTypeName, `(popr, false)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`b.ResetTimer()`)
+			p.P(`for i := 0; i < b.N; i++ {`)
+			p.In()
+			p.P(`total += pops[i%1000].`, sizeName, `()`)
+			p.Out()
+			p.P(`}`)
+			p.P(`b.SetBytes(int64(total / b.N))`)
+			p.Out()
+			p.P(`}`)
+			p.P()
+		}
+
+	}
+	return used
+}
+
+func init() {
+	testgen.RegisterTestPlugin(NewTest)
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/stringer/stringertest.go b/vendor/github.com/gogo/protobuf/plugin/stringer/stringertest.go
new file mode 100644
index 0000000000000..0912a22df638e
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/stringer/stringertest.go
@@ -0,0 +1,83 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 stringer
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/plugin/testgen"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type test struct {
+	*generator.Generator
+}
+
+func NewTest(g *generator.Generator) testgen.TestPlugin {
+	return &test{g}
+}
+
+func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	randPkg := imports.NewImport("math/rand")
+	timePkg := imports.NewImport("time")
+	testingPkg := imports.NewImport("testing")
+	fmtPkg := imports.NewImport("fmt")
+	for _, message := range file.Messages() {
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		if !gogoproto.IsStringer(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+
+		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+			p.P(`func Test`, ccTypeName, `Stringer(t *`, testingPkg.Use(), `.T) {`)
+			p.In()
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
+			p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
+			p.P(`s1 := p.String()`)
+			p.P(`s2 := `, fmtPkg.Use(), `.Sprintf("%v", p)`)
+			p.P(`if s1 != s2 {`)
+			p.In()
+			p.P(`t.Fatalf("String want %v got %v", s1, s2)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+		}
+
+	}
+	return used
+}
+
+func init() {
+	testgen.RegisterTestPlugin(NewTest)
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/testgen/testgen.go b/vendor/github.com/gogo/protobuf/plugin/testgen/testgen.go
new file mode 100644
index 0000000000000..e0a9287e56006
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/testgen/testgen.go
@@ -0,0 +1,608 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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.
+
+/*
+The testgen plugin generates Test and Benchmark functions for each message.
+
+Tests are enabled using the following extensions:
+
+  - testgen
+  - testgen_all
+
+Benchmarks are enabled using the following extensions:
+
+  - benchgen
+  - benchgen_all
+
+Let us look at:
+
+  github.com/gogo/protobuf/test/example/example.proto
+
+Btw all the output can be seen at:
+
+  github.com/gogo/protobuf/test/example/*
+
+The following message:
+
+  option (gogoproto.testgen_all) = true;
+  option (gogoproto.benchgen_all) = true;
+
+  message A {
+	optional string Description = 1 [(gogoproto.nullable) = false];
+	optional int64 Number = 2 [(gogoproto.nullable) = false];
+	optional bytes Id = 3 [(gogoproto.customtype) = "github.com/gogo/protobuf/test/custom.Uuid", (gogoproto.nullable) = false];
+  }
+
+given to the testgen plugin, will generate the following test code:
+
+	func TestAProto(t *testing.T) {
+		popr := math_rand.New(math_rand.NewSource(time.Now().UnixNano()))
+		p := NewPopulatedA(popr, false)
+		dAtA, err := github_com_gogo_protobuf_proto.Marshal(p)
+		if err != nil {
+			panic(err)
+		}
+		msg := &A{}
+		if err := github_com_gogo_protobuf_proto.Unmarshal(dAtA, msg); err != nil {
+			panic(err)
+		}
+		for i := range dAtA {
+			dAtA[i] = byte(popr.Intn(256))
+		}
+		if err := p.VerboseEqual(msg); err != nil {
+			t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err)
+		}
+		if !p.Equal(msg) {
+			t.Fatalf("%#v !Proto %#v", msg, p)
+		}
+	}
+
+	func BenchmarkAProtoMarshal(b *testing.B) {
+		popr := math_rand.New(math_rand.NewSource(616))
+		total := 0
+		pops := make([]*A, 10000)
+		for i := 0; i < 10000; i++ {
+			pops[i] = NewPopulatedA(popr, false)
+		}
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			dAtA, err := github_com_gogo_protobuf_proto.Marshal(pops[i%10000])
+			if err != nil {
+				panic(err)
+			}
+			total += len(dAtA)
+		}
+		b.SetBytes(int64(total / b.N))
+	}
+
+	func BenchmarkAProtoUnmarshal(b *testing.B) {
+		popr := math_rand.New(math_rand.NewSource(616))
+		total := 0
+		datas := make([][]byte, 10000)
+		for i := 0; i < 10000; i++ {
+			dAtA, err := github_com_gogo_protobuf_proto.Marshal(NewPopulatedA(popr, false))
+			if err != nil {
+				panic(err)
+			}
+			datas[i] = dAtA
+		}
+		msg := &A{}
+		b.ResetTimer()
+		for i := 0; i < b.N; i++ {
+			total += len(datas[i%10000])
+			if err := github_com_gogo_protobuf_proto.Unmarshal(datas[i%10000], msg); err != nil {
+				panic(err)
+			}
+		}
+		b.SetBytes(int64(total / b.N))
+	}
+
+
+	func TestAJSON(t *testing1.T) {
+		popr := math_rand1.New(math_rand1.NewSource(time1.Now().UnixNano()))
+		p := NewPopulatedA(popr, true)
+		jsondata, err := encoding_json.Marshal(p)
+		if err != nil {
+			panic(err)
+		}
+		msg := &A{}
+		err = encoding_json.Unmarshal(jsondata, msg)
+		if err != nil {
+			panic(err)
+		}
+		if err := p.VerboseEqual(msg); err != nil {
+			t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err)
+		}
+		if !p.Equal(msg) {
+			t.Fatalf("%#v !Json Equal %#v", msg, p)
+		}
+	}
+
+	func TestAProtoText(t *testing2.T) {
+		popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano()))
+		p := NewPopulatedA(popr, true)
+		dAtA := github_com_gogo_protobuf_proto1.MarshalTextString(p)
+		msg := &A{}
+		if err := github_com_gogo_protobuf_proto1.UnmarshalText(dAtA, msg); err != nil {
+			panic(err)
+		}
+		if err := p.VerboseEqual(msg); err != nil {
+			t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err)
+		}
+		if !p.Equal(msg) {
+			t.Fatalf("%#v !Proto %#v", msg, p)
+		}
+	}
+
+	func TestAProtoCompactText(t *testing2.T) {
+		popr := math_rand2.New(math_rand2.NewSource(time2.Now().UnixNano()))
+		p := NewPopulatedA(popr, true)
+		dAtA := github_com_gogo_protobuf_proto1.CompactTextString(p)
+		msg := &A{}
+		if err := github_com_gogo_protobuf_proto1.UnmarshalText(dAtA, msg); err != nil {
+			panic(err)
+		}
+		if err := p.VerboseEqual(msg); err != nil {
+			t.Fatalf("%#v !VerboseProto %#v, since %v", msg, p, err)
+		}
+		if !p.Equal(msg) {
+			t.Fatalf("%#v !Proto %#v", msg, p)
+		}
+	}
+
+Other registered tests are also generated.
+Tests are registered to this test plugin by calling the following function.
+
+  func RegisterTestPlugin(newFunc NewTestPlugin)
+
+where NewTestPlugin is:
+
+  type NewTestPlugin func(g *generator.Generator) TestPlugin
+
+and TestPlugin is an interface:
+
+  type TestPlugin interface {
+	Generate(imports generator.PluginImports, file *generator.FileDescriptor) (used bool)
+  }
+
+Plugins that use this interface include:
+
+  - populate
+  - gostring
+  - equal
+  - union
+  - and more
+
+Please look at these plugins as examples of how to create your own.
+A good idea is to let each plugin generate its own tests.
+
+*/
+package testgen
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type TestPlugin interface {
+	Generate(imports generator.PluginImports, file *generator.FileDescriptor) (used bool)
+}
+
+type NewTestPlugin func(g *generator.Generator) TestPlugin
+
+var testplugins = make([]NewTestPlugin, 0)
+
+func RegisterTestPlugin(newFunc NewTestPlugin) {
+	testplugins = append(testplugins, newFunc)
+}
+
+type plugin struct {
+	*generator.Generator
+	generator.PluginImports
+	tests []TestPlugin
+}
+
+func NewPlugin() *plugin {
+	return &plugin{}
+}
+
+func (p *plugin) Name() string {
+	return "testgen"
+}
+
+func (p *plugin) Init(g *generator.Generator) {
+	p.Generator = g
+	p.tests = make([]TestPlugin, 0, len(testplugins))
+	for i := range testplugins {
+		p.tests = append(p.tests, testplugins[i](g))
+	}
+}
+
+func (p *plugin) Generate(file *generator.FileDescriptor) {
+	p.PluginImports = generator.NewPluginImports(p.Generator)
+	atLeastOne := false
+	for i := range p.tests {
+		used := p.tests[i].Generate(p.PluginImports, file)
+		if used {
+			atLeastOne = true
+		}
+	}
+	if atLeastOne {
+		p.P(`//These tests are generated by github.com/gogo/protobuf/plugin/testgen`)
+	}
+}
+
+type testProto struct {
+	*generator.Generator
+}
+
+func newProto(g *generator.Generator) TestPlugin {
+	return &testProto{g}
+}
+
+func (p *testProto) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	testingPkg := imports.NewImport("testing")
+	randPkg := imports.NewImport("math/rand")
+	timePkg := imports.NewImport("time")
+	protoPkg := imports.NewImport("github.com/gogo/protobuf/proto")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		protoPkg = imports.NewImport("github.com/golang/protobuf/proto")
+	}
+	for _, message := range file.Messages() {
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+
+			p.P(`func Test`, ccTypeName, `Proto(t *`, testingPkg.Use(), `.T) {`)
+			p.In()
+			p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`)
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`)
+			p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
+			p.P(`dAtA, err := `, protoPkg.Use(), `.Marshal(p)`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`msg := &`, ccTypeName, `{}`)
+			p.P(`if err := `, protoPkg.Use(), `.Unmarshal(dAtA, msg); err != nil {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`littlefuzz := make([]byte, len(dAtA))`)
+			p.P(`copy(littlefuzz, dAtA)`)
+			p.P(`for i := range dAtA {`)
+			p.In()
+			p.P(`dAtA[i] = byte(popr.Intn(256))`)
+			p.Out()
+			p.P(`}`)
+			if gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P(`if err := p.VerboseEqual(msg); err != nil {`)
+				p.In()
+				p.P(`t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err)`)
+				p.Out()
+				p.P(`}`)
+			}
+			p.P(`if !p.Equal(msg) {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`if len(littlefuzz) > 0 {`)
+			p.In()
+			p.P(`fuzzamount := 100`)
+			p.P(`for i := 0; i < fuzzamount; i++ {`)
+			p.In()
+			p.P(`littlefuzz[popr.Intn(len(littlefuzz))] = byte(popr.Intn(256))`)
+			p.P(`littlefuzz = append(littlefuzz, byte(popr.Intn(256)))`)
+			p.Out()
+			p.P(`}`)
+			p.P(`// shouldn't panic`)
+			p.P(`_ = `, protoPkg.Use(), `.Unmarshal(littlefuzz, msg)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+			p.P()
+		}
+
+		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			if gogoproto.IsMarshaler(file.FileDescriptorProto, message.DescriptorProto) || gogoproto.IsUnsafeMarshaler(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P(`func Test`, ccTypeName, `MarshalTo(t *`, testingPkg.Use(), `.T) {`)
+				p.In()
+				p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`)
+				p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`)
+				p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
+				if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
+					p.P(`size := p.ProtoSize()`)
+				} else {
+					p.P(`size := p.Size()`)
+				}
+				p.P(`dAtA := make([]byte, size)`)
+				p.P(`for i := range dAtA {`)
+				p.In()
+				p.P(`dAtA[i] = byte(popr.Intn(256))`)
+				p.Out()
+				p.P(`}`)
+				p.P(`_, err := p.MarshalTo(dAtA)`)
+				p.P(`if err != nil {`)
+				p.In()
+				p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
+				p.Out()
+				p.P(`}`)
+				p.P(`msg := &`, ccTypeName, `{}`)
+				p.P(`if err := `, protoPkg.Use(), `.Unmarshal(dAtA, msg); err != nil {`)
+				p.In()
+				p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
+				p.Out()
+				p.P(`}`)
+				p.P(`for i := range dAtA {`)
+				p.In()
+				p.P(`dAtA[i] = byte(popr.Intn(256))`)
+				p.Out()
+				p.P(`}`)
+				if gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
+					p.P(`if err := p.VerboseEqual(msg); err != nil {`)
+					p.In()
+					p.P(`t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err)`)
+					p.Out()
+					p.P(`}`)
+				}
+				p.P(`if !p.Equal(msg) {`)
+				p.In()
+				p.P(`t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)`)
+				p.Out()
+				p.P(`}`)
+				p.Out()
+				p.P(`}`)
+				p.P()
+			}
+		}
+
+		if gogoproto.HasBenchGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+			p.P(`func Benchmark`, ccTypeName, `ProtoMarshal(b *`, testingPkg.Use(), `.B) {`)
+			p.In()
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(616))`)
+			p.P(`total := 0`)
+			p.P(`pops := make([]*`, ccTypeName, `, 10000)`)
+			p.P(`for i := 0; i < 10000; i++ {`)
+			p.In()
+			p.P(`pops[i] = NewPopulated`, ccTypeName, `(popr, false)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`b.ResetTimer()`)
+			p.P(`for i := 0; i < b.N; i++ {`)
+			p.In()
+			p.P(`dAtA, err := `, protoPkg.Use(), `.Marshal(pops[i%10000])`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`panic(err)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`total += len(dAtA)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`b.SetBytes(int64(total / b.N))`)
+			p.Out()
+			p.P(`}`)
+			p.P()
+
+			p.P(`func Benchmark`, ccTypeName, `ProtoUnmarshal(b *`, testingPkg.Use(), `.B) {`)
+			p.In()
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(616))`)
+			p.P(`total := 0`)
+			p.P(`datas := make([][]byte, 10000)`)
+			p.P(`for i := 0; i < 10000; i++ {`)
+			p.In()
+			p.P(`dAtA, err := `, protoPkg.Use(), `.Marshal(NewPopulated`, ccTypeName, `(popr, false))`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`panic(err)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`datas[i] = dAtA`)
+			p.Out()
+			p.P(`}`)
+			p.P(`msg := &`, ccTypeName, `{}`)
+			p.P(`b.ResetTimer()`)
+			p.P(`for i := 0; i < b.N; i++ {`)
+			p.In()
+			p.P(`total += len(datas[i%10000])`)
+			p.P(`if err := `, protoPkg.Use(), `.Unmarshal(datas[i%10000], msg); err != nil {`)
+			p.In()
+			p.P(`panic(err)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+			p.P(`b.SetBytes(int64(total / b.N))`)
+			p.Out()
+			p.P(`}`)
+			p.P()
+		}
+	}
+	return used
+}
+
+type testJson struct {
+	*generator.Generator
+}
+
+func newJson(g *generator.Generator) TestPlugin {
+	return &testJson{g}
+}
+
+func (p *testJson) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	testingPkg := imports.NewImport("testing")
+	randPkg := imports.NewImport("math/rand")
+	timePkg := imports.NewImport("time")
+	jsonPkg := imports.NewImport("github.com/gogo/protobuf/jsonpb")
+	for _, message := range file.Messages() {
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+			p.P(`func Test`, ccTypeName, `JSON(t *`, testingPkg.Use(), `.T) {`)
+			p.In()
+			p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`)
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`)
+			p.P(`p := NewPopulated`, ccTypeName, `(popr, true)`)
+			p.P(`marshaler := `, jsonPkg.Use(), `.Marshaler{}`)
+			p.P(`jsondata, err := marshaler.MarshalToString(p)`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
+			p.Out()
+			p.P(`}`)
+			p.P(`msg := &`, ccTypeName, `{}`)
+			p.P(`err = `, jsonPkg.Use(), `.UnmarshalString(jsondata, msg)`)
+			p.P(`if err != nil {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
+			p.Out()
+			p.P(`}`)
+			if gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P(`if err := p.VerboseEqual(msg); err != nil {`)
+				p.In()
+				p.P(`t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err)`)
+				p.Out()
+				p.P(`}`)
+			}
+			p.P(`if !p.Equal(msg) {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, %#v !Json Equal %#v", seed, msg, p)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+		}
+	}
+	return used
+}
+
+type testText struct {
+	*generator.Generator
+}
+
+func newText(g *generator.Generator) TestPlugin {
+	return &testText{g}
+}
+
+func (p *testText) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	testingPkg := imports.NewImport("testing")
+	randPkg := imports.NewImport("math/rand")
+	timePkg := imports.NewImport("time")
+	protoPkg := imports.NewImport("github.com/gogo/protobuf/proto")
+	if !gogoproto.ImportsGoGoProto(file.FileDescriptorProto) {
+		protoPkg = imports.NewImport("github.com/golang/protobuf/proto")
+	}
+	//fmtPkg := imports.NewImport("fmt")
+	for _, message := range file.Messages() {
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			used = true
+
+			p.P(`func Test`, ccTypeName, `ProtoText(t *`, testingPkg.Use(), `.T) {`)
+			p.In()
+			p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`)
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`)
+			p.P(`p := NewPopulated`, ccTypeName, `(popr, true)`)
+			p.P(`dAtA := `, protoPkg.Use(), `.MarshalTextString(p)`)
+			p.P(`msg := &`, ccTypeName, `{}`)
+			p.P(`if err := `, protoPkg.Use(), `.UnmarshalText(dAtA, msg); err != nil {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
+			p.Out()
+			p.P(`}`)
+			if gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P(`if err := p.VerboseEqual(msg); err != nil {`)
+				p.In()
+				p.P(`t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err)`)
+				p.Out()
+				p.P(`}`)
+			}
+			p.P(`if !p.Equal(msg) {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+			p.P()
+
+			p.P(`func Test`, ccTypeName, `ProtoCompactText(t *`, testingPkg.Use(), `.T) {`)
+			p.In()
+			p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`)
+			p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`)
+			p.P(`p := NewPopulated`, ccTypeName, `(popr, true)`)
+			p.P(`dAtA := `, protoPkg.Use(), `.CompactTextString(p)`)
+			p.P(`msg := &`, ccTypeName, `{}`)
+			p.P(`if err := `, protoPkg.Use(), `.UnmarshalText(dAtA, msg); err != nil {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
+			p.Out()
+			p.P(`}`)
+			if gogoproto.HasVerboseEqual(file.FileDescriptorProto, message.DescriptorProto) {
+				p.P(`if err := p.VerboseEqual(msg); err != nil {`)
+				p.In()
+				p.P(`t.Fatalf("seed = %d, %#v !VerboseProto %#v, since %v", seed, msg, p, err)`)
+				p.Out()
+				p.P(`}`)
+			}
+			p.P(`if !p.Equal(msg) {`)
+			p.In()
+			p.P(`t.Fatalf("seed = %d, %#v !Proto %#v", seed, msg, p)`)
+			p.Out()
+			p.P(`}`)
+			p.Out()
+			p.P(`}`)
+			p.P()
+
+		}
+	}
+	return used
+}
+
+func init() {
+	RegisterTestPlugin(newProto)
+	RegisterTestPlugin(newJson)
+	RegisterTestPlugin(newText)
+}
diff --git a/vendor/github.com/gogo/protobuf/plugin/union/uniontest.go b/vendor/github.com/gogo/protobuf/plugin/union/uniontest.go
new file mode 100644
index 0000000000000..949cf8338501e
--- /dev/null
+++ b/vendor/github.com/gogo/protobuf/plugin/union/uniontest.go
@@ -0,0 +1,86 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// http://github.com/gogo/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//
+// 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 union
+
+import (
+	"github.com/gogo/protobuf/gogoproto"
+	"github.com/gogo/protobuf/plugin/testgen"
+	"github.com/gogo/protobuf/protoc-gen-gogo/generator"
+)
+
+type test struct {
+	*generator.Generator
+}
+
+func NewTest(g *generator.Generator) testgen.TestPlugin {
+	return &test{g}
+}
+
+func (p *test) Generate(imports generator.PluginImports, file *generator.FileDescriptor) bool {
+	used := false
+	randPkg := imports.NewImport("math/rand")
+	timePkg := imports.NewImport("time")
+	testingPkg := imports.NewImport("testing")
+	for _, message := range file.Messages() {
+		if !gogoproto.IsUnion(file.FileDescriptorProto, message.DescriptorProto) ||
+			!gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
+			continue
+		}
+		if message.DescriptorProto.GetOptions().GetMapEntry() {
+			continue
+		}
+		used = true
+		ccTypeName := generator.CamelCaseSlice(message.TypeName())
+
+		p.P(`func Test`, ccTypeName, `OnlyOne(t *`, testingPkg.Use(), `.T) {`)
+		p.In()
+		p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(`, timePkg.Use(), `.Now().UnixNano()))`)
+		p.P(`p := NewPopulated`, ccTypeName, `(popr, true)`)
+		p.P(`v := p.GetValue()`)
+		p.P(`msg := &`, ccTypeName, `{}`)
+		p.P(`if !msg.SetValue(v) {`)
+		p.In()
+		p.P(`t.Fatalf("OnlyOne: Could not set Value")`)
+		p.Out()
+		p.P(`}`)
+		p.P(`if !p.Equal(msg) {`)
+		p.In()
+		p.P(`t.Fatalf("%#v !OnlyOne Equal %#v", msg, p)`)
+		p.Out()
+		p.P(`}`)
+		p.Out()
+		p.P(`}`)
+
+	}
+	return used
+}
+
+func init() {
+	testgen.RegisterTestPlugin(NewTest)
+}