Browse Source

go modified

Tobias von Dewitz 5 năm trước cách đây
mục cha
commit
362fdc9fb2
100 tập tin đã thay đổi với 13563 bổ sung6169 xóa
  1. 2 0
      .gitignore
  2. 5 2
      apache.go
  3. 36 0
      go.mod
  4. 110 0
      go.sum
  5. 0 22
      main.go
  6. 2 0
      rpc.go
  7. 4 2
      vendor/git.scraperwall.com/scw/geoip/geoip.go
  8. 0 0
      vendor/git.scraperwall.com/scw/grpc/scw/request.proto
  9. 0 142
      vendor/git.scraperwall.com/scw/grpc/scw/scw.pb.go
  10. 0 48
      vendor/git.scraperwall.com/scw/grpc/scw/scw.proto
  11. 10 1
      vendor/git.scraperwall.com/scw/ip/ip.go
  12. 5 0
      vendor/github.com/BurntSushi/toml/.gitignore
  13. 15 0
      vendor/github.com/BurntSushi/toml/.travis.yml
  14. 9 0
      vendor/github.com/Songmu/axslogparser/.travis.yml
  15. 1 1
      vendor/github.com/Songmu/axslogparser/Makefile
  16. 18 19
      vendor/github.com/Songmu/axslogparser/axslogparser.go
  17. 1 1
      vendor/github.com/Songmu/axslogparser/ltsv.go
  18. 5 0
      vendor/github.com/Songmu/go-ltsv/.gitignore
  19. 8 0
      vendor/github.com/Songmu/go-ltsv/.travis.yml
  20. 1 1
      vendor/github.com/Songmu/go-ltsv/Makefile
  21. 15 0
      vendor/github.com/gogo/protobuf/AUTHORS
  22. 23 0
      vendor/github.com/gogo/protobuf/CONTRIBUTORS
  23. 2 3
      vendor/github.com/gogo/protobuf/LICENSE
  24. 2 2
      vendor/github.com/gogo/protobuf/proto/Makefile
  25. 35 11
      vendor/github.com/gogo/protobuf/proto/clone.go
  26. 14 10
      vendor/github.com/gogo/protobuf/proto/custom_gogo.go
  27. 63 613
      vendor/github.com/gogo/protobuf/proto/decode.go
  28. 0 172
      vendor/github.com/gogo/protobuf/proto/decode_gogo.go
  29. 200 1
      vendor/github.com/gogo/protobuf/proto/discard.go
  30. 0 154
      vendor/github.com/gogo/protobuf/proto/duration_gogo.go
  31. 25 1184
      vendor/github.com/gogo/protobuf/proto/encode.go
  32. 0 317
      vendor/github.com/gogo/protobuf/proto/encode_gogo.go
  33. 15 15
      vendor/github.com/gogo/protobuf/proto/equal.go
  34. 97 186
      vendor/github.com/gogo/protobuf/proto/extensions.go
  35. 118 44
      vendor/github.com/gogo/protobuf/proto/extensions_gogo.go
  36. 118 28
      vendor/github.com/gogo/protobuf/proto/lib.go
  37. 8 0
      vendor/github.com/gogo/protobuf/proto/lib_gogo.go
  38. 42 39
      vendor/github.com/gogo/protobuf/proto/message_set.go
  39. 234 361
      vendor/github.com/gogo/protobuf/proto/pointer_reflect.go
  40. 19 45
      vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go
  41. 202 164
      vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go
  42. 14 86
      vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go
  43. 69 432
      vendor/github.com/gogo/protobuf/proto/properties.go
  44. 3 78
      vendor/github.com/gogo/protobuf/proto/properties_gogo.go
  45. 3006 0
      vendor/github.com/gogo/protobuf/proto/table_marshal.go
  46. 388 0
      vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go
  47. 657 0
      vendor/github.com/gogo/protobuf/proto/table_merge.go
  48. 2245 0
      vendor/github.com/gogo/protobuf/proto/table_unmarshal.go
  49. 385 0
      vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go
  50. 27 38
      vendor/github.com/gogo/protobuf/proto/text.go
  51. 54 49
      vendor/github.com/gogo/protobuf/proto/text_parser.go
  52. 0 180
      vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go
  53. 1888 0
      vendor/github.com/gogo/protobuf/proto/wrappers.go
  54. 113 0
      vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go
  55. 3 0
      vendor/github.com/golang/protobuf/AUTHORS
  56. 3 0
      vendor/github.com/golang/protobuf/CONTRIBUTORS
  57. 0 15
      vendor/github.com/golang/protobuf/proto/encode.go
  58. 60 2
      vendor/github.com/golang/protobuf/proto/lib.go
  59. 59 47
      vendor/github.com/golang/protobuf/proto/table_marshal.go
  60. 26 23
      vendor/github.com/golang/protobuf/proto/table_unmarshal.go
  61. 0 141
      vendor/github.com/golang/protobuf/ptypes/any.go
  62. 0 191
      vendor/github.com/golang/protobuf/ptypes/any/any.pb.go
  63. 0 149
      vendor/github.com/golang/protobuf/ptypes/any/any.proto
  64. 0 102
      vendor/github.com/golang/protobuf/ptypes/duration.go
  65. 0 159
      vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go
  66. 0 117
      vendor/github.com/golang/protobuf/ptypes/duration/duration.proto
  67. 0 134
      vendor/github.com/golang/protobuf/ptypes/timestamp.go
  68. 0 175
      vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go
  69. 0 133
      vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
  70. 1 0
      vendor/github.com/google/btree/.travis.yml
  71. 15 6
      vendor/github.com/google/btree/btree.go
  72. 38 0
      vendor/github.com/google/gopacket/.gitignore
  73. 7 0
      vendor/github.com/google/gopacket/.travis.gofmt.sh
  74. 28 0
      vendor/github.com/google/gopacket/.travis.golint.sh
  75. 10 0
      vendor/github.com/google/gopacket/.travis.govet.sh
  76. 18 0
      vendor/github.com/google/gopacket/.travis.yml
  77. 5 0
      vendor/github.com/google/gopacket/AUTHORS
  78. 2 0
      vendor/github.com/google/gopacket/README.md
  79. 6 1
      vendor/github.com/google/gopacket/doc.go
  80. 9 0
      vendor/github.com/google/gopacket/gc
  81. 39 0
      vendor/github.com/google/gopacket/layers/.lint_blacklist
  82. 24 11
      vendor/github.com/google/gopacket/layers/dhcpv4.go
  83. 341 0
      vendor/github.com/google/gopacket/layers/dhcpv6.go
  84. 621 0
      vendor/github.com/google/gopacket/layers/dhcpv6_options.go
  85. 37 17
      vendor/github.com/google/gopacket/layers/dns.go
  86. 732 57
      vendor/github.com/google/gopacket/layers/dot11.go
  87. 236 0
      vendor/github.com/google/gopacket/layers/eapol.go
  88. 16 0
      vendor/github.com/google/gopacket/layers/enums.go
  89. 1 0
      vendor/github.com/google/gopacket/layers/ethernet.go
  90. 18 6
      vendor/github.com/google/gopacket/layers/geneve.go
  91. 20 5
      vendor/github.com/google/gopacket/layers/gre.go
  92. 181 0
      vendor/github.com/google/gopacket/layers/gtp.go
  93. 25 0
      vendor/github.com/google/gopacket/layers/icmp6.go
  94. 85 2
      vendor/github.com/google/gopacket/layers/icmp6msg.go
  95. 20 6
      vendor/github.com/google/gopacket/layers/ip4.go
  96. 124 67
      vendor/github.com/google/gopacket/layers/ip6.go
  97. 146 120
      vendor/github.com/google/gopacket/layers/layertypes.go
  98. 213 0
      vendor/github.com/google/gopacket/layers/lcm.go
  99. 2 0
      vendor/github.com/google/gopacket/layers/linux_sll.go
  100. 79 32
      vendor/github.com/google/gopacket/layers/llc.go

+ 2 - 0
.gitignore

@@ -2,3 +2,5 @@
 /*.csv
 /m
 *.rpm
+/debian
+/rpms

+ 5 - 2
apache.go

@@ -2,6 +2,7 @@ package main
 
 import (
 	"bufio"
+	"fmt"
 	"log"
 	"net"
 	"os"
@@ -58,11 +59,13 @@ func apacheLogReplay(logfile string) {
 			time.Sleep(ts.Sub(time.Now()))
 		}
 
-		//pretty.Println(logEntry)
 		remote := logEntry.Host
 
 		if logEntry.VirtualHost != "" && config.UseVhostAsSource {
-			logEntry.VirtualHost = logEntry.VirtualHost[0:strings.Index(logEntry.VirtualHost, ",")]
+			commaIdx := strings.Index(logEntry.VirtualHost, ",")
+			if commaIdx > 0 {
+				logEntry.VirtualHost = logEntry.VirtualHost[0:commaIdx]
+			}
 			vhIP := net.ParseIP(logEntry.VirtualHost)
 			if vhIP != nil {
 				remote = logEntry.VirtualHost

+ 36 - 0
go.mod

@@ -0,0 +1,36 @@
+module git.scraperwall.com/scw/munchclient
+
+go 1.12
+
+require (
+	git.scraperwall.com/scw/ajp13 v0.0.0-20171106085938-4990ad476f28
+	git.scraperwall.com/scw/data v0.0.0-20180511082704-c25adfdbe44c
+	git.scraperwall.com/scw/geoip v1.0.2 // indirect
+	git.scraperwall.com/scw/grs v0.0.0-20170601133330-3236d4163146 // indirect
+	git.scraperwall.com/scw/ip v0.0.0-20181127150108-80dbbe18947e
+	github.com/BurntSushi/toml v0.3.1
+	github.com/Songmu/axslogparser v1.1.0
+	github.com/Songmu/go-ltsv v0.0.0-20181014062614-c30af2b7b171 // indirect
+	github.com/fsnotify/fsnotify v1.4.7 // indirect
+	github.com/google/btree v1.0.0 // indirect
+	github.com/google/gopacket v1.1.16
+	github.com/hpcloud/tail v1.0.0
+	github.com/jmcvetta/randutil v0.0.0-20150817122601-2bb1b664bcff // indirect
+	github.com/kr/pretty v0.1.0
+	github.com/mdlayher/raw v0.0.0-20190329140802-b0647ab7d8b3 // indirect
+	github.com/nats-io/gnatsd v1.4.1 // indirect
+	github.com/nats-io/go-nats v1.7.2 // indirect
+	github.com/nats-io/nats v1.7.2
+	github.com/nats-io/nkeys v0.0.2 // indirect
+	github.com/nats-io/nuid v1.0.1 // indirect
+	github.com/oschwald/geoip2-golang v1.2.1 // indirect
+	github.com/oschwald/maxminddb-golang v1.3.0 // indirect
+	github.com/pkg/errors v0.8.1 // indirect
+	github.com/satyrius/gonx v1.3.0
+	github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a // indirect
+	github.com/stretchr/testify v1.3.0 // indirect
+	google.golang.org/grpc v1.20.0 // indirect
+	gopkg.in/fsnotify.v1 v1.4.7 // indirect
+	gopkg.in/jmcvetta/napping.v3 v3.2.0 // indirect
+	gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
+)

+ 110 - 0
go.sum

@@ -0,0 +1,110 @@
+cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+git.scraperwall.com/scw/ajp13 v0.0.0-20171106085938-4990ad476f28 h1:sR9UeRyKZXzhgPsw4n1ss1Ne5zFbWiktd0a1xkFXaqY=
+git.scraperwall.com/scw/ajp13 v0.0.0-20171106085938-4990ad476f28/go.mod h1:HN1+zzxE2xkDTolr1MYEA3xkQDRofjAtwtAzyjQdhGc=
+git.scraperwall.com/scw/data v0.0.0-20180511082704-c25adfdbe44c h1:5TkzqPwse/w4OwgBB8joPOp2kH4KLFUQSzzOnvfl1dk=
+git.scraperwall.com/scw/data v0.0.0-20180511082704-c25adfdbe44c/go.mod h1:rbNuPUyyuOZNI5iMhlc4U1EiIdVR6iR57gdGI46uLMk=
+git.scraperwall.com/scw/geoip v1.0.2 h1:QrJr6aFyyx+5MaCJVHN/K4a60GxvkoLxiGUbPSbLv9k=
+git.scraperwall.com/scw/geoip v1.0.2/go.mod h1:vF7pVykGjjAXUNS7wkh1nP97grLRnlrtIzu2XjFI+Mg=
+git.scraperwall.com/scw/grs v0.0.0-20170601133330-3236d4163146 h1:pmtzyKPIrtqUmcRuHL6sgP0R4QdSj1xpV78L1fbBvKc=
+git.scraperwall.com/scw/grs v0.0.0-20170601133330-3236d4163146/go.mod h1:tBzymrSfvUbefC/s0jnUtcHjpcZbH7+7f755VdGGhwM=
+git.scraperwall.com/scw/ip v0.0.0-20181127150108-80dbbe18947e h1:TJIzDykAwl9XbHGRGIp2gSKmUgCzhAcQDeEjXGSCblE=
+git.scraperwall.com/scw/ip v0.0.0-20181127150108-80dbbe18947e/go.mod h1:VWpgAIAUfNlojwRfuTrv2xh4EHYHSO0jV5CKEJyktrg=
+github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
+github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
+github.com/Songmu/axslogparser v1.1.0 h1:nbDhqGSl4xNwdEvtbg71+st6Zh2I/xN9COToOTjLndM=
+github.com/Songmu/axslogparser v1.1.0/go.mod h1:AYO6MiYqW5+dcL4Y+yTMD+WL2yKqFRYevLdfKPIHHQ0=
+github.com/Songmu/go-ltsv v0.0.0-20181014062614-c30af2b7b171 h1:nwdeQV2pNjaTv3os4N4/bKDqv0PxW/9DoEAdtW6sY9o=
+github.com/Songmu/go-ltsv v0.0.0-20181014062614-c30af2b7b171/go.mod h1:LBP+tS9C2iiUoR7AGPaZYY+kjXgB5eZxZKbSEBL9UFw=
+github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
+github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
+github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g=
+github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
+github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
+github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s=
+github.com/gogo/protobuf v1.2.0 h1:xU6/SpYbvkNYiptHJYEDRseDLvYE7wSqhYYNy0QSUzI=
+github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
+github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
+github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
+github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
+github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
+github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
+github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
+github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
+github.com/google/gopacket v1.1.16 h1:u6Afvia5C5srlLcbTwpHaFW918asLYPxieziOaWwz8M=
+github.com/google/gopacket v1.1.16/go.mod h1:UCLx9mCmAwsVbn6qQl1WIEt2SO7Nd2fD0th1TBAsqBw=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
+github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
+github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
+github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
+github.com/jmcvetta/randutil v0.0.0-20150817122601-2bb1b664bcff h1:6NvhExg4omUC9NfA+l4Oq3ibNNeJUdiAF3iBVB0PlDk=
+github.com/jmcvetta/randutil v0.0.0-20150817122601-2bb1b664bcff/go.mod h1:ddfPX8Z28YMjiqoaJhNBzWHapTHXejnB5cDCUWDwriw=
+github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
+github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
+github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
+github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
+github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
+github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
+github.com/mdlayher/raw v0.0.0-20190329140802-b0647ab7d8b3 h1:RuWlSPko24MJpXCcZT6pmgYqLnhTjuMlIWsMTHL3Y9M=
+github.com/mdlayher/raw v0.0.0-20190329140802-b0647ab7d8b3/go.mod h1:r1fbeITl2xL/zLbVnNHFyOzQJTgr/3fpf1lJX/cjzR8=
+github.com/nats-io/gnatsd v1.4.1 h1:RconcfDeWpKCD6QIIwiVFcvForlXpWeJP7i5/lDLy44=
+github.com/nats-io/gnatsd v1.4.1/go.mod h1:nqco77VO78hLCJpIcVfygDP2rPGfsEHkGTUk94uh5DQ=
+github.com/nats-io/go-nats v1.7.2 h1:cJujlwCYR8iMz5ofZSD/p2WLW8FabhkQ2lIEVbSvNSA=
+github.com/nats-io/go-nats v1.7.2/go.mod h1:+t7RHT5ApZebkrQdnn6AhQJmhJJiKAvJUio1PiiCtj0=
+github.com/nats-io/nats v1.7.2 h1:8hasuHgNFiDGc7MTkGpPFc0v1Jz1nEoQwIHKAH2hFuo=
+github.com/nats-io/nats v1.7.2/go.mod h1:PpmYZwlgTfBI56QypJLfIMOfLnMRuVs+VL6r8mQ2SoQ=
+github.com/nats-io/nkeys v0.0.2 h1:+qM7QpgXnvDDixitZtQUBDY9w/s9mu1ghS+JIbsrx6M=
+github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4=
+github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
+github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+github.com/oschwald/geoip2-golang v1.2.1 h1:3iz+jmeJc6fuCyWeKgtXSXu7+zvkxJbHFXkMT5FVebU=
+github.com/oschwald/geoip2-golang v1.2.1/go.mod h1:0LTTzix/Ao1uMvOhAV4iLU0Lz7eCrP94qZWBTDKf0iE=
+github.com/oschwald/maxminddb-golang v1.3.0 h1:oTh8IBSj10S5JNlUDg5WjJ1QdBMdeaZIkPEVfESSWgE=
+github.com/oschwald/maxminddb-golang v1.3.0/go.mod h1:3jhIUymTJ5VREKyIhWm66LJiQt04F0UCDdodShpjWsY=
+github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
+github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
+github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/satyrius/gonx v1.3.0 h1:FSAzv/VRWvF8EVBxm5Jtd6GLsEjIuaDxwctx6WpVSaY=
+github.com/satyrius/gonx v1.3.0/go.mod h1:+r8KNe5d2tjkZU+DfhERo0G6KxkGih+1qYF6tqLHwvk=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
+github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a h1:pa8hGb/2YqsZKovtsgrwcDH1RZhVbTKCjLp47XpqCDs=
+github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
+github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
+github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
+golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M=
+golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
+golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a h1:oWX7TPOiFAMXLq8o0ikBYfCJVlRHBcsciT5bXOrH628=
+golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/net v0.0.0-20190313220215-9f648a60d977 h1:actzWV6iWn3GLqN8dZjzsB+CLt+gaV2+wsxroxiQI8I=
+golang.org/x/net v0.0.0-20190313220215-9f648a60d977/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
+golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f h1:wMNYb4v58l5UBM7MYRLPG6ZhfOqbKu7X5eyFl8ZhKvA=
+golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
+golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313 h1:pczuHS43Cp2ktBEEmLwScxgjWsBSzdaQiKzUyf3DTTc=
+golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
+golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
+google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 h1:Nw54tB0rB7hY/N0NQvRW8DG4Yk3Q6T9cu9RcFQDu1tc=
+google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
+google.golang.org/grpc v1.20.0 h1:DlsSIrgEBuZAUFJcta2B5i/lzeHHbnfkNFAfFXLVFYQ=
+google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM=
+gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4=
+gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
+gopkg.in/jmcvetta/napping.v3 v3.2.0 h1:NpSZLAL6VgiyhdqaOkxwVtHXOLrQJZ6fFOMQgp7G8PQ=
+gopkg.in/jmcvetta/napping.v3 v3.2.0/go.mod h1:0dPR4/IGM4+xGT+e48O2yJlg6qofrONCtEAWkurVlZQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
+gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
+honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

+ 0 - 22
main.go

@@ -56,14 +56,12 @@ var (
 	hostName              = flag.String("hostname", "", "Override the captured hostname with this one")
 	accessWatchKey        = flag.String("access-watch-key", "", "access.watch API key")
 	configFile            = flag.String("config", "", "The location of the TOML config file")
-	rpcAddr               = flag.String("rpc-address", "", "The address where the RPC server is listening")
 
 	beQuiet   = flag.Bool("quiet", true, "Be quiet")
 	doVersion = flag.Bool("version", false, "Show version information")
 
 	natsEC          *nats.EncodedConn
 	natsJSONEC      *nats.EncodedConn
-	rpcClient       *ScwRPC
 	natsErrorChan   chan error
 	natsIsAvailable bool
 	count           uint64
@@ -104,7 +102,6 @@ type Config struct {
 	NginxReplay           string
 	HostName              string
 	AccessWatchKey        string
-	RPCAddress            string
 	ReconnectToNatsAfter  duration
 	ResetLiveCaptureAfter duration
 }
@@ -144,7 +141,6 @@ func (c Config) print() {
 	fmt.Printf("UseVhostAsSource:      %t\n", c.UseVhostAsSource)
 	fmt.Printf("Protocol:              %s\n", c.Protocol)
 	fmt.Printf("Reset Live Cap After:  %s\n", c.ResetLiveCaptureAfter.String())
-	fmt.Printf("RPCAddress:            %s\n", c.RPCAddress)
 	fmt.Printf("Quiet:                 %t\n", c.Quiet)
 	fmt.Printf("Trace:                 %t\n", c.Trace)
 }
@@ -204,15 +200,6 @@ func main() {
 
 	go natsWatchdog(natsErrorChan)
 
-	// RPC
-	//
-	if config.RPCAddress != "" {
-		rpcClient, err = NewScwRPC(config.RPCAddress)
-		if err != nil {
-			log.Fatal(err)
-		}
-	}
-
 	// What should I do?
 	if config.RequestsFile != "" {
 		replayFile()
@@ -439,14 +426,6 @@ func publishRequest(queue string, request *data.Request) {
 		return
 	}
 
-	if rpcClient != nil {
-		select {
-		case rpcClient.RChan <- request:
-		default:
-		}
-		return
-	}
-
 	if !natsIsAvailable {
 		if rand.Intn(100) == 0 {
 			log.Println("nats connection is not available")
@@ -783,7 +762,6 @@ func loadConfig() {
 	config.Quiet = *beQuiet
 	config.Trace = *trace
 	config.AccessWatchKey = *accessWatchKey
-	config.RPCAddress = *rpcAddr
 	config.ReconnectToNatsAfter.Duration = *reconnectToNatsAfter
 	config.ResetLiveCaptureAfter.Duration = *resetLiveCapAfter
 

+ 2 - 0
rpc.go

@@ -1,5 +1,6 @@
 package main
 
+/*
 import (
 	"context"
 	"log"
@@ -70,3 +71,4 @@ func NewScwRPC(addr string) (*ScwRPC, error) {
 
 	return s, nil
 }
+*/

+ 4 - 2
vendor/git.scraperwall.com/scw/geoip/geoip.go

@@ -19,8 +19,10 @@ import (
 )
 
 const (
-	dbURL    = "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz"
-	dbMd5URL = "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz.md5"
+	dbURL    = "https://files.phlip.it/GeoLite2-City.tar.gz"
+	dbMd5URL = "https://files.phlip.it/GeoLite2-City.tar.gz.md5"
+	//bURL    = "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz"
+	//dbMd5URL = "http://geolite.maxmind.com/download/geoip/database/GeoLite2-City.tar.gz.md5"
 )
 
 // Anonymous contains information about whether an IP address is anonymous

+ 0 - 0
vendor/git.scraperwall.com/scw/grpc/scw/request.proto


+ 0 - 142
vendor/git.scraperwall.com/scw/grpc/scw/scw.pb.go

@@ -1,142 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: scw.proto
-
-/*
-Package scwrpc is a generated protocol buffer package.
-
-It is generated from these files:
-	scw.proto
-
-It has these top-level messages:
-	RequestResult
-*/
-package scwrpc
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import math "math"
-import data "git.scraperwall.com/scw/data"
-
-import (
-	context "golang.org/x/net/context"
-	grpc "google.golang.org/grpc"
-)
-
-// 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.ProtoPackageIsVersion2 // please upgrade the proto package
-
-type RequestResult struct {
-	OK bool `protobuf:"varint,10,opt,name=OK" json:"OK,omitempty"`
-}
-
-func (m *RequestResult) Reset()                    { *m = RequestResult{} }
-func (m *RequestResult) String() string            { return proto.CompactTextString(m) }
-func (*RequestResult) ProtoMessage()               {}
-func (*RequestResult) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
-
-func (m *RequestResult) GetOK() bool {
-	if m != nil {
-		return m.OK
-	}
-	return false
-}
-
-func init() {
-	proto.RegisterType((*RequestResult)(nil), "scwrpc.RequestResult")
-}
-
-// Reference imports to suppress errors if they are not otherwise used.
-var _ context.Context
-var _ grpc.ClientConn
-
-// This is a compile-time assertion to ensure that this generated file
-// is compatible with the grpc package it is being compiled against.
-const _ = grpc.SupportPackageIsVersion4
-
-// Client API for SCWProtos service
-
-type SCWProtosClient interface {
-	SendRequest(ctx context.Context, in *data.Request, opts ...grpc.CallOption) (*RequestResult, error)
-}
-
-type sCWProtosClient struct {
-	cc *grpc.ClientConn
-}
-
-func NewSCWProtosClient(cc *grpc.ClientConn) SCWProtosClient {
-	return &sCWProtosClient{cc}
-}
-
-func (c *sCWProtosClient) SendRequest(ctx context.Context, in *data.Request, opts ...grpc.CallOption) (*RequestResult, error) {
-	out := new(RequestResult)
-	err := grpc.Invoke(ctx, "/scwrpc.SCWProtos/SendRequest", in, out, c.cc, opts...)
-	if err != nil {
-		return nil, err
-	}
-	return out, nil
-}
-
-// Server API for SCWProtos service
-
-type SCWProtosServer interface {
-	SendRequest(context.Context, *data.Request) (*RequestResult, error)
-}
-
-func RegisterSCWProtosServer(s *grpc.Server, srv SCWProtosServer) {
-	s.RegisterService(&_SCWProtos_serviceDesc, srv)
-}
-
-func _SCWProtos_SendRequest_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
-	in := new(data.Request)
-	if err := dec(in); err != nil {
-		return nil, err
-	}
-	if interceptor == nil {
-		return srv.(SCWProtosServer).SendRequest(ctx, in)
-	}
-	info := &grpc.UnaryServerInfo{
-		Server:     srv,
-		FullMethod: "/scwrpc.SCWProtos/SendRequest",
-	}
-	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
-		return srv.(SCWProtosServer).SendRequest(ctx, req.(*data.Request))
-	}
-	return interceptor(ctx, in, info, handler)
-}
-
-var _SCWProtos_serviceDesc = grpc.ServiceDesc{
-	ServiceName: "scwrpc.SCWProtos",
-	HandlerType: (*SCWProtosServer)(nil),
-	Methods: []grpc.MethodDesc{
-		{
-			MethodName: "SendRequest",
-			Handler:    _SCWProtos_SendRequest_Handler,
-		},
-	},
-	Streams:  []grpc.StreamDesc{},
-	Metadata: "scw.proto",
-}
-
-func init() { proto.RegisterFile("scw.proto", fileDescriptor0) }
-
-var fileDescriptor0 = []byte{
-	// 155 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0x2c, 0x4e, 0x2e, 0xd7,
-	0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0x2b, 0x4e, 0x2e, 0x2f, 0x2a, 0x48, 0x96, 0xe2, 0x2d,
-	0x4a, 0x2d, 0x2c, 0x4d, 0x2d, 0x2e, 0x81, 0x08, 0x2b, 0xc9, 0x73, 0xf1, 0x06, 0x41, 0x04, 0x82,
-	0x52, 0x8b, 0x4b, 0x73, 0x4a, 0x84, 0xf8, 0xb8, 0x98, 0xfc, 0xbd, 0x25, 0xb8, 0x14, 0x18, 0x35,
-	0x38, 0x82, 0x98, 0xfc, 0xbd, 0x8d, 0x9c, 0xb8, 0x38, 0x83, 0x9d, 0xc3, 0x03, 0x40, 0x8a, 0x8b,
-	0x85, 0x4c, 0xb9, 0xb8, 0x83, 0x53, 0xf3, 0x52, 0xa0, 0x3a, 0x84, 0x78, 0xf5, 0x52, 0x12, 0x4b,
-	0x12, 0xf5, 0xa0, 0x5c, 0x29, 0x51, 0x3d, 0x88, 0x1d, 0x7a, 0x28, 0x26, 0x2a, 0x31, 0x38, 0xa9,
-	0x72, 0x89, 0x25, 0xe7, 0xe7, 0xea, 0x15, 0x27, 0x17, 0x25, 0x16, 0xa4, 0x16, 0x95, 0x27, 0xe6,
-	0xe4, 0x40, 0x55, 0x3a, 0x21, 0xcc, 0x0e, 0x60, 0x4c, 0x62, 0x03, 0x3b, 0xc9, 0x18, 0x10, 0x00,
-	0x00, 0xff, 0xff, 0x94, 0xc6, 0x4e, 0x70, 0xb6, 0x00, 0x00, 0x00,
-}

+ 0 - 48
vendor/git.scraperwall.com/scw/grpc/scw/scw.proto

@@ -1,48 +0,0 @@
-syntax = "proto3";
-
-option java_multiple_files = true;
-option java_package = "com.scraperwall.scwrpc";
-option java_outer_classname = "SCWProtos";
-
-
-import "request.proto";
-
-package scwrpc;
-
-service SCWProtos {
-    rpc SendRequest(data.Request) returns (RequestResult) {}
-}
-
-
-message RequestResult {
-    bool OK = 10;
-}
-
-/*
-message Request2 {
-    string Url = 100;
-    string Reverse = 200;
-    string IpSrc = 300;
-    string IpDst = 400;
-    uint32 PortSrc = 500;
-    uint32 PortDst = 600;
-    uint32 TcpSeq = 700;
-    int64 CreatedAt = 800;
-    string XForwardedFor = 900;
-    string XRealIP = 1000;
-    string Method = 1100;
-    string Origin = 1200;
-    string Referer = 1300;
-    string UserAgent = 1400;
-    string Source = 1500;
-    string Host = 1600;
-    string Protocol = 1700;
-    string Connection = 1800;
-    string XRequestedWith = 1900;
-    string AcceptEncoding = 2000;
-    string AcceptLanguage = 2100;
-    string Accept = 2200;
-    string Cookie = 2300;
-    string Via = 2400;
-  }
-  */

+ 10 - 1
vendor/git.scraperwall.com/scw/ip/ip.go

@@ -2,7 +2,7 @@ package ip
 
 import "net"
 
-var PRIVATE_NETWORKS = [...]string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fd00::/8"}
+var PRIVATE_NETWORKS = [...]string{"10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16", "fd00::/8", "127.0.0.0/8"}
 
 type IP struct {
 	IP               net.IP
@@ -28,3 +28,12 @@ func (i *IP) IsPrivate(ip net.IP) bool {
 	}
 	return false
 }
+
+func (i *IP) Network(ip net.IP) *net.IPNet {
+	for _, n := range i.private_networks {
+		if n.Contains(ip) {
+			return n
+		}
+	}
+	return nil
+}

+ 5 - 0
vendor/github.com/BurntSushi/toml/.gitignore

@@ -0,0 +1,5 @@
+TAGS
+tags
+.*.swp
+tomlcheck/tomlcheck
+toml.test

+ 15 - 0
vendor/github.com/BurntSushi/toml/.travis.yml

@@ -0,0 +1,15 @@
+language: go
+go:
+  - 1.1
+  - 1.2
+  - 1.3
+  - 1.4
+  - 1.5
+  - 1.6
+  - tip
+install:
+  - go install ./...
+  - go get github.com/BurntSushi/toml-test
+script:
+  - export PATH="$PATH:$HOME/gopath/bin"
+  - make test

+ 9 - 0
vendor/github.com/Songmu/axslogparser/.travis.yml

@@ -0,0 +1,9 @@
+language: go
+go:
+- "1.10"
+- tip
+script:
+- make lint
+- make test
+after_script:
+- make cover

+ 1 - 1
vendor/github.com/Songmu/axslogparser/Makefile

@@ -3,7 +3,7 @@ test: deps
 
 deps:
 	go get -d -v -t ./...
-	go get golang.org/x/lint/golint
+	go get github.com/golang/lint/golint
 	go get golang.org/x/tools/cmd/cover
 	go get github.com/mattn/goveralls
 

+ 18 - 19
vendor/github.com/Songmu/axslogparser/axslogparser.go

@@ -13,25 +13,24 @@ type Parser interface {
 
 // Log is the struct stored parsed result of single line of accesslog
 type Log struct {
-	VirtualHost     string `ltsv:"vhost"`
-	Host            string
-	RemoteLogname   string `ltsv:"ident"`
-	User            string
-	Time            time.Time `ltsv:"-"`
-	TimeStr         string    `ltsv:"time"`
-	Request         string    `ltsv:"req"`
-	Status          int
-	Size            uint64
-	Referer         string
-	UserAgent       string `ltsv:"ua"`
-	ReqTime         *float64
-	ReqTimeMicroSec *float64 `ltsv:"reqtime_microsec"`
-	AppTime         *float64
-	TakenSec        *float64 `ltsv:"taken_sec"` // Hatena specific
-	ForwardedFor    string
-	RequestURI      string `ltsv:"uri"`
-	Protocol        string
-	Method          string
+	VirtualHost   string `ltsv:"vhost"`
+	Host          string
+	RemoteLogname string `ltsv:"ident"`
+	User          string
+	Time          time.Time `ltsv:"-"`
+	TimeStr       string    `ltsv:"time"`
+	Request       string    `ltsv:"req"`
+	Status        int
+	Size          uint64
+	Referer       string
+	UserAgent     string `ltsv:"ua"`
+	ReqTime       *float64
+	AppTime       *float64
+	TakenSec      *float64 `ltsv:"taken_sec"` // Hatena specific
+	ForwardedFor  string
+	RequestURI    string `ltsv:"uri"`
+	Protocol      string
+	Method        string
 }
 
 func (l *Log) breakdownRequest() error {

+ 1 - 1
vendor/github.com/Songmu/axslogparser/ltsv.go

@@ -21,7 +21,7 @@ func (lv *LTSV) Parse(line string) (*Log, error) {
 	}
 	l.Time, _ = time.Parse(clfTimeLayout, strings.Trim(l.TimeStr, "[]"))
 	if err := l.breakdownRequest(); err != nil {
-		return nil, errors.Wrap(err, "failed to parse ltsvlog (invalid request)")
+		return nil, errors.Wrap(err, "failed to parse ltsvlog (invalid request): %s")
 	}
 	return l, nil
 }

+ 5 - 0
vendor/github.com/Songmu/go-ltsv/.gitignore

@@ -0,0 +1,5 @@
+.*
+!.gitignore
+!.travis.yml
+!.goxc.json
+dist/

+ 8 - 0
vendor/github.com/Songmu/go-ltsv/.travis.yml

@@ -0,0 +1,8 @@
+language: go
+go:
+- tip
+script:
+- make lint
+- make test
+after_script:
+- make cover

+ 1 - 1
vendor/github.com/Songmu/go-ltsv/Makefile

@@ -3,7 +3,7 @@ test: deps
 
 deps:
 	go get -d -v -t ./...
-	go get github.com/golang/lint/golint
+	go get golang.org/x/lint/golint
 	go get github.com/mattn/goveralls
 
 lint: deps

+ 15 - 0
vendor/github.com/gogo/protobuf/AUTHORS

@@ -0,0 +1,15 @@
+# This is the official list of GoGo authors for copyright purposes.
+# This file is distinct from the CONTRIBUTORS file, which
+# lists people.  For example, employees are listed in CONTRIBUTORS,
+# but not in AUTHORS, because the employer holds the copyright.
+
+# Names should be added to this file as one of
+#     Organization's name
+#     Individual's name <submission email address>
+#     Individual's name <submission email address> <email2> <emailN>
+
+# Please keep the list sorted.
+
+Sendgrid, Inc
+Vastech SA (PTY) LTD
+Walter Schulze <awalterschulze@gmail.com>

+ 23 - 0
vendor/github.com/gogo/protobuf/CONTRIBUTORS

@@ -0,0 +1,23 @@
+Anton Povarov <anton.povarov@gmail.com>
+Brian Goff <cpuguy83@gmail.com>
+Clayton Coleman <ccoleman@redhat.com>
+Denis Smirnov <denis.smirnov.91@gmail.com>
+DongYun Kang <ceram1000@gmail.com>
+Dwayne Schultz <dschultz@pivotal.io>
+Georg Apitz <gapitz@pivotal.io>
+Gustav Paul <gustav.paul@gmail.com>
+Johan Brandhorst <johan.brandhorst@gmail.com>
+John Shahid <jvshahid@gmail.com>
+John Tuley <john@tuley.org>
+Laurent <laurent@adyoulike.com>
+Patrick Lee <patrick@dropbox.com>
+Peter Edge <peter.edge@gmail.com>
+Roger Johansson <rogeralsing@gmail.com>
+Sam Nguyen <sam.nguyen@sendgrid.com>
+Sergio Arbeo <serabe@gmail.com>
+Stephen J Day <stephen.day@docker.com>
+Tamir Duberstein <tamird@gmail.com>
+Todd Eisenberger <teisenberger@dropbox.com>
+Tormod Erevik Lea <tormodlea@gmail.com>
+Vyacheslav Kim <kane@sendgrid.com>
+Walter Schulze <awalterschulze@gmail.com>

+ 2 - 3
vendor/github.com/gogo/protobuf/LICENSE

@@ -1,7 +1,6 @@
-Protocol Buffers for Go with Gadgets
-
 Copyright (c) 2013, The GoGo Authors. All rights reserved.
-http://github.com/gogo/protobuf
+
+Protocol Buffers for Go with Gadgets
 
 Go support for Protocol Buffers - Google's data interchange format
 

+ 2 - 2
vendor/github.com/gogo/protobuf/proto/Makefile

@@ -38,6 +38,6 @@ test: install generate-test-pbs
 
 generate-test-pbs:
 	make install
-	make -C testdata
-	protoc-min-version --version="3.0.0" --proto_path=.:../../../../:../protobuf --gogo_out=Mtestdata/test.proto=github.com/gogo/protobuf/proto/testdata,Mgoogle/protobuf/any.proto=github.com/gogo/protobuf/types:. proto3_proto/proto3.proto
+	make -C test_proto
+	make -C proto3_proto
 	make

+ 35 - 11
vendor/github.com/gogo/protobuf/proto/clone.go

@@ -35,22 +35,39 @@
 package proto
 
 import (
+	"fmt"
 	"log"
 	"reflect"
 	"strings"
 )
 
 // Clone returns a deep copy of a protocol buffer.
-func Clone(pb Message) Message {
-	in := reflect.ValueOf(pb)
+func Clone(src Message) Message {
+	in := reflect.ValueOf(src)
 	if in.IsNil() {
-		return pb
+		return src
 	}
-
 	out := reflect.New(in.Type().Elem())
-	// out is empty so a merge is a deep copy.
-	mergeStruct(out.Elem(), in.Elem())
-	return out.Interface().(Message)
+	dst := out.Interface().(Message)
+	Merge(dst, src)
+	return dst
+}
+
+// Merger is the interface representing objects that can merge messages of the same type.
+type Merger interface {
+	// Merge merges src into this message.
+	// Required and optional fields that are set in src will be set to that value in dst.
+	// Elements of repeated fields will be appended.
+	//
+	// Merge may panic if called with a different argument type than the receiver.
+	Merge(src Message)
+}
+
+// generatedMerger is the custom merge method that generated protos will have.
+// We must add this method since a generate Merge method will conflict with
+// many existing protos that have a Merge data field already defined.
+type generatedMerger interface {
+	XXX_Merge(src Message)
 }
 
 // Merge merges src into dst.
@@ -58,17 +75,24 @@ func Clone(pb Message) Message {
 // Elements of repeated fields will be appended.
 // Merge panics if src and dst are not the same type, or if dst is nil.
 func Merge(dst, src Message) {
+	if m, ok := dst.(Merger); ok {
+		m.Merge(src)
+		return
+	}
+
 	in := reflect.ValueOf(src)
 	out := reflect.ValueOf(dst)
 	if out.IsNil() {
 		panic("proto: nil destination")
 	}
 	if in.Type() != out.Type() {
-		// Explicit test prior to mergeStruct so that mistyped nils will fail
-		panic("proto: type mismatch")
+		panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src))
 	}
 	if in.IsNil() {
-		// Merging nil into non-nil is a quiet no-op
+		return // Merge from nil src is a noop
+	}
+	if m, ok := dst.(generatedMerger); ok {
+		m.XXX_Merge(src)
 		return
 	}
 	mergeStruct(out.Elem(), in.Elem())
@@ -89,7 +113,7 @@ func mergeStruct(out, in reflect.Value) {
 		bIn := emIn.GetExtensions()
 		bOut := emOut.GetExtensions()
 		*bOut = append(*bOut, *bIn...)
-	} else if emIn, ok := extendable(in.Addr().Interface()); ok {
+	} else if emIn, err := extendable(in.Addr().Interface()); err == nil {
 		emOut, _ := extendable(out.Addr().Interface())
 		mIn, muIn := emIn.extensionsRead()
 		if mIn != nil {

+ 14 - 10
vendor/github.com/golang/protobuf/ptypes/doc.go → vendor/github.com/gogo/protobuf/proto/custom_gogo.go

@@ -1,7 +1,7 @@
-// Go support for Protocol Buffers - Google's data interchange format
+// Protocol Buffers for Go with Gadgets
 //
-// Copyright 2016 The Go Authors.  All rights reserved.
-// https://github.com/golang/protobuf
+// Copyright (c) 2018, 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
@@ -13,9 +13,6 @@
 // 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
@@ -29,7 +26,14 @@
 // (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 ptypes contains code for interacting with well-known types.
-*/
-package ptypes
+package proto
+
+import "reflect"
+
+type custom interface {
+	Marshal() ([]byte, error)
+	Unmarshal(data []byte) error
+	Size() int
+}
+
+var customType = reflect.TypeOf((*custom)(nil)).Elem()

+ 63 - 613
vendor/github.com/gogo/protobuf/proto/decode.go

@@ -39,8 +39,6 @@ import (
 	"errors"
 	"fmt"
 	"io"
-	"os"
-	"reflect"
 )
 
 // errOverflow is returned when an integer is too large to be represented.
@@ -50,10 +48,6 @@ var errOverflow = errors.New("proto: integer overflow")
 // wire type is encountered. It does not get returned to user code.
 var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof")
 
-// The fundamental decoders that interpret bytes on the wire.
-// Those that take integer types all return uint64 and are
-// therefore of type valueDecoder.
-
 // DecodeVarint reads a varint-encoded integer from the slice.
 // It returns the integer and the number of bytes consumed, or
 // zero if there is not enough.
@@ -267,9 +261,6 @@ func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
 	return
 }
 
-// These are not ValueDecoders: they produce an array of bytes or a string.
-// bytes, embedded messages
-
 // DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
 // This is the format used for the bytes protocol buffer
 // type and for embedded messages.
@@ -311,81 +302,29 @@ func (p *Buffer) DecodeStringBytes() (s string, err error) {
 	return string(buf), nil
 }
 
-// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
-// If the protocol buffer has extensions, and the field matches, add it as an extension.
-// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
-func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
-	oi := o.index
-
-	err := o.skip(t, tag, wire)
-	if err != nil {
-		return err
-	}
-
-	if !unrecField.IsValid() {
-		return nil
-	}
-
-	ptr := structPointer_Bytes(base, unrecField)
-
-	// Add the skipped field to struct field
-	obuf := o.buf
-
-	o.buf = *ptr
-	o.EncodeVarint(uint64(tag<<3 | wire))
-	*ptr = append(o.buf, obuf[oi:o.index]...)
-
-	o.buf = obuf
-
-	return nil
-}
-
-// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
-func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
-
-	var u uint64
-	var err error
-
-	switch wire {
-	case WireVarint:
-		_, err = o.DecodeVarint()
-	case WireFixed64:
-		_, err = o.DecodeFixed64()
-	case WireBytes:
-		_, err = o.DecodeRawBytes(false)
-	case WireFixed32:
-		_, err = o.DecodeFixed32()
-	case WireStartGroup:
-		for {
-			u, err = o.DecodeVarint()
-			if err != nil {
-				break
-			}
-			fwire := int(u & 0x7)
-			if fwire == WireEndGroup {
-				break
-			}
-			ftag := int(u >> 3)
-			err = o.skip(t, ftag, fwire)
-			if err != nil {
-				break
-			}
-		}
-	default:
-		err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
-	}
-	return err
-}
-
 // Unmarshaler is the interface representing objects that can
-// unmarshal themselves.  The method should reset the receiver before
-// decoding starts.  The argument points to data that may be
+// unmarshal themselves.  The argument points to data that may be
 // overwritten, so implementations should not keep references to the
 // buffer.
+// Unmarshal implementations should not clear the receiver.
+// Any unmarshaled data should be merged into the receiver.
+// Callers of Unmarshal that do not want to retain existing data
+// should Reset the receiver before calling Unmarshal.
 type Unmarshaler interface {
 	Unmarshal([]byte) error
 }
 
+// newUnmarshaler is the interface representing objects that can
+// unmarshal themselves. The semantics are identical to Unmarshaler.
+//
+// This exists to support protoc-gen-go generated messages.
+// The proto package will stop type-asserting to this interface in the future.
+//
+// DO NOT DEPEND ON THIS.
+type newUnmarshaler interface {
+	XXX_Unmarshal([]byte) error
+}
+
 // Unmarshal parses the protocol buffer representation in buf and places the
 // decoded result in pb.  If the struct underlying pb does not match
 // the data in buf, the results can be unpredictable.
@@ -395,7 +334,13 @@ type Unmarshaler interface {
 // to preserve and append to existing data.
 func Unmarshal(buf []byte, pb Message) error {
 	pb.Reset()
-	return UnmarshalMerge(buf, pb)
+	if u, ok := pb.(newUnmarshaler); ok {
+		return u.XXX_Unmarshal(buf)
+	}
+	if u, ok := pb.(Unmarshaler); ok {
+		return u.Unmarshal(buf)
+	}
+	return NewBuffer(buf).Unmarshal(pb)
 }
 
 // UnmarshalMerge parses the protocol buffer representation in buf and
@@ -405,8 +350,16 @@ func Unmarshal(buf []byte, pb Message) error {
 // UnmarshalMerge merges into existing data in pb.
 // Most code should use Unmarshal instead.
 func UnmarshalMerge(buf []byte, pb Message) error {
-	// If the object can unmarshal itself, let it.
+	if u, ok := pb.(newUnmarshaler); ok {
+		return u.XXX_Unmarshal(buf)
+	}
 	if u, ok := pb.(Unmarshaler); ok {
+		// NOTE: The history of proto have unfortunately been inconsistent
+		// whether Unmarshaler should or should not implicitly clear itself.
+		// Some implementations do, most do not.
+		// Thus, calling this here may or may not do what people want.
+		//
+		// See https://github.com/golang/protobuf/issues/424
 		return u.Unmarshal(buf)
 	}
 	return NewBuffer(buf).Unmarshal(pb)
@@ -422,12 +375,17 @@ func (p *Buffer) DecodeMessage(pb Message) error {
 }
 
 // DecodeGroup reads a tag-delimited group from the Buffer.
+// StartGroup tag is already consumed. This function consumes
+// EndGroup tag.
 func (p *Buffer) DecodeGroup(pb Message) error {
-	typ, base, err := getbase(pb)
-	if err != nil {
-		return err
+	b := p.buf[p.index:]
+	x, y := findEndGroup(b)
+	if x < 0 {
+		return io.ErrUnexpectedEOF
 	}
-	return p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), true, base)
+	err := Unmarshal(b[:x], pb)
+	p.index += y
+	return err
 }
 
 // Unmarshal parses the protocol buffer representation in the
@@ -438,541 +396,33 @@ func (p *Buffer) DecodeGroup(pb Message) error {
 // Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal.
 func (p *Buffer) Unmarshal(pb Message) error {
 	// If the object can unmarshal itself, let it.
-	if u, ok := pb.(Unmarshaler); ok {
-		err := u.Unmarshal(p.buf[p.index:])
+	if u, ok := pb.(newUnmarshaler); ok {
+		err := u.XXX_Unmarshal(p.buf[p.index:])
 		p.index = len(p.buf)
 		return err
 	}
-
-	typ, base, err := getbase(pb)
-	if err != nil {
-		return err
-	}
-
-	err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
-
-	if collectStats {
-		stats.Decode++
-	}
-
-	return err
-}
-
-// unmarshalType does the work of unmarshaling a structure.
-func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
-	var state errorState
-	required, reqFields := prop.reqCount, uint64(0)
-
-	var err error
-	for err == nil && o.index < len(o.buf) {
-		oi := o.index
-		var u uint64
-		u, err = o.DecodeVarint()
-		if err != nil {
-			break
-		}
-		wire := int(u & 0x7)
-		if wire == WireEndGroup {
-			if is_group {
-				if required > 0 {
-					// Not enough information to determine the exact field.
-					// (See below.)
-					return &RequiredNotSetError{"{Unknown}"}
-				}
-				return nil // input is satisfied
-			}
-			return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
-		}
-		tag := int(u >> 3)
-		if tag <= 0 {
-			return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
-		}
-		fieldnum, ok := prop.decoderTags.get(tag)
-		if !ok {
-			// Maybe it's an extension?
-			if prop.extendable {
-				if e, eok := structPointer_Interface(base, st).(extensionsBytes); eok {
-					if isExtensionField(e, int32(tag)) {
-						if err = o.skip(st, tag, wire); err == nil {
-							ext := e.GetExtensions()
-							*ext = append(*ext, o.buf[oi:o.index]...)
-						}
-						continue
-					}
-				} else if e, _ := extendable(structPointer_Interface(base, st)); isExtensionField(e, int32(tag)) {
-					if err = o.skip(st, tag, wire); err == nil {
-						extmap := e.extensionsWrite()
-						ext := extmap[int32(tag)] // may be missing
-						ext.enc = append(ext.enc, o.buf[oi:o.index]...)
-						extmap[int32(tag)] = ext
-					}
-					continue
-				}
-			}
-			// Maybe it's a oneof?
-			if prop.oneofUnmarshaler != nil {
-				m := structPointer_Interface(base, st).(Message)
-				// First return value indicates whether tag is a oneof field.
-				ok, err = prop.oneofUnmarshaler(m, tag, wire, o)
-				if err == ErrInternalBadWireType {
-					// Map the error to something more descriptive.
-					// Do the formatting here to save generated code space.
-					err = fmt.Errorf("bad wiretype for oneof field in %T", m)
-				}
-				if ok {
-					continue
-				}
-			}
-			err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
-			continue
-		}
-		p := prop.Prop[fieldnum]
-
-		if p.dec == nil {
-			fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
-			continue
-		}
-		dec := p.dec
-		if wire != WireStartGroup && wire != p.WireType {
-			if wire == WireBytes && p.packedDec != nil {
-				// a packable field
-				dec = p.packedDec
-			} else {
-				err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType)
-				continue
-			}
-		}
-		decErr := dec(o, p, base)
-		if decErr != nil && !state.shouldContinue(decErr, p) {
-			err = decErr
-		}
-		if err == nil && p.Required {
-			// Successfully decoded a required field.
-			if tag <= 64 {
-				// use bitmap for fields 1-64 to catch field reuse.
-				var mask uint64 = 1 << uint64(tag-1)
-				if reqFields&mask == 0 {
-					// new required field
-					reqFields |= mask
-					required--
-				}
-			} else {
-				// This is imprecise. It can be fooled by a required field
-				// with a tag > 64 that is encoded twice; that's very rare.
-				// A fully correct implementation would require allocating
-				// a data structure, which we would like to avoid.
-				required--
-			}
-		}
-	}
-	if err == nil {
-		if is_group {
-			return io.ErrUnexpectedEOF
-		}
-		if state.err != nil {
-			return state.err
-		}
-		if required > 0 {
-			// Not enough information to determine the exact field. If we use extra
-			// CPU, we could determine the field only if the missing required field
-			// has a tag <= 64 and we check reqFields.
-			return &RequiredNotSetError{"{Unknown}"}
-		}
-	}
-	return err
-}
-
-// Individual type decoders
-// For each,
-//	u is the decoded value,
-//	v is a pointer to the field (pointer) in the struct
-
-// Sizes of the pools to allocate inside the Buffer.
-// The goal is modest amortization and allocation
-// on at least 16-byte boundaries.
-const (
-	boolPoolSize   = 16
-	uint32PoolSize = 8
-	uint64PoolSize = 4
-)
-
-// Decode a bool.
-func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	if len(o.bools) == 0 {
-		o.bools = make([]bool, boolPoolSize)
-	}
-	o.bools[0] = u != 0
-	*structPointer_Bool(base, p.field) = &o.bools[0]
-	o.bools = o.bools[1:]
-	return nil
-}
-
-func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	*structPointer_BoolVal(base, p.field) = u != 0
-	return nil
-}
-
-// Decode an int32.
-func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
-	return nil
-}
-
-func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
-	return nil
-}
-
-// Decode an int64.
-func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	word64_Set(structPointer_Word64(base, p.field), o, u)
-	return nil
-}
-
-func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
-	return nil
-}
-
-// Decode a string.
-func (o *Buffer) dec_string(p *Properties, base structPointer) error {
-	s, err := o.DecodeStringBytes()
-	if err != nil {
-		return err
-	}
-	*structPointer_String(base, p.field) = &s
-	return nil
-}
-
-func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
-	s, err := o.DecodeStringBytes()
-	if err != nil {
-		return err
-	}
-	*structPointer_StringVal(base, p.field) = s
-	return nil
-}
-
-// Decode a slice of bytes ([]byte).
-func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
-	b, err := o.DecodeRawBytes(true)
-	if err != nil {
-		return err
-	}
-	*structPointer_Bytes(base, p.field) = b
-	return nil
-}
-
-// Decode a slice of bools ([]bool).
-func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	v := structPointer_BoolSlice(base, p.field)
-	*v = append(*v, u != 0)
-	return nil
-}
-
-// Decode a slice of bools ([]bool) in packed format.
-func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
-	v := structPointer_BoolSlice(base, p.field)
-
-	nn, err := o.DecodeVarint()
-	if err != nil {
-		return err
-	}
-	nb := int(nn) // number of bytes of encoded bools
-	fin := o.index + nb
-	if fin < o.index {
-		return errOverflow
-	}
-
-	y := *v
-	for o.index < fin {
-		u, err := p.valDec(o)
-		if err != nil {
-			return err
-		}
-		y = append(y, u != 0)
-	}
-
-	*v = y
-	return nil
-}
-
-// Decode a slice of int32s ([]int32).
-func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-	structPointer_Word32Slice(base, p.field).Append(uint32(u))
-	return nil
-}
-
-// Decode a slice of int32s ([]int32) in packed format.
-func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
-	v := structPointer_Word32Slice(base, p.field)
-
-	nn, err := o.DecodeVarint()
-	if err != nil {
-		return err
-	}
-	nb := int(nn) // number of bytes of encoded int32s
-
-	fin := o.index + nb
-	if fin < o.index {
-		return errOverflow
-	}
-	for o.index < fin {
-		u, err := p.valDec(o)
-		if err != nil {
-			return err
-		}
-		v.Append(uint32(u))
-	}
-	return nil
-}
-
-// Decode a slice of int64s ([]int64).
-func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
-	u, err := p.valDec(o)
-	if err != nil {
-		return err
-	}
-
-	structPointer_Word64Slice(base, p.field).Append(u)
-	return nil
-}
-
-// Decode a slice of int64s ([]int64) in packed format.
-func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
-	v := structPointer_Word64Slice(base, p.field)
-
-	nn, err := o.DecodeVarint()
-	if err != nil {
-		return err
-	}
-	nb := int(nn) // number of bytes of encoded int64s
-
-	fin := o.index + nb
-	if fin < o.index {
-		return errOverflow
-	}
-	for o.index < fin {
-		u, err := p.valDec(o)
-		if err != nil {
-			return err
-		}
-		v.Append(u)
-	}
-	return nil
-}
-
-// Decode a slice of strings ([]string).
-func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
-	s, err := o.DecodeStringBytes()
-	if err != nil {
-		return err
-	}
-	v := structPointer_StringSlice(base, p.field)
-	*v = append(*v, s)
-	return nil
-}
-
-// Decode a slice of slice of bytes ([][]byte).
-func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
-	b, err := o.DecodeRawBytes(true)
-	if err != nil {
-		return err
-	}
-	v := structPointer_BytesSlice(base, p.field)
-	*v = append(*v, b)
-	return nil
-}
-
-// Decode a map field.
-func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
-	raw, err := o.DecodeRawBytes(false)
-	if err != nil {
-		return err
-	}
-	oi := o.index       // index at the end of this map entry
-	o.index -= len(raw) // move buffer back to start of map entry
-
-	mptr := structPointer_NewAt(base, p.field, p.mtype) // *map[K]V
-	if mptr.Elem().IsNil() {
-		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
-	}
-	v := mptr.Elem() // map[K]V
-
-	// Prepare addressable doubly-indirect placeholders for the key and value types.
-	// See enc_new_map for why.
-	keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
-	keybase := toStructPointer(keyptr.Addr())                  // **K
-
-	var valbase structPointer
-	var valptr reflect.Value
-	switch p.mtype.Elem().Kind() {
-	case reflect.Slice:
-		// []byte
-		var dummy []byte
-		valptr = reflect.ValueOf(&dummy)  // *[]byte
-		valbase = toStructPointer(valptr) // *[]byte
-	case reflect.Ptr:
-		// message; valptr is **Msg; need to allocate the intermediate pointer
-		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
-		valptr.Set(reflect.New(valptr.Type().Elem()))
-		valbase = toStructPointer(valptr)
-	default:
-		// everything else
-		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
-		valbase = toStructPointer(valptr.Addr())                   // **V
-	}
-
-	// Decode.
-	// This parses a restricted wire format, namely the encoding of a message
-	// with two fields. See enc_new_map for the format.
-	for o.index < oi {
-		// tagcode for key and value properties are always a single byte
-		// because they have tags 1 and 2.
-		tagcode := o.buf[o.index]
-		o.index++
-		switch tagcode {
-		case p.mkeyprop.tagcode[0]:
-			if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
-				return err
-			}
-		case p.mvalprop.tagcode[0]:
-			if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
-				return err
-			}
-		default:
-			// TODO: Should we silently skip this instead?
-			return fmt.Errorf("proto: bad map data tag %d", raw[0])
-		}
-	}
-	keyelem, valelem := keyptr.Elem(), valptr.Elem()
-	if !keyelem.IsValid() {
-		keyelem = reflect.Zero(p.mtype.Key())
-	}
-	if !valelem.IsValid() {
-		valelem = reflect.Zero(p.mtype.Elem())
-	}
-
-	v.SetMapIndex(keyelem, valelem)
-	return nil
-}
-
-// Decode a group.
-func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
-	bas := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(bas) {
-		// allocate new nested message
-		bas = toStructPointer(reflect.New(p.stype))
-		structPointer_SetStructPointer(base, p.field, bas)
-	}
-	return o.unmarshalType(p.stype, p.sprop, true, bas)
-}
-
-// Decode an embedded message.
-func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
-	raw, e := o.DecodeRawBytes(false)
-	if e != nil {
-		return e
-	}
-
-	bas := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(bas) {
-		// allocate new nested message
-		bas = toStructPointer(reflect.New(p.stype))
-		structPointer_SetStructPointer(base, p.field, bas)
-	}
-
-	// If the object can unmarshal itself, let it.
-	if p.isUnmarshaler {
-		iv := structPointer_Interface(bas, p.stype)
-		return iv.(Unmarshaler).Unmarshal(raw)
-	}
-
-	obuf := o.buf
-	oi := o.index
-	o.buf = raw
-	o.index = 0
-
-	err = o.unmarshalType(p.stype, p.sprop, false, bas)
-	o.buf = obuf
-	o.index = oi
-
-	return err
-}
-
-// Decode a slice of embedded messages.
-func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
-	return o.dec_slice_struct(p, false, base)
-}
-
-// Decode a slice of embedded groups.
-func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
-	return o.dec_slice_struct(p, true, base)
-}
-
-// Decode a slice of structs ([]*struct).
-func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
-	v := reflect.New(p.stype)
-	bas := toStructPointer(v)
-	structPointer_StructPointerSlice(base, p.field).Append(bas)
-
-	if is_group {
-		err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
-		return err
-	}
-
-	raw, err := o.DecodeRawBytes(false)
-	if err != nil {
+	if u, ok := pb.(Unmarshaler); ok {
+		// NOTE: The history of proto have unfortunately been inconsistent
+		// whether Unmarshaler should or should not implicitly clear itself.
+		// Some implementations do, most do not.
+		// Thus, calling this here may or may not do what people want.
+		//
+		// See https://github.com/golang/protobuf/issues/424
+		err := u.Unmarshal(p.buf[p.index:])
+		p.index = len(p.buf)
 		return err
 	}
 
-	// If the object can unmarshal itself, let it.
-	if p.isUnmarshaler {
-		iv := v.Interface()
-		return iv.(Unmarshaler).Unmarshal(raw)
-	}
-
-	obuf := o.buf
-	oi := o.index
-	o.buf = raw
-	o.index = 0
-
-	err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
-
-	o.buf = obuf
-	o.index = oi
-
+	// Slow workaround for messages that aren't Unmarshalers.
+	// This includes some hand-coded .pb.go files and
+	// bootstrap protos.
+	// TODO: fix all of those and then add Unmarshal to
+	// the Message interface. Then:
+	// The cast above and code below can be deleted.
+	// The old unmarshaler can be deleted.
+	// Clients can call Unmarshal directly (can already do that, actually).
+	var info InternalMessageInfo
+	err := info.Unmarshal(pb, p.buf[p.index:])
+	p.index = len(p.buf)
 	return err
 }

+ 0 - 172
vendor/github.com/gogo/protobuf/proto/decode_gogo.go

@@ -1,172 +0,0 @@
-// 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 proto
-
-import (
-	"reflect"
-)
-
-// Decode a reference to a struct pointer.
-func (o *Buffer) dec_ref_struct_message(p *Properties, base structPointer) (err error) {
-	raw, e := o.DecodeRawBytes(false)
-	if e != nil {
-		return e
-	}
-
-	// If the object can unmarshal itself, let it.
-	if p.isUnmarshaler {
-		panic("not supported, since this is a pointer receiver")
-	}
-
-	obuf := o.buf
-	oi := o.index
-	o.buf = raw
-	o.index = 0
-
-	bas := structPointer_FieldPointer(base, p.field)
-
-	err = o.unmarshalType(p.stype, p.sprop, false, bas)
-	o.buf = obuf
-	o.index = oi
-
-	return err
-}
-
-// Decode a slice of references to struct pointers ([]struct).
-func (o *Buffer) dec_slice_ref_struct(p *Properties, is_group bool, base structPointer) error {
-	newBas := appendStructPointer(base, p.field, p.sstype)
-
-	if is_group {
-		panic("not supported, maybe in future, if requested.")
-	}
-
-	raw, err := o.DecodeRawBytes(false)
-	if err != nil {
-		return err
-	}
-
-	// If the object can unmarshal itself, let it.
-	if p.isUnmarshaler {
-		panic("not supported, since this is not a pointer receiver.")
-	}
-
-	obuf := o.buf
-	oi := o.index
-	o.buf = raw
-	o.index = 0
-
-	err = o.unmarshalType(p.stype, p.sprop, is_group, newBas)
-
-	o.buf = obuf
-	o.index = oi
-
-	return err
-}
-
-// Decode a slice of references to struct pointers.
-func (o *Buffer) dec_slice_ref_struct_message(p *Properties, base structPointer) error {
-	return o.dec_slice_ref_struct(p, false, base)
-}
-
-func setPtrCustomType(base structPointer, f field, v interface{}) {
-	if v == nil {
-		return
-	}
-	structPointer_SetStructPointer(base, f, toStructPointer(reflect.ValueOf(v)))
-}
-
-func setCustomType(base structPointer, f field, value interface{}) {
-	if value == nil {
-		return
-	}
-	v := reflect.ValueOf(value).Elem()
-	t := reflect.TypeOf(value).Elem()
-	kind := t.Kind()
-	switch kind {
-	case reflect.Slice:
-		slice := reflect.MakeSlice(t, v.Len(), v.Cap())
-		reflect.Copy(slice, v)
-		oldHeader := structPointer_GetSliceHeader(base, f)
-		oldHeader.Data = slice.Pointer()
-		oldHeader.Len = v.Len()
-		oldHeader.Cap = v.Cap()
-	default:
-		size := reflect.TypeOf(value).Elem().Size()
-		structPointer_Copy(toStructPointer(reflect.ValueOf(value)), structPointer_Add(base, f), int(size))
-	}
-}
-
-func (o *Buffer) dec_custom_bytes(p *Properties, base structPointer) error {
-	b, err := o.DecodeRawBytes(true)
-	if err != nil {
-		return err
-	}
-	i := reflect.New(p.ctype.Elem()).Interface()
-	custom := (i).(Unmarshaler)
-	if err := custom.Unmarshal(b); err != nil {
-		return err
-	}
-	setPtrCustomType(base, p.field, custom)
-	return nil
-}
-
-func (o *Buffer) dec_custom_ref_bytes(p *Properties, base structPointer) error {
-	b, err := o.DecodeRawBytes(true)
-	if err != nil {
-		return err
-	}
-	i := reflect.New(p.ctype).Interface()
-	custom := (i).(Unmarshaler)
-	if err := custom.Unmarshal(b); err != nil {
-		return err
-	}
-	if custom != nil {
-		setCustomType(base, p.field, custom)
-	}
-	return nil
-}
-
-// Decode a slice of bytes ([]byte) into a slice of custom types.
-func (o *Buffer) dec_custom_slice_bytes(p *Properties, base structPointer) error {
-	b, err := o.DecodeRawBytes(true)
-	if err != nil {
-		return err
-	}
-	i := reflect.New(p.ctype.Elem()).Interface()
-	custom := (i).(Unmarshaler)
-	if err := custom.Unmarshal(b); err != nil {
-		return err
-	}
-	newBas := appendStructPointer(base, p.field, p.ctype)
-
-	var zero field
-	setCustomType(newBas, zero, custom)
-
-	return nil
-}

+ 200 - 1
vendor/github.com/gogo/protobuf/proto/discard.go

@@ -35,8 +35,14 @@ import (
 	"fmt"
 	"reflect"
 	"strings"
+	"sync"
+	"sync/atomic"
 )
 
+type generatedDiscarder interface {
+	XXX_DiscardUnknown()
+}
+
 // DiscardUnknown recursively discards all unknown fields from this message
 // and all embedded messages.
 //
@@ -49,9 +55,202 @@ import (
 // For proto2 messages, the unknown fields of message extensions are only
 // discarded from messages that have been accessed via GetExtension.
 func DiscardUnknown(m Message) {
+	if m, ok := m.(generatedDiscarder); ok {
+		m.XXX_DiscardUnknown()
+		return
+	}
+	// TODO: Dynamically populate a InternalMessageInfo for legacy messages,
+	// but the master branch has no implementation for InternalMessageInfo,
+	// so it would be more work to replicate that approach.
 	discardLegacy(m)
 }
 
+// DiscardUnknown recursively discards all unknown fields.
+func (a *InternalMessageInfo) DiscardUnknown(m Message) {
+	di := atomicLoadDiscardInfo(&a.discard)
+	if di == nil {
+		di = getDiscardInfo(reflect.TypeOf(m).Elem())
+		atomicStoreDiscardInfo(&a.discard, di)
+	}
+	di.discard(toPointer(&m))
+}
+
+type discardInfo struct {
+	typ reflect.Type
+
+	initialized int32 // 0: only typ is valid, 1: everything is valid
+	lock        sync.Mutex
+
+	fields       []discardFieldInfo
+	unrecognized field
+}
+
+type discardFieldInfo struct {
+	field   field // Offset of field, guaranteed to be valid
+	discard func(src pointer)
+}
+
+var (
+	discardInfoMap  = map[reflect.Type]*discardInfo{}
+	discardInfoLock sync.Mutex
+)
+
+func getDiscardInfo(t reflect.Type) *discardInfo {
+	discardInfoLock.Lock()
+	defer discardInfoLock.Unlock()
+	di := discardInfoMap[t]
+	if di == nil {
+		di = &discardInfo{typ: t}
+		discardInfoMap[t] = di
+	}
+	return di
+}
+
+func (di *discardInfo) discard(src pointer) {
+	if src.isNil() {
+		return // Nothing to do.
+	}
+
+	if atomic.LoadInt32(&di.initialized) == 0 {
+		di.computeDiscardInfo()
+	}
+
+	for _, fi := range di.fields {
+		sfp := src.offset(fi.field)
+		fi.discard(sfp)
+	}
+
+	// For proto2 messages, only discard unknown fields in message extensions
+	// that have been accessed via GetExtension.
+	if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil {
+		// Ignore lock since DiscardUnknown is not concurrency safe.
+		emm, _ := em.extensionsRead()
+		for _, mx := range emm {
+			if m, ok := mx.value.(Message); ok {
+				DiscardUnknown(m)
+			}
+		}
+	}
+
+	if di.unrecognized.IsValid() {
+		*src.offset(di.unrecognized).toBytes() = nil
+	}
+}
+
+func (di *discardInfo) computeDiscardInfo() {
+	di.lock.Lock()
+	defer di.lock.Unlock()
+	if di.initialized != 0 {
+		return
+	}
+	t := di.typ
+	n := t.NumField()
+
+	for i := 0; i < n; i++ {
+		f := t.Field(i)
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+
+		dfi := discardFieldInfo{field: toField(&f)}
+		tf := f.Type
+
+		// Unwrap tf to get its most basic type.
+		var isPointer, isSlice bool
+		if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
+			isSlice = true
+			tf = tf.Elem()
+		}
+		if tf.Kind() == reflect.Ptr {
+			isPointer = true
+			tf = tf.Elem()
+		}
+		if isPointer && isSlice && tf.Kind() != reflect.Struct {
+			panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name))
+		}
+
+		switch tf.Kind() {
+		case reflect.Struct:
+			switch {
+			case !isPointer:
+				panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name))
+			case isSlice: // E.g., []*pb.T
+				discardInfo := getDiscardInfo(tf)
+				dfi.discard = func(src pointer) {
+					sps := src.getPointerSlice()
+					for _, sp := range sps {
+						if !sp.isNil() {
+							discardInfo.discard(sp)
+						}
+					}
+				}
+			default: // E.g., *pb.T
+				discardInfo := getDiscardInfo(tf)
+				dfi.discard = func(src pointer) {
+					sp := src.getPointer()
+					if !sp.isNil() {
+						discardInfo.discard(sp)
+					}
+				}
+			}
+		case reflect.Map:
+			switch {
+			case isPointer || isSlice:
+				panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name))
+			default: // E.g., map[K]V
+				if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T)
+					dfi.discard = func(src pointer) {
+						sm := src.asPointerTo(tf).Elem()
+						if sm.Len() == 0 {
+							return
+						}
+						for _, key := range sm.MapKeys() {
+							val := sm.MapIndex(key)
+							DiscardUnknown(val.Interface().(Message))
+						}
+					}
+				} else {
+					dfi.discard = func(pointer) {} // Noop
+				}
+			}
+		case reflect.Interface:
+			// Must be oneof field.
+			switch {
+			case isPointer || isSlice:
+				panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name))
+			default: // E.g., interface{}
+				// TODO: Make this faster?
+				dfi.discard = func(src pointer) {
+					su := src.asPointerTo(tf).Elem()
+					if !su.IsNil() {
+						sv := su.Elem().Elem().Field(0)
+						if sv.Kind() == reflect.Ptr && sv.IsNil() {
+							return
+						}
+						switch sv.Type().Kind() {
+						case reflect.Ptr: // Proto struct (e.g., *T)
+							DiscardUnknown(sv.Interface().(Message))
+						}
+					}
+				}
+			}
+		default:
+			continue
+		}
+		di.fields = append(di.fields, dfi)
+	}
+
+	di.unrecognized = invalidField
+	if f, ok := t.FieldByName("XXX_unrecognized"); ok {
+		if f.Type != reflect.TypeOf([]byte{}) {
+			panic("expected XXX_unrecognized to be of type []byte")
+		}
+		di.unrecognized = toField(&f)
+	}
+
+	atomic.StoreInt32(&di.initialized, 1)
+}
+
 func discardLegacy(m Message) {
 	v := reflect.ValueOf(m)
 	if v.Kind() != reflect.Ptr || v.IsNil() {
@@ -139,7 +338,7 @@ func discardLegacy(m Message) {
 
 	// For proto2 messages, only discard unknown fields in message extensions
 	// that have been accessed via GetExtension.
-	if em, ok := extendable(m); ok {
+	if em, err := extendable(m); err == nil {
 		// Ignore lock since discardLegacy is not concurrency safe.
 		emm, _ := em.extensionsRead()
 		for _, mx := range emm {

+ 0 - 154
vendor/github.com/gogo/protobuf/proto/duration_gogo.go

@@ -47,157 +47,3 @@ func (*duration) String() string { return "duration<string>" }
 func init() {
 	RegisterType((*duration)(nil), "gogo.protobuf.proto.duration")
 }
-
-func (o *Buffer) decDuration() (time.Duration, error) {
-	b, err := o.DecodeRawBytes(true)
-	if err != nil {
-		return 0, err
-	}
-	dproto := &duration{}
-	if err := Unmarshal(b, dproto); err != nil {
-		return 0, err
-	}
-	return durationFromProto(dproto)
-}
-
-func (o *Buffer) dec_duration(p *Properties, base structPointer) error {
-	d, err := o.decDuration()
-	if err != nil {
-		return err
-	}
-	word64_Set(structPointer_Word64(base, p.field), o, uint64(d))
-	return nil
-}
-
-func (o *Buffer) dec_ref_duration(p *Properties, base structPointer) error {
-	d, err := o.decDuration()
-	if err != nil {
-		return err
-	}
-	word64Val_Set(structPointer_Word64Val(base, p.field), o, uint64(d))
-	return nil
-}
-
-func (o *Buffer) dec_slice_duration(p *Properties, base structPointer) error {
-	d, err := o.decDuration()
-	if err != nil {
-		return err
-	}
-	newBas := appendStructPointer(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType)))
-	var zero field
-	setPtrCustomType(newBas, zero, &d)
-	return nil
-}
-
-func (o *Buffer) dec_slice_ref_duration(p *Properties, base structPointer) error {
-	d, err := o.decDuration()
-	if err != nil {
-		return err
-	}
-	structPointer_Word64Slice(base, p.field).Append(uint64(d))
-	return nil
-}
-
-func size_duration(p *Properties, base structPointer) (n int) {
-	structp := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(structp) {
-		return 0
-	}
-	dur := structPointer_Interface(structp, durationType).(*time.Duration)
-	d := durationProto(*dur)
-	size := Size(d)
-	return size + sizeVarint(uint64(size)) + len(p.tagcode)
-}
-
-func (o *Buffer) enc_duration(p *Properties, base structPointer) error {
-	structp := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(structp) {
-		return ErrNil
-	}
-	dur := structPointer_Interface(structp, durationType).(*time.Duration)
-	d := durationProto(*dur)
-	data, err := Marshal(d)
-	if err != nil {
-		return err
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeRawBytes(data)
-	return nil
-}
-
-func size_ref_duration(p *Properties, base structPointer) (n int) {
-	dur := structPointer_InterfaceAt(base, p.field, durationType).(*time.Duration)
-	d := durationProto(*dur)
-	size := Size(d)
-	return size + sizeVarint(uint64(size)) + len(p.tagcode)
-}
-
-func (o *Buffer) enc_ref_duration(p *Properties, base structPointer) error {
-	dur := structPointer_InterfaceAt(base, p.field, durationType).(*time.Duration)
-	d := durationProto(*dur)
-	data, err := Marshal(d)
-	if err != nil {
-		return err
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeRawBytes(data)
-	return nil
-}
-
-func size_slice_duration(p *Properties, base structPointer) (n int) {
-	pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType))).(*[]*time.Duration)
-	durs := *pdurs
-	for i := 0; i < len(durs); i++ {
-		if durs[i] == nil {
-			return 0
-		}
-		dproto := durationProto(*durs[i])
-		size := Size(dproto)
-		n += len(p.tagcode) + size + sizeVarint(uint64(size))
-	}
-	return n
-}
-
-func (o *Buffer) enc_slice_duration(p *Properties, base structPointer) error {
-	pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(durationType))).(*[]*time.Duration)
-	durs := *pdurs
-	for i := 0; i < len(durs); i++ {
-		if durs[i] == nil {
-			return errRepeatedHasNil
-		}
-		dproto := durationProto(*durs[i])
-		data, err := Marshal(dproto)
-		if err != nil {
-			return err
-		}
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeRawBytes(data)
-	}
-	return nil
-}
-
-func size_slice_ref_duration(p *Properties, base structPointer) (n int) {
-	pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(durationType)).(*[]time.Duration)
-	durs := *pdurs
-	for i := 0; i < len(durs); i++ {
-		dproto := durationProto(durs[i])
-		size := Size(dproto)
-		n += len(p.tagcode) + size + sizeVarint(uint64(size))
-	}
-	return n
-}
-
-func (o *Buffer) enc_slice_ref_duration(p *Properties, base structPointer) error {
-	pdurs := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(durationType)).(*[]time.Duration)
-	durs := *pdurs
-	for i := 0; i < len(durs); i++ {
-		dproto := durationProto(durs[i])
-		data, err := Marshal(dproto)
-		if err != nil {
-			return err
-		}
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeRawBytes(data)
-	}
-	return nil
-}

+ 25 - 1184
vendor/github.com/gogo/protobuf/proto/encode.go

@@ -37,28 +37,9 @@ package proto
 
 import (
 	"errors"
-	"fmt"
 	"reflect"
-	"sort"
 )
 
-// RequiredNotSetError is the error returned if Marshal is called with
-// a protocol buffer struct whose required fields have not
-// all been initialized. It is also the error returned if Unmarshal is
-// called with an encoded protocol buffer that does not include all the
-// required fields.
-//
-// When printed, RequiredNotSetError reports the first unset required field in a
-// message. If the field cannot be precisely determined, it is reported as
-// "{Unknown}".
-type RequiredNotSetError struct {
-	field string
-}
-
-func (e *RequiredNotSetError) Error() string {
-	return fmt.Sprintf("proto: required field %q not set", e.field)
-}
-
 var (
 	// errRepeatedHasNil is the error returned if Marshal is called with
 	// a struct with a repeated field containing a nil element.
@@ -82,10 +63,6 @@ var (
 
 const maxVarintBytes = 10 // maximum length of a varint
 
-// maxMarshalSize is the largest allowed size of an encoded protobuf,
-// since C++ and Java use signed int32s for the size.
-const maxMarshalSize = 1<<31 - 1
-
 // EncodeVarint returns the varint encoding of x.
 // This is the format for the
 // int32, int64, uint32, uint64, bool, and enum
@@ -119,18 +96,27 @@ func (p *Buffer) EncodeVarint(x uint64) error {
 
 // SizeVarint returns the varint encoding size of an integer.
 func SizeVarint(x uint64) int {
-	return sizeVarint(x)
-}
-
-func sizeVarint(x uint64) (n int) {
-	for {
-		n++
-		x >>= 7
-		if x == 0 {
-			break
-		}
-	}
-	return n
+	switch {
+	case x < 1<<7:
+		return 1
+	case x < 1<<14:
+		return 2
+	case x < 1<<21:
+		return 3
+	case x < 1<<28:
+		return 4
+	case x < 1<<35:
+		return 5
+	case x < 1<<42:
+		return 6
+	case x < 1<<49:
+		return 7
+	case x < 1<<56:
+		return 8
+	case x < 1<<63:
+		return 9
+	}
+	return 10
 }
 
 // EncodeFixed64 writes a 64-bit integer to the Buffer.
@@ -149,10 +135,6 @@ func (p *Buffer) EncodeFixed64(x uint64) error {
 	return nil
 }
 
-func sizeFixed64(x uint64) int {
-	return 8
-}
-
 // EncodeFixed32 writes a 32-bit integer to the Buffer.
 // This is the format for the
 // fixed32, sfixed32, and float protocol buffer types.
@@ -165,20 +147,12 @@ func (p *Buffer) EncodeFixed32(x uint64) error {
 	return nil
 }
 
-func sizeFixed32(x uint64) int {
-	return 4
-}
-
 // EncodeZigzag64 writes a zigzag-encoded 64-bit integer
 // to the Buffer.
 // This is the format used for the sint64 protocol buffer type.
 func (p *Buffer) EncodeZigzag64(x uint64) error {
 	// use signed number to get arithmetic right shift.
-	return p.EncodeVarint((x << 1) ^ uint64((int64(x) >> 63)))
-}
-
-func sizeZigzag64(x uint64) int {
-	return sizeVarint((x << 1) ^ uint64((int64(x) >> 63)))
+	return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
 }
 
 // EncodeZigzag32 writes a zigzag-encoded 32-bit integer
@@ -189,10 +163,6 @@ func (p *Buffer) EncodeZigzag32(x uint64) error {
 	return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
 }
 
-func sizeZigzag32(x uint64) int {
-	return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
-}
-
 // EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
 // This is the format used for the bytes protocol buffer
 // type and for embedded messages.
@@ -202,11 +172,6 @@ func (p *Buffer) EncodeRawBytes(b []byte) error {
 	return nil
 }
 
-func sizeRawBytes(b []byte) int {
-	return sizeVarint(uint64(len(b))) +
-		len(b)
-}
-
 // EncodeStringBytes writes an encoded string to the Buffer.
 // This is the format used for the proto2 string type.
 func (p *Buffer) EncodeStringBytes(s string) error {
@@ -215,319 +180,17 @@ func (p *Buffer) EncodeStringBytes(s string) error {
 	return nil
 }
 
-func sizeStringBytes(s string) int {
-	return sizeVarint(uint64(len(s))) +
-		len(s)
-}
-
 // Marshaler is the interface representing objects that can marshal themselves.
 type Marshaler interface {
 	Marshal() ([]byte, error)
 }
 
-// Marshal takes the protocol buffer
-// and encodes it into the wire format, returning the data.
-func Marshal(pb Message) ([]byte, error) {
-	// Can the object marshal itself?
-	if m, ok := pb.(Marshaler); ok {
-		return m.Marshal()
-	}
-	p := NewBuffer(nil)
-	err := p.Marshal(pb)
-	if p.buf == nil && err == nil {
-		// Return a non-nil slice on success.
-		return []byte{}, nil
-	}
-	return p.buf, err
-}
-
 // EncodeMessage writes the protocol buffer to the Buffer,
 // prefixed by a varint-encoded length.
 func (p *Buffer) EncodeMessage(pb Message) error {
-	t, base, err := getbase(pb)
-	if structPointer_IsNil(base) {
-		return ErrNil
-	}
-	if err == nil {
-		var state errorState
-		err = p.enc_len_struct(GetProperties(t.Elem()), base, &state)
-	}
-	return err
-}
-
-// Marshal takes the protocol buffer
-// and encodes it into the wire format, writing the result to the
-// Buffer.
-func (p *Buffer) Marshal(pb Message) error {
-	// Can the object marshal itself?
-	if m, ok := pb.(Marshaler); ok {
-		data, err := m.Marshal()
-		p.buf = append(p.buf, data...)
-		return err
-	}
-
-	t, base, err := getbase(pb)
-	if structPointer_IsNil(base) {
-		return ErrNil
-	}
-	if err == nil {
-		err = p.enc_struct(GetProperties(t.Elem()), base)
-	}
-
-	if collectStats {
-		(stats).Encode++ // Parens are to work around a goimports bug.
-	}
-
-	if len(p.buf) > maxMarshalSize {
-		return ErrTooLarge
-	}
-	return err
-}
-
-// Size returns the encoded size of a protocol buffer.
-func Size(pb Message) (n int) {
-	// Can the object marshal itself?  If so, Size is slow.
-	// TODO: add Size to Marshaler, or add a Sizer interface.
-	if m, ok := pb.(Marshaler); ok {
-		b, _ := m.Marshal()
-		return len(b)
-	}
-
-	t, base, err := getbase(pb)
-	if structPointer_IsNil(base) {
-		return 0
-	}
-	if err == nil {
-		n = size_struct(GetProperties(t.Elem()), base)
-	}
-
-	if collectStats {
-		(stats).Size++ // Parens are to work around a goimports bug.
-	}
-
-	return
-}
-
-// Individual type encoders.
-
-// Encode a bool.
-func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
-	v := *structPointer_Bool(base, p.field)
-	if v == nil {
-		return ErrNil
-	}
-	x := 0
-	if *v {
-		x = 1
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
-	v := *structPointer_BoolVal(base, p.field)
-	if !v {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, 1)
-	return nil
-}
-
-func size_bool(p *Properties, base structPointer) int {
-	v := *structPointer_Bool(base, p.field)
-	if v == nil {
-		return 0
-	}
-	return len(p.tagcode) + 1 // each bool takes exactly one byte
-}
-
-func size_proto3_bool(p *Properties, base structPointer) int {
-	v := *structPointer_BoolVal(base, p.field)
-	if !v && !p.oneof {
-		return 0
-	}
-	return len(p.tagcode) + 1 // each bool takes exactly one byte
-}
-
-// Encode an int32.
-func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
-	v := structPointer_Word32(base, p.field)
-	if word32_IsNil(v) {
-		return ErrNil
-	}
-	x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
-	v := structPointer_Word32Val(base, p.field)
-	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
-	if x == 0 {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func size_int32(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word32(base, p.field)
-	if word32_IsNil(v) {
-		return 0
-	}
-	x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
-	n += len(p.tagcode)
-	n += p.valSize(uint64(x))
-	return
-}
-
-func size_proto3_int32(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word32Val(base, p.field)
-	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
-	if x == 0 && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += p.valSize(uint64(x))
-	return
-}
-
-// Encode a uint32.
-// Exactly the same as int32, except for no sign extension.
-func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
-	v := structPointer_Word32(base, p.field)
-	if word32_IsNil(v) {
-		return ErrNil
-	}
-	x := word32_Get(v)
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
-	v := structPointer_Word32Val(base, p.field)
-	x := word32Val_Get(v)
-	if x == 0 {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func size_uint32(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word32(base, p.field)
-	if word32_IsNil(v) {
-		return 0
-	}
-	x := word32_Get(v)
-	n += len(p.tagcode)
-	n += p.valSize(uint64(x))
-	return
-}
-
-func size_proto3_uint32(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word32Val(base, p.field)
-	x := word32Val_Get(v)
-	if x == 0 && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += p.valSize(uint64(x))
-	return
-}
-
-// Encode an int64.
-func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
-	v := structPointer_Word64(base, p.field)
-	if word64_IsNil(v) {
-		return ErrNil
-	}
-	x := word64_Get(v)
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, x)
-	return nil
-}
-
-func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
-	v := structPointer_Word64Val(base, p.field)
-	x := word64Val_Get(v)
-	if x == 0 {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, x)
-	return nil
-}
-
-func size_int64(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word64(base, p.field)
-	if word64_IsNil(v) {
-		return 0
-	}
-	x := word64_Get(v)
-	n += len(p.tagcode)
-	n += p.valSize(x)
-	return
-}
-
-func size_proto3_int64(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word64Val(base, p.field)
-	x := word64Val_Get(v)
-	if x == 0 && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += p.valSize(x)
-	return
-}
-
-// Encode a string.
-func (o *Buffer) enc_string(p *Properties, base structPointer) error {
-	v := *structPointer_String(base, p.field)
-	if v == nil {
-		return ErrNil
-	}
-	x := *v
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeStringBytes(x)
-	return nil
-}
-
-func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
-	v := *structPointer_StringVal(base, p.field)
-	if v == "" {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeStringBytes(v)
-	return nil
-}
-
-func size_string(p *Properties, base structPointer) (n int) {
-	v := *structPointer_String(base, p.field)
-	if v == nil {
-		return 0
-	}
-	x := *v
-	n += len(p.tagcode)
-	n += sizeStringBytes(x)
-	return
-}
-
-func size_proto3_string(p *Properties, base structPointer) (n int) {
-	v := *structPointer_StringVal(base, p.field)
-	if v == "" && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += sizeStringBytes(v)
-	return
+	siz := Size(pb)
+	p.EncodeVarint(uint64(siz))
+	return p.Marshal(pb)
 }
 
 // All protocol buffer fields are nillable, but be careful.
@@ -538,825 +201,3 @@ func isNil(v reflect.Value) bool {
 	}
 	return false
 }
-
-// Encode a message struct.
-func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
-	var state errorState
-	structp := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(structp) {
-		return ErrNil
-	}
-
-	// Can the object marshal itself?
-	if p.isMarshaler {
-		m := structPointer_Interface(structp, p.stype).(Marshaler)
-		data, err := m.Marshal()
-		if err != nil && !state.shouldContinue(err, nil) {
-			return err
-		}
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeRawBytes(data)
-		return state.err
-	}
-
-	o.buf = append(o.buf, p.tagcode...)
-	return o.enc_len_struct(p.sprop, structp, &state)
-}
-
-func size_struct_message(p *Properties, base structPointer) int {
-	structp := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(structp) {
-		return 0
-	}
-
-	// Can the object marshal itself?
-	if p.isMarshaler {
-		m := structPointer_Interface(structp, p.stype).(Marshaler)
-		data, _ := m.Marshal()
-		n0 := len(p.tagcode)
-		n1 := sizeRawBytes(data)
-		return n0 + n1
-	}
-
-	n0 := len(p.tagcode)
-	n1 := size_struct(p.sprop, structp)
-	n2 := sizeVarint(uint64(n1)) // size of encoded length
-	return n0 + n1 + n2
-}
-
-// Encode a group struct.
-func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
-	var state errorState
-	b := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(b) {
-		return ErrNil
-	}
-
-	o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
-	err := o.enc_struct(p.sprop, b)
-	if err != nil && !state.shouldContinue(err, nil) {
-		return err
-	}
-	o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
-	return state.err
-}
-
-func size_struct_group(p *Properties, base structPointer) (n int) {
-	b := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(b) {
-		return 0
-	}
-
-	n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
-	n += size_struct(p.sprop, b)
-	n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
-	return
-}
-
-// Encode a slice of bools ([]bool).
-func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
-	s := *structPointer_BoolSlice(base, p.field)
-	l := len(s)
-	if l == 0 {
-		return ErrNil
-	}
-	for _, x := range s {
-		o.buf = append(o.buf, p.tagcode...)
-		v := uint64(0)
-		if x {
-			v = 1
-		}
-		p.valEnc(o, v)
-	}
-	return nil
-}
-
-func size_slice_bool(p *Properties, base structPointer) int {
-	s := *structPointer_BoolSlice(base, p.field)
-	l := len(s)
-	if l == 0 {
-		return 0
-	}
-	return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
-}
-
-// Encode a slice of bools ([]bool) in packed format.
-func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
-	s := *structPointer_BoolSlice(base, p.field)
-	l := len(s)
-	if l == 0 {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
-	for _, x := range s {
-		v := uint64(0)
-		if x {
-			v = 1
-		}
-		p.valEnc(o, v)
-	}
-	return nil
-}
-
-func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
-	s := *structPointer_BoolSlice(base, p.field)
-	l := len(s)
-	if l == 0 {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += sizeVarint(uint64(l))
-	n += l // each bool takes exactly one byte
-	return
-}
-
-// Encode a slice of bytes ([]byte).
-func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
-	s := *structPointer_Bytes(base, p.field)
-	if s == nil {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeRawBytes(s)
-	return nil
-}
-
-func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
-	s := *structPointer_Bytes(base, p.field)
-	if len(s) == 0 {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeRawBytes(s)
-	return nil
-}
-
-func size_slice_byte(p *Properties, base structPointer) (n int) {
-	s := *structPointer_Bytes(base, p.field)
-	if s == nil && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += sizeRawBytes(s)
-	return
-}
-
-func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
-	s := *structPointer_Bytes(base, p.field)
-	if len(s) == 0 && !p.oneof {
-		return 0
-	}
-	n += len(p.tagcode)
-	n += sizeRawBytes(s)
-	return
-}
-
-// Encode a slice of int32s ([]int32).
-func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	for i := 0; i < l; i++ {
-		o.buf = append(o.buf, p.tagcode...)
-		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
-		p.valEnc(o, uint64(x))
-	}
-	return nil
-}
-
-func size_slice_int32(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	for i := 0; i < l; i++ {
-		n += len(p.tagcode)
-		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
-		n += p.valSize(uint64(x))
-	}
-	return
-}
-
-// Encode a slice of int32s ([]int32) in packed format.
-func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	// TODO: Reuse a Buffer.
-	buf := NewBuffer(nil)
-	for i := 0; i < l; i++ {
-		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
-		p.valEnc(buf, uint64(x))
-	}
-
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeVarint(uint64(len(buf.buf)))
-	o.buf = append(o.buf, buf.buf...)
-	return nil
-}
-
-func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	var bufSize int
-	for i := 0; i < l; i++ {
-		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
-		bufSize += p.valSize(uint64(x))
-	}
-
-	n += len(p.tagcode)
-	n += sizeVarint(uint64(bufSize))
-	n += bufSize
-	return
-}
-
-// Encode a slice of uint32s ([]uint32).
-// Exactly the same as int32, except for no sign extension.
-func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	for i := 0; i < l; i++ {
-		o.buf = append(o.buf, p.tagcode...)
-		x := s.Index(i)
-		p.valEnc(o, uint64(x))
-	}
-	return nil
-}
-
-func size_slice_uint32(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	for i := 0; i < l; i++ {
-		n += len(p.tagcode)
-		x := s.Index(i)
-		n += p.valSize(uint64(x))
-	}
-	return
-}
-
-// Encode a slice of uint32s ([]uint32) in packed format.
-// Exactly the same as int32, except for no sign extension.
-func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	// TODO: Reuse a Buffer.
-	buf := NewBuffer(nil)
-	for i := 0; i < l; i++ {
-		p.valEnc(buf, uint64(s.Index(i)))
-	}
-
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeVarint(uint64(len(buf.buf)))
-	o.buf = append(o.buf, buf.buf...)
-	return nil
-}
-
-func size_slice_packed_uint32(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word32Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	var bufSize int
-	for i := 0; i < l; i++ {
-		bufSize += p.valSize(uint64(s.Index(i)))
-	}
-
-	n += len(p.tagcode)
-	n += sizeVarint(uint64(bufSize))
-	n += bufSize
-	return
-}
-
-// Encode a slice of int64s ([]int64).
-func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
-	s := structPointer_Word64Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	for i := 0; i < l; i++ {
-		o.buf = append(o.buf, p.tagcode...)
-		p.valEnc(o, s.Index(i))
-	}
-	return nil
-}
-
-func size_slice_int64(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word64Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	for i := 0; i < l; i++ {
-		n += len(p.tagcode)
-		n += p.valSize(s.Index(i))
-	}
-	return
-}
-
-// Encode a slice of int64s ([]int64) in packed format.
-func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
-	s := structPointer_Word64Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return ErrNil
-	}
-	// TODO: Reuse a Buffer.
-	buf := NewBuffer(nil)
-	for i := 0; i < l; i++ {
-		p.valEnc(buf, s.Index(i))
-	}
-
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeVarint(uint64(len(buf.buf)))
-	o.buf = append(o.buf, buf.buf...)
-	return nil
-}
-
-func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
-	s := structPointer_Word64Slice(base, p.field)
-	l := s.Len()
-	if l == 0 {
-		return 0
-	}
-	var bufSize int
-	for i := 0; i < l; i++ {
-		bufSize += p.valSize(s.Index(i))
-	}
-
-	n += len(p.tagcode)
-	n += sizeVarint(uint64(bufSize))
-	n += bufSize
-	return
-}
-
-// Encode a slice of slice of bytes ([][]byte).
-func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
-	ss := *structPointer_BytesSlice(base, p.field)
-	l := len(ss)
-	if l == 0 {
-		return ErrNil
-	}
-	for i := 0; i < l; i++ {
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeRawBytes(ss[i])
-	}
-	return nil
-}
-
-func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
-	ss := *structPointer_BytesSlice(base, p.field)
-	l := len(ss)
-	if l == 0 {
-		return 0
-	}
-	n += l * len(p.tagcode)
-	for i := 0; i < l; i++ {
-		n += sizeRawBytes(ss[i])
-	}
-	return
-}
-
-// Encode a slice of strings ([]string).
-func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
-	ss := *structPointer_StringSlice(base, p.field)
-	l := len(ss)
-	for i := 0; i < l; i++ {
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeStringBytes(ss[i])
-	}
-	return nil
-}
-
-func size_slice_string(p *Properties, base structPointer) (n int) {
-	ss := *structPointer_StringSlice(base, p.field)
-	l := len(ss)
-	n += l * len(p.tagcode)
-	for i := 0; i < l; i++ {
-		n += sizeStringBytes(ss[i])
-	}
-	return
-}
-
-// Encode a slice of message structs ([]*struct).
-func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
-	var state errorState
-	s := structPointer_StructPointerSlice(base, p.field)
-	l := s.Len()
-
-	for i := 0; i < l; i++ {
-		structp := s.Index(i)
-		if structPointer_IsNil(structp) {
-			return errRepeatedHasNil
-		}
-
-		// Can the object marshal itself?
-		if p.isMarshaler {
-			m := structPointer_Interface(structp, p.stype).(Marshaler)
-			data, err := m.Marshal()
-			if err != nil && !state.shouldContinue(err, nil) {
-				return err
-			}
-			o.buf = append(o.buf, p.tagcode...)
-			o.EncodeRawBytes(data)
-			continue
-		}
-
-		o.buf = append(o.buf, p.tagcode...)
-		err := o.enc_len_struct(p.sprop, structp, &state)
-		if err != nil && !state.shouldContinue(err, nil) {
-			if err == ErrNil {
-				return errRepeatedHasNil
-			}
-			return err
-		}
-	}
-	return state.err
-}
-
-func size_slice_struct_message(p *Properties, base structPointer) (n int) {
-	s := structPointer_StructPointerSlice(base, p.field)
-	l := s.Len()
-	n += l * len(p.tagcode)
-	for i := 0; i < l; i++ {
-		structp := s.Index(i)
-		if structPointer_IsNil(structp) {
-			return // return the size up to this point
-		}
-
-		// Can the object marshal itself?
-		if p.isMarshaler {
-			m := structPointer_Interface(structp, p.stype).(Marshaler)
-			data, _ := m.Marshal()
-			n += sizeRawBytes(data)
-			continue
-		}
-
-		n0 := size_struct(p.sprop, structp)
-		n1 := sizeVarint(uint64(n0)) // size of encoded length
-		n += n0 + n1
-	}
-	return
-}
-
-// Encode a slice of group structs ([]*struct).
-func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
-	var state errorState
-	s := structPointer_StructPointerSlice(base, p.field)
-	l := s.Len()
-
-	for i := 0; i < l; i++ {
-		b := s.Index(i)
-		if structPointer_IsNil(b) {
-			return errRepeatedHasNil
-		}
-
-		o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
-
-		err := o.enc_struct(p.sprop, b)
-
-		if err != nil && !state.shouldContinue(err, nil) {
-			if err == ErrNil {
-				return errRepeatedHasNil
-			}
-			return err
-		}
-
-		o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
-	}
-	return state.err
-}
-
-func size_slice_struct_group(p *Properties, base structPointer) (n int) {
-	s := structPointer_StructPointerSlice(base, p.field)
-	l := s.Len()
-
-	n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
-	n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
-	for i := 0; i < l; i++ {
-		b := s.Index(i)
-		if structPointer_IsNil(b) {
-			return // return size up to this point
-		}
-
-		n += size_struct(p.sprop, b)
-	}
-	return
-}
-
-// Encode an extension map.
-func (o *Buffer) enc_map(p *Properties, base structPointer) error {
-	exts := structPointer_ExtMap(base, p.field)
-	if err := encodeExtensionsMap(*exts); err != nil {
-		return err
-	}
-
-	return o.enc_map_body(*exts)
-}
-
-func (o *Buffer) enc_exts(p *Properties, base structPointer) error {
-	exts := structPointer_Extensions(base, p.field)
-
-	v, mu := exts.extensionsRead()
-	if v == nil {
-		return nil
-	}
-
-	mu.Lock()
-	defer mu.Unlock()
-	if err := encodeExtensionsMap(v); err != nil {
-		return err
-	}
-
-	return o.enc_map_body(v)
-}
-
-func (o *Buffer) enc_map_body(v map[int32]Extension) error {
-	// Fast-path for common cases: zero or one extensions.
-	if len(v) <= 1 {
-		for _, e := range v {
-			o.buf = append(o.buf, e.enc...)
-		}
-		return nil
-	}
-
-	// Sort keys to provide a deterministic encoding.
-	keys := make([]int, 0, len(v))
-	for k := range v {
-		keys = append(keys, int(k))
-	}
-	sort.Ints(keys)
-
-	for _, k := range keys {
-		o.buf = append(o.buf, v[int32(k)].enc...)
-	}
-	return nil
-}
-
-func size_map(p *Properties, base structPointer) int {
-	v := structPointer_ExtMap(base, p.field)
-	return extensionsMapSize(*v)
-}
-
-func size_exts(p *Properties, base structPointer) int {
-	v := structPointer_Extensions(base, p.field)
-	return extensionsSize(v)
-}
-
-// Encode a map field.
-func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
-	var state errorState // XXX: or do we need to plumb this through?
-
-	/*
-		A map defined as
-			map<key_type, value_type> map_field = N;
-		is encoded in the same way as
-			message MapFieldEntry {
-				key_type key = 1;
-				value_type value = 2;
-			}
-			repeated MapFieldEntry map_field = N;
-	*/
-
-	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
-	if v.Len() == 0 {
-		return nil
-	}
-
-	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
-
-	enc := func() error {
-		if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
-			return err
-		}
-		if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil && err != ErrNil {
-			return err
-		}
-		return nil
-	}
-
-	// Don't sort map keys. It is not required by the spec, and C++ doesn't do it.
-	for _, key := range v.MapKeys() {
-		val := v.MapIndex(key)
-
-		keycopy.Set(key)
-		valcopy.Set(val)
-
-		o.buf = append(o.buf, p.tagcode...)
-		if err := o.enc_len_thing(enc, &state); err != nil {
-			return err
-		}
-	}
-	return nil
-}
-
-func size_new_map(p *Properties, base structPointer) int {
-	v := structPointer_NewAt(base, p.field, p.mtype).Elem() // map[K]V
-
-	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
-
-	n := 0
-	for _, key := range v.MapKeys() {
-		val := v.MapIndex(key)
-		keycopy.Set(key)
-		valcopy.Set(val)
-
-		// Tag codes for key and val are the responsibility of the sub-sizer.
-		keysize := p.mkeyprop.size(p.mkeyprop, keybase)
-		valsize := p.mvalprop.size(p.mvalprop, valbase)
-		entry := keysize + valsize
-		// Add on tag code and length of map entry itself.
-		n += len(p.tagcode) + sizeVarint(uint64(entry)) + entry
-	}
-	return n
-}
-
-// mapEncodeScratch returns a new reflect.Value matching the map's value type,
-// and a structPointer suitable for passing to an encoder or sizer.
-func mapEncodeScratch(mapType reflect.Type) (keycopy, valcopy reflect.Value, keybase, valbase structPointer) {
-	// Prepare addressable doubly-indirect placeholders for the key and value types.
-	// This is needed because the element-type encoders expect **T, but the map iteration produces T.
-
-	keycopy = reflect.New(mapType.Key()).Elem()                 // addressable K
-	keyptr := reflect.New(reflect.PtrTo(keycopy.Type())).Elem() // addressable *K
-	keyptr.Set(keycopy.Addr())                                  //
-	keybase = toStructPointer(keyptr.Addr())                    // **K
-
-	// Value types are more varied and require special handling.
-	switch mapType.Elem().Kind() {
-	case reflect.Slice:
-		// []byte
-		var dummy []byte
-		valcopy = reflect.ValueOf(&dummy).Elem() // addressable []byte
-		valbase = toStructPointer(valcopy.Addr())
-	case reflect.Ptr:
-		// message; the generated field type is map[K]*Msg (so V is *Msg),
-		// so we only need one level of indirection.
-		valcopy = reflect.New(mapType.Elem()).Elem() // addressable V
-		valbase = toStructPointer(valcopy.Addr())
-	default:
-		// everything else
-		valcopy = reflect.New(mapType.Elem()).Elem()                // addressable V
-		valptr := reflect.New(reflect.PtrTo(valcopy.Type())).Elem() // addressable *V
-		valptr.Set(valcopy.Addr())                                  //
-		valbase = toStructPointer(valptr.Addr())                    // **V
-	}
-	return
-}
-
-// Encode a struct.
-func (o *Buffer) enc_struct(prop *StructProperties, base structPointer) error {
-	var state errorState
-	// Encode fields in tag order so that decoders may use optimizations
-	// that depend on the ordering.
-	// https://developers.google.com/protocol-buffers/docs/encoding#order
-	for _, i := range prop.order {
-		p := prop.Prop[i]
-		if p.enc != nil {
-			err := p.enc(o, p, base)
-			if err != nil {
-				if err == ErrNil {
-					if p.Required && state.err == nil {
-						state.err = &RequiredNotSetError{p.Name}
-					}
-				} else if err == errRepeatedHasNil {
-					// Give more context to nil values in repeated fields.
-					return errors.New("repeated field " + p.OrigName + " has nil element")
-				} else if !state.shouldContinue(err, p) {
-					return err
-				}
-			}
-			if len(o.buf) > maxMarshalSize {
-				return ErrTooLarge
-			}
-		}
-	}
-
-	// Do oneof fields.
-	if prop.oneofMarshaler != nil {
-		m := structPointer_Interface(base, prop.stype).(Message)
-		if err := prop.oneofMarshaler(m, o); err == ErrNil {
-			return errOneofHasNil
-		} else if err != nil {
-			return err
-		}
-	}
-
-	// Add unrecognized fields at the end.
-	if prop.unrecField.IsValid() {
-		v := *structPointer_Bytes(base, prop.unrecField)
-		if len(o.buf)+len(v) > maxMarshalSize {
-			return ErrTooLarge
-		}
-		if len(v) > 0 {
-			o.buf = append(o.buf, v...)
-		}
-	}
-
-	return state.err
-}
-
-func size_struct(prop *StructProperties, base structPointer) (n int) {
-	for _, i := range prop.order {
-		p := prop.Prop[i]
-		if p.size != nil {
-			n += p.size(p, base)
-		}
-	}
-
-	// Add unrecognized fields at the end.
-	if prop.unrecField.IsValid() {
-		v := *structPointer_Bytes(base, prop.unrecField)
-		n += len(v)
-	}
-
-	// Factor in any oneof fields.
-	if prop.oneofSizer != nil {
-		m := structPointer_Interface(base, prop.stype).(Message)
-		n += prop.oneofSizer(m)
-	}
-
-	return
-}
-
-var zeroes [20]byte // longer than any conceivable sizeVarint
-
-// Encode a struct, preceded by its encoded length (as a varint).
-func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
-	return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
-}
-
-// Encode something, preceded by its encoded length (as a varint).
-func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
-	iLen := len(o.buf)
-	o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
-	iMsg := len(o.buf)
-	err := enc()
-	if err != nil && !state.shouldContinue(err, nil) {
-		return err
-	}
-	lMsg := len(o.buf) - iMsg
-	lLen := sizeVarint(uint64(lMsg))
-	switch x := lLen - (iMsg - iLen); {
-	case x > 0: // actual length is x bytes larger than the space we reserved
-		// Move msg x bytes right.
-		o.buf = append(o.buf, zeroes[:x]...)
-		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
-	case x < 0: // actual length is x bytes smaller than the space we reserved
-		// Move msg x bytes left.
-		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
-		o.buf = o.buf[:len(o.buf)+x] // x is negative
-	}
-	// Encode the length in the reserved space.
-	o.buf = o.buf[:iLen]
-	o.EncodeVarint(uint64(lMsg))
-	o.buf = o.buf[:len(o.buf)+lMsg]
-	return state.err
-}
-
-// errorState maintains the first error that occurs and updates that error
-// with additional context.
-type errorState struct {
-	err error
-}
-
-// shouldContinue reports whether encoding should continue upon encountering the
-// given error. If the error is RequiredNotSetError, shouldContinue returns true
-// and, if this is the first appearance of that error, remembers it for future
-// reporting.
-//
-// If prop is not nil, it may update any error with additional context about the
-// field with the error.
-func (s *errorState) shouldContinue(err error, prop *Properties) bool {
-	// Ignore unset required fields.
-	reqNotSet, ok := err.(*RequiredNotSetError)
-	if !ok {
-		return false
-	}
-	if s.err == nil {
-		if prop != nil {
-			err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
-		}
-		s.err = err
-	}
-	return true
-}

+ 0 - 317
vendor/github.com/gogo/protobuf/proto/encode_gogo.go

@@ -3,11 +3,6 @@
 // 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.
-// http://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:
@@ -18,9 +13,6 @@
 // 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
@@ -36,315 +28,6 @@
 
 package proto
 
-import (
-	"reflect"
-)
-
 func NewRequiredNotSetError(field string) *RequiredNotSetError {
 	return &RequiredNotSetError{field}
 }
-
-type Sizer interface {
-	Size() int
-}
-
-func (o *Buffer) enc_ext_slice_byte(p *Properties, base structPointer) error {
-	s := *structPointer_Bytes(base, p.field)
-	if s == nil {
-		return ErrNil
-	}
-	o.buf = append(o.buf, s...)
-	return nil
-}
-
-func size_ext_slice_byte(p *Properties, base structPointer) (n int) {
-	s := *structPointer_Bytes(base, p.field)
-	if s == nil {
-		return 0
-	}
-	n += len(s)
-	return
-}
-
-// Encode a reference to bool pointer.
-func (o *Buffer) enc_ref_bool(p *Properties, base structPointer) error {
-	v := *structPointer_BoolVal(base, p.field)
-	x := 0
-	if v {
-		x = 1
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func size_ref_bool(p *Properties, base structPointer) int {
-	return len(p.tagcode) + 1 // each bool takes exactly one byte
-}
-
-// Encode a reference to int32 pointer.
-func (o *Buffer) enc_ref_int32(p *Properties, base structPointer) error {
-	v := structPointer_Word32Val(base, p.field)
-	x := int32(word32Val_Get(v))
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func size_ref_int32(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word32Val(base, p.field)
-	x := int32(word32Val_Get(v))
-	n += len(p.tagcode)
-	n += p.valSize(uint64(x))
-	return
-}
-
-func (o *Buffer) enc_ref_uint32(p *Properties, base structPointer) error {
-	v := structPointer_Word32Val(base, p.field)
-	x := word32Val_Get(v)
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, uint64(x))
-	return nil
-}
-
-func size_ref_uint32(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word32Val(base, p.field)
-	x := word32Val_Get(v)
-	n += len(p.tagcode)
-	n += p.valSize(uint64(x))
-	return
-}
-
-// Encode a reference to an int64 pointer.
-func (o *Buffer) enc_ref_int64(p *Properties, base structPointer) error {
-	v := structPointer_Word64Val(base, p.field)
-	x := word64Val_Get(v)
-	o.buf = append(o.buf, p.tagcode...)
-	p.valEnc(o, x)
-	return nil
-}
-
-func size_ref_int64(p *Properties, base structPointer) (n int) {
-	v := structPointer_Word64Val(base, p.field)
-	x := word64Val_Get(v)
-	n += len(p.tagcode)
-	n += p.valSize(x)
-	return
-}
-
-// Encode a reference to a string pointer.
-func (o *Buffer) enc_ref_string(p *Properties, base structPointer) error {
-	v := *structPointer_StringVal(base, p.field)
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeStringBytes(v)
-	return nil
-}
-
-func size_ref_string(p *Properties, base structPointer) (n int) {
-	v := *structPointer_StringVal(base, p.field)
-	n += len(p.tagcode)
-	n += sizeStringBytes(v)
-	return
-}
-
-// Encode a reference to a message struct.
-func (o *Buffer) enc_ref_struct_message(p *Properties, base structPointer) error {
-	var state errorState
-	structp := structPointer_GetRefStructPointer(base, p.field)
-	if structPointer_IsNil(structp) {
-		return ErrNil
-	}
-
-	// Can the object marshal itself?
-	if p.isMarshaler {
-		m := structPointer_Interface(structp, p.stype).(Marshaler)
-		data, err := m.Marshal()
-		if err != nil && !state.shouldContinue(err, nil) {
-			return err
-		}
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeRawBytes(data)
-		return nil
-	}
-
-	o.buf = append(o.buf, p.tagcode...)
-	return o.enc_len_struct(p.sprop, structp, &state)
-}
-
-//TODO this is only copied, please fix this
-func size_ref_struct_message(p *Properties, base structPointer) int {
-	structp := structPointer_GetRefStructPointer(base, p.field)
-	if structPointer_IsNil(structp) {
-		return 0
-	}
-
-	// Can the object marshal itself?
-	if p.isMarshaler {
-		m := structPointer_Interface(structp, p.stype).(Marshaler)
-		data, _ := m.Marshal()
-		n0 := len(p.tagcode)
-		n1 := sizeRawBytes(data)
-		return n0 + n1
-	}
-
-	n0 := len(p.tagcode)
-	n1 := size_struct(p.sprop, structp)
-	n2 := sizeVarint(uint64(n1)) // size of encoded length
-	return n0 + n1 + n2
-}
-
-// Encode a slice of references to message struct pointers ([]struct).
-func (o *Buffer) enc_slice_ref_struct_message(p *Properties, base structPointer) error {
-	var state errorState
-	ss := structPointer_StructRefSlice(base, p.field, p.stype.Size())
-	l := ss.Len()
-	for i := 0; i < l; i++ {
-		structp := ss.Index(i)
-		if structPointer_IsNil(structp) {
-			return errRepeatedHasNil
-		}
-
-		// Can the object marshal itself?
-		if p.isMarshaler {
-			m := structPointer_Interface(structp, p.stype).(Marshaler)
-			data, err := m.Marshal()
-			if err != nil && !state.shouldContinue(err, nil) {
-				return err
-			}
-			o.buf = append(o.buf, p.tagcode...)
-			o.EncodeRawBytes(data)
-			continue
-		}
-
-		o.buf = append(o.buf, p.tagcode...)
-		err := o.enc_len_struct(p.sprop, structp, &state)
-		if err != nil && !state.shouldContinue(err, nil) {
-			if err == ErrNil {
-				return errRepeatedHasNil
-			}
-			return err
-		}
-
-	}
-	return state.err
-}
-
-//TODO this is only copied, please fix this
-func size_slice_ref_struct_message(p *Properties, base structPointer) (n int) {
-	ss := structPointer_StructRefSlice(base, p.field, p.stype.Size())
-	l := ss.Len()
-	n += l * len(p.tagcode)
-	for i := 0; i < l; i++ {
-		structp := ss.Index(i)
-		if structPointer_IsNil(structp) {
-			return // return the size up to this point
-		}
-
-		// Can the object marshal itself?
-		if p.isMarshaler {
-			m := structPointer_Interface(structp, p.stype).(Marshaler)
-			data, _ := m.Marshal()
-			n += len(p.tagcode)
-			n += sizeRawBytes(data)
-			continue
-		}
-
-		n0 := size_struct(p.sprop, structp)
-		n1 := sizeVarint(uint64(n0)) // size of encoded length
-		n += n0 + n1
-	}
-	return
-}
-
-func (o *Buffer) enc_custom_bytes(p *Properties, base structPointer) error {
-	i := structPointer_InterfaceRef(base, p.field, p.ctype)
-	if i == nil {
-		return ErrNil
-	}
-	custom := i.(Marshaler)
-	data, err := custom.Marshal()
-	if err != nil {
-		return err
-	}
-	if data == nil {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeRawBytes(data)
-	return nil
-}
-
-func size_custom_bytes(p *Properties, base structPointer) (n int) {
-	n += len(p.tagcode)
-	i := structPointer_InterfaceRef(base, p.field, p.ctype)
-	if i == nil {
-		return 0
-	}
-	custom := i.(Marshaler)
-	data, _ := custom.Marshal()
-	n += sizeRawBytes(data)
-	return
-}
-
-func (o *Buffer) enc_custom_ref_bytes(p *Properties, base structPointer) error {
-	custom := structPointer_InterfaceAt(base, p.field, p.ctype).(Marshaler)
-	data, err := custom.Marshal()
-	if err != nil {
-		return err
-	}
-	if data == nil {
-		return ErrNil
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeRawBytes(data)
-	return nil
-}
-
-func size_custom_ref_bytes(p *Properties, base structPointer) (n int) {
-	n += len(p.tagcode)
-	i := structPointer_InterfaceAt(base, p.field, p.ctype)
-	if i == nil {
-		return 0
-	}
-	custom := i.(Marshaler)
-	data, _ := custom.Marshal()
-	n += sizeRawBytes(data)
-	return
-}
-
-func (o *Buffer) enc_custom_slice_bytes(p *Properties, base structPointer) error {
-	inter := structPointer_InterfaceRef(base, p.field, p.ctype)
-	if inter == nil {
-		return ErrNil
-	}
-	slice := reflect.ValueOf(inter)
-	l := slice.Len()
-	for i := 0; i < l; i++ {
-		v := slice.Index(i)
-		custom := v.Interface().(Marshaler)
-		data, err := custom.Marshal()
-		if err != nil {
-			return err
-		}
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeRawBytes(data)
-	}
-	return nil
-}
-
-func size_custom_slice_bytes(p *Properties, base structPointer) (n int) {
-	inter := structPointer_InterfaceRef(base, p.field, p.ctype)
-	if inter == nil {
-		return 0
-	}
-	slice := reflect.ValueOf(inter)
-	l := slice.Len()
-	n += l * len(p.tagcode)
-	for i := 0; i < l; i++ {
-		v := slice.Index(i)
-		custom := v.Interface().(Marshaler)
-		data, _ := custom.Marshal()
-		n += sizeRawBytes(data)
-	}
-	return
-}

+ 15 - 15
vendor/github.com/gogo/protobuf/proto/equal.go

@@ -109,15 +109,6 @@ func equalStruct(v1, v2 reflect.Value) bool {
 				// set/unset mismatch
 				return false
 			}
-			b1, ok := f1.Interface().(raw)
-			if ok {
-				b2 := f2.Interface().(raw)
-				// RawMessage
-				if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
-					return false
-				}
-				continue
-			}
 			f1, f2 = f1.Elem(), f2.Elem()
 		}
 		if !equalAny(f1, f2, sprop.Prop[i]) {
@@ -146,11 +137,7 @@ func equalStruct(v1, v2 reflect.Value) bool {
 
 	u1 := uf.Bytes()
 	u2 := v2.FieldByName("XXX_unrecognized").Bytes()
-	if !bytes.Equal(u1, u2) {
-		return false
-	}
-
-	return true
+	return bytes.Equal(u1, u2)
 }
 
 // v1 and v2 are known to have the same type.
@@ -261,6 +248,15 @@ func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
 
 		m1, m2 := e1.value, e2.value
 
+		if m1 == nil && m2 == nil {
+			// Both have only encoded form.
+			if bytes.Equal(e1.enc, e2.enc) {
+				continue
+			}
+			// The bytes are different, but the extensions might still be
+			// equal. We need to decode them to compare.
+		}
+
 		if m1 != nil && m2 != nil {
 			// Both are unencoded.
 			if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) {
@@ -276,8 +272,12 @@ func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool {
 			desc = m[extNum]
 		}
 		if desc == nil {
+			// If both have only encoded form and the bytes are the same,
+			// it is handled above. We get here when the bytes are different.
+			// We don't know how to decode it, so just compare them as byte
+			// slices.
 			log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
-			continue
+			return false
 		}
 		var err error
 		if m1 == nil {

+ 97 - 186
vendor/github.com/gogo/protobuf/proto/extensions.go

@@ -38,6 +38,7 @@ package proto
 import (
 	"errors"
 	"fmt"
+	"io"
 	"reflect"
 	"strconv"
 	"sync"
@@ -69,12 +70,6 @@ type extendableProtoV1 interface {
 	ExtensionMap() map[int32]Extension
 }
 
-type extensionsBytes interface {
-	Message
-	ExtensionRangeArray() []ExtensionRange
-	GetExtensions() *[]byte
-}
-
 // extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto.
 type extensionAdapter struct {
 	extendableProtoV1
@@ -97,14 +92,31 @@ func (n notLocker) Unlock() {}
 // extendable returns the extendableProto interface for the given generated proto message.
 // If the proto message has the old extension format, it returns a wrapper that implements
 // the extendableProto interface.
-func extendable(p interface{}) (extendableProto, bool) {
-	if ep, ok := p.(extendableProto); ok {
-		return ep, ok
-	}
-	if ep, ok := p.(extendableProtoV1); ok {
-		return extensionAdapter{ep}, ok
+func extendable(p interface{}) (extendableProto, error) {
+	switch p := p.(type) {
+	case extendableProto:
+		if isNilPtr(p) {
+			return nil, fmt.Errorf("proto: nil %T is not extendable", p)
+		}
+		return p, nil
+	case extendableProtoV1:
+		if isNilPtr(p) {
+			return nil, fmt.Errorf("proto: nil %T is not extendable", p)
+		}
+		return extensionAdapter{p}, nil
+	case extensionsBytes:
+		return slowExtensionAdapter{p}, nil
 	}
-	return nil, false
+	// Don't allocate a specific error containing %T:
+	// this is the hot path for Clone and MarshalText.
+	return nil, errNotExtendable
+}
+
+var errNotExtendable = errors.New("proto: not an extendable proto.Message")
+
+func isNilPtr(x interface{}) bool {
+	v := reflect.ValueOf(x)
+	return v.Kind() == reflect.Ptr && v.IsNil()
 }
 
 // XXX_InternalExtensions is an internal representation of proto extensions.
@@ -149,16 +161,6 @@ func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Loc
 	return e.p.extensionMap, &e.p.mu
 }
 
-type extensionRange interface {
-	Message
-	ExtensionRangeArray() []ExtensionRange
-}
-
-var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
-var extendableProtoV1Type = reflect.TypeOf((*extendableProtoV1)(nil)).Elem()
-var extendableBytesType = reflect.TypeOf((*extensionsBytes)(nil)).Elem()
-var extensionRangeType = reflect.TypeOf((*extensionRange)(nil)).Elem()
-
 // ExtensionDesc represents an extension specification.
 // Used in generated code from the protocol compiler.
 type ExtensionDesc struct {
@@ -198,8 +200,8 @@ func SetRawExtension(base Message, id int32, b []byte) {
 		*ext = append(*ext, b...)
 		return
 	}
-	epb, ok := extendable(base)
-	if !ok {
+	epb, err := extendable(base)
+	if err != nil {
 		return
 	}
 	extmap := epb.extensionsWrite()
@@ -207,7 +209,7 @@ func SetRawExtension(base Message, id int32, b []byte) {
 }
 
 // isExtensionField returns true iff the given field number is in an extension range.
-func isExtensionField(pb extensionRange, field int32) bool {
+func isExtensionField(pb extendableProto, field int32) bool {
 	for _, er := range pb.ExtensionRangeArray() {
 		if er.Start <= field && field <= er.End {
 			return true
@@ -223,8 +225,11 @@ func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
 	if ea, ok := pbi.(extensionAdapter); ok {
 		pbi = ea.extendableProtoV1
 	}
+	if ea, ok := pbi.(slowExtensionAdapter); ok {
+		pbi = ea.extensionsBytes
+	}
 	if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b {
-		return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
+		return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a)
 	}
 	// Check the range.
 	if !isExtensionField(pb, extension.Field) {
@@ -269,80 +274,6 @@ func extensionProperties(ed *ExtensionDesc) *Properties {
 	return prop
 }
 
-// encode encodes any unmarshaled (unencoded) extensions in e.
-func encodeExtensions(e *XXX_InternalExtensions) error {
-	m, mu := e.extensionsRead()
-	if m == nil {
-		return nil // fast path
-	}
-	mu.Lock()
-	defer mu.Unlock()
-	return encodeExtensionsMap(m)
-}
-
-// encode encodes any unmarshaled (unencoded) extensions in e.
-func encodeExtensionsMap(m map[int32]Extension) error {
-	for k, e := range m {
-		if e.value == nil || e.desc == nil {
-			// Extension is only in its encoded form.
-			continue
-		}
-
-		// We don't skip extensions that have an encoded form set,
-		// because the extension value may have been mutated after
-		// the last time this function was called.
-
-		et := reflect.TypeOf(e.desc.ExtensionType)
-		props := extensionProperties(e.desc)
-
-		p := NewBuffer(nil)
-		// If e.value has type T, the encoder expects a *struct{ X T }.
-		// Pass a *T with a zero field and hope it all works out.
-		x := reflect.New(et)
-		x.Elem().Set(reflect.ValueOf(e.value))
-		if err := props.enc(p, props, toStructPointer(x)); err != nil {
-			return err
-		}
-		e.enc = p.buf
-		m[k] = e
-	}
-	return nil
-}
-
-func extensionsSize(e *XXX_InternalExtensions) (n int) {
-	m, mu := e.extensionsRead()
-	if m == nil {
-		return 0
-	}
-	mu.Lock()
-	defer mu.Unlock()
-	return extensionsMapSize(m)
-}
-
-func extensionsMapSize(m map[int32]Extension) (n int) {
-	for _, e := range m {
-		if e.value == nil || e.desc == nil {
-			// Extension is only in its encoded form.
-			n += len(e.enc)
-			continue
-		}
-
-		// We don't skip extensions that have an encoded form set,
-		// because the extension value may have been mutated after
-		// the last time this function was called.
-
-		et := reflect.TypeOf(e.desc.ExtensionType)
-		props := extensionProperties(e.desc)
-
-		// If e.value has type T, the encoder expects a *struct{ X T }.
-		// Pass a *T with a zero field and hope it all works out.
-		x := reflect.New(et)
-		x.Elem().Set(reflect.ValueOf(e.value))
-		n += props.size(props, toStructPointer(x))
-	}
-	return
-}
-
 // HasExtension returns whether the given extension is present in pb.
 func HasExtension(pb Message, extension *ExtensionDesc) bool {
 	if epb, doki := pb.(extensionsBytes); doki {
@@ -366,8 +297,8 @@ func HasExtension(pb Message, extension *ExtensionDesc) bool {
 		return false
 	}
 	// TODO: Check types, field numbers, etc.?
-	epb, ok := extendable(pb)
-	if !ok {
+	epb, err := extendable(pb)
+	if err != nil {
 		return false
 	}
 	extmap, mu := epb.extensionsRead()
@@ -375,46 +306,26 @@ func HasExtension(pb Message, extension *ExtensionDesc) bool {
 		return false
 	}
 	mu.Lock()
-	_, ok = extmap[extension.Field]
+	_, ok := extmap[extension.Field]
 	mu.Unlock()
 	return ok
 }
 
-func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
-	ext := pb.GetExtensions()
-	for offset < len(*ext) {
-		tag, n1 := DecodeVarint((*ext)[offset:])
-		fieldNum := int32(tag >> 3)
-		wireType := int(tag & 0x7)
-		n2, err := size((*ext)[offset+n1:], wireType)
-		if err != nil {
-			panic(err)
-		}
-		newOffset := offset + n1 + n2
-		if fieldNum == theFieldNum {
-			*ext = append((*ext)[:offset], (*ext)[newOffset:]...)
-			return offset
-		}
-		offset = newOffset
-	}
-	return -1
-}
-
 // ClearExtension removes the given extension from pb.
 func ClearExtension(pb Message, extension *ExtensionDesc) {
 	clearExtension(pb, extension.Field)
 }
 
 func clearExtension(pb Message, fieldNum int32) {
-	if epb, doki := pb.(extensionsBytes); doki {
+	if epb, ok := pb.(extensionsBytes); ok {
 		offset := 0
 		for offset != -1 {
 			offset = deleteExtension(epb, fieldNum, offset)
 		}
 		return
 	}
-	epb, ok := extendable(pb)
-	if !ok {
+	epb, err := extendable(pb)
+	if err != nil {
 		return
 	}
 	// TODO: Check types, field numbers, etc.?
@@ -422,39 +333,33 @@ func clearExtension(pb Message, fieldNum int32) {
 	delete(extmap, fieldNum)
 }
 
-// GetExtension parses and returns the given extension of pb.
-// If the extension is not present and has no default value it returns ErrMissingExtension.
+// GetExtension retrieves a proto2 extended field from pb.
+//
+// If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil),
+// then GetExtension parses the encoded field and returns a Go value of the specified type.
+// If the field is not present, then the default value is returned (if one is specified),
+// otherwise ErrMissingExtension is reported.
+//
+// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil),
+// then GetExtension returns the raw encoded bytes of the field extension.
 func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
 	if epb, doki := pb.(extensionsBytes); doki {
 		ext := epb.GetExtensions()
-		o := 0
-		for o < len(*ext) {
-			tag, n := DecodeVarint((*ext)[o:])
-			fieldNum := int32(tag >> 3)
-			wireType := int(tag & 0x7)
-			l, err := size((*ext)[o+n:], wireType)
-			if err != nil {
-				return nil, err
-			}
-			if int32(fieldNum) == extension.Field {
-				v, err := decodeExtension((*ext)[o:o+n+l], extension)
-				if err != nil {
-					return nil, err
-				}
-				return v, nil
-			}
-			o += n + l
-		}
-		return defaultExtensionValue(extension)
+		return decodeExtensionFromBytes(extension, *ext)
 	}
-	epb, ok := extendable(pb)
-	if !ok {
-		return nil, errors.New("proto: not an extendable proto")
-	}
-	if err := checkExtensionTypes(epb, extension); err != nil {
+
+	epb, err := extendable(pb)
+	if err != nil {
 		return nil, err
 	}
 
+	if extension.ExtendedType != nil {
+		// can only check type if this is a complete descriptor
+		if cerr := checkExtensionTypes(epb, extension); cerr != nil {
+			return nil, cerr
+		}
+	}
+
 	emap, mu := epb.extensionsRead()
 	if emap == nil {
 		return defaultExtensionValue(extension)
@@ -479,6 +384,11 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
 		return e.value, nil
 	}
 
+	if extension.ExtensionType == nil {
+		// incomplete descriptor
+		return e.enc, nil
+	}
+
 	v, err := decodeExtension(e.enc, extension)
 	if err != nil {
 		return nil, err
@@ -496,6 +406,11 @@ func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) {
 // defaultExtensionValue returns the default value for extension.
 // If no default for an extension is defined ErrMissingExtension is returned.
 func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
+	if extension.ExtensionType == nil {
+		// incomplete descriptor, so no default
+		return nil, ErrMissingExtension
+	}
+
 	t := reflect.TypeOf(extension.ExtensionType)
 	props := extensionProperties(extension)
 
@@ -530,31 +445,28 @@ func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) {
 
 // decodeExtension decodes an extension encoded in b.
 func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
-	o := NewBuffer(b)
-
 	t := reflect.TypeOf(extension.ExtensionType)
-
-	props := extensionProperties(extension)
+	unmarshal := typeUnmarshaler(t, extension.Tag)
 
 	// t is a pointer to a struct, pointer to basic type or a slice.
-	// Allocate a "field" to store the pointer/slice itself; the
-	// pointer/slice will be stored here. We pass
-	// the address of this field to props.dec.
-	// This passes a zero field and a *t and lets props.dec
-	// interpret it as a *struct{ x t }.
+	// Allocate space to store the pointer/slice.
 	value := reflect.New(t).Elem()
 
+	var err error
 	for {
-		// Discard wire type and field number varint. It isn't needed.
-		if _, err := o.DecodeVarint(); err != nil {
-			return nil, err
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
 		}
+		b = b[n:]
+		wire := int(x) & 7
 
-		if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
+		b, err = unmarshal(b, valToPointer(value.Addr()), wire)
+		if err != nil {
 			return nil, err
 		}
 
-		if o.index >= len(o.buf) {
+		if len(b) == 0 {
 			break
 		}
 	}
@@ -564,9 +476,13 @@ func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
 // GetExtensions returns a slice of the extensions present in pb that are also listed in es.
 // The returned slice has the same length as es; missing extensions will appear as nil elements.
 func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
+	epb, err := extendable(pb)
+	if err != nil {
+		return nil, err
+	}
 	extensions = make([]interface{}, len(es))
 	for i, e := range es {
-		extensions[i], err = GetExtension(pb, e)
+		extensions[i], err = GetExtension(epb, e)
 		if err == ErrMissingExtension {
 			err = nil
 		}
@@ -581,9 +497,9 @@ func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, e
 // For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing
 // just the Field field, which defines the extension's field number.
 func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
-	epb, ok := extendable(pb)
-	if !ok {
-		return nil, fmt.Errorf("proto: %T is not an extendable proto.Message", pb)
+	epb, err := extendable(pb)
+	if err != nil {
+		return nil, err
 	}
 	registeredExtensions := RegisteredExtensions(pb)
 
@@ -610,23 +526,18 @@ func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) {
 
 // SetExtension sets the specified extension of pb to the specified value.
 func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error {
-	if epb, doki := pb.(extensionsBytes); doki {
-		ClearExtension(pb, extension)
-		ext := epb.GetExtensions()
-		et := reflect.TypeOf(extension.ExtensionType)
-		props := extensionProperties(extension)
-		p := NewBuffer(nil)
-		x := reflect.New(et)
-		x.Elem().Set(reflect.ValueOf(value))
-		if err := props.enc(p, props, toStructPointer(x)); err != nil {
+	if epb, ok := pb.(extensionsBytes); ok {
+		newb, err := encodeExtension(extension, value)
+		if err != nil {
 			return err
 		}
-		*ext = append(*ext, p.buf...)
+		bb := epb.GetExtensions()
+		*bb = append(*bb, newb...)
 		return nil
 	}
-	epb, ok := extendable(pb)
-	if !ok {
-		return errors.New("proto: not an extendable proto")
+	epb, err := extendable(pb)
+	if err != nil {
+		return err
 	}
 	if err := checkExtensionTypes(epb, extension); err != nil {
 		return err
@@ -656,8 +567,8 @@ func ClearAllExtensions(pb Message) {
 		*ext = []byte{}
 		return
 	}
-	epb, ok := extendable(pb)
-	if !ok {
+	epb, err := extendable(pb)
+	if err != nil {
 		return
 	}
 	m := epb.extensionsWrite()

+ 118 - 44
vendor/github.com/gogo/protobuf/proto/extensions_gogo.go

@@ -32,12 +32,36 @@ import (
 	"bytes"
 	"errors"
 	"fmt"
+	"io"
 	"reflect"
 	"sort"
 	"strings"
 	"sync"
 )
 
+type extensionsBytes interface {
+	Message
+	ExtensionRangeArray() []ExtensionRange
+	GetExtensions() *[]byte
+}
+
+type slowExtensionAdapter struct {
+	extensionsBytes
+}
+
+func (s slowExtensionAdapter) extensionsWrite() map[int32]Extension {
+	panic("Please report a bug to github.com/gogo/protobuf if you see this message: Writing extensions is not supported for extensions stored in a byte slice field.")
+}
+
+func (s slowExtensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) {
+	b := s.GetExtensions()
+	m, err := BytesToExtensionsMap(*b)
+	if err != nil {
+		panic(err)
+	}
+	return m, notLocker{}
+}
+
 func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool {
 	if reflect.ValueOf(pb).IsNil() {
 		return ifnotset
@@ -56,19 +80,28 @@ func GetBoolExtension(pb Message, extension *ExtensionDesc, ifnotset bool) bool
 }
 
 func (this *Extension) Equal(that *Extension) bool {
+	if err := this.Encode(); err != nil {
+		return false
+	}
+	if err := that.Encode(); err != nil {
+		return false
+	}
 	return bytes.Equal(this.enc, that.enc)
 }
 
 func (this *Extension) Compare(that *Extension) int {
+	if err := this.Encode(); err != nil {
+		return 1
+	}
+	if err := that.Encode(); err != nil {
+		return -1
+	}
 	return bytes.Compare(this.enc, that.enc)
 }
 
 func SizeOfInternalExtension(m extendableProto) (n int) {
-	return SizeOfExtensionMap(m.extensionsWrite())
-}
-
-func SizeOfExtensionMap(m map[int32]Extension) (n int) {
-	return extensionsMapSize(m)
+	info := getMarshalInfo(reflect.TypeOf(m))
+	return info.sizeV1Extensions(m.extensionsWrite())
 }
 
 type sortableMapElem struct {
@@ -122,28 +155,26 @@ func EncodeInternalExtension(m extendableProto, data []byte) (n int, err error)
 }
 
 func EncodeExtensionMap(m map[int32]Extension, data []byte) (n int, err error) {
-	if err := encodeExtensionsMap(m); err != nil {
-		return 0, err
-	}
-	keys := make([]int, 0, len(m))
-	for k := range m {
-		keys = append(keys, int(k))
-	}
-	sort.Ints(keys)
-	for _, k := range keys {
-		n += copy(data[n:], m[int32(k)].enc)
+	o := 0
+	for _, e := range m {
+		if err := e.Encode(); err != nil {
+			return 0, err
+		}
+		n := copy(data[o:], e.enc)
+		if n != len(e.enc) {
+			return 0, io.ErrShortBuffer
+		}
+		o += n
 	}
-	return n, nil
+	return o, nil
 }
 
 func GetRawExtension(m map[int32]Extension, id int32) ([]byte, error) {
-	if m[id].value == nil || m[id].desc == nil {
-		return m[id].enc, nil
-	}
-	if err := encodeExtensionsMap(m); err != nil {
+	e := m[id]
+	if err := e.Encode(); err != nil {
 		return nil, err
 	}
-	return m[id].enc, nil
+	return e.enc, nil
 }
 
 func size(buf []byte, wire int) (int, error) {
@@ -218,35 +249,58 @@ func AppendExtension(e Message, tag int32, buf []byte) {
 	}
 }
 
-func encodeExtension(e *Extension) error {
-	if e.value == nil || e.desc == nil {
-		// Extension is only in its encoded form.
-		return nil
+func encodeExtension(extension *ExtensionDesc, value interface{}) ([]byte, error) {
+	u := getMarshalInfo(reflect.TypeOf(extension.ExtendedType))
+	ei := u.getExtElemInfo(extension)
+	v := value
+	p := toAddrPointer(&v, ei.isptr)
+	siz := ei.sizer(p, SizeVarint(ei.wiretag))
+	buf := make([]byte, 0, siz)
+	return ei.marshaler(buf, p, ei.wiretag, false)
+}
+
+func decodeExtensionFromBytes(extension *ExtensionDesc, buf []byte) (interface{}, error) {
+	o := 0
+	for o < len(buf) {
+		tag, n := DecodeVarint((buf)[o:])
+		fieldNum := int32(tag >> 3)
+		wireType := int(tag & 0x7)
+		if o+n > len(buf) {
+			return nil, fmt.Errorf("unable to decode extension")
+		}
+		l, err := size((buf)[o+n:], wireType)
+		if err != nil {
+			return nil, err
+		}
+		if int32(fieldNum) == extension.Field {
+			if o+n+l > len(buf) {
+				return nil, fmt.Errorf("unable to decode extension")
+			}
+			v, err := decodeExtension((buf)[o:o+n+l], extension)
+			if err != nil {
+				return nil, err
+			}
+			return v, nil
+		}
+		o += n + l
 	}
-	// We don't skip extensions that have an encoded form set,
-	// because the extension value may have been mutated after
-	// the last time this function was called.
-
-	et := reflect.TypeOf(e.desc.ExtensionType)
-	props := extensionProperties(e.desc)
-
-	p := NewBuffer(nil)
-	// If e.value has type T, the encoder expects a *struct{ X T }.
-	// Pass a *T with a zero field and hope it all works out.
-	x := reflect.New(et)
-	x.Elem().Set(reflect.ValueOf(e.value))
-	if err := props.enc(p, props, toStructPointer(x)); err != nil {
-		return err
+	return defaultExtensionValue(extension)
+}
+
+func (this *Extension) Encode() error {
+	if this.enc == nil {
+		var err error
+		this.enc, err = encodeExtension(this.desc, this.value)
+		if err != nil {
+			return err
+		}
 	}
-	e.enc = p.buf
 	return nil
 }
 
 func (this Extension) GoString() string {
-	if this.enc == nil {
-		if err := encodeExtension(&this); err != nil {
-			panic(err)
-		}
+	if err := this.Encode(); err != nil {
+		return fmt.Sprintf("error encoding extension: %v", err)
 	}
 	return fmt.Sprintf("proto.NewExtension(%#v)", this.enc)
 }
@@ -292,3 +346,23 @@ func GetUnsafeExtensionsMap(extendable Message) map[int32]Extension {
 	pb := extendable.(extendableProto)
 	return pb.extensionsWrite()
 }
+
+func deleteExtension(pb extensionsBytes, theFieldNum int32, offset int) int {
+	ext := pb.GetExtensions()
+	for offset < len(*ext) {
+		tag, n1 := DecodeVarint((*ext)[offset:])
+		fieldNum := int32(tag >> 3)
+		wireType := int(tag & 0x7)
+		n2, err := size((*ext)[offset+n1:], wireType)
+		if err != nil {
+			panic(err)
+		}
+		newOffset := offset + n1 + n2
+		if fieldNum == theFieldNum {
+			*ext = append((*ext)[:offset], (*ext)[newOffset:]...)
+			return offset
+		}
+		offset = newOffset
+	}
+	return -1
+}

+ 118 - 28
vendor/github.com/gogo/protobuf/proto/lib.go

@@ -273,6 +273,67 @@ import (
 	"sync"
 )
 
+// RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
+// Marshal reports this when a required field is not initialized.
+// Unmarshal reports this when a required field is missing from the wire data.
+type RequiredNotSetError struct{ field string }
+
+func (e *RequiredNotSetError) Error() string {
+	if e.field == "" {
+		return fmt.Sprintf("proto: required field not set")
+	}
+	return fmt.Sprintf("proto: required field %q not set", e.field)
+}
+func (e *RequiredNotSetError) RequiredNotSet() bool {
+	return true
+}
+
+type invalidUTF8Error struct{ field string }
+
+func (e *invalidUTF8Error) Error() string {
+	if e.field == "" {
+		return "proto: invalid UTF-8 detected"
+	}
+	return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field)
+}
+func (e *invalidUTF8Error) InvalidUTF8() bool {
+	return true
+}
+
+// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.
+// This error should not be exposed to the external API as such errors should
+// be recreated with the field information.
+var errInvalidUTF8 = &invalidUTF8Error{}
+
+// isNonFatal reports whether the error is either a RequiredNotSet error
+// or a InvalidUTF8 error.
+func isNonFatal(err error) bool {
+	if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() {
+		return true
+	}
+	if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() {
+		return true
+	}
+	return false
+}
+
+type nonFatal struct{ E error }
+
+// Merge merges err into nf and reports whether it was successful.
+// Otherwise it returns false for any fatal non-nil errors.
+func (nf *nonFatal) Merge(err error) (ok bool) {
+	if err == nil {
+		return true // not an error
+	}
+	if !isNonFatal(err) {
+		return false // fatal error
+	}
+	if nf.E == nil {
+		nf.E = err // store first instance of non-fatal error
+	}
+	return true
+}
+
 // Message is implemented by generated protocol buffer messages.
 type Message interface {
 	Reset()
@@ -309,16 +370,7 @@ type Buffer struct {
 	buf   []byte // encode/decode byte stream
 	index int    // read point
 
-	// pools of basic types to amortize allocation.
-	bools   []bool
-	uint32s []uint32
-	uint64s []uint64
-
-	// extra pools, only used with pointer_reflect.go
-	int32s   []int32
-	int64s   []int64
-	float32s []float32
-	float64s []float64
+	deterministic bool
 }
 
 // NewBuffer allocates a new Buffer and initializes its internal data to
@@ -343,6 +395,30 @@ func (p *Buffer) SetBuf(s []byte) {
 // Bytes returns the contents of the Buffer.
 func (p *Buffer) Bytes() []byte { return p.buf }
 
+// SetDeterministic sets whether to use deterministic serialization.
+//
+// Deterministic serialization guarantees that for a given binary, equal
+// messages will always be serialized to the same bytes. This implies:
+//
+//   - Repeated serialization of a message will return the same bytes.
+//   - Different processes of the same binary (which may be executing on
+//     different machines) will serialize equal messages to the same bytes.
+//
+// Note that the deterministic serialization is NOT canonical across
+// languages. It is not guaranteed to remain stable over time. It is unstable
+// across different builds with schema changes due to unknown fields.
+// Users who need canonical serialization (e.g., persistent storage in a
+// canonical form, fingerprinting, etc.) should define their own
+// canonicalization specification and implement their own serializer rather
+// than relying on this API.
+//
+// If deterministic serialization is requested, map entries will be sorted
+// by keys in lexographical order. This is an implementation detail and
+// subject to change.
+func (p *Buffer) SetDeterministic(deterministic bool) {
+	p.deterministic = deterministic
+}
+
 /*
  * Helper routines for simplifying the creation of optional fields of basic type.
  */
@@ -552,9 +628,11 @@ func SetDefaults(pb Message) {
 	setDefaults(reflect.ValueOf(pb), true, false)
 }
 
-// v is a pointer to a struct.
+// v is a struct.
 func setDefaults(v reflect.Value, recur, zeros bool) {
-	v = v.Elem()
+	if v.Kind() == reflect.Ptr {
+		v = v.Elem()
+	}
 
 	defaultMu.RLock()
 	dm, ok := defaults[v.Type()]
@@ -656,8 +734,11 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
 
 	for _, ni := range dm.nested {
 		f := v.Field(ni)
-		// f is *T or []*T or map[T]*T
+		// f is *T or T or []*T or []T
 		switch f.Kind() {
+		case reflect.Struct:
+			setDefaults(f, recur, zeros)
+
 		case reflect.Ptr:
 			if f.IsNil() {
 				continue
@@ -667,7 +748,7 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
 		case reflect.Slice:
 			for i := 0; i < f.Len(); i++ {
 				e := f.Index(i)
-				if e.IsNil() {
+				if e.Kind() == reflect.Ptr && e.IsNil() {
 					continue
 				}
 				setDefaults(e, recur, zeros)
@@ -739,6 +820,9 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
 func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
 	var canHaveDefault bool
 	switch ft.Kind() {
+	case reflect.Struct:
+		nestedMessage = true // non-nullable
+
 	case reflect.Ptr:
 		if ft.Elem().Kind() == reflect.Struct {
 			nestedMessage = true
@@ -748,7 +832,7 @@ func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMes
 
 	case reflect.Slice:
 		switch ft.Elem().Kind() {
-		case reflect.Ptr:
+		case reflect.Ptr, reflect.Struct:
 			nestedMessage = true // repeated message
 		case reflect.Uint8:
 			canHaveDefault = true // bytes field
@@ -831,22 +915,12 @@ func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMes
 	return sf, false, nil
 }
 
+// mapKeys returns a sort.Interface to be used for sorting the map keys.
 // Map fields may have key types of non-float scalars, strings and enums.
-// The easiest way to sort them in some deterministic order is to use fmt.
-// If this turns out to be inefficient we can always consider other options,
-// such as doing a Schwartzian transform.
-
 func mapKeys(vs []reflect.Value) sort.Interface {
-	s := mapKeySorter{
-		vs: vs,
-		// default Less function: textual comparison
-		less: func(a, b reflect.Value) bool {
-			return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
-		},
-	}
+	s := mapKeySorter{vs: vs}
 
-	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
-	// numeric keys are sorted numerically.
+	// Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps.
 	if len(vs) == 0 {
 		return s
 	}
@@ -855,6 +929,12 @@ func mapKeys(vs []reflect.Value) sort.Interface {
 		s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
 	case reflect.Uint32, reflect.Uint64:
 		s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
+	case reflect.Bool:
+		s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true
+	case reflect.String:
+		s.less = func(a, b reflect.Value) bool { return a.String() < b.String() }
+	default:
+		panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind()))
 	}
 
 	return s
@@ -895,3 +975,13 @@ const GoGoProtoPackageIsVersion2 = true
 // ProtoPackageIsVersion1 is referenced from generated protocol buffer files
 // to assert that that code is compatible with this version of the proto package.
 const GoGoProtoPackageIsVersion1 = true
+
+// InternalMessageInfo is a type used internally by generated .pb.go files.
+// This type is not intended to be used by non-generated code.
+// This type is not subject to any compatibility guarantee.
+type InternalMessageInfo struct {
+	marshal   *marshalInfo
+	unmarshal *unmarshalInfo
+	merge     *mergeInfo
+	discard   *discardInfo
+}

+ 8 - 0
vendor/github.com/gogo/protobuf/proto/lib_gogo.go

@@ -33,6 +33,14 @@ import (
 	"strconv"
 )
 
+type Sizer interface {
+	Size() int
+}
+
+type ProtoSizer interface {
+	ProtoSize() int
+}
+
 func MarshalJSONEnum(m map[int32]string, value int32) ([]byte, error) {
 	s, ok := m[value]
 	if !ok {

+ 42 - 39
vendor/github.com/gogo/protobuf/proto/message_set.go

@@ -42,6 +42,7 @@ import (
 	"fmt"
 	"reflect"
 	"sort"
+	"sync"
 )
 
 // errNoMessageTypeID occurs when a protocol buffer does not have a message type ID.
@@ -94,10 +95,7 @@ func (ms *messageSet) find(pb Message) *_MessageSet_Item {
 }
 
 func (ms *messageSet) Has(pb Message) bool {
-	if ms.find(pb) != nil {
-		return true
-	}
-	return false
+	return ms.find(pb) != nil
 }
 
 func (ms *messageSet) Unmarshal(pb Message) error {
@@ -150,46 +148,42 @@ func skipVarint(buf []byte) []byte {
 // MarshalMessageSet encodes the extension map represented by m in the message set wire format.
 // It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
 func MarshalMessageSet(exts interface{}) ([]byte, error) {
-	var m map[int32]Extension
+	return marshalMessageSet(exts, false)
+}
+
+// marshaMessageSet implements above function, with the opt to turn on / off deterministic during Marshal.
+func marshalMessageSet(exts interface{}, deterministic bool) ([]byte, error) {
 	switch exts := exts.(type) {
 	case *XXX_InternalExtensions:
-		if err := encodeExtensions(exts); err != nil {
-			return nil, err
-		}
-		m, _ = exts.extensionsRead()
+		var u marshalInfo
+		siz := u.sizeMessageSet(exts)
+		b := make([]byte, 0, siz)
+		return u.appendMessageSet(b, exts, deterministic)
+
 	case map[int32]Extension:
-		if err := encodeExtensionsMap(exts); err != nil {
-			return nil, err
+		// This is an old-style extension map.
+		// Wrap it in a new-style XXX_InternalExtensions.
+		ie := XXX_InternalExtensions{
+			p: &struct {
+				mu           sync.Mutex
+				extensionMap map[int32]Extension
+			}{
+				extensionMap: exts,
+			},
 		}
-		m = exts
+
+		var u marshalInfo
+		siz := u.sizeMessageSet(&ie)
+		b := make([]byte, 0, siz)
+		return u.appendMessageSet(b, &ie, deterministic)
+
 	default:
 		return nil, errors.New("proto: not an extension map")
 	}
-
-	// Sort extension IDs to provide a deterministic encoding.
-	// See also enc_map in encode.go.
-	ids := make([]int, 0, len(m))
-	for id := range m {
-		ids = append(ids, int(id))
-	}
-	sort.Ints(ids)
-
-	ms := &messageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
-	for _, id := range ids {
-		e := m[int32(id)]
-		// Remove the wire type and field number varint, as well as the length varint.
-		msg := skipVarint(skipVarint(e.enc))
-
-		ms.Item = append(ms.Item, &_MessageSet_Item{
-			TypeId:  Int32(int32(id)),
-			Message: msg,
-		})
-	}
-	return Marshal(ms)
 }
 
 // UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
-// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
+// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
 func UnmarshalMessageSet(buf []byte, exts interface{}) error {
 	var m map[int32]Extension
 	switch exts := exts.(type) {
@@ -235,7 +229,15 @@ func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
 	var m map[int32]Extension
 	switch exts := exts.(type) {
 	case *XXX_InternalExtensions:
-		m, _ = exts.extensionsRead()
+		var mu sync.Locker
+		m, mu = exts.extensionsRead()
+		if m != nil {
+			// Keep the extensions map locked until we're done marshaling to prevent
+			// races between marshaling and unmarshaling the lazily-{en,de}coded
+			// values.
+			mu.Lock()
+			defer mu.Unlock()
+		}
 	case map[int32]Extension:
 		m = exts
 	default:
@@ -253,15 +255,16 @@ func MarshalMessageSetJSON(exts interface{}) ([]byte, error) {
 
 	for i, id := range ids {
 		ext := m[id]
-		if i > 0 {
-			b.WriteByte(',')
-		}
-
 		msd, ok := messageSetMap[id]
 		if !ok {
 			// Unknown type; we can't render it, so skip it.
 			continue
 		}
+
+		if i > 0 && b.Len() > 1 {
+			b.WriteByte(',')
+		}
+
 		fmt.Fprintf(&b, `"[%s]":`, msd.name)
 
 		x := ext.value

+ 234 - 361
vendor/github.com/gogo/protobuf/proto/pointer_reflect.go

@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build appengine js
+// +build purego appengine js
 
 // This file contains an implementation of proto field accesses using package reflect.
 // It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
@@ -38,32 +38,13 @@
 package proto
 
 import (
-	"math"
 	"reflect"
+	"sync"
 )
 
-// A structPointer is a pointer to a struct.
-type structPointer struct {
-	v reflect.Value
-}
-
-// toStructPointer returns a structPointer equivalent to the given reflect value.
-// The reflect value must itself be a pointer to a struct.
-func toStructPointer(v reflect.Value) structPointer {
-	return structPointer{v}
-}
-
-// IsNil reports whether p is nil.
-func structPointer_IsNil(p structPointer) bool {
-	return p.v.IsNil()
-}
+const unsafeAllowed = false
 
-// Interface returns the struct pointer as an interface value.
-func structPointer_Interface(p structPointer, _ reflect.Type) interface{} {
-	return p.v.Interface()
-}
-
-// A field identifies a field in a struct, accessible from a structPointer.
+// A field identifies a field in a struct, accessible from a pointer.
 // In this implementation, a field is identified by the sequence of field indices
 // passed to reflect's FieldByIndex.
 type field []int
@@ -76,409 +57,301 @@ func toField(f *reflect.StructField) field {
 // invalidField is an invalid field identifier.
 var invalidField = field(nil)
 
+// zeroField is a noop when calling pointer.offset.
+var zeroField = field([]int{})
+
 // IsValid reports whether the field identifier is valid.
 func (f field) IsValid() bool { return f != nil }
 
-// field returns the given field in the struct as a reflect value.
-func structPointer_field(p structPointer, f field) reflect.Value {
-	// Special case: an extension map entry with a value of type T
-	// passes a *T to the struct-handling code with a zero field,
-	// expecting that it will be treated as equivalent to *struct{ X T },
-	// which has the same memory layout. We have to handle that case
-	// specially, because reflect will panic if we call FieldByIndex on a
-	// non-struct.
-	if f == nil {
-		return p.v.Elem()
-	}
-
-	return p.v.Elem().FieldByIndex(f)
+// The pointer type is for the table-driven decoder.
+// The implementation here uses a reflect.Value of pointer type to
+// create a generic pointer. In pointer_unsafe.go we use unsafe
+// instead of reflect to implement the same (but faster) interface.
+type pointer struct {
+	v reflect.Value
 }
 
-// ifield returns the given field in the struct as an interface value.
-func structPointer_ifield(p structPointer, f field) interface{} {
-	return structPointer_field(p, f).Addr().Interface()
+// toPointer converts an interface of pointer type to a pointer
+// that points to the same target.
+func toPointer(i *Message) pointer {
+	return pointer{v: reflect.ValueOf(*i)}
 }
 
-// Bytes returns the address of a []byte field in the struct.
-func structPointer_Bytes(p structPointer, f field) *[]byte {
-	return structPointer_ifield(p, f).(*[]byte)
+// toAddrPointer converts an interface to a pointer that points to
+// the interface data.
+func toAddrPointer(i *interface{}, isptr bool) pointer {
+	v := reflect.ValueOf(*i)
+	u := reflect.New(v.Type())
+	u.Elem().Set(v)
+	return pointer{v: u}
 }
 
-// BytesSlice returns the address of a [][]byte field in the struct.
-func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
-	return structPointer_ifield(p, f).(*[][]byte)
+// valToPointer converts v to a pointer.  v must be of pointer type.
+func valToPointer(v reflect.Value) pointer {
+	return pointer{v: v}
 }
 
-// Bool returns the address of a *bool field in the struct.
-func structPointer_Bool(p structPointer, f field) **bool {
-	return structPointer_ifield(p, f).(**bool)
+// offset converts from a pointer to a structure to a pointer to
+// one of its fields.
+func (p pointer) offset(f field) pointer {
+	return pointer{v: p.v.Elem().FieldByIndex(f).Addr()}
 }
 
-// BoolVal returns the address of a bool field in the struct.
-func structPointer_BoolVal(p structPointer, f field) *bool {
-	return structPointer_ifield(p, f).(*bool)
+func (p pointer) isNil() bool {
+	return p.v.IsNil()
 }
 
-// BoolSlice returns the address of a []bool field in the struct.
-func structPointer_BoolSlice(p structPointer, f field) *[]bool {
-	return structPointer_ifield(p, f).(*[]bool)
+// grow updates the slice s in place to make it one element longer.
+// s must be addressable.
+// Returns the (addressable) new element.
+func grow(s reflect.Value) reflect.Value {
+	n, m := s.Len(), s.Cap()
+	if n < m {
+		s.SetLen(n + 1)
+	} else {
+		s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem())))
+	}
+	return s.Index(n)
 }
 
-// String returns the address of a *string field in the struct.
-func structPointer_String(p structPointer, f field) **string {
-	return structPointer_ifield(p, f).(**string)
+func (p pointer) toInt64() *int64 {
+	return p.v.Interface().(*int64)
 }
-
-// StringVal returns the address of a string field in the struct.
-func structPointer_StringVal(p structPointer, f field) *string {
-	return structPointer_ifield(p, f).(*string)
+func (p pointer) toInt64Ptr() **int64 {
+	return p.v.Interface().(**int64)
 }
-
-// StringSlice returns the address of a []string field in the struct.
-func structPointer_StringSlice(p structPointer, f field) *[]string {
-	return structPointer_ifield(p, f).(*[]string)
+func (p pointer) toInt64Slice() *[]int64 {
+	return p.v.Interface().(*[]int64)
 }
 
-// Extensions returns the address of an extension map field in the struct.
-func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
-	return structPointer_ifield(p, f).(*XXX_InternalExtensions)
-}
+var int32ptr = reflect.TypeOf((*int32)(nil))
 
-// ExtMap returns the address of an extension map field in the struct.
-func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
-	return structPointer_ifield(p, f).(*map[int32]Extension)
+func (p pointer) toInt32() *int32 {
+	return p.v.Convert(int32ptr).Interface().(*int32)
 }
 
-// NewAt returns the reflect.Value for a pointer to a field in the struct.
-func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
-	return structPointer_field(p, f).Addr()
+// The toInt32Ptr/Slice methods don't work because of enums.
+// Instead, we must use set/get methods for the int32ptr/slice case.
+/*
+	func (p pointer) toInt32Ptr() **int32 {
+		return p.v.Interface().(**int32)
 }
-
-// SetStructPointer writes a *struct field in the struct.
-func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
-	structPointer_field(p, f).Set(q.v)
+	func (p pointer) toInt32Slice() *[]int32 {
+		return p.v.Interface().(*[]int32)
 }
-
-// GetStructPointer reads a *struct field in the struct.
-func structPointer_GetStructPointer(p structPointer, f field) structPointer {
-	return structPointer{structPointer_field(p, f)}
+*/
+func (p pointer) getInt32Ptr() *int32 {
+	if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
+		// raw int32 type
+		return p.v.Elem().Interface().(*int32)
+	}
+	// an enum
+	return p.v.Elem().Convert(int32PtrType).Interface().(*int32)
+}
+func (p pointer) setInt32Ptr(v int32) {
+	// Allocate value in a *int32. Possibly convert that to a *enum.
+	// Then assign it to a **int32 or **enum.
+	// Note: we can convert *int32 to *enum, but we can't convert
+	// **int32 to **enum!
+	p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem()))
+}
+
+// getInt32Slice copies []int32 from p as a new slice.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) getInt32Slice() []int32 {
+	if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
+		// raw int32 type
+		return p.v.Elem().Interface().([]int32)
+	}
+	// an enum
+	// Allocate a []int32, then assign []enum's values into it.
+	// Note: we can't convert []enum to []int32.
+	slice := p.v.Elem()
+	s := make([]int32, slice.Len())
+	for i := 0; i < slice.Len(); i++ {
+		s[i] = int32(slice.Index(i).Int())
+	}
+	return s
 }
 
-// StructPointerSlice the address of a []*struct field in the struct.
-func structPointer_StructPointerSlice(p structPointer, f field) structPointerSlice {
-	return structPointerSlice{structPointer_field(p, f)}
+// setInt32Slice copies []int32 into p as a new slice.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) setInt32Slice(v []int32) {
+	if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) {
+		// raw int32 type
+		p.v.Elem().Set(reflect.ValueOf(v))
+		return
+	}
+	// an enum
+	// Allocate a []enum, then assign []int32's values into it.
+	// Note: we can't convert []enum to []int32.
+	slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v))
+	for i, x := range v {
+		slice.Index(i).SetInt(int64(x))
+	}
+	p.v.Elem().Set(slice)
 }
-
-// A structPointerSlice represents the address of a slice of pointers to structs
-// (themselves messages or groups). That is, v.Type() is *[]*struct{...}.
-type structPointerSlice struct {
-	v reflect.Value
+func (p pointer) appendInt32Slice(v int32) {
+	grow(p.v.Elem()).SetInt(int64(v))
 }
 
-func (p structPointerSlice) Len() int                  { return p.v.Len() }
-func (p structPointerSlice) Index(i int) structPointer { return structPointer{p.v.Index(i)} }
-func (p structPointerSlice) Append(q structPointer) {
-	p.v.Set(reflect.Append(p.v, q.v))
+func (p pointer) toUint64() *uint64 {
+	return p.v.Interface().(*uint64)
 }
-
-var (
-	int32Type   = reflect.TypeOf(int32(0))
-	uint32Type  = reflect.TypeOf(uint32(0))
-	float32Type = reflect.TypeOf(float32(0))
-	int64Type   = reflect.TypeOf(int64(0))
-	uint64Type  = reflect.TypeOf(uint64(0))
-	float64Type = reflect.TypeOf(float64(0))
-)
-
-// A word32 represents a field of type *int32, *uint32, *float32, or *enum.
-// That is, v.Type() is *int32, *uint32, *float32, or *enum and v is assignable.
-type word32 struct {
-	v reflect.Value
+func (p pointer) toUint64Ptr() **uint64 {
+	return p.v.Interface().(**uint64)
 }
-
-// IsNil reports whether p is nil.
-func word32_IsNil(p word32) bool {
-	return p.v.IsNil()
+func (p pointer) toUint64Slice() *[]uint64 {
+	return p.v.Interface().(*[]uint64)
 }
-
-// Set sets p to point at a newly allocated word with bits set to x.
-func word32_Set(p word32, o *Buffer, x uint32) {
-	t := p.v.Type().Elem()
-	switch t {
-	case int32Type:
-		if len(o.int32s) == 0 {
-			o.int32s = make([]int32, uint32PoolSize)
-		}
-		o.int32s[0] = int32(x)
-		p.v.Set(reflect.ValueOf(&o.int32s[0]))
-		o.int32s = o.int32s[1:]
-		return
-	case uint32Type:
-		if len(o.uint32s) == 0 {
-			o.uint32s = make([]uint32, uint32PoolSize)
-		}
-		o.uint32s[0] = x
-		p.v.Set(reflect.ValueOf(&o.uint32s[0]))
-		o.uint32s = o.uint32s[1:]
-		return
-	case float32Type:
-		if len(o.float32s) == 0 {
-			o.float32s = make([]float32, uint32PoolSize)
-		}
-		o.float32s[0] = math.Float32frombits(x)
-		p.v.Set(reflect.ValueOf(&o.float32s[0]))
-		o.float32s = o.float32s[1:]
-		return
-	}
-
-	// must be enum
-	p.v.Set(reflect.New(t))
-	p.v.Elem().SetInt(int64(int32(x)))
+func (p pointer) toUint32() *uint32 {
+	return p.v.Interface().(*uint32)
 }
-
-// Get gets the bits pointed at by p, as a uint32.
-func word32_Get(p word32) uint32 {
-	elem := p.v.Elem()
-	switch elem.Kind() {
-	case reflect.Int32:
-		return uint32(elem.Int())
-	case reflect.Uint32:
-		return uint32(elem.Uint())
-	case reflect.Float32:
-		return math.Float32bits(float32(elem.Float()))
-	}
-	panic("unreachable")
+func (p pointer) toUint32Ptr() **uint32 {
+	return p.v.Interface().(**uint32)
 }
-
-// Word32 returns a reference to a *int32, *uint32, *float32, or *enum field in the struct.
-func structPointer_Word32(p structPointer, f field) word32 {
-	return word32{structPointer_field(p, f)}
+func (p pointer) toUint32Slice() *[]uint32 {
+	return p.v.Interface().(*[]uint32)
 }
-
-// A word32Val represents a field of type int32, uint32, float32, or enum.
-// That is, v.Type() is int32, uint32, float32, or enum and v is assignable.
-type word32Val struct {
-	v reflect.Value
+func (p pointer) toBool() *bool {
+	return p.v.Interface().(*bool)
 }
-
-// Set sets *p to x.
-func word32Val_Set(p word32Val, x uint32) {
-	switch p.v.Type() {
-	case int32Type:
-		p.v.SetInt(int64(x))
-		return
-	case uint32Type:
-		p.v.SetUint(uint64(x))
-		return
-	case float32Type:
-		p.v.SetFloat(float64(math.Float32frombits(x)))
-		return
-	}
-
-	// must be enum
-	p.v.SetInt(int64(int32(x)))
+func (p pointer) toBoolPtr() **bool {
+	return p.v.Interface().(**bool)
 }
-
-// Get gets the bits pointed at by p, as a uint32.
-func word32Val_Get(p word32Val) uint32 {
-	elem := p.v
-	switch elem.Kind() {
-	case reflect.Int32:
-		return uint32(elem.Int())
-	case reflect.Uint32:
-		return uint32(elem.Uint())
-	case reflect.Float32:
-		return math.Float32bits(float32(elem.Float()))
-	}
-	panic("unreachable")
+func (p pointer) toBoolSlice() *[]bool {
+	return p.v.Interface().(*[]bool)
 }
-
-// Word32Val returns a reference to a int32, uint32, float32, or enum field in the struct.
-func structPointer_Word32Val(p structPointer, f field) word32Val {
-	return word32Val{structPointer_field(p, f)}
+func (p pointer) toFloat64() *float64 {
+	return p.v.Interface().(*float64)
 }
-
-// A word32Slice is a slice of 32-bit values.
-// That is, v.Type() is []int32, []uint32, []float32, or []enum.
-type word32Slice struct {
-	v reflect.Value
+func (p pointer) toFloat64Ptr() **float64 {
+	return p.v.Interface().(**float64)
 }
-
-func (p word32Slice) Append(x uint32) {
-	n, m := p.v.Len(), p.v.Cap()
-	if n < m {
-		p.v.SetLen(n + 1)
-	} else {
-		t := p.v.Type().Elem()
-		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
-	}
-	elem := p.v.Index(n)
-	switch elem.Kind() {
-	case reflect.Int32:
-		elem.SetInt(int64(int32(x)))
-	case reflect.Uint32:
-		elem.SetUint(uint64(x))
-	case reflect.Float32:
-		elem.SetFloat(float64(math.Float32frombits(x)))
-	}
+func (p pointer) toFloat64Slice() *[]float64 {
+	return p.v.Interface().(*[]float64)
 }
-
-func (p word32Slice) Len() int {
-	return p.v.Len()
+func (p pointer) toFloat32() *float32 {
+	return p.v.Interface().(*float32)
 }
-
-func (p word32Slice) Index(i int) uint32 {
-	elem := p.v.Index(i)
-	switch elem.Kind() {
-	case reflect.Int32:
-		return uint32(elem.Int())
-	case reflect.Uint32:
-		return uint32(elem.Uint())
-	case reflect.Float32:
-		return math.Float32bits(float32(elem.Float()))
-	}
-	panic("unreachable")
+func (p pointer) toFloat32Ptr() **float32 {
+	return p.v.Interface().(**float32)
 }
-
-// Word32Slice returns a reference to a []int32, []uint32, []float32, or []enum field in the struct.
-func structPointer_Word32Slice(p structPointer, f field) word32Slice {
-	return word32Slice{structPointer_field(p, f)}
+func (p pointer) toFloat32Slice() *[]float32 {
+	return p.v.Interface().(*[]float32)
 }
-
-// word64 is like word32 but for 64-bit values.
-type word64 struct {
-	v reflect.Value
+func (p pointer) toString() *string {
+	return p.v.Interface().(*string)
 }
-
-func word64_Set(p word64, o *Buffer, x uint64) {
-	t := p.v.Type().Elem()
-	switch t {
-	case int64Type:
-		if len(o.int64s) == 0 {
-			o.int64s = make([]int64, uint64PoolSize)
-		}
-		o.int64s[0] = int64(x)
-		p.v.Set(reflect.ValueOf(&o.int64s[0]))
-		o.int64s = o.int64s[1:]
-		return
-	case uint64Type:
-		if len(o.uint64s) == 0 {
-			o.uint64s = make([]uint64, uint64PoolSize)
-		}
-		o.uint64s[0] = x
-		p.v.Set(reflect.ValueOf(&o.uint64s[0]))
-		o.uint64s = o.uint64s[1:]
-		return
-	case float64Type:
-		if len(o.float64s) == 0 {
-			o.float64s = make([]float64, uint64PoolSize)
-		}
-		o.float64s[0] = math.Float64frombits(x)
-		p.v.Set(reflect.ValueOf(&o.float64s[0]))
-		o.float64s = o.float64s[1:]
-		return
-	}
-	panic("unreachable")
+func (p pointer) toStringPtr() **string {
+	return p.v.Interface().(**string)
 }
-
-func word64_IsNil(p word64) bool {
-	return p.v.IsNil()
+func (p pointer) toStringSlice() *[]string {
+	return p.v.Interface().(*[]string)
 }
-
-func word64_Get(p word64) uint64 {
-	elem := p.v.Elem()
-	switch elem.Kind() {
-	case reflect.Int64:
-		return uint64(elem.Int())
-	case reflect.Uint64:
-		return elem.Uint()
-	case reflect.Float64:
-		return math.Float64bits(elem.Float())
-	}
-	panic("unreachable")
+func (p pointer) toBytes() *[]byte {
+	return p.v.Interface().(*[]byte)
 }
-
-func structPointer_Word64(p structPointer, f field) word64 {
-	return word64{structPointer_field(p, f)}
+func (p pointer) toBytesSlice() *[][]byte {
+	return p.v.Interface().(*[][]byte)
+}
+func (p pointer) toExtensions() *XXX_InternalExtensions {
+	return p.v.Interface().(*XXX_InternalExtensions)
+}
+func (p pointer) toOldExtensions() *map[int32]Extension {
+	return p.v.Interface().(*map[int32]Extension)
+}
+func (p pointer) getPointer() pointer {
+	return pointer{v: p.v.Elem()}
+}
+func (p pointer) setPointer(q pointer) {
+	p.v.Elem().Set(q.v)
+}
+func (p pointer) appendPointer(q pointer) {
+	grow(p.v.Elem()).Set(q.v)
 }
 
-// word64Val is like word32Val but for 64-bit values.
-type word64Val struct {
-	v reflect.Value
+// getPointerSlice copies []*T from p as a new []pointer.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) getPointerSlice() []pointer {
+	if p.v.IsNil() {
+		return nil
+	}
+	n := p.v.Elem().Len()
+	s := make([]pointer, n)
+	for i := 0; i < n; i++ {
+		s[i] = pointer{v: p.v.Elem().Index(i)}
+	}
+	return s
 }
 
-func word64Val_Set(p word64Val, o *Buffer, x uint64) {
-	switch p.v.Type() {
-	case int64Type:
-		p.v.SetInt(int64(x))
-		return
-	case uint64Type:
-		p.v.SetUint(x)
-		return
-	case float64Type:
-		p.v.SetFloat(math.Float64frombits(x))
+// setPointerSlice copies []pointer into p as a new []*T.
+// This behavior differs from the implementation in pointer_unsafe.go.
+func (p pointer) setPointerSlice(v []pointer) {
+	if v == nil {
+		p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem())
 		return
 	}
-	panic("unreachable")
+	s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v))
+	for _, p := range v {
+		s = reflect.Append(s, p.v)
+	}
+	p.v.Elem().Set(s)
 }
 
-func word64Val_Get(p word64Val) uint64 {
-	elem := p.v
-	switch elem.Kind() {
-	case reflect.Int64:
-		return uint64(elem.Int())
-	case reflect.Uint64:
-		return elem.Uint()
-	case reflect.Float64:
-		return math.Float64bits(elem.Float())
+// getInterfacePointer returns a pointer that points to the
+// interface data of the interface pointed by p.
+func (p pointer) getInterfacePointer() pointer {
+	if p.v.Elem().IsNil() {
+		return pointer{v: p.v.Elem()}
 	}
-	panic("unreachable")
+	return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct
 }
 
-func structPointer_Word64Val(p structPointer, f field) word64Val {
-	return word64Val{structPointer_field(p, f)}
+func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
+	// TODO: check that p.v.Type().Elem() == t?
+	return p.v
 }
 
-type word64Slice struct {
-	v reflect.Value
+func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	return *p
 }
-
-func (p word64Slice) Append(x uint64) {
-	n, m := p.v.Len(), p.v.Cap()
-	if n < m {
-		p.v.SetLen(n + 1)
-	} else {
-		t := p.v.Type().Elem()
-		p.v.Set(reflect.Append(p.v, reflect.Zero(t)))
-	}
-	elem := p.v.Index(n)
-	switch elem.Kind() {
-	case reflect.Int64:
-		elem.SetInt(int64(int64(x)))
-	case reflect.Uint64:
-		elem.SetUint(uint64(x))
-	case reflect.Float64:
-		elem.SetFloat(float64(math.Float64frombits(x)))
-	}
+func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	*p = v
 }
-
-func (p word64Slice) Len() int {
-	return p.v.Len()
+func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	return *p
 }
-
-func (p word64Slice) Index(i int) uint64 {
-	elem := p.v.Index(i)
-	switch elem.Kind() {
-	case reflect.Int64:
-		return uint64(elem.Int())
-	case reflect.Uint64:
-		return uint64(elem.Uint())
-	case reflect.Float64:
-		return math.Float64bits(float64(elem.Float()))
-	}
-	panic("unreachable")
+func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	*p = v
 }
-
-func structPointer_Word64Slice(p structPointer, f field) word64Slice {
-	return word64Slice{structPointer_field(p, f)}
+func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	return *p
+}
+func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	*p = v
 }
+func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	return *p
+}
+func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
+	atomicLock.Lock()
+	defer atomicLock.Unlock()
+	*p = v
+}
+
+var atomicLock sync.Mutex

+ 19 - 45
vendor/github.com/gogo/protobuf/proto/pointer_reflect_gogo.go

@@ -1,6 +1,6 @@
 // Protocol Buffers for Go with Gadgets
 //
-// Copyright (c) 2016, The GoGo Authors. All rights reserved.
+// Copyright (c) 2018, The GoGo Authors. All rights reserved.
 // http://github.com/gogo/protobuf
 //
 // Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,11 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build appengine js
+// +build purego appengine js
+
+// This file contains an implementation of proto field accesses using package reflect.
+// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
+// be used on App Engine.
 
 package proto
 
@@ -34,52 +38,22 @@ import (
 	"reflect"
 )
 
-func structPointer_FieldPointer(p structPointer, f field) structPointer {
-	panic("not implemented")
-}
-
-func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer {
-	panic("not implemented")
-}
-
-func structPointer_InterfaceAt(p structPointer, f field, t reflect.Type) interface{} {
-	panic("not implemented")
-}
-
-func structPointer_InterfaceRef(p structPointer, f field, t reflect.Type) interface{} {
-	panic("not implemented")
-}
-
-func structPointer_GetRefStructPointer(p structPointer, f field) structPointer {
-	panic("not implemented")
-}
+// TODO: untested, so probably incorrect.
 
-func structPointer_Add(p structPointer, size field) structPointer {
-	panic("not implemented")
+func (p pointer) getRef() pointer {
+	return pointer{v: p.v.Addr()}
 }
 
-func structPointer_Len(p structPointer, f field) int {
-	panic("not implemented")
-}
-
-func structPointer_GetSliceHeader(p structPointer, f field) *reflect.SliceHeader {
-	panic("not implemented")
-}
-
-func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) {
-	panic("not implemented")
-}
-
-func structPointer_StructRefSlice(p structPointer, f field, size uintptr) *structRefSlice {
-	panic("not implemented")
-}
-
-type structRefSlice struct{}
-
-func (v *structRefSlice) Len() int {
-	panic("not implemented")
+func (p pointer) appendRef(v pointer, typ reflect.Type) {
+	slice := p.getSlice(typ)
+	elem := v.asPointerTo(typ).Elem()
+	newSlice := reflect.Append(slice, elem)
+	slice.Set(newSlice)
 }
 
-func (v *structRefSlice) Index(i int) structPointer {
-	panic("not implemented")
+func (p pointer) getSlice(typ reflect.Type) reflect.Value {
+	sliceTyp := reflect.SliceOf(typ)
+	slice := p.asPointerTo(sliceTyp)
+	slice = slice.Elem()
+	return slice
 }

+ 202 - 164
vendor/github.com/gogo/protobuf/proto/pointer_unsafe.go

@@ -29,7 +29,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build !appengine,!js
+// +build !purego,!appengine,!js
 
 // This file contains the implementation of the proto field accesses using package unsafe.
 
@@ -37,38 +37,13 @@ package proto
 
 import (
 	"reflect"
+	"sync/atomic"
 	"unsafe"
 )
 
-// NOTE: These type_Foo functions would more idiomatically be methods,
-// but Go does not allow methods on pointer types, and we must preserve
-// some pointer type for the garbage collector. We use these
-// funcs with clunky names as our poor approximation to methods.
-//
-// An alternative would be
-//	type structPointer struct { p unsafe.Pointer }
-// but that does not registerize as well.
-
-// A structPointer is a pointer to a struct.
-type structPointer unsafe.Pointer
-
-// toStructPointer returns a structPointer equivalent to the given reflect value.
-func toStructPointer(v reflect.Value) structPointer {
-	return structPointer(unsafe.Pointer(v.Pointer()))
-}
-
-// IsNil reports whether p is nil.
-func structPointer_IsNil(p structPointer) bool {
-	return p == nil
-}
-
-// Interface returns the struct pointer, assumed to have element type t,
-// as an interface value.
-func structPointer_Interface(p structPointer, t reflect.Type) interface{} {
-	return reflect.NewAt(t, unsafe.Pointer(p)).Interface()
-}
+const unsafeAllowed = true
 
-// A field identifies a field in a struct, accessible from a structPointer.
+// A field identifies a field in a struct, accessible from a pointer.
 // In this implementation, a field is identified by its byte offset from the start of the struct.
 type field uintptr
 
@@ -80,191 +55,254 @@ func toField(f *reflect.StructField) field {
 // invalidField is an invalid field identifier.
 const invalidField = ^field(0)
 
+// zeroField is a noop when calling pointer.offset.
+const zeroField = field(0)
+
 // IsValid reports whether the field identifier is valid.
 func (f field) IsValid() bool {
-	return f != ^field(0)
+	return f != invalidField
 }
 
-// Bytes returns the address of a []byte field in the struct.
-func structPointer_Bytes(p structPointer, f field) *[]byte {
-	return (*[]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+// The pointer type below is for the new table-driven encoder/decoder.
+// The implementation here uses unsafe.Pointer to create a generic pointer.
+// In pointer_reflect.go we use reflect instead of unsafe to implement
+// the same (but slower) interface.
+type pointer struct {
+	p unsafe.Pointer
 }
 
-// BytesSlice returns the address of a [][]byte field in the struct.
-func structPointer_BytesSlice(p structPointer, f field) *[][]byte {
-	return (*[][]byte)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
+// size of pointer
+var ptrSize = unsafe.Sizeof(uintptr(0))
 
-// Bool returns the address of a *bool field in the struct.
-func structPointer_Bool(p structPointer, f field) **bool {
-	return (**bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+// toPointer converts an interface of pointer type to a pointer
+// that points to the same target.
+func toPointer(i *Message) pointer {
+	// Super-tricky - read pointer out of data word of interface value.
+	// Saves ~25ns over the equivalent:
+	// return valToPointer(reflect.ValueOf(*i))
+	return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
 }
 
-// BoolVal returns the address of a bool field in the struct.
-func structPointer_BoolVal(p structPointer, f field) *bool {
-	return (*bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+// toAddrPointer converts an interface to a pointer that points to
+// the interface data.
+func toAddrPointer(i *interface{}, isptr bool) pointer {
+	// Super-tricky - read or get the address of data word of interface value.
+	if isptr {
+		// The interface is of pointer type, thus it is a direct interface.
+		// The data word is the pointer data itself. We take its address.
+		return pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)}
+	}
+	// The interface is not of pointer type. The data word is the pointer
+	// to the data.
+	return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]}
 }
 
-// BoolSlice returns the address of a []bool field in the struct.
-func structPointer_BoolSlice(p structPointer, f field) *[]bool {
-	return (*[]bool)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+// valToPointer converts v to a pointer. v must be of pointer type.
+func valToPointer(v reflect.Value) pointer {
+	return pointer{p: unsafe.Pointer(v.Pointer())}
 }
 
-// String returns the address of a *string field in the struct.
-func structPointer_String(p structPointer, f field) **string {
-	return (**string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+// offset converts from a pointer to a structure to a pointer to
+// one of its fields.
+func (p pointer) offset(f field) pointer {
+	// For safety, we should panic if !f.IsValid, however calling panic causes
+	// this to no longer be inlineable, which is a serious performance cost.
+	/*
+		if !f.IsValid() {
+			panic("invalid field")
+		}
+	*/
+	return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))}
 }
 
-// StringVal returns the address of a string field in the struct.
-func structPointer_StringVal(p structPointer, f field) *string {
-	return (*string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+func (p pointer) isNil() bool {
+	return p.p == nil
 }
 
-// StringSlice returns the address of a []string field in the struct.
-func structPointer_StringSlice(p structPointer, f field) *[]string {
-	return (*[]string)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+func (p pointer) toInt64() *int64 {
+	return (*int64)(p.p)
 }
-
-// ExtMap returns the address of an extension map field in the struct.
-func structPointer_Extensions(p structPointer, f field) *XXX_InternalExtensions {
-	return (*XXX_InternalExtensions)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+func (p pointer) toInt64Ptr() **int64 {
+	return (**int64)(p.p)
 }
-
-func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
-	return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+func (p pointer) toInt64Slice() *[]int64 {
+	return (*[]int64)(p.p)
 }
-
-// NewAt returns the reflect.Value for a pointer to a field in the struct.
-func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
-	return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
+func (p pointer) toInt32() *int32 {
+	return (*int32)(p.p)
 }
 
-// SetStructPointer writes a *struct field in the struct.
-func structPointer_SetStructPointer(p structPointer, f field, q structPointer) {
-	*(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))) = q
+// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist.
+/*
+	func (p pointer) toInt32Ptr() **int32 {
+		return (**int32)(p.p)
+	}
+	func (p pointer) toInt32Slice() *[]int32 {
+		return (*[]int32)(p.p)
+	}
+*/
+func (p pointer) getInt32Ptr() *int32 {
+	return *(**int32)(p.p)
 }
-
-// GetStructPointer reads a *struct field in the struct.
-func structPointer_GetStructPointer(p structPointer, f field) structPointer {
-	return *(*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+func (p pointer) setInt32Ptr(v int32) {
+	*(**int32)(p.p) = &v
 }
 
-// StructPointerSlice the address of a []*struct field in the struct.
-func structPointer_StructPointerSlice(p structPointer, f field) *structPointerSlice {
-	return (*structPointerSlice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+// getInt32Slice loads a []int32 from p.
+// The value returned is aliased with the original slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) getInt32Slice() []int32 {
+	return *(*[]int32)(p.p)
 }
 
-// A structPointerSlice represents a slice of pointers to structs (themselves submessages or groups).
-type structPointerSlice []structPointer
-
-func (v *structPointerSlice) Len() int                  { return len(*v) }
-func (v *structPointerSlice) Index(i int) structPointer { return (*v)[i] }
-func (v *structPointerSlice) Append(p structPointer)    { *v = append(*v, p) }
-
-// A word32 is the address of a "pointer to 32-bit value" field.
-type word32 **uint32
-
-// IsNil reports whether *v is nil.
-func word32_IsNil(p word32) bool {
-	return *p == nil
+// setInt32Slice stores a []int32 to p.
+// The value set is aliased with the input slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) setInt32Slice(v []int32) {
+	*(*[]int32)(p.p) = v
 }
 
-// Set sets *v to point at a newly allocated word set to x.
-func word32_Set(p word32, o *Buffer, x uint32) {
-	if len(o.uint32s) == 0 {
-		o.uint32s = make([]uint32, uint32PoolSize)
-	}
-	o.uint32s[0] = x
-	*p = &o.uint32s[0]
-	o.uint32s = o.uint32s[1:]
+// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead?
+func (p pointer) appendInt32Slice(v int32) {
+	s := (*[]int32)(p.p)
+	*s = append(*s, v)
 }
 
-// Get gets the value pointed at by *v.
-func word32_Get(p word32) uint32 {
-	return **p
+func (p pointer) toUint64() *uint64 {
+	return (*uint64)(p.p)
 }
-
-// Word32 returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
-func structPointer_Word32(p structPointer, f field) word32 {
-	return word32((**uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+func (p pointer) toUint64Ptr() **uint64 {
+	return (**uint64)(p.p)
 }
-
-// A word32Val is the address of a 32-bit value field.
-type word32Val *uint32
-
-// Set sets *p to x.
-func word32Val_Set(p word32Val, x uint32) {
-	*p = x
+func (p pointer) toUint64Slice() *[]uint64 {
+	return (*[]uint64)(p.p)
 }
-
-// Get gets the value pointed at by p.
-func word32Val_Get(p word32Val) uint32 {
-	return *p
+func (p pointer) toUint32() *uint32 {
+	return (*uint32)(p.p)
 }
-
-// Word32Val returns the address of a *int32, *uint32, *float32, or *enum field in the struct.
-func structPointer_Word32Val(p structPointer, f field) word32Val {
-	return word32Val((*uint32)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+func (p pointer) toUint32Ptr() **uint32 {
+	return (**uint32)(p.p)
 }
-
-// A word32Slice is a slice of 32-bit values.
-type word32Slice []uint32
-
-func (v *word32Slice) Append(x uint32)    { *v = append(*v, x) }
-func (v *word32Slice) Len() int           { return len(*v) }
-func (v *word32Slice) Index(i int) uint32 { return (*v)[i] }
-
-// Word32Slice returns the address of a []int32, []uint32, []float32, or []enum field in the struct.
-func structPointer_Word32Slice(p structPointer, f field) *word32Slice {
-	return (*word32Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+func (p pointer) toUint32Slice() *[]uint32 {
+	return (*[]uint32)(p.p)
 }
-
-// word64 is like word32 but for 64-bit values.
-type word64 **uint64
-
-func word64_Set(p word64, o *Buffer, x uint64) {
-	if len(o.uint64s) == 0 {
-		o.uint64s = make([]uint64, uint64PoolSize)
-	}
-	o.uint64s[0] = x
-	*p = &o.uint64s[0]
-	o.uint64s = o.uint64s[1:]
+func (p pointer) toBool() *bool {
+	return (*bool)(p.p)
 }
-
-func word64_IsNil(p word64) bool {
-	return *p == nil
+func (p pointer) toBoolPtr() **bool {
+	return (**bool)(p.p)
 }
-
-func word64_Get(p word64) uint64 {
-	return **p
+func (p pointer) toBoolSlice() *[]bool {
+	return (*[]bool)(p.p)
+}
+func (p pointer) toFloat64() *float64 {
+	return (*float64)(p.p)
+}
+func (p pointer) toFloat64Ptr() **float64 {
+	return (**float64)(p.p)
+}
+func (p pointer) toFloat64Slice() *[]float64 {
+	return (*[]float64)(p.p)
+}
+func (p pointer) toFloat32() *float32 {
+	return (*float32)(p.p)
+}
+func (p pointer) toFloat32Ptr() **float32 {
+	return (**float32)(p.p)
+}
+func (p pointer) toFloat32Slice() *[]float32 {
+	return (*[]float32)(p.p)
+}
+func (p pointer) toString() *string {
+	return (*string)(p.p)
+}
+func (p pointer) toStringPtr() **string {
+	return (**string)(p.p)
+}
+func (p pointer) toStringSlice() *[]string {
+	return (*[]string)(p.p)
+}
+func (p pointer) toBytes() *[]byte {
+	return (*[]byte)(p.p)
+}
+func (p pointer) toBytesSlice() *[][]byte {
+	return (*[][]byte)(p.p)
+}
+func (p pointer) toExtensions() *XXX_InternalExtensions {
+	return (*XXX_InternalExtensions)(p.p)
+}
+func (p pointer) toOldExtensions() *map[int32]Extension {
+	return (*map[int32]Extension)(p.p)
 }
 
-func structPointer_Word64(p structPointer, f field) word64 {
-	return word64((**uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+// getPointerSlice loads []*T from p as a []pointer.
+// The value returned is aliased with the original slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) getPointerSlice() []pointer {
+	// Super-tricky - p should point to a []*T where T is a
+	// message type. We load it as []pointer.
+	return *(*[]pointer)(p.p)
 }
 
-// word64Val is like word32Val but for 64-bit values.
-type word64Val *uint64
+// setPointerSlice stores []pointer into p as a []*T.
+// The value set is aliased with the input slice.
+// This behavior differs from the implementation in pointer_reflect.go.
+func (p pointer) setPointerSlice(v []pointer) {
+	// Super-tricky - p should point to a []*T where T is a
+	// message type. We store it as []pointer.
+	*(*[]pointer)(p.p) = v
+}
 
-func word64Val_Set(p word64Val, o *Buffer, x uint64) {
-	*p = x
+// getPointer loads the pointer at p and returns it.
+func (p pointer) getPointer() pointer {
+	return pointer{p: *(*unsafe.Pointer)(p.p)}
 }
 
-func word64Val_Get(p word64Val) uint64 {
-	return *p
+// setPointer stores the pointer q at p.
+func (p pointer) setPointer(q pointer) {
+	*(*unsafe.Pointer)(p.p) = q.p
 }
 
-func structPointer_Word64Val(p structPointer, f field) word64Val {
-	return word64Val((*uint64)(unsafe.Pointer(uintptr(p) + uintptr(f))))
+// append q to the slice pointed to by p.
+func (p pointer) appendPointer(q pointer) {
+	s := (*[]unsafe.Pointer)(p.p)
+	*s = append(*s, q.p)
 }
 
-// word64Slice is like word32Slice but for 64-bit values.
-type word64Slice []uint64
+// getInterfacePointer returns a pointer that points to the
+// interface data of the interface pointed by p.
+func (p pointer) getInterfacePointer() pointer {
+	// Super-tricky - read pointer out of data word of interface value.
+	return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]}
+}
 
-func (v *word64Slice) Append(x uint64)    { *v = append(*v, x) }
-func (v *word64Slice) Len() int           { return len(*v) }
-func (v *word64Slice) Index(i int) uint64 { return (*v)[i] }
+// asPointerTo returns a reflect.Value that is a pointer to an
+// object of type t stored at p.
+func (p pointer) asPointerTo(t reflect.Type) reflect.Value {
+	return reflect.NewAt(t, p.p)
+}
 
-func structPointer_Word64Slice(p structPointer, f field) *word64Slice {
-	return (*word64Slice)(unsafe.Pointer(uintptr(p) + uintptr(f)))
+func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo {
+	return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) {
+	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+}
+func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo {
+	return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) {
+	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+}
+func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo {
+	return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) {
+	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
+}
+func atomicLoadDiscardInfo(p **discardInfo) *discardInfo {
+	return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p))))
+}
+func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) {
+	atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v))
 }

+ 14 - 86
vendor/github.com/gogo/protobuf/proto/pointer_unsafe_gogo.go

@@ -1,6 +1,6 @@
 // Protocol Buffers for Go with Gadgets
 //
-// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// Copyright (c) 2018, The GoGo Authors. All rights reserved.
 // http://github.com/gogo/protobuf
 //
 // Redistribution and use in source and binary forms, with or without
@@ -26,7 +26,7 @@
 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-// +build !appengine,!js
+// +build !purego,!appengine,!js
 
 // This file contains the implementation of the proto field accesses using package unsafe.
 
@@ -37,92 +37,20 @@ import (
 	"unsafe"
 )
 
-func structPointer_InterfaceAt(p structPointer, f field, t reflect.Type) interface{} {
-	point := unsafe.Pointer(uintptr(p) + uintptr(f))
-	r := reflect.NewAt(t, point)
-	return r.Interface()
+func (p pointer) getRef() pointer {
+	return pointer{p: (unsafe.Pointer)(&p.p)}
 }
 
-func structPointer_InterfaceRef(p structPointer, f field, t reflect.Type) interface{} {
-	point := unsafe.Pointer(uintptr(p) + uintptr(f))
-	r := reflect.NewAt(t, point)
-	if r.Elem().IsNil() {
-		return nil
-	}
-	return r.Elem().Interface()
+func (p pointer) appendRef(v pointer, typ reflect.Type) {
+	slice := p.getSlice(typ)
+	elem := v.asPointerTo(typ).Elem()
+	newSlice := reflect.Append(slice, elem)
+	slice.Set(newSlice)
 }
 
-func copyUintPtr(oldptr, newptr uintptr, size int) {
-	oldbytes := make([]byte, 0)
-	oldslice := (*reflect.SliceHeader)(unsafe.Pointer(&oldbytes))
-	oldslice.Data = oldptr
-	oldslice.Len = size
-	oldslice.Cap = size
-	newbytes := make([]byte, 0)
-	newslice := (*reflect.SliceHeader)(unsafe.Pointer(&newbytes))
-	newslice.Data = newptr
-	newslice.Len = size
-	newslice.Cap = size
-	copy(newbytes, oldbytes)
-}
-
-func structPointer_Copy(oldptr structPointer, newptr structPointer, size int) {
-	copyUintPtr(uintptr(oldptr), uintptr(newptr), size)
-}
-
-func appendStructPointer(base structPointer, f field, typ reflect.Type) structPointer {
-	size := typ.Elem().Size()
-
-	oldHeader := structPointer_GetSliceHeader(base, f)
-	oldSlice := reflect.NewAt(typ, unsafe.Pointer(oldHeader)).Elem()
-	newLen := oldHeader.Len + 1
-	newSlice := reflect.MakeSlice(typ, newLen, newLen)
-	reflect.Copy(newSlice, oldSlice)
-	bas := toStructPointer(newSlice)
-	oldHeader.Data = uintptr(bas)
-	oldHeader.Len = newLen
-	oldHeader.Cap = newLen
-
-	return structPointer(unsafe.Pointer(uintptr(unsafe.Pointer(bas)) + uintptr(uintptr(newLen-1)*size)))
-}
-
-func structPointer_FieldPointer(p structPointer, f field) structPointer {
-	return structPointer(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-func structPointer_GetRefStructPointer(p structPointer, f field) structPointer {
-	return structPointer((*structPointer)(unsafe.Pointer(uintptr(p) + uintptr(f))))
-}
-
-func structPointer_GetSliceHeader(p structPointer, f field) *reflect.SliceHeader {
-	return (*reflect.SliceHeader)(unsafe.Pointer(uintptr(p) + uintptr(f)))
-}
-
-func structPointer_Add(p structPointer, size field) structPointer {
-	return structPointer(unsafe.Pointer(uintptr(p) + uintptr(size)))
-}
-
-func structPointer_Len(p structPointer, f field) int {
-	return len(*(*[]interface{})(unsafe.Pointer(structPointer_GetRefStructPointer(p, f))))
-}
-
-func structPointer_StructRefSlice(p structPointer, f field, size uintptr) *structRefSlice {
-	return &structRefSlice{p: p, f: f, size: size}
-}
-
-// A structRefSlice represents a slice of structs (themselves submessages or groups).
-type structRefSlice struct {
-	p    structPointer
-	f    field
-	size uintptr
-}
-
-func (v *structRefSlice) Len() int {
-	return structPointer_Len(v.p, v.f)
-}
-
-func (v *structRefSlice) Index(i int) structPointer {
-	ss := structPointer_GetStructPointer(v.p, v.f)
-	ss1 := structPointer_GetRefStructPointer(ss, 0)
-	return structPointer_Add(ss1, field(uintptr(i)*v.size))
+func (p pointer) getSlice(typ reflect.Type) reflect.Value {
+	sliceTyp := reflect.SliceOf(typ)
+	slice := p.asPointerTo(sliceTyp)
+	slice = slice.Elem()
+	return slice
 }

+ 69 - 432
vendor/github.com/gogo/protobuf/proto/properties.go

@@ -63,42 +63,6 @@ const (
 	WireFixed32    = 5
 )
 
-const startSize = 10 // initial slice/string sizes
-
-// Encoders are defined in encode.go
-// An encoder outputs the full representation of a field, including its
-// tag and encoder type.
-type encoder func(p *Buffer, prop *Properties, base structPointer) error
-
-// A valueEncoder encodes a single integer in a particular encoding.
-type valueEncoder func(o *Buffer, x uint64) error
-
-// Sizers are defined in encode.go
-// A sizer returns the encoded size of a field, including its tag and encoder
-// type.
-type sizer func(prop *Properties, base structPointer) int
-
-// A valueSizer returns the encoded size of a single integer in a particular
-// encoding.
-type valueSizer func(x uint64) int
-
-// Decoders are defined in decode.go
-// A decoder creates a value from its wire representation.
-// Unrecognized subelements are saved in unrec.
-type decoder func(p *Buffer, prop *Properties, base structPointer) error
-
-// A valueDecoder decodes a single integer in a particular encoding.
-type valueDecoder func(o *Buffer) (x uint64, err error)
-
-// A oneofMarshaler does the marshaling for all oneof fields in a message.
-type oneofMarshaler func(Message, *Buffer) error
-
-// A oneofUnmarshaler does the unmarshaling for a oneof field in a message.
-type oneofUnmarshaler func(Message, int, int, *Buffer) (bool, error)
-
-// A oneofSizer does the sizing for all oneof fields in a message.
-type oneofSizer func(Message) int
-
 // tagMap is an optimization over map[int]int for typical protocol buffer
 // use-cases. Encoded protocol buffers are often in tag order with small tag
 // numbers.
@@ -145,13 +109,6 @@ type StructProperties struct {
 	decoderTags      tagMap         // map from proto tag to struct field number
 	decoderOrigNames map[string]int // map from original name to struct field number
 	order            []int          // list of struct field numbers in tag order
-	unrecField       field          // field id of the XXX_unrecognized []byte field
-	extendable       bool           // is this an extendable proto
-
-	oneofMarshaler   oneofMarshaler
-	oneofUnmarshaler oneofUnmarshaler
-	oneofSizer       oneofSizer
-	stype            reflect.Type
 
 	// OneofTypes contains information about the oneof fields in this message.
 	// It is keyed by the original name of a field.
@@ -187,7 +144,7 @@ type Properties struct {
 	Repeated bool
 	Packed   bool   // relevant for repeated primitives only
 	Enum     string // set for enum types only
-	proto3   bool   // whether this is known to be a proto3 field; set for []byte only
+	proto3   bool   // whether this is known to be a proto3 field
 	oneof    bool   // whether this is a oneof field
 
 	Default     string // default value
@@ -196,37 +153,21 @@ type Properties struct {
 	CastType    string
 	StdTime     bool
 	StdDuration bool
+	WktPointer  bool
 
-	enc           encoder
-	valEnc        valueEncoder // set for bool and numeric types only
-	field         field
-	tagcode       []byte // encoding of EncodeVarint((Tag<<3)|WireType)
-	tagbuf        [8]byte
-	stype         reflect.Type      // set for struct types only
-	sstype        reflect.Type      // set for slices of structs types only
-	ctype         reflect.Type      // set for custom types only
-	sprop         *StructProperties // set for struct types only
-	isMarshaler   bool
-	isUnmarshaler bool
-
-	mtype    reflect.Type // set for map types only
-	mkeyprop *Properties  // set for map types only
-	mvalprop *Properties  // set for map types only
-
-	size    sizer
-	valSize valueSizer // set for bool and numeric types only
-
-	dec    decoder
-	valDec valueDecoder // set for bool and numeric types only
-
-	// If this is a packable field, this will be the decoder for the packed version of the field.
-	packedDec decoder
+	stype reflect.Type      // set for struct types only
+	ctype reflect.Type      // set for custom types only
+	sprop *StructProperties // set for struct types only
+
+	mtype      reflect.Type // set for map types only
+	MapKeyProp *Properties  // set for map types only
+	MapValProp *Properties  // set for map types only
 }
 
 // String formats the properties in the protobuf struct field tag style.
 func (p *Properties) String() string {
 	s := p.Wire
-	s = ","
+	s += ","
 	s += strconv.Itoa(p.Tag)
 	if p.Required {
 		s += ",req"
@@ -272,29 +213,14 @@ func (p *Properties) Parse(s string) {
 	switch p.Wire {
 	case "varint":
 		p.WireType = WireVarint
-		p.valEnc = (*Buffer).EncodeVarint
-		p.valDec = (*Buffer).DecodeVarint
-		p.valSize = sizeVarint
 	case "fixed32":
 		p.WireType = WireFixed32
-		p.valEnc = (*Buffer).EncodeFixed32
-		p.valDec = (*Buffer).DecodeFixed32
-		p.valSize = sizeFixed32
 	case "fixed64":
 		p.WireType = WireFixed64
-		p.valEnc = (*Buffer).EncodeFixed64
-		p.valDec = (*Buffer).DecodeFixed64
-		p.valSize = sizeFixed64
 	case "zigzag32":
 		p.WireType = WireVarint
-		p.valEnc = (*Buffer).EncodeZigzag32
-		p.valDec = (*Buffer).DecodeZigzag32
-		p.valSize = sizeZigzag32
 	case "zigzag64":
 		p.WireType = WireVarint
-		p.valEnc = (*Buffer).EncodeZigzag64
-		p.valDec = (*Buffer).DecodeZigzag64
-		p.valSize = sizeZigzag64
 	case "bytes", "group":
 		p.WireType = WireBytes
 		// no numeric converter for non-numeric types
@@ -309,6 +235,7 @@ func (p *Properties) Parse(s string) {
 		return
 	}
 
+outer:
 	for i := 2; i < len(fields); i++ {
 		f := fields[i]
 		switch {
@@ -336,7 +263,7 @@ func (p *Properties) Parse(s string) {
 			if i+1 < len(fields) {
 				// Commas aren't escaped, and def is always last.
 				p.Default += "," + strings.Join(fields[i+1:], ",")
-				break
+				break outer
 			}
 		case strings.HasPrefix(f, "embedded="):
 			p.OrigName = strings.Split(f, "=")[1]
@@ -348,301 +275,58 @@ func (p *Properties) Parse(s string) {
 			p.StdTime = true
 		case f == "stdduration":
 			p.StdDuration = true
+		case f == "wktptr":
+			p.WktPointer = true
 		}
 	}
 }
 
-func logNoSliceEnc(t1, t2 reflect.Type) {
-	fmt.Fprintf(os.Stderr, "proto: no slice oenc for %T = []%T\n", t1, t2)
-}
-
 var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem()
 
-// Initialize the fields for encoding and decoding.
-func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
-	p.enc = nil
-	p.dec = nil
-	p.size = nil
+// setFieldProps initializes the field properties for submessages and maps.
+func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) {
 	isMap := typ.Kind() == reflect.Map
 	if len(p.CustomType) > 0 && !isMap {
-		p.setCustomEncAndDec(typ)
+		p.ctype = typ
 		p.setTag(lockGetProp)
 		return
 	}
 	if p.StdTime && !isMap {
-		p.setTimeEncAndDec(typ)
 		p.setTag(lockGetProp)
 		return
 	}
 	if p.StdDuration && !isMap {
-		p.setDurationEncAndDec(typ)
+		p.setTag(lockGetProp)
+		return
+	}
+	if p.WktPointer && !isMap {
 		p.setTag(lockGetProp)
 		return
 	}
 	switch t1 := typ; t1.Kind() {
-	default:
-		fmt.Fprintf(os.Stderr, "proto: no coders for %v\n", t1)
-
-	// proto3 scalar types
-
-	case reflect.Bool:
-		if p.proto3 {
-			p.enc = (*Buffer).enc_proto3_bool
-			p.dec = (*Buffer).dec_proto3_bool
-			p.size = size_proto3_bool
-		} else {
-			p.enc = (*Buffer).enc_ref_bool
-			p.dec = (*Buffer).dec_proto3_bool
-			p.size = size_ref_bool
-		}
-	case reflect.Int32:
-		if p.proto3 {
-			p.enc = (*Buffer).enc_proto3_int32
-			p.dec = (*Buffer).dec_proto3_int32
-			p.size = size_proto3_int32
-		} else {
-			p.enc = (*Buffer).enc_ref_int32
-			p.dec = (*Buffer).dec_proto3_int32
-			p.size = size_ref_int32
-		}
-	case reflect.Uint32:
-		if p.proto3 {
-			p.enc = (*Buffer).enc_proto3_uint32
-			p.dec = (*Buffer).dec_proto3_int32 // can reuse
-			p.size = size_proto3_uint32
-		} else {
-			p.enc = (*Buffer).enc_ref_uint32
-			p.dec = (*Buffer).dec_proto3_int32 // can reuse
-			p.size = size_ref_uint32
-		}
-	case reflect.Int64, reflect.Uint64:
-		if p.proto3 {
-			p.enc = (*Buffer).enc_proto3_int64
-			p.dec = (*Buffer).dec_proto3_int64
-			p.size = size_proto3_int64
-		} else {
-			p.enc = (*Buffer).enc_ref_int64
-			p.dec = (*Buffer).dec_proto3_int64
-			p.size = size_ref_int64
-		}
-	case reflect.Float32:
-		if p.proto3 {
-			p.enc = (*Buffer).enc_proto3_uint32 // can just treat them as bits
-			p.dec = (*Buffer).dec_proto3_int32
-			p.size = size_proto3_uint32
-		} else {
-			p.enc = (*Buffer).enc_ref_uint32 // can just treat them as bits
-			p.dec = (*Buffer).dec_proto3_int32
-			p.size = size_ref_uint32
-		}
-	case reflect.Float64:
-		if p.proto3 {
-			p.enc = (*Buffer).enc_proto3_int64 // can just treat them as bits
-			p.dec = (*Buffer).dec_proto3_int64
-			p.size = size_proto3_int64
-		} else {
-			p.enc = (*Buffer).enc_ref_int64 // can just treat them as bits
-			p.dec = (*Buffer).dec_proto3_int64
-			p.size = size_ref_int64
-		}
-	case reflect.String:
-		if p.proto3 {
-			p.enc = (*Buffer).enc_proto3_string
-			p.dec = (*Buffer).dec_proto3_string
-			p.size = size_proto3_string
-		} else {
-			p.enc = (*Buffer).enc_ref_string
-			p.dec = (*Buffer).dec_proto3_string
-			p.size = size_ref_string
-		}
 	case reflect.Struct:
 		p.stype = typ
-		p.isMarshaler = isMarshaler(typ)
-		p.isUnmarshaler = isUnmarshaler(typ)
-		if p.Wire == "bytes" {
-			p.enc = (*Buffer).enc_ref_struct_message
-			p.dec = (*Buffer).dec_ref_struct_message
-			p.size = size_ref_struct_message
-		} else {
-			fmt.Fprintf(os.Stderr, "proto: no coders for struct %T\n", typ)
-		}
-
 	case reflect.Ptr:
-		switch t2 := t1.Elem(); t2.Kind() {
-		default:
-			fmt.Fprintf(os.Stderr, "proto: no encoder function for %v -> %v\n", t1, t2)
-			break
-		case reflect.Bool:
-			p.enc = (*Buffer).enc_bool
-			p.dec = (*Buffer).dec_bool
-			p.size = size_bool
-		case reflect.Int32:
-			p.enc = (*Buffer).enc_int32
-			p.dec = (*Buffer).dec_int32
-			p.size = size_int32
-		case reflect.Uint32:
-			p.enc = (*Buffer).enc_uint32
-			p.dec = (*Buffer).dec_int32 // can reuse
-			p.size = size_uint32
-		case reflect.Int64, reflect.Uint64:
-			p.enc = (*Buffer).enc_int64
-			p.dec = (*Buffer).dec_int64
-			p.size = size_int64
-		case reflect.Float32:
-			p.enc = (*Buffer).enc_uint32 // can just treat them as bits
-			p.dec = (*Buffer).dec_int32
-			p.size = size_uint32
-		case reflect.Float64:
-			p.enc = (*Buffer).enc_int64 // can just treat them as bits
-			p.dec = (*Buffer).dec_int64
-			p.size = size_int64
-		case reflect.String:
-			p.enc = (*Buffer).enc_string
-			p.dec = (*Buffer).dec_string
-			p.size = size_string
-		case reflect.Struct:
+		if t1.Elem().Kind() == reflect.Struct {
 			p.stype = t1.Elem()
-			p.isMarshaler = isMarshaler(t1)
-			p.isUnmarshaler = isUnmarshaler(t1)
-			if p.Wire == "bytes" {
-				p.enc = (*Buffer).enc_struct_message
-				p.dec = (*Buffer).dec_struct_message
-				p.size = size_struct_message
-			} else {
-				p.enc = (*Buffer).enc_struct_group
-				p.dec = (*Buffer).dec_struct_group
-				p.size = size_struct_group
-			}
 		}
-
 	case reflect.Slice:
 		switch t2 := t1.Elem(); t2.Kind() {
-		default:
-			logNoSliceEnc(t1, t2)
-			break
-		case reflect.Bool:
-			if p.Packed {
-				p.enc = (*Buffer).enc_slice_packed_bool
-				p.size = size_slice_packed_bool
-			} else {
-				p.enc = (*Buffer).enc_slice_bool
-				p.size = size_slice_bool
-			}
-			p.dec = (*Buffer).dec_slice_bool
-			p.packedDec = (*Buffer).dec_slice_packed_bool
-		case reflect.Int32:
-			if p.Packed {
-				p.enc = (*Buffer).enc_slice_packed_int32
-				p.size = size_slice_packed_int32
-			} else {
-				p.enc = (*Buffer).enc_slice_int32
-				p.size = size_slice_int32
-			}
-			p.dec = (*Buffer).dec_slice_int32
-			p.packedDec = (*Buffer).dec_slice_packed_int32
-		case reflect.Uint32:
-			if p.Packed {
-				p.enc = (*Buffer).enc_slice_packed_uint32
-				p.size = size_slice_packed_uint32
-			} else {
-				p.enc = (*Buffer).enc_slice_uint32
-				p.size = size_slice_uint32
-			}
-			p.dec = (*Buffer).dec_slice_int32
-			p.packedDec = (*Buffer).dec_slice_packed_int32
-		case reflect.Int64, reflect.Uint64:
-			if p.Packed {
-				p.enc = (*Buffer).enc_slice_packed_int64
-				p.size = size_slice_packed_int64
-			} else {
-				p.enc = (*Buffer).enc_slice_int64
-				p.size = size_slice_int64
-			}
-			p.dec = (*Buffer).dec_slice_int64
-			p.packedDec = (*Buffer).dec_slice_packed_int64
-		case reflect.Uint8:
-			p.dec = (*Buffer).dec_slice_byte
-			if p.proto3 {
-				p.enc = (*Buffer).enc_proto3_slice_byte
-				p.size = size_proto3_slice_byte
-			} else {
-				p.enc = (*Buffer).enc_slice_byte
-				p.size = size_slice_byte
-			}
-		case reflect.Float32, reflect.Float64:
-			switch t2.Bits() {
-			case 32:
-				// can just treat them as bits
-				if p.Packed {
-					p.enc = (*Buffer).enc_slice_packed_uint32
-					p.size = size_slice_packed_uint32
-				} else {
-					p.enc = (*Buffer).enc_slice_uint32
-					p.size = size_slice_uint32
-				}
-				p.dec = (*Buffer).dec_slice_int32
-				p.packedDec = (*Buffer).dec_slice_packed_int32
-			case 64:
-				// can just treat them as bits
-				if p.Packed {
-					p.enc = (*Buffer).enc_slice_packed_int64
-					p.size = size_slice_packed_int64
-				} else {
-					p.enc = (*Buffer).enc_slice_int64
-					p.size = size_slice_int64
-				}
-				p.dec = (*Buffer).dec_slice_int64
-				p.packedDec = (*Buffer).dec_slice_packed_int64
-			default:
-				logNoSliceEnc(t1, t2)
-				break
-			}
-		case reflect.String:
-			p.enc = (*Buffer).enc_slice_string
-			p.dec = (*Buffer).dec_slice_string
-			p.size = size_slice_string
 		case reflect.Ptr:
 			switch t3 := t2.Elem(); t3.Kind() {
-			default:
-				fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T -> %T\n", t1, t2, t3)
-				break
 			case reflect.Struct:
-				p.stype = t2.Elem()
-				p.isMarshaler = isMarshaler(t2)
-				p.isUnmarshaler = isUnmarshaler(t2)
-				if p.Wire == "bytes" {
-					p.enc = (*Buffer).enc_slice_struct_message
-					p.dec = (*Buffer).dec_slice_struct_message
-					p.size = size_slice_struct_message
-				} else {
-					p.enc = (*Buffer).enc_slice_struct_group
-					p.dec = (*Buffer).dec_slice_struct_group
-					p.size = size_slice_struct_group
-				}
-			}
-		case reflect.Slice:
-			switch t2.Elem().Kind() {
-			default:
-				fmt.Fprintf(os.Stderr, "proto: no slice elem oenc for %T -> %T -> %T\n", t1, t2, t2.Elem())
-				break
-			case reflect.Uint8:
-				p.enc = (*Buffer).enc_slice_slice_byte
-				p.dec = (*Buffer).dec_slice_slice_byte
-				p.size = size_slice_slice_byte
+				p.stype = t3
 			}
 		case reflect.Struct:
-			p.setSliceOfNonPointerStructs(t1)
+			p.stype = t2
 		}
 
 	case reflect.Map:
-		p.enc = (*Buffer).enc_new_map
-		p.dec = (*Buffer).dec_new_map
-		p.size = size_new_map
 
 		p.mtype = t1
-		p.mkeyprop = &Properties{}
-		p.mkeyprop.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
-		p.mvalprop = &Properties{}
+		p.MapKeyProp = &Properties{}
+		p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp)
+		p.MapValProp = &Properties{}
 		vtype := p.mtype.Elem()
 		if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice {
 			// The value type is not a message (*T) or bytes ([]byte),
@@ -650,29 +334,16 @@ func (p *Properties) setEncAndDec(typ reflect.Type, f *reflect.StructField, lock
 			vtype = reflect.PtrTo(vtype)
 		}
 
-		p.mvalprop.CustomType = p.CustomType
-		p.mvalprop.StdDuration = p.StdDuration
-		p.mvalprop.StdTime = p.StdTime
-		p.mvalprop.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
+		p.MapValProp.CustomType = p.CustomType
+		p.MapValProp.StdDuration = p.StdDuration
+		p.MapValProp.StdTime = p.StdTime
+		p.MapValProp.WktPointer = p.WktPointer
+		p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp)
 	}
 	p.setTag(lockGetProp)
 }
 
 func (p *Properties) setTag(lockGetProp bool) {
-	// precalculate tag code
-	wire := p.WireType
-	if p.Packed {
-		wire = WireBytes
-	}
-	x := uint32(p.Tag)<<3 | uint32(wire)
-	i := 0
-	for i = 0; x > 127; i++ {
-		p.tagbuf[i] = 0x80 | uint8(x&0x7F)
-		x >>= 7
-	}
-	p.tagbuf[i] = uint8(x)
-	p.tagcode = p.tagbuf[0 : i+1]
-
 	if p.stype != nil {
 		if lockGetProp {
 			p.sprop = GetProperties(p.stype)
@@ -683,20 +354,9 @@ func (p *Properties) setTag(lockGetProp bool) {
 }
 
 var (
-	marshalerType   = reflect.TypeOf((*Marshaler)(nil)).Elem()
-	unmarshalerType = reflect.TypeOf((*Unmarshaler)(nil)).Elem()
+	marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem()
 )
 
-// isMarshaler reports whether type t implements Marshaler.
-func isMarshaler(t reflect.Type) bool {
-	return t.Implements(marshalerType)
-}
-
-// isUnmarshaler reports whether type t implements Unmarshaler.
-func isUnmarshaler(t reflect.Type) bool {
-	return t.Implements(unmarshalerType)
-}
-
 // Init populates the properties from a protocol buffer struct tag.
 func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) {
 	p.init(typ, name, tag, f, true)
@@ -706,14 +366,11 @@ func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructF
 	// "bytes,49,opt,def=hello!"
 	p.Name = name
 	p.OrigName = name
-	if f != nil {
-		p.field = toField(f)
-	}
 	if tag == "" {
 		return
 	}
 	p.Parse(tag)
-	p.setEncAndDec(typ, f, lockGetProp)
+	p.setFieldProps(typ, f, lockGetProp)
 }
 
 var (
@@ -763,10 +420,6 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 	propertiesMap[t] = prop
 
 	// build properties
-	prop.extendable = reflect.PtrTo(t).Implements(extendableProtoType) ||
-		reflect.PtrTo(t).Implements(extendableProtoV1Type) ||
-		reflect.PtrTo(t).Implements(extendableBytesType)
-	prop.unrecField = invalidField
 	prop.Prop = make([]*Properties, t.NumField())
 	prop.order = make([]int, t.NumField())
 
@@ -777,23 +430,6 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 		name := f.Name
 		p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false)
 
-		if f.Name == "XXX_InternalExtensions" { // special case
-			p.enc = (*Buffer).enc_exts
-			p.dec = nil // not needed
-			p.size = size_exts
-		} else if f.Name == "XXX_extensions" { // special case
-			if len(f.Tag.Get("protobuf")) > 0 {
-				p.enc = (*Buffer).enc_ext_slice_byte
-				p.dec = nil // not needed
-				p.size = size_ext_slice_byte
-			} else {
-				p.enc = (*Buffer).enc_map
-				p.dec = nil // not needed
-				p.size = size_map
-			}
-		} else if f.Name == "XXX_unrecognized" { // special case
-			prop.unrecField = toField(&f)
-		}
 		oneof := f.Tag.Get("protobuf_oneof") // special case
 		if oneof != "" {
 			isOneofMessage = true
@@ -809,9 +445,6 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 			}
 			print("\n")
 		}
-		if p.enc == nil && !strings.HasPrefix(f.Name, "XXX_") && oneof == "" {
-			fmt.Fprintln(os.Stderr, "proto: no encoder for", f.Name, f.Type.String(), "[GetProperties]")
-		}
 	}
 
 	// Re-order prop.order.
@@ -822,8 +455,7 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 	}
 	if om, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); isOneofMessage && ok {
 		var oots []interface{}
-		prop.oneofMarshaler, prop.oneofUnmarshaler, prop.oneofSizer, oots = om.XXX_OneofFuncs()
-		prop.stype = t
+		_, _, _, oots = om.XXX_OneofFuncs()
 
 		// Interpret oneof metadata.
 		prop.OneofTypes = make(map[string]*OneofProperties)
@@ -873,30 +505,6 @@ func getPropertiesLocked(t reflect.Type) *StructProperties {
 	return prop
 }
 
-// Return the Properties object for the x[0]'th field of the structure.
-func propByIndex(t reflect.Type, x []int) *Properties {
-	if len(x) != 1 {
-		fmt.Fprintf(os.Stderr, "proto: field index dimension %d (not 1) for type %s\n", len(x), t)
-		return nil
-	}
-	prop := GetProperties(t)
-	return prop.Prop[x[0]]
-}
-
-// Get the address and type of a pointer to a struct from an interface.
-func getbase(pb Message) (t reflect.Type, b structPointer, err error) {
-	if pb == nil {
-		err = ErrNil
-		return
-	}
-	// get the reflect type of the pointer to the struct.
-	t = reflect.TypeOf(pb)
-	// get the address of the struct.
-	value := reflect.ValueOf(pb)
-	b = toStructPointer(value)
-	return
-}
-
 // A global registry of enum types.
 // The generated code will register the generated maps by calling RegisterEnum.
 
@@ -925,20 +533,42 @@ func EnumValueMap(enumType string) map[string]int32 {
 // A registry of all linked message types.
 // The string is a fully-qualified proto name ("pkg.Message").
 var (
-	protoTypes    = make(map[string]reflect.Type)
-	revProtoTypes = make(map[reflect.Type]string)
+	protoTypedNils = make(map[string]Message)      // a map from proto names to typed nil pointers
+	protoMapTypes  = make(map[string]reflect.Type) // a map from proto names to map types
+	revProtoTypes  = make(map[reflect.Type]string)
 )
 
 // RegisterType is called from generated code and maps from the fully qualified
 // proto name to the type (pointer to struct) of the protocol buffer.
 func RegisterType(x Message, name string) {
-	if _, ok := protoTypes[name]; ok {
+	if _, ok := protoTypedNils[name]; ok {
 		// TODO: Some day, make this a panic.
 		log.Printf("proto: duplicate proto type registered: %s", name)
 		return
 	}
 	t := reflect.TypeOf(x)
-	protoTypes[name] = t
+	if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 {
+		// Generated code always calls RegisterType with nil x.
+		// This check is just for extra safety.
+		protoTypedNils[name] = x
+	} else {
+		protoTypedNils[name] = reflect.Zero(t).Interface().(Message)
+	}
+	revProtoTypes[t] = name
+}
+
+// RegisterMapType is called from generated code and maps from the fully qualified
+// proto name to the native map type of the proto map definition.
+func RegisterMapType(x interface{}, name string) {
+	if reflect.TypeOf(x).Kind() != reflect.Map {
+		panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name))
+	}
+	if _, ok := protoMapTypes[name]; ok {
+		log.Printf("proto: duplicate proto type registered: %s", name)
+		return
+	}
+	t := reflect.TypeOf(x)
+	protoMapTypes[name] = t
 	revProtoTypes[t] = name
 }
 
@@ -954,7 +584,14 @@ func MessageName(x Message) string {
 }
 
 // MessageType returns the message type (pointer to struct) for a named message.
-func MessageType(name string) reflect.Type { return protoTypes[name] }
+// The type is not guaranteed to implement proto.Message if the name refers to a
+// map entry.
+func MessageType(name string) reflect.Type {
+	if t, ok := protoTypedNils[name]; ok {
+		return reflect.TypeOf(t)
+	}
+	return protoMapTypes[name]
+}
 
 // A registry of all linked proto files.
 var (

+ 3 - 78
vendor/github.com/gogo/protobuf/proto/properties_gogo.go

@@ -1,6 +1,6 @@
 // Protocol Buffers for Go with Gadgets
 //
-// Copyright (c) 2013, The GoGo Authors. All rights reserved.
+// Copyright (c) 2018, The GoGo Authors. All rights reserved.
 // http://github.com/gogo/protobuf
 //
 // Redistribution and use in source and binary forms, with or without
@@ -29,83 +29,8 @@
 package proto
 
 import (
-	"fmt"
-	"os"
 	"reflect"
 )
 
-func (p *Properties) setCustomEncAndDec(typ reflect.Type) {
-	p.ctype = typ
-	if p.Repeated {
-		p.enc = (*Buffer).enc_custom_slice_bytes
-		p.dec = (*Buffer).dec_custom_slice_bytes
-		p.size = size_custom_slice_bytes
-	} else if typ.Kind() == reflect.Ptr {
-		p.enc = (*Buffer).enc_custom_bytes
-		p.dec = (*Buffer).dec_custom_bytes
-		p.size = size_custom_bytes
-	} else {
-		p.enc = (*Buffer).enc_custom_ref_bytes
-		p.dec = (*Buffer).dec_custom_ref_bytes
-		p.size = size_custom_ref_bytes
-	}
-}
-
-func (p *Properties) setDurationEncAndDec(typ reflect.Type) {
-	if p.Repeated {
-		if typ.Elem().Kind() == reflect.Ptr {
-			p.enc = (*Buffer).enc_slice_duration
-			p.dec = (*Buffer).dec_slice_duration
-			p.size = size_slice_duration
-		} else {
-			p.enc = (*Buffer).enc_slice_ref_duration
-			p.dec = (*Buffer).dec_slice_ref_duration
-			p.size = size_slice_ref_duration
-		}
-	} else if typ.Kind() == reflect.Ptr {
-		p.enc = (*Buffer).enc_duration
-		p.dec = (*Buffer).dec_duration
-		p.size = size_duration
-	} else {
-		p.enc = (*Buffer).enc_ref_duration
-		p.dec = (*Buffer).dec_ref_duration
-		p.size = size_ref_duration
-	}
-}
-
-func (p *Properties) setTimeEncAndDec(typ reflect.Type) {
-	if p.Repeated {
-		if typ.Elem().Kind() == reflect.Ptr {
-			p.enc = (*Buffer).enc_slice_time
-			p.dec = (*Buffer).dec_slice_time
-			p.size = size_slice_time
-		} else {
-			p.enc = (*Buffer).enc_slice_ref_time
-			p.dec = (*Buffer).dec_slice_ref_time
-			p.size = size_slice_ref_time
-		}
-	} else if typ.Kind() == reflect.Ptr {
-		p.enc = (*Buffer).enc_time
-		p.dec = (*Buffer).dec_time
-		p.size = size_time
-	} else {
-		p.enc = (*Buffer).enc_ref_time
-		p.dec = (*Buffer).dec_ref_time
-		p.size = size_ref_time
-	}
-
-}
-
-func (p *Properties) setSliceOfNonPointerStructs(typ reflect.Type) {
-	t2 := typ.Elem()
-	p.sstype = typ
-	p.stype = t2
-	p.isMarshaler = isMarshaler(t2)
-	p.isUnmarshaler = isUnmarshaler(t2)
-	p.enc = (*Buffer).enc_slice_ref_struct_message
-	p.dec = (*Buffer).dec_slice_ref_struct_message
-	p.size = size_slice_ref_struct_message
-	if p.Wire != "bytes" {
-		fmt.Fprintf(os.Stderr, "proto: no ptr oenc for %T -> %T \n", typ, t2)
-	}
-}
+var sizerType = reflect.TypeOf((*Sizer)(nil)).Elem()
+var protosizerType = reflect.TypeOf((*ProtoSizer)(nil)).Elem()

+ 3006 - 0
vendor/github.com/gogo/protobuf/proto/table_marshal.go

@@ -0,0 +1,3006 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+import (
+	"errors"
+	"fmt"
+	"math"
+	"reflect"
+	"sort"
+	"strconv"
+	"strings"
+	"sync"
+	"sync/atomic"
+	"unicode/utf8"
+)
+
+// a sizer takes a pointer to a field and the size of its tag, computes the size of
+// the encoded data.
+type sizer func(pointer, int) int
+
+// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format),
+// marshals the field to the end of the slice, returns the slice and error (if any).
+type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error)
+
+// marshalInfo is the information used for marshaling a message.
+type marshalInfo struct {
+	typ          reflect.Type
+	fields       []*marshalFieldInfo
+	unrecognized field                      // offset of XXX_unrecognized
+	extensions   field                      // offset of XXX_InternalExtensions
+	v1extensions field                      // offset of XXX_extensions
+	sizecache    field                      // offset of XXX_sizecache
+	initialized  int32                      // 0 -- only typ is set, 1 -- fully initialized
+	messageset   bool                       // uses message set wire format
+	hasmarshaler bool                       // has custom marshaler
+	sync.RWMutex                            // protect extElems map, also for initialization
+	extElems     map[int32]*marshalElemInfo // info of extension elements
+
+	hassizer      bool // has custom sizer
+	hasprotosizer bool // has custom protosizer
+
+	bytesExtensions field // offset of XXX_extensions where the field type is []byte
+}
+
+// marshalFieldInfo is the information used for marshaling a field of a message.
+type marshalFieldInfo struct {
+	field      field
+	wiretag    uint64 // tag in wire format
+	tagsize    int    // size of tag in wire format
+	sizer      sizer
+	marshaler  marshaler
+	isPointer  bool
+	required   bool                              // field is required
+	name       string                            // name of the field, for error reporting
+	oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements
+}
+
+// marshalElemInfo is the information used for marshaling an extension or oneof element.
+type marshalElemInfo struct {
+	wiretag   uint64 // tag in wire format
+	tagsize   int    // size of tag in wire format
+	sizer     sizer
+	marshaler marshaler
+	isptr     bool // elem is pointer typed, thus interface of this type is a direct interface (extension only)
+}
+
+var (
+	marshalInfoMap  = map[reflect.Type]*marshalInfo{}
+	marshalInfoLock sync.Mutex
+
+	uint8SliceType = reflect.TypeOf(([]uint8)(nil)).Kind()
+)
+
+// getMarshalInfo returns the information to marshal a given type of message.
+// The info it returns may not necessarily initialized.
+// t is the type of the message (NOT the pointer to it).
+func getMarshalInfo(t reflect.Type) *marshalInfo {
+	marshalInfoLock.Lock()
+	u, ok := marshalInfoMap[t]
+	if !ok {
+		u = &marshalInfo{typ: t}
+		marshalInfoMap[t] = u
+	}
+	marshalInfoLock.Unlock()
+	return u
+}
+
+// Size is the entry point from generated code,
+// and should be ONLY called by generated code.
+// It computes the size of encoded data of msg.
+// a is a pointer to a place to store cached marshal info.
+func (a *InternalMessageInfo) Size(msg Message) int {
+	u := getMessageMarshalInfo(msg, a)
+	ptr := toPointer(&msg)
+	if ptr.isNil() {
+		// We get here if msg is a typed nil ((*SomeMessage)(nil)),
+		// so it satisfies the interface, and msg == nil wouldn't
+		// catch it. We don't want crash in this case.
+		return 0
+	}
+	return u.size(ptr)
+}
+
+// Marshal is the entry point from generated code,
+// and should be ONLY called by generated code.
+// It marshals msg to the end of b.
+// a is a pointer to a place to store cached marshal info.
+func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) {
+	u := getMessageMarshalInfo(msg, a)
+	ptr := toPointer(&msg)
+	if ptr.isNil() {
+		// We get here if msg is a typed nil ((*SomeMessage)(nil)),
+		// so it satisfies the interface, and msg == nil wouldn't
+		// catch it. We don't want crash in this case.
+		return b, ErrNil
+	}
+	return u.marshal(b, ptr, deterministic)
+}
+
+func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo {
+	// u := a.marshal, but atomically.
+	// We use an atomic here to ensure memory consistency.
+	u := atomicLoadMarshalInfo(&a.marshal)
+	if u == nil {
+		// Get marshal information from type of message.
+		t := reflect.ValueOf(msg).Type()
+		if t.Kind() != reflect.Ptr {
+			panic(fmt.Sprintf("cannot handle non-pointer message type %v", t))
+		}
+		u = getMarshalInfo(t.Elem())
+		// Store it in the cache for later users.
+		// a.marshal = u, but atomically.
+		atomicStoreMarshalInfo(&a.marshal, u)
+	}
+	return u
+}
+
+// size is the main function to compute the size of the encoded data of a message.
+// ptr is the pointer to the message.
+func (u *marshalInfo) size(ptr pointer) int {
+	if atomic.LoadInt32(&u.initialized) == 0 {
+		u.computeMarshalInfo()
+	}
+
+	// If the message can marshal itself, let it do it, for compatibility.
+	// NOTE: This is not efficient.
+	if u.hasmarshaler {
+		// Uses the message's Size method if available
+		if u.hassizer {
+			s := ptr.asPointerTo(u.typ).Interface().(Sizer)
+			return s.Size()
+		}
+		// Uses the message's ProtoSize method if available
+		if u.hasprotosizer {
+			s := ptr.asPointerTo(u.typ).Interface().(ProtoSizer)
+			return s.ProtoSize()
+		}
+
+		m := ptr.asPointerTo(u.typ).Interface().(Marshaler)
+		b, _ := m.Marshal()
+		return len(b)
+	}
+
+	n := 0
+	for _, f := range u.fields {
+		if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
+			// nil pointer always marshals to nothing
+			continue
+		}
+		n += f.sizer(ptr.offset(f.field), f.tagsize)
+	}
+	if u.extensions.IsValid() {
+		e := ptr.offset(u.extensions).toExtensions()
+		if u.messageset {
+			n += u.sizeMessageSet(e)
+		} else {
+			n += u.sizeExtensions(e)
+		}
+	}
+	if u.v1extensions.IsValid() {
+		m := *ptr.offset(u.v1extensions).toOldExtensions()
+		n += u.sizeV1Extensions(m)
+	}
+	if u.bytesExtensions.IsValid() {
+		s := *ptr.offset(u.bytesExtensions).toBytes()
+		n += len(s)
+	}
+	if u.unrecognized.IsValid() {
+		s := *ptr.offset(u.unrecognized).toBytes()
+		n += len(s)
+	}
+
+	// cache the result for use in marshal
+	if u.sizecache.IsValid() {
+		atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n))
+	}
+	return n
+}
+
+// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated),
+// fall back to compute the size.
+func (u *marshalInfo) cachedsize(ptr pointer) int {
+	if u.sizecache.IsValid() {
+		return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32()))
+	}
+	return u.size(ptr)
+}
+
+// marshal is the main function to marshal a message. It takes a byte slice and appends
+// the encoded data to the end of the slice, returns the slice and error (if any).
+// ptr is the pointer to the message.
+// If deterministic is true, map is marshaled in deterministic order.
+func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) {
+	if atomic.LoadInt32(&u.initialized) == 0 {
+		u.computeMarshalInfo()
+	}
+
+	// If the message can marshal itself, let it do it, for compatibility.
+	// NOTE: This is not efficient.
+	if u.hasmarshaler {
+		m := ptr.asPointerTo(u.typ).Interface().(Marshaler)
+		b1, err := m.Marshal()
+		b = append(b, b1...)
+		return b, err
+	}
+
+	var err, errLater error
+	// The old marshaler encodes extensions at beginning.
+	if u.extensions.IsValid() {
+		e := ptr.offset(u.extensions).toExtensions()
+		if u.messageset {
+			b, err = u.appendMessageSet(b, e, deterministic)
+		} else {
+			b, err = u.appendExtensions(b, e, deterministic)
+		}
+		if err != nil {
+			return b, err
+		}
+	}
+	if u.v1extensions.IsValid() {
+		m := *ptr.offset(u.v1extensions).toOldExtensions()
+		b, err = u.appendV1Extensions(b, m, deterministic)
+		if err != nil {
+			return b, err
+		}
+	}
+	if u.bytesExtensions.IsValid() {
+		s := *ptr.offset(u.bytesExtensions).toBytes()
+		b = append(b, s...)
+	}
+	for _, f := range u.fields {
+		if f.required {
+			if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
+				// Required field is not set.
+				// We record the error but keep going, to give a complete marshaling.
+				if errLater == nil {
+					errLater = &RequiredNotSetError{f.name}
+				}
+				continue
+			}
+		}
+		if f.isPointer && ptr.offset(f.field).getPointer().isNil() {
+			// nil pointer always marshals to nothing
+			continue
+		}
+		b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic)
+		if err != nil {
+			if err1, ok := err.(*RequiredNotSetError); ok {
+				// Required field in submessage is not set.
+				// We record the error but keep going, to give a complete marshaling.
+				if errLater == nil {
+					errLater = &RequiredNotSetError{f.name + "." + err1.field}
+				}
+				continue
+			}
+			if err == errRepeatedHasNil {
+				err = errors.New("proto: repeated field " + f.name + " has nil element")
+			}
+			if err == errInvalidUTF8 {
+				if errLater == nil {
+					fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
+					errLater = &invalidUTF8Error{fullName}
+				}
+				continue
+			}
+			return b, err
+		}
+	}
+	if u.unrecognized.IsValid() {
+		s := *ptr.offset(u.unrecognized).toBytes()
+		b = append(b, s...)
+	}
+	return b, errLater
+}
+
+// computeMarshalInfo initializes the marshal info.
+func (u *marshalInfo) computeMarshalInfo() {
+	u.Lock()
+	defer u.Unlock()
+	if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock
+		return
+	}
+
+	t := u.typ
+	u.unrecognized = invalidField
+	u.extensions = invalidField
+	u.v1extensions = invalidField
+	u.bytesExtensions = invalidField
+	u.sizecache = invalidField
+	isOneofMessage := false
+
+	if reflect.PtrTo(t).Implements(sizerType) {
+		u.hassizer = true
+	}
+	if reflect.PtrTo(t).Implements(protosizerType) {
+		u.hasprotosizer = true
+	}
+	// If the message can marshal itself, let it do it, for compatibility.
+	// NOTE: This is not efficient.
+	if reflect.PtrTo(t).Implements(marshalerType) {
+		u.hasmarshaler = true
+		atomic.StoreInt32(&u.initialized, 1)
+		return
+	}
+
+	n := t.NumField()
+
+	// deal with XXX fields first
+	for i := 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+		if f.Tag.Get("protobuf_oneof") != "" {
+			isOneofMessage = true
+		}
+		if !strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		switch f.Name {
+		case "XXX_sizecache":
+			u.sizecache = toField(&f)
+		case "XXX_unrecognized":
+			u.unrecognized = toField(&f)
+		case "XXX_InternalExtensions":
+			u.extensions = toField(&f)
+			u.messageset = f.Tag.Get("protobuf_messageset") == "1"
+		case "XXX_extensions":
+			if f.Type.Kind() == reflect.Map {
+				u.v1extensions = toField(&f)
+			} else {
+				u.bytesExtensions = toField(&f)
+			}
+		case "XXX_NoUnkeyedLiteral":
+			// nothing to do
+		default:
+			panic("unknown XXX field: " + f.Name)
+		}
+		n--
+	}
+
+	// get oneof implementers
+	var oneofImplementers []interface{}
+	// gogo: isOneofMessage is needed for embedded oneof messages, without a marshaler and unmarshaler
+	if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(oneofMessage); ok && isOneofMessage {
+		_, _, _, oneofImplementers = m.XXX_OneofFuncs()
+	}
+
+	// normal fields
+	fields := make([]marshalFieldInfo, n) // batch allocation
+	u.fields = make([]*marshalFieldInfo, 0, n)
+	for i, j := 0, 0; i < t.NumField(); i++ {
+		f := t.Field(i)
+
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		field := &fields[j]
+		j++
+		field.name = f.Name
+		u.fields = append(u.fields, field)
+		if f.Tag.Get("protobuf_oneof") != "" {
+			field.computeOneofFieldInfo(&f, oneofImplementers)
+			continue
+		}
+		if f.Tag.Get("protobuf") == "" {
+			// field has no tag (not in generated message), ignore it
+			u.fields = u.fields[:len(u.fields)-1]
+			j--
+			continue
+		}
+		field.computeMarshalFieldInfo(&f)
+	}
+
+	// fields are marshaled in tag order on the wire.
+	sort.Sort(byTag(u.fields))
+
+	atomic.StoreInt32(&u.initialized, 1)
+}
+
+// helper for sorting fields by tag
+type byTag []*marshalFieldInfo
+
+func (a byTag) Len() int           { return len(a) }
+func (a byTag) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
+func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag }
+
+// getExtElemInfo returns the information to marshal an extension element.
+// The info it returns is initialized.
+func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo {
+	// get from cache first
+	u.RLock()
+	e, ok := u.extElems[desc.Field]
+	u.RUnlock()
+	if ok {
+		return e
+	}
+
+	t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct
+	tags := strings.Split(desc.Tag, ",")
+	tag, err := strconv.Atoi(tags[1])
+	if err != nil {
+		panic("tag is not an integer")
+	}
+	wt := wiretype(tags[0])
+	sizr, marshalr := typeMarshaler(t, tags, false, false)
+	e = &marshalElemInfo{
+		wiretag:   uint64(tag)<<3 | wt,
+		tagsize:   SizeVarint(uint64(tag) << 3),
+		sizer:     sizr,
+		marshaler: marshalr,
+		isptr:     t.Kind() == reflect.Ptr,
+	}
+
+	// update cache
+	u.Lock()
+	if u.extElems == nil {
+		u.extElems = make(map[int32]*marshalElemInfo)
+	}
+	u.extElems[desc.Field] = e
+	u.Unlock()
+	return e
+}
+
+// computeMarshalFieldInfo fills up the information to marshal a field.
+func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) {
+	// parse protobuf tag of the field.
+	// tag has format of "bytes,49,opt,name=foo,def=hello!"
+	tags := strings.Split(f.Tag.Get("protobuf"), ",")
+	if tags[0] == "" {
+		return
+	}
+	tag, err := strconv.Atoi(tags[1])
+	if err != nil {
+		panic("tag is not an integer")
+	}
+	wt := wiretype(tags[0])
+	if tags[2] == "req" {
+		fi.required = true
+	}
+	fi.setTag(f, tag, wt)
+	fi.setMarshaler(f, tags)
+}
+
+func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) {
+	fi.field = toField(f)
+	fi.wiretag = 1<<31 - 1 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire.
+	fi.isPointer = true
+	fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f)
+	fi.oneofElems = make(map[reflect.Type]*marshalElemInfo)
+
+	ityp := f.Type // interface type
+	for _, o := range oneofImplementers {
+		t := reflect.TypeOf(o)
+		if !t.Implements(ityp) {
+			continue
+		}
+		sf := t.Elem().Field(0) // oneof implementer is a struct with a single field
+		tags := strings.Split(sf.Tag.Get("protobuf"), ",")
+		tag, err := strconv.Atoi(tags[1])
+		if err != nil {
+			panic("tag is not an integer")
+		}
+		wt := wiretype(tags[0])
+		sizr, marshalr := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value
+		fi.oneofElems[t.Elem()] = &marshalElemInfo{
+			wiretag:   uint64(tag)<<3 | wt,
+			tagsize:   SizeVarint(uint64(tag) << 3),
+			sizer:     sizr,
+			marshaler: marshalr,
+		}
+	}
+}
+
+type oneofMessage interface {
+	XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{})
+}
+
+// wiretype returns the wire encoding of the type.
+func wiretype(encoding string) uint64 {
+	switch encoding {
+	case "fixed32":
+		return WireFixed32
+	case "fixed64":
+		return WireFixed64
+	case "varint", "zigzag32", "zigzag64":
+		return WireVarint
+	case "bytes":
+		return WireBytes
+	case "group":
+		return WireStartGroup
+	}
+	panic("unknown wire type " + encoding)
+}
+
+// setTag fills up the tag (in wire format) and its size in the info of a field.
+func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) {
+	fi.field = toField(f)
+	fi.wiretag = uint64(tag)<<3 | wt
+	fi.tagsize = SizeVarint(uint64(tag) << 3)
+}
+
+// setMarshaler fills up the sizer and marshaler in the info of a field.
+func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) {
+	switch f.Type.Kind() {
+	case reflect.Map:
+		// map field
+		fi.isPointer = true
+		fi.sizer, fi.marshaler = makeMapMarshaler(f)
+		return
+	case reflect.Ptr, reflect.Slice:
+		fi.isPointer = true
+	}
+	fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false)
+}
+
+// typeMarshaler returns the sizer and marshaler of a given field.
+// t is the type of the field.
+// tags is the generated "protobuf" tag of the field.
+// If nozero is true, zero value is not marshaled to the wire.
+// If oneof is true, it is a oneof field.
+func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) {
+	encoding := tags[0]
+
+	pointer := false
+	slice := false
+	if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
+		slice = true
+		t = t.Elem()
+	}
+	if t.Kind() == reflect.Ptr {
+		pointer = true
+		t = t.Elem()
+	}
+
+	packed := false
+	proto3 := false
+	ctype := false
+	isTime := false
+	isDuration := false
+	isWktPointer := false
+	validateUTF8 := true
+	for i := 2; i < len(tags); i++ {
+		if tags[i] == "packed" {
+			packed = true
+		}
+		if tags[i] == "proto3" {
+			proto3 = true
+		}
+		if strings.HasPrefix(tags[i], "customtype=") {
+			ctype = true
+		}
+		if tags[i] == "stdtime" {
+			isTime = true
+		}
+		if tags[i] == "stdduration" {
+			isDuration = true
+		}
+		if tags[i] == "wktptr" {
+			isWktPointer = true
+		}
+	}
+	validateUTF8 = validateUTF8 && proto3
+	if !proto3 && !pointer && !slice {
+		nozero = false
+	}
+
+	if ctype {
+		if reflect.PtrTo(t).Implements(customType) {
+			if slice {
+				return makeMessageRefSliceMarshaler(getMarshalInfo(t))
+			}
+			if pointer {
+				return makeCustomPtrMarshaler(getMarshalInfo(t))
+			}
+			return makeCustomMarshaler(getMarshalInfo(t))
+		} else {
+			panic(fmt.Sprintf("custom type: type: %v, does not implement the proto.custom interface", t))
+		}
+	}
+
+	if isTime {
+		if pointer {
+			if slice {
+				return makeTimePtrSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeTimePtrMarshaler(getMarshalInfo(t))
+		}
+		if slice {
+			return makeTimeSliceMarshaler(getMarshalInfo(t))
+		}
+		return makeTimeMarshaler(getMarshalInfo(t))
+	}
+
+	if isDuration {
+		if pointer {
+			if slice {
+				return makeDurationPtrSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeDurationPtrMarshaler(getMarshalInfo(t))
+		}
+		if slice {
+			return makeDurationSliceMarshaler(getMarshalInfo(t))
+		}
+		return makeDurationMarshaler(getMarshalInfo(t))
+	}
+
+	if isWktPointer {
+		switch t.Kind() {
+		case reflect.Float64:
+			if pointer {
+				if slice {
+					return makeStdDoubleValuePtrSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeStdDoubleValuePtrMarshaler(getMarshalInfo(t))
+			}
+			if slice {
+				return makeStdDoubleValueSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeStdDoubleValueMarshaler(getMarshalInfo(t))
+		case reflect.Float32:
+			if pointer {
+				if slice {
+					return makeStdFloatValuePtrSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeStdFloatValuePtrMarshaler(getMarshalInfo(t))
+			}
+			if slice {
+				return makeStdFloatValueSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeStdFloatValueMarshaler(getMarshalInfo(t))
+		case reflect.Int64:
+			if pointer {
+				if slice {
+					return makeStdInt64ValuePtrSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeStdInt64ValuePtrMarshaler(getMarshalInfo(t))
+			}
+			if slice {
+				return makeStdInt64ValueSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeStdInt64ValueMarshaler(getMarshalInfo(t))
+		case reflect.Uint64:
+			if pointer {
+				if slice {
+					return makeStdUInt64ValuePtrSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeStdUInt64ValuePtrMarshaler(getMarshalInfo(t))
+			}
+			if slice {
+				return makeStdUInt64ValueSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeStdUInt64ValueMarshaler(getMarshalInfo(t))
+		case reflect.Int32:
+			if pointer {
+				if slice {
+					return makeStdInt32ValuePtrSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeStdInt32ValuePtrMarshaler(getMarshalInfo(t))
+			}
+			if slice {
+				return makeStdInt32ValueSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeStdInt32ValueMarshaler(getMarshalInfo(t))
+		case reflect.Uint32:
+			if pointer {
+				if slice {
+					return makeStdUInt32ValuePtrSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeStdUInt32ValuePtrMarshaler(getMarshalInfo(t))
+			}
+			if slice {
+				return makeStdUInt32ValueSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeStdUInt32ValueMarshaler(getMarshalInfo(t))
+		case reflect.Bool:
+			if pointer {
+				if slice {
+					return makeStdBoolValuePtrSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeStdBoolValuePtrMarshaler(getMarshalInfo(t))
+			}
+			if slice {
+				return makeStdBoolValueSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeStdBoolValueMarshaler(getMarshalInfo(t))
+		case reflect.String:
+			if pointer {
+				if slice {
+					return makeStdStringValuePtrSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeStdStringValuePtrMarshaler(getMarshalInfo(t))
+			}
+			if slice {
+				return makeStdStringValueSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeStdStringValueMarshaler(getMarshalInfo(t))
+		case uint8SliceType:
+			if pointer {
+				if slice {
+					return makeStdBytesValuePtrSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeStdBytesValuePtrMarshaler(getMarshalInfo(t))
+			}
+			if slice {
+				return makeStdBytesValueSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeStdBytesValueMarshaler(getMarshalInfo(t))
+		default:
+			panic(fmt.Sprintf("unknown wktpointer type %#v", t))
+		}
+	}
+
+	switch t.Kind() {
+	case reflect.Bool:
+		if pointer {
+			return sizeBoolPtr, appendBoolPtr
+		}
+		if slice {
+			if packed {
+				return sizeBoolPackedSlice, appendBoolPackedSlice
+			}
+			return sizeBoolSlice, appendBoolSlice
+		}
+		if nozero {
+			return sizeBoolValueNoZero, appendBoolValueNoZero
+		}
+		return sizeBoolValue, appendBoolValue
+	case reflect.Uint32:
+		switch encoding {
+		case "fixed32":
+			if pointer {
+				return sizeFixed32Ptr, appendFixed32Ptr
+			}
+			if slice {
+				if packed {
+					return sizeFixed32PackedSlice, appendFixed32PackedSlice
+				}
+				return sizeFixed32Slice, appendFixed32Slice
+			}
+			if nozero {
+				return sizeFixed32ValueNoZero, appendFixed32ValueNoZero
+			}
+			return sizeFixed32Value, appendFixed32Value
+		case "varint":
+			if pointer {
+				return sizeVarint32Ptr, appendVarint32Ptr
+			}
+			if slice {
+				if packed {
+					return sizeVarint32PackedSlice, appendVarint32PackedSlice
+				}
+				return sizeVarint32Slice, appendVarint32Slice
+			}
+			if nozero {
+				return sizeVarint32ValueNoZero, appendVarint32ValueNoZero
+			}
+			return sizeVarint32Value, appendVarint32Value
+		}
+	case reflect.Int32:
+		switch encoding {
+		case "fixed32":
+			if pointer {
+				return sizeFixedS32Ptr, appendFixedS32Ptr
+			}
+			if slice {
+				if packed {
+					return sizeFixedS32PackedSlice, appendFixedS32PackedSlice
+				}
+				return sizeFixedS32Slice, appendFixedS32Slice
+			}
+			if nozero {
+				return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero
+			}
+			return sizeFixedS32Value, appendFixedS32Value
+		case "varint":
+			if pointer {
+				return sizeVarintS32Ptr, appendVarintS32Ptr
+			}
+			if slice {
+				if packed {
+					return sizeVarintS32PackedSlice, appendVarintS32PackedSlice
+				}
+				return sizeVarintS32Slice, appendVarintS32Slice
+			}
+			if nozero {
+				return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero
+			}
+			return sizeVarintS32Value, appendVarintS32Value
+		case "zigzag32":
+			if pointer {
+				return sizeZigzag32Ptr, appendZigzag32Ptr
+			}
+			if slice {
+				if packed {
+					return sizeZigzag32PackedSlice, appendZigzag32PackedSlice
+				}
+				return sizeZigzag32Slice, appendZigzag32Slice
+			}
+			if nozero {
+				return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero
+			}
+			return sizeZigzag32Value, appendZigzag32Value
+		}
+	case reflect.Uint64:
+		switch encoding {
+		case "fixed64":
+			if pointer {
+				return sizeFixed64Ptr, appendFixed64Ptr
+			}
+			if slice {
+				if packed {
+					return sizeFixed64PackedSlice, appendFixed64PackedSlice
+				}
+				return sizeFixed64Slice, appendFixed64Slice
+			}
+			if nozero {
+				return sizeFixed64ValueNoZero, appendFixed64ValueNoZero
+			}
+			return sizeFixed64Value, appendFixed64Value
+		case "varint":
+			if pointer {
+				return sizeVarint64Ptr, appendVarint64Ptr
+			}
+			if slice {
+				if packed {
+					return sizeVarint64PackedSlice, appendVarint64PackedSlice
+				}
+				return sizeVarint64Slice, appendVarint64Slice
+			}
+			if nozero {
+				return sizeVarint64ValueNoZero, appendVarint64ValueNoZero
+			}
+			return sizeVarint64Value, appendVarint64Value
+		}
+	case reflect.Int64:
+		switch encoding {
+		case "fixed64":
+			if pointer {
+				return sizeFixedS64Ptr, appendFixedS64Ptr
+			}
+			if slice {
+				if packed {
+					return sizeFixedS64PackedSlice, appendFixedS64PackedSlice
+				}
+				return sizeFixedS64Slice, appendFixedS64Slice
+			}
+			if nozero {
+				return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero
+			}
+			return sizeFixedS64Value, appendFixedS64Value
+		case "varint":
+			if pointer {
+				return sizeVarintS64Ptr, appendVarintS64Ptr
+			}
+			if slice {
+				if packed {
+					return sizeVarintS64PackedSlice, appendVarintS64PackedSlice
+				}
+				return sizeVarintS64Slice, appendVarintS64Slice
+			}
+			if nozero {
+				return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero
+			}
+			return sizeVarintS64Value, appendVarintS64Value
+		case "zigzag64":
+			if pointer {
+				return sizeZigzag64Ptr, appendZigzag64Ptr
+			}
+			if slice {
+				if packed {
+					return sizeZigzag64PackedSlice, appendZigzag64PackedSlice
+				}
+				return sizeZigzag64Slice, appendZigzag64Slice
+			}
+			if nozero {
+				return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero
+			}
+			return sizeZigzag64Value, appendZigzag64Value
+		}
+	case reflect.Float32:
+		if pointer {
+			return sizeFloat32Ptr, appendFloat32Ptr
+		}
+		if slice {
+			if packed {
+				return sizeFloat32PackedSlice, appendFloat32PackedSlice
+			}
+			return sizeFloat32Slice, appendFloat32Slice
+		}
+		if nozero {
+			return sizeFloat32ValueNoZero, appendFloat32ValueNoZero
+		}
+		return sizeFloat32Value, appendFloat32Value
+	case reflect.Float64:
+		if pointer {
+			return sizeFloat64Ptr, appendFloat64Ptr
+		}
+		if slice {
+			if packed {
+				return sizeFloat64PackedSlice, appendFloat64PackedSlice
+			}
+			return sizeFloat64Slice, appendFloat64Slice
+		}
+		if nozero {
+			return sizeFloat64ValueNoZero, appendFloat64ValueNoZero
+		}
+		return sizeFloat64Value, appendFloat64Value
+	case reflect.String:
+		if validateUTF8 {
+			if pointer {
+				return sizeStringPtr, appendUTF8StringPtr
+			}
+			if slice {
+				return sizeStringSlice, appendUTF8StringSlice
+			}
+			if nozero {
+				return sizeStringValueNoZero, appendUTF8StringValueNoZero
+			}
+			return sizeStringValue, appendUTF8StringValue
+		}
+		if pointer {
+			return sizeStringPtr, appendStringPtr
+		}
+		if slice {
+			return sizeStringSlice, appendStringSlice
+		}
+		if nozero {
+			return sizeStringValueNoZero, appendStringValueNoZero
+		}
+		return sizeStringValue, appendStringValue
+	case reflect.Slice:
+		if slice {
+			return sizeBytesSlice, appendBytesSlice
+		}
+		if oneof {
+			// Oneof bytes field may also have "proto3" tag.
+			// We want to marshal it as a oneof field. Do this
+			// check before the proto3 check.
+			return sizeBytesOneof, appendBytesOneof
+		}
+		if proto3 {
+			return sizeBytes3, appendBytes3
+		}
+		return sizeBytes, appendBytes
+	case reflect.Struct:
+		switch encoding {
+		case "group":
+			if slice {
+				return makeGroupSliceMarshaler(getMarshalInfo(t))
+			}
+			return makeGroupMarshaler(getMarshalInfo(t))
+		case "bytes":
+			if pointer {
+				if slice {
+					return makeMessageSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeMessageMarshaler(getMarshalInfo(t))
+			} else {
+				if slice {
+					return makeMessageRefSliceMarshaler(getMarshalInfo(t))
+				}
+				return makeMessageRefMarshaler(getMarshalInfo(t))
+			}
+		}
+	}
+	panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding))
+}
+
+// Below are functions to size/marshal a specific type of a field.
+// They are stored in the field's info, and called by function pointers.
+// They have type sizer or marshaler.
+
+func sizeFixed32Value(_ pointer, tagsize int) int {
+	return 4 + tagsize
+}
+func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toUint32()
+	if v == 0 {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFixed32Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toUint32Ptr()
+	if p == nil {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFixed32Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint32Slice()
+	return (4 + tagsize) * len(s)
+}
+func sizeFixed32PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
+}
+func sizeFixedS32Value(_ pointer, tagsize int) int {
+	return 4 + tagsize
+}
+func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt32()
+	if v == 0 {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFixedS32Ptr(ptr pointer, tagsize int) int {
+	p := ptr.getInt32Ptr()
+	if p == nil {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFixedS32Slice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	return (4 + tagsize) * len(s)
+}
+func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
+}
+func sizeFloat32Value(_ pointer, tagsize int) int {
+	return 4 + tagsize
+}
+func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int {
+	v := math.Float32bits(*ptr.toFloat32())
+	if v == 0 {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFloat32Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toFloat32Ptr()
+	if p == nil {
+		return 0
+	}
+	return 4 + tagsize
+}
+func sizeFloat32Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toFloat32Slice()
+	return (4 + tagsize) * len(s)
+}
+func sizeFloat32PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toFloat32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize
+}
+func sizeFixed64Value(_ pointer, tagsize int) int {
+	return 8 + tagsize
+}
+func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toUint64()
+	if v == 0 {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFixed64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toUint64Ptr()
+	if p == nil {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFixed64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint64Slice()
+	return (8 + tagsize) * len(s)
+}
+func sizeFixed64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
+}
+func sizeFixedS64Value(_ pointer, tagsize int) int {
+	return 8 + tagsize
+}
+func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt64()
+	if v == 0 {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFixedS64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toInt64Ptr()
+	if p == nil {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFixedS64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	return (8 + tagsize) * len(s)
+}
+func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
+}
+func sizeFloat64Value(_ pointer, tagsize int) int {
+	return 8 + tagsize
+}
+func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int {
+	v := math.Float64bits(*ptr.toFloat64())
+	if v == 0 {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFloat64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toFloat64Ptr()
+	if p == nil {
+		return 0
+	}
+	return 8 + tagsize
+}
+func sizeFloat64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toFloat64Slice()
+	return (8 + tagsize) * len(s)
+}
+func sizeFloat64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toFloat64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize
+}
+func sizeVarint32Value(ptr pointer, tagsize int) int {
+	v := *ptr.toUint32()
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toUint32()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarint32Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toUint32Ptr()
+	if p == nil {
+		return 0
+	}
+	return SizeVarint(uint64(*p)) + tagsize
+}
+func sizeVarint32Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint32Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v)) + tagsize
+	}
+	return n
+}
+func sizeVarint32PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v))
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeVarintS32Value(ptr pointer, tagsize int) int {
+	v := *ptr.toInt32()
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt32()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS32Ptr(ptr pointer, tagsize int) int {
+	p := ptr.getInt32Ptr()
+	if p == nil {
+		return 0
+	}
+	return SizeVarint(uint64(*p)) + tagsize
+}
+func sizeVarintS32Slice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v)) + tagsize
+	}
+	return n
+}
+func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v))
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeVarint64Value(ptr pointer, tagsize int) int {
+	v := *ptr.toUint64()
+	return SizeVarint(v) + tagsize
+}
+func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toUint64()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(v) + tagsize
+}
+func sizeVarint64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toUint64Ptr()
+	if p == nil {
+		return 0
+	}
+	return SizeVarint(*p) + tagsize
+}
+func sizeVarint64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint64Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(v) + tagsize
+	}
+	return n
+}
+func sizeVarint64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toUint64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(v)
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeVarintS64Value(ptr pointer, tagsize int) int {
+	v := *ptr.toInt64()
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt64()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(uint64(v)) + tagsize
+}
+func sizeVarintS64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toInt64Ptr()
+	if p == nil {
+		return 0
+	}
+	return SizeVarint(uint64(*p)) + tagsize
+}
+func sizeVarintS64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v)) + tagsize
+	}
+	return n
+}
+func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v))
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeZigzag32Value(ptr pointer, tagsize int) int {
+	v := *ptr.toInt32()
+	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+}
+func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt32()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+}
+func sizeZigzag32Ptr(ptr pointer, tagsize int) int {
+	p := ptr.getInt32Ptr()
+	if p == nil {
+		return 0
+	}
+	v := *p
+	return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+}
+func sizeZigzag32Slice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize
+	}
+	return n
+}
+func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int {
+	s := ptr.getInt32Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeZigzag64Value(ptr pointer, tagsize int) int {
+	v := *ptr.toInt64()
+	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+}
+func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toInt64()
+	if v == 0 {
+		return 0
+	}
+	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+}
+func sizeZigzag64Ptr(ptr pointer, tagsize int) int {
+	p := *ptr.toInt64Ptr()
+	if p == nil {
+		return 0
+	}
+	v := *p
+	return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+}
+func sizeZigzag64Slice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize
+	}
+	return n
+}
+func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toInt64Slice()
+	if len(s) == 0 {
+		return 0
+	}
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))
+	}
+	return n + SizeVarint(uint64(n)) + tagsize
+}
+func sizeBoolValue(_ pointer, tagsize int) int {
+	return 1 + tagsize
+}
+func sizeBoolValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toBool()
+	if !v {
+		return 0
+	}
+	return 1 + tagsize
+}
+func sizeBoolPtr(ptr pointer, tagsize int) int {
+	p := *ptr.toBoolPtr()
+	if p == nil {
+		return 0
+	}
+	return 1 + tagsize
+}
+func sizeBoolSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toBoolSlice()
+	return (1 + tagsize) * len(s)
+}
+func sizeBoolPackedSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toBoolSlice()
+	if len(s) == 0 {
+		return 0
+	}
+	return len(s) + SizeVarint(uint64(len(s))) + tagsize
+}
+func sizeStringValue(ptr pointer, tagsize int) int {
+	v := *ptr.toString()
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeStringValueNoZero(ptr pointer, tagsize int) int {
+	v := *ptr.toString()
+	if v == "" {
+		return 0
+	}
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeStringPtr(ptr pointer, tagsize int) int {
+	p := *ptr.toStringPtr()
+	if p == nil {
+		return 0
+	}
+	v := *p
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeStringSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toStringSlice()
+	n := 0
+	for _, v := range s {
+		n += len(v) + SizeVarint(uint64(len(v))) + tagsize
+	}
+	return n
+}
+func sizeBytes(ptr pointer, tagsize int) int {
+	v := *ptr.toBytes()
+	if v == nil {
+		return 0
+	}
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeBytes3(ptr pointer, tagsize int) int {
+	v := *ptr.toBytes()
+	if len(v) == 0 {
+		return 0
+	}
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeBytesOneof(ptr pointer, tagsize int) int {
+	v := *ptr.toBytes()
+	return len(v) + SizeVarint(uint64(len(v))) + tagsize
+}
+func sizeBytesSlice(ptr pointer, tagsize int) int {
+	s := *ptr.toBytesSlice()
+	n := 0
+	for _, v := range s {
+		n += len(v) + SizeVarint(uint64(len(v))) + tagsize
+	}
+	return n
+}
+
+// appendFixed32 appends an encoded fixed32 to b.
+func appendFixed32(b []byte, v uint32) []byte {
+	b = append(b,
+		byte(v),
+		byte(v>>8),
+		byte(v>>16),
+		byte(v>>24))
+	return b
+}
+
+// appendFixed64 appends an encoded fixed64 to b.
+func appendFixed64(b []byte, v uint64) []byte {
+	b = append(b,
+		byte(v),
+		byte(v>>8),
+		byte(v>>16),
+		byte(v>>24),
+		byte(v>>32),
+		byte(v>>40),
+		byte(v>>48),
+		byte(v>>56))
+	return b
+}
+
+// appendVarint appends an encoded varint to b.
+func appendVarint(b []byte, v uint64) []byte {
+	// TODO: make 1-byte (maybe 2-byte) case inline-able, once we
+	// have non-leaf inliner.
+	switch {
+	case v < 1<<7:
+		b = append(b, byte(v))
+	case v < 1<<14:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte(v>>7))
+	case v < 1<<21:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte(v>>14))
+	case v < 1<<28:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte(v>>21))
+	case v < 1<<35:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte(v>>28))
+	case v < 1<<42:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte(v>>35))
+	case v < 1<<49:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte(v>>42))
+	case v < 1<<56:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte((v>>42)&0x7f|0x80),
+			byte(v>>49))
+	case v < 1<<63:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte((v>>42)&0x7f|0x80),
+			byte((v>>49)&0x7f|0x80),
+			byte(v>>56))
+	default:
+		b = append(b,
+			byte(v&0x7f|0x80),
+			byte((v>>7)&0x7f|0x80),
+			byte((v>>14)&0x7f|0x80),
+			byte((v>>21)&0x7f|0x80),
+			byte((v>>28)&0x7f|0x80),
+			byte((v>>35)&0x7f|0x80),
+			byte((v>>42)&0x7f|0x80),
+			byte((v>>49)&0x7f|0x80),
+			byte((v>>56)&0x7f|0x80),
+			1)
+	}
+	return b
+}
+
+func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toUint32()
+	b = appendVarint(b, wiretag)
+	b = appendFixed32(b, v)
+	return b, nil
+}
+func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toUint32()
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed32(b, v)
+	return b, nil
+}
+func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toUint32Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed32(b, *p)
+	return b, nil
+}
+func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toUint32Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendFixed32(b, v)
+	}
+	return b, nil
+}
+func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toUint32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	b = appendVarint(b, uint64(4*len(s)))
+	for _, v := range s {
+		b = appendFixed32(b, v)
+	}
+	return b, nil
+}
+func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt32()
+	b = appendVarint(b, wiretag)
+	b = appendFixed32(b, uint32(v))
+	return b, nil
+}
+func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt32()
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed32(b, uint32(v))
+	return b, nil
+}
+func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := ptr.getInt32Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed32(b, uint32(*p))
+	return b, nil
+}
+func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := ptr.getInt32Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendFixed32(b, uint32(v))
+	}
+	return b, nil
+}
+func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := ptr.getInt32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	b = appendVarint(b, uint64(4*len(s)))
+	for _, v := range s {
+		b = appendFixed32(b, uint32(v))
+	}
+	return b, nil
+}
+func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := math.Float32bits(*ptr.toFloat32())
+	b = appendVarint(b, wiretag)
+	b = appendFixed32(b, v)
+	return b, nil
+}
+func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := math.Float32bits(*ptr.toFloat32())
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed32(b, v)
+	return b, nil
+}
+func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toFloat32Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed32(b, math.Float32bits(*p))
+	return b, nil
+}
+func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toFloat32Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendFixed32(b, math.Float32bits(v))
+	}
+	return b, nil
+}
+func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toFloat32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	b = appendVarint(b, uint64(4*len(s)))
+	for _, v := range s {
+		b = appendFixed32(b, math.Float32bits(v))
+	}
+	return b, nil
+}
+func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toUint64()
+	b = appendVarint(b, wiretag)
+	b = appendFixed64(b, v)
+	return b, nil
+}
+func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toUint64()
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed64(b, v)
+	return b, nil
+}
+func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toUint64Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed64(b, *p)
+	return b, nil
+}
+func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toUint64Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendFixed64(b, v)
+	}
+	return b, nil
+}
+func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toUint64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	b = appendVarint(b, uint64(8*len(s)))
+	for _, v := range s {
+		b = appendFixed64(b, v)
+	}
+	return b, nil
+}
+func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt64()
+	b = appendVarint(b, wiretag)
+	b = appendFixed64(b, uint64(v))
+	return b, nil
+}
+func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt64()
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed64(b, uint64(v))
+	return b, nil
+}
+func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toInt64Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed64(b, uint64(*p))
+	return b, nil
+}
+func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toInt64Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendFixed64(b, uint64(v))
+	}
+	return b, nil
+}
+func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toInt64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	b = appendVarint(b, uint64(8*len(s)))
+	for _, v := range s {
+		b = appendFixed64(b, uint64(v))
+	}
+	return b, nil
+}
+func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := math.Float64bits(*ptr.toFloat64())
+	b = appendVarint(b, wiretag)
+	b = appendFixed64(b, v)
+	return b, nil
+}
+func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := math.Float64bits(*ptr.toFloat64())
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed64(b, v)
+	return b, nil
+}
+func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toFloat64Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendFixed64(b, math.Float64bits(*p))
+	return b, nil
+}
+func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toFloat64Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendFixed64(b, math.Float64bits(v))
+	}
+	return b, nil
+}
+func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toFloat64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	b = appendVarint(b, uint64(8*len(s)))
+	for _, v := range s {
+		b = appendFixed64(b, math.Float64bits(v))
+	}
+	return b, nil
+}
+func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toUint32()
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(v))
+	return b, nil
+}
+func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toUint32()
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(v))
+	return b, nil
+}
+func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toUint32Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(*p))
+	return b, nil
+}
+func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toUint32Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toUint32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	// compute size
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v))
+	}
+	b = appendVarint(b, uint64(n))
+	for _, v := range s {
+		b = appendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt32()
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(v))
+	return b, nil
+}
+func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt32()
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(v))
+	return b, nil
+}
+func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := ptr.getInt32Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(*p))
+	return b, nil
+}
+func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := ptr.getInt32Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := ptr.getInt32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	// compute size
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v))
+	}
+	b = appendVarint(b, uint64(n))
+	for _, v := range s {
+		b = appendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toUint64()
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, v)
+	return b, nil
+}
+func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toUint64()
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, v)
+	return b, nil
+}
+func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toUint64Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, *p)
+	return b, nil
+}
+func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toUint64Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendVarint(b, v)
+	}
+	return b, nil
+}
+func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toUint64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	// compute size
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(v)
+	}
+	b = appendVarint(b, uint64(n))
+	for _, v := range s {
+		b = appendVarint(b, v)
+	}
+	return b, nil
+}
+func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt64()
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(v))
+	return b, nil
+}
+func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt64()
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(v))
+	return b, nil
+}
+func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toInt64Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(*p))
+	return b, nil
+}
+func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toInt64Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toInt64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	// compute size
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v))
+	}
+	b = appendVarint(b, uint64(n))
+	for _, v := range s {
+		b = appendVarint(b, uint64(v))
+	}
+	return b, nil
+}
+func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt32()
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
+	return b, nil
+}
+func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt32()
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
+	return b, nil
+}
+func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := ptr.getInt32Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	v := *p
+	b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
+	return b, nil
+}
+func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := ptr.getInt32Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
+	}
+	return b, nil
+}
+func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := ptr.getInt32Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	// compute size
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31))))
+	}
+	b = appendVarint(b, uint64(n))
+	for _, v := range s {
+		b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31))))
+	}
+	return b, nil
+}
+func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt64()
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
+	return b, nil
+}
+func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toInt64()
+	if v == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
+	return b, nil
+}
+func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toInt64Ptr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	v := *p
+	b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
+	return b, nil
+}
+func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toInt64Slice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
+	}
+	return b, nil
+}
+func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toInt64Slice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	// compute size
+	n := 0
+	for _, v := range s {
+		n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63)))
+	}
+	b = appendVarint(b, uint64(n))
+	for _, v := range s {
+		b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63)))
+	}
+	return b, nil
+}
+func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toBool()
+	b = appendVarint(b, wiretag)
+	if v {
+		b = append(b, 1)
+	} else {
+		b = append(b, 0)
+	}
+	return b, nil
+}
+func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toBool()
+	if !v {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = append(b, 1)
+	return b, nil
+}
+
+func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toBoolPtr()
+	if p == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	if *p {
+		b = append(b, 1)
+	} else {
+		b = append(b, 0)
+	}
+	return b, nil
+}
+func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toBoolSlice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		if v {
+			b = append(b, 1)
+		} else {
+			b = append(b, 0)
+		}
+	}
+	return b, nil
+}
+func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toBoolSlice()
+	if len(s) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag&^7|WireBytes)
+	b = appendVarint(b, uint64(len(s)))
+	for _, v := range s {
+		if v {
+			b = append(b, 1)
+		} else {
+			b = append(b, 0)
+		}
+	}
+	return b, nil
+}
+func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toString()
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(len(v)))
+	b = append(b, v...)
+	return b, nil
+}
+func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toString()
+	if v == "" {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(len(v)))
+	b = append(b, v...)
+	return b, nil
+}
+func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	p := *ptr.toStringPtr()
+	if p == nil {
+		return b, nil
+	}
+	v := *p
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(len(v)))
+	b = append(b, v...)
+	return b, nil
+}
+func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toStringSlice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendVarint(b, uint64(len(v)))
+		b = append(b, v...)
+	}
+	return b, nil
+}
+func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	var invalidUTF8 bool
+	v := *ptr.toString()
+	if !utf8.ValidString(v) {
+		invalidUTF8 = true
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(len(v)))
+	b = append(b, v...)
+	if invalidUTF8 {
+		return b, errInvalidUTF8
+	}
+	return b, nil
+}
+func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	var invalidUTF8 bool
+	v := *ptr.toString()
+	if v == "" {
+		return b, nil
+	}
+	if !utf8.ValidString(v) {
+		invalidUTF8 = true
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(len(v)))
+	b = append(b, v...)
+	if invalidUTF8 {
+		return b, errInvalidUTF8
+	}
+	return b, nil
+}
+func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	var invalidUTF8 bool
+	p := *ptr.toStringPtr()
+	if p == nil {
+		return b, nil
+	}
+	v := *p
+	if !utf8.ValidString(v) {
+		invalidUTF8 = true
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(len(v)))
+	b = append(b, v...)
+	if invalidUTF8 {
+		return b, errInvalidUTF8
+	}
+	return b, nil
+}
+func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	var invalidUTF8 bool
+	s := *ptr.toStringSlice()
+	for _, v := range s {
+		if !utf8.ValidString(v) {
+			invalidUTF8 = true
+		}
+		b = appendVarint(b, wiretag)
+		b = appendVarint(b, uint64(len(v)))
+		b = append(b, v...)
+	}
+	if invalidUTF8 {
+		return b, errInvalidUTF8
+	}
+	return b, nil
+}
+func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toBytes()
+	if v == nil {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(len(v)))
+	b = append(b, v...)
+	return b, nil
+}
+func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toBytes()
+	if len(v) == 0 {
+		return b, nil
+	}
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(len(v)))
+	b = append(b, v...)
+	return b, nil
+}
+func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	v := *ptr.toBytes()
+	b = appendVarint(b, wiretag)
+	b = appendVarint(b, uint64(len(v)))
+	b = append(b, v...)
+	return b, nil
+}
+func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	s := *ptr.toBytesSlice()
+	for _, v := range s {
+		b = appendVarint(b, wiretag)
+		b = appendVarint(b, uint64(len(v)))
+		b = append(b, v...)
+	}
+	return b, nil
+}
+
+// makeGroupMarshaler returns the sizer and marshaler for a group.
+// u is the marshal info of the underlying message.
+func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			p := ptr.getPointer()
+			if p.isNil() {
+				return 0
+			}
+			return u.size(p) + 2*tagsize
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			p := ptr.getPointer()
+			if p.isNil() {
+				return b, nil
+			}
+			var err error
+			b = appendVarint(b, wiretag) // start group
+			b, err = u.marshal(b, p, deterministic)
+			b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
+			return b, err
+		}
+}
+
+// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice.
+// u is the marshal info of the underlying message.
+func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getPointerSlice()
+			n := 0
+			for _, v := range s {
+				if v.isNil() {
+					continue
+				}
+				n += u.size(v) + 2*tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getPointerSlice()
+			var err error
+			var nerr nonFatal
+			for _, v := range s {
+				if v.isNil() {
+					return b, errRepeatedHasNil
+				}
+				b = appendVarint(b, wiretag) // start group
+				b, err = u.marshal(b, v, deterministic)
+				b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
+				if !nerr.Merge(err) {
+					if err == ErrNil {
+						err = errRepeatedHasNil
+					}
+					return b, err
+				}
+			}
+			return b, nerr.E
+		}
+}
+
+// makeMessageMarshaler returns the sizer and marshaler for a message field.
+// u is the marshal info of the message.
+func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			p := ptr.getPointer()
+			if p.isNil() {
+				return 0
+			}
+			siz := u.size(p)
+			return siz + SizeVarint(uint64(siz)) + tagsize
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			p := ptr.getPointer()
+			if p.isNil() {
+				return b, nil
+			}
+			b = appendVarint(b, wiretag)
+			siz := u.cachedsize(p)
+			b = appendVarint(b, uint64(siz))
+			return u.marshal(b, p, deterministic)
+		}
+}
+
+// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice.
+// u is the marshal info of the message.
+func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getPointerSlice()
+			n := 0
+			for _, v := range s {
+				if v.isNil() {
+					continue
+				}
+				siz := u.size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getPointerSlice()
+			var err error
+			var nerr nonFatal
+			for _, v := range s {
+				if v.isNil() {
+					return b, errRepeatedHasNil
+				}
+				b = appendVarint(b, wiretag)
+				siz := u.cachedsize(v)
+				b = appendVarint(b, uint64(siz))
+				b, err = u.marshal(b, v, deterministic)
+
+				if !nerr.Merge(err) {
+					if err == ErrNil {
+						err = errRepeatedHasNil
+					}
+					return b, err
+				}
+			}
+			return b, nerr.E
+		}
+}
+
+// makeMapMarshaler returns the sizer and marshaler for a map field.
+// f is the pointer to the reflect data structure of the field.
+func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
+	// figure out key and value type
+	t := f.Type
+	keyType := t.Key()
+	valType := t.Elem()
+	tags := strings.Split(f.Tag.Get("protobuf"), ",")
+	keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",")
+	valTags := strings.Split(f.Tag.Get("protobuf_val"), ",")
+	stdOptions := false
+	for _, t := range tags {
+		if strings.HasPrefix(t, "customtype=") {
+			valTags = append(valTags, t)
+		}
+		if t == "stdtime" {
+			valTags = append(valTags, t)
+			stdOptions = true
+		}
+		if t == "stdduration" {
+			valTags = append(valTags, t)
+			stdOptions = true
+		}
+		if t == "wktptr" {
+			valTags = append(valTags, t)
+		}
+	}
+	keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map
+	valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map
+	keyWireTag := 1<<3 | wiretype(keyTags[0])
+	valWireTag := 2<<3 | wiretype(valTags[0])
+
+	// We create an interface to get the addresses of the map key and value.
+	// If value is pointer-typed, the interface is a direct interface, the
+	// idata itself is the value. Otherwise, the idata is the pointer to the
+	// value.
+	// Key cannot be pointer-typed.
+	valIsPtr := valType.Kind() == reflect.Ptr
+
+	// If value is a message with nested maps, calling
+	// valSizer in marshal may be quadratic. We should use
+	// cached version in marshal (but not in size).
+	// If value is not message type, we don't have size cache,
+	// but it cannot be nested either. Just use valSizer.
+	valCachedSizer := valSizer
+	if valIsPtr && !stdOptions && valType.Elem().Kind() == reflect.Struct {
+		u := getMarshalInfo(valType.Elem())
+		valCachedSizer = func(ptr pointer, tagsize int) int {
+			// Same as message sizer, but use cache.
+			p := ptr.getPointer()
+			if p.isNil() {
+				return 0
+			}
+			siz := u.cachedsize(p)
+			return siz + SizeVarint(uint64(siz)) + tagsize
+		}
+	}
+	return func(ptr pointer, tagsize int) int {
+			m := ptr.asPointerTo(t).Elem() // the map
+			n := 0
+			for _, k := range m.MapKeys() {
+				ki := k.Interface()
+				vi := m.MapIndex(k).Interface()
+				kaddr := toAddrPointer(&ki, false)             // pointer to key
+				vaddr := toAddrPointer(&vi, valIsPtr)          // pointer to value
+				siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) {
+			m := ptr.asPointerTo(t).Elem() // the map
+			var err error
+			keys := m.MapKeys()
+			if len(keys) > 1 && deterministic {
+				sort.Sort(mapKeys(keys))
+			}
+
+			var nerr nonFatal
+			for _, k := range keys {
+				ki := k.Interface()
+				vi := m.MapIndex(k).Interface()
+				kaddr := toAddrPointer(&ki, false)    // pointer to key
+				vaddr := toAddrPointer(&vi, valIsPtr) // pointer to value
+				b = appendVarint(b, tag)
+				siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
+				b = appendVarint(b, uint64(siz))
+				b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic)
+				if !nerr.Merge(err) {
+					return b, err
+				}
+				b, err = valMarshaler(b, vaddr, valWireTag, deterministic)
+				if err != ErrNil && !nerr.Merge(err) { // allow nil value in map
+					return b, err
+				}
+			}
+			return b, nerr.E
+		}
+}
+
+// makeOneOfMarshaler returns the sizer and marshaler for a oneof field.
+// fi is the marshal info of the field.
+// f is the pointer to the reflect data structure of the field.
+func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) {
+	// Oneof field is an interface. We need to get the actual data type on the fly.
+	t := f.Type
+	return func(ptr pointer, _ int) int {
+			p := ptr.getInterfacePointer()
+			if p.isNil() {
+				return 0
+			}
+			v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct
+			telem := v.Type()
+			e := fi.oneofElems[telem]
+			return e.sizer(p, e.tagsize)
+		},
+		func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) {
+			p := ptr.getInterfacePointer()
+			if p.isNil() {
+				return b, nil
+			}
+			v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct
+			telem := v.Type()
+			if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() {
+				return b, errOneofHasNil
+			}
+			e := fi.oneofElems[telem]
+			return e.marshaler(b, p, e.wiretag, deterministic)
+		}
+}
+
+// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field.
+func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int {
+	m, mu := ext.extensionsRead()
+	if m == nil {
+		return 0
+	}
+	mu.Lock()
+
+	n := 0
+	for _, e := range m {
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			n += len(e.enc)
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+		ei := u.getExtElemInfo(e.desc)
+		v := e.value
+		p := toAddrPointer(&v, ei.isptr)
+		n += ei.sizer(p, ei.tagsize)
+	}
+	mu.Unlock()
+	return n
+}
+
+// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b.
+func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) {
+	m, mu := ext.extensionsRead()
+	if m == nil {
+		return b, nil
+	}
+	mu.Lock()
+	defer mu.Unlock()
+
+	var err error
+	var nerr nonFatal
+
+	// Fast-path for common cases: zero or one extensions.
+	// Don't bother sorting the keys.
+	if len(m) <= 1 {
+		for _, e := range m {
+			if e.value == nil || e.desc == nil {
+				// Extension is only in its encoded form.
+				b = append(b, e.enc...)
+				continue
+			}
+
+			// We don't skip extensions that have an encoded form set,
+			// because the extension value may have been mutated after
+			// the last time this function was called.
+
+			ei := u.getExtElemInfo(e.desc)
+			v := e.value
+			p := toAddrPointer(&v, ei.isptr)
+			b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
+			if !nerr.Merge(err) {
+				return b, err
+			}
+		}
+		return b, nerr.E
+	}
+
+	// Sort the keys to provide a deterministic encoding.
+	// Not sure this is required, but the old code does it.
+	keys := make([]int, 0, len(m))
+	for k := range m {
+		keys = append(keys, int(k))
+	}
+	sort.Ints(keys)
+
+	for _, k := range keys {
+		e := m[int32(k)]
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			b = append(b, e.enc...)
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		ei := u.getExtElemInfo(e.desc)
+		v := e.value
+		p := toAddrPointer(&v, ei.isptr)
+		b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
+		if !nerr.Merge(err) {
+			return b, err
+		}
+	}
+	return b, nerr.E
+}
+
+// message set format is:
+//   message MessageSet {
+//     repeated group Item = 1 {
+//       required int32 type_id = 2;
+//       required string message = 3;
+//     };
+//   }
+
+// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field
+// in message set format (above).
+func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int {
+	m, mu := ext.extensionsRead()
+	if m == nil {
+		return 0
+	}
+	mu.Lock()
+
+	n := 0
+	for id, e := range m {
+		n += 2                          // start group, end group. tag = 1 (size=1)
+		n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1)
+
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
+			siz := len(msgWithLen)
+			n += siz + 1 // message, tag = 3 (size=1)
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		ei := u.getExtElemInfo(e.desc)
+		v := e.value
+		p := toAddrPointer(&v, ei.isptr)
+		n += ei.sizer(p, 1) // message, tag = 3 (size=1)
+	}
+	mu.Unlock()
+	return n
+}
+
+// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above)
+// to the end of byte slice b.
+func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) {
+	m, mu := ext.extensionsRead()
+	if m == nil {
+		return b, nil
+	}
+	mu.Lock()
+	defer mu.Unlock()
+
+	var err error
+	var nerr nonFatal
+
+	// Fast-path for common cases: zero or one extensions.
+	// Don't bother sorting the keys.
+	if len(m) <= 1 {
+		for id, e := range m {
+			b = append(b, 1<<3|WireStartGroup)
+			b = append(b, 2<<3|WireVarint)
+			b = appendVarint(b, uint64(id))
+
+			if e.value == nil || e.desc == nil {
+				// Extension is only in its encoded form.
+				msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
+				b = append(b, 3<<3|WireBytes)
+				b = append(b, msgWithLen...)
+				b = append(b, 1<<3|WireEndGroup)
+				continue
+			}
+
+			// We don't skip extensions that have an encoded form set,
+			// because the extension value may have been mutated after
+			// the last time this function was called.
+
+			ei := u.getExtElemInfo(e.desc)
+			v := e.value
+			p := toAddrPointer(&v, ei.isptr)
+			b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
+			if !nerr.Merge(err) {
+				return b, err
+			}
+			b = append(b, 1<<3|WireEndGroup)
+		}
+		return b, nerr.E
+	}
+
+	// Sort the keys to provide a deterministic encoding.
+	keys := make([]int, 0, len(m))
+	for k := range m {
+		keys = append(keys, int(k))
+	}
+	sort.Ints(keys)
+
+	for _, id := range keys {
+		e := m[int32(id)]
+		b = append(b, 1<<3|WireStartGroup)
+		b = append(b, 2<<3|WireVarint)
+		b = appendVarint(b, uint64(id))
+
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint
+			b = append(b, 3<<3|WireBytes)
+			b = append(b, msgWithLen...)
+			b = append(b, 1<<3|WireEndGroup)
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		ei := u.getExtElemInfo(e.desc)
+		v := e.value
+		p := toAddrPointer(&v, ei.isptr)
+		b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
+		b = append(b, 1<<3|WireEndGroup)
+		if !nerr.Merge(err) {
+			return b, err
+		}
+	}
+	return b, nerr.E
+}
+
+// sizeV1Extensions computes the size of encoded data for a V1-API extension field.
+func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int {
+	if m == nil {
+		return 0
+	}
+
+	n := 0
+	for _, e := range m {
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			n += len(e.enc)
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		ei := u.getExtElemInfo(e.desc)
+		v := e.value
+		p := toAddrPointer(&v, ei.isptr)
+		n += ei.sizer(p, ei.tagsize)
+	}
+	return n
+}
+
+// appendV1Extensions marshals a V1-API extension field to the end of byte slice b.
+func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) {
+	if m == nil {
+		return b, nil
+	}
+
+	// Sort the keys to provide a deterministic encoding.
+	keys := make([]int, 0, len(m))
+	for k := range m {
+		keys = append(keys, int(k))
+	}
+	sort.Ints(keys)
+
+	var err error
+	var nerr nonFatal
+	for _, k := range keys {
+		e := m[int32(k)]
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			b = append(b, e.enc...)
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		ei := u.getExtElemInfo(e.desc)
+		v := e.value
+		p := toAddrPointer(&v, ei.isptr)
+		b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
+		if !nerr.Merge(err) {
+			return b, err
+		}
+	}
+	return b, nerr.E
+}
+
+// newMarshaler is the interface representing objects that can marshal themselves.
+//
+// This exists to support protoc-gen-go generated messages.
+// The proto package will stop type-asserting to this interface in the future.
+//
+// DO NOT DEPEND ON THIS.
+type newMarshaler interface {
+	XXX_Size() int
+	XXX_Marshal(b []byte, deterministic bool) ([]byte, error)
+}
+
+// Size returns the encoded size of a protocol buffer message.
+// This is the main entry point.
+func Size(pb Message) int {
+	if m, ok := pb.(newMarshaler); ok {
+		return m.XXX_Size()
+	}
+	if m, ok := pb.(Marshaler); ok {
+		// If the message can marshal itself, let it do it, for compatibility.
+		// NOTE: This is not efficient.
+		b, _ := m.Marshal()
+		return len(b)
+	}
+	// in case somehow we didn't generate the wrapper
+	if pb == nil {
+		return 0
+	}
+	var info InternalMessageInfo
+	return info.Size(pb)
+}
+
+// Marshal takes a protocol buffer message
+// and encodes it into the wire format, returning the data.
+// This is the main entry point.
+func Marshal(pb Message) ([]byte, error) {
+	if m, ok := pb.(newMarshaler); ok {
+		siz := m.XXX_Size()
+		b := make([]byte, 0, siz)
+		return m.XXX_Marshal(b, false)
+	}
+	if m, ok := pb.(Marshaler); ok {
+		// If the message can marshal itself, let it do it, for compatibility.
+		// NOTE: This is not efficient.
+		return m.Marshal()
+	}
+	// in case somehow we didn't generate the wrapper
+	if pb == nil {
+		return nil, ErrNil
+	}
+	var info InternalMessageInfo
+	siz := info.Size(pb)
+	b := make([]byte, 0, siz)
+	return info.Marshal(b, pb, false)
+}
+
+// Marshal takes a protocol buffer message
+// and encodes it into the wire format, writing the result to the
+// Buffer.
+// This is an alternative entry point. It is not necessary to use
+// a Buffer for most applications.
+func (p *Buffer) Marshal(pb Message) error {
+	var err error
+	if p.deterministic {
+		if _, ok := pb.(Marshaler); ok {
+			return fmt.Errorf("proto: deterministic not supported by the Marshal method of %T", pb)
+		}
+	}
+	if m, ok := pb.(newMarshaler); ok {
+		siz := m.XXX_Size()
+		p.grow(siz) // make sure buf has enough capacity
+		p.buf, err = m.XXX_Marshal(p.buf, p.deterministic)
+		return err
+	}
+	if m, ok := pb.(Marshaler); ok {
+		// If the message can marshal itself, let it do it, for compatibility.
+		// NOTE: This is not efficient.
+		var b []byte
+		b, err = m.Marshal()
+		p.buf = append(p.buf, b...)
+		return err
+	}
+	// in case somehow we didn't generate the wrapper
+	if pb == nil {
+		return ErrNil
+	}
+	var info InternalMessageInfo
+	siz := info.Size(pb)
+	p.grow(siz) // make sure buf has enough capacity
+	p.buf, err = info.Marshal(p.buf, pb, p.deterministic)
+	return err
+}
+
+// grow grows the buffer's capacity, if necessary, to guarantee space for
+// another n bytes. After grow(n), at least n bytes can be written to the
+// buffer without another allocation.
+func (p *Buffer) grow(n int) {
+	need := len(p.buf) + n
+	if need <= cap(p.buf) {
+		return
+	}
+	newCap := len(p.buf) * 2
+	if newCap < need {
+		newCap = need
+	}
+	p.buf = append(make([]byte, 0, newCap), p.buf...)
+}

+ 388 - 0
vendor/github.com/gogo/protobuf/proto/table_marshal_gogo.go

@@ -0,0 +1,388 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2018, 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 proto
+
+import (
+	"reflect"
+	"time"
+)
+
+// makeMessageRefMarshaler differs a bit from makeMessageMarshaler
+// It marshal a message T instead of a *T
+func makeMessageRefMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			siz := u.size(ptr)
+			return siz + SizeVarint(uint64(siz)) + tagsize
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			b = appendVarint(b, wiretag)
+			siz := u.cachedsize(ptr)
+			b = appendVarint(b, uint64(siz))
+			return u.marshal(b, ptr, deterministic)
+		}
+}
+
+// makeMessageRefSliceMarshaler differs quite a lot from makeMessageSliceMarshaler
+// It marshals a slice of messages []T instead of []*T
+func makeMessageRefSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				e := elem.Interface()
+				v := toAddrPointer(&e, false)
+				siz := u.size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			var err, errreq error
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				e := elem.Interface()
+				v := toAddrPointer(&e, false)
+				b = appendVarint(b, wiretag)
+				siz := u.size(v)
+				b = appendVarint(b, uint64(siz))
+				b, err = u.marshal(b, v, deterministic)
+
+				if err != nil {
+					if _, ok := err.(*RequiredNotSetError); ok {
+						// Required field in submessage is not set.
+						// We record the error but keep going, to give a complete marshaling.
+						if errreq == nil {
+							errreq = err
+						}
+						continue
+					}
+					if err == ErrNil {
+						err = errRepeatedHasNil
+					}
+					return b, err
+				}
+			}
+
+			return b, errreq
+		}
+}
+
+func makeCustomPtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom)
+			siz := m.Size()
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			m := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(custom)
+			siz := m.Size()
+			buf, err := m.Marshal()
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(siz))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeCustomMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			m := ptr.asPointerTo(u.typ).Interface().(custom)
+			siz := m.Size()
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			m := ptr.asPointerTo(u.typ).Interface().(custom)
+			siz := m.Size()
+			buf, err := m.Marshal()
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(siz))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeTimeMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			t := ptr.asPointerTo(u.typ).Interface().(*time.Time)
+			ts, err := timestampProto(*t)
+			if err != nil {
+				return 0
+			}
+			siz := Size(ts)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			t := ptr.asPointerTo(u.typ).Interface().(*time.Time)
+			ts, err := timestampProto(*t)
+			if err != nil {
+				return nil, err
+			}
+			buf, err := Marshal(ts)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeTimePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time)
+			ts, err := timestampProto(*t)
+			if err != nil {
+				return 0
+			}
+			siz := Size(ts)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Time)
+			ts, err := timestampProto(*t)
+			if err != nil {
+				return nil, err
+			}
+			buf, err := Marshal(ts)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeTimeSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(time.Time)
+				ts, err := timestampProto(t)
+				if err != nil {
+					return 0
+				}
+				siz := Size(ts)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(time.Time)
+				ts, err := timestampProto(t)
+				if err != nil {
+					return nil, err
+				}
+				siz := Size(ts)
+				buf, err := Marshal(ts)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeTimePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*time.Time)
+				ts, err := timestampProto(*t)
+				if err != nil {
+					return 0
+				}
+				siz := Size(ts)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*time.Time)
+				ts, err := timestampProto(*t)
+				if err != nil {
+					return nil, err
+				}
+				siz := Size(ts)
+				buf, err := Marshal(ts)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeDurationMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			d := ptr.asPointerTo(u.typ).Interface().(*time.Duration)
+			dur := durationProto(*d)
+			siz := Size(dur)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			d := ptr.asPointerTo(u.typ).Interface().(*time.Duration)
+			dur := durationProto(*d)
+			buf, err := Marshal(dur)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeDurationPtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration)
+			dur := durationProto(*d)
+			siz := Size(dur)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			d := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*time.Duration)
+			dur := durationProto(*d)
+			buf, err := Marshal(dur)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeDurationSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				d := elem.Interface().(time.Duration)
+				dur := durationProto(d)
+				siz := Size(dur)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				d := elem.Interface().(time.Duration)
+				dur := durationProto(d)
+				siz := Size(dur)
+				buf, err := Marshal(dur)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeDurationPtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				d := elem.Interface().(*time.Duration)
+				dur := durationProto(*d)
+				siz := Size(dur)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				d := elem.Interface().(*time.Duration)
+				dur := durationProto(*d)
+				siz := Size(dur)
+				buf, err := Marshal(dur)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}

+ 657 - 0
vendor/github.com/gogo/protobuf/proto/table_merge.go

@@ -0,0 +1,657 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+import (
+	"fmt"
+	"reflect"
+	"strings"
+	"sync"
+	"sync/atomic"
+)
+
+// Merge merges the src message into dst.
+// This assumes that dst and src of the same type and are non-nil.
+func (a *InternalMessageInfo) Merge(dst, src Message) {
+	mi := atomicLoadMergeInfo(&a.merge)
+	if mi == nil {
+		mi = getMergeInfo(reflect.TypeOf(dst).Elem())
+		atomicStoreMergeInfo(&a.merge, mi)
+	}
+	mi.merge(toPointer(&dst), toPointer(&src))
+}
+
+type mergeInfo struct {
+	typ reflect.Type
+
+	initialized int32 // 0: only typ is valid, 1: everything is valid
+	lock        sync.Mutex
+
+	fields       []mergeFieldInfo
+	unrecognized field // Offset of XXX_unrecognized
+}
+
+type mergeFieldInfo struct {
+	field field // Offset of field, guaranteed to be valid
+
+	// isPointer reports whether the value in the field is a pointer.
+	// This is true for the following situations:
+	//	* Pointer to struct
+	//	* Pointer to basic type (proto2 only)
+	//	* Slice (first value in slice header is a pointer)
+	//	* String (first value in string header is a pointer)
+	isPointer bool
+
+	// basicWidth reports the width of the field assuming that it is directly
+	// embedded in the struct (as is the case for basic types in proto3).
+	// The possible values are:
+	// 	0: invalid
+	//	1: bool
+	//	4: int32, uint32, float32
+	//	8: int64, uint64, float64
+	basicWidth int
+
+	// Where dst and src are pointers to the types being merged.
+	merge func(dst, src pointer)
+}
+
+var (
+	mergeInfoMap  = map[reflect.Type]*mergeInfo{}
+	mergeInfoLock sync.Mutex
+)
+
+func getMergeInfo(t reflect.Type) *mergeInfo {
+	mergeInfoLock.Lock()
+	defer mergeInfoLock.Unlock()
+	mi := mergeInfoMap[t]
+	if mi == nil {
+		mi = &mergeInfo{typ: t}
+		mergeInfoMap[t] = mi
+	}
+	return mi
+}
+
+// merge merges src into dst assuming they are both of type *mi.typ.
+func (mi *mergeInfo) merge(dst, src pointer) {
+	if dst.isNil() {
+		panic("proto: nil destination")
+	}
+	if src.isNil() {
+		return // Nothing to do.
+	}
+
+	if atomic.LoadInt32(&mi.initialized) == 0 {
+		mi.computeMergeInfo()
+	}
+
+	for _, fi := range mi.fields {
+		sfp := src.offset(fi.field)
+
+		// As an optimization, we can avoid the merge function call cost
+		// if we know for sure that the source will have no effect
+		// by checking if it is the zero value.
+		if unsafeAllowed {
+			if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string
+				continue
+			}
+			if fi.basicWidth > 0 {
+				switch {
+				case fi.basicWidth == 1 && !*sfp.toBool():
+					continue
+				case fi.basicWidth == 4 && *sfp.toUint32() == 0:
+					continue
+				case fi.basicWidth == 8 && *sfp.toUint64() == 0:
+					continue
+				}
+			}
+		}
+
+		dfp := dst.offset(fi.field)
+		fi.merge(dfp, sfp)
+	}
+
+	// TODO: Make this faster?
+	out := dst.asPointerTo(mi.typ).Elem()
+	in := src.asPointerTo(mi.typ).Elem()
+	if emIn, err := extendable(in.Addr().Interface()); err == nil {
+		emOut, _ := extendable(out.Addr().Interface())
+		mIn, muIn := emIn.extensionsRead()
+		if mIn != nil {
+			mOut := emOut.extensionsWrite()
+			muIn.Lock()
+			mergeExtension(mOut, mIn)
+			muIn.Unlock()
+		}
+	}
+
+	if mi.unrecognized.IsValid() {
+		if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 {
+			*dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...)
+		}
+	}
+}
+
+func (mi *mergeInfo) computeMergeInfo() {
+	mi.lock.Lock()
+	defer mi.lock.Unlock()
+	if mi.initialized != 0 {
+		return
+	}
+	t := mi.typ
+	n := t.NumField()
+
+	props := GetProperties(t)
+	for i := 0; i < n; i++ {
+		f := t.Field(i)
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+
+		mfi := mergeFieldInfo{field: toField(&f)}
+		tf := f.Type
+
+		// As an optimization, we can avoid the merge function call cost
+		// if we know for sure that the source will have no effect
+		// by checking if it is the zero value.
+		if unsafeAllowed {
+			switch tf.Kind() {
+			case reflect.Ptr, reflect.Slice, reflect.String:
+				// As a special case, we assume slices and strings are pointers
+				// since we know that the first field in the SliceSlice or
+				// StringHeader is a data pointer.
+				mfi.isPointer = true
+			case reflect.Bool:
+				mfi.basicWidth = 1
+			case reflect.Int32, reflect.Uint32, reflect.Float32:
+				mfi.basicWidth = 4
+			case reflect.Int64, reflect.Uint64, reflect.Float64:
+				mfi.basicWidth = 8
+			}
+		}
+
+		// Unwrap tf to get at its most basic type.
+		var isPointer, isSlice bool
+		if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 {
+			isSlice = true
+			tf = tf.Elem()
+		}
+		if tf.Kind() == reflect.Ptr {
+			isPointer = true
+			tf = tf.Elem()
+		}
+		if isPointer && isSlice && tf.Kind() != reflect.Struct {
+			panic("both pointer and slice for basic type in " + tf.Name())
+		}
+
+		switch tf.Kind() {
+		case reflect.Int32:
+			switch {
+			case isSlice: // E.g., []int32
+				mfi.merge = func(dst, src pointer) {
+					// NOTE: toInt32Slice is not defined (see pointer_reflect.go).
+					/*
+						sfsp := src.toInt32Slice()
+						if *sfsp != nil {
+							dfsp := dst.toInt32Slice()
+							*dfsp = append(*dfsp, *sfsp...)
+							if *dfsp == nil {
+								*dfsp = []int64{}
+							}
+						}
+					*/
+					sfs := src.getInt32Slice()
+					if sfs != nil {
+						dfs := dst.getInt32Slice()
+						dfs = append(dfs, sfs...)
+						if dfs == nil {
+							dfs = []int32{}
+						}
+						dst.setInt32Slice(dfs)
+					}
+				}
+			case isPointer: // E.g., *int32
+				mfi.merge = func(dst, src pointer) {
+					// NOTE: toInt32Ptr is not defined (see pointer_reflect.go).
+					/*
+						sfpp := src.toInt32Ptr()
+						if *sfpp != nil {
+							dfpp := dst.toInt32Ptr()
+							if *dfpp == nil {
+								*dfpp = Int32(**sfpp)
+							} else {
+								**dfpp = **sfpp
+							}
+						}
+					*/
+					sfp := src.getInt32Ptr()
+					if sfp != nil {
+						dfp := dst.getInt32Ptr()
+						if dfp == nil {
+							dst.setInt32Ptr(*sfp)
+						} else {
+							*dfp = *sfp
+						}
+					}
+				}
+			default: // E.g., int32
+				mfi.merge = func(dst, src pointer) {
+					if v := *src.toInt32(); v != 0 {
+						*dst.toInt32() = v
+					}
+				}
+			}
+		case reflect.Int64:
+			switch {
+			case isSlice: // E.g., []int64
+				mfi.merge = func(dst, src pointer) {
+					sfsp := src.toInt64Slice()
+					if *sfsp != nil {
+						dfsp := dst.toInt64Slice()
+						*dfsp = append(*dfsp, *sfsp...)
+						if *dfsp == nil {
+							*dfsp = []int64{}
+						}
+					}
+				}
+			case isPointer: // E.g., *int64
+				mfi.merge = func(dst, src pointer) {
+					sfpp := src.toInt64Ptr()
+					if *sfpp != nil {
+						dfpp := dst.toInt64Ptr()
+						if *dfpp == nil {
+							*dfpp = Int64(**sfpp)
+						} else {
+							**dfpp = **sfpp
+						}
+					}
+				}
+			default: // E.g., int64
+				mfi.merge = func(dst, src pointer) {
+					if v := *src.toInt64(); v != 0 {
+						*dst.toInt64() = v
+					}
+				}
+			}
+		case reflect.Uint32:
+			switch {
+			case isSlice: // E.g., []uint32
+				mfi.merge = func(dst, src pointer) {
+					sfsp := src.toUint32Slice()
+					if *sfsp != nil {
+						dfsp := dst.toUint32Slice()
+						*dfsp = append(*dfsp, *sfsp...)
+						if *dfsp == nil {
+							*dfsp = []uint32{}
+						}
+					}
+				}
+			case isPointer: // E.g., *uint32
+				mfi.merge = func(dst, src pointer) {
+					sfpp := src.toUint32Ptr()
+					if *sfpp != nil {
+						dfpp := dst.toUint32Ptr()
+						if *dfpp == nil {
+							*dfpp = Uint32(**sfpp)
+						} else {
+							**dfpp = **sfpp
+						}
+					}
+				}
+			default: // E.g., uint32
+				mfi.merge = func(dst, src pointer) {
+					if v := *src.toUint32(); v != 0 {
+						*dst.toUint32() = v
+					}
+				}
+			}
+		case reflect.Uint64:
+			switch {
+			case isSlice: // E.g., []uint64
+				mfi.merge = func(dst, src pointer) {
+					sfsp := src.toUint64Slice()
+					if *sfsp != nil {
+						dfsp := dst.toUint64Slice()
+						*dfsp = append(*dfsp, *sfsp...)
+						if *dfsp == nil {
+							*dfsp = []uint64{}
+						}
+					}
+				}
+			case isPointer: // E.g., *uint64
+				mfi.merge = func(dst, src pointer) {
+					sfpp := src.toUint64Ptr()
+					if *sfpp != nil {
+						dfpp := dst.toUint64Ptr()
+						if *dfpp == nil {
+							*dfpp = Uint64(**sfpp)
+						} else {
+							**dfpp = **sfpp
+						}
+					}
+				}
+			default: // E.g., uint64
+				mfi.merge = func(dst, src pointer) {
+					if v := *src.toUint64(); v != 0 {
+						*dst.toUint64() = v
+					}
+				}
+			}
+		case reflect.Float32:
+			switch {
+			case isSlice: // E.g., []float32
+				mfi.merge = func(dst, src pointer) {
+					sfsp := src.toFloat32Slice()
+					if *sfsp != nil {
+						dfsp := dst.toFloat32Slice()
+						*dfsp = append(*dfsp, *sfsp...)
+						if *dfsp == nil {
+							*dfsp = []float32{}
+						}
+					}
+				}
+			case isPointer: // E.g., *float32
+				mfi.merge = func(dst, src pointer) {
+					sfpp := src.toFloat32Ptr()
+					if *sfpp != nil {
+						dfpp := dst.toFloat32Ptr()
+						if *dfpp == nil {
+							*dfpp = Float32(**sfpp)
+						} else {
+							**dfpp = **sfpp
+						}
+					}
+				}
+			default: // E.g., float32
+				mfi.merge = func(dst, src pointer) {
+					if v := *src.toFloat32(); v != 0 {
+						*dst.toFloat32() = v
+					}
+				}
+			}
+		case reflect.Float64:
+			switch {
+			case isSlice: // E.g., []float64
+				mfi.merge = func(dst, src pointer) {
+					sfsp := src.toFloat64Slice()
+					if *sfsp != nil {
+						dfsp := dst.toFloat64Slice()
+						*dfsp = append(*dfsp, *sfsp...)
+						if *dfsp == nil {
+							*dfsp = []float64{}
+						}
+					}
+				}
+			case isPointer: // E.g., *float64
+				mfi.merge = func(dst, src pointer) {
+					sfpp := src.toFloat64Ptr()
+					if *sfpp != nil {
+						dfpp := dst.toFloat64Ptr()
+						if *dfpp == nil {
+							*dfpp = Float64(**sfpp)
+						} else {
+							**dfpp = **sfpp
+						}
+					}
+				}
+			default: // E.g., float64
+				mfi.merge = func(dst, src pointer) {
+					if v := *src.toFloat64(); v != 0 {
+						*dst.toFloat64() = v
+					}
+				}
+			}
+		case reflect.Bool:
+			switch {
+			case isSlice: // E.g., []bool
+				mfi.merge = func(dst, src pointer) {
+					sfsp := src.toBoolSlice()
+					if *sfsp != nil {
+						dfsp := dst.toBoolSlice()
+						*dfsp = append(*dfsp, *sfsp...)
+						if *dfsp == nil {
+							*dfsp = []bool{}
+						}
+					}
+				}
+			case isPointer: // E.g., *bool
+				mfi.merge = func(dst, src pointer) {
+					sfpp := src.toBoolPtr()
+					if *sfpp != nil {
+						dfpp := dst.toBoolPtr()
+						if *dfpp == nil {
+							*dfpp = Bool(**sfpp)
+						} else {
+							**dfpp = **sfpp
+						}
+					}
+				}
+			default: // E.g., bool
+				mfi.merge = func(dst, src pointer) {
+					if v := *src.toBool(); v {
+						*dst.toBool() = v
+					}
+				}
+			}
+		case reflect.String:
+			switch {
+			case isSlice: // E.g., []string
+				mfi.merge = func(dst, src pointer) {
+					sfsp := src.toStringSlice()
+					if *sfsp != nil {
+						dfsp := dst.toStringSlice()
+						*dfsp = append(*dfsp, *sfsp...)
+						if *dfsp == nil {
+							*dfsp = []string{}
+						}
+					}
+				}
+			case isPointer: // E.g., *string
+				mfi.merge = func(dst, src pointer) {
+					sfpp := src.toStringPtr()
+					if *sfpp != nil {
+						dfpp := dst.toStringPtr()
+						if *dfpp == nil {
+							*dfpp = String(**sfpp)
+						} else {
+							**dfpp = **sfpp
+						}
+					}
+				}
+			default: // E.g., string
+				mfi.merge = func(dst, src pointer) {
+					if v := *src.toString(); v != "" {
+						*dst.toString() = v
+					}
+				}
+			}
+		case reflect.Slice:
+			isProto3 := props.Prop[i].proto3
+			switch {
+			case isPointer:
+				panic("bad pointer in byte slice case in " + tf.Name())
+			case tf.Elem().Kind() != reflect.Uint8:
+				panic("bad element kind in byte slice case in " + tf.Name())
+			case isSlice: // E.g., [][]byte
+				mfi.merge = func(dst, src pointer) {
+					sbsp := src.toBytesSlice()
+					if *sbsp != nil {
+						dbsp := dst.toBytesSlice()
+						for _, sb := range *sbsp {
+							if sb == nil {
+								*dbsp = append(*dbsp, nil)
+							} else {
+								*dbsp = append(*dbsp, append([]byte{}, sb...))
+							}
+						}
+						if *dbsp == nil {
+							*dbsp = [][]byte{}
+						}
+					}
+				}
+			default: // E.g., []byte
+				mfi.merge = func(dst, src pointer) {
+					sbp := src.toBytes()
+					if *sbp != nil {
+						dbp := dst.toBytes()
+						if !isProto3 || len(*sbp) > 0 {
+							*dbp = append([]byte{}, *sbp...)
+						}
+					}
+				}
+			}
+		case reflect.Struct:
+			switch {
+			case !isPointer:
+				mergeInfo := getMergeInfo(tf)
+				mfi.merge = func(dst, src pointer) {
+					mergeInfo.merge(dst, src)
+				}
+			case isSlice: // E.g., []*pb.T
+				mergeInfo := getMergeInfo(tf)
+				mfi.merge = func(dst, src pointer) {
+					sps := src.getPointerSlice()
+					if sps != nil {
+						dps := dst.getPointerSlice()
+						for _, sp := range sps {
+							var dp pointer
+							if !sp.isNil() {
+								dp = valToPointer(reflect.New(tf))
+								mergeInfo.merge(dp, sp)
+							}
+							dps = append(dps, dp)
+						}
+						if dps == nil {
+							dps = []pointer{}
+						}
+						dst.setPointerSlice(dps)
+					}
+				}
+			default: // E.g., *pb.T
+				mergeInfo := getMergeInfo(tf)
+				mfi.merge = func(dst, src pointer) {
+					sp := src.getPointer()
+					if !sp.isNil() {
+						dp := dst.getPointer()
+						if dp.isNil() {
+							dp = valToPointer(reflect.New(tf))
+							dst.setPointer(dp)
+						}
+						mergeInfo.merge(dp, sp)
+					}
+				}
+			}
+		case reflect.Map:
+			switch {
+			case isPointer || isSlice:
+				panic("bad pointer or slice in map case in " + tf.Name())
+			default: // E.g., map[K]V
+				mfi.merge = func(dst, src pointer) {
+					sm := src.asPointerTo(tf).Elem()
+					if sm.Len() == 0 {
+						return
+					}
+					dm := dst.asPointerTo(tf).Elem()
+					if dm.IsNil() {
+						dm.Set(reflect.MakeMap(tf))
+					}
+
+					switch tf.Elem().Kind() {
+					case reflect.Ptr: // Proto struct (e.g., *T)
+						for _, key := range sm.MapKeys() {
+							val := sm.MapIndex(key)
+							val = reflect.ValueOf(Clone(val.Interface().(Message)))
+							dm.SetMapIndex(key, val)
+						}
+					case reflect.Slice: // E.g. Bytes type (e.g., []byte)
+						for _, key := range sm.MapKeys() {
+							val := sm.MapIndex(key)
+							val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
+							dm.SetMapIndex(key, val)
+						}
+					default: // Basic type (e.g., string)
+						for _, key := range sm.MapKeys() {
+							val := sm.MapIndex(key)
+							dm.SetMapIndex(key, val)
+						}
+					}
+				}
+			}
+		case reflect.Interface:
+			// Must be oneof field.
+			switch {
+			case isPointer || isSlice:
+				panic("bad pointer or slice in interface case in " + tf.Name())
+			default: // E.g., interface{}
+				// TODO: Make this faster?
+				mfi.merge = func(dst, src pointer) {
+					su := src.asPointerTo(tf).Elem()
+					if !su.IsNil() {
+						du := dst.asPointerTo(tf).Elem()
+						typ := su.Elem().Type()
+						if du.IsNil() || du.Elem().Type() != typ {
+							du.Set(reflect.New(typ.Elem())) // Initialize interface if empty
+						}
+						sv := su.Elem().Elem().Field(0)
+						if sv.Kind() == reflect.Ptr && sv.IsNil() {
+							return
+						}
+						dv := du.Elem().Elem().Field(0)
+						if dv.Kind() == reflect.Ptr && dv.IsNil() {
+							dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty
+						}
+						switch sv.Type().Kind() {
+						case reflect.Ptr: // Proto struct (e.g., *T)
+							Merge(dv.Interface().(Message), sv.Interface().(Message))
+						case reflect.Slice: // E.g. Bytes type (e.g., []byte)
+							dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...)))
+						default: // Basic type (e.g., string)
+							dv.Set(sv)
+						}
+					}
+				}
+			}
+		default:
+			panic(fmt.Sprintf("merger not found for type:%s", tf))
+		}
+		mi.fields = append(mi.fields, mfi)
+	}
+
+	mi.unrecognized = invalidField
+	if f, ok := t.FieldByName("XXX_unrecognized"); ok {
+		if f.Type != reflect.TypeOf([]byte{}) {
+			panic("expected XXX_unrecognized to be of type []byte")
+		}
+		mi.unrecognized = toField(&f)
+	}
+
+	atomic.StoreInt32(&mi.initialized, 1)
+}

+ 2245 - 0
vendor/github.com/gogo/protobuf/proto/table_unmarshal.go

@@ -0,0 +1,2245 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2016 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"math"
+	"reflect"
+	"strconv"
+	"strings"
+	"sync"
+	"sync/atomic"
+	"unicode/utf8"
+)
+
+// Unmarshal is the entry point from the generated .pb.go files.
+// This function is not intended to be used by non-generated code.
+// This function is not subject to any compatibility guarantee.
+// msg contains a pointer to a protocol buffer struct.
+// b is the data to be unmarshaled into the protocol buffer.
+// a is a pointer to a place to store cached unmarshal information.
+func (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error {
+	// Load the unmarshal information for this message type.
+	// The atomic load ensures memory consistency.
+	u := atomicLoadUnmarshalInfo(&a.unmarshal)
+	if u == nil {
+		// Slow path: find unmarshal info for msg, update a with it.
+		u = getUnmarshalInfo(reflect.TypeOf(msg).Elem())
+		atomicStoreUnmarshalInfo(&a.unmarshal, u)
+	}
+	// Then do the unmarshaling.
+	err := u.unmarshal(toPointer(&msg), b)
+	return err
+}
+
+type unmarshalInfo struct {
+	typ reflect.Type // type of the protobuf struct
+
+	// 0 = only typ field is initialized
+	// 1 = completely initialized
+	initialized     int32
+	lock            sync.Mutex                    // prevents double initialization
+	dense           []unmarshalFieldInfo          // fields indexed by tag #
+	sparse          map[uint64]unmarshalFieldInfo // fields indexed by tag #
+	reqFields       []string                      // names of required fields
+	reqMask         uint64                        // 1<<len(reqFields)-1
+	unrecognized    field                         // offset of []byte to put unrecognized data (or invalidField if we should throw it away)
+	extensions      field                         // offset of extensions field (of type proto.XXX_InternalExtensions), or invalidField if it does not exist
+	oldExtensions   field                         // offset of old-form extensions field (of type map[int]Extension)
+	extensionRanges []ExtensionRange              // if non-nil, implies extensions field is valid
+	isMessageSet    bool                          // if true, implies extensions field is valid
+
+	bytesExtensions field // offset of XXX_extensions with type []byte
+}
+
+// An unmarshaler takes a stream of bytes and a pointer to a field of a message.
+// It decodes the field, stores it at f, and returns the unused bytes.
+// w is the wire encoding.
+// b is the data after the tag and wire encoding have been read.
+type unmarshaler func(b []byte, f pointer, w int) ([]byte, error)
+
+type unmarshalFieldInfo struct {
+	// location of the field in the proto message structure.
+	field field
+
+	// function to unmarshal the data for the field.
+	unmarshal unmarshaler
+
+	// if a required field, contains a single set bit at this field's index in the required field list.
+	reqMask uint64
+
+	name string // name of the field, for error reporting
+}
+
+var (
+	unmarshalInfoMap  = map[reflect.Type]*unmarshalInfo{}
+	unmarshalInfoLock sync.Mutex
+)
+
+// getUnmarshalInfo returns the data structure which can be
+// subsequently used to unmarshal a message of the given type.
+// t is the type of the message (note: not pointer to message).
+func getUnmarshalInfo(t reflect.Type) *unmarshalInfo {
+	// It would be correct to return a new unmarshalInfo
+	// unconditionally. We would end up allocating one
+	// per occurrence of that type as a message or submessage.
+	// We use a cache here just to reduce memory usage.
+	unmarshalInfoLock.Lock()
+	defer unmarshalInfoLock.Unlock()
+	u := unmarshalInfoMap[t]
+	if u == nil {
+		u = &unmarshalInfo{typ: t}
+		// Note: we just set the type here. The rest of the fields
+		// will be initialized on first use.
+		unmarshalInfoMap[t] = u
+	}
+	return u
+}
+
+// unmarshal does the main work of unmarshaling a message.
+// u provides type information used to unmarshal the message.
+// m is a pointer to a protocol buffer message.
+// b is a byte stream to unmarshal into m.
+// This is top routine used when recursively unmarshaling submessages.
+func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
+	if atomic.LoadInt32(&u.initialized) == 0 {
+		u.computeUnmarshalInfo()
+	}
+	if u.isMessageSet {
+		return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
+	}
+	var reqMask uint64 // bitmask of required fields we've seen.
+	var errLater error
+	for len(b) > 0 {
+		// Read tag and wire type.
+		// Special case 1 and 2 byte varints.
+		var x uint64
+		if b[0] < 128 {
+			x = uint64(b[0])
+			b = b[1:]
+		} else if len(b) >= 2 && b[1] < 128 {
+			x = uint64(b[0]&0x7f) + uint64(b[1])<<7
+			b = b[2:]
+		} else {
+			var n int
+			x, n = decodeVarint(b)
+			if n == 0 {
+				return io.ErrUnexpectedEOF
+			}
+			b = b[n:]
+		}
+		tag := x >> 3
+		wire := int(x) & 7
+
+		// Dispatch on the tag to one of the unmarshal* functions below.
+		var f unmarshalFieldInfo
+		if tag < uint64(len(u.dense)) {
+			f = u.dense[tag]
+		} else {
+			f = u.sparse[tag]
+		}
+		if fn := f.unmarshal; fn != nil {
+			var err error
+			b, err = fn(b, m.offset(f.field), wire)
+			if err == nil {
+				reqMask |= f.reqMask
+				continue
+			}
+			if r, ok := err.(*RequiredNotSetError); ok {
+				// Remember this error, but keep parsing. We need to produce
+				// a full parse even if a required field is missing.
+				if errLater == nil {
+					errLater = r
+				}
+				reqMask |= f.reqMask
+				continue
+			}
+			if err != errInternalBadWireType {
+				if err == errInvalidUTF8 {
+					if errLater == nil {
+						fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
+						errLater = &invalidUTF8Error{fullName}
+					}
+					continue
+				}
+				return err
+			}
+			// Fragments with bad wire type are treated as unknown fields.
+		}
+
+		// Unknown tag.
+		if !u.unrecognized.IsValid() {
+			// Don't keep unrecognized data; just skip it.
+			var err error
+			b, err = skipField(b, wire)
+			if err != nil {
+				return err
+			}
+			continue
+		}
+		// Keep unrecognized data around.
+		// maybe in extensions, maybe in the unrecognized field.
+		z := m.offset(u.unrecognized).toBytes()
+		var emap map[int32]Extension
+		var e Extension
+		for _, r := range u.extensionRanges {
+			if uint64(r.Start) <= tag && tag <= uint64(r.End) {
+				if u.extensions.IsValid() {
+					mp := m.offset(u.extensions).toExtensions()
+					emap = mp.extensionsWrite()
+					e = emap[int32(tag)]
+					z = &e.enc
+					break
+				}
+				if u.oldExtensions.IsValid() {
+					p := m.offset(u.oldExtensions).toOldExtensions()
+					emap = *p
+					if emap == nil {
+						emap = map[int32]Extension{}
+						*p = emap
+					}
+					e = emap[int32(tag)]
+					z = &e.enc
+					break
+				}
+				if u.bytesExtensions.IsValid() {
+					z = m.offset(u.bytesExtensions).toBytes()
+					break
+				}
+				panic("no extensions field available")
+			}
+		}
+		// Use wire type to skip data.
+		var err error
+		b0 := b
+		b, err = skipField(b, wire)
+		if err != nil {
+			return err
+		}
+		*z = encodeVarint(*z, tag<<3|uint64(wire))
+		*z = append(*z, b0[:len(b0)-len(b)]...)
+
+		if emap != nil {
+			emap[int32(tag)] = e
+		}
+	}
+	if reqMask != u.reqMask && errLater == nil {
+		// A required field of this message is missing.
+		for _, n := range u.reqFields {
+			if reqMask&1 == 0 {
+				errLater = &RequiredNotSetError{n}
+			}
+			reqMask >>= 1
+		}
+	}
+	return errLater
+}
+
+// computeUnmarshalInfo fills in u with information for use
+// in unmarshaling protocol buffers of type u.typ.
+func (u *unmarshalInfo) computeUnmarshalInfo() {
+	u.lock.Lock()
+	defer u.lock.Unlock()
+	if u.initialized != 0 {
+		return
+	}
+	t := u.typ
+	n := t.NumField()
+
+	// Set up the "not found" value for the unrecognized byte buffer.
+	// This is the default for proto3.
+	u.unrecognized = invalidField
+	u.extensions = invalidField
+	u.oldExtensions = invalidField
+	u.bytesExtensions = invalidField
+
+	// List of the generated type and offset for each oneof field.
+	type oneofField struct {
+		ityp  reflect.Type // interface type of oneof field
+		field field        // offset in containing message
+	}
+	var oneofFields []oneofField
+
+	for i := 0; i < n; i++ {
+		f := t.Field(i)
+		if f.Name == "XXX_unrecognized" {
+			// The byte slice used to hold unrecognized input is special.
+			if f.Type != reflect.TypeOf(([]byte)(nil)) {
+				panic("bad type for XXX_unrecognized field: " + f.Type.Name())
+			}
+			u.unrecognized = toField(&f)
+			continue
+		}
+		if f.Name == "XXX_InternalExtensions" {
+			// Ditto here.
+			if f.Type != reflect.TypeOf(XXX_InternalExtensions{}) {
+				panic("bad type for XXX_InternalExtensions field: " + f.Type.Name())
+			}
+			u.extensions = toField(&f)
+			if f.Tag.Get("protobuf_messageset") == "1" {
+				u.isMessageSet = true
+			}
+			continue
+		}
+		if f.Name == "XXX_extensions" {
+			// An older form of the extensions field.
+			if f.Type == reflect.TypeOf((map[int32]Extension)(nil)) {
+				u.oldExtensions = toField(&f)
+				continue
+			} else if f.Type == reflect.TypeOf(([]byte)(nil)) {
+				u.bytesExtensions = toField(&f)
+				continue
+			}
+			panic("bad type for XXX_extensions field: " + f.Type.Name())
+		}
+		if f.Name == "XXX_NoUnkeyedLiteral" || f.Name == "XXX_sizecache" {
+			continue
+		}
+
+		oneof := f.Tag.Get("protobuf_oneof")
+		if oneof != "" {
+			oneofFields = append(oneofFields, oneofField{f.Type, toField(&f)})
+			// The rest of oneof processing happens below.
+			continue
+		}
+
+		tags := f.Tag.Get("protobuf")
+		tagArray := strings.Split(tags, ",")
+		if len(tagArray) < 2 {
+			panic("protobuf tag not enough fields in " + t.Name() + "." + f.Name + ": " + tags)
+		}
+		tag, err := strconv.Atoi(tagArray[1])
+		if err != nil {
+			panic("protobuf tag field not an integer: " + tagArray[1])
+		}
+
+		name := ""
+		for _, tag := range tagArray[3:] {
+			if strings.HasPrefix(tag, "name=") {
+				name = tag[5:]
+			}
+		}
+
+		// Extract unmarshaling function from the field (its type and tags).
+		unmarshal := fieldUnmarshaler(&f)
+
+		// Required field?
+		var reqMask uint64
+		if tagArray[2] == "req" {
+			bit := len(u.reqFields)
+			u.reqFields = append(u.reqFields, name)
+			reqMask = uint64(1) << uint(bit)
+			// TODO: if we have more than 64 required fields, we end up
+			// not verifying that all required fields are present.
+			// Fix this, perhaps using a count of required fields?
+		}
+
+		// Store the info in the correct slot in the message.
+		u.setTag(tag, toField(&f), unmarshal, reqMask, name)
+	}
+
+	// Find any types associated with oneof fields.
+	// TODO: XXX_OneofFuncs returns more info than we need.  Get rid of some of it?
+	fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("XXX_OneofFuncs")
+	// gogo: len(oneofFields) > 0 is needed for embedded oneof messages, without a marshaler and unmarshaler
+	if fn.IsValid() && len(oneofFields) > 0 {
+		res := fn.Call(nil)[3] // last return value from XXX_OneofFuncs: []interface{}
+		for i := res.Len() - 1; i >= 0; i-- {
+			v := res.Index(i)                             // interface{}
+			tptr := reflect.ValueOf(v.Interface()).Type() // *Msg_X
+			typ := tptr.Elem()                            // Msg_X
+
+			f := typ.Field(0) // oneof implementers have one field
+			baseUnmarshal := fieldUnmarshaler(&f)
+			tags := strings.Split(f.Tag.Get("protobuf"), ",")
+			fieldNum, err := strconv.Atoi(tags[1])
+			if err != nil {
+				panic("protobuf tag field not an integer: " + tags[1])
+			}
+			var name string
+			for _, tag := range tags {
+				if strings.HasPrefix(tag, "name=") {
+					name = strings.TrimPrefix(tag, "name=")
+					break
+				}
+			}
+
+			// Find the oneof field that this struct implements.
+			// Might take O(n^2) to process all of the oneofs, but who cares.
+			for _, of := range oneofFields {
+				if tptr.Implements(of.ityp) {
+					// We have found the corresponding interface for this struct.
+					// That lets us know where this struct should be stored
+					// when we encounter it during unmarshaling.
+					unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal)
+					u.setTag(fieldNum, of.field, unmarshal, 0, name)
+				}
+			}
+		}
+	}
+
+	// Get extension ranges, if any.
+	fn = reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray")
+	if fn.IsValid() {
+		if !u.extensions.IsValid() && !u.oldExtensions.IsValid() && !u.bytesExtensions.IsValid() {
+			panic("a message with extensions, but no extensions field in " + t.Name())
+		}
+		u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange)
+	}
+
+	// Explicitly disallow tag 0. This will ensure we flag an error
+	// when decoding a buffer of all zeros. Without this code, we
+	// would decode and skip an all-zero buffer of even length.
+	// [0 0] is [tag=0/wiretype=varint varint-encoded-0].
+	u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) {
+		return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w)
+	}, 0, "")
+
+	// Set mask for required field check.
+	u.reqMask = uint64(1)<<uint(len(u.reqFields)) - 1
+
+	atomic.StoreInt32(&u.initialized, 1)
+}
+
+// setTag stores the unmarshal information for the given tag.
+// tag = tag # for field
+// field/unmarshal = unmarshal info for that field.
+// reqMask = if required, bitmask for field position in required field list. 0 otherwise.
+// name = short name of the field.
+func (u *unmarshalInfo) setTag(tag int, field field, unmarshal unmarshaler, reqMask uint64, name string) {
+	i := unmarshalFieldInfo{field: field, unmarshal: unmarshal, reqMask: reqMask, name: name}
+	n := u.typ.NumField()
+	if tag >= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here?
+		for len(u.dense) <= tag {
+			u.dense = append(u.dense, unmarshalFieldInfo{})
+		}
+		u.dense[tag] = i
+		return
+	}
+	if u.sparse == nil {
+		u.sparse = map[uint64]unmarshalFieldInfo{}
+	}
+	u.sparse[uint64(tag)] = i
+}
+
+// fieldUnmarshaler returns an unmarshaler for the given field.
+func fieldUnmarshaler(f *reflect.StructField) unmarshaler {
+	if f.Type.Kind() == reflect.Map {
+		return makeUnmarshalMap(f)
+	}
+	return typeUnmarshaler(f.Type, f.Tag.Get("protobuf"))
+}
+
+// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair.
+func typeUnmarshaler(t reflect.Type, tags string) unmarshaler {
+	tagArray := strings.Split(tags, ",")
+	encoding := tagArray[0]
+	name := "unknown"
+	ctype := false
+	isTime := false
+	isDuration := false
+	isWktPointer := false
+	proto3 := false
+	validateUTF8 := true
+	for _, tag := range tagArray[3:] {
+		if strings.HasPrefix(tag, "name=") {
+			name = tag[5:]
+		}
+		if tag == "proto3" {
+			proto3 = true
+		}
+		if strings.HasPrefix(tag, "customtype=") {
+			ctype = true
+		}
+		if tag == "stdtime" {
+			isTime = true
+		}
+		if tag == "stdduration" {
+			isDuration = true
+		}
+		if tag == "wktptr" {
+			isWktPointer = true
+		}
+	}
+	validateUTF8 = validateUTF8 && proto3
+
+	// Figure out packaging (pointer, slice, or both)
+	slice := false
+	pointer := false
+	if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 {
+		slice = true
+		t = t.Elem()
+	}
+	if t.Kind() == reflect.Ptr {
+		pointer = true
+		t = t.Elem()
+	}
+
+	if ctype {
+		if reflect.PtrTo(t).Implements(customType) {
+			if slice {
+				return makeUnmarshalCustomSlice(getUnmarshalInfo(t), name)
+			}
+			if pointer {
+				return makeUnmarshalCustomPtr(getUnmarshalInfo(t), name)
+			}
+			return makeUnmarshalCustom(getUnmarshalInfo(t), name)
+		} else {
+			panic(fmt.Sprintf("custom type: type: %v, does not implement the proto.custom interface", t))
+		}
+	}
+
+	if isTime {
+		if pointer {
+			if slice {
+				return makeUnmarshalTimePtrSlice(getUnmarshalInfo(t), name)
+			}
+			return makeUnmarshalTimePtr(getUnmarshalInfo(t), name)
+		}
+		if slice {
+			return makeUnmarshalTimeSlice(getUnmarshalInfo(t), name)
+		}
+		return makeUnmarshalTime(getUnmarshalInfo(t), name)
+	}
+
+	if isDuration {
+		if pointer {
+			if slice {
+				return makeUnmarshalDurationPtrSlice(getUnmarshalInfo(t), name)
+			}
+			return makeUnmarshalDurationPtr(getUnmarshalInfo(t), name)
+		}
+		if slice {
+			return makeUnmarshalDurationSlice(getUnmarshalInfo(t), name)
+		}
+		return makeUnmarshalDuration(getUnmarshalInfo(t), name)
+	}
+
+	if isWktPointer {
+		switch t.Kind() {
+		case reflect.Float64:
+			if pointer {
+				if slice {
+					return makeStdDoubleValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)
+				}
+				return makeStdDoubleValuePtrUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			if slice {
+				return makeStdDoubleValueSliceUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			return makeStdDoubleValueUnmarshaler(getUnmarshalInfo(t), name)
+		case reflect.Float32:
+			if pointer {
+				if slice {
+					return makeStdFloatValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)
+				}
+				return makeStdFloatValuePtrUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			if slice {
+				return makeStdFloatValueSliceUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			return makeStdFloatValueUnmarshaler(getUnmarshalInfo(t), name)
+		case reflect.Int64:
+			if pointer {
+				if slice {
+					return makeStdInt64ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)
+				}
+				return makeStdInt64ValuePtrUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			if slice {
+				return makeStdInt64ValueSliceUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			return makeStdInt64ValueUnmarshaler(getUnmarshalInfo(t), name)
+		case reflect.Uint64:
+			if pointer {
+				if slice {
+					return makeStdUInt64ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)
+				}
+				return makeStdUInt64ValuePtrUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			if slice {
+				return makeStdUInt64ValueSliceUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			return makeStdUInt64ValueUnmarshaler(getUnmarshalInfo(t), name)
+		case reflect.Int32:
+			if pointer {
+				if slice {
+					return makeStdInt32ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)
+				}
+				return makeStdInt32ValuePtrUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			if slice {
+				return makeStdInt32ValueSliceUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			return makeStdInt32ValueUnmarshaler(getUnmarshalInfo(t), name)
+		case reflect.Uint32:
+			if pointer {
+				if slice {
+					return makeStdUInt32ValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)
+				}
+				return makeStdUInt32ValuePtrUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			if slice {
+				return makeStdUInt32ValueSliceUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			return makeStdUInt32ValueUnmarshaler(getUnmarshalInfo(t), name)
+		case reflect.Bool:
+			if pointer {
+				if slice {
+					return makeStdBoolValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)
+				}
+				return makeStdBoolValuePtrUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			if slice {
+				return makeStdBoolValueSliceUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			return makeStdBoolValueUnmarshaler(getUnmarshalInfo(t), name)
+		case reflect.String:
+			if pointer {
+				if slice {
+					return makeStdStringValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)
+				}
+				return makeStdStringValuePtrUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			if slice {
+				return makeStdStringValueSliceUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			return makeStdStringValueUnmarshaler(getUnmarshalInfo(t), name)
+		case uint8SliceType:
+			if pointer {
+				if slice {
+					return makeStdBytesValuePtrSliceUnmarshaler(getUnmarshalInfo(t), name)
+				}
+				return makeStdBytesValuePtrUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			if slice {
+				return makeStdBytesValueSliceUnmarshaler(getUnmarshalInfo(t), name)
+			}
+			return makeStdBytesValueUnmarshaler(getUnmarshalInfo(t), name)
+		default:
+			panic(fmt.Sprintf("unknown wktpointer type %#v", t))
+		}
+	}
+
+	// We'll never have both pointer and slice for basic types.
+	if pointer && slice && t.Kind() != reflect.Struct {
+		panic("both pointer and slice for basic type in " + t.Name())
+	}
+
+	switch t.Kind() {
+	case reflect.Bool:
+		if pointer {
+			return unmarshalBoolPtr
+		}
+		if slice {
+			return unmarshalBoolSlice
+		}
+		return unmarshalBoolValue
+	case reflect.Int32:
+		switch encoding {
+		case "fixed32":
+			if pointer {
+				return unmarshalFixedS32Ptr
+			}
+			if slice {
+				return unmarshalFixedS32Slice
+			}
+			return unmarshalFixedS32Value
+		case "varint":
+			// this could be int32 or enum
+			if pointer {
+				return unmarshalInt32Ptr
+			}
+			if slice {
+				return unmarshalInt32Slice
+			}
+			return unmarshalInt32Value
+		case "zigzag32":
+			if pointer {
+				return unmarshalSint32Ptr
+			}
+			if slice {
+				return unmarshalSint32Slice
+			}
+			return unmarshalSint32Value
+		}
+	case reflect.Int64:
+		switch encoding {
+		case "fixed64":
+			if pointer {
+				return unmarshalFixedS64Ptr
+			}
+			if slice {
+				return unmarshalFixedS64Slice
+			}
+			return unmarshalFixedS64Value
+		case "varint":
+			if pointer {
+				return unmarshalInt64Ptr
+			}
+			if slice {
+				return unmarshalInt64Slice
+			}
+			return unmarshalInt64Value
+		case "zigzag64":
+			if pointer {
+				return unmarshalSint64Ptr
+			}
+			if slice {
+				return unmarshalSint64Slice
+			}
+			return unmarshalSint64Value
+		}
+	case reflect.Uint32:
+		switch encoding {
+		case "fixed32":
+			if pointer {
+				return unmarshalFixed32Ptr
+			}
+			if slice {
+				return unmarshalFixed32Slice
+			}
+			return unmarshalFixed32Value
+		case "varint":
+			if pointer {
+				return unmarshalUint32Ptr
+			}
+			if slice {
+				return unmarshalUint32Slice
+			}
+			return unmarshalUint32Value
+		}
+	case reflect.Uint64:
+		switch encoding {
+		case "fixed64":
+			if pointer {
+				return unmarshalFixed64Ptr
+			}
+			if slice {
+				return unmarshalFixed64Slice
+			}
+			return unmarshalFixed64Value
+		case "varint":
+			if pointer {
+				return unmarshalUint64Ptr
+			}
+			if slice {
+				return unmarshalUint64Slice
+			}
+			return unmarshalUint64Value
+		}
+	case reflect.Float32:
+		if pointer {
+			return unmarshalFloat32Ptr
+		}
+		if slice {
+			return unmarshalFloat32Slice
+		}
+		return unmarshalFloat32Value
+	case reflect.Float64:
+		if pointer {
+			return unmarshalFloat64Ptr
+		}
+		if slice {
+			return unmarshalFloat64Slice
+		}
+		return unmarshalFloat64Value
+	case reflect.Map:
+		panic("map type in typeUnmarshaler in " + t.Name())
+	case reflect.Slice:
+		if pointer {
+			panic("bad pointer in slice case in " + t.Name())
+		}
+		if slice {
+			return unmarshalBytesSlice
+		}
+		return unmarshalBytesValue
+	case reflect.String:
+		if validateUTF8 {
+			if pointer {
+				return unmarshalUTF8StringPtr
+			}
+			if slice {
+				return unmarshalUTF8StringSlice
+			}
+			return unmarshalUTF8StringValue
+		}
+		if pointer {
+			return unmarshalStringPtr
+		}
+		if slice {
+			return unmarshalStringSlice
+		}
+		return unmarshalStringValue
+	case reflect.Struct:
+		// message or group field
+		if !pointer {
+			switch encoding {
+			case "bytes":
+				if slice {
+					return makeUnmarshalMessageSlice(getUnmarshalInfo(t), name)
+				}
+				return makeUnmarshalMessage(getUnmarshalInfo(t), name)
+			}
+		}
+		switch encoding {
+		case "bytes":
+			if slice {
+				return makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name)
+			}
+			return makeUnmarshalMessagePtr(getUnmarshalInfo(t), name)
+		case "group":
+			if slice {
+				return makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name)
+			}
+			return makeUnmarshalGroupPtr(getUnmarshalInfo(t), name)
+		}
+	}
+	panic(fmt.Sprintf("unmarshaler not found type:%s encoding:%s", t, encoding))
+}
+
+// Below are all the unmarshalers for individual fields of various types.
+
+func unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int64(x)
+	*f.toInt64() = v
+	return b, nil
+}
+
+func unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int64(x)
+	*f.toInt64Ptr() = &v
+	return b, nil
+}
+
+func unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			x, n = decodeVarint(b)
+			if n == 0 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			b = b[n:]
+			v := int64(x)
+			s := f.toInt64Slice()
+			*s = append(*s, v)
+		}
+		return res, nil
+	}
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int64(x)
+	s := f.toInt64Slice()
+	*s = append(*s, v)
+	return b, nil
+}
+
+func unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int64(x>>1) ^ int64(x)<<63>>63
+	*f.toInt64() = v
+	return b, nil
+}
+
+func unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int64(x>>1) ^ int64(x)<<63>>63
+	*f.toInt64Ptr() = &v
+	return b, nil
+}
+
+func unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			x, n = decodeVarint(b)
+			if n == 0 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			b = b[n:]
+			v := int64(x>>1) ^ int64(x)<<63>>63
+			s := f.toInt64Slice()
+			*s = append(*s, v)
+		}
+		return res, nil
+	}
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int64(x>>1) ^ int64(x)<<63>>63
+	s := f.toInt64Slice()
+	*s = append(*s, v)
+	return b, nil
+}
+
+func unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := uint64(x)
+	*f.toUint64() = v
+	return b, nil
+}
+
+func unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := uint64(x)
+	*f.toUint64Ptr() = &v
+	return b, nil
+}
+
+func unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			x, n = decodeVarint(b)
+			if n == 0 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			b = b[n:]
+			v := uint64(x)
+			s := f.toUint64Slice()
+			*s = append(*s, v)
+		}
+		return res, nil
+	}
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := uint64(x)
+	s := f.toUint64Slice()
+	*s = append(*s, v)
+	return b, nil
+}
+
+func unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int32(x)
+	*f.toInt32() = v
+	return b, nil
+}
+
+func unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int32(x)
+	f.setInt32Ptr(v)
+	return b, nil
+}
+
+func unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			x, n = decodeVarint(b)
+			if n == 0 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			b = b[n:]
+			v := int32(x)
+			f.appendInt32Slice(v)
+		}
+		return res, nil
+	}
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int32(x)
+	f.appendInt32Slice(v)
+	return b, nil
+}
+
+func unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int32(x>>1) ^ int32(x)<<31>>31
+	*f.toInt32() = v
+	return b, nil
+}
+
+func unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int32(x>>1) ^ int32(x)<<31>>31
+	f.setInt32Ptr(v)
+	return b, nil
+}
+
+func unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			x, n = decodeVarint(b)
+			if n == 0 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			b = b[n:]
+			v := int32(x>>1) ^ int32(x)<<31>>31
+			f.appendInt32Slice(v)
+		}
+		return res, nil
+	}
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := int32(x>>1) ^ int32(x)<<31>>31
+	f.appendInt32Slice(v)
+	return b, nil
+}
+
+func unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := uint32(x)
+	*f.toUint32() = v
+	return b, nil
+}
+
+func unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := uint32(x)
+	*f.toUint32Ptr() = &v
+	return b, nil
+}
+
+func unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			x, n = decodeVarint(b)
+			if n == 0 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			b = b[n:]
+			v := uint32(x)
+			s := f.toUint32Slice()
+			*s = append(*s, v)
+		}
+		return res, nil
+	}
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	v := uint32(x)
+	s := f.toUint32Slice()
+	*s = append(*s, v)
+	return b, nil
+}
+
+func unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed64 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 8 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+	*f.toUint64() = v
+	return b[8:], nil
+}
+
+func unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed64 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 8 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+	*f.toUint64Ptr() = &v
+	return b[8:], nil
+}
+
+func unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			if len(b) < 8 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+			s := f.toUint64Slice()
+			*s = append(*s, v)
+			b = b[8:]
+		}
+		return res, nil
+	}
+	if w != WireFixed64 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 8 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56
+	s := f.toUint64Slice()
+	*s = append(*s, v)
+	return b[8:], nil
+}
+
+func unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed64 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 8 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
+	*f.toInt64() = v
+	return b[8:], nil
+}
+
+func unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed64 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 8 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
+	*f.toInt64Ptr() = &v
+	return b[8:], nil
+}
+
+func unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			if len(b) < 8 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
+			s := f.toInt64Slice()
+			*s = append(*s, v)
+			b = b[8:]
+		}
+		return res, nil
+	}
+	if w != WireFixed64 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 8 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56
+	s := f.toInt64Slice()
+	*s = append(*s, v)
+	return b[8:], nil
+}
+
+func unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed32 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 4 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+	*f.toUint32() = v
+	return b[4:], nil
+}
+
+func unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed32 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 4 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+	*f.toUint32Ptr() = &v
+	return b[4:], nil
+}
+
+func unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			if len(b) < 4 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+			s := f.toUint32Slice()
+			*s = append(*s, v)
+			b = b[4:]
+		}
+		return res, nil
+	}
+	if w != WireFixed32 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 4 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24
+	s := f.toUint32Slice()
+	*s = append(*s, v)
+	return b[4:], nil
+}
+
+func unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed32 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 4 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
+	*f.toInt32() = v
+	return b[4:], nil
+}
+
+func unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed32 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 4 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
+	f.setInt32Ptr(v)
+	return b[4:], nil
+}
+
+func unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			if len(b) < 4 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
+			f.appendInt32Slice(v)
+			b = b[4:]
+		}
+		return res, nil
+	}
+	if w != WireFixed32 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 4 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24
+	f.appendInt32Slice(v)
+	return b[4:], nil
+}
+
+func unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	// Note: any length varint is allowed, even though any sane
+	// encoder will use one byte.
+	// See https://github.com/golang/protobuf/issues/76
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	// TODO: check if x>1? Tests seem to indicate no.
+	v := x != 0
+	*f.toBool() = v
+	return b[n:], nil
+}
+
+func unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := x != 0
+	*f.toBoolPtr() = &v
+	return b[n:], nil
+}
+
+func unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			x, n = decodeVarint(b)
+			if n == 0 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			v := x != 0
+			s := f.toBoolSlice()
+			*s = append(*s, v)
+			b = b[n:]
+		}
+		return res, nil
+	}
+	if w != WireVarint {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := x != 0
+	s := f.toBoolSlice()
+	*s = append(*s, v)
+	return b[n:], nil
+}
+
+func unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed64 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 8 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
+	*f.toFloat64() = v
+	return b[8:], nil
+}
+
+func unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed64 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 8 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
+	*f.toFloat64Ptr() = &v
+	return b[8:], nil
+}
+
+func unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			if len(b) < 8 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
+			s := f.toFloat64Slice()
+			*s = append(*s, v)
+			b = b[8:]
+		}
+		return res, nil
+	}
+	if w != WireFixed64 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 8 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56)
+	s := f.toFloat64Slice()
+	*s = append(*s, v)
+	return b[8:], nil
+}
+
+func unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed32 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 4 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
+	*f.toFloat32() = v
+	return b[4:], nil
+}
+
+func unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireFixed32 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 4 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
+	*f.toFloat32Ptr() = &v
+	return b[4:], nil
+}
+
+func unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) {
+	if w == WireBytes { // packed
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		res := b[x:]
+		b = b[:x]
+		for len(b) > 0 {
+			if len(b) < 4 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
+			s := f.toFloat32Slice()
+			*s = append(*s, v)
+			b = b[4:]
+		}
+		return res, nil
+	}
+	if w != WireFixed32 {
+		return b, errInternalBadWireType
+	}
+	if len(b) < 4 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24)
+	s := f.toFloat32Slice()
+	*s = append(*s, v)
+	return b[4:], nil
+}
+
+func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireBytes {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	if x > uint64(len(b)) {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := string(b[:x])
+	*f.toString() = v
+	return b[x:], nil
+}
+
+func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireBytes {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	if x > uint64(len(b)) {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := string(b[:x])
+	*f.toStringPtr() = &v
+	return b[x:], nil
+}
+
+func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireBytes {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	if x > uint64(len(b)) {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := string(b[:x])
+	s := f.toStringSlice()
+	*s = append(*s, v)
+	return b[x:], nil
+}
+
+func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireBytes {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	if x > uint64(len(b)) {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := string(b[:x])
+	*f.toString() = v
+	if !utf8.ValidString(v) {
+		return b[x:], errInvalidUTF8
+	}
+	return b[x:], nil
+}
+
+func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireBytes {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	if x > uint64(len(b)) {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := string(b[:x])
+	*f.toStringPtr() = &v
+	if !utf8.ValidString(v) {
+		return b[x:], errInvalidUTF8
+	}
+	return b[x:], nil
+}
+
+func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireBytes {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	if x > uint64(len(b)) {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := string(b[:x])
+	s := f.toStringSlice()
+	*s = append(*s, v)
+	if !utf8.ValidString(v) {
+		return b[x:], errInvalidUTF8
+	}
+	return b[x:], nil
+}
+
+var emptyBuf [0]byte
+
+func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireBytes {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	if x > uint64(len(b)) {
+		return nil, io.ErrUnexpectedEOF
+	}
+	// The use of append here is a trick which avoids the zeroing
+	// that would be required if we used a make/copy pair.
+	// We append to emptyBuf instead of nil because we want
+	// a non-nil result even when the length is 0.
+	v := append(emptyBuf[:], b[:x]...)
+	*f.toBytes() = v
+	return b[x:], nil
+}
+
+func unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) {
+	if w != WireBytes {
+		return b, errInternalBadWireType
+	}
+	x, n := decodeVarint(b)
+	if n == 0 {
+		return nil, io.ErrUnexpectedEOF
+	}
+	b = b[n:]
+	if x > uint64(len(b)) {
+		return nil, io.ErrUnexpectedEOF
+	}
+	v := append(emptyBuf[:], b[:x]...)
+	s := f.toBytesSlice()
+	*s = append(*s, v)
+	return b[x:], nil
+}
+
+func makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return b, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		// First read the message field to see if something is there.
+		// The semantics of multiple submessages are weird.  Instead of
+		// the last one winning (as it is for all other fields), multiple
+		// submessages are merged.
+		v := f.getPointer()
+		if v.isNil() {
+			v = valToPointer(reflect.New(sub.typ))
+			f.setPointer(v)
+		}
+		err := sub.unmarshal(v, b[:x])
+		if err != nil {
+			if r, ok := err.(*RequiredNotSetError); ok {
+				r.field = name + "." + r.field
+			} else {
+				return nil, err
+			}
+		}
+		return b[x:], err
+	}
+}
+
+func makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return b, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		v := valToPointer(reflect.New(sub.typ))
+		err := sub.unmarshal(v, b[:x])
+		if err != nil {
+			if r, ok := err.(*RequiredNotSetError); ok {
+				r.field = name + "." + r.field
+			} else {
+				return nil, err
+			}
+		}
+		f.appendPointer(v)
+		return b[x:], err
+	}
+}
+
+func makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireStartGroup {
+			return b, errInternalBadWireType
+		}
+		x, y := findEndGroup(b)
+		if x < 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		v := f.getPointer()
+		if v.isNil() {
+			v = valToPointer(reflect.New(sub.typ))
+			f.setPointer(v)
+		}
+		err := sub.unmarshal(v, b[:x])
+		if err != nil {
+			if r, ok := err.(*RequiredNotSetError); ok {
+				r.field = name + "." + r.field
+			} else {
+				return nil, err
+			}
+		}
+		return b[y:], err
+	}
+}
+
+func makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireStartGroup {
+			return b, errInternalBadWireType
+		}
+		x, y := findEndGroup(b)
+		if x < 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		v := valToPointer(reflect.New(sub.typ))
+		err := sub.unmarshal(v, b[:x])
+		if err != nil {
+			if r, ok := err.(*RequiredNotSetError); ok {
+				r.field = name + "." + r.field
+			} else {
+				return nil, err
+			}
+		}
+		f.appendPointer(v)
+		return b[y:], err
+	}
+}
+
+func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
+	t := f.Type
+	kt := t.Key()
+	vt := t.Elem()
+	tagArray := strings.Split(f.Tag.Get("protobuf"), ",")
+	valTags := strings.Split(f.Tag.Get("protobuf_val"), ",")
+	for _, t := range tagArray {
+		if strings.HasPrefix(t, "customtype=") {
+			valTags = append(valTags, t)
+		}
+		if t == "stdtime" {
+			valTags = append(valTags, t)
+		}
+		if t == "stdduration" {
+			valTags = append(valTags, t)
+		}
+		if t == "wktptr" {
+			valTags = append(valTags, t)
+		}
+	}
+	unmarshalKey := typeUnmarshaler(kt, f.Tag.Get("protobuf_key"))
+	unmarshalVal := typeUnmarshaler(vt, strings.Join(valTags, ","))
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		// The map entry is a submessage. Figure out how big it is.
+		if w != WireBytes {
+			return nil, fmt.Errorf("proto: bad wiretype for map field: got %d want %d", w, WireBytes)
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		r := b[x:] // unused data to return
+		b = b[:x]  // data for map entry
+
+		// Note: we could use #keys * #values ~= 200 functions
+		// to do map decoding without reflection. Probably not worth it.
+		// Maps will be somewhat slow. Oh well.
+
+		// Read key and value from data.
+		var nerr nonFatal
+		k := reflect.New(kt)
+		v := reflect.New(vt)
+		for len(b) > 0 {
+			x, n := decodeVarint(b)
+			if n == 0 {
+				return nil, io.ErrUnexpectedEOF
+			}
+			wire := int(x) & 7
+			b = b[n:]
+
+			var err error
+			switch x >> 3 {
+			case 1:
+				b, err = unmarshalKey(b, valToPointer(k), wire)
+			case 2:
+				b, err = unmarshalVal(b, valToPointer(v), wire)
+			default:
+				err = errInternalBadWireType // skip unknown tag
+			}
+
+			if nerr.Merge(err) {
+				continue
+			}
+			if err != errInternalBadWireType {
+				return nil, err
+			}
+
+			// Skip past unknown fields.
+			b, err = skipField(b, wire)
+			if err != nil {
+				return nil, err
+			}
+		}
+
+		// Get map, allocate if needed.
+		m := f.asPointerTo(t).Elem() // an addressable map[K]T
+		if m.IsNil() {
+			m.Set(reflect.MakeMap(t))
+		}
+
+		// Insert into map.
+		m.SetMapIndex(k.Elem(), v.Elem())
+
+		return r, nerr.E
+	}
+}
+
+// makeUnmarshalOneof makes an unmarshaler for oneof fields.
+// for:
+// message Msg {
+//   oneof F {
+//     int64 X = 1;
+//     float64 Y = 2;
+//   }
+// }
+// typ is the type of the concrete entry for a oneof case (e.g. Msg_X).
+// ityp is the interface type of the oneof field (e.g. isMsg_F).
+// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64).
+// Note that this function will be called once for each case in the oneof.
+func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler {
+	sf := typ.Field(0)
+	field0 := toField(&sf)
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		// Allocate holder for value.
+		v := reflect.New(typ)
+
+		// Unmarshal data into holder.
+		// We unmarshal into the first field of the holder object.
+		var err error
+		var nerr nonFatal
+		b, err = unmarshal(b, valToPointer(v).offset(field0), w)
+		if !nerr.Merge(err) {
+			return nil, err
+		}
+
+		// Write pointer to holder into target field.
+		f.asPointerTo(ityp).Elem().Set(v)
+
+		return b, nerr.E
+	}
+}
+
+// Error used by decode internally.
+var errInternalBadWireType = errors.New("proto: internal error: bad wiretype")
+
+// skipField skips past a field of type wire and returns the remaining bytes.
+func skipField(b []byte, wire int) ([]byte, error) {
+	switch wire {
+	case WireVarint:
+		_, k := decodeVarint(b)
+		if k == 0 {
+			return b, io.ErrUnexpectedEOF
+		}
+		b = b[k:]
+	case WireFixed32:
+		if len(b) < 4 {
+			return b, io.ErrUnexpectedEOF
+		}
+		b = b[4:]
+	case WireFixed64:
+		if len(b) < 8 {
+			return b, io.ErrUnexpectedEOF
+		}
+		b = b[8:]
+	case WireBytes:
+		m, k := decodeVarint(b)
+		if k == 0 || uint64(len(b)-k) < m {
+			return b, io.ErrUnexpectedEOF
+		}
+		b = b[uint64(k)+m:]
+	case WireStartGroup:
+		_, i := findEndGroup(b)
+		if i == -1 {
+			return b, io.ErrUnexpectedEOF
+		}
+		b = b[i:]
+	default:
+		return b, fmt.Errorf("proto: can't skip unknown wire type %d", wire)
+	}
+	return b, nil
+}
+
+// findEndGroup finds the index of the next EndGroup tag.
+// Groups may be nested, so the "next" EndGroup tag is the first
+// unpaired EndGroup.
+// findEndGroup returns the indexes of the start and end of the EndGroup tag.
+// Returns (-1,-1) if it can't find one.
+func findEndGroup(b []byte) (int, int) {
+	depth := 1
+	i := 0
+	for {
+		x, n := decodeVarint(b[i:])
+		if n == 0 {
+			return -1, -1
+		}
+		j := i
+		i += n
+		switch x & 7 {
+		case WireVarint:
+			_, k := decodeVarint(b[i:])
+			if k == 0 {
+				return -1, -1
+			}
+			i += k
+		case WireFixed32:
+			if len(b)-4 < i {
+				return -1, -1
+			}
+			i += 4
+		case WireFixed64:
+			if len(b)-8 < i {
+				return -1, -1
+			}
+			i += 8
+		case WireBytes:
+			m, k := decodeVarint(b[i:])
+			if k == 0 {
+				return -1, -1
+			}
+			i += k
+			if uint64(len(b)-i) < m {
+				return -1, -1
+			}
+			i += int(m)
+		case WireStartGroup:
+			depth++
+		case WireEndGroup:
+			depth--
+			if depth == 0 {
+				return j, i
+			}
+		default:
+			return -1, -1
+		}
+	}
+}
+
+// encodeVarint appends a varint-encoded integer to b and returns the result.
+func encodeVarint(b []byte, x uint64) []byte {
+	for x >= 1<<7 {
+		b = append(b, byte(x&0x7f|0x80))
+		x >>= 7
+	}
+	return append(b, byte(x))
+}
+
+// decodeVarint reads a varint-encoded integer from b.
+// Returns the decoded integer and the number of bytes read.
+// If there is an error, it returns 0,0.
+func decodeVarint(b []byte) (uint64, int) {
+	var x, y uint64
+	if len(b) <= 0 {
+		goto bad
+	}
+	x = uint64(b[0])
+	if x < 0x80 {
+		return x, 1
+	}
+	x -= 0x80
+
+	if len(b) <= 1 {
+		goto bad
+	}
+	y = uint64(b[1])
+	x += y << 7
+	if y < 0x80 {
+		return x, 2
+	}
+	x -= 0x80 << 7
+
+	if len(b) <= 2 {
+		goto bad
+	}
+	y = uint64(b[2])
+	x += y << 14
+	if y < 0x80 {
+		return x, 3
+	}
+	x -= 0x80 << 14
+
+	if len(b) <= 3 {
+		goto bad
+	}
+	y = uint64(b[3])
+	x += y << 21
+	if y < 0x80 {
+		return x, 4
+	}
+	x -= 0x80 << 21
+
+	if len(b) <= 4 {
+		goto bad
+	}
+	y = uint64(b[4])
+	x += y << 28
+	if y < 0x80 {
+		return x, 5
+	}
+	x -= 0x80 << 28
+
+	if len(b) <= 5 {
+		goto bad
+	}
+	y = uint64(b[5])
+	x += y << 35
+	if y < 0x80 {
+		return x, 6
+	}
+	x -= 0x80 << 35
+
+	if len(b) <= 6 {
+		goto bad
+	}
+	y = uint64(b[6])
+	x += y << 42
+	if y < 0x80 {
+		return x, 7
+	}
+	x -= 0x80 << 42
+
+	if len(b) <= 7 {
+		goto bad
+	}
+	y = uint64(b[7])
+	x += y << 49
+	if y < 0x80 {
+		return x, 8
+	}
+	x -= 0x80 << 49
+
+	if len(b) <= 8 {
+		goto bad
+	}
+	y = uint64(b[8])
+	x += y << 56
+	if y < 0x80 {
+		return x, 9
+	}
+	x -= 0x80 << 56
+
+	if len(b) <= 9 {
+		goto bad
+	}
+	y = uint64(b[9])
+	x += y << 63
+	if y < 2 {
+		return x, 10
+	}
+
+bad:
+	return 0, 0
+}

+ 385 - 0
vendor/github.com/gogo/protobuf/proto/table_unmarshal_gogo.go

@@ -0,0 +1,385 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2018, 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 proto
+
+import (
+	"io"
+	"reflect"
+)
+
+func makeUnmarshalMessage(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		// First read the message field to see if something is there.
+		// The semantics of multiple submessages are weird.  Instead of
+		// the last one winning (as it is for all other fields), multiple
+		// submessages are merged.
+		v := f // gogo: changed from v := f.getPointer()
+		if v.isNil() {
+			v = valToPointer(reflect.New(sub.typ))
+			f.setPointer(v)
+		}
+		err := sub.unmarshal(v, b[:x])
+		if err != nil {
+			if r, ok := err.(*RequiredNotSetError); ok {
+				r.field = name + "." + r.field
+			} else {
+				return nil, err
+			}
+		}
+		return b[x:], err
+	}
+}
+
+func makeUnmarshalMessageSlice(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		v := valToPointer(reflect.New(sub.typ))
+		err := sub.unmarshal(v, b[:x])
+		if err != nil {
+			if r, ok := err.(*RequiredNotSetError); ok {
+				r.field = name + "." + r.field
+			} else {
+				return nil, err
+			}
+		}
+		f.appendRef(v, sub.typ) // gogo: changed from f.appendPointer(v)
+		return b[x:], err
+	}
+}
+
+func makeUnmarshalCustomPtr(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.New(sub.typ))
+		m := s.Interface().(custom)
+		if err := m.Unmarshal(b[:x]); err != nil {
+			return nil, err
+		}
+		return b[x:], nil
+	}
+}
+
+func makeUnmarshalCustomSlice(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := reflect.New(sub.typ)
+		c := m.Interface().(custom)
+		if err := c.Unmarshal(b[:x]); err != nil {
+			return nil, err
+		}
+		v := valToPointer(m)
+		f.appendRef(v, sub.typ)
+		return b[x:], nil
+	}
+}
+
+func makeUnmarshalCustom(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+
+		m := f.asPointerTo(sub.typ).Interface().(custom)
+		if err := m.Unmarshal(b[:x]); err != nil {
+			return nil, err
+		}
+		return b[x:], nil
+	}
+}
+
+func makeUnmarshalTime(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &timestamp{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		t, err := timestampFromProto(m)
+		if err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(t))
+		return b[x:], nil
+	}
+}
+
+func makeUnmarshalTimePtr(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &timestamp{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		t, err := timestampFromProto(m)
+		if err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&t))
+		return b[x:], nil
+	}
+}
+
+func makeUnmarshalTimePtrSlice(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &timestamp{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		t, err := timestampFromProto(m)
+		if err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&t))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeUnmarshalTimeSlice(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &timestamp{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		t, err := timestampFromProto(m)
+		if err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(t))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeUnmarshalDurationPtr(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &duration{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		d, err := durationFromProto(m)
+		if err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&d))
+		return b[x:], nil
+	}
+}
+
+func makeUnmarshalDuration(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &duration{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		d, err := durationFromProto(m)
+		if err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(d))
+		return b[x:], nil
+	}
+}
+
+func makeUnmarshalDurationPtrSlice(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &duration{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		d, err := durationFromProto(m)
+		if err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&d))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeUnmarshalDurationSlice(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &duration{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		d, err := durationFromProto(m)
+		if err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(d))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}

+ 27 - 38
vendor/github.com/gogo/protobuf/proto/text.go

@@ -57,7 +57,6 @@ import (
 var (
 	newline         = []byte("\n")
 	spaces          = []byte("                                        ")
-	gtNewline       = []byte(">\n")
 	endBraceNewline = []byte("}\n")
 	backslashN      = []byte{'\\', 'n'}
 	backslashR      = []byte{'\\', 'r'}
@@ -177,11 +176,6 @@ func writeName(w *textWriter, props *Properties) error {
 	return nil
 }
 
-// raw is the interface satisfied by RawMessage.
-type raw interface {
-	Bytes() []byte
-}
-
 func requiresQuotes(u string) bool {
 	// When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted.
 	for _, ch := range u {
@@ -276,6 +270,10 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 		props := sprops.Prop[i]
 		name := st.Field(i).Name
 
+		if name == "XXX_NoUnkeyedLiteral" {
+			continue
+		}
+
 		if strings.HasPrefix(name, "XXX_") {
 			// There are two XXX_ fields:
 			//   XXX_unrecognized []byte
@@ -366,7 +364,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 						return err
 					}
 				}
-				if err := tm.writeAny(w, key, props.mkeyprop); err != nil {
+				if err := tm.writeAny(w, key, props.MapKeyProp); err != nil {
 					return err
 				}
 				if err := w.WriteByte('\n'); err != nil {
@@ -383,7 +381,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 							return err
 						}
 					}
-					if err := tm.writeAny(w, val, props.mvalprop); err != nil {
+					if err := tm.writeAny(w, val, props.MapValProp); err != nil {
 						return err
 					}
 					if err := w.WriteByte('\n'); err != nil {
@@ -447,12 +445,6 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 				return err
 			}
 		}
-		if b, ok := fv.Interface().(raw); ok {
-			if err := writeRaw(w, b.Bytes()); err != nil {
-				return err
-			}
-			continue
-		}
 
 		if len(props.Enum) > 0 {
 			if err := tm.writeEnum(w, fv, props); err != nil {
@@ -475,7 +467,7 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 		pv = reflect.New(sv.Type())
 		pv.Elem().Set(sv)
 	}
-	if pv.Type().Implements(extensionRangeType) {
+	if _, err := extendable(pv.Interface()); err == nil {
 		if err := tm.writeExtensions(w, pv); err != nil {
 			return err
 		}
@@ -484,27 +476,6 @@ func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error {
 	return nil
 }
 
-// writeRaw writes an uninterpreted raw message.
-func writeRaw(w *textWriter, b []byte) error {
-	if err := w.WriteByte('<'); err != nil {
-		return err
-	}
-	if !w.compact {
-		if err := w.WriteByte('\n'); err != nil {
-			return err
-		}
-	}
-	w.indent()
-	if err := writeUnknownStruct(w, b); err != nil {
-		return err
-	}
-	w.unindent()
-	if err := w.WriteByte('>'); err != nil {
-		return err
-	}
-	return nil
-}
-
 // writeAny writes an arbitrary field.
 func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error {
 	v = reflect.Indirect(v)
@@ -605,6 +576,19 @@ func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Propert
 			}
 		}
 		w.indent()
+		if v.CanAddr() {
+			// Calling v.Interface on a struct causes the reflect package to
+			// copy the entire struct. This is racy with the new Marshaler
+			// since we atomically update the XXX_sizecache.
+			//
+			// Thus, we retrieve a pointer to the struct if possible to avoid
+			// a race since v.Interface on the pointer doesn't copy the struct.
+			//
+			// If v is not addressable, then we are not worried about a race
+			// since it implies that the binary Marshaler cannot possibly be
+			// mutating this value.
+			v = v.Addr()
+		}
 		if etm, ok := v.Interface().(encoding.TextMarshaler); ok {
 			text, err := etm.MarshalText()
 			if err != nil {
@@ -613,8 +597,13 @@ func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Propert
 			if _, err = w.Write(text); err != nil {
 				return err
 			}
-		} else if err := tm.writeStruct(w, v); err != nil {
-			return err
+		} else {
+			if v.Kind() == reflect.Ptr {
+				v = v.Elem()
+			}
+			if err := tm.writeStruct(w, v); err != nil {
+				return err
+			}
 		}
 		w.unindent()
 		if err := w.WriteByte(ket); err != nil {

+ 54 - 49
vendor/github.com/gogo/protobuf/proto/text_parser.go

@@ -212,7 +212,6 @@ func (p *textParser) advance() {
 
 var (
 	errBadUTF8 = errors.New("proto: bad UTF-8")
-	errBadHex  = errors.New("proto: bad hexadecimal")
 )
 
 func unquoteC(s string, quote rune) (string, error) {
@@ -283,60 +282,47 @@ func unescape(s string) (ch string, tail string, err error) {
 		return "?", s, nil // trigraph workaround
 	case '\'', '"', '\\':
 		return string(r), s, nil
-	case '0', '1', '2', '3', '4', '5', '6', '7', 'x', 'X':
+	case '0', '1', '2', '3', '4', '5', '6', '7':
 		if len(s) < 2 {
 			return "", "", fmt.Errorf(`\%c requires 2 following digits`, r)
 		}
-		base := 8
-		ss := s[:2]
+		ss := string(r) + s[:2]
 		s = s[2:]
-		if r == 'x' || r == 'X' {
-			base = 16
-		} else {
-			ss = string(r) + ss
-		}
-		i, err := strconv.ParseUint(ss, base, 8)
+		i, err := strconv.ParseUint(ss, 8, 8)
 		if err != nil {
-			return "", "", err
+			return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss)
 		}
 		return string([]byte{byte(i)}), s, nil
-	case 'u', 'U':
-		n := 4
-		if r == 'U' {
+	case 'x', 'X', 'u', 'U':
+		var n int
+		switch r {
+		case 'x', 'X':
+			n = 2
+		case 'u':
+			n = 4
+		case 'U':
 			n = 8
 		}
 		if len(s) < n {
-			return "", "", fmt.Errorf(`\%c requires %d digits`, r, n)
-		}
-
-		bs := make([]byte, n/2)
-		for i := 0; i < n; i += 2 {
-			a, ok1 := unhex(s[i])
-			b, ok2 := unhex(s[i+1])
-			if !ok1 || !ok2 {
-				return "", "", errBadHex
-			}
-			bs[i/2] = a<<4 | b
+			return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n)
 		}
+		ss := s[:n]
 		s = s[n:]
-		return string(bs), s, nil
+		i, err := strconv.ParseUint(ss, 16, 64)
+		if err != nil {
+			return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss)
+		}
+		if r == 'x' || r == 'X' {
+			return string([]byte{byte(i)}), s, nil
+		}
+		if i > utf8.MaxRune {
+			return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss)
+		}
+		return string(i), s, nil
 	}
 	return "", "", fmt.Errorf(`unknown escape \%c`, r)
 }
 
-// Adapted from src/pkg/strconv/quote.go.
-func unhex(b byte) (v byte, ok bool) {
-	switch {
-	case '0' <= b && b <= '9':
-		return b - '0', true
-	case 'a' <= b && b <= 'f':
-		return b - 'a' + 10, true
-	case 'A' <= b && b <= 'F':
-		return b - 'A' + 10, true
-	}
-	return 0, false
-}
-
 // Back off the parser by one token. Can only be done between calls to next().
 // It makes the next advance() a no-op.
 func (p *textParser) back() { p.backed = true }
@@ -650,17 +636,17 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
 					if err := p.consumeToken(":"); err != nil {
 						return err
 					}
-					if err := p.readAny(key, props.mkeyprop); err != nil {
+					if err := p.readAny(key, props.MapKeyProp); err != nil {
 						return err
 					}
 					if err := p.consumeOptionalSeparator(); err != nil {
 						return err
 					}
 				case "value":
-					if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
+					if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil {
 						return err
 					}
-					if err := p.readAny(val, props.mvalprop); err != nil {
+					if err := p.readAny(val, props.MapValProp); err != nil {
 						return err
 					}
 					if err := p.consumeOptionalSeparator(); err != nil {
@@ -734,6 +720,9 @@ func (p *textParser) consumeExtName() (string, error) {
 		if tok.err != nil {
 			return "", p.errorf("unrecognized type_url or extension name: %s", tok.err)
 		}
+		if p.done && tok.value != "]" {
+			return "", p.errorf("unclosed type_url or extension name")
+		}
 	}
 	return strings.Join(parts, ""), nil
 }
@@ -934,6 +923,16 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 			fv.SetFloat(f)
 			return nil
 		}
+	case reflect.Int8:
+		if x, err := strconv.ParseInt(tok.value, 0, 8); err == nil {
+			fv.SetInt(x)
+			return nil
+		}
+	case reflect.Int16:
+		if x, err := strconv.ParseInt(tok.value, 0, 16); err == nil {
+			fv.SetInt(x)
+			return nil
+		}
 	case reflect.Int32:
 		if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil {
 			fv.SetInt(x)
@@ -981,9 +980,19 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 		}
 		// TODO: Handle nested messages which implement encoding.TextUnmarshaler.
 		return p.readStruct(fv, terminator)
+	case reflect.Uint8:
+		if x, err := strconv.ParseUint(tok.value, 0, 8); err == nil {
+			fv.SetUint(x)
+			return nil
+		}
+	case reflect.Uint16:
+		if x, err := strconv.ParseUint(tok.value, 0, 16); err == nil {
+			fv.SetUint(x)
+			return nil
+		}
 	case reflect.Uint32:
 		if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil {
-			fv.SetUint(x)
+			fv.SetUint(uint64(x))
 			return nil
 		}
 	case reflect.Uint64:
@@ -1001,13 +1010,9 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
 // UnmarshalText returns *RequiredNotSetError.
 func UnmarshalText(s string, pb Message) error {
 	if um, ok := pb.(encoding.TextUnmarshaler); ok {
-		err := um.UnmarshalText([]byte(s))
-		return err
+		return um.UnmarshalText([]byte(s))
 	}
 	pb.Reset()
 	v := reflect.ValueOf(pb)
-	if pe := newTextParser(s).readStruct(v.Elem(), ""); pe != nil {
-		return pe
-	}
-	return nil
+	return newTextParser(s).readStruct(v.Elem(), "")
 }

+ 0 - 180
vendor/github.com/gogo/protobuf/proto/timestamp_gogo.go

@@ -47,183 +47,3 @@ func (*timestamp) String() string { return "timestamp<string>" }
 func init() {
 	RegisterType((*timestamp)(nil), "gogo.protobuf.proto.timestamp")
 }
-
-func (o *Buffer) decTimestamp() (time.Time, error) {
-	b, err := o.DecodeRawBytes(true)
-	if err != nil {
-		return time.Time{}, err
-	}
-	tproto := &timestamp{}
-	if err := Unmarshal(b, tproto); err != nil {
-		return time.Time{}, err
-	}
-	return timestampFromProto(tproto)
-}
-
-func (o *Buffer) dec_time(p *Properties, base structPointer) error {
-	t, err := o.decTimestamp()
-	if err != nil {
-		return err
-	}
-	setPtrCustomType(base, p.field, &t)
-	return nil
-}
-
-func (o *Buffer) dec_ref_time(p *Properties, base structPointer) error {
-	t, err := o.decTimestamp()
-	if err != nil {
-		return err
-	}
-	setCustomType(base, p.field, &t)
-	return nil
-}
-
-func (o *Buffer) dec_slice_time(p *Properties, base structPointer) error {
-	t, err := o.decTimestamp()
-	if err != nil {
-		return err
-	}
-	newBas := appendStructPointer(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType)))
-	var zero field
-	setPtrCustomType(newBas, zero, &t)
-	return nil
-}
-
-func (o *Buffer) dec_slice_ref_time(p *Properties, base structPointer) error {
-	t, err := o.decTimestamp()
-	if err != nil {
-		return err
-	}
-	newBas := appendStructPointer(base, p.field, reflect.SliceOf(timeType))
-	var zero field
-	setCustomType(newBas, zero, &t)
-	return nil
-}
-
-func size_time(p *Properties, base structPointer) (n int) {
-	structp := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(structp) {
-		return 0
-	}
-	tim := structPointer_Interface(structp, timeType).(*time.Time)
-	t, err := timestampProto(*tim)
-	if err != nil {
-		return 0
-	}
-	size := Size(t)
-	return size + sizeVarint(uint64(size)) + len(p.tagcode)
-}
-
-func (o *Buffer) enc_time(p *Properties, base structPointer) error {
-	structp := structPointer_GetStructPointer(base, p.field)
-	if structPointer_IsNil(structp) {
-		return ErrNil
-	}
-	tim := structPointer_Interface(structp, timeType).(*time.Time)
-	t, err := timestampProto(*tim)
-	if err != nil {
-		return err
-	}
-	data, err := Marshal(t)
-	if err != nil {
-		return err
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeRawBytes(data)
-	return nil
-}
-
-func size_ref_time(p *Properties, base structPointer) (n int) {
-	tim := structPointer_InterfaceAt(base, p.field, timeType).(*time.Time)
-	t, err := timestampProto(*tim)
-	if err != nil {
-		return 0
-	}
-	size := Size(t)
-	return size + sizeVarint(uint64(size)) + len(p.tagcode)
-}
-
-func (o *Buffer) enc_ref_time(p *Properties, base structPointer) error {
-	tim := structPointer_InterfaceAt(base, p.field, timeType).(*time.Time)
-	t, err := timestampProto(*tim)
-	if err != nil {
-		return err
-	}
-	data, err := Marshal(t)
-	if err != nil {
-		return err
-	}
-	o.buf = append(o.buf, p.tagcode...)
-	o.EncodeRawBytes(data)
-	return nil
-}
-
-func size_slice_time(p *Properties, base structPointer) (n int) {
-	ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType))).(*[]*time.Time)
-	tims := *ptims
-	for i := 0; i < len(tims); i++ {
-		if tims[i] == nil {
-			return 0
-		}
-		tproto, err := timestampProto(*tims[i])
-		if err != nil {
-			return 0
-		}
-		size := Size(tproto)
-		n += len(p.tagcode) + size + sizeVarint(uint64(size))
-	}
-	return n
-}
-
-func (o *Buffer) enc_slice_time(p *Properties, base structPointer) error {
-	ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(reflect.PtrTo(timeType))).(*[]*time.Time)
-	tims := *ptims
-	for i := 0; i < len(tims); i++ {
-		if tims[i] == nil {
-			return errRepeatedHasNil
-		}
-		tproto, err := timestampProto(*tims[i])
-		if err != nil {
-			return err
-		}
-		data, err := Marshal(tproto)
-		if err != nil {
-			return err
-		}
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeRawBytes(data)
-	}
-	return nil
-}
-
-func size_slice_ref_time(p *Properties, base structPointer) (n int) {
-	ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(timeType)).(*[]time.Time)
-	tims := *ptims
-	for i := 0; i < len(tims); i++ {
-		tproto, err := timestampProto(tims[i])
-		if err != nil {
-			return 0
-		}
-		size := Size(tproto)
-		n += len(p.tagcode) + size + sizeVarint(uint64(size))
-	}
-	return n
-}
-
-func (o *Buffer) enc_slice_ref_time(p *Properties, base structPointer) error {
-	ptims := structPointer_InterfaceAt(base, p.field, reflect.SliceOf(timeType)).(*[]time.Time)
-	tims := *ptims
-	for i := 0; i < len(tims); i++ {
-		tproto, err := timestampProto(tims[i])
-		if err != nil {
-			return err
-		}
-		data, err := Marshal(tproto)
-		if err != nil {
-			return err
-		}
-		o.buf = append(o.buf, p.tagcode...)
-		o.EncodeRawBytes(data)
-	}
-	return nil
-}

+ 1888 - 0
vendor/github.com/gogo/protobuf/proto/wrappers.go

@@ -0,0 +1,1888 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2018, 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 proto
+
+import (
+	"io"
+	"reflect"
+)
+
+func makeStdDoubleValueMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			t := ptr.asPointerTo(u.typ).Interface().(*float64)
+			v := &float64Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			t := ptr.asPointerTo(u.typ).Interface().(*float64)
+			v := &float64Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdDoubleValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float64)
+			v := &float64Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float64)
+			v := &float64Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdDoubleValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(float64)
+				v := &float64Value{t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(float64)
+				v := &float64Value{t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdDoubleValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*float64)
+				v := &float64Value{*t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*float64)
+				v := &float64Value{*t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdDoubleValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &float64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdDoubleValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &float64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdDoubleValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &float64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdDoubleValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &float64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdFloatValueMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			t := ptr.asPointerTo(u.typ).Interface().(*float32)
+			v := &float32Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			t := ptr.asPointerTo(u.typ).Interface().(*float32)
+			v := &float32Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdFloatValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float32)
+			v := &float32Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*float32)
+			v := &float32Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdFloatValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(float32)
+				v := &float32Value{t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(float32)
+				v := &float32Value{t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdFloatValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*float32)
+				v := &float32Value{*t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*float32)
+				v := &float32Value{*t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdFloatValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &float32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdFloatValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &float32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdFloatValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &float32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdFloatValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &float32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdInt64ValueMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			t := ptr.asPointerTo(u.typ).Interface().(*int64)
+			v := &int64Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			t := ptr.asPointerTo(u.typ).Interface().(*int64)
+			v := &int64Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdInt64ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int64)
+			v := &int64Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int64)
+			v := &int64Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdInt64ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(int64)
+				v := &int64Value{t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(int64)
+				v := &int64Value{t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdInt64ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*int64)
+				v := &int64Value{*t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*int64)
+				v := &int64Value{*t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdInt64ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &int64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdInt64ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &int64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdInt64ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &int64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdInt64ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &int64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdUInt64ValueMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			t := ptr.asPointerTo(u.typ).Interface().(*uint64)
+			v := &uint64Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			t := ptr.asPointerTo(u.typ).Interface().(*uint64)
+			v := &uint64Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdUInt64ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint64)
+			v := &uint64Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint64)
+			v := &uint64Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdUInt64ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(uint64)
+				v := &uint64Value{t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(uint64)
+				v := &uint64Value{t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdUInt64ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*uint64)
+				v := &uint64Value{*t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*uint64)
+				v := &uint64Value{*t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdUInt64ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &uint64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdUInt64ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &uint64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdUInt64ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &uint64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdUInt64ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &uint64Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdInt32ValueMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			t := ptr.asPointerTo(u.typ).Interface().(*int32)
+			v := &int32Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			t := ptr.asPointerTo(u.typ).Interface().(*int32)
+			v := &int32Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdInt32ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int32)
+			v := &int32Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*int32)
+			v := &int32Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdInt32ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(int32)
+				v := &int32Value{t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(int32)
+				v := &int32Value{t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdInt32ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*int32)
+				v := &int32Value{*t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*int32)
+				v := &int32Value{*t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdInt32ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &int32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdInt32ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &int32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdInt32ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &int32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdInt32ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &int32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdUInt32ValueMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			t := ptr.asPointerTo(u.typ).Interface().(*uint32)
+			v := &uint32Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			t := ptr.asPointerTo(u.typ).Interface().(*uint32)
+			v := &uint32Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdUInt32ValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint32)
+			v := &uint32Value{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*uint32)
+			v := &uint32Value{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdUInt32ValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(uint32)
+				v := &uint32Value{t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(uint32)
+				v := &uint32Value{t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdUInt32ValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*uint32)
+				v := &uint32Value{*t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*uint32)
+				v := &uint32Value{*t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdUInt32ValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &uint32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdUInt32ValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &uint32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdUInt32ValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &uint32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdUInt32ValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &uint32Value{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdBoolValueMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			t := ptr.asPointerTo(u.typ).Interface().(*bool)
+			v := &boolValue{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			t := ptr.asPointerTo(u.typ).Interface().(*bool)
+			v := &boolValue{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdBoolValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*bool)
+			v := &boolValue{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*bool)
+			v := &boolValue{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdBoolValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(bool)
+				v := &boolValue{t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(bool)
+				v := &boolValue{t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdBoolValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*bool)
+				v := &boolValue{*t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*bool)
+				v := &boolValue{*t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdBoolValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &boolValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdBoolValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &boolValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdBoolValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &boolValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdBoolValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &boolValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdStringValueMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			t := ptr.asPointerTo(u.typ).Interface().(*string)
+			v := &stringValue{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			t := ptr.asPointerTo(u.typ).Interface().(*string)
+			v := &stringValue{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdStringValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*string)
+			v := &stringValue{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*string)
+			v := &stringValue{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdStringValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(string)
+				v := &stringValue{t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(string)
+				v := &stringValue{t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdStringValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*string)
+				v := &stringValue{*t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*string)
+				v := &stringValue{*t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdStringValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &stringValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdStringValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &stringValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdStringValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &stringValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdStringValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &stringValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdBytesValueMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			t := ptr.asPointerTo(u.typ).Interface().(*[]byte)
+			v := &bytesValue{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			t := ptr.asPointerTo(u.typ).Interface().(*[]byte)
+			v := &bytesValue{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdBytesValuePtrMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			if ptr.isNil() {
+				return 0
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*[]byte)
+			v := &bytesValue{*t}
+			siz := Size(v)
+			return tagsize + SizeVarint(uint64(siz)) + siz
+		}, func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			if ptr.isNil() {
+				return b, nil
+			}
+			t := ptr.asPointerTo(reflect.PtrTo(u.typ)).Elem().Interface().(*[]byte)
+			v := &bytesValue{*t}
+			buf, err := Marshal(v)
+			if err != nil {
+				return nil, err
+			}
+			b = appendVarint(b, wiretag)
+			b = appendVarint(b, uint64(len(buf)))
+			b = append(b, buf...)
+			return b, nil
+		}
+}
+
+func makeStdBytesValueSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(u.typ)
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().([]byte)
+				v := &bytesValue{t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(u.typ)
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().([]byte)
+				v := &bytesValue{t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdBytesValuePtrSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
+	return func(ptr pointer, tagsize int) int {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			n := 0
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*[]byte)
+				v := &bytesValue{*t}
+				siz := Size(v)
+				n += siz + SizeVarint(uint64(siz)) + tagsize
+			}
+			return n
+		},
+		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
+			s := ptr.getSlice(reflect.PtrTo(u.typ))
+			for i := 0; i < s.Len(); i++ {
+				elem := s.Index(i)
+				t := elem.Interface().(*[]byte)
+				v := &bytesValue{*t}
+				siz := Size(v)
+				buf, err := Marshal(v)
+				if err != nil {
+					return nil, err
+				}
+				b = appendVarint(b, wiretag)
+				b = appendVarint(b, uint64(siz))
+				b = append(b, buf...)
+			}
+
+			return b, nil
+		}
+}
+
+func makeStdBytesValueUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &bytesValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(sub.typ).Elem()
+		s.Set(reflect.ValueOf(m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdBytesValuePtrUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &bytesValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		s := f.asPointerTo(reflect.PtrTo(sub.typ)).Elem()
+		s.Set(reflect.ValueOf(&m.Value))
+		return b[x:], nil
+	}
+}
+
+func makeStdBytesValuePtrSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &bytesValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(reflect.PtrTo(sub.typ))
+		newSlice := reflect.Append(slice, reflect.ValueOf(&m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}
+
+func makeStdBytesValueSliceUnmarshaler(sub *unmarshalInfo, name string) unmarshaler {
+	return func(b []byte, f pointer, w int) ([]byte, error) {
+		if w != WireBytes {
+			return nil, errInternalBadWireType
+		}
+		x, n := decodeVarint(b)
+		if n == 0 {
+			return nil, io.ErrUnexpectedEOF
+		}
+		b = b[n:]
+		if x > uint64(len(b)) {
+			return nil, io.ErrUnexpectedEOF
+		}
+		m := &bytesValue{}
+		if err := Unmarshal(b[:x], m); err != nil {
+			return nil, err
+		}
+		slice := f.getSlice(sub.typ)
+		newSlice := reflect.Append(slice, reflect.ValueOf(m.Value))
+		slice.Set(newSlice)
+		return b[x:], nil
+	}
+}

+ 113 - 0
vendor/github.com/gogo/protobuf/proto/wrappers_gogo.go

@@ -0,0 +1,113 @@
+// Protocol Buffers for Go with Gadgets
+//
+// Copyright (c) 2018, 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 proto
+
+type float64Value struct {
+	Value float64 `protobuf:"fixed64,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *float64Value) Reset()       { *m = float64Value{} }
+func (*float64Value) ProtoMessage()  {}
+func (*float64Value) String() string { return "float64<string>" }
+
+type float32Value struct {
+	Value float32 `protobuf:"fixed32,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *float32Value) Reset()       { *m = float32Value{} }
+func (*float32Value) ProtoMessage()  {}
+func (*float32Value) String() string { return "float32<string>" }
+
+type int64Value struct {
+	Value int64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *int64Value) Reset()       { *m = int64Value{} }
+func (*int64Value) ProtoMessage()  {}
+func (*int64Value) String() string { return "int64<string>" }
+
+type uint64Value struct {
+	Value uint64 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *uint64Value) Reset()       { *m = uint64Value{} }
+func (*uint64Value) ProtoMessage()  {}
+func (*uint64Value) String() string { return "uint64<string>" }
+
+type int32Value struct {
+	Value int32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *int32Value) Reset()       { *m = int32Value{} }
+func (*int32Value) ProtoMessage()  {}
+func (*int32Value) String() string { return "int32<string>" }
+
+type uint32Value struct {
+	Value uint32 `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *uint32Value) Reset()       { *m = uint32Value{} }
+func (*uint32Value) ProtoMessage()  {}
+func (*uint32Value) String() string { return "uint32<string>" }
+
+type boolValue struct {
+	Value bool `protobuf:"varint,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *boolValue) Reset()       { *m = boolValue{} }
+func (*boolValue) ProtoMessage()  {}
+func (*boolValue) String() string { return "bool<string>" }
+
+type stringValue struct {
+	Value string `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *stringValue) Reset()       { *m = stringValue{} }
+func (*stringValue) ProtoMessage()  {}
+func (*stringValue) String() string { return "string<string>" }
+
+type bytesValue struct {
+	Value []byte `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
+}
+
+func (m *bytesValue) Reset()       { *m = bytesValue{} }
+func (*bytesValue) ProtoMessage()  {}
+func (*bytesValue) String() string { return "[]byte<string>" }
+
+func init() {
+	RegisterType((*float64Value)(nil), "gogo.protobuf.proto.DoubleValue")
+	RegisterType((*float32Value)(nil), "gogo.protobuf.proto.FloatValue")
+	RegisterType((*int64Value)(nil), "gogo.protobuf.proto.Int64Value")
+	RegisterType((*uint64Value)(nil), "gogo.protobuf.proto.UInt64Value")
+	RegisterType((*int32Value)(nil), "gogo.protobuf.proto.Int32Value")
+	RegisterType((*uint32Value)(nil), "gogo.protobuf.proto.UInt32Value")
+	RegisterType((*boolValue)(nil), "gogo.protobuf.proto.BoolValue")
+	RegisterType((*stringValue)(nil), "gogo.protobuf.proto.StringValue")
+	RegisterType((*bytesValue)(nil), "gogo.protobuf.proto.BytesValue")
+}

+ 3 - 0
vendor/github.com/golang/protobuf/AUTHORS

@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.

+ 3 - 0
vendor/github.com/golang/protobuf/CONTRIBUTORS

@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.

+ 0 - 15
vendor/github.com/golang/protobuf/proto/encode.go

@@ -37,24 +37,9 @@ package proto
 
 import (
 	"errors"
-	"fmt"
 	"reflect"
 )
 
-// RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
-// Marshal reports this when a required field is not initialized.
-// Unmarshal reports this when a required field is missing from the wire data.
-type RequiredNotSetError struct {
-	field string
-}
-
-func (e *RequiredNotSetError) Error() string {
-	if e.field == "" {
-		return fmt.Sprintf("proto: required field not set")
-	}
-	return fmt.Sprintf("proto: required field %q not set", e.field)
-}
-
 var (
 	// errRepeatedHasNil is the error returned if Marshal is called with
 	// a struct with a repeated field containing a nil element.

+ 60 - 2
vendor/github.com/golang/protobuf/proto/lib.go

@@ -265,7 +265,6 @@ package proto
 
 import (
 	"encoding/json"
-	"errors"
 	"fmt"
 	"log"
 	"reflect"
@@ -274,7 +273,66 @@ import (
 	"sync"
 )
 
-var errInvalidUTF8 = errors.New("proto: invalid UTF-8 string")
+// RequiredNotSetError is an error type returned by either Marshal or Unmarshal.
+// Marshal reports this when a required field is not initialized.
+// Unmarshal reports this when a required field is missing from the wire data.
+type RequiredNotSetError struct{ field string }
+
+func (e *RequiredNotSetError) Error() string {
+	if e.field == "" {
+		return fmt.Sprintf("proto: required field not set")
+	}
+	return fmt.Sprintf("proto: required field %q not set", e.field)
+}
+func (e *RequiredNotSetError) RequiredNotSet() bool {
+	return true
+}
+
+type invalidUTF8Error struct{ field string }
+
+func (e *invalidUTF8Error) Error() string {
+	if e.field == "" {
+		return "proto: invalid UTF-8 detected"
+	}
+	return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field)
+}
+func (e *invalidUTF8Error) InvalidUTF8() bool {
+	return true
+}
+
+// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8.
+// This error should not be exposed to the external API as such errors should
+// be recreated with the field information.
+var errInvalidUTF8 = &invalidUTF8Error{}
+
+// isNonFatal reports whether the error is either a RequiredNotSet error
+// or a InvalidUTF8 error.
+func isNonFatal(err error) bool {
+	if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() {
+		return true
+	}
+	if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() {
+		return true
+	}
+	return false
+}
+
+type nonFatal struct{ E error }
+
+// Merge merges err into nf and reports whether it was successful.
+// Otherwise it returns false for any fatal non-nil errors.
+func (nf *nonFatal) Merge(err error) (ok bool) {
+	if err == nil {
+		return true // not an error
+	}
+	if !isNonFatal(err) {
+		return false // fatal error
+	}
+	if nf.E == nil {
+		nf.E = err // store first instance of non-fatal error
+	}
+	return true
+}
 
 // Message is implemented by generated protocol buffer messages.
 type Message interface {

+ 59 - 47
vendor/github.com/golang/protobuf/proto/table_marshal.go

@@ -231,7 +231,7 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
 		return b, err
 	}
 
-	var err, errreq error
+	var err, errLater error
 	// The old marshaler encodes extensions at beginning.
 	if u.extensions.IsValid() {
 		e := ptr.offset(u.extensions).toExtensions()
@@ -252,11 +252,13 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
 		}
 	}
 	for _, f := range u.fields {
-		if f.required && errreq == nil {
+		if f.required {
 			if ptr.offset(f.field).getPointer().isNil() {
 				// Required field is not set.
 				// We record the error but keep going, to give a complete marshaling.
-				errreq = &RequiredNotSetError{f.name}
+				if errLater == nil {
+					errLater = &RequiredNotSetError{f.name}
+				}
 				continue
 			}
 		}
@@ -269,8 +271,8 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
 			if err1, ok := err.(*RequiredNotSetError); ok {
 				// Required field in submessage is not set.
 				// We record the error but keep going, to give a complete marshaling.
-				if errreq == nil {
-					errreq = &RequiredNotSetError{f.name + "." + err1.field}
+				if errLater == nil {
+					errLater = &RequiredNotSetError{f.name + "." + err1.field}
 				}
 				continue
 			}
@@ -278,8 +280,11 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
 				err = errors.New("proto: repeated field " + f.name + " has nil element")
 			}
 			if err == errInvalidUTF8 {
-				fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
-				err = fmt.Errorf("proto: string field %q contains invalid UTF-8", fullName)
+				if errLater == nil {
+					fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
+					errLater = &invalidUTF8Error{fullName}
+				}
+				continue
 			}
 			return b, err
 		}
@@ -288,7 +293,7 @@ func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte
 		s := *ptr.offset(u.unrecognized).toBytes()
 		b = append(b, s...)
 	}
-	return b, errreq
+	return b, errLater
 }
 
 // computeMarshalInfo initializes the marshal info.
@@ -2038,52 +2043,68 @@ func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, e
 	return b, nil
 }
 func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	var invalidUTF8 bool
 	v := *ptr.toString()
 	if !utf8.ValidString(v) {
-		return nil, errInvalidUTF8
+		invalidUTF8 = true
 	}
 	b = appendVarint(b, wiretag)
 	b = appendVarint(b, uint64(len(v)))
 	b = append(b, v...)
+	if invalidUTF8 {
+		return b, errInvalidUTF8
+	}
 	return b, nil
 }
 func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	var invalidUTF8 bool
 	v := *ptr.toString()
 	if v == "" {
 		return b, nil
 	}
 	if !utf8.ValidString(v) {
-		return nil, errInvalidUTF8
+		invalidUTF8 = true
 	}
 	b = appendVarint(b, wiretag)
 	b = appendVarint(b, uint64(len(v)))
 	b = append(b, v...)
+	if invalidUTF8 {
+		return b, errInvalidUTF8
+	}
 	return b, nil
 }
 func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	var invalidUTF8 bool
 	p := *ptr.toStringPtr()
 	if p == nil {
 		return b, nil
 	}
 	v := *p
 	if !utf8.ValidString(v) {
-		return nil, errInvalidUTF8
+		invalidUTF8 = true
 	}
 	b = appendVarint(b, wiretag)
 	b = appendVarint(b, uint64(len(v)))
 	b = append(b, v...)
+	if invalidUTF8 {
+		return b, errInvalidUTF8
+	}
 	return b, nil
 }
 func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
+	var invalidUTF8 bool
 	s := *ptr.toStringSlice()
 	for _, v := range s {
 		if !utf8.ValidString(v) {
-			return nil, errInvalidUTF8
+			invalidUTF8 = true
 		}
 		b = appendVarint(b, wiretag)
 		b = appendVarint(b, uint64(len(v)))
 		b = append(b, v...)
 	}
+	if invalidUTF8 {
+		return b, errInvalidUTF8
+	}
 	return b, nil
 }
 func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) {
@@ -2162,7 +2183,8 @@ func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
 		},
 		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
 			s := ptr.getPointerSlice()
-			var err, errreq error
+			var err error
+			var nerr nonFatal
 			for _, v := range s {
 				if v.isNil() {
 					return b, errRepeatedHasNil
@@ -2170,22 +2192,14 @@ func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
 				b = appendVarint(b, wiretag) // start group
 				b, err = u.marshal(b, v, deterministic)
 				b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group
-				if err != nil {
-					if _, ok := err.(*RequiredNotSetError); ok {
-						// Required field in submessage is not set.
-						// We record the error but keep going, to give a complete marshaling.
-						if errreq == nil {
-							errreq = err
-						}
-						continue
-					}
+				if !nerr.Merge(err) {
 					if err == ErrNil {
 						err = errRepeatedHasNil
 					}
 					return b, err
 				}
 			}
-			return b, errreq
+			return b, nerr.E
 		}
 }
 
@@ -2229,7 +2243,8 @@ func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
 		},
 		func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) {
 			s := ptr.getPointerSlice()
-			var err, errreq error
+			var err error
+			var nerr nonFatal
 			for _, v := range s {
 				if v.isNil() {
 					return b, errRepeatedHasNil
@@ -2239,22 +2254,14 @@ func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) {
 				b = appendVarint(b, uint64(siz))
 				b, err = u.marshal(b, v, deterministic)
 
-				if err != nil {
-					if _, ok := err.(*RequiredNotSetError); ok {
-						// Required field in submessage is not set.
-						// We record the error but keep going, to give a complete marshaling.
-						if errreq == nil {
-							errreq = err
-						}
-						continue
-					}
+				if !nerr.Merge(err) {
 					if err == ErrNil {
 						err = errRepeatedHasNil
 					}
 					return b, err
 				}
 			}
-			return b, errreq
+			return b, nerr.E
 		}
 }
 
@@ -2317,6 +2324,8 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
 			if len(keys) > 1 && deterministic {
 				sort.Sort(mapKeys(keys))
 			}
+
+			var nerr nonFatal
 			for _, k := range keys {
 				ki := k.Interface()
 				vi := m.MapIndex(k).Interface()
@@ -2326,15 +2335,15 @@ func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) {
 				siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1)
 				b = appendVarint(b, uint64(siz))
 				b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic)
-				if err != nil {
+				if !nerr.Merge(err) {
 					return b, err
 				}
 				b, err = valMarshaler(b, vaddr, valWireTag, deterministic)
-				if err != nil && err != ErrNil { // allow nil value in map
+				if err != ErrNil && !nerr.Merge(err) { // allow nil value in map
 					return b, err
 				}
 			}
-			return b, nil
+			return b, nerr.E
 		}
 }
 
@@ -2407,6 +2416,7 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
 	defer mu.Unlock()
 
 	var err error
+	var nerr nonFatal
 
 	// Fast-path for common cases: zero or one extensions.
 	// Don't bother sorting the keys.
@@ -2426,11 +2436,11 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
 			v := e.value
 			p := toAddrPointer(&v, ei.isptr)
 			b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
-			if err != nil {
+			if !nerr.Merge(err) {
 				return b, err
 			}
 		}
-		return b, nil
+		return b, nerr.E
 	}
 
 	// Sort the keys to provide a deterministic encoding.
@@ -2457,11 +2467,11 @@ func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, de
 		v := e.value
 		p := toAddrPointer(&v, ei.isptr)
 		b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
-		if err != nil {
+		if !nerr.Merge(err) {
 			return b, err
 		}
 	}
-	return b, nil
+	return b, nerr.E
 }
 
 // message set format is:
@@ -2518,6 +2528,7 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
 	defer mu.Unlock()
 
 	var err error
+	var nerr nonFatal
 
 	// Fast-path for common cases: zero or one extensions.
 	// Don't bother sorting the keys.
@@ -2544,12 +2555,12 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
 			v := e.value
 			p := toAddrPointer(&v, ei.isptr)
 			b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
-			if err != nil {
+			if !nerr.Merge(err) {
 				return b, err
 			}
 			b = append(b, 1<<3|WireEndGroup)
 		}
-		return b, nil
+		return b, nerr.E
 	}
 
 	// Sort the keys to provide a deterministic encoding.
@@ -2583,11 +2594,11 @@ func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, de
 		p := toAddrPointer(&v, ei.isptr)
 		b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic)
 		b = append(b, 1<<3|WireEndGroup)
-		if err != nil {
+		if !nerr.Merge(err) {
 			return b, err
 		}
 	}
-	return b, nil
+	return b, nerr.E
 }
 
 // sizeV1Extensions computes the size of encoded data for a V1-API extension field.
@@ -2630,6 +2641,7 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ
 	sort.Ints(keys)
 
 	var err error
+	var nerr nonFatal
 	for _, k := range keys {
 		e := m[int32(k)]
 		if e.value == nil || e.desc == nil {
@@ -2646,11 +2658,11 @@ func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, determ
 		v := e.value
 		p := toAddrPointer(&v, ei.isptr)
 		b, err = ei.marshaler(b, p, ei.wiretag, deterministic)
-		if err != nil {
+		if !nerr.Merge(err) {
 			return b, err
 		}
 	}
-	return b, nil
+	return b, nerr.E
 }
 
 // newMarshaler is the interface representing objects that can marshal themselves.

+ 26 - 23
vendor/github.com/golang/protobuf/proto/table_unmarshal.go

@@ -138,8 +138,8 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
 	if u.isMessageSet {
 		return UnmarshalMessageSet(b, m.offset(u.extensions).toExtensions())
 	}
-	var reqMask uint64            // bitmask of required fields we've seen.
-	var rnse *RequiredNotSetError // an instance of a RequiredNotSetError returned by a submessage.
+	var reqMask uint64 // bitmask of required fields we've seen.
+	var errLater error
 	for len(b) > 0 {
 		// Read tag and wire type.
 		// Special case 1 and 2 byte varints.
@@ -178,14 +178,19 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
 			if r, ok := err.(*RequiredNotSetError); ok {
 				// Remember this error, but keep parsing. We need to produce
 				// a full parse even if a required field is missing.
-				rnse = r
+				if errLater == nil {
+					errLater = r
+				}
 				reqMask |= f.reqMask
 				continue
 			}
 			if err != errInternalBadWireType {
 				if err == errInvalidUTF8 {
-					fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
-					err = fmt.Errorf("proto: string field %q contains invalid UTF-8", fullName)
+					if errLater == nil {
+						fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name
+						errLater = &invalidUTF8Error{fullName}
+					}
+					continue
 				}
 				return err
 			}
@@ -245,20 +250,16 @@ func (u *unmarshalInfo) unmarshal(m pointer, b []byte) error {
 			emap[int32(tag)] = e
 		}
 	}
-	if rnse != nil {
-		// A required field of a submessage/group is missing. Return that error.
-		return rnse
-	}
-	if reqMask != u.reqMask {
+	if reqMask != u.reqMask && errLater == nil {
 		// A required field of this message is missing.
 		for _, n := range u.reqFields {
 			if reqMask&1 == 0 {
-				return &RequiredNotSetError{n}
+				errLater = &RequiredNotSetError{n}
 			}
 			reqMask >>= 1
 		}
 	}
-	return nil
+	return errLater
 }
 
 // computeUnmarshalInfo fills in u with information for use
@@ -1529,10 +1530,10 @@ func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) {
 		return nil, io.ErrUnexpectedEOF
 	}
 	v := string(b[:x])
+	*f.toString() = v
 	if !utf8.ValidString(v) {
-		return nil, errInvalidUTF8
+		return b[x:], errInvalidUTF8
 	}
-	*f.toString() = v
 	return b[x:], nil
 }
 
@@ -1549,10 +1550,10 @@ func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) {
 		return nil, io.ErrUnexpectedEOF
 	}
 	v := string(b[:x])
+	*f.toStringPtr() = &v
 	if !utf8.ValidString(v) {
-		return nil, errInvalidUTF8
+		return b[x:], errInvalidUTF8
 	}
-	*f.toStringPtr() = &v
 	return b[x:], nil
 }
 
@@ -1569,11 +1570,11 @@ func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) {
 		return nil, io.ErrUnexpectedEOF
 	}
 	v := string(b[:x])
-	if !utf8.ValidString(v) {
-		return nil, errInvalidUTF8
-	}
 	s := f.toStringSlice()
 	*s = append(*s, v)
+	if !utf8.ValidString(v) {
+		return b[x:], errInvalidUTF8
+	}
 	return b[x:], nil
 }
 
@@ -1755,6 +1756,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
 		// Maps will be somewhat slow. Oh well.
 
 		// Read key and value from data.
+		var nerr nonFatal
 		k := reflect.New(kt)
 		v := reflect.New(vt)
 		for len(b) > 0 {
@@ -1775,7 +1777,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
 				err = errInternalBadWireType // skip unknown tag
 			}
 
-			if err == nil {
+			if nerr.Merge(err) {
 				continue
 			}
 			if err != errInternalBadWireType {
@@ -1798,7 +1800,7 @@ func makeUnmarshalMap(f *reflect.StructField) unmarshaler {
 		// Insert into map.
 		m.SetMapIndex(k.Elem(), v.Elem())
 
-		return r, nil
+		return r, nerr.E
 	}
 }
 
@@ -1824,15 +1826,16 @@ func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshal
 		// Unmarshal data into holder.
 		// We unmarshal into the first field of the holder object.
 		var err error
+		var nerr nonFatal
 		b, err = unmarshal(b, valToPointer(v).offset(field0), w)
-		if err != nil {
+		if !nerr.Merge(err) {
 			return nil, err
 		}
 
 		// Write pointer to holder into target field.
 		f.asPointerTo(ityp).Elem().Set(v)
 
-		return b, nil
+		return b, nerr.E
 	}
 }
 

+ 0 - 141
vendor/github.com/golang/protobuf/ptypes/any.go

@@ -1,141 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2016 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 ptypes
-
-// This file implements functions to marshal proto.Message to/from
-// google.protobuf.Any message.
-
-import (
-	"fmt"
-	"reflect"
-	"strings"
-
-	"github.com/golang/protobuf/proto"
-	"github.com/golang/protobuf/ptypes/any"
-)
-
-const googleApis = "type.googleapis.com/"
-
-// AnyMessageName returns the name of the message contained in a google.protobuf.Any message.
-//
-// Note that regular type assertions should be done using the Is
-// function. AnyMessageName is provided for less common use cases like filtering a
-// sequence of Any messages based on a set of allowed message type names.
-func AnyMessageName(any *any.Any) (string, error) {
-	if any == nil {
-		return "", fmt.Errorf("message is nil")
-	}
-	slash := strings.LastIndex(any.TypeUrl, "/")
-	if slash < 0 {
-		return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl)
-	}
-	return any.TypeUrl[slash+1:], nil
-}
-
-// MarshalAny takes the protocol buffer and encodes it into google.protobuf.Any.
-func MarshalAny(pb proto.Message) (*any.Any, error) {
-	value, err := proto.Marshal(pb)
-	if err != nil {
-		return nil, err
-	}
-	return &any.Any{TypeUrl: googleApis + proto.MessageName(pb), Value: value}, nil
-}
-
-// DynamicAny is a value that can be passed to UnmarshalAny to automatically
-// allocate a proto.Message for the type specified in a google.protobuf.Any
-// message. The allocated message is stored in the embedded proto.Message.
-//
-// Example:
-//
-//   var x ptypes.DynamicAny
-//   if err := ptypes.UnmarshalAny(a, &x); err != nil { ... }
-//   fmt.Printf("unmarshaled message: %v", x.Message)
-type DynamicAny struct {
-	proto.Message
-}
-
-// Empty returns a new proto.Message of the type specified in a
-// google.protobuf.Any message. It returns an error if corresponding message
-// type isn't linked in.
-func Empty(any *any.Any) (proto.Message, error) {
-	aname, err := AnyMessageName(any)
-	if err != nil {
-		return nil, err
-	}
-
-	t := proto.MessageType(aname)
-	if t == nil {
-		return nil, fmt.Errorf("any: message type %q isn't linked in", aname)
-	}
-	return reflect.New(t.Elem()).Interface().(proto.Message), nil
-}
-
-// UnmarshalAny parses the protocol buffer representation in a google.protobuf.Any
-// message and places the decoded result in pb. It returns an error if type of
-// contents of Any message does not match type of pb message.
-//
-// pb can be a proto.Message, or a *DynamicAny.
-func UnmarshalAny(any *any.Any, pb proto.Message) error {
-	if d, ok := pb.(*DynamicAny); ok {
-		if d.Message == nil {
-			var err error
-			d.Message, err = Empty(any)
-			if err != nil {
-				return err
-			}
-		}
-		return UnmarshalAny(any, d.Message)
-	}
-
-	aname, err := AnyMessageName(any)
-	if err != nil {
-		return err
-	}
-
-	mname := proto.MessageName(pb)
-	if aname != mname {
-		return fmt.Errorf("mismatched message type: got %q want %q", aname, mname)
-	}
-	return proto.Unmarshal(any.Value, pb)
-}
-
-// Is returns true if any value contains a given message type.
-func Is(any *any.Any, pb proto.Message) bool {
-	// The following is equivalent to AnyMessageName(any) == proto.MessageName(pb),
-	// but it avoids scanning TypeUrl for the slash.
-	if any == nil {
-		return false
-	}
-	name := proto.MessageName(pb)
-	prefix := len(any.TypeUrl) - len(name)
-	return prefix >= 1 && any.TypeUrl[prefix-1] == '/' && any.TypeUrl[prefix:] == name
-}

+ 0 - 191
vendor/github.com/golang/protobuf/ptypes/any/any.pb.go

@@ -1,191 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: google/protobuf/any.proto
-
-package any // import "github.com/golang/protobuf/ptypes/any"
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import 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.ProtoPackageIsVersion2 // please upgrade the proto package
-
-// `Any` contains an arbitrary serialized protocol buffer message along with a
-// URL that describes the type of the serialized message.
-//
-// Protobuf library provides support to pack/unpack Any values in the form
-// of utility functions or additional generated methods of the Any type.
-//
-// Example 1: Pack and unpack a message in C++.
-//
-//     Foo foo = ...;
-//     Any any;
-//     any.PackFrom(foo);
-//     ...
-//     if (any.UnpackTo(&foo)) {
-//       ...
-//     }
-//
-// Example 2: Pack and unpack a message in Java.
-//
-//     Foo foo = ...;
-//     Any any = Any.pack(foo);
-//     ...
-//     if (any.is(Foo.class)) {
-//       foo = any.unpack(Foo.class);
-//     }
-//
-//  Example 3: Pack and unpack a message in Python.
-//
-//     foo = Foo(...)
-//     any = Any()
-//     any.Pack(foo)
-//     ...
-//     if any.Is(Foo.DESCRIPTOR):
-//       any.Unpack(foo)
-//       ...
-//
-//  Example 4: Pack and unpack a message in Go
-//
-//      foo := &pb.Foo{...}
-//      any, err := ptypes.MarshalAny(foo)
-//      ...
-//      foo := &pb.Foo{}
-//      if err := ptypes.UnmarshalAny(any, foo); err != nil {
-//        ...
-//      }
-//
-// The pack methods provided by protobuf library will by default use
-// 'type.googleapis.com/full.type.name' as the type URL and the unpack
-// methods only use the fully qualified type name after the last '/'
-// in the type URL, for example "foo.bar.com/x/y.z" will yield type
-// name "y.z".
-//
-//
-// JSON
-// ====
-// The JSON representation of an `Any` value uses the regular
-// representation of the deserialized, embedded message, with an
-// additional field `@type` which contains the type URL. Example:
-//
-//     package google.profile;
-//     message Person {
-//       string first_name = 1;
-//       string last_name = 2;
-//     }
-//
-//     {
-//       "@type": "type.googleapis.com/google.profile.Person",
-//       "firstName": <string>,
-//       "lastName": <string>
-//     }
-//
-// If the embedded message type is well-known and has a custom JSON
-// representation, that representation will be embedded adding a field
-// `value` which holds the custom JSON in addition to the `@type`
-// field. Example (for message [google.protobuf.Duration][]):
-//
-//     {
-//       "@type": "type.googleapis.com/google.protobuf.Duration",
-//       "value": "1.212s"
-//     }
-//
-type Any struct {
-	// A URL/resource name whose content describes the type of the
-	// serialized protocol buffer message.
-	//
-	// For URLs which use the scheme `http`, `https`, or no scheme, the
-	// following restrictions and interpretations apply:
-	//
-	// * If no scheme is provided, `https` is assumed.
-	// * The last segment of the URL's path must represent the fully
-	//   qualified name of the type (as in `path/google.protobuf.Duration`).
-	//   The name should be in a canonical form (e.g., leading "." is
-	//   not accepted).
-	// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-	//   value in binary format, or produce an error.
-	// * Applications are allowed to cache lookup results based on the
-	//   URL, or have them precompiled into a binary to avoid any
-	//   lookup. Therefore, binary compatibility needs to be preserved
-	//   on changes to types. (Use versioned type names to manage
-	//   breaking changes.)
-	//
-	// Schemes other than `http`, `https` (or the empty scheme) might be
-	// used with implementation specific semantics.
-	//
-	TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"`
-	// Must be a valid serialized protocol buffer of the above specified type.
-	Value                []byte   `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *Any) Reset()         { *m = Any{} }
-func (m *Any) String() string { return proto.CompactTextString(m) }
-func (*Any) ProtoMessage()    {}
-func (*Any) Descriptor() ([]byte, []int) {
-	return fileDescriptor_any_744b9ca530f228db, []int{0}
-}
-func (*Any) XXX_WellKnownType() string { return "Any" }
-func (m *Any) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Any.Unmarshal(m, b)
-}
-func (m *Any) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Any.Marshal(b, m, deterministic)
-}
-func (dst *Any) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Any.Merge(dst, src)
-}
-func (m *Any) XXX_Size() int {
-	return xxx_messageInfo_Any.Size(m)
-}
-func (m *Any) XXX_DiscardUnknown() {
-	xxx_messageInfo_Any.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Any proto.InternalMessageInfo
-
-func (m *Any) GetTypeUrl() string {
-	if m != nil {
-		return m.TypeUrl
-	}
-	return ""
-}
-
-func (m *Any) GetValue() []byte {
-	if m != nil {
-		return m.Value
-	}
-	return nil
-}
-
-func init() {
-	proto.RegisterType((*Any)(nil), "google.protobuf.Any")
-}
-
-func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_any_744b9ca530f228db) }
-
-var fileDescriptor_any_744b9ca530f228db = []byte{
-	// 185 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0xcf, 0xcf, 0x4f,
-	0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcc, 0xab, 0xd4,
-	0x03, 0x73, 0x84, 0xf8, 0x21, 0x52, 0x7a, 0x30, 0x29, 0x25, 0x33, 0x2e, 0x66, 0xc7, 0xbc, 0x4a,
-	0x21, 0x49, 0x2e, 0x8e, 0x92, 0xca, 0x82, 0xd4, 0xf8, 0xd2, 0xa2, 0x1c, 0x09, 0x46, 0x05, 0x46,
-	0x0d, 0xce, 0x20, 0x76, 0x10, 0x3f, 0xb4, 0x28, 0x47, 0x48, 0x84, 0x8b, 0xb5, 0x2c, 0x31, 0xa7,
-	0x34, 0x55, 0x82, 0x49, 0x81, 0x51, 0x83, 0x27, 0x08, 0xc2, 0x71, 0xca, 0xe7, 0x12, 0x4e, 0xce,
-	0xcf, 0xd5, 0x43, 0x33, 0xce, 0x89, 0xc3, 0x31, 0xaf, 0x32, 0x00, 0xc4, 0x09, 0x60, 0x8c, 0x52,
-	0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc,
-	0x4b, 0x47, 0xb8, 0xa8, 0x00, 0x64, 0x7a, 0x31, 0xc8, 0x61, 0x8b, 0x98, 0x98, 0xdd, 0x03, 0x9c,
-	0x56, 0x31, 0xc9, 0xb9, 0x43, 0x8c, 0x0a, 0x80, 0x2a, 0xd1, 0x0b, 0x4f, 0xcd, 0xc9, 0xf1, 0xce,
-	0xcb, 0x2f, 0xcf, 0x0b, 0x01, 0x29, 0x4d, 0x62, 0x03, 0xeb, 0x35, 0x06, 0x04, 0x00, 0x00, 0xff,
-	0xff, 0x13, 0xf8, 0xe8, 0x42, 0xdd, 0x00, 0x00, 0x00,
-}

+ 0 - 149
vendor/github.com/golang/protobuf/ptypes/any/any.proto

@@ -1,149 +0,0 @@
-// 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.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option go_package = "github.com/golang/protobuf/ptypes/any";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "AnyProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-// `Any` contains an arbitrary serialized protocol buffer message along with a
-// URL that describes the type of the serialized message.
-//
-// Protobuf library provides support to pack/unpack Any values in the form
-// of utility functions or additional generated methods of the Any type.
-//
-// Example 1: Pack and unpack a message in C++.
-//
-//     Foo foo = ...;
-//     Any any;
-//     any.PackFrom(foo);
-//     ...
-//     if (any.UnpackTo(&foo)) {
-//       ...
-//     }
-//
-// Example 2: Pack and unpack a message in Java.
-//
-//     Foo foo = ...;
-//     Any any = Any.pack(foo);
-//     ...
-//     if (any.is(Foo.class)) {
-//       foo = any.unpack(Foo.class);
-//     }
-//
-//  Example 3: Pack and unpack a message in Python.
-//
-//     foo = Foo(...)
-//     any = Any()
-//     any.Pack(foo)
-//     ...
-//     if any.Is(Foo.DESCRIPTOR):
-//       any.Unpack(foo)
-//       ...
-//
-//  Example 4: Pack and unpack a message in Go
-//
-//      foo := &pb.Foo{...}
-//      any, err := ptypes.MarshalAny(foo)
-//      ...
-//      foo := &pb.Foo{}
-//      if err := ptypes.UnmarshalAny(any, foo); err != nil {
-//        ...
-//      }
-//
-// The pack methods provided by protobuf library will by default use
-// 'type.googleapis.com/full.type.name' as the type URL and the unpack
-// methods only use the fully qualified type name after the last '/'
-// in the type URL, for example "foo.bar.com/x/y.z" will yield type
-// name "y.z".
-//
-//
-// JSON
-// ====
-// The JSON representation of an `Any` value uses the regular
-// representation of the deserialized, embedded message, with an
-// additional field `@type` which contains the type URL. Example:
-//
-//     package google.profile;
-//     message Person {
-//       string first_name = 1;
-//       string last_name = 2;
-//     }
-//
-//     {
-//       "@type": "type.googleapis.com/google.profile.Person",
-//       "firstName": <string>,
-//       "lastName": <string>
-//     }
-//
-// If the embedded message type is well-known and has a custom JSON
-// representation, that representation will be embedded adding a field
-// `value` which holds the custom JSON in addition to the `@type`
-// field. Example (for message [google.protobuf.Duration][]):
-//
-//     {
-//       "@type": "type.googleapis.com/google.protobuf.Duration",
-//       "value": "1.212s"
-//     }
-//
-message Any {
-  // A URL/resource name whose content describes the type of the
-  // serialized protocol buffer message.
-  //
-  // For URLs which use the scheme `http`, `https`, or no scheme, the
-  // following restrictions and interpretations apply:
-  //
-  // * If no scheme is provided, `https` is assumed.
-  // * The last segment of the URL's path must represent the fully
-  //   qualified name of the type (as in `path/google.protobuf.Duration`).
-  //   The name should be in a canonical form (e.g., leading "." is
-  //   not accepted).
-  // * An HTTP GET on the URL must yield a [google.protobuf.Type][]
-  //   value in binary format, or produce an error.
-  // * Applications are allowed to cache lookup results based on the
-  //   URL, or have them precompiled into a binary to avoid any
-  //   lookup. Therefore, binary compatibility needs to be preserved
-  //   on changes to types. (Use versioned type names to manage
-  //   breaking changes.)
-  //
-  // Schemes other than `http`, `https` (or the empty scheme) might be
-  // used with implementation specific semantics.
-  //
-  string type_url = 1;
-
-  // Must be a valid serialized protocol buffer of the above specified type.
-  bytes value = 2;
-}

+ 0 - 102
vendor/github.com/golang/protobuf/ptypes/duration.go

@@ -1,102 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2016 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 ptypes
-
-// This file implements conversions between google.protobuf.Duration
-// and time.Duration.
-
-import (
-	"errors"
-	"fmt"
-	"time"
-
-	durpb "github.com/golang/protobuf/ptypes/duration"
-)
-
-const (
-	// Range of a durpb.Duration in seconds, as specified in
-	// google/protobuf/duration.proto. This is about 10,000 years in seconds.
-	maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60)
-	minSeconds = -maxSeconds
-)
-
-// validateDuration determines whether the durpb.Duration is valid according to the
-// definition in google/protobuf/duration.proto. A valid durpb.Duration
-// may still be too large to fit into a time.Duration (the range of durpb.Duration
-// is about 10,000 years, and the range of time.Duration is about 290).
-func validateDuration(d *durpb.Duration) error {
-	if d == nil {
-		return errors.New("duration: nil Duration")
-	}
-	if d.Seconds < minSeconds || d.Seconds > maxSeconds {
-		return fmt.Errorf("duration: %v: seconds out of range", d)
-	}
-	if d.Nanos <= -1e9 || d.Nanos >= 1e9 {
-		return fmt.Errorf("duration: %v: nanos out of range", d)
-	}
-	// Seconds and Nanos must have the same sign, unless d.Nanos is zero.
-	if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) {
-		return fmt.Errorf("duration: %v: seconds and nanos have different signs", d)
-	}
-	return nil
-}
-
-// Duration converts a durpb.Duration to a time.Duration. Duration
-// returns an error if the durpb.Duration is invalid or is too large to be
-// represented in a time.Duration.
-func Duration(p *durpb.Duration) (time.Duration, error) {
-	if err := validateDuration(p); err != nil {
-		return 0, err
-	}
-	d := time.Duration(p.Seconds) * time.Second
-	if int64(d/time.Second) != p.Seconds {
-		return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
-	}
-	if p.Nanos != 0 {
-		d += time.Duration(p.Nanos)
-		if (d < 0) != (p.Nanos < 0) {
-			return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p)
-		}
-	}
-	return d, nil
-}
-
-// DurationProto converts a time.Duration to a durpb.Duration.
-func DurationProto(d time.Duration) *durpb.Duration {
-	nanos := d.Nanoseconds()
-	secs := nanos / 1e9
-	nanos -= secs * 1e9
-	return &durpb.Duration{
-		Seconds: secs,
-		Nanos:   int32(nanos),
-	}
-}

+ 0 - 159
vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go

@@ -1,159 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: google/protobuf/duration.proto
-
-package duration // import "github.com/golang/protobuf/ptypes/duration"
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import 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.ProtoPackageIsVersion2 // please upgrade the proto package
-
-// A Duration represents a signed, fixed-length span of time represented
-// as a count of seconds and fractions of seconds at nanosecond
-// resolution. It is independent of any calendar and concepts like "day"
-// or "month". It is related to Timestamp in that the difference between
-// two Timestamp values is a Duration and it can be added or subtracted
-// from a Timestamp. Range is approximately +-10,000 years.
-//
-// # Examples
-//
-// Example 1: Compute Duration from two Timestamps in pseudo code.
-//
-//     Timestamp start = ...;
-//     Timestamp end = ...;
-//     Duration duration = ...;
-//
-//     duration.seconds = end.seconds - start.seconds;
-//     duration.nanos = end.nanos - start.nanos;
-//
-//     if (duration.seconds < 0 && duration.nanos > 0) {
-//       duration.seconds += 1;
-//       duration.nanos -= 1000000000;
-//     } else if (durations.seconds > 0 && duration.nanos < 0) {
-//       duration.seconds -= 1;
-//       duration.nanos += 1000000000;
-//     }
-//
-// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
-//
-//     Timestamp start = ...;
-//     Duration duration = ...;
-//     Timestamp end = ...;
-//
-//     end.seconds = start.seconds + duration.seconds;
-//     end.nanos = start.nanos + duration.nanos;
-//
-//     if (end.nanos < 0) {
-//       end.seconds -= 1;
-//       end.nanos += 1000000000;
-//     } else if (end.nanos >= 1000000000) {
-//       end.seconds += 1;
-//       end.nanos -= 1000000000;
-//     }
-//
-// Example 3: Compute Duration from datetime.timedelta in Python.
-//
-//     td = datetime.timedelta(days=3, minutes=10)
-//     duration = Duration()
-//     duration.FromTimedelta(td)
-//
-// # JSON Mapping
-//
-// In JSON format, the Duration type is encoded as a string rather than an
-// object, where the string ends in the suffix "s" (indicating seconds) and
-// is preceded by the number of seconds, with nanoseconds expressed as
-// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
-// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
-// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
-// microsecond should be expressed in JSON format as "3.000001s".
-//
-//
-type Duration struct {
-	// Signed seconds of the span of time. Must be from -315,576,000,000
-	// to +315,576,000,000 inclusive. Note: these bounds are computed from:
-	// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-	Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
-	// Signed fractions of a second at nanosecond resolution of the span
-	// of time. Durations less than one second are represented with a 0
-	// `seconds` field and a positive or negative `nanos` field. For durations
-	// of one second or more, a non-zero value for the `nanos` field must be
-	// of the same sign as the `seconds` field. Must be from -999,999,999
-	// to +999,999,999 inclusive.
-	Nanos                int32    `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *Duration) Reset()         { *m = Duration{} }
-func (m *Duration) String() string { return proto.CompactTextString(m) }
-func (*Duration) ProtoMessage()    {}
-func (*Duration) Descriptor() ([]byte, []int) {
-	return fileDescriptor_duration_e7d612259e3f0613, []int{0}
-}
-func (*Duration) XXX_WellKnownType() string { return "Duration" }
-func (m *Duration) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Duration.Unmarshal(m, b)
-}
-func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Duration.Marshal(b, m, deterministic)
-}
-func (dst *Duration) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Duration.Merge(dst, src)
-}
-func (m *Duration) XXX_Size() int {
-	return xxx_messageInfo_Duration.Size(m)
-}
-func (m *Duration) XXX_DiscardUnknown() {
-	xxx_messageInfo_Duration.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Duration proto.InternalMessageInfo
-
-func (m *Duration) GetSeconds() int64 {
-	if m != nil {
-		return m.Seconds
-	}
-	return 0
-}
-
-func (m *Duration) GetNanos() int32 {
-	if m != nil {
-		return m.Nanos
-	}
-	return 0
-}
-
-func init() {
-	proto.RegisterType((*Duration)(nil), "google.protobuf.Duration")
-}
-
-func init() {
-	proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_duration_e7d612259e3f0613)
-}
-
-var fileDescriptor_duration_e7d612259e3f0613 = []byte{
-	// 190 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f,
-	0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0x29, 0x2d, 0x4a,
-	0x2c, 0xc9, 0xcc, 0xcf, 0xd3, 0x03, 0x8b, 0x08, 0xf1, 0x43, 0xe4, 0xf5, 0x60, 0xf2, 0x4a, 0x56,
-	0x5c, 0x1c, 0x2e, 0x50, 0x25, 0x42, 0x12, 0x5c, 0xec, 0xc5, 0xa9, 0xc9, 0xf9, 0x79, 0x29, 0xc5,
-	0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x30, 0xae, 0x90, 0x08, 0x17, 0x6b, 0x5e, 0x62, 0x5e,
-	0x7e, 0xb1, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0x84, 0xe3, 0x54, 0xc3, 0x25, 0x9c, 0x9c,
-	0x9f, 0xab, 0x87, 0x66, 0xa4, 0x13, 0x2f, 0xcc, 0xc0, 0x00, 0x90, 0x48, 0x00, 0x63, 0x94, 0x56,
-	0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x7a, 0x7e, 0x4e, 0x62, 0x5e,
-	0x3a, 0xc2, 0x7d, 0x05, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x70, 0x67, 0xfe, 0x60, 0x64, 0x5c, 0xc4,
-	0xc4, 0xec, 0x1e, 0xe0, 0xb4, 0x8a, 0x49, 0xce, 0x1d, 0x62, 0x6e, 0x00, 0x54, 0xa9, 0x5e, 0x78,
-	0x6a, 0x4e, 0x8e, 0x77, 0x5e, 0x7e, 0x79, 0x5e, 0x08, 0x48, 0x4b, 0x12, 0x1b, 0xd8, 0x0c, 0x63,
-	0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x84, 0x30, 0xff, 0xf3, 0x00, 0x00, 0x00,
-}

+ 0 - 117
vendor/github.com/golang/protobuf/ptypes/duration/duration.proto

@@ -1,117 +0,0 @@
-// 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.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option cc_enable_arenas = true;
-option go_package = "github.com/golang/protobuf/ptypes/duration";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "DurationProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-// A Duration represents a signed, fixed-length span of time represented
-// as a count of seconds and fractions of seconds at nanosecond
-// resolution. It is independent of any calendar and concepts like "day"
-// or "month". It is related to Timestamp in that the difference between
-// two Timestamp values is a Duration and it can be added or subtracted
-// from a Timestamp. Range is approximately +-10,000 years.
-//
-// # Examples
-//
-// Example 1: Compute Duration from two Timestamps in pseudo code.
-//
-//     Timestamp start = ...;
-//     Timestamp end = ...;
-//     Duration duration = ...;
-//
-//     duration.seconds = end.seconds - start.seconds;
-//     duration.nanos = end.nanos - start.nanos;
-//
-//     if (duration.seconds < 0 && duration.nanos > 0) {
-//       duration.seconds += 1;
-//       duration.nanos -= 1000000000;
-//     } else if (durations.seconds > 0 && duration.nanos < 0) {
-//       duration.seconds -= 1;
-//       duration.nanos += 1000000000;
-//     }
-//
-// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
-//
-//     Timestamp start = ...;
-//     Duration duration = ...;
-//     Timestamp end = ...;
-//
-//     end.seconds = start.seconds + duration.seconds;
-//     end.nanos = start.nanos + duration.nanos;
-//
-//     if (end.nanos < 0) {
-//       end.seconds -= 1;
-//       end.nanos += 1000000000;
-//     } else if (end.nanos >= 1000000000) {
-//       end.seconds += 1;
-//       end.nanos -= 1000000000;
-//     }
-//
-// Example 3: Compute Duration from datetime.timedelta in Python.
-//
-//     td = datetime.timedelta(days=3, minutes=10)
-//     duration = Duration()
-//     duration.FromTimedelta(td)
-//
-// # JSON Mapping
-//
-// In JSON format, the Duration type is encoded as a string rather than an
-// object, where the string ends in the suffix "s" (indicating seconds) and
-// is preceded by the number of seconds, with nanoseconds expressed as
-// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
-// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
-// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
-// microsecond should be expressed in JSON format as "3.000001s".
-//
-//
-message Duration {
-
-  // Signed seconds of the span of time. Must be from -315,576,000,000
-  // to +315,576,000,000 inclusive. Note: these bounds are computed from:
-  // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
-  int64 seconds = 1;
-
-  // Signed fractions of a second at nanosecond resolution of the span
-  // of time. Durations less than one second are represented with a 0
-  // `seconds` field and a positive or negative `nanos` field. For durations
-  // of one second or more, a non-zero value for the `nanos` field must be
-  // of the same sign as the `seconds` field. Must be from -999,999,999
-  // to +999,999,999 inclusive.
-  int32 nanos = 2;
-}

+ 0 - 134
vendor/github.com/golang/protobuf/ptypes/timestamp.go

@@ -1,134 +0,0 @@
-// Go support for Protocol Buffers - Google's data interchange format
-//
-// Copyright 2016 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 ptypes
-
-// This file implements operations on google.protobuf.Timestamp.
-
-import (
-	"errors"
-	"fmt"
-	"time"
-
-	tspb "github.com/golang/protobuf/ptypes/timestamp"
-)
-
-const (
-	// Seconds field of the earliest valid Timestamp.
-	// This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
-	minValidSeconds = -62135596800
-	// Seconds field just after the latest valid Timestamp.
-	// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
-	maxValidSeconds = 253402300800
-)
-
-// validateTimestamp determines whether a Timestamp is valid.
-// A valid timestamp represents a time in the range
-// [0001-01-01, 10000-01-01) and has a Nanos field
-// in the range [0, 1e9).
-//
-// If the Timestamp is valid, validateTimestamp returns nil.
-// Otherwise, it returns an error that describes
-// the problem.
-//
-// Every valid Timestamp can be represented by a time.Time, but the converse is not true.
-func validateTimestamp(ts *tspb.Timestamp) error {
-	if ts == nil {
-		return errors.New("timestamp: nil Timestamp")
-	}
-	if ts.Seconds < minValidSeconds {
-		return fmt.Errorf("timestamp: %v before 0001-01-01", ts)
-	}
-	if ts.Seconds >= maxValidSeconds {
-		return fmt.Errorf("timestamp: %v after 10000-01-01", ts)
-	}
-	if ts.Nanos < 0 || ts.Nanos >= 1e9 {
-		return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts)
-	}
-	return nil
-}
-
-// Timestamp converts a google.protobuf.Timestamp proto to a time.Time.
-// It returns an error if the argument is invalid.
-//
-// Unlike most Go functions, if Timestamp returns an error, the first return value
-// is not the zero time.Time. Instead, it is the value obtained from the
-// time.Unix function when passed the contents of the Timestamp, in the UTC
-// locale. This may or may not be a meaningful time; many invalid Timestamps
-// do map to valid time.Times.
-//
-// A nil Timestamp returns an error. The first return value in that case is
-// undefined.
-func Timestamp(ts *tspb.Timestamp) (time.Time, error) {
-	// Don't return the zero value on error, because corresponds to a valid
-	// timestamp. Instead return whatever time.Unix gives us.
-	var t time.Time
-	if ts == nil {
-		t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
-	} else {
-		t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC()
-	}
-	return t, validateTimestamp(ts)
-}
-
-// TimestampNow returns a google.protobuf.Timestamp for the current time.
-func TimestampNow() *tspb.Timestamp {
-	ts, err := TimestampProto(time.Now())
-	if err != nil {
-		panic("ptypes: time.Now() out of Timestamp range")
-	}
-	return ts
-}
-
-// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
-// It returns an error if the resulting Timestamp is invalid.
-func TimestampProto(t time.Time) (*tspb.Timestamp, error) {
-	seconds := t.Unix()
-	nanos := int32(t.Sub(time.Unix(seconds, 0)))
-	ts := &tspb.Timestamp{
-		Seconds: seconds,
-		Nanos:   nanos,
-	}
-	if err := validateTimestamp(ts); err != nil {
-		return nil, err
-	}
-	return ts, nil
-}
-
-// TimestampString returns the RFC 3339 string for valid Timestamps. For invalid
-// Timestamps, it returns an error message in parentheses.
-func TimestampString(ts *tspb.Timestamp) string {
-	t, err := Timestamp(ts)
-	if err != nil {
-		return fmt.Sprintf("(%v)", err)
-	}
-	return t.Format(time.RFC3339Nano)
-}

+ 0 - 175
vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go

@@ -1,175 +0,0 @@
-// Code generated by protoc-gen-go. DO NOT EDIT.
-// source: google/protobuf/timestamp.proto
-
-package timestamp // import "github.com/golang/protobuf/ptypes/timestamp"
-
-import proto "github.com/golang/protobuf/proto"
-import fmt "fmt"
-import 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.ProtoPackageIsVersion2 // please upgrade the proto package
-
-// A Timestamp represents a point in time independent of any time zone
-// or calendar, represented as seconds and fractions of seconds at
-// nanosecond resolution in UTC Epoch time. It is encoded using the
-// Proleptic Gregorian Calendar which extends the Gregorian calendar
-// backwards to year one. It is encoded assuming all minutes are 60
-// seconds long, i.e. leap seconds are "smeared" so that no leap second
-// table is needed for interpretation. Range is from
-// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
-// By restricting to that range, we ensure that we can convert to
-// and from  RFC 3339 date strings.
-// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
-//
-// # Examples
-//
-// Example 1: Compute Timestamp from POSIX `time()`.
-//
-//     Timestamp timestamp;
-//     timestamp.set_seconds(time(NULL));
-//     timestamp.set_nanos(0);
-//
-// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
-//
-//     struct timeval tv;
-//     gettimeofday(&tv, NULL);
-//
-//     Timestamp timestamp;
-//     timestamp.set_seconds(tv.tv_sec);
-//     timestamp.set_nanos(tv.tv_usec * 1000);
-//
-// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
-//
-//     FILETIME ft;
-//     GetSystemTimeAsFileTime(&ft);
-//     UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
-//
-//     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
-//     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
-//     Timestamp timestamp;
-//     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
-//     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
-//
-// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
-//
-//     long millis = System.currentTimeMillis();
-//
-//     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
-//         .setNanos((int) ((millis % 1000) * 1000000)).build();
-//
-//
-// Example 5: Compute Timestamp from current time in Python.
-//
-//     timestamp = Timestamp()
-//     timestamp.GetCurrentTime()
-//
-// # JSON Mapping
-//
-// In JSON format, the Timestamp type is encoded as a string in the
-// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
-// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
-// where {year} is always expressed using four digits while {month}, {day},
-// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
-// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
-// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
-// is required, though only UTC (as indicated by "Z") is presently supported.
-//
-// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
-// 01:30 UTC on January 15, 2017.
-//
-// In JavaScript, one can convert a Date object to this format using the
-// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString]
-// method. In Python, a standard `datetime.datetime` object can be converted
-// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
-// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
-// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
-// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--)
-// to obtain a formatter capable of generating timestamps in this format.
-//
-//
-type Timestamp struct {
-	// Represents seconds of UTC time since Unix epoch
-	// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
-	// 9999-12-31T23:59:59Z inclusive.
-	Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"`
-	// Non-negative fractions of a second at nanosecond resolution. Negative
-	// second values with fractions must still have non-negative nanos values
-	// that count forward in time. Must be from 0 to 999,999,999
-	// inclusive.
-	Nanos                int32    `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"`
-	XXX_NoUnkeyedLiteral struct{} `json:"-"`
-	XXX_unrecognized     []byte   `json:"-"`
-	XXX_sizecache        int32    `json:"-"`
-}
-
-func (m *Timestamp) Reset()         { *m = Timestamp{} }
-func (m *Timestamp) String() string { return proto.CompactTextString(m) }
-func (*Timestamp) ProtoMessage()    {}
-func (*Timestamp) Descriptor() ([]byte, []int) {
-	return fileDescriptor_timestamp_b826e8e5fba671a8, []int{0}
-}
-func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" }
-func (m *Timestamp) XXX_Unmarshal(b []byte) error {
-	return xxx_messageInfo_Timestamp.Unmarshal(m, b)
-}
-func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
-	return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic)
-}
-func (dst *Timestamp) XXX_Merge(src proto.Message) {
-	xxx_messageInfo_Timestamp.Merge(dst, src)
-}
-func (m *Timestamp) XXX_Size() int {
-	return xxx_messageInfo_Timestamp.Size(m)
-}
-func (m *Timestamp) XXX_DiscardUnknown() {
-	xxx_messageInfo_Timestamp.DiscardUnknown(m)
-}
-
-var xxx_messageInfo_Timestamp proto.InternalMessageInfo
-
-func (m *Timestamp) GetSeconds() int64 {
-	if m != nil {
-		return m.Seconds
-	}
-	return 0
-}
-
-func (m *Timestamp) GetNanos() int32 {
-	if m != nil {
-		return m.Nanos
-	}
-	return 0
-}
-
-func init() {
-	proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp")
-}
-
-func init() {
-	proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_timestamp_b826e8e5fba671a8)
-}
-
-var fileDescriptor_timestamp_b826e8e5fba671a8 = []byte{
-	// 191 bytes of a gzipped FileDescriptorProto
-	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xcf, 0xcf, 0x4f,
-	0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d,
-	0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0xd0, 0x03, 0x0b, 0x09, 0xf1, 0x43, 0x14, 0xe8, 0xc1, 0x14, 0x28,
-	0x59, 0x73, 0x71, 0x86, 0xc0, 0xd4, 0x08, 0x49, 0x70, 0xb1, 0x17, 0xa7, 0x26, 0xe7, 0xe7, 0xa5,
-	0x14, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0x30, 0x07, 0xc1, 0xb8, 0x42, 0x22, 0x5c, 0xac, 0x79, 0x89,
-	0x79, 0xf9, 0xc5, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xac, 0x41, 0x10, 0x8e, 0x53, 0x1d, 0x97, 0x70,
-	0x72, 0x7e, 0xae, 0x1e, 0x9a, 0x99, 0x4e, 0x7c, 0x70, 0x13, 0x03, 0x40, 0x42, 0x01, 0x8c, 0x51,
-	0xda, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xe9, 0xf9, 0x39, 0x89,
-	0x79, 0xe9, 0x08, 0x27, 0x16, 0x94, 0x54, 0x16, 0xa4, 0x16, 0x23, 0x5c, 0xfa, 0x83, 0x91, 0x71,
-	0x11, 0x13, 0xb3, 0x7b, 0x80, 0xd3, 0x2a, 0x26, 0x39, 0x77, 0x88, 0xc9, 0x01, 0x50, 0xb5, 0x7a,
-	0xe1, 0xa9, 0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5, 0x79, 0x21, 0x20, 0x3d, 0x49, 0x6c, 0x60, 0x43,
-	0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x77, 0x4a, 0x07, 0xf7, 0x00, 0x00, 0x00,
-}

+ 0 - 133
vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto

@@ -1,133 +0,0 @@
-// 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.
-
-syntax = "proto3";
-
-package google.protobuf;
-
-option csharp_namespace = "Google.Protobuf.WellKnownTypes";
-option cc_enable_arenas = true;
-option go_package = "github.com/golang/protobuf/ptypes/timestamp";
-option java_package = "com.google.protobuf";
-option java_outer_classname = "TimestampProto";
-option java_multiple_files = true;
-option objc_class_prefix = "GPB";
-
-// A Timestamp represents a point in time independent of any time zone
-// or calendar, represented as seconds and fractions of seconds at
-// nanosecond resolution in UTC Epoch time. It is encoded using the
-// Proleptic Gregorian Calendar which extends the Gregorian calendar
-// backwards to year one. It is encoded assuming all minutes are 60
-// seconds long, i.e. leap seconds are "smeared" so that no leap second
-// table is needed for interpretation. Range is from
-// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
-// By restricting to that range, we ensure that we can convert to
-// and from  RFC 3339 date strings.
-// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
-//
-// # Examples
-//
-// Example 1: Compute Timestamp from POSIX `time()`.
-//
-//     Timestamp timestamp;
-//     timestamp.set_seconds(time(NULL));
-//     timestamp.set_nanos(0);
-//
-// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
-//
-//     struct timeval tv;
-//     gettimeofday(&tv, NULL);
-//
-//     Timestamp timestamp;
-//     timestamp.set_seconds(tv.tv_sec);
-//     timestamp.set_nanos(tv.tv_usec * 1000);
-//
-// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
-//
-//     FILETIME ft;
-//     GetSystemTimeAsFileTime(&ft);
-//     UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
-//
-//     // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
-//     // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
-//     Timestamp timestamp;
-//     timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
-//     timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
-//
-// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
-//
-//     long millis = System.currentTimeMillis();
-//
-//     Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
-//         .setNanos((int) ((millis % 1000) * 1000000)).build();
-//
-//
-// Example 5: Compute Timestamp from current time in Python.
-//
-//     timestamp = Timestamp()
-//     timestamp.GetCurrentTime()
-//
-// # JSON Mapping
-//
-// In JSON format, the Timestamp type is encoded as a string in the
-// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
-// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
-// where {year} is always expressed using four digits while {month}, {day},
-// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
-// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
-// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
-// is required, though only UTC (as indicated by "Z") is presently supported.
-//
-// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
-// 01:30 UTC on January 15, 2017.
-//
-// In JavaScript, one can convert a Date object to this format using the
-// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString]
-// method. In Python, a standard `datetime.datetime` object can be converted
-// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
-// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
-// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
-// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--)
-// to obtain a formatter capable of generating timestamps in this format.
-//
-//
-message Timestamp {
-
-  // Represents seconds of UTC time since Unix epoch
-  // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
-  // 9999-12-31T23:59:59Z inclusive.
-  int64 seconds = 1;
-
-  // Non-negative fractions of a second at nanosecond resolution. Negative
-  // second values with fractions must still have non-negative nanos values
-  // that count forward in time. Must be from 0 to 999,999,999
-  // inclusive.
-  int32 nanos = 2;
-}

+ 1 - 0
vendor/github.com/google/btree/.travis.yml

@@ -0,0 +1 @@
+language: go

+ 15 - 6
vendor/github.com/google/btree/btree.go

@@ -500,13 +500,14 @@ const (
 // thus creating a "greaterOrEqual" or "lessThanEqual" rather than just a
 // "greaterThan" or "lessThan" queries.
 func (n *node) iterate(dir direction, start, stop Item, includeStart bool, hit bool, iter ItemIterator) (bool, bool) {
-	var ok bool
+	var ok, found bool
+	var index int
 	switch dir {
 	case ascend:
-		for i := 0; i < len(n.items); i++ {
-			if start != nil && n.items[i].Less(start) {
-				continue
-			}
+		if start != nil {
+			index, _ = n.items.find(start)
+		}
+		for i := index; i < len(n.items); i++ {
 			if len(n.children) > 0 {
 				if hit, ok = n.children[i].iterate(dir, start, stop, includeStart, hit, iter); !ok {
 					return hit, false
@@ -530,7 +531,15 @@ func (n *node) iterate(dir direction, start, stop Item, includeStart bool, hit b
 			}
 		}
 	case descend:
-		for i := len(n.items) - 1; i >= 0; i-- {
+		if start != nil {
+			index, found = n.items.find(start)
+			if !found {
+				index = index - 1
+			}
+		} else {
+			index = len(n.items) - 1
+		}
+		for i := index; i >= 0; i-- {
 			if start != nil && !n.items[i].Less(start) {
 				if !includeStart || hit || start.Less(n.items[i]) {
 					continue

+ 38 - 0
vendor/github.com/google/gopacket/.gitignore

@@ -0,0 +1,38 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
+#*
+*~
+
+# examples binaries
+examples/synscan/synscan
+examples/pfdump/pfdump
+examples/pcapdump/pcapdump
+examples/httpassembly/httpassembly
+examples/statsassembly/statsassembly
+examples/arpscan/arpscan
+examples/bidirectional/bidirectional
+examples/bytediff/bytediff
+examples/reassemblydump/reassemblydump
+layers/gen
+macs/gen
+pcap/pcap_tester

+ 7 - 0
vendor/github.com/google/gopacket/.travis.gofmt.sh

@@ -0,0 +1,7 @@
+#!/bin/bash
+
+cd "$(dirname $0)"
+if [ -n "$(go fmt ./...)" ]; then
+  echo "Go code is not formatted, run 'go fmt github.com/google/stenographer/...'" >&2
+  exit 1
+fi

+ 28 - 0
vendor/github.com/google/gopacket/.travis.golint.sh

@@ -0,0 +1,28 @@
+#!/bin/bash
+
+cd "$(dirname $0)"
+
+go get golang.org/x/lint/golint
+DIRS=". tcpassembly tcpassembly/tcpreader ip4defrag reassembly macs pcapgo pcap afpacket pfring routing defrag/lcmdefrag"
+# Add subdirectories here as we clean up golint on each.
+for subdir in $DIRS; do
+  pushd $subdir
+  if golint |
+      grep -v CannotSetRFMon |  # pcap exported error name
+      grep -v DataLost |        # tcpassembly/tcpreader exported error name
+      grep .; then
+    exit 1
+  fi
+  popd
+done
+
+pushd layers
+for file in *.go; do
+  if cat .lint_blacklist | grep -q $file; then
+    echo "Skipping lint of $file due to .lint_blacklist"
+  elif golint $file | grep .; then
+    echo "Lint error in file $file"
+    exit 1
+  fi
+done
+popd

+ 10 - 0
vendor/github.com/google/gopacket/.travis.govet.sh

@@ -0,0 +1,10 @@
+#!/bin/bash
+
+cd "$(dirname $0)"
+DIRS=". layers pcap pcapgo tcpassembly tcpassembly/tcpreader routing ip4defrag bytediff macs defrag/lcmdefrag"
+set -e
+for subdir in $DIRS; do
+  pushd $subdir
+  go vet
+  popd
+done

+ 18 - 0
vendor/github.com/google/gopacket/.travis.yml

@@ -0,0 +1,18 @@
+language: go
+before_install:
+ - sudo apt-get install libpcap-dev
+install:
+ - go get github.com/google/gopacket
+ - go get github.com/google/gopacket/layers
+ - go get github.com/google/gopacket/pcapgo
+ - go get github.com/google/gopacket/tcpassembly
+ - go get github.com/google/gopacket/reassembly
+script:
+ - go test github.com/google/gopacket
+ - go test github.com/google/gopacket/layers
+ - go test github.com/google/gopacket/pcapgo 
+ - go test github.com/google/gopacket/tcpassembly
+ - go test github.com/google/gopacket/reassembly
+ - ./.travis.gofmt.sh
+ - ./.travis.govet.sh
+ - ./.travis.golint.sh

+ 5 - 0
vendor/github.com/google/gopacket/AUTHORS

@@ -13,6 +13,9 @@ Hiroaki Kawai <Hiroaki.Kawai@gmail.com>
 Lukas Lueg <lukas.lueg@gmail.com>
 Laurent Hausermann <laurent.hausermann@gmail.com>
 Bill Green <bgreen@newrelic.com>
+Christian Mäder <christian.maeder@nine.ch>
+Gernot Vormayr <gvormayr@gmail.com>
+Vitor Garcia Graveto <victor.graveto@gmail.com>
 
 CONTRIBUTORS:
 Attila Oláh <attila@attilaolah.eu>
@@ -26,6 +29,8 @@ Satoshi Matsumoto <kaorimatz@gmail.com>
 David Stainton <dstainton415@gmail.com>
 Jesse Ward <jesse@jesseward.com>
 Kane Mathers <kane@kanemathers.name>
+Jose Selvi <jselvi@pentester.es>
+Yerden Zhumabekov <yerden.zhumabekov@gmail.com>
 
 -----------------------------------------------
 FORKED FROM github.com/akrennmair/gopcap

+ 2 - 0
vendor/github.com/google/gopacket/README.md

@@ -6,5 +6,7 @@ See [godoc](https://godoc.org/github.com/google/gopacket) for more details.
 [![Build Status](https://travis-ci.org/google/gopacket.svg?branch=master)](https://travis-ci.org/google/gopacket)
 [![GoDoc](https://godoc.org/github.com/google/gopacket?status.svg)](https://godoc.org/github.com/google/gopacket)
 
+Minimum Go version required is 1.5.
+
 Originally forked from the gopcap project written by Andreas
 Krennmair <ak@synflood.at> (http://github.com/akrennmair/gopcap).

+ 6 - 1
vendor/github.com/google/gopacket/doc.go

@@ -22,6 +22,8 @@ useful, including:
 Also, if you're looking to dive right into code, see the examples subdirectory
 for numerous simple binaries built using gopacket libraries.
 
+Minimum go version required is 1.5.
+
 Basic Usage
 
 gopacket takes in packet data as a []byte and decodes it into a packet with
@@ -288,7 +290,10 @@ the packet's information.  A quick example:
    parser := gopacket.NewDecodingLayerParser(layers.LayerTypeEthernet, &eth, &ip4, &ip6, &tcp)
    decoded := []gopacket.LayerType{}
    for packetData := range somehowGetPacketData() {
-     err := parser.DecodeLayers(packetData, &decoded)
+     if err := parser.DecodeLayers(packetData, &decoded); err != nil {
+       fmt.Fprintf(os.Stderr, "Could not decode layers: %v\n", err)
+       continue
+     }
      for _, layerType := range decoded {
        switch layerType {
          case layers.LayerTypeIPv6:

+ 9 - 0
vendor/github.com/google/gopacket/gc

@@ -127,6 +127,9 @@ if [ -f /usr/include/pcap.h ]; then
   Root pcap_tester --mode=filtered
   Root pcap_tester --mode=timestamp || echo "You might not support timestamp sources"
   popd
+  pushd examples/afpacket
+  go build
+  popd
   pushd examples/pcapdump
   go build
   popd
@@ -183,6 +186,12 @@ if [ -f /usr/include/pfring.h ]; then
   go build
   popd
 fi
+pushd ip4defrag
+go test ./...
+popd
+pushd defrag
+go test ./...
+popd
 
 for travis_script in `ls .travis.*.sh`; do
   ./$travis_script

+ 39 - 0
vendor/github.com/google/gopacket/layers/.lint_blacklist

@@ -0,0 +1,39 @@
+dot11.go
+eap.go
+endpoints.go
+enums_generated.go
+enums.go
+ethernet.go
+geneve.go
+icmp4.go
+icmp6.go
+igmp.go
+ip4.go
+ip6.go
+layertypes.go
+linux_sll.go
+llc.go
+lldp.go
+mpls.go
+ndp.go
+ntp.go
+ospf.go
+pflog.go
+pppoe.go
+prism.go
+radiotap.go
+rudp.go
+sctp.go
+sflow.go
+tcp.go
+tcpip.go
+tls.go
+tls_alert.go
+tls_appdata.go
+tls_cipherspec.go
+tls_hanshake.go
+tls_test.go
+udp.go
+udplite.go
+usb.go
+vrrp.go

+ 24 - 11
vendor/github.com/google/gopacket/layers/dhcpv4.go

@@ -9,7 +9,6 @@ package layers
 import (
 	"bytes"
 	"encoding/binary"
-	"errors"
 	"fmt"
 	"net"
 
@@ -141,7 +140,7 @@ func (d *DHCPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error
 	d.ServerName = data[44:108]
 	d.File = data[108:236]
 	if binary.BigEndian.Uint32(data[236:240]) != DHCPMagic {
-		return errors.New("Bad DHCP header")
+		return InvalidMagicCookie
 	}
 
 	if len(data) <= 240 {
@@ -539,9 +538,6 @@ func (o *DHCPOption) encode(b []byte) error {
 	case DHCPOptPad, DHCPOptEnd:
 		b[0] = byte(o.Type)
 	default:
-		if o.Length > 253 {
-			return errors.New("data too long to encode")
-		}
 		b[0] = byte(o.Type)
 		b[1] = o.Length
 		copy(b[2:], o.Data)
@@ -552,21 +548,38 @@ func (o *DHCPOption) encode(b []byte) error {
 func (o *DHCPOption) decode(data []byte) error {
 	if len(data) < 1 {
 		// Pad/End have a length of 1
-		return errors.New("Not enough data to decode")
+		return DecOptionNotEnoughData
 	}
 	o.Type = DHCPOpt(data[0])
 	switch o.Type {
 	case DHCPOptPad, DHCPOptEnd:
 		o.Data = nil
 	default:
-		if len(data) < 3 {
-			return errors.New("Not enough data to decode")
+		if len(data) < 2 {
+			return DecOptionNotEnoughData
 		}
 		o.Length = data[1]
-		if o.Length > 253 {
-			return errors.New("data too long to decode")
+		if int(o.Length) > len(data[2:]) {
+			return DecOptionMalformed
 		}
-		o.Data = data[2 : 2+o.Length]
+		o.Data = data[2 : 2+int(o.Length)]
 	}
 	return nil
 }
+
+// DHCPv4Error is used for constant errors for DHCPv4. It is needed for test asserts.
+type DHCPv4Error string
+
+// DHCPv4Error implements error interface.
+func (d DHCPv4Error) Error() string {
+	return string(d)
+}
+
+const (
+	// DecOptionNotEnoughData is returned when there is not enough data during option's decode process
+	DecOptionNotEnoughData = DHCPv4Error("Not enough data to decode")
+	// DecOptionMalformed is returned when the option is malformed
+	DecOptionMalformed = DHCPv4Error("Option is malformed")
+	// InvalidMagicCookie is returned when Magic cookie is missing into BOOTP header
+	InvalidMagicCookie = DHCPv4Error("Bad DHCP header")
+)

+ 341 - 0
vendor/github.com/google/gopacket/layers/dhcpv6.go

@@ -0,0 +1,341 @@
+// Copyright 2018 Google, Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+
+package layers
+
+import (
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"net"
+
+	"github.com/google/gopacket"
+)
+
+// DHCPv6MsgType represents a DHCPv6 operation
+type DHCPv6MsgType byte
+
+// Constants that represent DHCP operations
+const (
+	DHCPv6MsgTypeUnspecified DHCPv6MsgType = iota
+	DHCPv6MsgTypeSolicit
+	DHCPv6MsgTypeAdverstise
+	DHCPv6MsgTypeRequest
+	DHCPv6MsgTypeConfirm
+	DHCPv6MsgTypeRenew
+	DHCPv6MsgTypeRebind
+	DHCPv6MsgTypeReply
+	DHCPv6MsgTypeRelease
+	DHCPv6MsgTypeDecline
+	DHCPv6MsgTypeReconfigure
+	DHCPv6MsgTypeInformationRequest
+	DHCPv6MsgTypeRelayForward
+	DHCPv6MsgTypeRelayReply
+)
+
+// String returns a string version of a DHCPv6MsgType.
+func (o DHCPv6MsgType) String() string {
+	switch o {
+	case DHCPv6MsgTypeUnspecified:
+		return "Unspecified"
+	case DHCPv6MsgTypeSolicit:
+		return "Solicit"
+	case DHCPv6MsgTypeAdverstise:
+		return "Adverstise"
+	case DHCPv6MsgTypeRequest:
+		return "Request"
+	case DHCPv6MsgTypeConfirm:
+		return "Confirm"
+	case DHCPv6MsgTypeRenew:
+		return "Renew"
+	case DHCPv6MsgTypeRebind:
+		return "Rebind"
+	case DHCPv6MsgTypeReply:
+		return "Reply"
+	case DHCPv6MsgTypeRelease:
+		return "Release"
+	case DHCPv6MsgTypeDecline:
+		return "Decline"
+	case DHCPv6MsgTypeReconfigure:
+		return "Reconfigure"
+	case DHCPv6MsgTypeInformationRequest:
+		return "InformationRequest"
+	case DHCPv6MsgTypeRelayForward:
+		return "RelayForward"
+	case DHCPv6MsgTypeRelayReply:
+		return "RelayReply"
+	default:
+		return "Unknown"
+	}
+}
+
+// DHCPv6 contains data for a single DHCP packet.
+type DHCPv6 struct {
+	BaseLayer
+	MsgType       DHCPv6MsgType
+	HopCount      uint8
+	LinkAddr      net.IP
+	PeerAddr      net.IP
+	TransactionID []byte
+	Options       DHCPv6Options
+}
+
+// LayerType returns gopacket.LayerTypeDHCPv6
+func (d *DHCPv6) LayerType() gopacket.LayerType { return LayerTypeDHCPv6 }
+
+// DecodeFromBytes decodes the given bytes into this layer.
+func (d *DHCPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	d.BaseLayer = BaseLayer{Contents: data}
+	d.Options = d.Options[:0]
+	d.MsgType = DHCPv6MsgType(data[0])
+
+	offset := 0
+	if d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply {
+		d.HopCount = data[1]
+		d.LinkAddr = net.IP(data[2:18])
+		d.PeerAddr = net.IP(data[18:34])
+		offset = 34
+	} else {
+		d.TransactionID = data[1:4]
+		offset = 4
+	}
+
+	stop := len(data)
+	for offset < stop {
+		o := DHCPv6Option{}
+		if err := o.decode(data[offset:]); err != nil {
+			return err
+		}
+		d.Options = append(d.Options, o)
+		offset += int(o.Length) + 4 // 2 from option code, 2 from option length
+	}
+
+	return nil
+}
+
+// Len returns the length of a DHCPv6 packet.
+func (d *DHCPv6) Len() int {
+	n := 1
+	if d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply {
+		n += 33
+	} else {
+		n += 3
+	}
+
+	for _, o := range d.Options {
+		n += int(o.Length) + 4 // 2 from option code, 2 from option length
+	}
+
+	return n
+}
+
+// SerializeTo writes the serialized form of this layer into the
+// SerializationBuffer, implementing gopacket.SerializableLayer.
+// See the docs for gopacket.SerializableLayer for more info.
+func (d *DHCPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	plen := int(d.Len())
+
+	data, err := b.PrependBytes(plen)
+	if err != nil {
+		return err
+	}
+
+	offset := 0
+	data[0] = byte(d.MsgType)
+	if d.MsgType == DHCPv6MsgTypeRelayForward || d.MsgType == DHCPv6MsgTypeRelayReply {
+		data[1] = byte(d.HopCount)
+		copy(data[2:18], d.LinkAddr.To16())
+		copy(data[18:34], d.PeerAddr.To16())
+		offset = 34
+	} else {
+		copy(data[1:4], d.TransactionID)
+		offset = 4
+	}
+
+	if len(d.Options) > 0 {
+		for _, o := range d.Options {
+			if err := o.encode(data[offset:], opts); err != nil {
+				return err
+			}
+			offset += int(o.Length) + 4 // 2 from option code, 2 from option length
+		}
+	}
+	return nil
+}
+
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (d *DHCPv6) CanDecode() gopacket.LayerClass {
+	return LayerTypeDHCPv6
+}
+
+// NextLayerType returns the layer type contained by this DecodingLayer.
+func (d *DHCPv6) NextLayerType() gopacket.LayerType {
+	return gopacket.LayerTypePayload
+}
+
+func decodeDHCPv6(data []byte, p gopacket.PacketBuilder) error {
+	dhcp := &DHCPv6{}
+	err := dhcp.DecodeFromBytes(data, p)
+	if err != nil {
+		return err
+	}
+	p.AddLayer(dhcp)
+	return p.NextDecoder(gopacket.LayerTypePayload)
+}
+
+// DHCPv6StatusCode represents a DHCP status code - RFC-3315
+type DHCPv6StatusCode uint16
+
+// Constants for the DHCPv6StatusCode.
+const (
+	DHCPv6StatusCodeSuccess DHCPv6StatusCode = iota
+	DHCPv6StatusCodeUnspecFail
+	DHCPv6StatusCodeNoAddrsAvail
+	DHCPv6StatusCodeNoBinding
+	DHCPv6StatusCodeNotOnLink
+	DHCPv6StatusCodeUseMulticast
+)
+
+// String returns a string version of a DHCPv6StatusCode.
+func (o DHCPv6StatusCode) String() string {
+	switch o {
+	case DHCPv6StatusCodeSuccess:
+		return "Success"
+	case DHCPv6StatusCodeUnspecFail:
+		return "UnspecifiedFailure"
+	case DHCPv6StatusCodeNoAddrsAvail:
+		return "NoAddressAvailable"
+	case DHCPv6StatusCodeNoBinding:
+		return "NoBinding"
+	case DHCPv6StatusCodeNotOnLink:
+		return "NotOnLink"
+	case DHCPv6StatusCodeUseMulticast:
+		return "UseMulticast"
+	default:
+		return "Unknown"
+	}
+}
+
+// DHCPv6DUIDType represents a DHCP DUID - RFC-3315
+type DHCPv6DUIDType uint16
+
+// Constants for the DHCPv6DUIDType.
+const (
+	DHCPv6DUIDTypeLLT DHCPv6DUIDType = iota + 1
+	DHCPv6DUIDTypeEN
+	DHCPv6DUIDTypeLL
+)
+
+// String returns a string version of a DHCPv6DUIDType.
+func (o DHCPv6DUIDType) String() string {
+	switch o {
+	case DHCPv6DUIDTypeLLT:
+		return "LLT"
+	case DHCPv6DUIDTypeEN:
+		return "EN"
+	case DHCPv6DUIDTypeLL:
+		return "LL"
+	default:
+		return "Unknown"
+	}
+}
+
+// DHCPv6DUID means DHCP Unique Identifier as stated in RFC 3315, section 9 (https://tools.ietf.org/html/rfc3315#page-19)
+type DHCPv6DUID struct {
+	Type DHCPv6DUIDType
+	// LLT, LL
+	HardwareType []byte
+	// EN
+	EnterpriseNumber []byte
+	// LLT
+	Time []byte
+	// LLT, LL
+	LinkLayerAddress net.HardwareAddr
+	// EN
+	Identifier []byte
+}
+
+// DecodeFromBytes decodes the given bytes into a DHCPv6DUID
+func (d *DHCPv6DUID) DecodeFromBytes(data []byte) error {
+	if len(data) < 2 {
+		return errors.New("Not enough bytes to decode: " + string(len(data)))
+	}
+
+	d.Type = DHCPv6DUIDType(binary.BigEndian.Uint16(data[:2]))
+	if d.Type == DHCPv6DUIDTypeLLT || d.Type == DHCPv6DUIDTypeLL {
+		d.HardwareType = data[2:4]
+	}
+
+	if d.Type == DHCPv6DUIDTypeLLT {
+		d.Time = data[4:8]
+		d.LinkLayerAddress = net.HardwareAddr(data[8:])
+	} else if d.Type == DHCPv6DUIDTypeEN {
+		d.EnterpriseNumber = data[2:6]
+		d.Identifier = data[6:]
+	} else { // DHCPv6DUIDTypeLL
+		d.LinkLayerAddress = net.HardwareAddr(data[4:])
+	}
+
+	return nil
+}
+
+// Encode encodes the DHCPv6DUID in a slice of bytes
+func (d *DHCPv6DUID) Encode() []byte {
+	length := d.Len()
+	data := make([]byte, length)
+	binary.BigEndian.PutUint16(data[0:2], uint16(d.Type))
+
+	if d.Type == DHCPv6DUIDTypeLLT || d.Type == DHCPv6DUIDTypeLL {
+		copy(data[2:4], d.HardwareType)
+	}
+
+	if d.Type == DHCPv6DUIDTypeLLT {
+		copy(data[4:8], d.Time)
+		copy(data[8:], d.LinkLayerAddress)
+	} else if d.Type == DHCPv6DUIDTypeEN {
+		copy(data[2:6], d.EnterpriseNumber)
+		copy(data[6:], d.Identifier)
+	} else {
+		copy(data[4:], d.LinkLayerAddress)
+	}
+
+	return data
+}
+
+// Len returns the length of the DHCPv6DUID, respecting the type
+func (d *DHCPv6DUID) Len() int {
+	length := 2 // d.Type
+	if d.Type == DHCPv6DUIDTypeLLT {
+		length += 2 /*HardwareType*/ + 4 /*d.Time*/ + len(d.LinkLayerAddress)
+	} else if d.Type == DHCPv6DUIDTypeEN {
+		length += 4 /*d.EnterpriseNumber*/ + len(d.Identifier)
+	} else { // LL
+		length += 2 /*d.HardwareType*/ + len(d.LinkLayerAddress)
+	}
+
+	return length
+}
+
+func (d *DHCPv6DUID) String() string {
+	duid := "Type: " + d.Type.String() + ", "
+	if d.Type == DHCPv6DUIDTypeLLT {
+		duid += fmt.Sprintf("HardwareType: %v, Time: %v, LinkLayerAddress: %v", d.HardwareType, d.Time, d.LinkLayerAddress)
+	} else if d.Type == DHCPv6DUIDTypeEN {
+		duid += fmt.Sprintf("EnterpriseNumber: %v, Identifier: %v", d.EnterpriseNumber, d.Identifier)
+	} else { // DHCPv6DUIDTypeLL
+		duid += fmt.Sprintf("HardwareType: %v, LinkLayerAddress: %v", d.HardwareType, d.LinkLayerAddress)
+	}
+	return duid
+}
+
+func decodeDHCPv6DUID(data []byte) (*DHCPv6DUID, error) {
+	duid := &DHCPv6DUID{}
+	err := duid.DecodeFromBytes(data)
+	if err != nil {
+		return nil, err
+	}
+	return duid, nil
+}

+ 621 - 0
vendor/github.com/google/gopacket/layers/dhcpv6_options.go

@@ -0,0 +1,621 @@
+// Copyright 2018 The GoPacket Authors. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+
+package layers
+
+import (
+	"bytes"
+	"encoding/binary"
+	"errors"
+	"fmt"
+	"github.com/google/gopacket"
+)
+
+// DHCPv6Opt represents a DHCP option or parameter from RFC-3315
+type DHCPv6Opt uint16
+
+// Constants for the DHCPv6Opt options.
+const (
+	DHCPv6OptClientID           DHCPv6Opt = 1
+	DHCPv6OptServerID           DHCPv6Opt = 2
+	DHCPv6OptIANA               DHCPv6Opt = 3
+	DHCPv6OptIATA               DHCPv6Opt = 4
+	DHCPv6OptIAAddr             DHCPv6Opt = 5
+	DHCPv6OptOro                DHCPv6Opt = 6
+	DHCPv6OptPreference         DHCPv6Opt = 7
+	DHCPv6OptElapsedTime        DHCPv6Opt = 8
+	DHCPv6OptRelayMessage       DHCPv6Opt = 9
+	DHCPv6OptAuth               DHCPv6Opt = 11
+	DHCPv6OptUnicast            DHCPv6Opt = 12
+	DHCPv6OptStatusCode         DHCPv6Opt = 13
+	DHCPv6OptRapidCommit        DHCPv6Opt = 14
+	DHCPv6OptUserClass          DHCPv6Opt = 15
+	DHCPv6OptVendorClass        DHCPv6Opt = 16
+	DHCPv6OptVendorOpts         DHCPv6Opt = 17
+	DHCPv6OptInterfaceID        DHCPv6Opt = 18
+	DHCPv6OptReconfigureMessage DHCPv6Opt = 19
+	DHCPv6OptReconfigureAccept  DHCPv6Opt = 20
+
+	// RFC 3319 Session Initiation Protocol (SIP)
+	DHCPv6OptSIPServersDomainList  DHCPv6Opt = 21
+	DHCPv6OptSIPServersAddressList DHCPv6Opt = 22
+
+	// RFC 3646 DNS Configuration
+	DHCPv6OptDNSServers DHCPv6Opt = 23
+	DHCPv6OptDomainList DHCPv6Opt = 24
+
+	// RFC 3633 Prefix Delegation
+	DHCPv6OptIAPD     DHCPv6Opt = 25
+	DHCPv6OptIAPrefix DHCPv6Opt = 26
+
+	// RFC 3898 Network Information Service (NIS)
+	DHCPv6OptNISServers     DHCPv6Opt = 27
+	DHCPv6OptNISPServers    DHCPv6Opt = 28
+	DHCPv6OptNISDomainName  DHCPv6Opt = 29
+	DHCPv6OptNISPDomainName DHCPv6Opt = 30
+
+	// RFC 4075 Simple Network Time Protocol (SNTP)
+	DHCPv6OptSNTPServers DHCPv6Opt = 31
+
+	// RFC 4242 Information Refresh Time Option
+	DHCPv6OptInformationRefreshTime DHCPv6Opt = 32
+
+	// RFC 4280 Broadcast and Multicast Control Servers
+	DHCPv6OptBCMCSServerDomainNameList DHCPv6Opt = 33
+	DHCPv6OptBCMCSServerAddressList    DHCPv6Opt = 34
+
+	// RFC 4776 Civic Address ConfigurationOption
+	DHCPv6OptGeoconfCivic DHCPv6Opt = 36
+
+	// RFC 4649 Relay Agent Remote-ID
+	DHCPv6OptRemoteID DHCPv6Opt = 37
+
+	// RFC 4580 Relay Agent Subscriber-ID
+	DHCPv6OptSubscriberID DHCPv6Opt = 38
+
+	// RFC 4704 Client Full Qualified Domain Name (FQDN)
+	DHCPv6OptClientFQDN DHCPv6Opt = 39
+
+	// RFC 5192 Protocol for Carrying Authentication for Network Access (PANA)
+	DHCPv6OptPanaAgent DHCPv6Opt = 40
+
+	// RFC 4833 Timezone Options
+	DHCPv6OptNewPOSIXTimezone DHCPv6Opt = 41
+	DHCPv6OptNewTZDBTimezone  DHCPv6Opt = 42
+
+	// RFC 4994 Relay Agent Echo Request
+	DHCPv6OptEchoRequestOption DHCPv6Opt = 43
+
+	// RFC 5007 Leasequery
+	DHCPv6OptLQQuery      DHCPv6Opt = 44
+	DHCPv6OptCLTTime      DHCPv6Opt = 45
+	DHCPv6OptClientData   DHCPv6Opt = 46
+	DHCPv6OptLQRelayData  DHCPv6Opt = 47
+	DHCPv6OptLQClientLink DHCPv6Opt = 48
+
+	// RFC 6610 Home Information Discovery in Mobile IPv6 (MIPv6)
+	DHCPv6OptMIP6HNIDF DHCPv6Opt = 49
+	DHCPv6OptMIP6VDINF DHCPv6Opt = 50
+	DHCPv6OptMIP6IDINF DHCPv6Opt = 69
+	DHCPv6OptMIP6UDINF DHCPv6Opt = 70
+	DHCPv6OptMIP6HNP   DHCPv6Opt = 71
+	DHCPv6OptMIP6HAA   DHCPv6Opt = 72
+	DHCPv6OptMIP6HAF   DHCPv6Opt = 73
+
+	// RFC 5223 Discovering Location-to-Service Translation (LoST) Servers
+	DHCPv6OptV6LOST DHCPv6Opt = 51
+
+	// RFC 5417 Control And Provisioning of Wireless Access Points (CAPWAP)
+	DHCPv6OptCAPWAPACV6 DHCPv6Opt = 52
+
+	// RFC 5460 Bulk Leasequery
+	DHCPv6OptRelayID DHCPv6Opt = 53
+
+	// RFC 5678 IEEE 802.21 Mobility Services (MoS) Discovery
+	DHCPv6OptIPv6AddressMoS DHCPv6Opt = 54
+	DHCPv6OptIPv6FQDNMoS    DHCPv6Opt = 55
+
+	// RFC 5908 NTP Server Option
+	DHCPv6OptNTPServer DHCPv6Opt = 56
+
+	// RFC 5986 Discovering the Local Location Information Server (LIS)
+	DHCPv6OptV6AccessDomain DHCPv6Opt = 57
+
+	// RFC 5986 SIP User Agent
+	DHCPv6OptSIPUACSList DHCPv6Opt = 58
+
+	// RFC 5970 Options for Network Boot
+	DHCPv6OptBootFileURL    DHCPv6Opt = 59
+	DHCPv6OptBootFileParam  DHCPv6Opt = 60
+	DHCPv6OptClientArchType DHCPv6Opt = 61
+	DHCPv6OptNII            DHCPv6Opt = 62
+
+	// RFC 6225 Coordinate-Based Location Configuration Information
+	DHCPv6OptGeolocation DHCPv6Opt = 63
+
+	// RFC 6334 Dual-Stack Lite
+	DHCPv6OptAFTRName DHCPv6Opt = 64
+
+	// RFC 6440 EAP Re-authentication Protocol (ERP)
+	DHCPv6OptERPLocalDomainName DHCPv6Opt = 65
+
+	// RFC 6422 Relay-Supplied DHCP Options
+	DHCPv6OptRSOO DHCPv6Opt = 66
+
+	// RFC 6603 Prefix Exclude Option for DHCPv6-based Prefix Delegation
+	DHCPv6OptPDExclude DHCPv6Opt = 67
+
+	// RFC 6607 Virtual Subnet Selection
+	DHCPv6OptVSS DHCPv6Opt = 68
+
+	// RFC 6731 Improved Recursive DNS Server Selection for Multi-Interfaced Nodes
+	DHCPv6OptRDNSSSelection DHCPv6Opt = 74
+
+	// RFC 6784 Kerberos Options for DHCPv6
+	DHCPv6OptKRBPrincipalName DHCPv6Opt = 75
+	DHCPv6OptKRBRealmName     DHCPv6Opt = 76
+	DHCPv6OptKRBKDC           DHCPv6Opt = 77
+
+	// RFC 6939 Client Link-Layer Address Option
+	DHCPv6OptClientLinkLayerAddress DHCPv6Opt = 79
+
+	// RFC 6977 Triggering DHCPv6 Reconfiguration from Relay Agents
+	DHCPv6OptLinkAddress DHCPv6Opt = 80
+
+	// RFC 7037 RADIUS Option for the DHCPv6 Relay Agent
+	DHCPv6OptRADIUS DHCPv6Opt = 81
+
+	// RFC 7083 Modification to Default Values of SOL_MAX_RT and INF_MAX_RT
+	DHCPv6OptSolMaxRt DHCPv6Opt = 82
+	DHCPv6OptInfMaxRt DHCPv6Opt = 83
+
+	// RFC 7078 Distributing Address Selection Policy
+	DHCPv6OptAddrSel      DHCPv6Opt = 84
+	DHCPv6OptAddrSelTable DHCPv6Opt = 85
+
+	// RFC 7291 DHCP Options for the Port Control Protocol (PCP)
+	DHCPv6OptV6PCPServer DHCPv6Opt = 86
+
+	// RFC 7341 DHCPv4-over-DHCPv6 (DHCP 4o6) Transport
+	DHCPv6OptDHCPv4Message          DHCPv6Opt = 87
+	DHCPv6OptDHCPv4OverDHCPv6Server DHCPv6Opt = 88
+
+	// RFC 7598 Configuration of Softwire Address and Port-Mapped Clients
+	DHCPv6OptS46Rule           DHCPv6Opt = 89
+	DHCPv6OptS46BR             DHCPv6Opt = 90
+	DHCPv6OptS46DMR            DHCPv6Opt = 91
+	DHCPv6OptS46V4V4Bind       DHCPv6Opt = 92
+	DHCPv6OptS46PortParameters DHCPv6Opt = 93
+	DHCPv6OptS46ContMAPE       DHCPv6Opt = 94
+	DHCPv6OptS46ContMAPT       DHCPv6Opt = 95
+	DHCPv6OptS46ContLW         DHCPv6Opt = 96
+
+	// RFC 7600 IPv4 Residual Deployment via IPv6
+	DHCPv6Opt4RD           DHCPv6Opt = 97
+	DHCPv6Opt4RDMapRule    DHCPv6Opt = 98
+	DHCPv6Opt4RDNonMapRule DHCPv6Opt = 99
+
+	// RFC 7653 Active Leasequery
+	DHCPv6OptLQBaseTime  DHCPv6Opt = 100
+	DHCPv6OptLQStartTime DHCPv6Opt = 101
+	DHCPv6OptLQEndTime   DHCPv6Opt = 102
+
+	// RFC 7710 Captive-Portal Identification
+	DHCPv6OptCaptivePortal DHCPv6Opt = 103
+
+	// RFC 7774 Multicast Protocol for Low-Power and Lossy Networks (MPL) Parameter Configuration
+	DHCPv6OptMPLParameters DHCPv6Opt = 104
+
+	// RFC 7839 Access-Network-Identifier (ANI)
+	DHCPv6OptANIATT           DHCPv6Opt = 105
+	DHCPv6OptANINetworkName   DHCPv6Opt = 106
+	DHCPv6OptANIAPName        DHCPv6Opt = 107
+	DHCPv6OptANIAPBSSID       DHCPv6Opt = 108
+	DHCPv6OptANIOperatorID    DHCPv6Opt = 109
+	DHCPv6OptANIOperatorRealm DHCPv6Opt = 110
+
+	// RFC 8026 Unified IPv4-in-IPv6 Softwire Customer Premises Equipment (CPE)
+	DHCPv6OptS46Priority DHCPv6Opt = 111
+
+	// draft-ietf-opsawg-mud-25 Manufacturer Usage Description (MUD)
+	DHCPv6OptMUDURLV6 DHCPv6Opt = 112
+
+	// RFC 8115 IPv4-Embedded Multicast and Unicast IPv6 Prefixes
+	DHCPv6OptV6Prefix64 DHCPv6Opt = 113
+
+	// RFC 8156 DHCPv6 Failover Protocol
+	DHCPv6OptFBindingStatus           DHCPv6Opt = 114
+	DHCPv6OptFConnectFlags            DHCPv6Opt = 115
+	DHCPv6OptFDNSRemovalInfo          DHCPv6Opt = 116
+	DHCPv6OptFDNSHostName             DHCPv6Opt = 117
+	DHCPv6OptFDNSZoneName             DHCPv6Opt = 118
+	DHCPv6OptFDNSFlags                DHCPv6Opt = 119
+	DHCPv6OptFExpirationTime          DHCPv6Opt = 120
+	DHCPv6OptFMaxUnacknowledgedBNDUPD DHCPv6Opt = 121
+	DHCPv6OptFMCLT                    DHCPv6Opt = 122
+	DHCPv6OptFPartnerLifetime         DHCPv6Opt = 123
+	DHCPv6OptFPartnerLifetimeSent     DHCPv6Opt = 124
+	DHCPv6OptFPartnerDownTime         DHCPv6Opt = 125
+	DHCPv6OptFPartnerRawCltTime       DHCPv6Opt = 126
+	DHCPv6OptFProtocolVersion         DHCPv6Opt = 127
+	DHCPv6OptFKeepaliveTime           DHCPv6Opt = 128
+	DHCPv6OptFReconfigureData         DHCPv6Opt = 129
+	DHCPv6OptFRelationshipName        DHCPv6Opt = 130
+	DHCPv6OptFServerFlags             DHCPv6Opt = 131
+	DHCPv6OptFServerState             DHCPv6Opt = 132
+	DHCPv6OptFStartTimeOfState        DHCPv6Opt = 133
+	DHCPv6OptFStateExpirationTime     DHCPv6Opt = 134
+
+	// RFC 8357 Generalized UDP Source Port for DHCP Relay
+	DHCPv6OptRelayPort DHCPv6Opt = 135
+
+	// draft-ietf-netconf-zerotouch-25 Zero Touch Provisioning for Networking Devices
+	DHCPv6OptV6ZeroTouchRedirect DHCPv6Opt = 136
+
+	// RFC 6153 Access Network Discovery and Selection Function (ANDSF) Discovery
+	DHCPv6OptIPV6AddressANDSF DHCPv6Opt = 143
+)
+
+// String returns a string version of a DHCPv6Opt.
+func (o DHCPv6Opt) String() string {
+	switch o {
+	case DHCPv6OptClientID:
+		return "ClientID"
+	case DHCPv6OptServerID:
+		return "ServerID"
+	case DHCPv6OptIANA:
+		return "IA_NA"
+	case DHCPv6OptIATA:
+		return "IA_TA"
+	case DHCPv6OptIAAddr:
+		return "IAAddr"
+	case DHCPv6OptOro:
+		return "Oro"
+	case DHCPv6OptPreference:
+		return "Preference"
+	case DHCPv6OptElapsedTime:
+		return "ElapsedTime"
+	case DHCPv6OptRelayMessage:
+		return "RelayMessage"
+	case DHCPv6OptAuth:
+		return "Auth"
+	case DHCPv6OptUnicast:
+		return "Unicast"
+	case DHCPv6OptStatusCode:
+		return "StatusCode"
+	case DHCPv6OptRapidCommit:
+		return "RapidCommit"
+	case DHCPv6OptUserClass:
+		return "UserClass"
+	case DHCPv6OptVendorClass:
+		return "VendorClass"
+	case DHCPv6OptVendorOpts:
+		return "VendorOpts"
+	case DHCPv6OptInterfaceID:
+		return "InterfaceID"
+	case DHCPv6OptReconfigureMessage:
+		return "ReconfigureMessage"
+	case DHCPv6OptReconfigureAccept:
+		return "ReconfigureAccept"
+	case DHCPv6OptSIPServersDomainList:
+		return "SIPServersDomainList"
+	case DHCPv6OptSIPServersAddressList:
+		return "SIPServersAddressList"
+	case DHCPv6OptDNSServers:
+		return "DNSRecursiveNameServer"
+	case DHCPv6OptDomainList:
+		return "DomainSearchList"
+	case DHCPv6OptIAPD:
+		return "IdentityAssociationPrefixDelegation"
+	case DHCPv6OptIAPrefix:
+		return "IAPDPrefix"
+	case DHCPv6OptNISServers:
+		return "NISServers"
+	case DHCPv6OptNISPServers:
+		return "NISv2Servers"
+	case DHCPv6OptNISDomainName:
+		return "NISDomainName"
+	case DHCPv6OptNISPDomainName:
+		return "NISv2DomainName"
+	case DHCPv6OptSNTPServers:
+		return "SNTPServers"
+	case DHCPv6OptInformationRefreshTime:
+		return "InformationRefreshTime"
+	case DHCPv6OptBCMCSServerDomainNameList:
+		return "BCMCSControlServersDomainNameList"
+	case DHCPv6OptBCMCSServerAddressList:
+		return "BCMCSControlServersAddressList"
+	case DHCPv6OptGeoconfCivic:
+		return "CivicAddress"
+	case DHCPv6OptRemoteID:
+		return "RelayAgentRemoteID"
+	case DHCPv6OptSubscriberID:
+		return "RelayAgentSubscriberID"
+	case DHCPv6OptClientFQDN:
+		return "ClientFQDN"
+	case DHCPv6OptPanaAgent:
+		return "PANAAuthenticationAgent"
+	case DHCPv6OptNewPOSIXTimezone:
+		return "NewPOSIXTimezone"
+	case DHCPv6OptNewTZDBTimezone:
+		return "NewTZDBTimezone"
+	case DHCPv6OptEchoRequestOption:
+		return "EchoRequest"
+	case DHCPv6OptLQQuery:
+		return "LeasequeryQuery"
+	case DHCPv6OptClientData:
+		return "LeasequeryClientData"
+	case DHCPv6OptCLTTime:
+		return "LeasequeryClientLastTransactionTime"
+	case DHCPv6OptLQRelayData:
+		return "LeasequeryRelayData"
+	case DHCPv6OptLQClientLink:
+		return "LeasequeryClientLink"
+	case DHCPv6OptMIP6HNIDF:
+		return "MIPv6HomeNetworkIDFQDN"
+	case DHCPv6OptMIP6VDINF:
+		return "MIPv6VisitedHomeNetworkInformation"
+	case DHCPv6OptMIP6IDINF:
+		return "MIPv6IdentifiedHomeNetworkInformation"
+	case DHCPv6OptMIP6UDINF:
+		return "MIPv6UnrestrictedHomeNetworkInformation"
+	case DHCPv6OptMIP6HNP:
+		return "MIPv6HomeNetworkPrefix"
+	case DHCPv6OptMIP6HAA:
+		return "MIPv6HomeAgentAddress"
+	case DHCPv6OptMIP6HAF:
+		return "MIPv6HomeAgentFQDN"
+	case DHCPv6OptV6LOST:
+		return "LoST Server"
+	case DHCPv6OptCAPWAPACV6:
+		return "CAPWAPAccessControllerV6"
+	case DHCPv6OptRelayID:
+		return "LeasequeryRelayID"
+	case DHCPv6OptIPv6AddressMoS:
+		return "MoSIPv6Address"
+	case DHCPv6OptIPv6FQDNMoS:
+		return "MoSDomainNameList"
+	case DHCPv6OptNTPServer:
+		return "NTPServer"
+	case DHCPv6OptV6AccessDomain:
+		return "AccessNetworkDomainName"
+	case DHCPv6OptSIPUACSList:
+		return "SIPUserAgentConfigurationServiceDomains"
+	case DHCPv6OptBootFileURL:
+		return "BootFileURL"
+	case DHCPv6OptBootFileParam:
+		return "BootFileParameters"
+	case DHCPv6OptClientArchType:
+		return "ClientSystemArchitectureType"
+	case DHCPv6OptNII:
+		return "ClientNetworkInterfaceIdentifier"
+	case DHCPv6OptGeolocation:
+		return "Geolocation"
+	case DHCPv6OptAFTRName:
+		return "AFTRName"
+	case DHCPv6OptERPLocalDomainName:
+		return "AFTRName"
+	case DHCPv6OptRSOO:
+		return "RSOOption"
+	case DHCPv6OptPDExclude:
+		return "PrefixExclude"
+	case DHCPv6OptVSS:
+		return "VirtualSubnetSelection"
+	case DHCPv6OptRDNSSSelection:
+		return "RDNSSSelection"
+	case DHCPv6OptKRBPrincipalName:
+		return "KerberosPrincipalName"
+	case DHCPv6OptKRBRealmName:
+		return "KerberosRealmName"
+	case DHCPv6OptKRBKDC:
+		return "KerberosKDC"
+	case DHCPv6OptClientLinkLayerAddress:
+		return "ClientLinkLayerAddress"
+	case DHCPv6OptLinkAddress:
+		return "LinkAddress"
+	case DHCPv6OptRADIUS:
+		return "RADIUS"
+	case DHCPv6OptSolMaxRt:
+		return "SolMaxRt"
+	case DHCPv6OptInfMaxRt:
+		return "InfMaxRt"
+	case DHCPv6OptAddrSel:
+		return "AddressSelection"
+	case DHCPv6OptAddrSelTable:
+		return "AddressSelectionTable"
+	case DHCPv6OptV6PCPServer:
+		return "PCPServer"
+	case DHCPv6OptDHCPv4Message:
+		return "DHCPv4Message"
+	case DHCPv6OptDHCPv4OverDHCPv6Server:
+		return "DHCP4o6ServerAddress"
+	case DHCPv6OptS46Rule:
+		return "S46Rule"
+	case DHCPv6OptS46BR:
+		return "S46BR"
+	case DHCPv6OptS46DMR:
+		return "S46DMR"
+	case DHCPv6OptS46V4V4Bind:
+		return "S46IPv4IPv6AddressBinding"
+	case DHCPv6OptS46PortParameters:
+		return "S46PortParameters"
+	case DHCPv6OptS46ContMAPE:
+		return "S46MAPEContainer"
+	case DHCPv6OptS46ContMAPT:
+		return "S46MAPTContainer"
+	case DHCPv6OptS46ContLW:
+		return "S46Lightweight4Over6Container"
+	case DHCPv6Opt4RD:
+		return "4RD"
+	case DHCPv6Opt4RDMapRule:
+		return "4RDMapRule"
+	case DHCPv6Opt4RDNonMapRule:
+		return "4RDNonMapRule"
+	case DHCPv6OptLQBaseTime:
+		return "LQBaseTime"
+	case DHCPv6OptLQStartTime:
+		return "LQStartTime"
+	case DHCPv6OptLQEndTime:
+		return "LQEndTime"
+	case DHCPv6OptCaptivePortal:
+		return "CaptivePortal"
+	case DHCPv6OptMPLParameters:
+		return "MPLParameterConfiguration"
+	case DHCPv6OptANIATT:
+		return "ANIAccessTechnologyType"
+	case DHCPv6OptANINetworkName:
+		return "ANINetworkName"
+	case DHCPv6OptANIAPName:
+		return "ANIAccessPointName"
+	case DHCPv6OptANIAPBSSID:
+		return "ANIAccessPointBSSID"
+	case DHCPv6OptANIOperatorID:
+		return "ANIOperatorIdentifier"
+	case DHCPv6OptANIOperatorRealm:
+		return "ANIOperatorRealm"
+	case DHCPv6OptS46Priority:
+		return "S64Priority"
+	case DHCPv6OptMUDURLV6:
+		return "ManufacturerUsageDescriptionURL"
+	case DHCPv6OptV6Prefix64:
+		return "V6Prefix64"
+	case DHCPv6OptFBindingStatus:
+		return "FailoverBindingStatus"
+	case DHCPv6OptFConnectFlags:
+		return "FailoverConnectFlags"
+	case DHCPv6OptFDNSRemovalInfo:
+		return "FailoverDNSRemovalInfo"
+	case DHCPv6OptFDNSHostName:
+		return "FailoverDNSHostName"
+	case DHCPv6OptFDNSZoneName:
+		return "FailoverDNSZoneName"
+	case DHCPv6OptFDNSFlags:
+		return "FailoverDNSFlags"
+	case DHCPv6OptFExpirationTime:
+		return "FailoverExpirationTime"
+	case DHCPv6OptFMaxUnacknowledgedBNDUPD:
+		return "FailoverMaxUnacknowledgedBNDUPDMessages"
+	case DHCPv6OptFMCLT:
+		return "FailoverMaximumClientLeadTime"
+	case DHCPv6OptFPartnerLifetime:
+		return "FailoverPartnerLifetime"
+	case DHCPv6OptFPartnerLifetimeSent:
+		return "FailoverPartnerLifetimeSent"
+	case DHCPv6OptFPartnerDownTime:
+		return "FailoverPartnerDownTime"
+	case DHCPv6OptFPartnerRawCltTime:
+		return "FailoverPartnerRawClientLeadTime"
+	case DHCPv6OptFProtocolVersion:
+		return "FailoverProtocolVersion"
+	case DHCPv6OptFKeepaliveTime:
+		return "FailoverKeepaliveTime"
+	case DHCPv6OptFReconfigureData:
+		return "FailoverReconfigureData"
+	case DHCPv6OptFRelationshipName:
+		return "FailoverRelationshipName"
+	case DHCPv6OptFServerFlags:
+		return "FailoverServerFlags"
+	case DHCPv6OptFServerState:
+		return "FailoverServerState"
+	case DHCPv6OptFStartTimeOfState:
+		return "FailoverStartTimeOfState"
+	case DHCPv6OptFStateExpirationTime:
+		return "FailoverStateExpirationTime"
+	case DHCPv6OptRelayPort:
+		return "RelayPort"
+	case DHCPv6OptV6ZeroTouchRedirect:
+		return "ZeroTouch"
+	case DHCPv6OptIPV6AddressANDSF:
+		return "ANDSFIPv6Address"
+	default:
+		return fmt.Sprintf("Unknown(%d)", uint16(o))
+	}
+}
+
+// DHCPv6Options is used to get nicely printed option lists which would normally
+// be cut off after 5 options.
+type DHCPv6Options []DHCPv6Option
+
+// String returns a string version of the options list.
+func (o DHCPv6Options) String() string {
+	buf := &bytes.Buffer{}
+	buf.WriteByte('[')
+	for i, opt := range o {
+		buf.WriteString(opt.String())
+		if i+1 != len(o) {
+			buf.WriteString(", ")
+		}
+	}
+	buf.WriteByte(']')
+	return buf.String()
+}
+
+// DHCPv6Option rerpresents a DHCP option.
+type DHCPv6Option struct {
+	Code   DHCPv6Opt
+	Length uint16
+	Data   []byte
+}
+
+// String returns a string version of a DHCP Option.
+func (o DHCPv6Option) String() string {
+	switch o.Code {
+	case DHCPv6OptClientID, DHCPv6OptServerID:
+		duid, err := decodeDHCPv6DUID(o.Data)
+		if err != nil {
+			return fmt.Sprintf("Option(%s:INVALID)", o.Code)
+		}
+		return fmt.Sprintf("Option(%s:[%s])", o.Code, duid.String())
+	case DHCPv6OptOro:
+		options := ""
+		for i := 0; i < int(o.Length); i += 2 {
+			if options != "" {
+				options += ","
+			}
+			option := DHCPv6Opt(binary.BigEndian.Uint16(o.Data[i : i+2]))
+			options += option.String()
+		}
+		return fmt.Sprintf("Option(%s:[%s])", o.Code, options)
+	default:
+		return fmt.Sprintf("Option(%s:%v)", o.Code, o.Data)
+	}
+}
+
+// NewDHCPv6Option constructs a new DHCPv6Option with a given type and data.
+func NewDHCPv6Option(code DHCPv6Opt, data []byte) DHCPv6Option {
+	o := DHCPv6Option{Code: code}
+	if data != nil {
+		o.Data = data
+		o.Length = uint16(len(data))
+	}
+
+	return o
+}
+
+func (o *DHCPv6Option) encode(b []byte, opts gopacket.SerializeOptions) error {
+	binary.BigEndian.PutUint16(b[0:2], uint16(o.Code))
+	if opts.FixLengths {
+		binary.BigEndian.PutUint16(b[2:4], uint16(len(o.Data)))
+	} else {
+		binary.BigEndian.PutUint16(b[2:4], o.Length)
+	}
+	copy(b[4:], o.Data)
+
+	return nil
+}
+
+func (o *DHCPv6Option) decode(data []byte) error {
+	if len(data) < 2 {
+		return errors.New("not enough data to decode")
+	}
+	o.Code = DHCPv6Opt(binary.BigEndian.Uint16(data[0:2]))
+	if len(data) < 3 {
+		return errors.New("not enough data to decode")
+	}
+	o.Length = binary.BigEndian.Uint16(data[2:4])
+	o.Data = data[4 : 4+o.Length]
+	return nil
+}

+ 37 - 17
vendor/github.com/google/gopacket/layers/dns.go

@@ -296,7 +296,7 @@ func (d *DNS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
 
 	if len(data) < 12 {
 		df.SetTruncated()
-		return errors.New("DNS packet too short")
+		return errDNSPacketTooShort
 	}
 
 	// since there are no further layers, the baselayer's content is
@@ -366,13 +366,13 @@ func (d *DNS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
 	}
 
 	if uint16(len(d.Questions)) != d.QDCount {
-		return errors.New("Invalid query decoding, not the right number of questions")
+		return errDecodeQueryBadQDCount
 	} else if uint16(len(d.Answers)) != d.ANCount {
-		return errors.New("Invalid query decoding, not the right number of answers")
+		return errDecodeQueryBadANCount
 	} else if uint16(len(d.Authorities)) != d.NSCount {
-		return errors.New("Invalid query decoding, not the right number of authorities")
+		return errDecodeQueryBadNSCount
 	} else if uint16(len(d.Additionals)) != d.ARCount {
-		return errors.New("Invalid query decoding, not the right number of additionals info")
+		return errDecodeQueryBadARCount
 	}
 	return nil
 }
@@ -504,17 +504,15 @@ func (d *DNS) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt
 	return nil
 }
 
-var errMaxRecursion = errors.New("max DNS recursion level hit")
-
 const maxRecursionLevel = 255
 
 func decodeName(data []byte, offset int, buffer *[]byte, level int) ([]byte, int, error) {
 	if level > maxRecursionLevel {
 		return nil, 0, errMaxRecursion
 	} else if offset >= len(data) {
-		return nil, 0, errors.New("dns name offset too high")
+		return nil, 0, errDNSNameOffsetTooHigh
 	} else if offset < 0 {
-		return nil, 0, errors.New("dns name offset is negative")
+		return nil, 0, errDNSNameOffsetNegative
 	}
 	start := len(*buffer)
 	index := offset
@@ -535,9 +533,9 @@ loop:
 			*/
 			index2 := index + int(data[index]) + 1
 			if index2-offset > 255 {
-				return nil, 0, errors.New("dns name is too long")
+				return nil, 0, errDNSNameTooLong
 			} else if index2 < index+1 || index2 > len(data) {
-				return nil, 0, errors.New("dns name uncomputable: invalid index")
+				return nil, 0, errDNSNameInvalidIndex
 			}
 			*buffer = append(*buffer, '.')
 			*buffer = append(*buffer, data[index+1:index2]...)
@@ -564,11 +562,11 @@ loop:
 			      - a sequence of labels ending with a pointer
 			*/
 			if index+2 > len(data) {
-				return nil, 0, errors.New("dns offset pointer too high")
+				return nil, 0, errDNSPointerOffsetTooHigh
 			}
 			offsetp := int(binary.BigEndian.Uint16(data[index:index+2]) & 0x3fff)
 			if offsetp > len(data) {
-				return nil, 0, errors.New("dns offset pointer too high")
+				return nil, 0, errDNSPointerOffsetTooHigh
 			}
 			// This looks a little tricky, but actually isn't.  Because of how
 			// decodeName is written, calling it appends the decoded name to the
@@ -590,11 +588,11 @@ loop:
 				data[index], index)
 		}
 		if index >= len(data) {
-			return nil, 0, errors.New("dns index walked out of range")
+			return nil, 0, errDNSIndexOutOfRange
 		}
 	}
 	if len(*buffer) <= start {
-		return nil, 0, errors.New("no dns data found for name")
+		return nil, 0, errDNSNameHasNoData
 	}
 	return (*buffer)[start+1:], index + 1, nil
 }
@@ -686,7 +684,7 @@ func (rr *DNSResourceRecord) decode(data []byte, offset int, df gopacket.DecodeF
 	rr.DataLength = binary.BigEndian.Uint16(data[endq+8 : endq+10])
 	end := endq + 10 + int(rr.DataLength)
 	if end > len(data) {
-		return 0, fmt.Errorf("resource record length exceeds data")
+		return 0, errDecodeRecordLength
 	}
 	rr.Data = data[endq+10 : end]
 
@@ -798,7 +796,7 @@ func decodeCharacterStrings(data []byte) ([][]byte, error) {
 	for index, index2 := 0, 0; index != end; index = index2 {
 		index2 = index + 1 + int(data[index]) // index increases by 1..256 and does not overflow
 		if index2 > end {
-			return nil, errors.New("Insufficient data for a <character-string>")
+			return nil, errCharStringMissData
 		}
 		strings = append(strings, data[index+1:index2])
 	}
@@ -892,3 +890,25 @@ type DNSMX struct {
 	Preference uint16
 	Name       []byte
 }
+
+var (
+	errMaxRecursion = errors.New("max DNS recursion level hit")
+
+	errDNSNameOffsetTooHigh    = errors.New("dns name offset too high")
+	errDNSNameOffsetNegative   = errors.New("dns name offset is negative")
+	errDNSPacketTooShort       = errors.New("DNS packet too short")
+	errDNSNameTooLong          = errors.New("dns name is too long")
+	errDNSNameInvalidIndex     = errors.New("dns name uncomputable: invalid index")
+	errDNSPointerOffsetTooHigh = errors.New("dns offset pointer too high")
+	errDNSIndexOutOfRange      = errors.New("dns index walked out of range")
+	errDNSNameHasNoData        = errors.New("no dns data found for name")
+
+	errCharStringMissData = errors.New("Insufficient data for a <character-string>")
+
+	errDecodeRecordLength = errors.New("resource record length exceeds data")
+
+	errDecodeQueryBadQDCount = errors.New("Invalid query decoding, not the right number of questions")
+	errDecodeQueryBadANCount = errors.New("Invalid query decoding, not the right number of answers")
+	errDecodeQueryBadNSCount = errors.New("Invalid query decoding, not the right number of authorities")
+	errDecodeQueryBadARCount = errors.New("Invalid query decoding, not the right number of additionals info")
+)

+ 732 - 57
vendor/github.com/google/gopacket/layers/dot11.go

@@ -240,24 +240,178 @@ func (a Dot11Algorithm) String() string {
 
 type Dot11InformationElementID uint8
 
-// TODO: Verify these element ids, and append more ids if more.
-
 const (
-	Dot11InformationElementIDSSID          Dot11InformationElementID = 0
-	Dot11InformationElementIDRates         Dot11InformationElementID = 1
-	Dot11InformationElementIDFHSet         Dot11InformationElementID = 2
-	Dot11InformationElementIDDSSet         Dot11InformationElementID = 3
-	Dot11InformationElementIDCFSet         Dot11InformationElementID = 4
-	Dot11InformationElementIDTIM           Dot11InformationElementID = 5
-	Dot11InformationElementIDIBSSSet       Dot11InformationElementID = 6
-	Dot11InformationElementIDChallenge     Dot11InformationElementID = 16
-	Dot11InformationElementIDERPInfo       Dot11InformationElementID = 42
-	Dot11InformationElementIDQOSCapability Dot11InformationElementID = 46
-	Dot11InformationElementIDERPInfo2      Dot11InformationElementID = 47
-	Dot11InformationElementIDRSNInfo       Dot11InformationElementID = 48
-	Dot11InformationElementIDESRates       Dot11InformationElementID = 50
-	Dot11InformationElementIDVendor        Dot11InformationElementID = 221
-	Dot11InformationElementIDReserved      Dot11InformationElementID = 68
+	Dot11InformationElementIDSSID                      Dot11InformationElementID = 0
+	Dot11InformationElementIDRates                     Dot11InformationElementID = 1
+	Dot11InformationElementIDFHSet                     Dot11InformationElementID = 2
+	Dot11InformationElementIDDSSet                     Dot11InformationElementID = 3
+	Dot11InformationElementIDCFSet                     Dot11InformationElementID = 4
+	Dot11InformationElementIDTIM                       Dot11InformationElementID = 5
+	Dot11InformationElementIDIBSSSet                   Dot11InformationElementID = 6
+	Dot11InformationElementIDCountryInfo               Dot11InformationElementID = 7
+	Dot11InformationElementIDHoppingPatternParam       Dot11InformationElementID = 8
+	Dot11InformationElementIDHoppingPatternTable       Dot11InformationElementID = 9
+	Dot11InformationElementIDRequest                   Dot11InformationElementID = 10
+	Dot11InformationElementIDQBSSLoadElem              Dot11InformationElementID = 11
+	Dot11InformationElementIDEDCAParamSet              Dot11InformationElementID = 12
+	Dot11InformationElementIDTrafficSpec               Dot11InformationElementID = 13
+	Dot11InformationElementIDTrafficClass              Dot11InformationElementID = 14
+	Dot11InformationElementIDSchedule                  Dot11InformationElementID = 15
+	Dot11InformationElementIDChallenge                 Dot11InformationElementID = 16
+	Dot11InformationElementIDPowerConst                Dot11InformationElementID = 32
+	Dot11InformationElementIDPowerCapability           Dot11InformationElementID = 33
+	Dot11InformationElementIDTPCRequest                Dot11InformationElementID = 34
+	Dot11InformationElementIDTPCReport                 Dot11InformationElementID = 35
+	Dot11InformationElementIDSupportedChannels         Dot11InformationElementID = 36
+	Dot11InformationElementIDSwitchChannelAnnounce     Dot11InformationElementID = 37
+	Dot11InformationElementIDMeasureRequest            Dot11InformationElementID = 38
+	Dot11InformationElementIDMeasureReport             Dot11InformationElementID = 39
+	Dot11InformationElementIDQuiet                     Dot11InformationElementID = 40
+	Dot11InformationElementIDIBSSDFS                   Dot11InformationElementID = 41
+	Dot11InformationElementIDERPInfo                   Dot11InformationElementID = 42
+	Dot11InformationElementIDTSDelay                   Dot11InformationElementID = 43
+	Dot11InformationElementIDTCLASProcessing           Dot11InformationElementID = 44
+	Dot11InformationElementIDHTCapabilities            Dot11InformationElementID = 45
+	Dot11InformationElementIDQOSCapability             Dot11InformationElementID = 46
+	Dot11InformationElementIDERPInfo2                  Dot11InformationElementID = 47
+	Dot11InformationElementIDRSNInfo                   Dot11InformationElementID = 48
+	Dot11InformationElementIDESRates                   Dot11InformationElementID = 50
+	Dot11InformationElementIDAPChannelReport           Dot11InformationElementID = 51
+	Dot11InformationElementIDNeighborReport            Dot11InformationElementID = 52
+	Dot11InformationElementIDRCPI                      Dot11InformationElementID = 53
+	Dot11InformationElementIDMobilityDomain            Dot11InformationElementID = 54
+	Dot11InformationElementIDFastBSSTrans              Dot11InformationElementID = 55
+	Dot11InformationElementIDTimeoutInt                Dot11InformationElementID = 56
+	Dot11InformationElementIDRICData                   Dot11InformationElementID = 57
+	Dot11InformationElementIDDSERegisteredLoc          Dot11InformationElementID = 58
+	Dot11InformationElementIDSuppOperatingClass        Dot11InformationElementID = 59
+	Dot11InformationElementIDExtChanSwitchAnnounce     Dot11InformationElementID = 60
+	Dot11InformationElementIDHTInfo                    Dot11InformationElementID = 61
+	Dot11InformationElementIDSecChanOffset             Dot11InformationElementID = 62
+	Dot11InformationElementIDBSSAverageAccessDelay     Dot11InformationElementID = 63
+	Dot11InformationElementIDAntenna                   Dot11InformationElementID = 64
+	Dot11InformationElementIDRSNI                      Dot11InformationElementID = 65
+	Dot11InformationElementIDMeasurePilotTrans         Dot11InformationElementID = 66
+	Dot11InformationElementIDBSSAvailAdmCapacity       Dot11InformationElementID = 67
+	Dot11InformationElementIDBSSACAccDelayWAPIParam    Dot11InformationElementID = 68
+	Dot11InformationElementIDTimeAdvertisement         Dot11InformationElementID = 69
+	Dot11InformationElementIDRMEnabledCapabilities     Dot11InformationElementID = 70
+	Dot11InformationElementIDMultipleBSSID             Dot11InformationElementID = 71
+	Dot11InformationElementID2040BSSCoExist            Dot11InformationElementID = 72
+	Dot11InformationElementID2040BSSIntChanReport      Dot11InformationElementID = 73
+	Dot11InformationElementIDOverlapBSSScanParam       Dot11InformationElementID = 74
+	Dot11InformationElementIDRICDescriptor             Dot11InformationElementID = 75
+	Dot11InformationElementIDManagementMIC             Dot11InformationElementID = 76
+	Dot11InformationElementIDEventRequest              Dot11InformationElementID = 78
+	Dot11InformationElementIDEventReport               Dot11InformationElementID = 79
+	Dot11InformationElementIDDiagnosticRequest         Dot11InformationElementID = 80
+	Dot11InformationElementIDDiagnosticReport          Dot11InformationElementID = 81
+	Dot11InformationElementIDLocationParam             Dot11InformationElementID = 82
+	Dot11InformationElementIDNonTransBSSIDCapability   Dot11InformationElementID = 83
+	Dot11InformationElementIDSSIDList                  Dot11InformationElementID = 84
+	Dot11InformationElementIDMultipleBSSIDIndex        Dot11InformationElementID = 85
+	Dot11InformationElementIDFMSDescriptor             Dot11InformationElementID = 86
+	Dot11InformationElementIDFMSRequest                Dot11InformationElementID = 87
+	Dot11InformationElementIDFMSResponse               Dot11InformationElementID = 88
+	Dot11InformationElementIDQOSTrafficCapability      Dot11InformationElementID = 89
+	Dot11InformationElementIDBSSMaxIdlePeriod          Dot11InformationElementID = 90
+	Dot11InformationElementIDTFSRequest                Dot11InformationElementID = 91
+	Dot11InformationElementIDTFSResponse               Dot11InformationElementID = 92
+	Dot11InformationElementIDWNMSleepMode              Dot11InformationElementID = 93
+	Dot11InformationElementIDTIMBroadcastRequest       Dot11InformationElementID = 94
+	Dot11InformationElementIDTIMBroadcastResponse      Dot11InformationElementID = 95
+	Dot11InformationElementIDCollInterferenceReport    Dot11InformationElementID = 96
+	Dot11InformationElementIDChannelUsage              Dot11InformationElementID = 97
+	Dot11InformationElementIDTimeZone                  Dot11InformationElementID = 98
+	Dot11InformationElementIDDMSRequest                Dot11InformationElementID = 99
+	Dot11InformationElementIDDMSResponse               Dot11InformationElementID = 100
+	Dot11InformationElementIDLinkIdentifier            Dot11InformationElementID = 101
+	Dot11InformationElementIDWakeupSchedule            Dot11InformationElementID = 102
+	Dot11InformationElementIDChannelSwitchTiming       Dot11InformationElementID = 104
+	Dot11InformationElementIDPTIControl                Dot11InformationElementID = 105
+	Dot11InformationElementIDPUBufferStatus            Dot11InformationElementID = 106
+	Dot11InformationElementIDInterworking              Dot11InformationElementID = 107
+	Dot11InformationElementIDAdvertisementProtocol     Dot11InformationElementID = 108
+	Dot11InformationElementIDExpBWRequest              Dot11InformationElementID = 109
+	Dot11InformationElementIDQOSMapSet                 Dot11InformationElementID = 110
+	Dot11InformationElementIDRoamingConsortium         Dot11InformationElementID = 111
+	Dot11InformationElementIDEmergencyAlertIdentifier  Dot11InformationElementID = 112
+	Dot11InformationElementIDMeshConfiguration         Dot11InformationElementID = 113
+	Dot11InformationElementIDMeshID                    Dot11InformationElementID = 114
+	Dot11InformationElementIDMeshLinkMetricReport      Dot11InformationElementID = 115
+	Dot11InformationElementIDCongestionNotification    Dot11InformationElementID = 116
+	Dot11InformationElementIDMeshPeeringManagement     Dot11InformationElementID = 117
+	Dot11InformationElementIDMeshChannelSwitchParam    Dot11InformationElementID = 118
+	Dot11InformationElementIDMeshAwakeWindows          Dot11InformationElementID = 119
+	Dot11InformationElementIDBeaconTiming              Dot11InformationElementID = 120
+	Dot11InformationElementIDMCCAOPSetupRequest        Dot11InformationElementID = 121
+	Dot11InformationElementIDMCCAOPSetupReply          Dot11InformationElementID = 122
+	Dot11InformationElementIDMCCAOPAdvertisement       Dot11InformationElementID = 123
+	Dot11InformationElementIDMCCAOPTeardown            Dot11InformationElementID = 124
+	Dot11InformationElementIDGateAnnouncement          Dot11InformationElementID = 125
+	Dot11InformationElementIDRootAnnouncement          Dot11InformationElementID = 126
+	Dot11InformationElementIDExtCapability             Dot11InformationElementID = 127
+	Dot11InformationElementIDAgereProprietary          Dot11InformationElementID = 128
+	Dot11InformationElementIDPathRequest               Dot11InformationElementID = 130
+	Dot11InformationElementIDPathReply                 Dot11InformationElementID = 131
+	Dot11InformationElementIDPathError                 Dot11InformationElementID = 132
+	Dot11InformationElementIDCiscoCCX1CKIPDeviceName   Dot11InformationElementID = 133
+	Dot11InformationElementIDCiscoCCX2                 Dot11InformationElementID = 136
+	Dot11InformationElementIDProxyUpdate               Dot11InformationElementID = 137
+	Dot11InformationElementIDProxyUpdateConfirmation   Dot11InformationElementID = 138
+	Dot11InformationElementIDAuthMeshPerringExch       Dot11InformationElementID = 139
+	Dot11InformationElementIDMIC                       Dot11InformationElementID = 140
+	Dot11InformationElementIDDestinationURI            Dot11InformationElementID = 141
+	Dot11InformationElementIDUAPSDCoexistence          Dot11InformationElementID = 142
+	Dot11InformationElementIDWakeupSchedule80211ad     Dot11InformationElementID = 143
+	Dot11InformationElementIDExtendedSchedule          Dot11InformationElementID = 144
+	Dot11InformationElementIDSTAAvailability           Dot11InformationElementID = 145
+	Dot11InformationElementIDDMGTSPEC                  Dot11InformationElementID = 146
+	Dot11InformationElementIDNextDMGATI                Dot11InformationElementID = 147
+	Dot11InformationElementIDDMSCapabilities           Dot11InformationElementID = 148
+	Dot11InformationElementIDCiscoUnknown95            Dot11InformationElementID = 149
+	Dot11InformationElementIDVendor2                   Dot11InformationElementID = 150
+	Dot11InformationElementIDDMGOperating              Dot11InformationElementID = 151
+	Dot11InformationElementIDDMGBSSParamChange         Dot11InformationElementID = 152
+	Dot11InformationElementIDDMGBeamRefinement         Dot11InformationElementID = 153
+	Dot11InformationElementIDChannelMeasFeedback       Dot11InformationElementID = 154
+	Dot11InformationElementIDAwakeWindow               Dot11InformationElementID = 157
+	Dot11InformationElementIDMultiBand                 Dot11InformationElementID = 158
+	Dot11InformationElementIDADDBAExtension            Dot11InformationElementID = 159
+	Dot11InformationElementIDNEXTPCPList               Dot11InformationElementID = 160
+	Dot11InformationElementIDPCPHandover               Dot11InformationElementID = 161
+	Dot11InformationElementIDDMGLinkMargin             Dot11InformationElementID = 162
+	Dot11InformationElementIDSwitchingStream           Dot11InformationElementID = 163
+	Dot11InformationElementIDSessionTransmission       Dot11InformationElementID = 164
+	Dot11InformationElementIDDynamicTonePairReport     Dot11InformationElementID = 165
+	Dot11InformationElementIDClusterReport             Dot11InformationElementID = 166
+	Dot11InformationElementIDRelayCapabilities         Dot11InformationElementID = 167
+	Dot11InformationElementIDRelayTransferParameter    Dot11InformationElementID = 168
+	Dot11InformationElementIDBeamlinkMaintenance       Dot11InformationElementID = 169
+	Dot11InformationElementIDMultipleMacSublayers      Dot11InformationElementID = 170
+	Dot11InformationElementIDUPID                      Dot11InformationElementID = 171
+	Dot11InformationElementIDDMGLinkAdaptionAck        Dot11InformationElementID = 172
+	Dot11InformationElementIDSymbolProprietary         Dot11InformationElementID = 173
+	Dot11InformationElementIDMCCAOPAdvertOverview      Dot11InformationElementID = 174
+	Dot11InformationElementIDQuietPeriodRequest        Dot11InformationElementID = 175
+	Dot11InformationElementIDQuietPeriodResponse       Dot11InformationElementID = 177
+	Dot11InformationElementIDECPACPolicy               Dot11InformationElementID = 182
+	Dot11InformationElementIDClusterTimeOffset         Dot11InformationElementID = 183
+	Dot11InformationElementIDAntennaSectorID           Dot11InformationElementID = 190
+	Dot11InformationElementIDVHTCapabilities           Dot11InformationElementID = 191
+	Dot11InformationElementIDVHTOperation              Dot11InformationElementID = 192
+	Dot11InformationElementIDExtendedBSSLoad           Dot11InformationElementID = 193
+	Dot11InformationElementIDWideBWChannelSwitch       Dot11InformationElementID = 194
+	Dot11InformationElementIDVHTTxPowerEnvelope        Dot11InformationElementID = 195
+	Dot11InformationElementIDChannelSwitchWrapper      Dot11InformationElementID = 196
+	Dot11InformationElementIDOperatingModeNotification Dot11InformationElementID = 199
+	Dot11InformationElementIDUPSIM                     Dot11InformationElementID = 200
+	Dot11InformationElementIDReducedNeighborReport     Dot11InformationElementID = 201
+	Dot11InformationElementIDTVHTOperation             Dot11InformationElementID = 202
+	Dot11InformationElementIDDeviceLocation            Dot11InformationElementID = 204
+	Dot11InformationElementIDWhiteSpaceMap             Dot11InformationElementID = 205
+	Dot11InformationElementIDFineTuningMeasureParams   Dot11InformationElementID = 206
+	Dot11InformationElementIDVendor                    Dot11InformationElementID = 221
 )
 
 // String provides a human readable string for Dot11InformationElementID.
@@ -267,35 +421,347 @@ const (
 func (a Dot11InformationElementID) String() string {
 	switch a {
 	case Dot11InformationElementIDSSID:
-		return "SSID"
+		return "SSID parameter set"
 	case Dot11InformationElementIDRates:
-		return "Rates"
+		return "Supported Rates"
 	case Dot11InformationElementIDFHSet:
-		return "FHset"
+		return "FH Parameter set"
 	case Dot11InformationElementIDDSSet:
-		return "DSset"
+		return "DS Parameter set"
 	case Dot11InformationElementIDCFSet:
-		return "CFset"
+		return "CF Parameter set"
 	case Dot11InformationElementIDTIM:
-		return "TIM"
+		return "Traffic Indication Map (TIM)"
 	case Dot11InformationElementIDIBSSSet:
-		return "IBSSset"
+		return "IBSS Parameter set"
+	case Dot11InformationElementIDCountryInfo:
+		return "Country Information"
+	case Dot11InformationElementIDHoppingPatternParam:
+		return "Hopping Pattern Parameters"
+	case Dot11InformationElementIDHoppingPatternTable:
+		return "Hopping Pattern Table"
+	case Dot11InformationElementIDRequest:
+		return "Request"
+	case Dot11InformationElementIDQBSSLoadElem:
+		return "QBSS Load Element"
+	case Dot11InformationElementIDEDCAParamSet:
+		return "EDCA Parameter Set"
+	case Dot11InformationElementIDTrafficSpec:
+		return "Traffic Specification"
+	case Dot11InformationElementIDTrafficClass:
+		return "Traffic Classification"
+	case Dot11InformationElementIDSchedule:
+		return "Schedule"
 	case Dot11InformationElementIDChallenge:
-		return "Challenge"
+		return "Challenge text"
+	case Dot11InformationElementIDPowerConst:
+		return "Power Constraint"
+	case Dot11InformationElementIDPowerCapability:
+		return "Power Capability"
+	case Dot11InformationElementIDTPCRequest:
+		return "TPC Request"
+	case Dot11InformationElementIDTPCReport:
+		return "TPC Report"
+	case Dot11InformationElementIDSupportedChannels:
+		return "Supported Channels"
+	case Dot11InformationElementIDSwitchChannelAnnounce:
+		return "Channel Switch Announcement"
+	case Dot11InformationElementIDMeasureRequest:
+		return "Measurement Request"
+	case Dot11InformationElementIDMeasureReport:
+		return "Measurement Report"
+	case Dot11InformationElementIDQuiet:
+		return "Quiet"
+	case Dot11InformationElementIDIBSSDFS:
+		return "IBSS DFS"
 	case Dot11InformationElementIDERPInfo:
-		return "ERPinfo"
+		return "ERP Information"
+	case Dot11InformationElementIDTSDelay:
+		return "TS Delay"
+	case Dot11InformationElementIDTCLASProcessing:
+		return "TCLAS Processing"
+	case Dot11InformationElementIDHTCapabilities:
+		return "HT Capabilities (802.11n D1.10)"
 	case Dot11InformationElementIDQOSCapability:
-		return "QOS capability"
+		return "QOS Capability"
 	case Dot11InformationElementIDERPInfo2:
-		return "ERPinfo2"
+		return "ERP Information-2"
 	case Dot11InformationElementIDRSNInfo:
-		return "RSNinfo"
+		return "RSN Information"
 	case Dot11InformationElementIDESRates:
-		return "ESrates"
+		return "Extended Supported Rates"
+	case Dot11InformationElementIDAPChannelReport:
+		return "AP Channel Report"
+	case Dot11InformationElementIDNeighborReport:
+		return "Neighbor Report"
+	case Dot11InformationElementIDRCPI:
+		return "RCPI"
+	case Dot11InformationElementIDMobilityDomain:
+		return "Mobility Domain"
+	case Dot11InformationElementIDFastBSSTrans:
+		return "Fast BSS Transition"
+	case Dot11InformationElementIDTimeoutInt:
+		return "Timeout Interval"
+	case Dot11InformationElementIDRICData:
+		return "RIC Data"
+	case Dot11InformationElementIDDSERegisteredLoc:
+		return "DSE Registered Location"
+	case Dot11InformationElementIDSuppOperatingClass:
+		return "Supported Operating Classes"
+	case Dot11InformationElementIDExtChanSwitchAnnounce:
+		return "Extended Channel Switch Announcement"
+	case Dot11InformationElementIDHTInfo:
+		return "HT Information (802.11n D1.10)"
+	case Dot11InformationElementIDSecChanOffset:
+		return "Secondary Channel Offset (802.11n D1.10)"
+	case Dot11InformationElementIDBSSAverageAccessDelay:
+		return "BSS Average Access Delay"
+	case Dot11InformationElementIDAntenna:
+		return "Antenna"
+	case Dot11InformationElementIDRSNI:
+		return "RSNI"
+	case Dot11InformationElementIDMeasurePilotTrans:
+		return "Measurement Pilot Transmission"
+	case Dot11InformationElementIDBSSAvailAdmCapacity:
+		return "BSS Available Admission Capacity"
+	case Dot11InformationElementIDBSSACAccDelayWAPIParam:
+		return "BSS AC Access Delay/WAPI Parameter Set"
+	case Dot11InformationElementIDTimeAdvertisement:
+		return "Time Advertisement"
+	case Dot11InformationElementIDRMEnabledCapabilities:
+		return "RM Enabled Capabilities"
+	case Dot11InformationElementIDMultipleBSSID:
+		return "Multiple BSSID"
+	case Dot11InformationElementID2040BSSCoExist:
+		return "20/40 BSS Coexistence"
+	case Dot11InformationElementID2040BSSIntChanReport:
+		return "20/40 BSS Intolerant Channel Report"
+	case Dot11InformationElementIDOverlapBSSScanParam:
+		return "Overlapping BSS Scan Parameters"
+	case Dot11InformationElementIDRICDescriptor:
+		return "RIC Descriptor"
+	case Dot11InformationElementIDManagementMIC:
+		return "Management MIC"
+	case Dot11InformationElementIDEventRequest:
+		return "Event Request"
+	case Dot11InformationElementIDEventReport:
+		return "Event Report"
+	case Dot11InformationElementIDDiagnosticRequest:
+		return "Diagnostic Request"
+	case Dot11InformationElementIDDiagnosticReport:
+		return "Diagnostic Report"
+	case Dot11InformationElementIDLocationParam:
+		return "Location Parameters"
+	case Dot11InformationElementIDNonTransBSSIDCapability:
+		return "Non Transmitted BSSID Capability"
+	case Dot11InformationElementIDSSIDList:
+		return "SSID List"
+	case Dot11InformationElementIDMultipleBSSIDIndex:
+		return "Multiple BSSID Index"
+	case Dot11InformationElementIDFMSDescriptor:
+		return "FMS Descriptor"
+	case Dot11InformationElementIDFMSRequest:
+		return "FMS Request"
+	case Dot11InformationElementIDFMSResponse:
+		return "FMS Response"
+	case Dot11InformationElementIDQOSTrafficCapability:
+		return "QoS Traffic Capability"
+	case Dot11InformationElementIDBSSMaxIdlePeriod:
+		return "BSS Max Idle Period"
+	case Dot11InformationElementIDTFSRequest:
+		return "TFS Request"
+	case Dot11InformationElementIDTFSResponse:
+		return "TFS Response"
+	case Dot11InformationElementIDWNMSleepMode:
+		return "WNM-Sleep Mode"
+	case Dot11InformationElementIDTIMBroadcastRequest:
+		return "TIM Broadcast Request"
+	case Dot11InformationElementIDTIMBroadcastResponse:
+		return "TIM Broadcast Response"
+	case Dot11InformationElementIDCollInterferenceReport:
+		return "Collocated Interference Report"
+	case Dot11InformationElementIDChannelUsage:
+		return "Channel Usage"
+	case Dot11InformationElementIDTimeZone:
+		return "Time Zone"
+	case Dot11InformationElementIDDMSRequest:
+		return "DMS Request"
+	case Dot11InformationElementIDDMSResponse:
+		return "DMS Response"
+	case Dot11InformationElementIDLinkIdentifier:
+		return "Link Identifier"
+	case Dot11InformationElementIDWakeupSchedule:
+		return "Wakeup Schedule"
+	case Dot11InformationElementIDChannelSwitchTiming:
+		return "Channel Switch Timing"
+	case Dot11InformationElementIDPTIControl:
+		return "PTI Control"
+	case Dot11InformationElementIDPUBufferStatus:
+		return "PU Buffer Status"
+	case Dot11InformationElementIDInterworking:
+		return "Interworking"
+	case Dot11InformationElementIDAdvertisementProtocol:
+		return "Advertisement Protocol"
+	case Dot11InformationElementIDExpBWRequest:
+		return "Expedited Bandwidth Request"
+	case Dot11InformationElementIDQOSMapSet:
+		return "QoS Map Set"
+	case Dot11InformationElementIDRoamingConsortium:
+		return "Roaming Consortium"
+	case Dot11InformationElementIDEmergencyAlertIdentifier:
+		return "Emergency Alert Identifier"
+	case Dot11InformationElementIDMeshConfiguration:
+		return "Mesh Configuration"
+	case Dot11InformationElementIDMeshID:
+		return "Mesh ID"
+	case Dot11InformationElementIDMeshLinkMetricReport:
+		return "Mesh Link Metric Report"
+	case Dot11InformationElementIDCongestionNotification:
+		return "Congestion Notification"
+	case Dot11InformationElementIDMeshPeeringManagement:
+		return "Mesh Peering Management"
+	case Dot11InformationElementIDMeshChannelSwitchParam:
+		return "Mesh Channel Switch Parameters"
+	case Dot11InformationElementIDMeshAwakeWindows:
+		return "Mesh Awake Windows"
+	case Dot11InformationElementIDBeaconTiming:
+		return "Beacon Timing"
+	case Dot11InformationElementIDMCCAOPSetupRequest:
+		return "MCCAOP Setup Request"
+	case Dot11InformationElementIDMCCAOPSetupReply:
+		return "MCCAOP SETUP Reply"
+	case Dot11InformationElementIDMCCAOPAdvertisement:
+		return "MCCAOP Advertisement"
+	case Dot11InformationElementIDMCCAOPTeardown:
+		return "MCCAOP Teardown"
+	case Dot11InformationElementIDGateAnnouncement:
+		return "Gate Announcement"
+	case Dot11InformationElementIDRootAnnouncement:
+		return "Root Announcement"
+	case Dot11InformationElementIDExtCapability:
+		return "Extended Capabilities"
+	case Dot11InformationElementIDAgereProprietary:
+		return "Agere Proprietary"
+	case Dot11InformationElementIDPathRequest:
+		return "Path Request"
+	case Dot11InformationElementIDPathReply:
+		return "Path Reply"
+	case Dot11InformationElementIDPathError:
+		return "Path Error"
+	case Dot11InformationElementIDCiscoCCX1CKIPDeviceName:
+		return "Cisco CCX1 CKIP + Device Name"
+	case Dot11InformationElementIDCiscoCCX2:
+		return "Cisco CCX2"
+	case Dot11InformationElementIDProxyUpdate:
+		return "Proxy Update"
+	case Dot11InformationElementIDProxyUpdateConfirmation:
+		return "Proxy Update Confirmation"
+	case Dot11InformationElementIDAuthMeshPerringExch:
+		return "Auhenticated Mesh Perring Exchange"
+	case Dot11InformationElementIDMIC:
+		return "MIC (Message Integrity Code)"
+	case Dot11InformationElementIDDestinationURI:
+		return "Destination URI"
+	case Dot11InformationElementIDUAPSDCoexistence:
+		return "U-APSD Coexistence"
+	case Dot11InformationElementIDWakeupSchedule80211ad:
+		return "Wakeup Schedule 802.11ad"
+	case Dot11InformationElementIDExtendedSchedule:
+		return "Extended Schedule"
+	case Dot11InformationElementIDSTAAvailability:
+		return "STA Availability"
+	case Dot11InformationElementIDDMGTSPEC:
+		return "DMG TSPEC"
+	case Dot11InformationElementIDNextDMGATI:
+		return "Next DMG ATI"
+	case Dot11InformationElementIDDMSCapabilities:
+		return "DMG Capabilities"
+	case Dot11InformationElementIDCiscoUnknown95:
+		return "Cisco Unknown 95"
+	case Dot11InformationElementIDVendor2:
+		return "Vendor Specific"
+	case Dot11InformationElementIDDMGOperating:
+		return "DMG Operating"
+	case Dot11InformationElementIDDMGBSSParamChange:
+		return "DMG BSS Parameter Change"
+	case Dot11InformationElementIDDMGBeamRefinement:
+		return "DMG Beam Refinement"
+	case Dot11InformationElementIDChannelMeasFeedback:
+		return "Channel Measurement Feedback"
+	case Dot11InformationElementIDAwakeWindow:
+		return "Awake Window"
+	case Dot11InformationElementIDMultiBand:
+		return "Multi Band"
+	case Dot11InformationElementIDADDBAExtension:
+		return "ADDBA Extension"
+	case Dot11InformationElementIDNEXTPCPList:
+		return "NEXTPCP List"
+	case Dot11InformationElementIDPCPHandover:
+		return "PCP Handover"
+	case Dot11InformationElementIDDMGLinkMargin:
+		return "DMG Link Margin"
+	case Dot11InformationElementIDSwitchingStream:
+		return "Switching Stream"
+	case Dot11InformationElementIDSessionTransmission:
+		return "Session Transmission"
+	case Dot11InformationElementIDDynamicTonePairReport:
+		return "Dynamic Tone Pairing Report"
+	case Dot11InformationElementIDClusterReport:
+		return "Cluster Report"
+	case Dot11InformationElementIDRelayCapabilities:
+		return "Relay Capabilities"
+	case Dot11InformationElementIDRelayTransferParameter:
+		return "Relay Transfer Parameter"
+	case Dot11InformationElementIDBeamlinkMaintenance:
+		return "Beamlink Maintenance"
+	case Dot11InformationElementIDMultipleMacSublayers:
+		return "Multiple MAC Sublayers"
+	case Dot11InformationElementIDUPID:
+		return "U-PID"
+	case Dot11InformationElementIDDMGLinkAdaptionAck:
+		return "DMG Link Adaption Acknowledgment"
+	case Dot11InformationElementIDSymbolProprietary:
+		return "Symbol Proprietary"
+	case Dot11InformationElementIDMCCAOPAdvertOverview:
+		return "MCCAOP Advertisement Overview"
+	case Dot11InformationElementIDQuietPeriodRequest:
+		return "Quiet Period Request"
+	case Dot11InformationElementIDQuietPeriodResponse:
+		return "Quiet Period Response"
+	case Dot11InformationElementIDECPACPolicy:
+		return "ECPAC Policy"
+	case Dot11InformationElementIDClusterTimeOffset:
+		return "Cluster Time Offset"
+	case Dot11InformationElementIDAntennaSectorID:
+		return "Antenna Sector ID"
+	case Dot11InformationElementIDVHTCapabilities:
+		return "VHT Capabilities (IEEE Std 802.11ac/D3.1)"
+	case Dot11InformationElementIDVHTOperation:
+		return "VHT Operation (IEEE Std 802.11ac/D3.1)"
+	case Dot11InformationElementIDExtendedBSSLoad:
+		return "Extended BSS Load"
+	case Dot11InformationElementIDWideBWChannelSwitch:
+		return "Wide Bandwidth Channel Switch"
+	case Dot11InformationElementIDVHTTxPowerEnvelope:
+		return "VHT Tx Power Envelope (IEEE Std 802.11ac/D5.0)"
+	case Dot11InformationElementIDChannelSwitchWrapper:
+		return "Channel Switch Wrapper"
+	case Dot11InformationElementIDOperatingModeNotification:
+		return "Operating Mode Notification"
+	case Dot11InformationElementIDUPSIM:
+		return "UP SIM"
+	case Dot11InformationElementIDReducedNeighborReport:
+		return "Reduced Neighbor Report"
+	case Dot11InformationElementIDTVHTOperation:
+		return "TVHT Op"
+	case Dot11InformationElementIDDeviceLocation:
+		return "Device Location"
+	case Dot11InformationElementIDWhiteSpaceMap:
+		return "White Space Map"
+	case Dot11InformationElementIDFineTuningMeasureParams:
+		return "Fine Tuning Measure Parameters"
 	case Dot11InformationElementIDVendor:
 		return "Vendor"
-	case Dot11InformationElementIDReserved:
-		return "Reserved"
 	default:
 		return "Unknown information element id"
 	}
@@ -303,7 +769,7 @@ func (a Dot11InformationElementID) String() string {
 
 // Dot11 provides an IEEE 802.11 base packet header.
 // See http://standards.ieee.org/findstds/standard/802.11-2012.html
-// for excrutiating detail.
+// for excruciating detail.
 type Dot11 struct {
 	BaseLayer
 	Type           Dot11Type
@@ -317,23 +783,138 @@ type Dot11 struct {
 	SequenceNumber uint16
 	FragmentNumber uint16
 	Checksum       uint32
+	QOS            *Dot11QOS
+	HTControl      *Dot11HTControl
+	DataLayer      gopacket.Layer
+}
+
+type Dot11QOS struct {
+	TID       uint8 /* Traffic IDentifier */
+	EOSP      bool  /* End of service period */
+	AckPolicy Dot11AckPolicy
+	TXOP      uint8
+}
+
+type Dot11HTControl struct {
+	ACConstraint bool
+	RDGMorePPDU  bool
+
+	VHT *Dot11HTControlVHT
+	HT  *Dot11HTControlHT
+}
+
+type Dot11HTControlHT struct {
+	LinkAdapationControl *Dot11LinkAdapationControl
+	CalibrationPosition  uint8
+	CalibrationSequence  uint8
+	CSISteering          uint8
+	NDPAnnouncement      bool
+	DEI                  bool
+}
+
+type Dot11HTControlVHT struct {
+	MRQ            bool
+	UnsolicitedMFB bool
+	MSI            *uint8
+	MFB            Dot11HTControlMFB
+	CompressedMSI  *uint8
+	STBCIndication bool
+	MFSI           *uint8
+	GID            *uint8
+	CodingType     *Dot11CodingType
+	FbTXBeamformed bool
+}
+
+type Dot11HTControlMFB struct {
+	NumSTS uint8
+	VHTMCS uint8
+	BW     uint8
+	SNR    int8
+}
+
+type Dot11LinkAdapationControl struct {
+	TRQ  bool
+	MRQ  bool
+	MSI  uint8
+	MFSI uint8
+	ASEL *Dot11ASEL
+	MFB  *uint8
+}
+
+type Dot11ASEL struct {
+	Command uint8
+	Data    uint8
+}
+
+type Dot11CodingType uint8
+
+const (
+	Dot11CodingTypeBCC  = 0
+	Dot11CodingTypeLDPC = 1
+)
+
+func (a Dot11CodingType) String() string {
+	switch a {
+	case Dot11CodingTypeBCC:
+		return "BCC"
+	case Dot11CodingTypeLDPC:
+		return "LDPC"
+	default:
+		return "Unknown coding type"
+	}
+}
+
+func (m *Dot11HTControlMFB) NoFeedBackPresent() bool {
+	return m.VHTMCS == 15 && m.NumSTS == 7
 }
 
 func decodeDot11(data []byte, p gopacket.PacketBuilder) error {
 	d := &Dot11{}
-	return decodingLayerDecoder(d, data, p)
+	err := d.DecodeFromBytes(data, p)
+	if err != nil {
+		return err
+	}
+	p.AddLayer(d)
+	if d.DataLayer != nil {
+		p.AddLayer(d.DataLayer)
+	}
+	return p.NextDecoder(d.NextLayerType())
 }
 
 func (m *Dot11) LayerType() gopacket.LayerType  { return LayerTypeDot11 }
 func (m *Dot11) CanDecode() gopacket.LayerClass { return LayerTypeDot11 }
 func (m *Dot11) NextLayerType() gopacket.LayerType {
-	if m.Flags.WEP() {
-		return (LayerTypeDot11WEP)
+	if m.DataLayer != nil {
+		if m.Flags.WEP() {
+			return LayerTypeDot11WEP
+		}
+		return m.DataLayer.(gopacket.DecodingLayer).NextLayerType()
 	}
-
 	return m.Type.LayerType()
 }
 
+func createU8(x uint8) *uint8 {
+	return &x
+}
+
+var dataDecodeMap = map[Dot11Type]func() gopacket.DecodingLayer{
+	Dot11TypeData:                   func() gopacket.DecodingLayer { return &Dot11Data{} },
+	Dot11TypeDataCFAck:              func() gopacket.DecodingLayer { return &Dot11DataCFAck{} },
+	Dot11TypeDataCFPoll:             func() gopacket.DecodingLayer { return &Dot11DataCFPoll{} },
+	Dot11TypeDataCFAckPoll:          func() gopacket.DecodingLayer { return &Dot11DataCFAckPoll{} },
+	Dot11TypeDataNull:               func() gopacket.DecodingLayer { return &Dot11DataNull{} },
+	Dot11TypeDataCFAckNoData:        func() gopacket.DecodingLayer { return &Dot11DataCFAckNoData{} },
+	Dot11TypeDataCFPollNoData:       func() gopacket.DecodingLayer { return &Dot11DataCFPollNoData{} },
+	Dot11TypeDataCFAckPollNoData:    func() gopacket.DecodingLayer { return &Dot11DataCFAckPollNoData{} },
+	Dot11TypeDataQOSData:            func() gopacket.DecodingLayer { return &Dot11DataQOSData{} },
+	Dot11TypeDataQOSDataCFAck:       func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFAck{} },
+	Dot11TypeDataQOSDataCFPoll:      func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFPoll{} },
+	Dot11TypeDataQOSDataCFAckPoll:   func() gopacket.DecodingLayer { return &Dot11DataQOSDataCFAckPoll{} },
+	Dot11TypeDataQOSNull:            func() gopacket.DecodingLayer { return &Dot11DataQOSNull{} },
+	Dot11TypeDataQOSCFPollNoData:    func() gopacket.DecodingLayer { return &Dot11DataQOSCFPollNoData{} },
+	Dot11TypeDataQOSCFAckPollNoData: func() gopacket.DecodingLayer { return &Dot11DataQOSCFAckPollNoData{} },
+}
+
 func (m *Dot11) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
 	if len(data) < 10 {
 		df.SetTruncated()
@@ -385,7 +966,112 @@ func (m *Dot11) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
 		offset += 6
 	}
 
-	m.BaseLayer = BaseLayer{Contents: data[0:offset], Payload: data[offset : len(data)-4]}
+	if m.Type.QOS() {
+		if len(data) < offset+2 {
+			df.SetTruncated()
+			return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6)
+		}
+		m.QOS = &Dot11QOS{
+			TID:       (uint8(data[offset]) & 0x0F),
+			EOSP:      (uint8(data[offset]) & 0x10) == 0x10,
+			AckPolicy: Dot11AckPolicy((uint8(data[offset]) & 0x60) >> 5),
+			TXOP:      uint8(data[offset+1]),
+		}
+		offset += 2
+	}
+	if m.Flags.Order() && (m.Type.QOS() || mainType == Dot11TypeMgmt) {
+		if len(data) < offset+4 {
+			df.SetTruncated()
+			return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+6)
+		}
+
+		htc := &Dot11HTControl{
+			ACConstraint: data[offset+3]&0x40 != 0,
+			RDGMorePPDU:  data[offset+3]&0x80 != 0,
+		}
+		m.HTControl = htc
+
+		if data[offset]&0x1 != 0 { // VHT Variant
+			vht := &Dot11HTControlVHT{}
+			htc.VHT = vht
+			vht.MRQ = data[offset]&0x4 != 0
+			vht.UnsolicitedMFB = data[offset+3]&0x20 != 0
+			vht.MFB = Dot11HTControlMFB{
+				NumSTS: uint8(data[offset+1] >> 1 & 0x7),
+				VHTMCS: uint8(data[offset+1] >> 4 & 0xF),
+				BW:     uint8(data[offset+2] & 0x3),
+				SNR:    int8((-(data[offset+2] >> 2 & 0x20))+data[offset+2]>>2&0x1F) + 22,
+			}
+
+			if vht.UnsolicitedMFB {
+				if !vht.MFB.NoFeedBackPresent() {
+					vht.CompressedMSI = createU8(data[offset] >> 3 & 0x3)
+					vht.STBCIndication = data[offset]&0x20 != 0
+					vht.CodingType = (*Dot11CodingType)(createU8(data[offset+3] >> 3 & 0x1))
+					vht.FbTXBeamformed = data[offset+3]&0x10 != 0
+					vht.GID = createU8(
+						data[offset]>>6 +
+							(data[offset+1] & 0x1 << 2) +
+							data[offset+3]&0x7<<3)
+				}
+			} else {
+				if vht.MRQ {
+					vht.MSI = createU8((data[offset] >> 3) & 0x07)
+				}
+				vht.MFSI = createU8(data[offset]>>6 + (data[offset+1] & 0x1 << 2))
+			}
+
+		} else { // HT Variant
+			ht := &Dot11HTControlHT{}
+			htc.HT = ht
+
+			lac := &Dot11LinkAdapationControl{}
+			ht.LinkAdapationControl = lac
+			lac.TRQ = data[offset]&0x2 != 0
+			lac.MFSI = data[offset]>>6&0x3 + data[offset+1]&0x1<<3
+			if data[offset]&0x3C == 0x38 { // ASEL
+				lac.ASEL = &Dot11ASEL{
+					Command: data[offset+1] >> 1 & 0x7,
+					Data:    data[offset+1] >> 4 & 0xF,
+				}
+			} else {
+				lac.MRQ = data[offset]&0x4 != 0
+				if lac.MRQ {
+					lac.MSI = data[offset] >> 3 & 0x7
+				}
+				lac.MFB = createU8(data[offset+1] >> 1)
+			}
+			ht.CalibrationPosition = data[offset+2] & 0x3
+			ht.CalibrationSequence = data[offset+2] >> 2 & 0x3
+			ht.CSISteering = data[offset+2] >> 6 & 0x3
+			ht.NDPAnnouncement = data[offset+3]&0x1 != 0
+			if mainType != Dot11TypeMgmt {
+				ht.DEI = data[offset+3]&0x20 != 0
+			}
+		}
+
+		offset += 4
+	}
+
+	if len(data) < offset+4 {
+		df.SetTruncated()
+		return fmt.Errorf("Dot11 length %v too short, %v required", len(data), offset+4)
+	}
+
+	m.BaseLayer = BaseLayer{
+		Contents: data[0:offset],
+		Payload:  data[offset : len(data)-4],
+	}
+
+	if mainType == Dot11TypeData {
+		l := dataDecodeMap[m.Type]()
+		err := l.DecodeFromBytes(m.BaseLayer.Payload, df)
+		if err != nil {
+			return err
+		}
+		m.DataLayer = l.(gopacket.Layer)
+	}
+
 	m.Checksum = binary.LittleEndian.Uint32(data[len(data)-4 : len(data)])
 	return nil
 }
@@ -474,7 +1160,7 @@ type Dot11WEP struct {
 	BaseLayer
 }
 
-func (m *Dot11WEP) NextLayerType() gopacket.LayerType { return LayerTypeLLC }
+func (m *Dot11WEP) NextLayerType() gopacket.LayerType { return gopacket.LayerTypePayload }
 
 func (m *Dot11WEP) LayerType() gopacket.LayerType  { return LayerTypeDot11WEP }
 func (m *Dot11WEP) CanDecode() gopacket.LayerClass { return LayerTypeDot11WEP }
@@ -493,7 +1179,9 @@ type Dot11Data struct {
 	BaseLayer
 }
 
-func (m *Dot11Data) NextLayerType() gopacket.LayerType { return LayerTypeLLC }
+func (m *Dot11Data) NextLayerType() gopacket.LayerType {
+	return LayerTypeLLC
+}
 
 func (m *Dot11Data) LayerType() gopacket.LayerType  { return LayerTypeDot11Data }
 func (m *Dot11Data) CanDecode() gopacket.LayerClass { return LayerTypeDot11Data }
@@ -618,23 +1306,10 @@ func (m *Dot11DataCFAckPollNoData) DecodeFromBytes(data []byte, df gopacket.Deco
 
 type Dot11DataQOS struct {
 	Dot11Ctrl
-	TID       uint8 /* Traffic IDentifier */
-	EOSP      bool  /* End of service period */
-	AckPolicy Dot11AckPolicy
-	TXOP      uint8
 }
 
 func (m *Dot11DataQOS) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
-	if len(data) < 4 {
-		df.SetTruncated()
-		return fmt.Errorf("Dot11DataQOS length %v too short, %v required", len(data), 4)
-	}
-	m.TID = (uint8(data[0]) & 0x0F)
-	m.EOSP = (uint8(data[0]) & 0x10) == 0x10
-	m.AckPolicy = Dot11AckPolicy((uint8(data[0]) & 0x60) >> 5)
-	m.TXOP = uint8(data[1])
-	// TODO: Mesh Control bytes 2:4
-	m.BaseLayer = BaseLayer{Contents: data[0:4], Payload: data[4:]}
+	m.BaseLayer = BaseLayer{Payload: data}
 	return nil
 }
 
@@ -802,7 +1477,7 @@ func (m *Dot11InformationElement) DecodeFromBytes(data []byte, df gopacket.Decod
 
 func (d *Dot11InformationElement) String() string {
 	if d.ID == 0 {
-		return fmt.Sprintf("802.11 Information Element (SSID: %v)", string(d.Info))
+		return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, SSID: %v)", d.ID, d.Length, string(d.Info))
 	} else if d.ID == 1 {
 		rates := ""
 		for i := 0; i < len(d.Info); i++ {
@@ -812,9 +1487,9 @@ func (d *Dot11InformationElement) String() string {
 				rates += fmt.Sprintf("%.1f* ", float32(d.Info[i]&0x7F)*0.5)
 			}
 		}
-		return fmt.Sprintf("802.11 Information Element (Rates: %s Mbit)", rates)
+		return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, Rates: %s Mbit)", d.ID, d.Length, rates)
 	} else if d.ID == 221 {
-		return fmt.Sprintf("802.11 Information Element (Vendor: ID: %v, Length: %v, OUI: %X, Info: %X)", d.ID, d.Length, d.OUI, d.Info)
+		return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, OUI: %X, Info: %X)", d.ID, d.Length, d.OUI, d.Info)
 	} else {
 		return fmt.Sprintf("802.11 Information Element (ID: %v, Length: %v, Info: %X)", d.ID, d.Length, d.Info)
 	}

+ 236 - 0
vendor/github.com/google/gopacket/layers/eapol.go

@@ -8,6 +8,7 @@ package layers
 
 import (
 	"encoding/binary"
+	"fmt"
 	"github.com/google/gopacket"
 )
 
@@ -55,3 +56,238 @@ func decodeEAPOL(data []byte, p gopacket.PacketBuilder) error {
 	e := &EAPOL{}
 	return decodingLayerDecoder(e, data, p)
 }
+
+// EAPOLKeyDescriptorType is an enumeration of key descriptor types
+// as specified by 802.1x in the EAPOL-Key frame
+type EAPOLKeyDescriptorType uint8
+
+// Enumeration of EAPOLKeyDescriptorType
+const (
+	EAPOLKeyDescriptorTypeRC4   EAPOLKeyDescriptorType = 1
+	EAPOLKeyDescriptorTypeDot11 EAPOLKeyDescriptorType = 2
+	EAPOLKeyDescriptorTypeWPA   EAPOLKeyDescriptorType = 254
+)
+
+func (kdt EAPOLKeyDescriptorType) String() string {
+	switch kdt {
+	case EAPOLKeyDescriptorTypeRC4:
+		return "RC4"
+	case EAPOLKeyDescriptorTypeDot11:
+		return "802.11"
+	case EAPOLKeyDescriptorTypeWPA:
+		return "WPA"
+	default:
+		return fmt.Sprintf("unknown descriptor type %d", kdt)
+	}
+}
+
+// EAPOLKeyDescriptorVersion is an enumeration of versions specifying the
+// encryption algorithm for the key data and the authentication for the
+// message integrity code (MIC)
+type EAPOLKeyDescriptorVersion uint8
+
+// Enumeration of EAPOLKeyDescriptorVersion
+const (
+	EAPOLKeyDescriptorVersionOther       EAPOLKeyDescriptorVersion = 0
+	EAPOLKeyDescriptorVersionRC4HMACMD5  EAPOLKeyDescriptorVersion = 1
+	EAPOLKeyDescriptorVersionAESHMACSHA1 EAPOLKeyDescriptorVersion = 2
+	EAPOLKeyDescriptorVersionAES128CMAC  EAPOLKeyDescriptorVersion = 3
+)
+
+func (v EAPOLKeyDescriptorVersion) String() string {
+	switch v {
+	case EAPOLKeyDescriptorVersionOther:
+		return "Other"
+	case EAPOLKeyDescriptorVersionRC4HMACMD5:
+		return "RC4-HMAC-MD5"
+	case EAPOLKeyDescriptorVersionAESHMACSHA1:
+		return "AES-HMAC-SHA1-128"
+	case EAPOLKeyDescriptorVersionAES128CMAC:
+		return "AES-128-CMAC"
+	default:
+		return fmt.Sprintf("unknown version %d", v)
+	}
+}
+
+// EAPOLKeyType is an enumeration of key derivation types describing
+// the purpose of the keys being derived.
+type EAPOLKeyType uint8
+
+// Enumeration of EAPOLKeyType
+const (
+	EAPOLKeyTypeGroupSMK EAPOLKeyType = 0
+	EAPOLKeyTypePairwise EAPOLKeyType = 1
+)
+
+func (kt EAPOLKeyType) String() string {
+	switch kt {
+	case EAPOLKeyTypeGroupSMK:
+		return "Group/SMK"
+	case EAPOLKeyTypePairwise:
+		return "Pairwise"
+	default:
+		return fmt.Sprintf("unknown key type %d", kt)
+	}
+}
+
+// EAPOLKey defines an EAPOL-Key frame for 802.1x authentication
+type EAPOLKey struct {
+	BaseLayer
+	KeyDescriptorType    EAPOLKeyDescriptorType
+	KeyDescriptorVersion EAPOLKeyDescriptorVersion
+	KeyType              EAPOLKeyType
+	KeyIndex             uint8
+	Install              bool
+	KeyACK               bool
+	KeyMIC               bool
+	Secure               bool
+	MICError             bool
+	Request              bool
+	HasEncryptedKeyData  bool
+	SMKMessage           bool
+	KeyLength            uint16
+	ReplayCounter        uint64
+	Nonce                []byte
+	IV                   []byte
+	RSC                  uint64
+	ID                   uint64
+	MIC                  []byte
+	KeyDataLength        uint16
+	EncryptedKeyData     []byte
+}
+
+// LayerType returns LayerTypeEAPOLKey.
+func (ek *EAPOLKey) LayerType() gopacket.LayerType {
+	return LayerTypeEAPOLKey
+}
+
+// NextLayerType returns layers.LayerTypeDot11InformationElement if the key
+// data exists and is unencrypted, otherwise it does not expect a next layer.
+func (ek *EAPOLKey) NextLayerType() gopacket.LayerType {
+	if !ek.HasEncryptedKeyData && ek.KeyDataLength > 0 {
+		return LayerTypeDot11InformationElement
+	}
+	return gopacket.LayerTypePayload
+}
+
+const eapolKeyFrameLen = 95
+
+// DecodeFromBytes decodes the given bytes into this layer.
+func (ek *EAPOLKey) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < eapolKeyFrameLen {
+		df.SetTruncated()
+		return fmt.Errorf("EAPOLKey length %v too short, %v required",
+			len(data), eapolKeyFrameLen)
+	}
+
+	ek.KeyDescriptorType = EAPOLKeyDescriptorType(data[0])
+
+	info := binary.BigEndian.Uint16(data[1:3])
+	ek.KeyDescriptorVersion = EAPOLKeyDescriptorVersion(info & 0x0007)
+	ek.KeyType = EAPOLKeyType((info & 0x0008) >> 3)
+	ek.KeyIndex = uint8((info & 0x0030) >> 4)
+	ek.Install = (info & 0x0040) != 0
+	ek.KeyACK = (info & 0x0080) != 0
+	ek.KeyMIC = (info & 0x0100) != 0
+	ek.Secure = (info & 0x0200) != 0
+	ek.MICError = (info & 0x0400) != 0
+	ek.Request = (info & 0x0800) != 0
+	ek.HasEncryptedKeyData = (info & 0x1000) != 0
+	ek.SMKMessage = (info & 0x2000) != 0
+
+	ek.KeyLength = binary.BigEndian.Uint16(data[3:5])
+	ek.ReplayCounter = binary.BigEndian.Uint64(data[5:13])
+
+	ek.Nonce = data[13:45]
+	ek.IV = data[45:61]
+	ek.RSC = binary.BigEndian.Uint64(data[61:69])
+	ek.ID = binary.BigEndian.Uint64(data[69:77])
+	ek.MIC = data[77:93]
+
+	ek.KeyDataLength = binary.BigEndian.Uint16(data[93:95])
+
+	totalLength := eapolKeyFrameLen + int(ek.KeyDataLength)
+	if len(data) < totalLength {
+		df.SetTruncated()
+		return fmt.Errorf("EAPOLKey data length %d too short, %d required",
+			len(data)-eapolKeyFrameLen, ek.KeyDataLength)
+	}
+
+	if ek.HasEncryptedKeyData {
+		ek.EncryptedKeyData = data[eapolKeyFrameLen:totalLength]
+		ek.BaseLayer = BaseLayer{
+			Contents: data[:totalLength],
+			Payload:  data[totalLength:],
+		}
+	} else {
+		ek.BaseLayer = BaseLayer{
+			Contents: data[:eapolKeyFrameLen],
+			Payload:  data[eapolKeyFrameLen:],
+		}
+	}
+
+	return nil
+}
+
+// SerializeTo writes the serialized form of this layer into the
+// SerializationBuffer, implementing gopacket.SerializableLayer.
+// See the docs for gopacket.SerializableLayer for more info.
+func (ek *EAPOLKey) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	buf, err := b.PrependBytes(eapolKeyFrameLen + len(ek.EncryptedKeyData))
+	if err != nil {
+		return err
+	}
+
+	buf[0] = byte(ek.KeyDescriptorType)
+
+	var info uint16
+	info |= uint16(ek.KeyDescriptorVersion)
+	info |= uint16(ek.KeyType) << 3
+	info |= uint16(ek.KeyIndex) << 4
+	if ek.Install {
+		info |= 0x0040
+	}
+	if ek.KeyACK {
+		info |= 0x0080
+	}
+	if ek.KeyMIC {
+		info |= 0x0100
+	}
+	if ek.Secure {
+		info |= 0x0200
+	}
+	if ek.MICError {
+		info |= 0x0400
+	}
+	if ek.Request {
+		info |= 0x0800
+	}
+	if ek.HasEncryptedKeyData {
+		info |= 0x1000
+	}
+	if ek.SMKMessage {
+		info |= 0x2000
+	}
+	binary.BigEndian.PutUint16(buf[1:3], info)
+
+	binary.BigEndian.PutUint16(buf[3:5], ek.KeyLength)
+	binary.BigEndian.PutUint64(buf[5:13], ek.ReplayCounter)
+
+	copy(buf[13:45], ek.Nonce)
+	copy(buf[45:61], ek.IV)
+	binary.BigEndian.PutUint64(buf[61:69], ek.RSC)
+	binary.BigEndian.PutUint64(buf[69:77], ek.ID)
+	copy(buf[77:93], ek.MIC)
+
+	binary.BigEndian.PutUint16(buf[93:95], ek.KeyDataLength)
+	if len(ek.EncryptedKeyData) > 0 {
+		copy(buf[95:95+len(ek.EncryptedKeyData)], ek.EncryptedKeyData)
+	}
+
+	return nil
+}
+
+func decodeEAPOLKey(data []byte, p gopacket.PacketBuilder) error {
+	ek := &EAPOLKey{}
+	return decodingLayerDecoder(ek, data, p)
+}

+ 16 - 0
vendor/github.com/google/gopacket/layers/enums.go

@@ -10,6 +10,7 @@ package layers
 import (
 	"errors"
 	"fmt"
+	"runtime"
 
 	"github.com/google/gopacket"
 )
@@ -49,6 +50,7 @@ const (
 	EthernetTypeNortelDiscovery             EthernetType = 0x01a2
 	EthernetTypeTransparentEthernetBridging EthernetType = 0x6558
 	EthernetTypeDot1Q                       EthernetType = 0x8100
+	EthernetTypePPP                         EthernetType = 0x880b
 	EthernetTypePPPoEDiscovery              EthernetType = 0x8863
 	EthernetTypePPPoESession                EthernetType = 0x8864
 	EthernetTypeMPLSUnicast                 EthernetType = 0x8847
@@ -219,12 +221,17 @@ func (d Dot11Type) MainType() Dot11Type {
 	return d & dot11TypeMask
 }
 
+func (d Dot11Type) QOS() bool {
+	return d&dot11QOSMask == Dot11TypeDataQOSData
+}
+
 const (
 	Dot11TypeMgmt     Dot11Type = 0x00
 	Dot11TypeCtrl     Dot11Type = 0x01
 	Dot11TypeData     Dot11Type = 0x02
 	Dot11TypeReserved Dot11Type = 0x03
 	dot11TypeMask               = 0x03
+	dot11QOSMask                = 0x23
 
 	// The following are type/subtype conglomerations.
 
@@ -305,6 +312,7 @@ func initActualTypeData() {
 	EthernetTypeMetadata[EthernetTypeIPv6] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6}
 	EthernetTypeMetadata[EthernetTypeARP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeARP), Name: "ARP", LayerType: LayerTypeARP}
 	EthernetTypeMetadata[EthernetTypeDot1Q] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot1Q), Name: "Dot1Q", LayerType: LayerTypeDot1Q}
+	EthernetTypeMetadata[EthernetTypePPP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPP), Name: "PPP", LayerType: LayerTypePPP}
 	EthernetTypeMetadata[EthernetTypePPPoEDiscovery] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPPoE), Name: "PPPoEDiscovery", LayerType: LayerTypePPPoE}
 	EthernetTypeMetadata[EthernetTypePPPoESession] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePPPoE), Name: "PPPoESession", LayerType: LayerTypePPPoE}
 	EthernetTypeMetadata[EthernetTypeEthernetCTP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEthernetCTP), Name: "EthernetCTP", LayerType: LayerTypeEthernetCTP}
@@ -370,6 +378,13 @@ func initActualTypeData() {
 	LinkTypeMetadata[LinkTypeLoop] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLoopback), Name: "Loop"}
 	LinkTypeMetadata[LinkTypeIEEE802_11] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeDot11), Name: "802.11"}
 	LinkTypeMetadata[LinkTypeRaw] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: "Raw"}
+	// See https://github.com/the-tcpdump-group/libpcap/blob/170f717e6e818cdc4bcbbfd906b63088eaa88fa0/pcap/dlt.h#L85
+	// Or https://github.com/wireshark/wireshark/blob/854cfe53efe44080609c78053ecfb2342ad84a08/wiretap/pcap-common.c#L508
+	if runtime.GOOS == "openbsd" {
+		LinkTypeMetadata[14] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: "Raw"}
+	} else {
+		LinkTypeMetadata[12] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4or6), Name: "Raw"}
+	}
 	LinkTypeMetadata[LinkTypePFLog] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodePFLog), Name: "PFLog"}
 	LinkTypeMetadata[LinkTypeIEEE80211Radio] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeRadioTap), Name: "RadioTap"}
 	LinkTypeMetadata[LinkTypeLinuxUSB] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeUSB), Name: "USB"}
@@ -379,6 +394,7 @@ func initActualTypeData() {
 	FDDIFrameControlMetadata[FDDIFrameControlLLC] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeLLC), Name: "LLC"}
 
 	EAPOLTypeMetadata[EAPOLTypeEAP] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAP), Name: "EAP", LayerType: LayerTypeEAP}
+	EAPOLTypeMetadata[EAPOLTypeKey] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeEAPOLKey), Name: "EAPOLKey", LayerType: LayerTypeEAPOLKey}
 
 	ProtocolFamilyMetadata[ProtocolFamilyIPv4] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv4), Name: "IPv4", LayerType: LayerTypeIPv4}
 	ProtocolFamilyMetadata[ProtocolFamilyIPv6BSD] = EnumMetadata{DecodeWith: gopacket.DecodeFunc(decodeIPv6), Name: "IPv6", LayerType: LayerTypeIPv6}

+ 1 - 0
vendor/github.com/google/gopacket/layers/ethernet.go

@@ -46,6 +46,7 @@ func (eth *Ethernet) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) er
 	eth.SrcMAC = net.HardwareAddr(data[6:12])
 	eth.EthernetType = EthernetType(binary.BigEndian.Uint16(data[12:14]))
 	eth.BaseLayer = BaseLayer{data[:14], data[14:]}
+	eth.Length = 0
 	if eth.EthernetType < 0x0600 {
 		eth.Length = uint16(eth.EthernetType)
 		eth.EthernetType = EthernetTypeLLC

+ 18 - 6
vendor/github.com/google/gopacket/layers/geneve.go

@@ -8,6 +8,7 @@ package layers
 
 import (
 	"encoding/binary"
+	"errors"
 
 	"github.com/google/gopacket"
 )
@@ -52,19 +53,25 @@ func (gn *Geneve) LayerType() gopacket.LayerType { return LayerTypeGeneve }
 func decodeGeneveOption(data []byte, gn *Geneve) (*GeneveOption, uint8) {
 	opt := &GeneveOption{}
 
-	opt.Class = binary.BigEndian.Uint16(data[0:1])
+	opt.Class = binary.BigEndian.Uint16(data[0:2])
 	opt.Type = data[2]
 	opt.Flags = data[3] >> 4
-	opt.Length = data[3] & 0xf
+	opt.Length = (data[3]&0xf)*4 + 4
 
+	opt.Data = make([]byte, opt.Length-4)
 	copy(opt.Data, data[4:opt.Length])
 
-	return opt, 4 + opt.Length
+	return opt, opt.Length
 }
 
 func (gn *Geneve) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < 7 {
+		df.SetTruncated()
+		return errors.New("geneve packet too short")
+	}
+
 	gn.Version = data[0] >> 7
-	gn.OptionsLength = data[0] & 0x3f
+	gn.OptionsLength = (data[0] & 0x3f) * 4
 
 	gn.OAMPacket = data[1]&0x80 > 0
 	gn.CriticalOption = data[1]&0x40 > 0
@@ -74,12 +81,17 @@ func (gn *Geneve) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error
 	copy(buf[1:], data[4:7])
 	gn.VNI = binary.BigEndian.Uint32(buf[:])
 
-	offset, length := uint8(8), gn.OptionsLength
+	offset, length := uint8(8), int32(gn.OptionsLength)
+	if len(data) < int(length+7) {
+		df.SetTruncated()
+		return errors.New("geneve packet too short")
+	}
+
 	for length > 0 {
 		opt, len := decodeGeneveOption(data[offset:], gn)
 		gn.Options = append(gn.Options, opt)
 
-		length -= len
+		length -= int32(len)
 		offset += len
 	}
 

+ 20 - 5
vendor/github.com/google/gopacket/layers/gre.go

@@ -15,11 +15,11 @@ import (
 // GRE is a Generic Routing Encapsulation header.
 type GRE struct {
 	BaseLayer
-	ChecksumPresent, RoutingPresent, KeyPresent, SeqPresent, StrictSourceRoute bool
-	RecursionControl, Flags, Version                                           uint8
-	Protocol                                                                   EthernetType
-	Checksum, Offset                                                           uint16
-	Key, Seq                                                                   uint32
+	ChecksumPresent, RoutingPresent, KeyPresent, SeqPresent, StrictSourceRoute, AckPresent bool
+	RecursionControl, Flags, Version                                                       uint8
+	Protocol                                                                               EthernetType
+	Checksum, Offset                                                                       uint16
+	Key, Seq, Ack                                                                          uint32
 	*GRERouting
 }
 
@@ -42,6 +42,7 @@ func (g *GRE) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
 	g.KeyPresent = data[0]&0x20 != 0
 	g.SeqPresent = data[0]&0x10 != 0
 	g.StrictSourceRoute = data[0]&0x08 != 0
+	g.AckPresent = data[1]&0x80 != 0
 	g.RecursionControl = data[0] & 0x7
 	g.Flags = data[1] >> 3
 	g.Version = data[1] & 0x7
@@ -77,6 +78,10 @@ func (g *GRE) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
 			tail = &sre.Next
 		}
 	}
+	if g.AckPresent {
+		g.Ack = binary.BigEndian.Uint32(data[offset : offset+4])
+		offset += 4
+	}
 	g.BaseLayer = BaseLayer{data[:offset], data[offset:]}
 	return nil
 }
@@ -102,6 +107,9 @@ func (g *GRE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt
 		}
 		size += 4
 	}
+	if g.AckPresent {
+		size += 4
+	}
 	buf, err := b.PrependBytes(size)
 	if err != nil {
 		return err
@@ -124,6 +132,9 @@ func (g *GRE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt
 	if g.StrictSourceRoute {
 		buf[0] |= 0x08
 	}
+	if g.AckPresent {
+		buf[1] |= 0x80
+	}
 	buf[0] |= g.RecursionControl
 	buf[1] |= g.Flags << 3
 	buf[1] |= g.Version
@@ -159,6 +170,10 @@ func (g *GRE) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt
 		// Terminate routing field with a "NULL" SRE.
 		binary.BigEndian.PutUint32(buf[offset:offset+4], 0)
 	}
+	if g.AckPresent {
+		binary.BigEndian.PutUint32(buf[offset:offset+4], g.Ack)
+		offset += 4
+	}
 	if g.ChecksumPresent {
 		if opts.ComputeChecksums {
 			g.Checksum = tcpipChecksum(b.Bytes(), 0)

+ 181 - 0
vendor/github.com/google/gopacket/layers/gtp.go

@@ -0,0 +1,181 @@
+// Copyright 2017 Google, Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+//
+
+package layers
+
+import (
+	"encoding/binary"
+	"fmt"
+	"github.com/google/gopacket"
+)
+
+const gtpMinimumSizeInBytes int = 8
+
+// GTPExtensionHeader is used to carry extra data and enable future extensions of the GTP  without the need to use another version number.
+type GTPExtensionHeader struct {
+	Type    uint8
+	Content []byte
+}
+
+// GTPv1U protocol is used to exchange user data over GTP tunnels across the Sx interfaces.
+// Defined in https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1595
+type GTPv1U struct {
+	BaseLayer
+	Version             uint8
+	ProtocolType        uint8
+	Reserved            uint8
+	ExtensionHeaderFlag bool
+	SequenceNumberFlag  bool
+	NPDUFlag            bool
+	MessageType         uint8
+	MessageLength       uint16
+	TEID                uint32
+	SequenceNumber      uint16
+	NPDU                uint8
+	GTPExtensionHeaders []GTPExtensionHeader
+}
+
+// LayerType returns LayerTypeGTPV1U
+func (g *GTPv1U) LayerType() gopacket.LayerType { return LayerTypeGTPv1U }
+
+// DecodeFromBytes analyses a byte slice and attempts to decode it as a GTPv1U packet
+func (g *GTPv1U) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	hLen := gtpMinimumSizeInBytes
+	dLen := len(data)
+	if dLen < hLen {
+		return fmt.Errorf("GTP packet too small: %d bytes", dLen)
+	}
+	g.Version = (data[0] >> 5) & 0x07
+	g.ProtocolType = (data[0] >> 4) & 0x01
+	g.Reserved = (data[0] >> 3) & 0x01
+	g.SequenceNumberFlag = ((data[0] >> 1) & 0x01) == 1
+	g.NPDUFlag = (data[0] & 0x01) == 1
+	g.ExtensionHeaderFlag = ((data[0] >> 2) & 0x01) == 1
+	g.MessageType = data[1]
+	g.MessageLength = binary.BigEndian.Uint16(data[2:4])
+	pLen := 8 + g.MessageLength
+	if uint16(dLen) < pLen {
+		return fmt.Errorf("GTP packet too small: %d bytes", dLen)
+	}
+	//  Field used to multiplex different connections in the same GTP tunnel.
+	g.TEID = binary.BigEndian.Uint32(data[4:8])
+	cIndex := uint16(hLen)
+	if g.SequenceNumberFlag || g.NPDUFlag || g.ExtensionHeaderFlag {
+		hLen += 4
+		cIndex += 4
+		if dLen < hLen {
+			return fmt.Errorf("GTP packet too small: %d bytes", dLen)
+		}
+		if g.SequenceNumberFlag {
+			g.SequenceNumber = binary.BigEndian.Uint16(data[8:10])
+		}
+		if g.NPDUFlag {
+			g.NPDU = data[10]
+		}
+		if g.ExtensionHeaderFlag {
+			extensionFlag := true
+			for extensionFlag {
+				extensionType := uint8(data[cIndex-1])
+				extensionLength := uint(data[cIndex])
+				if extensionLength == 0 {
+					return fmt.Errorf("GTP packet with invalid extension header")
+				}
+				// extensionLength is in 4-octet units
+				lIndex := cIndex + (uint16(extensionLength) * 4)
+				if uint16(dLen) < lIndex {
+					fmt.Println(dLen, lIndex)
+					return fmt.Errorf("GTP packet with small extension header: %d bytes", dLen)
+				}
+				content := data[cIndex+1 : lIndex-1]
+				eh := GTPExtensionHeader{Type: extensionType, Content: content}
+				g.GTPExtensionHeaders = append(g.GTPExtensionHeaders, eh)
+				cIndex = lIndex
+				// Check if coming bytes are from an extension header
+				extensionFlag = data[cIndex-1] != 0
+
+			}
+		}
+	}
+	g.BaseLayer = BaseLayer{Contents: data[:cIndex], Payload: data[cIndex:]}
+	return nil
+
+}
+
+// SerializeTo writes the serialized form of this layer into the
+// SerializationBuffer, implementing gopacket.SerializableLayer.
+// See the docs for gopacket.SerializableLayer for more info.
+func (g *GTPv1U) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	data, err := b.PrependBytes(gtpMinimumSizeInBytes)
+	if err != nil {
+		return err
+	}
+	data[0] |= (g.Version << 5)
+	data[0] |= (1 << 4)
+	if len(g.GTPExtensionHeaders) > 0 {
+		data[0] |= 0x04
+		g.ExtensionHeaderFlag = true
+	}
+	if g.SequenceNumberFlag {
+		data[0] |= 0x02
+	}
+	if g.NPDUFlag {
+		data[0] |= 0x01
+	}
+	data[1] = g.MessageType
+	binary.BigEndian.PutUint16(data[2:4], g.MessageLength)
+	binary.BigEndian.PutUint32(data[4:8], g.TEID)
+	if g.ExtensionHeaderFlag || g.SequenceNumberFlag || g.NPDUFlag {
+		data, err := b.AppendBytes(4)
+		if err != nil {
+			return err
+		}
+		binary.BigEndian.PutUint16(data[:2], g.SequenceNumber)
+		data[2] = g.NPDU
+		for _, eh := range g.GTPExtensionHeaders {
+			data[len(data)-1] = eh.Type
+			lContent := len(eh.Content)
+			// extensionLength is in 4-octet units
+			extensionLength := (lContent + 2) / 4
+			// Get two extra byte for the next extension header type and length
+			data, err = b.AppendBytes(lContent + 2)
+			if err != nil {
+				return err
+			}
+			data[0] = byte(extensionLength)
+			copy(data[1:lContent+1], eh.Content)
+		}
+	}
+	return nil
+
+}
+
+// CanDecode returns a set of layers that GTP objects can decode.
+func (g *GTPv1U) CanDecode() gopacket.LayerClass {
+	return LayerTypeGTPv1U
+}
+
+// NextLayerType specifies the next layer that GoPacket should attempt to
+func (g *GTPv1U) NextLayerType() gopacket.LayerType {
+	version := uint8(g.LayerPayload()[0]) >> 4
+	if version == 4 {
+		return LayerTypeIPv4
+	} else if version == 6 {
+		return LayerTypeIPv6
+	} else {
+		return LayerTypePPP
+	}
+}
+
+func decodeGTPv1u(data []byte, p gopacket.PacketBuilder) error {
+	gtp := &GTPv1U{}
+	err := gtp.DecodeFromBytes(data, p)
+	if err != nil {
+		return err
+	}
+	p.AddLayer(gtp)
+	return p.NextDecoder(gtp.NextLayerType())
+}

+ 25 - 0
vendor/github.com/google/gopacket/layers/icmp6.go

@@ -24,12 +24,21 @@ const (
 	ICMPv6TypeParameterProblem       = 4
 	ICMPv6TypeEchoRequest            = 128
 	ICMPv6TypeEchoReply              = 129
+
 	// The following are from RFC 4861
 	ICMPv6TypeRouterSolicitation    = 133
 	ICMPv6TypeRouterAdvertisement   = 134
 	ICMPv6TypeNeighborSolicitation  = 135
 	ICMPv6TypeNeighborAdvertisement = 136
 	ICMPv6TypeRedirect              = 137
+
+	// The following are from RFC 2710
+	ICMPv6TypeMLDv1MulticastListenerQueryMessage  = 130
+	ICMPv6TypeMLDv1MulticastListenerReportMessage = 131
+	ICMPv6TypeMLDv1MulticastListenerDoneMessage   = 132
+
+	// The following are from RFC 3810
+	ICMPv6TypeMLDv2MulticastListenerReportMessageV2 = 143
 )
 
 const (
@@ -220,6 +229,10 @@ func (i *ICMPv6) CanDecode() gopacket.LayerClass {
 // NextLayerType returns the layer type contained by this DecodingLayer.
 func (i *ICMPv6) NextLayerType() gopacket.LayerType {
 	switch i.TypeCode.Type() {
+	case ICMPv6TypeEchoRequest:
+		return LayerTypeICMPv6Echo
+	case ICMPv6TypeEchoReply:
+		return LayerTypeICMPv6Echo
 	case ICMPv6TypeRouterSolicitation:
 		return LayerTypeICMPv6RouterSolicitation
 	case ICMPv6TypeRouterAdvertisement:
@@ -230,6 +243,18 @@ func (i *ICMPv6) NextLayerType() gopacket.LayerType {
 		return LayerTypeICMPv6NeighborAdvertisement
 	case ICMPv6TypeRedirect:
 		return LayerTypeICMPv6Redirect
+	case ICMPv6TypeMLDv1MulticastListenerQueryMessage: // Same Code for MLDv1 Query and MLDv2 Query
+		if len(i.Payload) > 20 { // Only payload size differs
+			return LayerTypeMLDv2MulticastListenerQuery
+		} else {
+			return LayerTypeMLDv1MulticastListenerQuery
+		}
+	case ICMPv6TypeMLDv1MulticastListenerDoneMessage:
+		return LayerTypeMLDv1MulticastListenerDone
+	case ICMPv6TypeMLDv1MulticastListenerReportMessage:
+		return LayerTypeMLDv1MulticastListenerReport
+	case ICMPv6TypeMLDv2MulticastListenerReportMessageV2:
+		return LayerTypeMLDv2MulticastListenerReport
 	}
 
 	return gopacket.LayerTypePayload

+ 85 - 2
vendor/github.com/google/gopacket/layers/icmp6msg.go

@@ -54,6 +54,13 @@ const (
 	ICMPv6OptMTU
 )
 
+// ICMPv6Echo represents the structure of a ping.
+type ICMPv6Echo struct {
+	BaseLayer
+	Identifier uint16
+	SeqNumber  uint16
+}
+
 // ICMPv6RouterSolicitation is sent by hosts to find routers.
 type ICMPv6RouterSolicitation struct {
 	BaseLayer
@@ -122,6 +129,47 @@ func (i ICMPv6Opt) String() string {
 	}
 }
 
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (i *ICMPv6Echo) CanDecode() gopacket.LayerClass {
+	return LayerTypeICMPv6Echo
+}
+
+// LayerType returns LayerTypeICMPv6Echo.
+func (i *ICMPv6Echo) LayerType() gopacket.LayerType {
+	return LayerTypeICMPv6Echo
+}
+
+// NextLayerType returns the layer type contained by this DecodingLayer.
+func (i *ICMPv6Echo) NextLayerType() gopacket.LayerType {
+	return gopacket.LayerTypePayload
+}
+
+// DecodeFromBytes decodes the given bytes into this layer.
+func (i *ICMPv6Echo) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < 4 {
+		df.SetTruncated()
+		return errors.New("ICMP layer less then 4 bytes for ICMPv6 Echo")
+	}
+	i.Identifier = binary.BigEndian.Uint16(data[0:2])
+	i.SeqNumber = binary.BigEndian.Uint16(data[2:4])
+
+	return nil
+}
+
+// SerializeTo writes the serialized form of this layer into the
+// SerializationBuffer, implementing gopacket.SerializableLayer.
+// See the docs for gopacket.SerializableLayer for more info.
+func (i *ICMPv6Echo) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+	buf, err := b.PrependBytes(4)
+	if err != nil {
+		return err
+	}
+
+	binary.BigEndian.PutUint16(buf, i.Identifier)
+	binary.BigEndian.PutUint16(buf[2:], i.SeqNumber)
+	return nil
+}
+
 // LayerType returns LayerTypeICMPv6.
 func (i *ICMPv6RouterSolicitation) LayerType() gopacket.LayerType {
 	return LayerTypeICMPv6RouterSolicitation
@@ -163,6 +211,11 @@ func (i *ICMPv6RouterSolicitation) SerializeTo(b gopacket.SerializeBuffer, opts
 	return nil
 }
 
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (i *ICMPv6RouterSolicitation) CanDecode() gopacket.LayerClass {
+	return LayerTypeICMPv6RouterSolicitation
+}
+
 // LayerType returns LayerTypeICMPv6RouterAdvertisement.
 func (i *ICMPv6RouterAdvertisement) LayerType() gopacket.LayerType {
 	return LayerTypeICMPv6RouterAdvertisement
@@ -215,16 +268,21 @@ func (i *ICMPv6RouterAdvertisement) SerializeTo(b gopacket.SerializeBuffer, opts
 	return nil
 }
 
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (i *ICMPv6RouterAdvertisement) CanDecode() gopacket.LayerClass {
+	return LayerTypeICMPv6RouterAdvertisement
+}
+
 // ManagedAddressConfig is true when addresses are available via DHCPv6. If
 // set, the OtherConfig flag is redundant.
 func (i *ICMPv6RouterAdvertisement) ManagedAddressConfig() bool {
-	return i.Flags&0x80 != 1
+	return i.Flags&0x80 != 0
 }
 
 // OtherConfig is true when there is other configuration information available
 // via DHCPv6. For example, DNS-related information.
 func (i *ICMPv6RouterAdvertisement) OtherConfig() bool {
-	return i.Flags&0x40 != 1
+	return i.Flags&0x40 != 0
 }
 
 // LayerType returns LayerTypeICMPv6NeighborSolicitation.
@@ -271,6 +329,11 @@ func (i *ICMPv6NeighborSolicitation) SerializeTo(b gopacket.SerializeBuffer, opt
 	return nil
 }
 
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (i *ICMPv6NeighborSolicitation) CanDecode() gopacket.LayerClass {
+	return LayerTypeICMPv6NeighborSolicitation
+}
+
 // LayerType returns LayerTypeICMPv6NeighborAdvertisement.
 func (i *ICMPv6NeighborAdvertisement) LayerType() gopacket.LayerType {
 	return LayerTypeICMPv6NeighborAdvertisement
@@ -317,6 +380,11 @@ func (i *ICMPv6NeighborAdvertisement) SerializeTo(b gopacket.SerializeBuffer, op
 	return nil
 }
 
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (i *ICMPv6NeighborAdvertisement) CanDecode() gopacket.LayerClass {
+	return LayerTypeICMPv6NeighborAdvertisement
+}
+
 // Router indicates whether the sender is a router or not.
 func (i *ICMPv6NeighborAdvertisement) Router() bool {
 	return i.Flags&0x80 != 0
@@ -379,6 +447,11 @@ func (i *ICMPv6Redirect) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.S
 	return nil
 }
 
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (i *ICMPv6Redirect) CanDecode() gopacket.LayerClass {
+	return LayerTypeICMPv6Redirect
+}
+
 func (i ICMPv6Option) String() string {
 	hd := hex.EncodeToString(i.Data)
 	if len(hd) > 0 {
@@ -431,6 +504,11 @@ func (i *ICMPv6Options) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback)
 		// unit is 8 octets, convert to bytes
 		length := int(data[1]) * 8
 
+		if length == 0 {
+			df.SetTruncated()
+			return errors.New("ICMPv6 message option with length 0")
+		}
+
 		if len(data) < length {
 			df.SetTruncated()
 			return fmt.Errorf("ICMP layer only %v bytes for ICMPv6 message option with length %v", len(data), length)
@@ -469,6 +547,11 @@ func (i *ICMPv6Options) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Se
 	return nil
 }
 
+func decodeICMPv6Echo(data []byte, p gopacket.PacketBuilder) error {
+	i := &ICMPv6Echo{}
+	return decodingLayerDecoder(i, data, p)
+}
+
 func decodeICMPv6RouterSolicitation(data []byte, p gopacket.PacketBuilder) error {
 	i := &ICMPv6RouterSolicitation{}
 	return decodingLayerDecoder(i, data, p)

+ 20 - 6
vendor/github.com/google/gopacket/layers/ip4.go

@@ -186,6 +186,10 @@ func (ip *IPv4) flagsfrags() (ff uint16) {
 
 // DecodeFromBytes decodes the given bytes into this layer.
 func (ip *IPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < 20 {
+		df.SetTruncated()
+		return fmt.Errorf("Invalid ip4 header. Length %d less than 20", len(data))
+	}
 	flagsfrags := binary.BigEndian.Uint16(data[6:8])
 
 	ip.Version = uint8(data[0]) >> 4
@@ -201,6 +205,7 @@ func (ip *IPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
 	ip.SrcIP = data[12:16]
 	ip.DstIP = data[16:20]
 	ip.Options = ip.Options[:0]
+	ip.Padding = nil
 	// Set up an initial guess for contents/payload... we'll reset these soon.
 	ip.BaseLayer = BaseLayer{Contents: data}
 
@@ -243,19 +248,28 @@ func (ip *IPv4) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
 			opt.OptionLength = 1
 			ip.Options = append(ip.Options, opt)
 			ip.Padding = data[1:]
-			break
+			return nil
 		case 1: // 1 byte padding
 			opt.OptionLength = 1
+			data = data[1:]
+			ip.Options = append(ip.Options, opt)
 		default:
+			if len(data) < 2 {
+				df.SetTruncated()
+				return fmt.Errorf("Invalid ip4 option length. Length %d less than 2", len(data))
+			}
 			opt.OptionLength = data[1]
+			if len(data) < int(opt.OptionLength) {
+				df.SetTruncated()
+				return fmt.Errorf("IP option length exceeds remaining IP header size, option type %v length %v", opt.OptionType, opt.OptionLength)
+			}
+			if opt.OptionLength <= 2 {
+				return fmt.Errorf("Invalid IP option type %v length %d. Must be greater than 2", opt.OptionType, opt.OptionLength)
+			}
 			opt.OptionData = data[2:opt.OptionLength]
-		}
-		if len(data) >= int(opt.OptionLength) {
 			data = data[opt.OptionLength:]
-		} else {
-			return fmt.Errorf("IP option length exceeds remaining IP header size, option type %v length %v", opt.OptionType, opt.OptionLength)
+			ip.Options = append(ip.Options, opt)
 		}
-		ip.Options = append(ip.Options, opt)
 	}
 	return nil
 }

+ 124 - 67
vendor/github.com/google/gopacket/layers/ip6.go

@@ -17,7 +17,8 @@ import (
 )
 
 const (
-	IPv6HopByHopOptionJumbogram = 0xC2 // RFC 2675
+	// IPv6HopByHopOptionJumbogram code as defined in RFC 2675
+	IPv6HopByHopOptionJumbogram = 0xC2
 )
 
 const (
@@ -42,10 +43,11 @@ type IPv6 struct {
 }
 
 // LayerType returns LayerTypeIPv6
-func (i *IPv6) LayerType() gopacket.LayerType { return LayerTypeIPv6 }
+func (ipv6 *IPv6) LayerType() gopacket.LayerType { return LayerTypeIPv6 }
 
-func (i *IPv6) NetworkFlow() gopacket.Flow {
-	return gopacket.NewFlow(EndpointIPv6, i.SrcIP, i.DstIP)
+// NetworkFlow returns this new Flow (EndpointIPv6, SrcIP, DstIP)
+func (ipv6 *IPv6) NetworkFlow() gopacket.Flow {
+	return gopacket.NewFlow(EndpointIPv6, ipv6.SrcIP, ipv6.DstIP)
 }
 
 // Search for Jumbo Payload TLV in IPv6HopByHop and return (length, true) if found
@@ -115,7 +117,7 @@ func setIPv6PayloadJumboLength(hbh []byte) error {
 		opt := hbh[offset]
 		if opt == 0 {
 			//Pad1
-			offset += 1
+			offset++
 			continue
 		}
 		optLen := int(hbh[offset+1])
@@ -134,7 +136,7 @@ func setIPv6PayloadJumboLength(hbh []byte) error {
 // SerializeTo writes the serialized form of this layer into the
 // SerializationBuffer, implementing gopacket.SerializableLayer.
 // See the docs for gopacket.SerializableLayer for more info.
-func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
+func (ipv6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
 	var jumbo bool
 	var err error
 
@@ -145,11 +147,11 @@ func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize
 		if opts.FixLengths {
 			// We need to set the length later because the hop-by-hop header may
 			// not exist or else need padding, so pLen may yet change
-			addIPv6JumboOption(ip6)
-		} else if ip6.HopByHop == nil {
+			addIPv6JumboOption(ipv6)
+		} else if ipv6.HopByHop == nil {
 			return fmt.Errorf("Cannot fit payload length of %d into IPv6 packet", pLen)
 		} else {
-			_, ok, err := getIPv6HopByHopJumboLength(ip6.HopByHop)
+			_, ok, err := getIPv6HopByHopJumboLength(ipv6.HopByHop)
 			if err != nil {
 				return err
 			}
@@ -158,12 +160,22 @@ func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize
 			}
 		}
 	}
-	if ip6.HopByHop != nil {
-		if ip6.NextHeader != IPProtocolIPv6HopByHop {
+
+	hbhAlreadySerialized := false
+	if ipv6.HopByHop != nil {
+		for _, l := range b.Layers() {
+			if l == LayerTypeIPv6HopByHop {
+				hbhAlreadySerialized = true
+				break
+			}
+		}
+	}
+	if ipv6.HopByHop != nil && !hbhAlreadySerialized {
+		if ipv6.NextHeader != IPProtocolIPv6HopByHop {
 			// Just fix it instead of throwing an error
-			ip6.NextHeader = IPProtocolIPv6HopByHop
+			ipv6.NextHeader = IPProtocolIPv6HopByHop
 		}
-		err = ip6.HopByHop.SerializeTo(b, opts)
+		err = ipv6.HopByHop.SerializeTo(b, opts)
 		if err != nil {
 			return err
 		}
@@ -176,6 +188,7 @@ func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize
 			}
 		}
 	}
+
 	if !jumbo && pLen > ipv6MaxPayloadLength {
 		return errors.New("Cannot fit payload into IPv6 header")
 	}
@@ -183,88 +196,98 @@ func (ip6 *IPv6) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Serialize
 	if err != nil {
 		return err
 	}
-	bytes[0] = (ip6.Version << 4) | (ip6.TrafficClass >> 4)
-	bytes[1] = (ip6.TrafficClass << 4) | uint8(ip6.FlowLabel>>16)
-	binary.BigEndian.PutUint16(bytes[2:], uint16(ip6.FlowLabel))
+	bytes[0] = (ipv6.Version << 4) | (ipv6.TrafficClass >> 4)
+	bytes[1] = (ipv6.TrafficClass << 4) | uint8(ipv6.FlowLabel>>16)
+	binary.BigEndian.PutUint16(bytes[2:], uint16(ipv6.FlowLabel))
 	if opts.FixLengths {
 		if jumbo {
-			ip6.Length = 0
+			ipv6.Length = 0
 		} else {
-			ip6.Length = uint16(pLen)
+			ipv6.Length = uint16(pLen)
 		}
 	}
-	binary.BigEndian.PutUint16(bytes[4:], ip6.Length)
-	bytes[6] = byte(ip6.NextHeader)
-	bytes[7] = byte(ip6.HopLimit)
-	if err := ip6.AddressTo16(); err != nil {
+	binary.BigEndian.PutUint16(bytes[4:], ipv6.Length)
+	bytes[6] = byte(ipv6.NextHeader)
+	bytes[7] = byte(ipv6.HopLimit)
+	if err := ipv6.AddressTo16(); err != nil {
 		return err
 	}
-	copy(bytes[8:], ip6.SrcIP)
-	copy(bytes[24:], ip6.DstIP)
+	copy(bytes[8:], ipv6.SrcIP)
+	copy(bytes[24:], ipv6.DstIP)
 	return nil
 }
 
-func (ip6 *IPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
-	ip6.Version = uint8(data[0]) >> 4
-	ip6.TrafficClass = uint8((binary.BigEndian.Uint16(data[0:2]) >> 4) & 0x00FF)
-	ip6.FlowLabel = binary.BigEndian.Uint32(data[0:4]) & 0x000FFFFF
-	ip6.Length = binary.BigEndian.Uint16(data[4:6])
-	ip6.NextHeader = IPProtocol(data[6])
-	ip6.HopLimit = data[7]
-	ip6.SrcIP = data[8:24]
-	ip6.DstIP = data[24:40]
-	ip6.HopByHop = nil
-	ip6.BaseLayer = BaseLayer{data[:40], data[40:]}
+// DecodeFromBytes implementation according to gopacket.DecodingLayer
+func (ipv6 *IPv6) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < 40 {
+		df.SetTruncated()
+		return fmt.Errorf("Invalid ip6 header. Length %d less than 40", len(data))
+	}
+	ipv6.Version = uint8(data[0]) >> 4
+	ipv6.TrafficClass = uint8((binary.BigEndian.Uint16(data[0:2]) >> 4) & 0x00FF)
+	ipv6.FlowLabel = binary.BigEndian.Uint32(data[0:4]) & 0x000FFFFF
+	ipv6.Length = binary.BigEndian.Uint16(data[4:6])
+	ipv6.NextHeader = IPProtocol(data[6])
+	ipv6.HopLimit = data[7]
+	ipv6.SrcIP = data[8:24]
+	ipv6.DstIP = data[24:40]
+	ipv6.HopByHop = nil
+	ipv6.BaseLayer = BaseLayer{data[:40], data[40:]}
 
 	// We treat a HopByHop IPv6 option as part of the IPv6 packet, since its
 	// options are crucial for understanding what's actually happening per packet.
-	if ip6.NextHeader == IPProtocolIPv6HopByHop {
-		err := ip6.hbh.DecodeFromBytes(ip6.Payload, df)
+	if ipv6.NextHeader == IPProtocolIPv6HopByHop {
+		err := ipv6.hbh.DecodeFromBytes(ipv6.Payload, df)
 		if err != nil {
 			return err
 		}
-		ip6.HopByHop = &ip6.hbh
-		pEnd, jumbo, err := getIPv6HopByHopJumboLength(ip6.HopByHop)
+		ipv6.HopByHop = &ipv6.hbh
+		pEnd, jumbo, err := getIPv6HopByHopJumboLength(ipv6.HopByHop)
 		if err != nil {
 			return err
 		}
-		if jumbo && ip6.Length == 0 {
+		if jumbo && ipv6.Length == 0 {
 			pEnd := int(pEnd)
-			if pEnd > len(ip6.Payload) {
+			if pEnd > len(ipv6.Payload) {
 				df.SetTruncated()
-				pEnd = len(ip6.Payload)
+				pEnd = len(ipv6.Payload)
 			}
-			ip6.Payload = ip6.Payload[:pEnd]
+			ipv6.Payload = ipv6.Payload[:pEnd]
 			return nil
-		} else if jumbo && ip6.Length != 0 {
+		} else if jumbo && ipv6.Length != 0 {
 			return errors.New("IPv6 has jumbo length and IPv6 length is not 0")
-		} else if !jumbo && ip6.Length == 0 {
+		} else if !jumbo && ipv6.Length == 0 {
 			return errors.New("IPv6 length 0, but HopByHop header does not have jumbogram option")
+		} else {
+			ipv6.Payload = ipv6.Payload[ipv6.hbh.ActualLength:]
 		}
 	}
 
-	if ip6.Length == 0 {
-		return fmt.Errorf("IPv6 length 0, but next header is %v, not HopByHop", ip6.NextHeader)
-	} else {
-		pEnd := int(ip6.Length)
-		if pEnd > len(ip6.Payload) {
-			df.SetTruncated()
-			pEnd = len(ip6.Payload)
-		}
-		ip6.Payload = ip6.Payload[:pEnd]
+	if ipv6.Length == 0 {
+		return fmt.Errorf("IPv6 length 0, but next header is %v, not HopByHop", ipv6.NextHeader)
+	}
+
+	pEnd := int(ipv6.Length)
+	if pEnd > len(ipv6.Payload) {
+		df.SetTruncated()
+		pEnd = len(ipv6.Payload)
 	}
+	ipv6.Payload = ipv6.Payload[:pEnd]
+
 	return nil
 }
 
-func (i *IPv6) CanDecode() gopacket.LayerClass {
+// CanDecode implementation according to gopacket.DecodingLayer
+func (ipv6 *IPv6) CanDecode() gopacket.LayerClass {
 	return LayerTypeIPv6
 }
 
-func (i *IPv6) NextLayerType() gopacket.LayerType {
-	if i.HopByHop != nil {
-		return i.HopByHop.NextHeader.LayerType()
+// NextLayerType implementation according to gopacket.DecodingLayer
+func (ipv6 *IPv6) NextLayerType() gopacket.LayerType {
+	if ipv6.HopByHop != nil {
+		return ipv6.HopByHop.NextHeader.LayerType()
 	}
-	return i.NextHeader.LayerType()
+	return ipv6.NextHeader.LayerType()
 }
 
 func decodeIPv6(data []byte, p gopacket.PacketBuilder) error {
@@ -384,10 +407,17 @@ type ipv6ExtensionBase struct {
 	ActualLength int
 }
 
-func decodeIPv6ExtensionBase(data []byte) (i ipv6ExtensionBase) {
+func decodeIPv6ExtensionBase(data []byte, df gopacket.DecodeFeedback) (i ipv6ExtensionBase, returnedErr error) {
+	if len(data) < 2 {
+		df.SetTruncated()
+		return ipv6ExtensionBase{}, fmt.Errorf("Invalid ip6-extension header. Length %d less than 2", len(data))
+	}
 	i.NextHeader = IPProtocol(data[0])
 	i.HeaderLength = data[1]
 	i.ActualLength = int(i.HeaderLength)*8 + 8
+	if len(data) < i.ActualLength {
+		return ipv6ExtensionBase{}, fmt.Errorf("Invalid ip6-extension header. Length %d less than specified length %d", len(data), i.ActualLength)
+	}
 	i.Contents = data[:i.ActualLength]
 	i.Payload = data[i.ActualLength:]
 	return
@@ -401,17 +431,23 @@ type IPv6ExtensionSkipper struct {
 	BaseLayer
 }
 
+// DecodeFromBytes implementation according to gopacket.DecodingLayer
 func (i *IPv6ExtensionSkipper) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
-	extension := decodeIPv6ExtensionBase(data)
+	extension, err := decodeIPv6ExtensionBase(data, df)
+	if err != nil {
+		return err
+	}
 	i.BaseLayer = BaseLayer{data[:extension.ActualLength], data[extension.ActualLength:]}
 	i.NextHeader = extension.NextHeader
 	return nil
 }
 
+// CanDecode implementation according to gopacket.DecodingLayer
 func (i *IPv6ExtensionSkipper) CanDecode() gopacket.LayerClass {
 	return LayerClassIPv6Extension
 }
 
+// NextLayerType implementation according to gopacket.DecodingLayer
 func (i *IPv6ExtensionSkipper) NextLayerType() gopacket.LayerType {
 	return i.NextHeader.LayerType()
 }
@@ -428,6 +464,7 @@ type IPv6HopByHop struct {
 // LayerType returns LayerTypeIPv6HopByHop.
 func (i *IPv6HopByHop) LayerType() gopacket.LayerType { return LayerTypeIPv6HopByHop }
 
+// SerializeTo implementation according to gopacket.SerializableLayer
 func (i *IPv6HopByHop) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
 	var bytes []byte
 	var err error
@@ -460,8 +497,13 @@ func (i *IPv6HopByHop) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.Ser
 	return nil
 }
 
+// DecodeFromBytes implementation according to gopacket.DecodingLayer
 func (i *IPv6HopByHop) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
-	i.ipv6ExtensionBase = decodeIPv6ExtensionBase(data)
+	var err error
+	i.ipv6ExtensionBase, err = decodeIPv6ExtensionBase(data, df)
+	if err != nil {
+		return err
+	}
 	offset := 2
 	for offset < i.ActualLength {
 		opt := decodeIPv6HeaderTLVOption(data[offset:])
@@ -481,6 +523,7 @@ func decodeIPv6HopByHop(data []byte, p gopacket.PacketBuilder) error {
 	return p.NextDecoder(i.NextHeader)
 }
 
+// SetJumboLength adds the IPv6HopByHopOptionJumbogram with the given length
 func (o *IPv6HopByHopOption) SetJumboLength(len uint32) {
 	o.OptionType = IPv6HopByHopOptionJumbogram
 	o.OptionLength = 4
@@ -509,8 +552,12 @@ type IPv6Routing struct {
 func (i *IPv6Routing) LayerType() gopacket.LayerType { return LayerTypeIPv6Routing }
 
 func decodeIPv6Routing(data []byte, p gopacket.PacketBuilder) error {
+	base, err := decodeIPv6ExtensionBase(data, p)
+	if err != nil {
+		return err
+	}
 	i := &IPv6Routing{
-		ipv6ExtensionBase: decodeIPv6ExtensionBase(data),
+		ipv6ExtensionBase: base,
 		RoutingType:       data[2],
 		SegmentsLeft:      data[3],
 		Reserved:          data[4:8],
@@ -548,6 +595,10 @@ type IPv6Fragment struct {
 func (i *IPv6Fragment) LayerType() gopacket.LayerType { return LayerTypeIPv6Fragment }
 
 func decodeIPv6Fragment(data []byte, p gopacket.PacketBuilder) error {
+	if len(data) < 8 {
+		p.SetTruncated()
+		return fmt.Errorf("Invalid ip6-fragment header. Length %d less than 8", len(data))
+	}
 	i := &IPv6Fragment{
 		BaseLayer:      BaseLayer{data[:8], data[8:]},
 		NextHeader:     IPProtocol(data[0]),
@@ -573,8 +624,13 @@ type IPv6Destination struct {
 // LayerType returns LayerTypeIPv6Destination.
 func (i *IPv6Destination) LayerType() gopacket.LayerType { return LayerTypeIPv6Destination }
 
+// DecodeFromBytes implementation according to gopacket.DecodingLayer
 func (i *IPv6Destination) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
-	i.ipv6ExtensionBase = decodeIPv6ExtensionBase(data)
+	var err error
+	i.ipv6ExtensionBase, err = decodeIPv6ExtensionBase(data, df)
+	if err != nil {
+		return err
+	}
 	offset := 2
 	for offset < i.ActualLength {
 		opt := decodeIPv6HeaderTLVOption(data[offset:])
@@ -639,11 +695,12 @@ func checkIPv6Address(addr net.IP) error {
 	return fmt.Errorf("wrong length of %d bytes instead of %d", len(addr), net.IPv6len)
 }
 
-func (ip *IPv6) AddressTo16() error {
-	if err := checkIPv6Address(ip.SrcIP); err != nil {
+// AddressTo16 ensures IPv6.SrcIP and IPv6.DstIP are actually IPv6 addresses (i.e. 16 byte addresses)
+func (ipv6 *IPv6) AddressTo16() error {
+	if err := checkIPv6Address(ipv6.SrcIP); err != nil {
 		return fmt.Errorf("Invalid source IPv6 address (%s)", err)
 	}
-	if err := checkIPv6Address(ip.DstIP); err != nil {
+	if err := checkIPv6Address(ipv6.DstIP); err != nil {
 		return fmt.Errorf("Invalid destination IPv6 address (%s)", err)
 	}
 	return nil

+ 146 - 120
vendor/github.com/google/gopacket/layers/layertypes.go

@@ -11,126 +11,138 @@ import (
 )
 
 var (
-	LayerTypeARP                         = gopacket.RegisterLayerType(10, gopacket.LayerTypeMetadata{Name: "ARP", Decoder: gopacket.DecodeFunc(decodeARP)})
-	LayerTypeCiscoDiscovery              = gopacket.RegisterLayerType(11, gopacket.LayerTypeMetadata{Name: "CiscoDiscovery", Decoder: gopacket.DecodeFunc(decodeCiscoDiscovery)})
-	LayerTypeEthernetCTP                 = gopacket.RegisterLayerType(12, gopacket.LayerTypeMetadata{Name: "EthernetCTP", Decoder: gopacket.DecodeFunc(decodeEthernetCTP)})
-	LayerTypeEthernetCTPForwardData      = gopacket.RegisterLayerType(13, gopacket.LayerTypeMetadata{Name: "EthernetCTPForwardData", Decoder: nil})
-	LayerTypeEthernetCTPReply            = gopacket.RegisterLayerType(14, gopacket.LayerTypeMetadata{Name: "EthernetCTPReply", Decoder: nil})
-	LayerTypeDot1Q                       = gopacket.RegisterLayerType(15, gopacket.LayerTypeMetadata{Name: "Dot1Q", Decoder: gopacket.DecodeFunc(decodeDot1Q)})
-	LayerTypeEtherIP                     = gopacket.RegisterLayerType(16, gopacket.LayerTypeMetadata{Name: "EtherIP", Decoder: gopacket.DecodeFunc(decodeEtherIP)})
-	LayerTypeEthernet                    = gopacket.RegisterLayerType(17, gopacket.LayerTypeMetadata{Name: "Ethernet", Decoder: gopacket.DecodeFunc(decodeEthernet)})
-	LayerTypeGRE                         = gopacket.RegisterLayerType(18, gopacket.LayerTypeMetadata{Name: "GRE", Decoder: gopacket.DecodeFunc(decodeGRE)})
-	LayerTypeICMPv4                      = gopacket.RegisterLayerType(19, gopacket.LayerTypeMetadata{Name: "ICMPv4", Decoder: gopacket.DecodeFunc(decodeICMPv4)})
-	LayerTypeIPv4                        = gopacket.RegisterLayerType(20, gopacket.LayerTypeMetadata{Name: "IPv4", Decoder: gopacket.DecodeFunc(decodeIPv4)})
-	LayerTypeIPv6                        = gopacket.RegisterLayerType(21, gopacket.LayerTypeMetadata{Name: "IPv6", Decoder: gopacket.DecodeFunc(decodeIPv6)})
-	LayerTypeLLC                         = gopacket.RegisterLayerType(22, gopacket.LayerTypeMetadata{Name: "LLC", Decoder: gopacket.DecodeFunc(decodeLLC)})
-	LayerTypeSNAP                        = gopacket.RegisterLayerType(23, gopacket.LayerTypeMetadata{Name: "SNAP", Decoder: gopacket.DecodeFunc(decodeSNAP)})
-	LayerTypeMPLS                        = gopacket.RegisterLayerType(24, gopacket.LayerTypeMetadata{Name: "MPLS", Decoder: gopacket.DecodeFunc(decodeMPLS)})
-	LayerTypePPP                         = gopacket.RegisterLayerType(25, gopacket.LayerTypeMetadata{Name: "PPP", Decoder: gopacket.DecodeFunc(decodePPP)})
-	LayerTypePPPoE                       = gopacket.RegisterLayerType(26, gopacket.LayerTypeMetadata{Name: "PPPoE", Decoder: gopacket.DecodeFunc(decodePPPoE)})
-	LayerTypeRUDP                        = gopacket.RegisterLayerType(27, gopacket.LayerTypeMetadata{Name: "RUDP", Decoder: gopacket.DecodeFunc(decodeRUDP)})
-	LayerTypeSCTP                        = gopacket.RegisterLayerType(28, gopacket.LayerTypeMetadata{Name: "SCTP", Decoder: gopacket.DecodeFunc(decodeSCTP)})
-	LayerTypeSCTPUnknownChunkType        = gopacket.RegisterLayerType(29, gopacket.LayerTypeMetadata{Name: "SCTPUnknownChunkType", Decoder: nil})
-	LayerTypeSCTPData                    = gopacket.RegisterLayerType(30, gopacket.LayerTypeMetadata{Name: "SCTPData", Decoder: nil})
-	LayerTypeSCTPInit                    = gopacket.RegisterLayerType(31, gopacket.LayerTypeMetadata{Name: "SCTPInit", Decoder: nil})
-	LayerTypeSCTPSack                    = gopacket.RegisterLayerType(32, gopacket.LayerTypeMetadata{Name: "SCTPSack", Decoder: nil})
-	LayerTypeSCTPHeartbeat               = gopacket.RegisterLayerType(33, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeat", Decoder: nil})
-	LayerTypeSCTPError                   = gopacket.RegisterLayerType(34, gopacket.LayerTypeMetadata{Name: "SCTPError", Decoder: nil})
-	LayerTypeSCTPShutdown                = gopacket.RegisterLayerType(35, gopacket.LayerTypeMetadata{Name: "SCTPShutdown", Decoder: nil})
-	LayerTypeSCTPShutdownAck             = gopacket.RegisterLayerType(36, gopacket.LayerTypeMetadata{Name: "SCTPShutdownAck", Decoder: nil})
-	LayerTypeSCTPCookieEcho              = gopacket.RegisterLayerType(37, gopacket.LayerTypeMetadata{Name: "SCTPCookieEcho", Decoder: nil})
-	LayerTypeSCTPEmptyLayer              = gopacket.RegisterLayerType(38, gopacket.LayerTypeMetadata{Name: "SCTPEmptyLayer", Decoder: nil})
-	LayerTypeSCTPInitAck                 = gopacket.RegisterLayerType(39, gopacket.LayerTypeMetadata{Name: "SCTPInitAck", Decoder: nil})
-	LayerTypeSCTPHeartbeatAck            = gopacket.RegisterLayerType(40, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeatAck", Decoder: nil})
-	LayerTypeSCTPAbort                   = gopacket.RegisterLayerType(41, gopacket.LayerTypeMetadata{Name: "SCTPAbort", Decoder: nil})
-	LayerTypeSCTPShutdownComplete        = gopacket.RegisterLayerType(42, gopacket.LayerTypeMetadata{Name: "SCTPShutdownComplete", Decoder: nil})
-	LayerTypeSCTPCookieAck               = gopacket.RegisterLayerType(43, gopacket.LayerTypeMetadata{Name: "SCTPCookieAck", Decoder: nil})
-	LayerTypeTCP                         = gopacket.RegisterLayerType(44, gopacket.LayerTypeMetadata{Name: "TCP", Decoder: gopacket.DecodeFunc(decodeTCP)})
-	LayerTypeUDP                         = gopacket.RegisterLayerType(45, gopacket.LayerTypeMetadata{Name: "UDP", Decoder: gopacket.DecodeFunc(decodeUDP)})
-	LayerTypeIPv6HopByHop                = gopacket.RegisterLayerType(46, gopacket.LayerTypeMetadata{Name: "IPv6HopByHop", Decoder: gopacket.DecodeFunc(decodeIPv6HopByHop)})
-	LayerTypeIPv6Routing                 = gopacket.RegisterLayerType(47, gopacket.LayerTypeMetadata{Name: "IPv6Routing", Decoder: gopacket.DecodeFunc(decodeIPv6Routing)})
-	LayerTypeIPv6Fragment                = gopacket.RegisterLayerType(48, gopacket.LayerTypeMetadata{Name: "IPv6Fragment", Decoder: gopacket.DecodeFunc(decodeIPv6Fragment)})
-	LayerTypeIPv6Destination             = gopacket.RegisterLayerType(49, gopacket.LayerTypeMetadata{Name: "IPv6Destination", Decoder: gopacket.DecodeFunc(decodeIPv6Destination)})
-	LayerTypeIPSecAH                     = gopacket.RegisterLayerType(50, gopacket.LayerTypeMetadata{Name: "IPSecAH", Decoder: gopacket.DecodeFunc(decodeIPSecAH)})
-	LayerTypeIPSecESP                    = gopacket.RegisterLayerType(51, gopacket.LayerTypeMetadata{Name: "IPSecESP", Decoder: gopacket.DecodeFunc(decodeIPSecESP)})
-	LayerTypeUDPLite                     = gopacket.RegisterLayerType(52, gopacket.LayerTypeMetadata{Name: "UDPLite", Decoder: gopacket.DecodeFunc(decodeUDPLite)})
-	LayerTypeFDDI                        = gopacket.RegisterLayerType(53, gopacket.LayerTypeMetadata{Name: "FDDI", Decoder: gopacket.DecodeFunc(decodeFDDI)})
-	LayerTypeLoopback                    = gopacket.RegisterLayerType(54, gopacket.LayerTypeMetadata{Name: "Loopback", Decoder: gopacket.DecodeFunc(decodeLoopback)})
-	LayerTypeEAP                         = gopacket.RegisterLayerType(55, gopacket.LayerTypeMetadata{Name: "EAP", Decoder: gopacket.DecodeFunc(decodeEAP)})
-	LayerTypeEAPOL                       = gopacket.RegisterLayerType(56, gopacket.LayerTypeMetadata{Name: "EAPOL", Decoder: gopacket.DecodeFunc(decodeEAPOL)})
-	LayerTypeICMPv6                      = gopacket.RegisterLayerType(57, gopacket.LayerTypeMetadata{Name: "ICMPv6", Decoder: gopacket.DecodeFunc(decodeICMPv6)})
-	LayerTypeLinkLayerDiscovery          = gopacket.RegisterLayerType(58, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscovery", Decoder: gopacket.DecodeFunc(decodeLinkLayerDiscovery)})
-	LayerTypeCiscoDiscoveryInfo          = gopacket.RegisterLayerType(59, gopacket.LayerTypeMetadata{Name: "CiscoDiscoveryInfo", Decoder: gopacket.DecodeFunc(decodeCiscoDiscoveryInfo)})
-	LayerTypeLinkLayerDiscoveryInfo      = gopacket.RegisterLayerType(60, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscoveryInfo", Decoder: nil})
-	LayerTypeNortelDiscovery             = gopacket.RegisterLayerType(61, gopacket.LayerTypeMetadata{Name: "NortelDiscovery", Decoder: gopacket.DecodeFunc(decodeNortelDiscovery)})
-	LayerTypeIGMP                        = gopacket.RegisterLayerType(62, gopacket.LayerTypeMetadata{Name: "IGMP", Decoder: gopacket.DecodeFunc(decodeIGMP)})
-	LayerTypePFLog                       = gopacket.RegisterLayerType(63, gopacket.LayerTypeMetadata{Name: "PFLog", Decoder: gopacket.DecodeFunc(decodePFLog)})
-	LayerTypeRadioTap                    = gopacket.RegisterLayerType(64, gopacket.LayerTypeMetadata{Name: "RadioTap", Decoder: gopacket.DecodeFunc(decodeRadioTap)})
-	LayerTypeDot11                       = gopacket.RegisterLayerType(65, gopacket.LayerTypeMetadata{Name: "Dot11", Decoder: gopacket.DecodeFunc(decodeDot11)})
-	LayerTypeDot11Ctrl                   = gopacket.RegisterLayerType(66, gopacket.LayerTypeMetadata{Name: "Dot11Ctrl", Decoder: gopacket.DecodeFunc(decodeDot11Ctrl)})
-	LayerTypeDot11Data                   = gopacket.RegisterLayerType(67, gopacket.LayerTypeMetadata{Name: "Dot11Data", Decoder: gopacket.DecodeFunc(decodeDot11Data)})
-	LayerTypeDot11DataCFAck              = gopacket.RegisterLayerType(68, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)})
-	LayerTypeDot11DataCFPoll             = gopacket.RegisterLayerType(69, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)})
-	LayerTypeDot11DataCFAckPoll          = gopacket.RegisterLayerType(70, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)})
-	LayerTypeDot11DataNull               = gopacket.RegisterLayerType(71, gopacket.LayerTypeMetadata{Name: "Dot11DataNull", Decoder: gopacket.DecodeFunc(decodeDot11DataNull)})
-	LayerTypeDot11DataCFAckNoData        = gopacket.RegisterLayerType(72, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)})
-	LayerTypeDot11DataCFPollNoData       = gopacket.RegisterLayerType(73, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)})
-	LayerTypeDot11DataCFAckPollNoData    = gopacket.RegisterLayerType(74, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)})
-	LayerTypeDot11DataQOSData            = gopacket.RegisterLayerType(75, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSData", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSData)})
-	LayerTypeDot11DataQOSDataCFAck       = gopacket.RegisterLayerType(76, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck)})
-	LayerTypeDot11DataQOSDataCFPoll      = gopacket.RegisterLayerType(77, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll)})
-	LayerTypeDot11DataQOSDataCFAckPoll   = gopacket.RegisterLayerType(78, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll)})
-	LayerTypeDot11DataQOSNull            = gopacket.RegisterLayerType(79, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSNull", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSNull)})
-	LayerTypeDot11DataQOSCFPollNoData    = gopacket.RegisterLayerType(80, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData)})
-	LayerTypeDot11DataQOSCFAckPollNoData = gopacket.RegisterLayerType(81, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData)})
-	LayerTypeDot11InformationElement     = gopacket.RegisterLayerType(82, gopacket.LayerTypeMetadata{Name: "Dot11InformationElement", Decoder: gopacket.DecodeFunc(decodeDot11InformationElement)})
-	LayerTypeDot11CtrlCTS                = gopacket.RegisterLayerType(83, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCTS)})
-	LayerTypeDot11CtrlRTS                = gopacket.RegisterLayerType(84, gopacket.LayerTypeMetadata{Name: "Dot11CtrlRTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlRTS)})
-	LayerTypeDot11CtrlBlockAckReq        = gopacket.RegisterLayerType(85, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAckReq", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq)})
-	LayerTypeDot11CtrlBlockAck           = gopacket.RegisterLayerType(86, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAck)})
-	LayerTypeDot11CtrlPowersavePoll      = gopacket.RegisterLayerType(87, gopacket.LayerTypeMetadata{Name: "Dot11CtrlPowersavePoll", Decoder: gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll)})
-	LayerTypeDot11CtrlAck                = gopacket.RegisterLayerType(88, gopacket.LayerTypeMetadata{Name: "Dot11CtrlAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlAck)})
-	LayerTypeDot11CtrlCFEnd              = gopacket.RegisterLayerType(89, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEnd", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEnd)})
-	LayerTypeDot11CtrlCFEndAck           = gopacket.RegisterLayerType(90, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEndAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEndAck)})
-	LayerTypeDot11MgmtAssociationReq     = gopacket.RegisterLayerType(91, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationReq)})
-	LayerTypeDot11MgmtAssociationResp    = gopacket.RegisterLayerType(92, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationResp)})
-	LayerTypeDot11MgmtReassociationReq   = gopacket.RegisterLayerType(93, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationReq)})
-	LayerTypeDot11MgmtReassociationResp  = gopacket.RegisterLayerType(94, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationResp)})
-	LayerTypeDot11MgmtProbeReq           = gopacket.RegisterLayerType(95, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeReq)})
-	LayerTypeDot11MgmtProbeResp          = gopacket.RegisterLayerType(96, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeResp)})
-	LayerTypeDot11MgmtMeasurementPilot   = gopacket.RegisterLayerType(97, gopacket.LayerTypeMetadata{Name: "Dot11MgmtMeasurementPilot", Decoder: gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot)})
-	LayerTypeDot11MgmtBeacon             = gopacket.RegisterLayerType(98, gopacket.LayerTypeMetadata{Name: "Dot11MgmtBeacon", Decoder: gopacket.DecodeFunc(decodeDot11MgmtBeacon)})
-	LayerTypeDot11MgmtATIM               = gopacket.RegisterLayerType(99, gopacket.LayerTypeMetadata{Name: "Dot11MgmtATIM", Decoder: gopacket.DecodeFunc(decodeDot11MgmtATIM)})
-	LayerTypeDot11MgmtDisassociation     = gopacket.RegisterLayerType(100, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDisassociation", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDisassociation)})
-	LayerTypeDot11MgmtAuthentication     = gopacket.RegisterLayerType(101, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAuthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAuthentication)})
-	LayerTypeDot11MgmtDeauthentication   = gopacket.RegisterLayerType(102, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDeauthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDeauthentication)})
-	LayerTypeDot11MgmtAction             = gopacket.RegisterLayerType(103, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAction", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAction)})
-	LayerTypeDot11MgmtActionNoAck        = gopacket.RegisterLayerType(104, gopacket.LayerTypeMetadata{Name: "Dot11MgmtActionNoAck", Decoder: gopacket.DecodeFunc(decodeDot11MgmtActionNoAck)})
-	LayerTypeDot11MgmtArubaWLAN          = gopacket.RegisterLayerType(105, gopacket.LayerTypeMetadata{Name: "Dot11MgmtArubaWLAN", Decoder: gopacket.DecodeFunc(decodeDot11MgmtArubaWLAN)})
-	LayerTypeDot11WEP                    = gopacket.RegisterLayerType(106, gopacket.LayerTypeMetadata{Name: "Dot11WEP", Decoder: gopacket.DecodeFunc(decodeDot11WEP)})
-	LayerTypeDNS                         = gopacket.RegisterLayerType(107, gopacket.LayerTypeMetadata{Name: "DNS", Decoder: gopacket.DecodeFunc(decodeDNS)})
-	LayerTypeUSB                         = gopacket.RegisterLayerType(108, gopacket.LayerTypeMetadata{Name: "USB", Decoder: gopacket.DecodeFunc(decodeUSB)})
-	LayerTypeUSBRequestBlockSetup        = gopacket.RegisterLayerType(109, gopacket.LayerTypeMetadata{Name: "USBRequestBlockSetup", Decoder: gopacket.DecodeFunc(decodeUSBRequestBlockSetup)})
-	LayerTypeUSBControl                  = gopacket.RegisterLayerType(110, gopacket.LayerTypeMetadata{Name: "USBControl", Decoder: gopacket.DecodeFunc(decodeUSBControl)})
-	LayerTypeUSBInterrupt                = gopacket.RegisterLayerType(111, gopacket.LayerTypeMetadata{Name: "USBInterrupt", Decoder: gopacket.DecodeFunc(decodeUSBInterrupt)})
-	LayerTypeUSBBulk                     = gopacket.RegisterLayerType(112, gopacket.LayerTypeMetadata{Name: "USBBulk", Decoder: gopacket.DecodeFunc(decodeUSBBulk)})
-	LayerTypeLinuxSLL                    = gopacket.RegisterLayerType(113, gopacket.LayerTypeMetadata{Name: "Linux SLL", Decoder: gopacket.DecodeFunc(decodeLinuxSLL)})
-	LayerTypeSFlow                       = gopacket.RegisterLayerType(114, gopacket.LayerTypeMetadata{Name: "SFlow", Decoder: gopacket.DecodeFunc(decodeSFlow)})
-	LayerTypePrismHeader                 = gopacket.RegisterLayerType(115, gopacket.LayerTypeMetadata{Name: "Prism monitor mode header", Decoder: gopacket.DecodeFunc(decodePrismHeader)})
-	LayerTypeVXLAN                       = gopacket.RegisterLayerType(116, gopacket.LayerTypeMetadata{Name: "VXLAN", Decoder: gopacket.DecodeFunc(decodeVXLAN)})
-	LayerTypeNTP                         = gopacket.RegisterLayerType(117, gopacket.LayerTypeMetadata{Name: "NTP", Decoder: gopacket.DecodeFunc(decodeNTP)})
-	LayerTypeDHCPv4                      = gopacket.RegisterLayerType(118, gopacket.LayerTypeMetadata{Name: "DHCPv4", Decoder: gopacket.DecodeFunc(decodeDHCPv4)})
-	LayerTypeVRRP                        = gopacket.RegisterLayerType(119, gopacket.LayerTypeMetadata{Name: "VRRP", Decoder: gopacket.DecodeFunc(decodeVRRP)})
-	LayerTypeGeneve                      = gopacket.RegisterLayerType(120, gopacket.LayerTypeMetadata{Name: "Geneve", Decoder: gopacket.DecodeFunc(decodeGeneve)})
-	LayerTypeSTP                         = gopacket.RegisterLayerType(121, gopacket.LayerTypeMetadata{Name: "STP", Decoder: gopacket.DecodeFunc(decodeSTP)})
-	LayerTypeBFD                         = gopacket.RegisterLayerType(122, gopacket.LayerTypeMetadata{Name: "BFD", Decoder: gopacket.DecodeFunc(decodeBFD)})
-	LayerTypeOSPF                        = gopacket.RegisterLayerType(123, gopacket.LayerTypeMetadata{Name: "OSPF", Decoder: gopacket.DecodeFunc(decodeOSPF)})
-
-	LayerTypeICMPv6RouterSolicitation    = gopacket.RegisterLayerType(124, gopacket.LayerTypeMetadata{Name: "ICMPv6RouterSolicitation", Decoder: gopacket.DecodeFunc(decodeICMPv6RouterSolicitation)})
-	LayerTypeICMPv6RouterAdvertisement   = gopacket.RegisterLayerType(125, gopacket.LayerTypeMetadata{Name: "ICMPv6RouterAdvertisement", Decoder: gopacket.DecodeFunc(decodeICMPv6RouterAdvertisement)})
-	LayerTypeICMPv6NeighborSolicitation  = gopacket.RegisterLayerType(126, gopacket.LayerTypeMetadata{Name: "ICMPv6NeighborSolicitation", Decoder: gopacket.DecodeFunc(decodeICMPv6NeighborSolicitation)})
-	LayerTypeICMPv6NeighborAdvertisement = gopacket.RegisterLayerType(127, gopacket.LayerTypeMetadata{Name: "ICMPv6NeighborAdvertisement", Decoder: gopacket.DecodeFunc(decodeICMPv6NeighborAdvertisement)})
-	LayerTypeICMPv6Redirect              = gopacket.RegisterLayerType(128, gopacket.LayerTypeMetadata{Name: "ICMPv6Redirect", Decoder: gopacket.DecodeFunc(decodeICMPv6Redirect)})
+	LayerTypeARP                          = gopacket.RegisterLayerType(10, gopacket.LayerTypeMetadata{Name: "ARP", Decoder: gopacket.DecodeFunc(decodeARP)})
+	LayerTypeCiscoDiscovery               = gopacket.RegisterLayerType(11, gopacket.LayerTypeMetadata{Name: "CiscoDiscovery", Decoder: gopacket.DecodeFunc(decodeCiscoDiscovery)})
+	LayerTypeEthernetCTP                  = gopacket.RegisterLayerType(12, gopacket.LayerTypeMetadata{Name: "EthernetCTP", Decoder: gopacket.DecodeFunc(decodeEthernetCTP)})
+	LayerTypeEthernetCTPForwardData       = gopacket.RegisterLayerType(13, gopacket.LayerTypeMetadata{Name: "EthernetCTPForwardData", Decoder: nil})
+	LayerTypeEthernetCTPReply             = gopacket.RegisterLayerType(14, gopacket.LayerTypeMetadata{Name: "EthernetCTPReply", Decoder: nil})
+	LayerTypeDot1Q                        = gopacket.RegisterLayerType(15, gopacket.LayerTypeMetadata{Name: "Dot1Q", Decoder: gopacket.DecodeFunc(decodeDot1Q)})
+	LayerTypeEtherIP                      = gopacket.RegisterLayerType(16, gopacket.LayerTypeMetadata{Name: "EtherIP", Decoder: gopacket.DecodeFunc(decodeEtherIP)})
+	LayerTypeEthernet                     = gopacket.RegisterLayerType(17, gopacket.LayerTypeMetadata{Name: "Ethernet", Decoder: gopacket.DecodeFunc(decodeEthernet)})
+	LayerTypeGRE                          = gopacket.RegisterLayerType(18, gopacket.LayerTypeMetadata{Name: "GRE", Decoder: gopacket.DecodeFunc(decodeGRE)})
+	LayerTypeICMPv4                       = gopacket.RegisterLayerType(19, gopacket.LayerTypeMetadata{Name: "ICMPv4", Decoder: gopacket.DecodeFunc(decodeICMPv4)})
+	LayerTypeIPv4                         = gopacket.RegisterLayerType(20, gopacket.LayerTypeMetadata{Name: "IPv4", Decoder: gopacket.DecodeFunc(decodeIPv4)})
+	LayerTypeIPv6                         = gopacket.RegisterLayerType(21, gopacket.LayerTypeMetadata{Name: "IPv6", Decoder: gopacket.DecodeFunc(decodeIPv6)})
+	LayerTypeLLC                          = gopacket.RegisterLayerType(22, gopacket.LayerTypeMetadata{Name: "LLC", Decoder: gopacket.DecodeFunc(decodeLLC)})
+	LayerTypeSNAP                         = gopacket.RegisterLayerType(23, gopacket.LayerTypeMetadata{Name: "SNAP", Decoder: gopacket.DecodeFunc(decodeSNAP)})
+	LayerTypeMPLS                         = gopacket.RegisterLayerType(24, gopacket.LayerTypeMetadata{Name: "MPLS", Decoder: gopacket.DecodeFunc(decodeMPLS)})
+	LayerTypePPP                          = gopacket.RegisterLayerType(25, gopacket.LayerTypeMetadata{Name: "PPP", Decoder: gopacket.DecodeFunc(decodePPP)})
+	LayerTypePPPoE                        = gopacket.RegisterLayerType(26, gopacket.LayerTypeMetadata{Name: "PPPoE", Decoder: gopacket.DecodeFunc(decodePPPoE)})
+	LayerTypeRUDP                         = gopacket.RegisterLayerType(27, gopacket.LayerTypeMetadata{Name: "RUDP", Decoder: gopacket.DecodeFunc(decodeRUDP)})
+	LayerTypeSCTP                         = gopacket.RegisterLayerType(28, gopacket.LayerTypeMetadata{Name: "SCTP", Decoder: gopacket.DecodeFunc(decodeSCTP)})
+	LayerTypeSCTPUnknownChunkType         = gopacket.RegisterLayerType(29, gopacket.LayerTypeMetadata{Name: "SCTPUnknownChunkType", Decoder: nil})
+	LayerTypeSCTPData                     = gopacket.RegisterLayerType(30, gopacket.LayerTypeMetadata{Name: "SCTPData", Decoder: nil})
+	LayerTypeSCTPInit                     = gopacket.RegisterLayerType(31, gopacket.LayerTypeMetadata{Name: "SCTPInit", Decoder: nil})
+	LayerTypeSCTPSack                     = gopacket.RegisterLayerType(32, gopacket.LayerTypeMetadata{Name: "SCTPSack", Decoder: nil})
+	LayerTypeSCTPHeartbeat                = gopacket.RegisterLayerType(33, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeat", Decoder: nil})
+	LayerTypeSCTPError                    = gopacket.RegisterLayerType(34, gopacket.LayerTypeMetadata{Name: "SCTPError", Decoder: nil})
+	LayerTypeSCTPShutdown                 = gopacket.RegisterLayerType(35, gopacket.LayerTypeMetadata{Name: "SCTPShutdown", Decoder: nil})
+	LayerTypeSCTPShutdownAck              = gopacket.RegisterLayerType(36, gopacket.LayerTypeMetadata{Name: "SCTPShutdownAck", Decoder: nil})
+	LayerTypeSCTPCookieEcho               = gopacket.RegisterLayerType(37, gopacket.LayerTypeMetadata{Name: "SCTPCookieEcho", Decoder: nil})
+	LayerTypeSCTPEmptyLayer               = gopacket.RegisterLayerType(38, gopacket.LayerTypeMetadata{Name: "SCTPEmptyLayer", Decoder: nil})
+	LayerTypeSCTPInitAck                  = gopacket.RegisterLayerType(39, gopacket.LayerTypeMetadata{Name: "SCTPInitAck", Decoder: nil})
+	LayerTypeSCTPHeartbeatAck             = gopacket.RegisterLayerType(40, gopacket.LayerTypeMetadata{Name: "SCTPHeartbeatAck", Decoder: nil})
+	LayerTypeSCTPAbort                    = gopacket.RegisterLayerType(41, gopacket.LayerTypeMetadata{Name: "SCTPAbort", Decoder: nil})
+	LayerTypeSCTPShutdownComplete         = gopacket.RegisterLayerType(42, gopacket.LayerTypeMetadata{Name: "SCTPShutdownComplete", Decoder: nil})
+	LayerTypeSCTPCookieAck                = gopacket.RegisterLayerType(43, gopacket.LayerTypeMetadata{Name: "SCTPCookieAck", Decoder: nil})
+	LayerTypeTCP                          = gopacket.RegisterLayerType(44, gopacket.LayerTypeMetadata{Name: "TCP", Decoder: gopacket.DecodeFunc(decodeTCP)})
+	LayerTypeUDP                          = gopacket.RegisterLayerType(45, gopacket.LayerTypeMetadata{Name: "UDP", Decoder: gopacket.DecodeFunc(decodeUDP)})
+	LayerTypeIPv6HopByHop                 = gopacket.RegisterLayerType(46, gopacket.LayerTypeMetadata{Name: "IPv6HopByHop", Decoder: gopacket.DecodeFunc(decodeIPv6HopByHop)})
+	LayerTypeIPv6Routing                  = gopacket.RegisterLayerType(47, gopacket.LayerTypeMetadata{Name: "IPv6Routing", Decoder: gopacket.DecodeFunc(decodeIPv6Routing)})
+	LayerTypeIPv6Fragment                 = gopacket.RegisterLayerType(48, gopacket.LayerTypeMetadata{Name: "IPv6Fragment", Decoder: gopacket.DecodeFunc(decodeIPv6Fragment)})
+	LayerTypeIPv6Destination              = gopacket.RegisterLayerType(49, gopacket.LayerTypeMetadata{Name: "IPv6Destination", Decoder: gopacket.DecodeFunc(decodeIPv6Destination)})
+	LayerTypeIPSecAH                      = gopacket.RegisterLayerType(50, gopacket.LayerTypeMetadata{Name: "IPSecAH", Decoder: gopacket.DecodeFunc(decodeIPSecAH)})
+	LayerTypeIPSecESP                     = gopacket.RegisterLayerType(51, gopacket.LayerTypeMetadata{Name: "IPSecESP", Decoder: gopacket.DecodeFunc(decodeIPSecESP)})
+	LayerTypeUDPLite                      = gopacket.RegisterLayerType(52, gopacket.LayerTypeMetadata{Name: "UDPLite", Decoder: gopacket.DecodeFunc(decodeUDPLite)})
+	LayerTypeFDDI                         = gopacket.RegisterLayerType(53, gopacket.LayerTypeMetadata{Name: "FDDI", Decoder: gopacket.DecodeFunc(decodeFDDI)})
+	LayerTypeLoopback                     = gopacket.RegisterLayerType(54, gopacket.LayerTypeMetadata{Name: "Loopback", Decoder: gopacket.DecodeFunc(decodeLoopback)})
+	LayerTypeEAP                          = gopacket.RegisterLayerType(55, gopacket.LayerTypeMetadata{Name: "EAP", Decoder: gopacket.DecodeFunc(decodeEAP)})
+	LayerTypeEAPOL                        = gopacket.RegisterLayerType(56, gopacket.LayerTypeMetadata{Name: "EAPOL", Decoder: gopacket.DecodeFunc(decodeEAPOL)})
+	LayerTypeICMPv6                       = gopacket.RegisterLayerType(57, gopacket.LayerTypeMetadata{Name: "ICMPv6", Decoder: gopacket.DecodeFunc(decodeICMPv6)})
+	LayerTypeLinkLayerDiscovery           = gopacket.RegisterLayerType(58, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscovery", Decoder: gopacket.DecodeFunc(decodeLinkLayerDiscovery)})
+	LayerTypeCiscoDiscoveryInfo           = gopacket.RegisterLayerType(59, gopacket.LayerTypeMetadata{Name: "CiscoDiscoveryInfo", Decoder: gopacket.DecodeFunc(decodeCiscoDiscoveryInfo)})
+	LayerTypeLinkLayerDiscoveryInfo       = gopacket.RegisterLayerType(60, gopacket.LayerTypeMetadata{Name: "LinkLayerDiscoveryInfo", Decoder: nil})
+	LayerTypeNortelDiscovery              = gopacket.RegisterLayerType(61, gopacket.LayerTypeMetadata{Name: "NortelDiscovery", Decoder: gopacket.DecodeFunc(decodeNortelDiscovery)})
+	LayerTypeIGMP                         = gopacket.RegisterLayerType(62, gopacket.LayerTypeMetadata{Name: "IGMP", Decoder: gopacket.DecodeFunc(decodeIGMP)})
+	LayerTypePFLog                        = gopacket.RegisterLayerType(63, gopacket.LayerTypeMetadata{Name: "PFLog", Decoder: gopacket.DecodeFunc(decodePFLog)})
+	LayerTypeRadioTap                     = gopacket.RegisterLayerType(64, gopacket.LayerTypeMetadata{Name: "RadioTap", Decoder: gopacket.DecodeFunc(decodeRadioTap)})
+	LayerTypeDot11                        = gopacket.RegisterLayerType(65, gopacket.LayerTypeMetadata{Name: "Dot11", Decoder: gopacket.DecodeFunc(decodeDot11)})
+	LayerTypeDot11Ctrl                    = gopacket.RegisterLayerType(66, gopacket.LayerTypeMetadata{Name: "Dot11Ctrl", Decoder: gopacket.DecodeFunc(decodeDot11Ctrl)})
+	LayerTypeDot11Data                    = gopacket.RegisterLayerType(67, gopacket.LayerTypeMetadata{Name: "Dot11Data", Decoder: gopacket.DecodeFunc(decodeDot11Data)})
+	LayerTypeDot11DataCFAck               = gopacket.RegisterLayerType(68, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)})
+	LayerTypeDot11DataCFPoll              = gopacket.RegisterLayerType(69, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)})
+	LayerTypeDot11DataCFAckPoll           = gopacket.RegisterLayerType(70, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)})
+	LayerTypeDot11DataNull                = gopacket.RegisterLayerType(71, gopacket.LayerTypeMetadata{Name: "Dot11DataNull", Decoder: gopacket.DecodeFunc(decodeDot11DataNull)})
+	LayerTypeDot11DataCFAckNoData         = gopacket.RegisterLayerType(72, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAck)})
+	LayerTypeDot11DataCFPollNoData        = gopacket.RegisterLayerType(73, gopacket.LayerTypeMetadata{Name: "Dot11DataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFPoll)})
+	LayerTypeDot11DataCFAckPollNoData     = gopacket.RegisterLayerType(74, gopacket.LayerTypeMetadata{Name: "Dot11DataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataCFAckPoll)})
+	LayerTypeDot11DataQOSData             = gopacket.RegisterLayerType(75, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSData", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSData)})
+	LayerTypeDot11DataQOSDataCFAck        = gopacket.RegisterLayerType(76, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAck", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAck)})
+	LayerTypeDot11DataQOSDataCFPoll       = gopacket.RegisterLayerType(77, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFPoll)})
+	LayerTypeDot11DataQOSDataCFAckPoll    = gopacket.RegisterLayerType(78, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSDataCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSDataCFAckPoll)})
+	LayerTypeDot11DataQOSNull             = gopacket.RegisterLayerType(79, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSNull", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSNull)})
+	LayerTypeDot11DataQOSCFPollNoData     = gopacket.RegisterLayerType(80, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFPollNoData)})
+	LayerTypeDot11DataQOSCFAckPollNoData  = gopacket.RegisterLayerType(81, gopacket.LayerTypeMetadata{Name: "Dot11DataQOSCFAckPoll", Decoder: gopacket.DecodeFunc(decodeDot11DataQOSCFAckPollNoData)})
+	LayerTypeDot11InformationElement      = gopacket.RegisterLayerType(82, gopacket.LayerTypeMetadata{Name: "Dot11InformationElement", Decoder: gopacket.DecodeFunc(decodeDot11InformationElement)})
+	LayerTypeDot11CtrlCTS                 = gopacket.RegisterLayerType(83, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCTS)})
+	LayerTypeDot11CtrlRTS                 = gopacket.RegisterLayerType(84, gopacket.LayerTypeMetadata{Name: "Dot11CtrlRTS", Decoder: gopacket.DecodeFunc(decodeDot11CtrlRTS)})
+	LayerTypeDot11CtrlBlockAckReq         = gopacket.RegisterLayerType(85, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAckReq", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAckReq)})
+	LayerTypeDot11CtrlBlockAck            = gopacket.RegisterLayerType(86, gopacket.LayerTypeMetadata{Name: "Dot11CtrlBlockAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlBlockAck)})
+	LayerTypeDot11CtrlPowersavePoll       = gopacket.RegisterLayerType(87, gopacket.LayerTypeMetadata{Name: "Dot11CtrlPowersavePoll", Decoder: gopacket.DecodeFunc(decodeDot11CtrlPowersavePoll)})
+	LayerTypeDot11CtrlAck                 = gopacket.RegisterLayerType(88, gopacket.LayerTypeMetadata{Name: "Dot11CtrlAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlAck)})
+	LayerTypeDot11CtrlCFEnd               = gopacket.RegisterLayerType(89, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEnd", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEnd)})
+	LayerTypeDot11CtrlCFEndAck            = gopacket.RegisterLayerType(90, gopacket.LayerTypeMetadata{Name: "Dot11CtrlCFEndAck", Decoder: gopacket.DecodeFunc(decodeDot11CtrlCFEndAck)})
+	LayerTypeDot11MgmtAssociationReq      = gopacket.RegisterLayerType(91, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationReq)})
+	LayerTypeDot11MgmtAssociationResp     = gopacket.RegisterLayerType(92, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAssociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAssociationResp)})
+	LayerTypeDot11MgmtReassociationReq    = gopacket.RegisterLayerType(93, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationReq)})
+	LayerTypeDot11MgmtReassociationResp   = gopacket.RegisterLayerType(94, gopacket.LayerTypeMetadata{Name: "Dot11MgmtReassociationResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtReassociationResp)})
+	LayerTypeDot11MgmtProbeReq            = gopacket.RegisterLayerType(95, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeReq", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeReq)})
+	LayerTypeDot11MgmtProbeResp           = gopacket.RegisterLayerType(96, gopacket.LayerTypeMetadata{Name: "Dot11MgmtProbeResp", Decoder: gopacket.DecodeFunc(decodeDot11MgmtProbeResp)})
+	LayerTypeDot11MgmtMeasurementPilot    = gopacket.RegisterLayerType(97, gopacket.LayerTypeMetadata{Name: "Dot11MgmtMeasurementPilot", Decoder: gopacket.DecodeFunc(decodeDot11MgmtMeasurementPilot)})
+	LayerTypeDot11MgmtBeacon              = gopacket.RegisterLayerType(98, gopacket.LayerTypeMetadata{Name: "Dot11MgmtBeacon", Decoder: gopacket.DecodeFunc(decodeDot11MgmtBeacon)})
+	LayerTypeDot11MgmtATIM                = gopacket.RegisterLayerType(99, gopacket.LayerTypeMetadata{Name: "Dot11MgmtATIM", Decoder: gopacket.DecodeFunc(decodeDot11MgmtATIM)})
+	LayerTypeDot11MgmtDisassociation      = gopacket.RegisterLayerType(100, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDisassociation", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDisassociation)})
+	LayerTypeDot11MgmtAuthentication      = gopacket.RegisterLayerType(101, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAuthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAuthentication)})
+	LayerTypeDot11MgmtDeauthentication    = gopacket.RegisterLayerType(102, gopacket.LayerTypeMetadata{Name: "Dot11MgmtDeauthentication", Decoder: gopacket.DecodeFunc(decodeDot11MgmtDeauthentication)})
+	LayerTypeDot11MgmtAction              = gopacket.RegisterLayerType(103, gopacket.LayerTypeMetadata{Name: "Dot11MgmtAction", Decoder: gopacket.DecodeFunc(decodeDot11MgmtAction)})
+	LayerTypeDot11MgmtActionNoAck         = gopacket.RegisterLayerType(104, gopacket.LayerTypeMetadata{Name: "Dot11MgmtActionNoAck", Decoder: gopacket.DecodeFunc(decodeDot11MgmtActionNoAck)})
+	LayerTypeDot11MgmtArubaWLAN           = gopacket.RegisterLayerType(105, gopacket.LayerTypeMetadata{Name: "Dot11MgmtArubaWLAN", Decoder: gopacket.DecodeFunc(decodeDot11MgmtArubaWLAN)})
+	LayerTypeDot11WEP                     = gopacket.RegisterLayerType(106, gopacket.LayerTypeMetadata{Name: "Dot11WEP", Decoder: gopacket.DecodeFunc(decodeDot11WEP)})
+	LayerTypeDNS                          = gopacket.RegisterLayerType(107, gopacket.LayerTypeMetadata{Name: "DNS", Decoder: gopacket.DecodeFunc(decodeDNS)})
+	LayerTypeUSB                          = gopacket.RegisterLayerType(108, gopacket.LayerTypeMetadata{Name: "USB", Decoder: gopacket.DecodeFunc(decodeUSB)})
+	LayerTypeUSBRequestBlockSetup         = gopacket.RegisterLayerType(109, gopacket.LayerTypeMetadata{Name: "USBRequestBlockSetup", Decoder: gopacket.DecodeFunc(decodeUSBRequestBlockSetup)})
+	LayerTypeUSBControl                   = gopacket.RegisterLayerType(110, gopacket.LayerTypeMetadata{Name: "USBControl", Decoder: gopacket.DecodeFunc(decodeUSBControl)})
+	LayerTypeUSBInterrupt                 = gopacket.RegisterLayerType(111, gopacket.LayerTypeMetadata{Name: "USBInterrupt", Decoder: gopacket.DecodeFunc(decodeUSBInterrupt)})
+	LayerTypeUSBBulk                      = gopacket.RegisterLayerType(112, gopacket.LayerTypeMetadata{Name: "USBBulk", Decoder: gopacket.DecodeFunc(decodeUSBBulk)})
+	LayerTypeLinuxSLL                     = gopacket.RegisterLayerType(113, gopacket.LayerTypeMetadata{Name: "Linux SLL", Decoder: gopacket.DecodeFunc(decodeLinuxSLL)})
+	LayerTypeSFlow                        = gopacket.RegisterLayerType(114, gopacket.LayerTypeMetadata{Name: "SFlow", Decoder: gopacket.DecodeFunc(decodeSFlow)})
+	LayerTypePrismHeader                  = gopacket.RegisterLayerType(115, gopacket.LayerTypeMetadata{Name: "Prism monitor mode header", Decoder: gopacket.DecodeFunc(decodePrismHeader)})
+	LayerTypeVXLAN                        = gopacket.RegisterLayerType(116, gopacket.LayerTypeMetadata{Name: "VXLAN", Decoder: gopacket.DecodeFunc(decodeVXLAN)})
+	LayerTypeNTP                          = gopacket.RegisterLayerType(117, gopacket.LayerTypeMetadata{Name: "NTP", Decoder: gopacket.DecodeFunc(decodeNTP)})
+	LayerTypeDHCPv4                       = gopacket.RegisterLayerType(118, gopacket.LayerTypeMetadata{Name: "DHCPv4", Decoder: gopacket.DecodeFunc(decodeDHCPv4)})
+	LayerTypeVRRP                         = gopacket.RegisterLayerType(119, gopacket.LayerTypeMetadata{Name: "VRRP", Decoder: gopacket.DecodeFunc(decodeVRRP)})
+	LayerTypeGeneve                       = gopacket.RegisterLayerType(120, gopacket.LayerTypeMetadata{Name: "Geneve", Decoder: gopacket.DecodeFunc(decodeGeneve)})
+	LayerTypeSTP                          = gopacket.RegisterLayerType(121, gopacket.LayerTypeMetadata{Name: "STP", Decoder: gopacket.DecodeFunc(decodeSTP)})
+	LayerTypeBFD                          = gopacket.RegisterLayerType(122, gopacket.LayerTypeMetadata{Name: "BFD", Decoder: gopacket.DecodeFunc(decodeBFD)})
+	LayerTypeOSPF                         = gopacket.RegisterLayerType(123, gopacket.LayerTypeMetadata{Name: "OSPF", Decoder: gopacket.DecodeFunc(decodeOSPF)})
+	LayerTypeICMPv6RouterSolicitation     = gopacket.RegisterLayerType(124, gopacket.LayerTypeMetadata{Name: "ICMPv6RouterSolicitation", Decoder: gopacket.DecodeFunc(decodeICMPv6RouterSolicitation)})
+	LayerTypeICMPv6RouterAdvertisement    = gopacket.RegisterLayerType(125, gopacket.LayerTypeMetadata{Name: "ICMPv6RouterAdvertisement", Decoder: gopacket.DecodeFunc(decodeICMPv6RouterAdvertisement)})
+	LayerTypeICMPv6NeighborSolicitation   = gopacket.RegisterLayerType(126, gopacket.LayerTypeMetadata{Name: "ICMPv6NeighborSolicitation", Decoder: gopacket.DecodeFunc(decodeICMPv6NeighborSolicitation)})
+	LayerTypeICMPv6NeighborAdvertisement  = gopacket.RegisterLayerType(127, gopacket.LayerTypeMetadata{Name: "ICMPv6NeighborAdvertisement", Decoder: gopacket.DecodeFunc(decodeICMPv6NeighborAdvertisement)})
+	LayerTypeICMPv6Redirect               = gopacket.RegisterLayerType(128, gopacket.LayerTypeMetadata{Name: "ICMPv6Redirect", Decoder: gopacket.DecodeFunc(decodeICMPv6Redirect)})
+	LayerTypeGTPv1U                       = gopacket.RegisterLayerType(129, gopacket.LayerTypeMetadata{Name: "GTPv1U", Decoder: gopacket.DecodeFunc(decodeGTPv1u)})
+	LayerTypeEAPOLKey                     = gopacket.RegisterLayerType(130, gopacket.LayerTypeMetadata{Name: "EAPOLKey", Decoder: gopacket.DecodeFunc(decodeEAPOLKey)})
+	LayerTypeLCM                          = gopacket.RegisterLayerType(131, gopacket.LayerTypeMetadata{Name: "LCM", Decoder: gopacket.DecodeFunc(decodeLCM)})
+	LayerTypeICMPv6Echo                   = gopacket.RegisterLayerType(132, gopacket.LayerTypeMetadata{Name: "ICMPv6Echo", Decoder: gopacket.DecodeFunc(decodeICMPv6Echo)})
+	LayerTypeSIP                          = gopacket.RegisterLayerType(133, gopacket.LayerTypeMetadata{Name: "SIP", Decoder: gopacket.DecodeFunc(decodeSIP)})
+	LayerTypeDHCPv6                       = gopacket.RegisterLayerType(134, gopacket.LayerTypeMetadata{Name: "DHCPv6", Decoder: gopacket.DecodeFunc(decodeDHCPv6)})
+	LayerTypeMLDv1MulticastListenerReport = gopacket.RegisterLayerType(135, gopacket.LayerTypeMetadata{Name: "MLDv1MulticastListenerReport", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerReport)})
+	LayerTypeMLDv1MulticastListenerDone   = gopacket.RegisterLayerType(136, gopacket.LayerTypeMetadata{Name: "MLDv1MulticastListenerDone", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerDone)})
+	LayerTypeMLDv1MulticastListenerQuery  = gopacket.RegisterLayerType(137, gopacket.LayerTypeMetadata{Name: "MLDv1MulticastListenerQuery", Decoder: gopacket.DecodeFunc(decodeMLDv1MulticastListenerQuery)})
+	LayerTypeMLDv2MulticastListenerReport = gopacket.RegisterLayerType(138, gopacket.LayerTypeMetadata{Name: "MLDv2MulticastListenerReport", Decoder: gopacket.DecodeFunc(decodeMLDv2MulticastListenerReport)})
+	LayerTypeMLDv2MulticastListenerQuery  = gopacket.RegisterLayerType(139, gopacket.LayerTypeMetadata{Name: "MLDv2MulticastListenerQuery", Decoder: gopacket.DecodeFunc(decodeMLDv2MulticastListenerQuery)})
+	LayerTypeTLS                          = gopacket.RegisterLayerType(140, gopacket.LayerTypeMetadata{Name: "TLS", Decoder: gopacket.DecodeFunc(decodeTLS)})
+	LayerTypeModbusTCP                    = gopacket.RegisterLayerType(141, gopacket.LayerTypeMetadata{Name: "ModbusTCP", Decoder: gopacket.DecodeFunc(decodeModbusTCP)})
 )
 
 var (
@@ -189,4 +201,18 @@ var (
 		LayerTypeICMPv6NeighborAdvertisement,
 		LayerTypeICMPv6Redirect,
 	})
+	// LayerClassMLDv1 contains multicast listener discovery protocol
+	LayerClassMLDv1 = gopacket.NewLayerClass([]gopacket.LayerType{
+		LayerTypeMLDv1MulticastListenerQuery,
+		LayerTypeMLDv1MulticastListenerReport,
+		LayerTypeMLDv1MulticastListenerDone,
+	})
+	// LayerClassMLDv2 contains multicast listener discovery protocol v2
+	LayerClassMLDv2 = gopacket.NewLayerClass([]gopacket.LayerType{
+		LayerTypeMLDv1MulticastListenerReport,
+		LayerTypeMLDv1MulticastListenerDone,
+		LayerTypeMLDv2MulticastListenerReport,
+		LayerTypeMLDv1MulticastListenerQuery,
+		LayerTypeMLDv2MulticastListenerQuery,
+	})
 )

+ 213 - 0
vendor/github.com/google/gopacket/layers/lcm.go

@@ -0,0 +1,213 @@
+// Copyright 2018 Google, Inc. All rights reserved.
+//
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file in the root of the source
+// tree.
+
+package layers
+
+import (
+	"encoding/binary"
+	"fmt"
+
+	"github.com/google/gopacket"
+)
+
+const (
+	// LCMShortHeaderMagic is the LCM small message header magic number
+	LCMShortHeaderMagic uint32 = 0x4c433032
+	// LCMFragmentedHeaderMagic is the LCM fragmented message header magic number
+	LCMFragmentedHeaderMagic uint32 = 0x4c433033
+)
+
+// LCM (Lightweight Communications and Marshalling) is a set of libraries and
+// tools for message passing and data marshalling, targeted at real-time systems
+// where high-bandwidth and low latency are critical. It provides a
+// publish/subscribe message passing model and automatic
+// marshalling/unmarshalling code generation with bindings for applications in a
+// variety of programming languages.
+//
+// References
+//   https://lcm-proj.github.io/
+//   https://github.com/lcm-proj/lcm
+type LCM struct {
+	// Common (short & fragmented header) fields
+	Magic          uint32
+	SequenceNumber uint32
+	// Fragmented header only fields
+	PayloadSize    uint32
+	FragmentOffset uint32
+	FragmentNumber uint16
+	TotalFragments uint16
+	// Common field
+	ChannelName string
+	// Gopacket helper fields
+	Fragmented  bool
+	fingerprint LCMFingerprint
+	contents    []byte
+	payload     []byte
+}
+
+// LCMFingerprint is the type of a LCM fingerprint.
+type LCMFingerprint uint64
+
+var (
+	// lcmLayerTypes contains a map of all LCM fingerprints that we support and
+	// their LayerType
+	lcmLayerTypes  = map[LCMFingerprint]gopacket.LayerType{}
+	layerTypeIndex = 1001
+)
+
+// RegisterLCMLayerType allows users to register decoders for the underlying
+// LCM payload. This is done based on the fingerprint that every LCM message
+// contains and which identifies it uniquely. If num is not the zero value it
+// will be used when registering with RegisterLayerType towards gopacket,
+// otherwise an incremental value starting from 1001 will be used.
+func RegisterLCMLayerType(num int, name string, fingerprint LCMFingerprint,
+	decoder gopacket.Decoder) gopacket.LayerType {
+	metadata := gopacket.LayerTypeMetadata{Name: name, Decoder: decoder}
+
+	if num == 0 {
+		num = layerTypeIndex
+		layerTypeIndex++
+	}
+
+	lcmLayerTypes[fingerprint] = gopacket.RegisterLayerType(num, metadata)
+
+	return lcmLayerTypes[fingerprint]
+}
+
+// SupportedLCMFingerprints returns a slice of all LCM fingerprints that has
+// been registered so far.
+func SupportedLCMFingerprints() []LCMFingerprint {
+	fingerprints := make([]LCMFingerprint, 0, len(lcmLayerTypes))
+	for fp := range lcmLayerTypes {
+		fingerprints = append(fingerprints, fp)
+	}
+	return fingerprints
+}
+
+// GetLCMLayerType returns the underlying LCM message's LayerType.
+// This LayerType has to be registered by using RegisterLCMLayerType.
+func GetLCMLayerType(fingerprint LCMFingerprint) gopacket.LayerType {
+	layerType, ok := lcmLayerTypes[fingerprint]
+	if !ok {
+		return gopacket.LayerTypePayload
+	}
+
+	return layerType
+}
+
+func decodeLCM(data []byte, p gopacket.PacketBuilder) error {
+	lcm := &LCM{}
+
+	err := lcm.DecodeFromBytes(data, p)
+	if err != nil {
+		return err
+	}
+
+	p.AddLayer(lcm)
+	p.SetApplicationLayer(lcm)
+
+	return p.NextDecoder(lcm.NextLayerType())
+}
+
+// DecodeFromBytes decodes the given bytes into this layer.
+func (lcm *LCM) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	offset := 0
+
+	lcm.Magic = binary.BigEndian.Uint32(data[offset:4])
+	offset += 4
+
+	if lcm.Magic != LCMShortHeaderMagic && lcm.Magic != LCMFragmentedHeaderMagic {
+		return fmt.Errorf("Received LCM header magic %v does not match know "+
+			"LCM magic numbers. Dropping packet.", lcm.Magic)
+	}
+
+	lcm.SequenceNumber = binary.BigEndian.Uint32(data[offset:8])
+	offset += 4
+
+	if lcm.Magic == LCMFragmentedHeaderMagic {
+		lcm.Fragmented = true
+
+		lcm.PayloadSize = binary.BigEndian.Uint32(data[offset : offset+4])
+		offset += 4
+
+		lcm.FragmentOffset = binary.BigEndian.Uint32(data[offset : offset+4])
+		offset += 4
+
+		lcm.FragmentNumber = binary.BigEndian.Uint16(data[offset : offset+2])
+		offset += 2
+
+		lcm.TotalFragments = binary.BigEndian.Uint16(data[offset : offset+2])
+		offset += 2
+	} else {
+		lcm.Fragmented = false
+	}
+
+	if !lcm.Fragmented || (lcm.Fragmented && lcm.FragmentNumber == 0) {
+		buffer := make([]byte, 0)
+		for _, b := range data[offset:] {
+			offset++
+
+			if b == 0 {
+				break
+			}
+
+			buffer = append(buffer, b)
+		}
+
+		lcm.ChannelName = string(buffer)
+	}
+
+	lcm.fingerprint = LCMFingerprint(
+		binary.BigEndian.Uint64(data[offset : offset+8]))
+
+	lcm.contents = data[:offset]
+	lcm.payload = data[offset:]
+
+	return nil
+}
+
+// CanDecode returns a set of layers that LCM objects can decode.
+// As LCM objects can only decode the LCM layer, we just return that layer.
+func (lcm LCM) CanDecode() gopacket.LayerClass {
+	return LayerTypeLCM
+}
+
+// NextLayerType specifies the LCM payload layer type following this header.
+// As LCM packets are serialized structs with uniq fingerprints for each uniq
+// combination of data types, lookup of correct layer type is based on that
+// fingerprint.
+func (lcm LCM) NextLayerType() gopacket.LayerType {
+	if !lcm.Fragmented || (lcm.Fragmented && lcm.FragmentNumber == 0) {
+		return GetLCMLayerType(lcm.fingerprint)
+	}
+
+	return gopacket.LayerTypeFragment
+}
+
+// LayerType returns LayerTypeLCM
+func (lcm LCM) LayerType() gopacket.LayerType {
+	return LayerTypeLCM
+}
+
+// LayerContents returns the contents of the LCM header.
+func (lcm LCM) LayerContents() []byte {
+	return lcm.contents
+}
+
+// LayerPayload returns the payload following this LCM header.
+func (lcm LCM) LayerPayload() []byte {
+	return lcm.payload
+}
+
+// Payload returns the payload following this LCM header.
+func (lcm LCM) Payload() []byte {
+	return lcm.LayerPayload()
+}
+
+// Fingerprint returns the LCM fingerprint of the underlying message.
+func (lcm LCM) Fingerprint() LCMFingerprint {
+	return lcm.fingerprint
+}

+ 2 - 0
vendor/github.com/google/gopacket/layers/linux_sll.go

@@ -54,6 +54,7 @@ type LinuxSLL struct {
 	AddrLen      uint16
 	Addr         net.HardwareAddr
 	EthernetType EthernetType
+	AddrType     uint16
 }
 
 // LayerType returns LayerTypeLinuxSLL.
@@ -76,6 +77,7 @@ func (sll *LinuxSLL) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) er
 		return errors.New("Linux SLL packet too small")
 	}
 	sll.PacketType = LinuxSLLPacketType(binary.BigEndian.Uint16(data[0:2]))
+	sll.AddrType = binary.BigEndian.Uint16(data[2:4])
 	sll.AddrLen = binary.BigEndian.Uint16(data[4:6])
 
 	sll.Addr = net.HardwareAddr(data[6 : sll.AddrLen+6])

+ 79 - 32
vendor/github.com/google/gopacket/layers/llc.go

@@ -27,6 +27,47 @@ type LLC struct {
 // LayerType returns gopacket.LayerTypeLLC.
 func (l *LLC) LayerType() gopacket.LayerType { return LayerTypeLLC }
 
+// DecodeFromBytes decodes the given bytes into this layer.
+func (l *LLC) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < 3 {
+		return errors.New("LLC header too small")
+	}
+	l.DSAP = data[0] & 0xFE
+	l.IG = data[0]&0x1 != 0
+	l.SSAP = data[1] & 0xFE
+	l.CR = data[1]&0x1 != 0
+	l.Control = uint16(data[2])
+
+	if l.Control&0x1 == 0 || l.Control&0x3 == 0x1 {
+		if len(data) < 4 {
+			return errors.New("LLC header too small")
+		}
+		l.Control = l.Control<<8 | uint16(data[3])
+		l.Contents = data[:4]
+		l.Payload = data[4:]
+	} else {
+		l.Contents = data[:3]
+		l.Payload = data[3:]
+	}
+	return nil
+}
+
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (l *LLC) CanDecode() gopacket.LayerClass {
+	return LayerTypeLLC
+}
+
+// NextLayerType returns the layer type contained by this DecodingLayer.
+func (l *LLC) NextLayerType() gopacket.LayerType {
+	switch {
+	case l.DSAP == 0xAA && l.SSAP == 0xAA:
+		return LayerTypeSNAP
+	case l.DSAP == 0x42 && l.SSAP == 0x42:
+		return LayerTypeSTP
+	}
+	return gopacket.LayerTypeZero // Not implemented
+}
+
 // SNAP is used inside LLC.  See
 // http://standards.ieee.org/getieee802/download/802-2001.pdf.
 // From http://en.wikipedia.org/wiki/Subnetwork_Access_Protocol:
@@ -42,37 +83,43 @@ type SNAP struct {
 // LayerType returns gopacket.LayerTypeSNAP.
 func (s *SNAP) LayerType() gopacket.LayerType { return LayerTypeSNAP }
 
-func decodeLLC(data []byte, p gopacket.PacketBuilder) error {
-	l := &LLC{
-		DSAP:    data[0] & 0xFE,
-		IG:      data[0]&0x1 != 0,
-		SSAP:    data[1] & 0xFE,
-		CR:      data[1]&0x1 != 0,
-		Control: uint16(data[2]),
+// DecodeFromBytes decodes the given bytes into this layer.
+func (s *SNAP) DecodeFromBytes(data []byte, df gopacket.DecodeFeedback) error {
+	if len(data) < 5 {
+		return errors.New("SNAP header too small")
 	}
-	if l.Control&0x1 == 0 || l.Control&0x3 == 0x1 {
-		l.Control = l.Control<<8 | uint16(data[3])
-		l.Contents = data[:4]
-		l.Payload = data[4:]
-	} else {
-		l.Contents = data[:3]
-		l.Payload = data[3:]
+	s.OrganizationalCode = data[:3]
+	s.Type = EthernetType(binary.BigEndian.Uint16(data[3:5]))
+	s.BaseLayer = BaseLayer{data[:5], data[5:]}
+	return nil
+}
+
+// CanDecode returns the set of layer types that this DecodingLayer can decode.
+func (s *SNAP) CanDecode() gopacket.LayerClass {
+	return LayerTypeLLC
+}
+
+// NextLayerType returns the layer type contained by this DecodingLayer.
+func (s *SNAP) NextLayerType() gopacket.LayerType {
+	// See BUG(gconnel) in decodeSNAP
+	return s.Type.LayerType()
+}
+
+func decodeLLC(data []byte, p gopacket.PacketBuilder) error {
+	l := &LLC{}
+	err := l.DecodeFromBytes(data, p)
+	if err != nil {
+		return err
 	}
 	p.AddLayer(l)
-	switch {
-	case l.DSAP == 0xAA && l.SSAP == 0xAA:
-		return p.NextDecoder(LayerTypeSNAP)
-	case l.DSAP == 0x42 && l.SSAP == 0x42:
-		return p.NextDecoder(LayerTypeSTP)
-	}
-	return p.NextDecoder(gopacket.DecodeUnknown)
+	return p.NextDecoder(l.NextLayerType())
 }
 
 func decodeSNAP(data []byte, p gopacket.PacketBuilder) error {
-	s := &SNAP{
-		OrganizationalCode: data[:3],
-		Type:               EthernetType(binary.BigEndian.Uint16(data[3:5])),
-		BaseLayer:          BaseLayer{data[:5], data[5:]},
+	s := &SNAP{}
+	err := s.DecodeFromBytes(data, p)
+	if err != nil {
+		return err
 	}
 	p.AddLayer(s)
 	// BUG(gconnell):  When decoding SNAP, we treat the SNAP type as an Ethernet
@@ -85,7 +132,7 @@ func decodeSNAP(data []byte, p gopacket.PacketBuilder) error {
 // SerializationBuffer, implementing gopacket.SerializableLayer.
 // See the docs for gopacket.SerializableLayer for more info.
 func (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOptions) error {
-	var ig_flag, cr_flag byte
+	var igFlag, crFlag byte
 	var length int
 
 	if l.Control&0xFF00 != 0 {
@@ -105,18 +152,18 @@ func (l *LLC) SerializeTo(b gopacket.SerializeBuffer, opts gopacket.SerializeOpt
 	if buf, err := b.PrependBytes(length); err != nil {
 		return err
 	} else {
-		ig_flag = 0
+		igFlag = 0
 		if l.IG {
-			ig_flag = 0x1
+			igFlag = 0x1
 		}
 
-		cr_flag = 0
+		crFlag = 0
 		if l.CR {
-			cr_flag = 0x1
+			crFlag = 0x1
 		}
 
-		buf[0] = l.DSAP + ig_flag
-		buf[1] = l.SSAP + cr_flag
+		buf[0] = l.DSAP + igFlag
+		buf[1] = l.SSAP + crFlag
 
 		if length == 4 {
 			buf[2] = uint8(l.Control >> 8)

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác