Przeglądaj źródła

Merge pull request #13482 from boucher/criu-libcontainer-update

Update vendored libcontainer
Alexander Morozov 10 lat temu
rodzic
commit
6d8e517bce
100 zmienionych plików z 9575 dodań i 296 usunięć
  1. 2 1
      hack/vendor.sh
  2. 3 1
      vendor/src/github.com/docker/libcontainer/Dockerfile
  3. 51 19
      vendor/src/github.com/docker/libcontainer/README.md
  4. 2 0
      vendor/src/github.com/docker/libcontainer/apparmor/gen.go
  5. 2 0
      vendor/src/github.com/docker/libcontainer/apparmor/setup.go
  6. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/cgroups.go
  7. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/cgroups_test.go
  8. 3 0
      vendor/src/github.com/docker/libcontainer/cgroups/cgroups_unsupported.go
  9. 4 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go
  10. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/blkio.go
  11. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/blkio_test.go
  12. 12 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/cpu.go
  13. 28 4
      vendor/src/github.com/docker/libcontainer/cgroups/fs/cpu_test.go
  14. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go
  15. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuset.go
  16. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuset_test.go
  17. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/devices.go
  18. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/devices_test.go
  19. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/freezer.go
  20. 3 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/fs_unsupported.go
  21. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/hugetlb.go
  22. 7 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/memory.go
  23. 30 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/memory_test.go
  24. 40 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/net_cls.go
  25. 36 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/net_cls_test.go
  26. 40 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/net_prio.go
  27. 36 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/net_prio_test.go
  28. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go
  29. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/stats_util_test.go
  30. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/util_test.go
  31. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/utils.go
  32. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go
  33. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/stats.go
  34. 69 17
      vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go
  35. 2 0
      vendor/src/github.com/docker/libcontainer/cgroups/utils.go
  36. 18 0
      vendor/src/github.com/docker/libcontainer/configs/cgroup.go
  37. 3 48
      vendor/src/github.com/docker/libcontainer/configs/config.go
  38. 49 0
      vendor/src/github.com/docker/libcontainer/configs/config_linux.go
  39. 2 0
      vendor/src/github.com/docker/libcontainer/configs/device.go
  40. 2 0
      vendor/src/github.com/docker/libcontainer/configs/device_defaults.go
  41. 14 0
      vendor/src/github.com/docker/libcontainer/configs/interface_priority_map.go
  42. 0 86
      vendor/src/github.com/docker/libcontainer/configs/namespaces.go
  43. 89 0
      vendor/src/github.com/docker/libcontainer/configs/namespaces_linux.go
  44. 1 1
      vendor/src/github.com/docker/libcontainer/configs/namespaces_syscall_unsupported.go
  45. 6 0
      vendor/src/github.com/docker/libcontainer/configs/namespaces_windows.go
  46. 0 2
      vendor/src/github.com/docker/libcontainer/console_linux.go
  47. 30 0
      vendor/src/github.com/docker/libcontainer/console_windows.go
  48. 18 0
      vendor/src/github.com/docker/libcontainer/container.go
  49. 462 1
      vendor/src/github.com/docker/libcontainer/container_linux.go
  50. 7 0
      vendor/src/github.com/docker/libcontainer/container_linux_test.go
  51. 16 0
      vendor/src/github.com/docker/libcontainer/criu_opts.go
  52. 2 0
      vendor/src/github.com/docker/libcontainer/criurpc/Makefile
  53. 602 0
      vendor/src/github.com/docker/libcontainer/criurpc/criurpc.pb.go
  54. 127 0
      vendor/src/github.com/docker/libcontainer/criurpc/criurpc.proto
  55. 0 0
      vendor/src/github.com/docker/libcontainer/devices/devices_linux.go
  56. 16 0
      vendor/src/github.com/docker/libcontainer/devices/devices_windows.go
  57. 2 0
      vendor/src/github.com/docker/libcontainer/devices/number.go
  58. 9 33
      vendor/src/github.com/docker/libcontainer/factory_linux.go
  59. 163 0
      vendor/src/github.com/docker/libcontainer/integration/checkpoint_test.go
  60. 5 24
      vendor/src/github.com/docker/libcontainer/integration/exec_test.go
  61. 16 22
      vendor/src/github.com/docker/libcontainer/integration/execin_test.go
  62. 13 0
      vendor/src/github.com/docker/libcontainer/integration/utils_test.go
  63. 19 5
      vendor/src/github.com/docker/libcontainer/netlink/netlink_linux.go
  64. 49 14
      vendor/src/github.com/docker/libcontainer/network_linux.go
  65. 2 0
      vendor/src/github.com/docker/libcontainer/nsenter/nsenter_unsupported.go
  66. 67 0
      vendor/src/github.com/docker/libcontainer/nsinit/checkpoint.go
  67. 9 0
      vendor/src/github.com/docker/libcontainer/nsinit/config.go
  68. 8 1
      vendor/src/github.com/docker/libcontainer/nsinit/exec.go
  69. 6 3
      vendor/src/github.com/docker/libcontainer/nsinit/main.go
  70. 120 0
      vendor/src/github.com/docker/libcontainer/nsinit/restore.go
  71. 31 2
      vendor/src/github.com/docker/libcontainer/nsinit/tty.go
  72. 12 2
      vendor/src/github.com/docker/libcontainer/nsinit/utils.go
  73. 51 0
      vendor/src/github.com/docker/libcontainer/process_linux.go
  74. 118 0
      vendor/src/github.com/docker/libcontainer/restored_process.go
  75. 3 0
      vendor/src/github.com/docker/libcontainer/stacktrace/frame.go
  76. 0 7
      vendor/src/github.com/docker/libcontainer/stats.go
  77. 8 0
      vendor/src/github.com/docker/libcontainer/stats_linux.go
  78. 5 0
      vendor/src/github.com/docker/libcontainer/stats_windows.go
  79. 1 1
      vendor/src/github.com/docker/libcontainer/system/sysconfig.go
  80. 8 1
      vendor/src/github.com/docker/libcontainer/system/sysconfig_notcgo.go
  81. 2 1
      vendor/src/github.com/docker/libcontainer/update-vendor.sh
  82. 17 0
      vendor/src/github.com/golang/protobuf/.gitignore
  83. 3 0
      vendor/src/github.com/golang/protobuf/AUTHORS
  84. 3 0
      vendor/src/github.com/golang/protobuf/CONTRIBUTORS
  85. 31 0
      vendor/src/github.com/golang/protobuf/LICENSE
  86. 40 0
      vendor/src/github.com/golang/protobuf/Make.protobuf
  87. 52 0
      vendor/src/github.com/golang/protobuf/Makefile
  88. 148 0
      vendor/src/github.com/golang/protobuf/README
  89. 43 0
      vendor/src/github.com/golang/protobuf/proto/Makefile
  90. 2071 0
      vendor/src/github.com/golang/protobuf/proto/all_test.go
  91. 197 0
      vendor/src/github.com/golang/protobuf/proto/clone.go
  92. 227 0
      vendor/src/github.com/golang/protobuf/proto/clone_test.go
  93. 821 0
      vendor/src/github.com/golang/protobuf/proto/decode.go
  94. 1288 0
      vendor/src/github.com/golang/protobuf/proto/encode.go
  95. 256 0
      vendor/src/github.com/golang/protobuf/proto/equal.go
  96. 191 0
      vendor/src/github.com/golang/protobuf/proto/equal_test.go
  97. 362 0
      vendor/src/github.com/golang/protobuf/proto/extensions.go
  98. 153 0
      vendor/src/github.com/golang/protobuf/proto/extensions_test.go
  99. 790 0
      vendor/src/github.com/golang/protobuf/proto/lib.go
  100. 287 0
      vendor/src/github.com/golang/protobuf/proto/message_set.go

+ 2 - 1
hack/vendor.sh

@@ -69,8 +69,9 @@ mv tmp-digest src/github.com/docker/distribution/digest
 mkdir -p src/github.com/docker/distribution/registry
 mv tmp-api src/github.com/docker/distribution/registry/api
 
-clone git github.com/docker/libcontainer a37b2a4f152e2a1c9de596f54c051cb889de0691
+clone git github.com/docker/libcontainer v2.1.0
 # libcontainer deps (see src/github.com/docker/libcontainer/update-vendor.sh)
 clone git github.com/coreos/go-systemd v2
 clone git github.com/godbus/dbus v2
 clone git github.com/syndtr/gocapability 66ef2aa7a23ba682594e2b6f74cf40c0692b49fb
+clone git github.com/golang/protobuf 655cdfa588ea

+ 3 - 1
vendor/src/github.com/docker/libcontainer/Dockerfile

@@ -1,5 +1,8 @@
 FROM golang:1.4
 
+RUN echo "deb http://ftp.us.debian.org/debian testing main contrib" >> /etc/apt/sources.list
+RUN apt-get update && apt-get install -y iptables criu=1.5.2-1 && rm -rf /var/lib/apt/lists/*
+
 RUN go get golang.org/x/tools/cmd/cover
 
 ENV GOPATH $GOPATH:/go/src/github.com/docker/libcontainer/vendor
@@ -16,7 +19,6 @@ COPY . /go/src/github.com/docker/libcontainer
 WORKDIR /go/src/github.com/docker/libcontainer
 RUN cp sample_configs/minimal.json /busybox/container.json
 
-RUN go get -d -v ./...
 RUN make direct-install
 
 ENTRYPOINT ["/dind"]

+ 51 - 19
vendor/src/github.com/docker/libcontainer/README.md

@@ -1,13 +1,13 @@
-## libcontainer - reference implementation for containers [![Build Status](https://jenkins.dockerproject.com/buildStatus/icon?job=Libcontainer Master)](https://jenkins.dockerproject.com/job/Libcontainer%20Master/) 
+## libcontainer - reference implementation for containers [![Build Status](https://jenkins.dockerproject.com/buildStatus/icon?job=Libcontainer Master)](https://jenkins.dockerproject.com/job/Libcontainer%20Master/)
 
-Libcontainer provides a native Go implementation for creating containers 
+Libcontainer provides a native Go implementation for creating containers
 with namespaces, cgroups, capabilities, and filesystem access controls.
 It allows you to manage the lifecycle of the container performing additional operations
 after the container is created.
 
 
 #### Container
-A container is a self contained execution environment that shares the kernel of the 
+A container is a self contained execution environment that shares the kernel of the
 host system and which is (optionally) isolated from other containers in the system.
 
 #### Using libcontainer
@@ -27,7 +27,7 @@ if err != nil {
 }
 ```
 
-Once you have an instance of the factory created we can create a configuration 
+Once you have an instance of the factory created we can create a configuration
 struct describing how the container is to be created.  A sample would look similar to this:
 
 ```go
@@ -120,9 +120,9 @@ Additional ways to interact with a running container are:
 
 ```go
 // return all the pids for all processes running inside the container.
-processes, err := container.Processes() 
+processes, err := container.Processes()
 
-// get detailed cpu, memory, io, and network statistics for the container and 
+// get detailed cpu, memory, io, and network statistics for the container and
 // it's processes.
 stats, err := container.Stats()
 
@@ -137,18 +137,18 @@ container.Resume()
 
 #### nsinit
 
-`nsinit` is a cli application which demonstrates the use of libcontainer.  
+`nsinit` is a cli application which demonstrates the use of libcontainer.
 It is able to spawn new containers or join existing containers.  A root
 filesystem must be provided for use along with a container configuration file.
 
 To build `nsinit`, run `make binary`. It will save the binary into
 `bundles/nsinit`.
 
-To use `nsinit`, cd into a Linux rootfs and copy a `container.json` file into 
-the directory with your specified configuration. Environment, networking, 
-and different capabilities for the container are specified in this file. 
+To use `nsinit`, cd into a Linux rootfs and copy a `container.json` file into
+the directory with your specified configuration. Environment, networking,
+and different capabilities for the container are specified in this file.
 The configuration is used for each process executed inside the container.
-                                                                                                                               
+
 See the `sample_configs` folder for examples of what the container configuration should look like.
 
 To execute `/bin/bash` in the current directory as a container just run the following **as root**:
@@ -156,18 +156,50 @@ To execute `/bin/bash` in the current directory as a container just run the foll
 nsinit exec --tty /bin/bash
 ```
 
-If you wish to spawn another process inside the container while your 
-current bash session is running, run the same command again to 
-get another bash shell (or change the command).  If the original 
-process (PID 1) dies, all other processes spawned inside the container 
-will be killed and the namespace will be removed. 
+If you wish to spawn another process inside the container while your
+current bash session is running, run the same command again to
+get another bash shell (or change the command).  If the original
+process (PID 1) dies, all other processes spawned inside the container
+will be killed and the namespace will be removed.
 
-You can identify if a process is running in a container by 
+You can identify if a process is running in a container by
 looking to see if `state.json` is in the root of the directory.
-   
-You may also specify an alternate root place where 
+
+You may also specify an alternate root place where
 the `container.json` file is read and where the `state.json` file will be saved.
 
+
+#### Checkpoint & Restore
+
+libcontainer now integrates [CRIU](http://criu.org/) for checkpointing and restoring containers.
+This let's you save the state of a process running inside a container to disk, and then restore
+that state into a new process, on the same machine or on another machine.
+
+`criu` version 1.5.2 or higher is required to use checkpoint and restore.
+If you don't already  have `criu` installed, you can build it from source, following the
+[online instructions](http://criu.org/Installation). `criu` is also installed in the docker image
+generated when building libcontainer with docker.
+
+To try an example with `nsinit`, open two terminals to the same busybox directory.
+In the first terminal, run a command like this one:
+```bash
+nsinit exec -- sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'
+```
+
+You should see logs printing to the terminal every second. Now, in the second terminal, run:
+```bash
+nsinit checkpoint --image-path=/tmp/criu
+```
+
+The logs in your first terminal will stop and the process will exit. Finally, in the second
+terminal, run the restore command:
+```bash
+nsinit restore --image-path=/tmp/criu
+```
+
+The process will resume counting where it left off and printing to the new terminal window.
+
+
 #### Future
 See the [roadmap](ROADMAP.md).
 

+ 2 - 0
vendor/src/github.com/docker/libcontainer/apparmor/gen.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package apparmor
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/apparmor/setup.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package apparmor
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/cgroups.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package cgroups
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/cgroups_test.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package cgroups
 
 import (

+ 3 - 0
vendor/src/github.com/docker/libcontainer/cgroups/cgroups_unsupported.go

@@ -0,0 +1,3 @@
+// +build !linux
+
+package cgroups

+ 4 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/apply_raw.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (
@@ -22,6 +24,8 @@ var (
 		"cpuacct":    &CpuacctGroup{},
 		"blkio":      &BlkioGroup{},
 		"hugetlb":    &HugetlbGroup{},
+		"net_cls":    &NetClsGroup{},
+		"net_prio":   &NetPrioGroup{},
 		"perf_event": &PerfEventGroup{},
 		"freezer":    &FreezerGroup{},
 	}

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/blkio.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/blkio_test.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 12 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/cpu.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (
@@ -44,6 +46,16 @@ func (s *CpuGroup) Set(path string, cgroup *configs.Cgroup) error {
 			return err
 		}
 	}
+	if cgroup.CpuRtPeriod != 0 {
+		if err := writeFile(path, "cpu.rt_period_us", strconv.FormatInt(cgroup.CpuRtPeriod, 10)); err != nil {
+			return err
+		}
+	}
+	if cgroup.CpuRtRuntime != 0 {
+		if err := writeFile(path, "cpu.rt_runtime_us", strconv.FormatInt(cgroup.CpuRtRuntime, 10)); err != nil {
+			return err
+		}
+	}
 
 	return nil
 }

+ 28 - 4
vendor/src/github.com/docker/libcontainer/cgroups/fs/cpu_test.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (
@@ -42,19 +44,27 @@ func TestCpuSetBandWidth(t *testing.T) {
 	defer helper.cleanup()
 
 	const (
-		quotaBefore  = 8000
-		quotaAfter   = 5000
-		periodBefore = 10000
-		periodAfter  = 7000
+		quotaBefore     = 8000
+		quotaAfter      = 5000
+		periodBefore    = 10000
+		periodAfter     = 7000
+		rtRuntimeBefore = 8000
+		rtRuntimeAfter  = 5000
+		rtPeriodBefore  = 10000
+		rtPeriodAfter   = 7000
 	)
 
 	helper.writeFileContents(map[string]string{
 		"cpu.cfs_quota_us":  strconv.Itoa(quotaBefore),
 		"cpu.cfs_period_us": strconv.Itoa(periodBefore),
+		"cpu.rt_runtime_us": strconv.Itoa(rtRuntimeBefore),
+		"cpu.rt_period_us":  strconv.Itoa(rtPeriodBefore),
 	})
 
 	helper.CgroupData.c.CpuQuota = quotaAfter
 	helper.CgroupData.c.CpuPeriod = periodAfter
+	helper.CgroupData.c.CpuRtRuntime = rtRuntimeAfter
+	helper.CgroupData.c.CpuRtPeriod = rtPeriodAfter
 	cpu := &CpuGroup{}
 	if err := cpu.Set(helper.CgroupPath, helper.CgroupData.c); err != nil {
 		t.Fatal(err)
@@ -75,6 +85,20 @@ func TestCpuSetBandWidth(t *testing.T) {
 	if period != periodAfter {
 		t.Fatal("Got the wrong value, set cpu.cfs_period_us failed.")
 	}
+	rtRuntime, err := getCgroupParamUint(helper.CgroupPath, "cpu.rt_runtime_us")
+	if err != nil {
+		t.Fatalf("Failed to parse cpu.rt_runtime_us - %s", err)
+	}
+	if rtRuntime != rtRuntimeAfter {
+		t.Fatal("Got the wrong value, set cpu.rt_runtime_us failed.")
+	}
+	rtPeriod, err := getCgroupParamUint(helper.CgroupPath, "cpu.rt_period_us")
+	if err != nil {
+		t.Fatalf("Failed to parse cpu.rt_period_us - %s", err)
+	}
+	if rtPeriod != rtPeriodAfter {
+		t.Fatal("Got the wrong value, set cpu.rt_period_us failed.")
+	}
 }
 
 func TestCpuStats(t *testing.T) {

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuacct.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuset.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/cpuset_test.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/devices.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/devices_test.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/freezer.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 3 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/fs_unsupported.go

@@ -0,0 +1,3 @@
+// +build !linux
+
+package fs

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/hugetlb.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 7 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/memory.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (
@@ -54,6 +56,11 @@ func (s *MemoryGroup) Set(path string, cgroup *configs.Cgroup) error {
 			return err
 		}
 	}
+	if cgroup.KernelMemory > 0 {
+		if err := writeFile(path, "memory.kmem.limit_in_bytes", strconv.FormatInt(cgroup.KernelMemory, 10)); err != nil {
+			return err
+		}
+	}
 
 	if cgroup.OomKillDisable {
 		if err := writeFile(path, "memory.oom_control", "1"); err != nil {

+ 30 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/memory_test.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (
@@ -112,6 +114,34 @@ func TestMemorySetMemoryswapDefault(t *testing.T) {
 	}
 }
 
+func TestMemorySetKernelMemory(t *testing.T) {
+	helper := NewCgroupTestUtil("memory", t)
+	defer helper.cleanup()
+
+	const (
+		kernelMemoryBefore = 314572800 // 300M
+		kernelMemoryAfter  = 524288000 // 500M
+	)
+
+	helper.writeFileContents(map[string]string{
+		"memory.kmem.limit_in_bytes": strconv.Itoa(kernelMemoryBefore),
+	})
+
+	helper.CgroupData.c.KernelMemory = kernelMemoryAfter
+	memory := &MemoryGroup{}
+	if err := memory.Set(helper.CgroupPath, helper.CgroupData.c); err != nil {
+		t.Fatal(err)
+	}
+
+	value, err := getCgroupParamUint(helper.CgroupPath, "memory.kmem.limit_in_bytes")
+	if err != nil {
+		t.Fatalf("Failed to parse memory.kmem.limit_in_bytes - %s", err)
+	}
+	if value != kernelMemoryAfter {
+		t.Fatal("Got the wrong value, set memory.kmem.limit_in_bytes failed.")
+	}
+}
+
 func TestMemoryStats(t *testing.T) {
 	helper := NewCgroupTestUtil("memory", t)
 	defer helper.cleanup()

+ 40 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/net_cls.go

@@ -0,0 +1,40 @@
+package fs
+
+import (
+	"github.com/docker/libcontainer/cgroups"
+	"github.com/docker/libcontainer/configs"
+)
+
+type NetClsGroup struct {
+}
+
+func (s *NetClsGroup) Apply(d *data) error {
+	dir, err := d.join("net_cls")
+	if err != nil && !cgroups.IsNotFound(err) {
+		return err
+	}
+
+	if err := s.Set(dir, d.c); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (s *NetClsGroup) Set(path string, cgroup *configs.Cgroup) error {
+	if cgroup.NetClsClassid != "" {
+		if err := writeFile(path, "net_cls.classid", cgroup.NetClsClassid); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (s *NetClsGroup) Remove(d *data) error {
+	return removePath(d.path("net_cls"))
+}
+
+func (s *NetClsGroup) GetStats(path string, stats *cgroups.Stats) error {
+	return nil
+}

+ 36 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/net_cls_test.go

@@ -0,0 +1,36 @@
+package fs
+
+import (
+	"testing"
+)
+
+const (
+	classidBefore = "0x100002"
+	classidAfter  = "0x100001"
+)
+
+func TestNetClsSetClassid(t *testing.T) {
+	helper := NewCgroupTestUtil("net_cls", t)
+	defer helper.cleanup()
+
+	helper.writeFileContents(map[string]string{
+		"net_cls.classid": classidBefore,
+	})
+
+	helper.CgroupData.c.NetClsClassid = classidAfter
+	netcls := &NetClsGroup{}
+	if err := netcls.Set(helper.CgroupPath, helper.CgroupData.c); err != nil {
+		t.Fatal(err)
+	}
+
+	// As we are in mock environment, we can't get correct value of classid from
+	// net_cls.classid.
+	// So. we just judge if we successfully write classid into file
+	value, err := getCgroupParamString(helper.CgroupPath, "net_cls.classid")
+	if err != nil {
+		t.Fatalf("Failed to parse net_cls.classid - %s", err)
+	}
+	if value != classidAfter {
+		t.Fatal("Got the wrong value, set net_cls.classid failed.")
+	}
+}

+ 40 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/net_prio.go

@@ -0,0 +1,40 @@
+package fs
+
+import (
+	"github.com/docker/libcontainer/cgroups"
+	"github.com/docker/libcontainer/configs"
+)
+
+type NetPrioGroup struct {
+}
+
+func (s *NetPrioGroup) Apply(d *data) error {
+	dir, err := d.join("net_prio")
+	if err != nil && !cgroups.IsNotFound(err) {
+		return err
+	}
+
+	if err := s.Set(dir, d.c); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+func (s *NetPrioGroup) Set(path string, cgroup *configs.Cgroup) error {
+	for _, prioMap := range cgroup.NetPrioIfpriomap {
+		if err := writeFile(path, "net_prio.ifpriomap", prioMap.CgroupString()); err != nil {
+			return err
+		}
+	}
+
+	return nil
+}
+
+func (s *NetPrioGroup) Remove(d *data) error {
+	return removePath(d.path("net_prio"))
+}
+
+func (s *NetPrioGroup) GetStats(path string, stats *cgroups.Stats) error {
+	return nil
+}

+ 36 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/net_prio_test.go

@@ -0,0 +1,36 @@
+package fs
+
+import (
+	"strings"
+	"testing"
+
+	"github.com/docker/libcontainer/configs"
+)
+
+var (
+	prioMap = []*configs.IfPrioMap{
+		{
+			Interface: "test",
+			Priority:  5,
+		},
+	}
+)
+
+func TestNetPrioSetIfPrio(t *testing.T) {
+	helper := NewCgroupTestUtil("net_prio", t)
+	defer helper.cleanup()
+
+	helper.CgroupData.c.NetPrioIfpriomap = prioMap
+	netPrio := &NetPrioGroup{}
+	if err := netPrio.Set(helper.CgroupPath, helper.CgroupData.c); err != nil {
+		t.Fatal(err)
+	}
+
+	value, err := getCgroupParamString(helper.CgroupPath, "net_prio.ifpriomap")
+	if err != nil {
+		t.Fatalf("Failed to parse net_prio.ifpriomap - %s", err)
+	}
+	if !strings.Contains(value, "test 5") {
+		t.Fatal("Got the wrong value, set net_prio.ifpriomap failed.")
+	}
+}

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/perf_event.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/stats_util_test.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/util_test.go

@@ -1,3 +1,5 @@
+// +build linux
+
 /*
 Utility for testing cgroup operations.
 

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/utils.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/fs/utils_test.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package fs
 
 import (

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/stats.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package cgroups
 
 type ThrottlingData struct {

+ 69 - 17
vendor/src/github.com/docker/libcontainer/cgroups/systemd/apply_systemd.go

@@ -41,6 +41,8 @@ var subsystems = map[string]subsystem{
 	"hugetlb":    &fs.HugetlbGroup{},
 	"perf_event": &fs.PerfEventGroup{},
 	"freezer":    &fs.FreezerGroup{},
+	"net_prio":   &fs.NetPrioGroup{},
+	"net_cls":    &fs.NetClsGroup{},
 }
 
 const (
@@ -199,20 +201,23 @@ func (m *Manager) Apply(pid int) error {
 		return err
 	}
 
-	// -1 disables memorySwap
-	if c.MemorySwap >= 0 && c.Memory != 0 {
-		if err := joinMemory(c, pid); err != nil {
-			return err
-		}
-
+	if err := joinMemory(c, pid); err != nil {
+		return err
 	}
 
-	// we need to manually join the freezer and cpuset cgroup in systemd
+	// we need to manually join the freezer, net_cls, net_prio and cpuset cgroup in systemd
 	// because it does not currently support it via the dbus api.
 	if err := joinFreezer(c, pid); err != nil {
 		return err
 	}
 
+	if err := joinNetPrio(c, pid); err != nil {
+		return err
+	}
+	if err := joinNetCls(c, pid); err != nil {
+		return err
+	}
+
 	if err := joinCpuset(c, pid); err != nil {
 		return err
 	}
@@ -294,15 +299,48 @@ func joinCpu(c *configs.Cgroup, pid int) error {
 			return err
 		}
 	}
+	if c.CpuRtPeriod != 0 {
+		if err = writeFile(path, "cpu.rt_period_us", strconv.FormatInt(c.CpuRtPeriod, 10)); err != nil {
+			return err
+		}
+	}
+	if c.CpuRtRuntime != 0 {
+		if err = writeFile(path, "cpu.rt_runtime_us", strconv.FormatInt(c.CpuRtRuntime, 10)); err != nil {
+			return err
+		}
+	}
+
 	return nil
 }
 
 func joinFreezer(c *configs.Cgroup, pid int) error {
-	if _, err := join(c, "freezer", pid); err != nil && !cgroups.IsNotFound(err) {
+	path, err := join(c, "freezer", pid)
+	if err != nil && !cgroups.IsNotFound(err) {
 		return err
 	}
 
-	return nil
+	freezer := subsystems["freezer"]
+	return freezer.Set(path, c)
+}
+
+func joinNetPrio(c *configs.Cgroup, pid int) error {
+	path, err := join(c, "net_prio", pid)
+	if err != nil && !cgroups.IsNotFound(err) {
+		return err
+	}
+	netPrio := subsystems["net_prio"]
+
+	return netPrio.Set(path, c)
+}
+
+func joinNetCls(c *configs.Cgroup, pid int) error {
+	path, err := join(c, "net_cls", pid)
+	if err != nil && !cgroups.IsNotFound(err) {
+		return err
+	}
+	netcls := subsystems["net_cls"]
+
+	return netcls.Set(path, c)
 }
 
 func getSubsystemPath(c *configs.Cgroup, subsystem string) (string, error) {
@@ -409,19 +447,33 @@ func joinDevices(c *configs.Cgroup, pid int) error {
 }
 
 func joinMemory(c *configs.Cgroup, pid int) error {
-	memorySwap := c.MemorySwap
-
-	if memorySwap == 0 {
-		// By default, MemorySwap is set to twice the size of RAM.
-		memorySwap = c.Memory * 2
-	}
-
 	path, err := getSubsystemPath(c, "memory")
 	if err != nil && !cgroups.IsNotFound(err) {
 		return err
 	}
 
-	return writeFile(path, "memory.memsw.limit_in_bytes", strconv.FormatInt(memorySwap, 10))
+	// -1 disables memoryswap
+	if c.Memory != 0 && c.MemorySwap >= 0 {
+		memorySwap := c.MemorySwap
+
+		if memorySwap == 0 {
+			// By default, MemorySwap is set to twice the size of RAM.
+			memorySwap = c.Memory * 2
+		}
+		err = writeFile(path, "memory.memsw.limit_in_bytes", strconv.FormatInt(memorySwap, 10))
+		if err != nil {
+			return err
+		}
+	}
+
+	if c.KernelMemory > 0 {
+		err = writeFile(path, "memory.kmem.limit_in_bytes", strconv.FormatInt(c.KernelMemory, 10))
+		if err != nil {
+			return err
+		}
+	}
+
+	return nil
 }
 
 // systemd does not atm set up the cpuset controller, so we must manually

+ 2 - 0
vendor/src/github.com/docker/libcontainer/cgroups/utils.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package cgroups
 
 import (

+ 18 - 0
vendor/src/github.com/docker/libcontainer/configs/cgroup.go

@@ -8,6 +8,9 @@ const (
 	Thawed    FreezerState = "THAWED"
 )
 
+// TODO Windows: This can be factored out in the future as Cgroups are not
+// supported on the Windows platform.
+
 type Cgroup struct {
 	Name string `json:"name"`
 
@@ -30,6 +33,9 @@ type Cgroup struct {
 	// Total memory usage (memory + swap); set `-1' to disable swap
 	MemorySwap int64 `json:"memory_swap"`
 
+	// Kernel memory limit (in bytes)
+	KernelMemory int64 `json:"kernel_memory"`
+
 	// CPU shares (relative weight vs. other containers)
 	CpuShares int64 `json:"cpu_shares"`
 
@@ -39,6 +45,12 @@ type Cgroup struct {
 	// CPU period to be used for hardcapping (in usecs). 0 to use system default.
 	CpuPeriod int64 `json:"cpu_period"`
 
+	// How many time CPU will use in realtime scheduling (in usecs).
+	CpuRtRuntime int64 `json:"cpu_quota"`
+
+	// CPU period to be used for realtime scheduling (in usecs).
+	CpuRtPeriod int64 `json:"cpu_period"`
+
 	// CPU to use
 	CpusetCpus string `json:"cpuset_cpus"`
 
@@ -71,4 +83,10 @@ type Cgroup struct {
 
 	// Whether to disable OOM Killer
 	OomKillDisable bool `json:"oom_kill_disable"`
+
+	// Set priority of network traffic for container
+	NetPrioIfpriomap []*IfPrioMap `json:"net_prio_ifpriomap"`
+
+	// Set class identifier for container's network packets
+	NetClsClassid string `json:"net_cls_classid"`
 }

+ 3 - 48
vendor/src/github.com/docker/libcontainer/configs/config.go

@@ -1,7 +1,5 @@
 package configs
 
-import "fmt"
-
 type Rlimit struct {
 	Type int    `json:"type"`
 	Hard uint64 `json:"hard"`
@@ -15,6 +13,9 @@ type IDMap struct {
 	Size        int `json:"size"`
 }
 
+// TODO Windows. Many of these fields should be factored out into those parts
+// which are common across platforms, and those which are platform specific.
+
 // Config defines configuration options for executing a process inside a contained environment.
 type Config struct {
 	// NoPivotRoot will use MS_MOVE and a chroot to jail the process into the container's rootfs
@@ -104,49 +105,3 @@ type Config struct {
 	// sysctl -w my.property.name value in Linux.
 	SystemProperties map[string]string `json:"system_properties"`
 }
-
-// Gets the root uid for the process on host which could be non-zero
-// when user namespaces are enabled.
-func (c Config) HostUID() (int, error) {
-	if c.Namespaces.Contains(NEWUSER) {
-		if c.UidMappings == nil {
-			return -1, fmt.Errorf("User namespaces enabled, but no user mappings found.")
-		}
-		id, found := c.hostIDFromMapping(0, c.UidMappings)
-		if !found {
-			return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
-		}
-		return id, nil
-	}
-	// Return default root uid 0
-	return 0, nil
-}
-
-// Gets the root uid for the process on host which could be non-zero
-// when user namespaces are enabled.
-func (c Config) HostGID() (int, error) {
-	if c.Namespaces.Contains(NEWUSER) {
-		if c.GidMappings == nil {
-			return -1, fmt.Errorf("User namespaces enabled, but no gid mappings found.")
-		}
-		id, found := c.hostIDFromMapping(0, c.GidMappings)
-		if !found {
-			return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
-		}
-		return id, nil
-	}
-	// Return default root uid 0
-	return 0, nil
-}
-
-// Utility function that gets a host ID for a container ID from user namespace map
-// if that ID is present in the map.
-func (c Config) hostIDFromMapping(containerID int, uMap []IDMap) (int, bool) {
-	for _, m := range uMap {
-		if (containerID >= m.ContainerID) && (containerID <= (m.ContainerID + m.Size - 1)) {
-			hostID := m.HostID + (containerID - m.ContainerID)
-			return hostID, true
-		}
-	}
-	return -1, false
-}

+ 49 - 0
vendor/src/github.com/docker/libcontainer/configs/config_linux.go

@@ -0,0 +1,49 @@
+package configs
+
+import "fmt"
+
+// Gets the root uid for the process on host which could be non-zero
+// when user namespaces are enabled.
+func (c Config) HostUID() (int, error) {
+	if c.Namespaces.Contains(NEWUSER) {
+		if c.UidMappings == nil {
+			return -1, fmt.Errorf("User namespaces enabled, but no user mappings found.")
+		}
+		id, found := c.hostIDFromMapping(0, c.UidMappings)
+		if !found {
+			return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
+		}
+		return id, nil
+	}
+	// Return default root uid 0
+	return 0, nil
+}
+
+// Gets the root uid for the process on host which could be non-zero
+// when user namespaces are enabled.
+func (c Config) HostGID() (int, error) {
+	if c.Namespaces.Contains(NEWUSER) {
+		if c.GidMappings == nil {
+			return -1, fmt.Errorf("User namespaces enabled, but no gid mappings found.")
+		}
+		id, found := c.hostIDFromMapping(0, c.GidMappings)
+		if !found {
+			return -1, fmt.Errorf("User namespaces enabled, but no root user mapping found.")
+		}
+		return id, nil
+	}
+	// Return default root uid 0
+	return 0, nil
+}
+
+// Utility function that gets a host ID for a container ID from user namespace map
+// if that ID is present in the map.
+func (c Config) hostIDFromMapping(containerID int, uMap []IDMap) (int, bool) {
+	for _, m := range uMap {
+		if (containerID >= m.ContainerID) && (containerID <= (m.ContainerID + m.Size - 1)) {
+			hostID := m.HostID + (containerID - m.ContainerID)
+			return hostID, true
+		}
+	}
+	return -1, false
+}

+ 2 - 0
vendor/src/github.com/docker/libcontainer/configs/device.go

@@ -9,6 +9,8 @@ const (
 	Wildcard = -1
 )
 
+// TODO Windows: This can be factored out in the future
+
 type Device struct {
 	// Device type, block, char, etc.
 	Type rune `json:"type"`

+ 2 - 0
vendor/src/github.com/docker/libcontainer/configs/device_defaults.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package configs
 
 var (

+ 14 - 0
vendor/src/github.com/docker/libcontainer/configs/interface_priority_map.go

@@ -0,0 +1,14 @@
+package configs
+
+import (
+	"fmt"
+)
+
+type IfPrioMap struct {
+	Interface string `json:"interface"`
+	Priority  int64  `json:"priority"`
+}
+
+func (i *IfPrioMap) CgroupString() string {
+	return fmt.Sprintf("%s %d", i.Interface, i.Priority)
+}

+ 0 - 86
vendor/src/github.com/docker/libcontainer/configs/namespaces.go

@@ -1,91 +1,5 @@
 package configs
 
-import "fmt"
-
 type NamespaceType string
 
-const (
-	NEWNET  NamespaceType = "NEWNET"
-	NEWPID  NamespaceType = "NEWPID"
-	NEWNS   NamespaceType = "NEWNS"
-	NEWUTS  NamespaceType = "NEWUTS"
-	NEWIPC  NamespaceType = "NEWIPC"
-	NEWUSER NamespaceType = "NEWUSER"
-)
-
-func NamespaceTypes() []NamespaceType {
-	return []NamespaceType{
-		NEWNET,
-		NEWPID,
-		NEWNS,
-		NEWUTS,
-		NEWIPC,
-		NEWUSER,
-	}
-}
-
-// Namespace defines configuration for each namespace.  It specifies an
-// alternate path that is able to be joined via setns.
-type Namespace struct {
-	Type NamespaceType `json:"type"`
-	Path string        `json:"path"`
-}
-
-func (n *Namespace) GetPath(pid int) string {
-	if n.Path != "" {
-		return n.Path
-	}
-	return fmt.Sprintf("/proc/%d/ns/%s", pid, n.file())
-}
-
-func (n *Namespace) file() string {
-	file := ""
-	switch n.Type {
-	case NEWNET:
-		file = "net"
-	case NEWNS:
-		file = "mnt"
-	case NEWPID:
-		file = "pid"
-	case NEWIPC:
-		file = "ipc"
-	case NEWUSER:
-		file = "user"
-	case NEWUTS:
-		file = "uts"
-	}
-	return file
-}
-
 type Namespaces []Namespace
-
-func (n *Namespaces) Remove(t NamespaceType) bool {
-	i := n.index(t)
-	if i == -1 {
-		return false
-	}
-	*n = append((*n)[:i], (*n)[i+1:]...)
-	return true
-}
-
-func (n *Namespaces) Add(t NamespaceType, path string) {
-	i := n.index(t)
-	if i == -1 {
-		*n = append(*n, Namespace{Type: t, Path: path})
-		return
-	}
-	(*n)[i].Path = path
-}
-
-func (n *Namespaces) index(t NamespaceType) int {
-	for i, ns := range *n {
-		if ns.Type == t {
-			return i
-		}
-	}
-	return -1
-}
-
-func (n *Namespaces) Contains(t NamespaceType) bool {
-	return n.index(t) != -1
-}

+ 89 - 0
vendor/src/github.com/docker/libcontainer/configs/namespaces_linux.go

@@ -0,0 +1,89 @@
+// +build linux
+
+package configs
+
+import "fmt"
+
+const (
+	NEWNET  NamespaceType = "NEWNET"
+	NEWPID  NamespaceType = "NEWPID"
+	NEWNS   NamespaceType = "NEWNS"
+	NEWUTS  NamespaceType = "NEWUTS"
+	NEWIPC  NamespaceType = "NEWIPC"
+	NEWUSER NamespaceType = "NEWUSER"
+)
+
+func NamespaceTypes() []NamespaceType {
+	return []NamespaceType{
+		NEWNET,
+		NEWPID,
+		NEWNS,
+		NEWUTS,
+		NEWIPC,
+		NEWUSER,
+	}
+}
+
+// Namespace defines configuration for each namespace.  It specifies an
+// alternate path that is able to be joined via setns.
+type Namespace struct {
+	Type NamespaceType `json:"type"`
+	Path string        `json:"path"`
+}
+
+func (n *Namespace) GetPath(pid int) string {
+	if n.Path != "" {
+		return n.Path
+	}
+	return fmt.Sprintf("/proc/%d/ns/%s", pid, n.file())
+}
+
+func (n *Namespace) file() string {
+	file := ""
+	switch n.Type {
+	case NEWNET:
+		file = "net"
+	case NEWNS:
+		file = "mnt"
+	case NEWPID:
+		file = "pid"
+	case NEWIPC:
+		file = "ipc"
+	case NEWUSER:
+		file = "user"
+	case NEWUTS:
+		file = "uts"
+	}
+	return file
+}
+
+func (n *Namespaces) Remove(t NamespaceType) bool {
+	i := n.index(t)
+	if i == -1 {
+		return false
+	}
+	*n = append((*n)[:i], (*n)[i+1:]...)
+	return true
+}
+
+func (n *Namespaces) Add(t NamespaceType, path string) {
+	i := n.index(t)
+	if i == -1 {
+		*n = append(*n, Namespace{Type: t, Path: path})
+		return
+	}
+	(*n)[i].Path = path
+}
+
+func (n *Namespaces) index(t NamespaceType) int {
+	for i, ns := range *n {
+		if ns.Type == t {
+			return i
+		}
+	}
+	return -1
+}
+
+func (n *Namespaces) Contains(t NamespaceType) bool {
+	return n.index(t) != -1
+}

+ 1 - 1
vendor/src/github.com/docker/libcontainer/configs/namespaces_syscall_unsupported.go

@@ -1,4 +1,4 @@
-// +build !linux
+// +build !linux,!windows
 
 package configs
 

+ 6 - 0
vendor/src/github.com/docker/libcontainer/configs/namespaces_windows.go

@@ -0,0 +1,6 @@
+package configs
+
+// Namespace defines configuration for each namespace.  It specifies an
+// alternate path that is able to be joined via setns.
+type Namespace struct {
+}

+ 0 - 2
vendor/src/github.com/docker/libcontainer/console_linux.go

@@ -1,5 +1,3 @@
-// +build linux
-
 package libcontainer
 
 import (

+ 30 - 0
vendor/src/github.com/docker/libcontainer/console_windows.go

@@ -0,0 +1,30 @@
+package libcontainer
+
+// newConsole returns an initalized console that can be used within a container
+func newConsole(uid, gid int) (Console, error) {
+	return &windowsConsole{}, nil
+}
+
+// windowsConsole is a Windows psuedo TTY for use within a container.
+type windowsConsole struct {
+}
+
+func (c *windowsConsole) Fd() uintptr {
+	return 0
+}
+
+func (c *windowsConsole) Path() string {
+	return ""
+}
+
+func (c *windowsConsole) Read(b []byte) (int, error) {
+	return 0, nil
+}
+
+func (c *windowsConsole) Write(b []byte) (int, error) {
+	return 0, nil
+}
+
+func (c *windowsConsole) Close() error {
+	return nil
+}

+ 18 - 0
vendor/src/github.com/docker/libcontainer/container.go

@@ -21,6 +21,9 @@ const (
 	// The container exists, but all its processes are paused.
 	Paused
 
+	// The container exists, but its state is saved on disk
+	Checkpointed
+
 	// The container does not exist.
 	Destroyed
 )
@@ -46,6 +49,9 @@ type State struct {
 
 	// Config is the container's configuration.
 	Config configs.Config `json:"config"`
+
+	// Container's standard descriptors (std{in,out,err}), needed for checkpoint and restore
+	ExternalDescriptors []string `json:"external_descriptors,omitempty"`
 }
 
 // A libcontainer container object.
@@ -108,6 +114,18 @@ type Container interface {
 	// Systemerror - System error.
 	Start(process *Process) (err error)
 
+	// Checkpoint checkpoints the running container's state to disk using the criu(8) utility.
+	//
+	// errors:
+	// Systemerror - System error.
+	Checkpoint(criuOpts *CriuOpts) error
+
+	// Restore restores the checkpointed container to a running state using the criu(8) utiity.
+	//
+	// errors:
+	// Systemerror - System error.
+	Restore(process *Process, criuOpts *CriuOpts) error
+
 	// Destroys the container after killing all running processes.
 	//
 	// Any event registrations are removed before the container is destroyed.

+ 462 - 1
vendor/src/github.com/docker/libcontainer/container_linux.go

@@ -5,15 +5,19 @@ package libcontainer
 import (
 	"encoding/json"
 	"fmt"
+	"io/ioutil"
 	"os"
 	"os/exec"
 	"path/filepath"
+	"strings"
 	"sync"
 	"syscall"
 
 	"github.com/Sirupsen/logrus"
 	"github.com/docker/libcontainer/cgroups"
 	"github.com/docker/libcontainer/configs"
+	"github.com/docker/libcontainer/criurpc"
+	"github.com/golang/protobuf/proto"
 )
 
 const stdioFdCount = 3
@@ -26,6 +30,7 @@ type linuxContainer struct {
 	initPath      string
 	initArgs      []string
 	initProcess   parentProcess
+	criuPath      string
 	m             sync.Mutex
 }
 
@@ -108,7 +113,6 @@ func (c *linuxContainer) Start(process *Process) error {
 	}
 	process.ops = parent
 	if doInit {
-
 		c.updateState(parent)
 	}
 	return nil
@@ -254,6 +258,458 @@ func (c *linuxContainer) NotifyOOM() (<-chan struct{}, error) {
 	return notifyOnOOM(c.cgroupManager.GetPaths())
 }
 
+// XXX debug support, remove when debugging done.
+func addArgsFromEnv(evar string, args *[]string) {
+	if e := os.Getenv(evar); e != "" {
+		for _, f := range strings.Fields(e) {
+			*args = append(*args, f)
+		}
+	}
+	fmt.Printf(">>> criu %v\n", *args)
+}
+
+func (c *linuxContainer) checkCriuVersion() error {
+	var x, y, z int
+
+	out, err := exec.Command(c.criuPath, "-V").Output()
+	if err != nil {
+		return err
+	}
+
+	n, err := fmt.Sscanf(string(out), "Version: %d.%d.%d\n", &x, &y, &z) // 1.5.2
+	if err != nil {
+		n, err = fmt.Sscanf(string(out), "Version: %d.%d\n", &x, &y) // 1.6
+	}
+	if n < 2 || err != nil {
+		return fmt.Errorf("Unable to parse the CRIU version: %s %d %s", out, n, err)
+	}
+
+	if x*10000+y*100+z < 10502 {
+		return fmt.Errorf("CRIU version must be 1.5.2 or higher")
+	}
+
+	return nil
+}
+
+const descriptors_filename = "descriptors.json"
+
+func (c *linuxContainer) Checkpoint(criuOpts *CriuOpts) error {
+	c.m.Lock()
+	defer c.m.Unlock()
+
+	if err := c.checkCriuVersion(); err != nil {
+		return err
+	}
+
+	if criuOpts.ImagesDirectory == "" {
+		criuOpts.ImagesDirectory = filepath.Join(c.root, "criu.image")
+	}
+
+	// Since a container can be C/R'ed multiple times,
+	// the checkpoint directory may already exist.
+	if err := os.Mkdir(criuOpts.ImagesDirectory, 0755); err != nil && !os.IsExist(err) {
+		return err
+	}
+
+	if criuOpts.WorkDirectory == "" {
+		criuOpts.WorkDirectory = filepath.Join(c.root, "criu.work")
+	}
+
+	if err := os.Mkdir(criuOpts.WorkDirectory, 0755); err != nil && !os.IsExist(err) {
+		return err
+	}
+
+	workDir, err := os.Open(criuOpts.WorkDirectory)
+	if err != nil {
+		return err
+	}
+	defer workDir.Close()
+
+	imageDir, err := os.Open(criuOpts.ImagesDirectory)
+	if err != nil {
+		return err
+	}
+	defer imageDir.Close()
+
+	rpcOpts := criurpc.CriuOpts{
+		ImagesDirFd:    proto.Int32(int32(imageDir.Fd())),
+		WorkDirFd:      proto.Int32(int32(workDir.Fd())),
+		LogLevel:       proto.Int32(4),
+		LogFile:        proto.String("dump.log"),
+		Root:           proto.String(c.config.Rootfs),
+		ManageCgroups:  proto.Bool(true),
+		NotifyScripts:  proto.Bool(true),
+		Pid:            proto.Int32(int32(c.initProcess.pid())),
+		ShellJob:       proto.Bool(criuOpts.ShellJob),
+		LeaveRunning:   proto.Bool(criuOpts.LeaveRunning),
+		TcpEstablished: proto.Bool(criuOpts.TcpEstablished),
+		ExtUnixSk:      proto.Bool(criuOpts.ExternalUnixConnections),
+	}
+
+	// append optional criu opts, e.g., page-server and port
+	if criuOpts.PageServer.Address != "" && criuOpts.PageServer.Port != 0 {
+		rpcOpts.Ps = &criurpc.CriuPageServerInfo{
+			Address: proto.String(criuOpts.PageServer.Address),
+			Port:    proto.Int32(criuOpts.PageServer.Port),
+		}
+	}
+
+	t := criurpc.CriuReqType_DUMP
+	req := criurpc.CriuReq{
+		Type: &t,
+		Opts: &rpcOpts,
+	}
+
+	for _, m := range c.config.Mounts {
+		if m.Device == "bind" {
+			mountDest := m.Destination
+			if strings.HasPrefix(mountDest, c.config.Rootfs) {
+				mountDest = mountDest[len(c.config.Rootfs):]
+			}
+
+			extMnt := new(criurpc.ExtMountMap)
+			extMnt.Key = proto.String(mountDest)
+			extMnt.Val = proto.String(mountDest)
+			req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
+		}
+	}
+
+	// Write the FD info to a file in the image directory
+
+	fdsJSON, err := json.Marshal(c.initProcess.externalDescriptors())
+	if err != nil {
+		return err
+	}
+
+	err = ioutil.WriteFile(filepath.Join(criuOpts.ImagesDirectory, descriptors_filename), fdsJSON, 0655)
+	if err != nil {
+		return err
+	}
+
+	err = c.criuSwrk(nil, &req, criuOpts)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (c *linuxContainer) Restore(process *Process, criuOpts *CriuOpts) error {
+	c.m.Lock()
+	defer c.m.Unlock()
+
+	if err := c.checkCriuVersion(); err != nil {
+		return err
+	}
+
+	if criuOpts.WorkDirectory == "" {
+		criuOpts.WorkDirectory = filepath.Join(c.root, "criu.work")
+	}
+	// Since a container can be C/R'ed multiple times,
+	// the work directory may already exist.
+	if err := os.Mkdir(criuOpts.WorkDirectory, 0655); err != nil && !os.IsExist(err) {
+		return err
+	}
+
+	workDir, err := os.Open(criuOpts.WorkDirectory)
+	if err != nil {
+		return err
+	}
+	defer workDir.Close()
+
+	if criuOpts.ImagesDirectory == "" {
+		criuOpts.ImagesDirectory = filepath.Join(c.root, "criu.image")
+	}
+	imageDir, err := os.Open(criuOpts.ImagesDirectory)
+	if err != nil {
+		return err
+	}
+	defer imageDir.Close()
+
+	// CRIU has a few requirements for a root directory:
+	// * it must be a mount point
+	// * its parent must not be overmounted
+	// c.config.Rootfs is bind-mounted to a temporary directory
+	// to satisfy these requirements.
+	root := filepath.Join(c.root, "criu-root")
+	if err := os.Mkdir(root, 0755); err != nil {
+		return err
+	}
+	defer os.Remove(root)
+
+	root, err = filepath.EvalSymlinks(root)
+	if err != nil {
+		return err
+	}
+
+	err = syscall.Mount(c.config.Rootfs, root, "", syscall.MS_BIND|syscall.MS_REC, "")
+	if err != nil {
+		return err
+	}
+	defer syscall.Unmount(root, syscall.MNT_DETACH)
+
+	t := criurpc.CriuReqType_RESTORE
+	req := criurpc.CriuReq{
+		Type: &t,
+		Opts: &criurpc.CriuOpts{
+			ImagesDirFd:    proto.Int32(int32(imageDir.Fd())),
+			WorkDirFd:      proto.Int32(int32(workDir.Fd())),
+			EvasiveDevices: proto.Bool(true),
+			LogLevel:       proto.Int32(4),
+			LogFile:        proto.String("restore.log"),
+			RstSibling:     proto.Bool(true),
+			Root:           proto.String(root),
+			ManageCgroups:  proto.Bool(true),
+			NotifyScripts:  proto.Bool(true),
+			ShellJob:       proto.Bool(criuOpts.ShellJob),
+			ExtUnixSk:      proto.Bool(criuOpts.ExternalUnixConnections),
+			TcpEstablished: proto.Bool(criuOpts.TcpEstablished),
+		},
+	}
+	for _, m := range c.config.Mounts {
+		if m.Device == "bind" {
+			mountDest := m.Destination
+			if strings.HasPrefix(mountDest, c.config.Rootfs) {
+				mountDest = mountDest[len(c.config.Rootfs):]
+			}
+
+			extMnt := new(criurpc.ExtMountMap)
+			extMnt.Key = proto.String(mountDest)
+			extMnt.Val = proto.String(m.Source)
+			req.Opts.ExtMnt = append(req.Opts.ExtMnt, extMnt)
+		}
+	}
+	for _, iface := range c.config.Networks {
+		switch iface.Type {
+		case "veth":
+			veth := new(criurpc.CriuVethPair)
+			veth.IfOut = proto.String(iface.HostInterfaceName)
+			veth.IfIn = proto.String(iface.Name)
+			req.Opts.Veths = append(req.Opts.Veths, veth)
+			break
+		case "loopback":
+			break
+		}
+	}
+
+	var (
+		fds    []string
+		fdJSON []byte
+	)
+
+	if fdJSON, err = ioutil.ReadFile(filepath.Join(criuOpts.ImagesDirectory, descriptors_filename)); err != nil {
+		return err
+	}
+
+	if err = json.Unmarshal(fdJSON, &fds); err != nil {
+		return err
+	}
+
+	for i := range fds {
+		if s := fds[i]; strings.Contains(s, "pipe:") {
+			inheritFd := new(criurpc.InheritFd)
+			inheritFd.Key = proto.String(s)
+			inheritFd.Fd = proto.Int32(int32(i))
+			req.Opts.InheritFd = append(req.Opts.InheritFd, inheritFd)
+		}
+	}
+
+	err = c.criuSwrk(process, &req, criuOpts)
+	if err != nil {
+		return err
+	}
+	return nil
+}
+
+func (c *linuxContainer) criuSwrk(process *Process, req *criurpc.CriuReq, opts *CriuOpts) error {
+	fds, err := syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_SEQPACKET|syscall.SOCK_CLOEXEC, 0)
+	if err != nil {
+		return err
+	}
+
+	criuClient := os.NewFile(uintptr(fds[0]), "criu-transport-client")
+	criuServer := os.NewFile(uintptr(fds[1]), "criu-transport-server")
+	defer criuClient.Close()
+	defer criuServer.Close()
+
+	args := []string{"swrk", "3"}
+	cmd := exec.Command(c.criuPath, args...)
+	if process != nil {
+		cmd.Stdin = process.Stdin
+		cmd.Stdout = process.Stdout
+		cmd.Stderr = process.Stderr
+	}
+	cmd.ExtraFiles = append(cmd.ExtraFiles, criuServer)
+
+	if err := cmd.Start(); err != nil {
+		return err
+	}
+	criuServer.Close()
+
+	defer func() {
+		criuClient.Close()
+		_, err := cmd.Process.Wait()
+		if err != nil {
+			return
+		}
+	}()
+
+	var extFds []string
+	if process != nil {
+		extFds, err = getPipeFds(cmd.Process.Pid)
+		if err != nil {
+			return err
+		}
+	}
+
+	data, err := proto.Marshal(req)
+	if err != nil {
+		return err
+	}
+	_, err = criuClient.Write(data)
+	if err != nil {
+		return err
+	}
+
+	buf := make([]byte, 10*4096)
+	for true {
+		n, err := criuClient.Read(buf)
+		if err != nil {
+			return err
+		}
+		if n == 0 {
+			return fmt.Errorf("unexpected EOF")
+		}
+		if n == len(buf) {
+			return fmt.Errorf("buffer is too small")
+		}
+
+		resp := new(criurpc.CriuResp)
+		err = proto.Unmarshal(buf[:n], resp)
+		if err != nil {
+			return err
+		}
+		if !resp.GetSuccess() {
+			return fmt.Errorf("criu failed: type %s errno %d", req.GetType().String(), resp.GetCrErrno())
+		}
+
+		t := resp.GetType()
+		switch {
+		case t == criurpc.CriuReqType_NOTIFY:
+			if err := c.criuNotifications(resp, process, opts, extFds); err != nil {
+				return err
+			}
+			t = criurpc.CriuReqType_NOTIFY
+			req = &criurpc.CriuReq{
+				Type:          &t,
+				NotifySuccess: proto.Bool(true),
+			}
+			data, err = proto.Marshal(req)
+			if err != nil {
+				return err
+			}
+			n, err = criuClient.Write(data)
+			if err != nil {
+				return err
+			}
+			continue
+		case t == criurpc.CriuReqType_RESTORE:
+		case t == criurpc.CriuReqType_DUMP:
+			break
+		default:
+			return fmt.Errorf("unable to parse the response %s", resp.String())
+		}
+
+		break
+	}
+
+	// cmd.Wait() waits cmd.goroutines which are used for proxying file descriptors.
+	// Here we want to wait only the CRIU process.
+	st, err := cmd.Process.Wait()
+	if err != nil {
+		return err
+	}
+	if !st.Success() {
+		return fmt.Errorf("criu failed: %s", st.String())
+	}
+	return nil
+}
+
+// block any external network activity
+func lockNetwork(config *configs.Config) error {
+	for _, config := range config.Networks {
+		strategy, err := getStrategy(config.Type)
+		if err != nil {
+			return err
+		}
+
+		if err := strategy.detach(config); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func unlockNetwork(config *configs.Config) error {
+	for _, config := range config.Networks {
+		strategy, err := getStrategy(config.Type)
+		if err != nil {
+			return err
+		}
+		if err = strategy.attach(config); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func (c *linuxContainer) criuNotifications(resp *criurpc.CriuResp, process *Process, opts *CriuOpts, fds []string) error {
+	notify := resp.GetNotify()
+	if notify == nil {
+		return fmt.Errorf("invalid response: %s", resp.String())
+	}
+
+	switch {
+	case notify.GetScript() == "post-dump":
+		if !opts.LeaveRunning {
+			f, err := os.Create(filepath.Join(c.root, "checkpoint"))
+			if err != nil {
+				return err
+			}
+			f.Close()
+		}
+		break
+
+	case notify.GetScript() == "network-unlock":
+		if err := unlockNetwork(c.config); err != nil {
+			return err
+		}
+		break
+
+	case notify.GetScript() == "network-lock":
+		if err := lockNetwork(c.config); err != nil {
+			return err
+		}
+		break
+
+	case notify.GetScript() == "post-restore":
+		pid := notify.GetPid()
+		r, err := newRestoredProcess(int(pid), fds)
+		if err != nil {
+			return err
+		}
+
+		// TODO: crosbymichael restore previous process information by saving the init process information in
+		// the container's state file or separate process state files.
+		if err := c.updateState(r); err != nil {
+			return err
+		}
+		process.ops = r
+		break
+	}
+
+	return nil
+}
+
 func (c *linuxContainer) updateState(process parentProcess) error {
 	c.initProcess = process
 	state, err := c.currentState()
@@ -265,10 +721,14 @@ func (c *linuxContainer) updateState(process parentProcess) error {
 		return err
 	}
 	defer f.Close()
+	os.Remove(filepath.Join(c.root, "checkpoint"))
 	return json.NewEncoder(f).Encode(state)
 }
 
 func (c *linuxContainer) currentStatus() (Status, error) {
+	if _, err := os.Stat(filepath.Join(c.root, "checkpoint")); err == nil {
+		return Checkpointed, nil
+	}
 	if c.initProcess == nil {
 		return Destroyed, nil
 	}
@@ -304,6 +764,7 @@ func (c *linuxContainer) currentState() (*State, error) {
 		InitProcessStartTime: startTime,
 		CgroupPaths:          c.cgroupManager.GetPaths(),
 		NamespacePaths:       make(map[configs.NamespaceType]string),
+		ExternalDescriptors:  c.initProcess.externalDescriptors(),
 	}
 	for _, ns := range c.config.Namespaces {
 		state.NamespacePaths[ns.Type] = ns.GetPath(c.initProcess.pid())

+ 7 - 0
vendor/src/github.com/docker/libcontainer/container_linux_test.go

@@ -74,6 +74,13 @@ func (m *mockProcess) signal(_ os.Signal) error {
 	return nil
 }
 
+func (p *mockProcess) externalDescriptors() []string {
+	return []string{}
+}
+
+func (p *mockProcess) setExternalDescriptors(newFds []string) {
+}
+
 func TestGetContainerPids(t *testing.T) {
 	container := &linuxContainer{
 		id:            "myid",

+ 16 - 0
vendor/src/github.com/docker/libcontainer/criu_opts.go

@@ -0,0 +1,16 @@
+package libcontainer
+
+type CriuPageServerInfo struct {
+	Address string // IP address of CRIU page server
+	Port    int32  // port number of CRIU page server
+}
+
+type CriuOpts struct {
+	ImagesDirectory         string             // directory for storing image files
+	WorkDirectory           string             // directory to cd and write logs/pidfiles/stats to
+	LeaveRunning            bool               // leave container in running state after checkpoint
+	TcpEstablished          bool               // checkpoint/restore established TCP connections
+	ExternalUnixConnections bool               // allow external unix connections
+	ShellJob                bool               // allow to dump and restore shell jobs
+	PageServer              CriuPageServerInfo // allow to dump to criu page server
+}

+ 2 - 0
vendor/src/github.com/docker/libcontainer/criurpc/Makefile

@@ -0,0 +1,2 @@
+gen: criurpc.proto
+	protoc --go_out=. criurpc.proto

+ 602 - 0
vendor/src/github.com/docker/libcontainer/criurpc/criurpc.pb.go

@@ -0,0 +1,602 @@
+// Code generated by protoc-gen-go.
+// source: criurpc.proto
+// DO NOT EDIT!
+
+package criurpc
+
+import proto "github.com/golang/protobuf/proto"
+import json "encoding/json"
+import math "math"
+
+// Reference proto, json, and math imports to suppress error if they are not otherwise used.
+var _ = proto.Marshal
+var _ = &json.SyntaxError{}
+var _ = math.Inf
+
+type CriuReqType int32
+
+const (
+	CriuReqType_EMPTY         CriuReqType = 0
+	CriuReqType_DUMP          CriuReqType = 1
+	CriuReqType_RESTORE       CriuReqType = 2
+	CriuReqType_CHECK         CriuReqType = 3
+	CriuReqType_PRE_DUMP      CriuReqType = 4
+	CriuReqType_PAGE_SERVER   CriuReqType = 5
+	CriuReqType_NOTIFY        CriuReqType = 6
+	CriuReqType_CPUINFO_DUMP  CriuReqType = 7
+	CriuReqType_CPUINFO_CHECK CriuReqType = 8
+)
+
+var CriuReqType_name = map[int32]string{
+	0: "EMPTY",
+	1: "DUMP",
+	2: "RESTORE",
+	3: "CHECK",
+	4: "PRE_DUMP",
+	5: "PAGE_SERVER",
+	6: "NOTIFY",
+	7: "CPUINFO_DUMP",
+	8: "CPUINFO_CHECK",
+}
+var CriuReqType_value = map[string]int32{
+	"EMPTY":         0,
+	"DUMP":          1,
+	"RESTORE":       2,
+	"CHECK":         3,
+	"PRE_DUMP":      4,
+	"PAGE_SERVER":   5,
+	"NOTIFY":        6,
+	"CPUINFO_DUMP":  7,
+	"CPUINFO_CHECK": 8,
+}
+
+func (x CriuReqType) Enum() *CriuReqType {
+	p := new(CriuReqType)
+	*p = x
+	return p
+}
+func (x CriuReqType) String() string {
+	return proto.EnumName(CriuReqType_name, int32(x))
+}
+func (x CriuReqType) MarshalJSON() ([]byte, error) {
+	return json.Marshal(x.String())
+}
+func (x *CriuReqType) UnmarshalJSON(data []byte) error {
+	value, err := proto.UnmarshalJSONEnum(CriuReqType_value, data, "CriuReqType")
+	if err != nil {
+		return err
+	}
+	*x = CriuReqType(value)
+	return nil
+}
+
+type CriuPageServerInfo struct {
+	Address          *string `protobuf:"bytes,1,opt,name=address" json:"address,omitempty"`
+	Port             *int32  `protobuf:"varint,2,opt,name=port" json:"port,omitempty"`
+	Pid              *int32  `protobuf:"varint,3,opt,name=pid" json:"pid,omitempty"`
+	Fd               *int32  `protobuf:"varint,4,opt,name=fd" json:"fd,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *CriuPageServerInfo) Reset()         { *m = CriuPageServerInfo{} }
+func (m *CriuPageServerInfo) String() string { return proto.CompactTextString(m) }
+func (*CriuPageServerInfo) ProtoMessage()    {}
+
+func (m *CriuPageServerInfo) GetAddress() string {
+	if m != nil && m.Address != nil {
+		return *m.Address
+	}
+	return ""
+}
+
+func (m *CriuPageServerInfo) GetPort() int32 {
+	if m != nil && m.Port != nil {
+		return *m.Port
+	}
+	return 0
+}
+
+func (m *CriuPageServerInfo) GetPid() int32 {
+	if m != nil && m.Pid != nil {
+		return *m.Pid
+	}
+	return 0
+}
+
+func (m *CriuPageServerInfo) GetFd() int32 {
+	if m != nil && m.Fd != nil {
+		return *m.Fd
+	}
+	return 0
+}
+
+type CriuVethPair struct {
+	IfIn             *string `protobuf:"bytes,1,req,name=if_in" json:"if_in,omitempty"`
+	IfOut            *string `protobuf:"bytes,2,req,name=if_out" json:"if_out,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *CriuVethPair) Reset()         { *m = CriuVethPair{} }
+func (m *CriuVethPair) String() string { return proto.CompactTextString(m) }
+func (*CriuVethPair) ProtoMessage()    {}
+
+func (m *CriuVethPair) GetIfIn() string {
+	if m != nil && m.IfIn != nil {
+		return *m.IfIn
+	}
+	return ""
+}
+
+func (m *CriuVethPair) GetIfOut() string {
+	if m != nil && m.IfOut != nil {
+		return *m.IfOut
+	}
+	return ""
+}
+
+type ExtMountMap struct {
+	Key              *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"`
+	Val              *string `protobuf:"bytes,2,req,name=val" json:"val,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *ExtMountMap) Reset()         { *m = ExtMountMap{} }
+func (m *ExtMountMap) String() string { return proto.CompactTextString(m) }
+func (*ExtMountMap) ProtoMessage()    {}
+
+func (m *ExtMountMap) GetKey() string {
+	if m != nil && m.Key != nil {
+		return *m.Key
+	}
+	return ""
+}
+
+func (m *ExtMountMap) GetVal() string {
+	if m != nil && m.Val != nil {
+		return *m.Val
+	}
+	return ""
+}
+
+type InheritFd struct {
+	Key              *string `protobuf:"bytes,1,req,name=key" json:"key,omitempty"`
+	Fd               *int32  `protobuf:"varint,2,req,name=fd" json:"fd,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *InheritFd) Reset()         { *m = InheritFd{} }
+func (m *InheritFd) String() string { return proto.CompactTextString(m) }
+func (*InheritFd) ProtoMessage()    {}
+
+func (m *InheritFd) GetKey() string {
+	if m != nil && m.Key != nil {
+		return *m.Key
+	}
+	return ""
+}
+
+func (m *InheritFd) GetFd() int32 {
+	if m != nil && m.Fd != nil {
+		return *m.Fd
+	}
+	return 0
+}
+
+type CgroupRoot struct {
+	Ctrl             *string `protobuf:"bytes,1,opt,name=ctrl" json:"ctrl,omitempty"`
+	Path             *string `protobuf:"bytes,2,req,name=path" json:"path,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *CgroupRoot) Reset()         { *m = CgroupRoot{} }
+func (m *CgroupRoot) String() string { return proto.CompactTextString(m) }
+func (*CgroupRoot) ProtoMessage()    {}
+
+func (m *CgroupRoot) GetCtrl() string {
+	if m != nil && m.Ctrl != nil {
+		return *m.Ctrl
+	}
+	return ""
+}
+
+func (m *CgroupRoot) GetPath() string {
+	if m != nil && m.Path != nil {
+		return *m.Path
+	}
+	return ""
+}
+
+type CriuOpts struct {
+	ImagesDirFd      *int32              `protobuf:"varint,1,req,name=images_dir_fd" json:"images_dir_fd,omitempty"`
+	Pid              *int32              `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"`
+	LeaveRunning     *bool               `protobuf:"varint,3,opt,name=leave_running" json:"leave_running,omitempty"`
+	ExtUnixSk        *bool               `protobuf:"varint,4,opt,name=ext_unix_sk" json:"ext_unix_sk,omitempty"`
+	TcpEstablished   *bool               `protobuf:"varint,5,opt,name=tcp_established" json:"tcp_established,omitempty"`
+	EvasiveDevices   *bool               `protobuf:"varint,6,opt,name=evasive_devices" json:"evasive_devices,omitempty"`
+	ShellJob         *bool               `protobuf:"varint,7,opt,name=shell_job" json:"shell_job,omitempty"`
+	FileLocks        *bool               `protobuf:"varint,8,opt,name=file_locks" json:"file_locks,omitempty"`
+	LogLevel         *int32              `protobuf:"varint,9,opt,name=log_level,def=2" json:"log_level,omitempty"`
+	LogFile          *string             `protobuf:"bytes,10,opt,name=log_file" json:"log_file,omitempty"`
+	Ps               *CriuPageServerInfo `protobuf:"bytes,11,opt,name=ps" json:"ps,omitempty"`
+	NotifyScripts    *bool               `protobuf:"varint,12,opt,name=notify_scripts" json:"notify_scripts,omitempty"`
+	Root             *string             `protobuf:"bytes,13,opt,name=root" json:"root,omitempty"`
+	ParentImg        *string             `protobuf:"bytes,14,opt,name=parent_img" json:"parent_img,omitempty"`
+	TrackMem         *bool               `protobuf:"varint,15,opt,name=track_mem" json:"track_mem,omitempty"`
+	AutoDedup        *bool               `protobuf:"varint,16,opt,name=auto_dedup" json:"auto_dedup,omitempty"`
+	WorkDirFd        *int32              `protobuf:"varint,17,opt,name=work_dir_fd" json:"work_dir_fd,omitempty"`
+	LinkRemap        *bool               `protobuf:"varint,18,opt,name=link_remap" json:"link_remap,omitempty"`
+	Veths            []*CriuVethPair     `protobuf:"bytes,19,rep,name=veths" json:"veths,omitempty"`
+	CpuCap           *uint32             `protobuf:"varint,20,opt,name=cpu_cap,def=4294967295" json:"cpu_cap,omitempty"`
+	ForceIrmap       *bool               `protobuf:"varint,21,opt,name=force_irmap" json:"force_irmap,omitempty"`
+	ExecCmd          []string            `protobuf:"bytes,22,rep,name=exec_cmd" json:"exec_cmd,omitempty"`
+	ExtMnt           []*ExtMountMap      `protobuf:"bytes,23,rep,name=ext_mnt" json:"ext_mnt,omitempty"`
+	ManageCgroups    *bool               `protobuf:"varint,24,opt,name=manage_cgroups" json:"manage_cgroups,omitempty"`
+	CgRoot           []*CgroupRoot       `protobuf:"bytes,25,rep,name=cg_root" json:"cg_root,omitempty"`
+	RstSibling       *bool               `protobuf:"varint,26,opt,name=rst_sibling" json:"rst_sibling,omitempty"`
+	InheritFd        []*InheritFd        `protobuf:"bytes,27,rep,name=inherit_fd" json:"inherit_fd,omitempty"`
+	XXX_unrecognized []byte              `json:"-"`
+}
+
+func (m *CriuOpts) Reset()         { *m = CriuOpts{} }
+func (m *CriuOpts) String() string { return proto.CompactTextString(m) }
+func (*CriuOpts) ProtoMessage()    {}
+
+const Default_CriuOpts_LogLevel int32 = 2
+const Default_CriuOpts_CpuCap uint32 = 4294967295
+
+func (m *CriuOpts) GetImagesDirFd() int32 {
+	if m != nil && m.ImagesDirFd != nil {
+		return *m.ImagesDirFd
+	}
+	return 0
+}
+
+func (m *CriuOpts) GetPid() int32 {
+	if m != nil && m.Pid != nil {
+		return *m.Pid
+	}
+	return 0
+}
+
+func (m *CriuOpts) GetLeaveRunning() bool {
+	if m != nil && m.LeaveRunning != nil {
+		return *m.LeaveRunning
+	}
+	return false
+}
+
+func (m *CriuOpts) GetExtUnixSk() bool {
+	if m != nil && m.ExtUnixSk != nil {
+		return *m.ExtUnixSk
+	}
+	return false
+}
+
+func (m *CriuOpts) GetTcpEstablished() bool {
+	if m != nil && m.TcpEstablished != nil {
+		return *m.TcpEstablished
+	}
+	return false
+}
+
+func (m *CriuOpts) GetEvasiveDevices() bool {
+	if m != nil && m.EvasiveDevices != nil {
+		return *m.EvasiveDevices
+	}
+	return false
+}
+
+func (m *CriuOpts) GetShellJob() bool {
+	if m != nil && m.ShellJob != nil {
+		return *m.ShellJob
+	}
+	return false
+}
+
+func (m *CriuOpts) GetFileLocks() bool {
+	if m != nil && m.FileLocks != nil {
+		return *m.FileLocks
+	}
+	return false
+}
+
+func (m *CriuOpts) GetLogLevel() int32 {
+	if m != nil && m.LogLevel != nil {
+		return *m.LogLevel
+	}
+	return Default_CriuOpts_LogLevel
+}
+
+func (m *CriuOpts) GetLogFile() string {
+	if m != nil && m.LogFile != nil {
+		return *m.LogFile
+	}
+	return ""
+}
+
+func (m *CriuOpts) GetPs() *CriuPageServerInfo {
+	if m != nil {
+		return m.Ps
+	}
+	return nil
+}
+
+func (m *CriuOpts) GetNotifyScripts() bool {
+	if m != nil && m.NotifyScripts != nil {
+		return *m.NotifyScripts
+	}
+	return false
+}
+
+func (m *CriuOpts) GetRoot() string {
+	if m != nil && m.Root != nil {
+		return *m.Root
+	}
+	return ""
+}
+
+func (m *CriuOpts) GetParentImg() string {
+	if m != nil && m.ParentImg != nil {
+		return *m.ParentImg
+	}
+	return ""
+}
+
+func (m *CriuOpts) GetTrackMem() bool {
+	if m != nil && m.TrackMem != nil {
+		return *m.TrackMem
+	}
+	return false
+}
+
+func (m *CriuOpts) GetAutoDedup() bool {
+	if m != nil && m.AutoDedup != nil {
+		return *m.AutoDedup
+	}
+	return false
+}
+
+func (m *CriuOpts) GetWorkDirFd() int32 {
+	if m != nil && m.WorkDirFd != nil {
+		return *m.WorkDirFd
+	}
+	return 0
+}
+
+func (m *CriuOpts) GetLinkRemap() bool {
+	if m != nil && m.LinkRemap != nil {
+		return *m.LinkRemap
+	}
+	return false
+}
+
+func (m *CriuOpts) GetVeths() []*CriuVethPair {
+	if m != nil {
+		return m.Veths
+	}
+	return nil
+}
+
+func (m *CriuOpts) GetCpuCap() uint32 {
+	if m != nil && m.CpuCap != nil {
+		return *m.CpuCap
+	}
+	return Default_CriuOpts_CpuCap
+}
+
+func (m *CriuOpts) GetForceIrmap() bool {
+	if m != nil && m.ForceIrmap != nil {
+		return *m.ForceIrmap
+	}
+	return false
+}
+
+func (m *CriuOpts) GetExecCmd() []string {
+	if m != nil {
+		return m.ExecCmd
+	}
+	return nil
+}
+
+func (m *CriuOpts) GetExtMnt() []*ExtMountMap {
+	if m != nil {
+		return m.ExtMnt
+	}
+	return nil
+}
+
+func (m *CriuOpts) GetManageCgroups() bool {
+	if m != nil && m.ManageCgroups != nil {
+		return *m.ManageCgroups
+	}
+	return false
+}
+
+func (m *CriuOpts) GetCgRoot() []*CgroupRoot {
+	if m != nil {
+		return m.CgRoot
+	}
+	return nil
+}
+
+func (m *CriuOpts) GetRstSibling() bool {
+	if m != nil && m.RstSibling != nil {
+		return *m.RstSibling
+	}
+	return false
+}
+
+func (m *CriuOpts) GetInheritFd() []*InheritFd {
+	if m != nil {
+		return m.InheritFd
+	}
+	return nil
+}
+
+type CriuDumpResp struct {
+	Restored         *bool  `protobuf:"varint,1,opt,name=restored" json:"restored,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *CriuDumpResp) Reset()         { *m = CriuDumpResp{} }
+func (m *CriuDumpResp) String() string { return proto.CompactTextString(m) }
+func (*CriuDumpResp) ProtoMessage()    {}
+
+func (m *CriuDumpResp) GetRestored() bool {
+	if m != nil && m.Restored != nil {
+		return *m.Restored
+	}
+	return false
+}
+
+type CriuRestoreResp struct {
+	Pid              *int32 `protobuf:"varint,1,req,name=pid" json:"pid,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *CriuRestoreResp) Reset()         { *m = CriuRestoreResp{} }
+func (m *CriuRestoreResp) String() string { return proto.CompactTextString(m) }
+func (*CriuRestoreResp) ProtoMessage()    {}
+
+func (m *CriuRestoreResp) GetPid() int32 {
+	if m != nil && m.Pid != nil {
+		return *m.Pid
+	}
+	return 0
+}
+
+type CriuNotify struct {
+	Script           *string `protobuf:"bytes,1,opt,name=script" json:"script,omitempty"`
+	Pid              *int32  `protobuf:"varint,2,opt,name=pid" json:"pid,omitempty"`
+	XXX_unrecognized []byte  `json:"-"`
+}
+
+func (m *CriuNotify) Reset()         { *m = CriuNotify{} }
+func (m *CriuNotify) String() string { return proto.CompactTextString(m) }
+func (*CriuNotify) ProtoMessage()    {}
+
+func (m *CriuNotify) GetScript() string {
+	if m != nil && m.Script != nil {
+		return *m.Script
+	}
+	return ""
+}
+
+func (m *CriuNotify) GetPid() int32 {
+	if m != nil && m.Pid != nil {
+		return *m.Pid
+	}
+	return 0
+}
+
+type CriuReq struct {
+	Type          *CriuReqType `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"`
+	Opts          *CriuOpts    `protobuf:"bytes,2,opt,name=opts" json:"opts,omitempty"`
+	NotifySuccess *bool        `protobuf:"varint,3,opt,name=notify_success" json:"notify_success,omitempty"`
+	//
+	// When set service won't close the connection but
+	// will wait for more req-s to appear. Works not
+	// for all request types.
+	KeepOpen         *bool  `protobuf:"varint,4,opt,name=keep_open" json:"keep_open,omitempty"`
+	XXX_unrecognized []byte `json:"-"`
+}
+
+func (m *CriuReq) Reset()         { *m = CriuReq{} }
+func (m *CriuReq) String() string { return proto.CompactTextString(m) }
+func (*CriuReq) ProtoMessage()    {}
+
+func (m *CriuReq) GetType() CriuReqType {
+	if m != nil && m.Type != nil {
+		return *m.Type
+	}
+	return 0
+}
+
+func (m *CriuReq) GetOpts() *CriuOpts {
+	if m != nil {
+		return m.Opts
+	}
+	return nil
+}
+
+func (m *CriuReq) GetNotifySuccess() bool {
+	if m != nil && m.NotifySuccess != nil {
+		return *m.NotifySuccess
+	}
+	return false
+}
+
+func (m *CriuReq) GetKeepOpen() bool {
+	if m != nil && m.KeepOpen != nil {
+		return *m.KeepOpen
+	}
+	return false
+}
+
+type CriuResp struct {
+	Type             *CriuReqType        `protobuf:"varint,1,req,name=type,enum=CriuReqType" json:"type,omitempty"`
+	Success          *bool               `protobuf:"varint,2,req,name=success" json:"success,omitempty"`
+	Dump             *CriuDumpResp       `protobuf:"bytes,3,opt,name=dump" json:"dump,omitempty"`
+	Restore          *CriuRestoreResp    `protobuf:"bytes,4,opt,name=restore" json:"restore,omitempty"`
+	Notify           *CriuNotify         `protobuf:"bytes,5,opt,name=notify" json:"notify,omitempty"`
+	Ps               *CriuPageServerInfo `protobuf:"bytes,6,opt,name=ps" json:"ps,omitempty"`
+	CrErrno          *int32              `protobuf:"varint,7,opt,name=cr_errno" json:"cr_errno,omitempty"`
+	XXX_unrecognized []byte              `json:"-"`
+}
+
+func (m *CriuResp) Reset()         { *m = CriuResp{} }
+func (m *CriuResp) String() string { return proto.CompactTextString(m) }
+func (*CriuResp) ProtoMessage()    {}
+
+func (m *CriuResp) GetType() CriuReqType {
+	if m != nil && m.Type != nil {
+		return *m.Type
+	}
+	return 0
+}
+
+func (m *CriuResp) GetSuccess() bool {
+	if m != nil && m.Success != nil {
+		return *m.Success
+	}
+	return false
+}
+
+func (m *CriuResp) GetDump() *CriuDumpResp {
+	if m != nil {
+		return m.Dump
+	}
+	return nil
+}
+
+func (m *CriuResp) GetRestore() *CriuRestoreResp {
+	if m != nil {
+		return m.Restore
+	}
+	return nil
+}
+
+func (m *CriuResp) GetNotify() *CriuNotify {
+	if m != nil {
+		return m.Notify
+	}
+	return nil
+}
+
+func (m *CriuResp) GetPs() *CriuPageServerInfo {
+	if m != nil {
+		return m.Ps
+	}
+	return nil
+}
+
+func (m *CriuResp) GetCrErrno() int32 {
+	if m != nil && m.CrErrno != nil {
+		return *m.CrErrno
+	}
+	return 0
+}
+
+func init() {
+	proto.RegisterEnum("CriuReqType", CriuReqType_name, CriuReqType_value)
+}

+ 127 - 0
vendor/src/github.com/docker/libcontainer/criurpc/criurpc.proto

@@ -0,0 +1,127 @@
+message criu_page_server_info {
+	optional string		address	= 1;
+	optional int32		port	= 2;
+	optional int32		pid	= 3;
+	optional int32		fd	= 4;
+}
+
+message criu_veth_pair {
+	required string		if_in	= 1;
+	required string		if_out	= 2;
+};
+
+message ext_mount_map {
+	required string		key	= 1;
+	required string		val	= 2;
+};
+
+message inherit_fd {
+	required string		key	= 1;
+	required int32		fd	= 2;
+};
+
+message cgroup_root {
+	optional string		ctrl	= 1;
+	required string		path	= 2;
+};
+
+message criu_opts {
+	required int32			images_dir_fd	= 1;
+	optional int32			pid		= 2; /* if not set on dump, will dump requesting process */
+
+	optional bool			leave_running	= 3;
+	optional bool			ext_unix_sk	= 4;
+	optional bool			tcp_established	= 5;
+	optional bool			evasive_devices	= 6;
+	optional bool			shell_job	= 7;
+	optional bool			file_locks	= 8;
+	optional int32			log_level	= 9 [default = 2];
+	optional string			log_file	= 10; /* No subdirs are allowed. Consider using work-dir */
+
+	optional criu_page_server_info	ps		= 11;
+
+	optional bool			notify_scripts	= 12;
+
+	optional string			root		= 13;
+	optional string			parent_img	= 14;
+	optional bool			track_mem	= 15;
+	optional bool			auto_dedup	= 16;
+
+	optional int32			work_dir_fd	= 17;
+	optional bool			link_remap	= 18;
+	repeated criu_veth_pair		veths		= 19;
+
+	optional uint32			cpu_cap		= 20 [default = 0xffffffff];
+	optional bool			force_irmap	= 21;
+	repeated string			exec_cmd	= 22;
+
+	repeated ext_mount_map		ext_mnt		= 23;
+	optional bool			manage_cgroups	= 24;
+	repeated cgroup_root		cg_root		= 25;
+
+	optional bool			rst_sibling	= 26; /* swrk only */
+	repeated inherit_fd		inherit_fd	= 27;
+}
+
+message criu_dump_resp {
+	optional bool restored		= 1;
+}
+
+message criu_restore_resp {
+	required int32 pid		= 1;
+}
+
+message criu_notify {
+	optional string script		= 1;
+	optional int32	pid		= 2;
+}
+
+enum criu_req_type {
+	EMPTY		= 0;
+	DUMP		= 1;
+	RESTORE		= 2;
+	CHECK		= 3;
+	PRE_DUMP	= 4;
+	PAGE_SERVER	= 5;
+
+	NOTIFY		= 6;
+
+	CPUINFO_DUMP	= 7;
+	CPUINFO_CHECK	= 8;
+}
+
+/*
+ * Request -- each type corresponds to must-be-there
+ * request arguments of respective type
+ */
+
+message criu_req {
+	required criu_req_type		type		= 1;
+
+	optional criu_opts		opts		= 2;
+	optional bool			notify_success	= 3;
+
+	/*
+	 * When set service won't close the connection but
+	 * will wait for more req-s to appear. Works not
+	 * for all request types.
+	 */
+	optional bool			keep_open	= 4;
+}
+
+/*
+ * Responce -- it states whether the request was served
+ * and additional request-specific informarion
+ */
+
+message criu_resp {
+	required criu_req_type		type		= 1;
+	required bool			success		= 2;
+
+	optional criu_dump_resp		dump		= 3;
+	optional criu_restore_resp	restore		= 4;
+	optional criu_notify		notify		= 5;
+	optional criu_page_server_info	ps		= 6;
+
+	optional int32			cr_errno	= 7;
+}

+ 0 - 0
vendor/src/github.com/docker/libcontainer/devices/devices.go → vendor/src/github.com/docker/libcontainer/devices/devices_linux.go


+ 16 - 0
vendor/src/github.com/docker/libcontainer/devices/devices_windows.go

@@ -0,0 +1,16 @@
+package devices
+
+import (
+	"github.com/docker/libcontainer/configs"
+)
+
+// TODO Windows. This can be factored out further - Devices are not supported
+// by Windows Containers.
+
+func DeviceFromPath(path, permissions string) (*configs.Device, error) {
+	return nil, nil
+}
+
+func HostDevices() ([]*configs.Device, error) {
+	return nil, nil
+}

+ 2 - 0
vendor/src/github.com/docker/libcontainer/devices/number.go

@@ -1,3 +1,5 @@
+// +build linux
+
 package devices
 
 /*

+ 9 - 33
vendor/src/github.com/docker/libcontainer/factory_linux.go

@@ -106,6 +106,7 @@ func New(root string, options ...func(*LinuxFactory) error) (Factory, error) {
 	l := &LinuxFactory{
 		Root:      root,
 		Validator: validate.New(),
+		CriuPath:  "criu",
 	}
 	InitArgs(os.Args[0], "init")(l)
 	Cgroupfs(l)
@@ -129,6 +130,10 @@ type LinuxFactory struct {
 	// a container.
 	InitArgs []string
 
+	// CriuPath is the path to the criu binary used for checkpoint and restore of
+	// containers.
+	CriuPath string
+
 	// Validator provides validation to container configurations.
 	Validator validate.Validator
 
@@ -161,6 +166,7 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
 		config:        config,
 		initPath:      l.InitPath,
 		initArgs:      l.InitArgs,
+		criuPath:      l.CriuPath,
 		cgroupManager: l.NewCgroupsManager(config.Cgroups, nil),
 	}, nil
 }
@@ -174,9 +180,10 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
 	if err != nil {
 		return nil, err
 	}
-	r := &restoredProcess{
+	r := &nonChildProcess{
 		processPid:       state.InitProcessPid,
 		processStartTime: state.InitProcessStartTime,
+		fds:              state.ExternalDescriptors,
 	}
 	return &linuxContainer{
 		initProcess:   r,
@@ -184,6 +191,7 @@ func (l *LinuxFactory) Load(id string) (Container, error) {
 		config:        &state.Config,
 		initPath:      l.InitPath,
 		initArgs:      l.InitArgs,
+		criuPath:      l.CriuPath,
 		cgroupManager: l.NewCgroupsManager(state.Config.Cgroups, state.CgroupPaths),
 		root:          containerRoot,
 	}, nil
@@ -253,35 +261,3 @@ func (l *LinuxFactory) validateID(id string) error {
 	}
 	return nil
 }
-
-// restoredProcess represents a process where the calling process may or may not be
-// the parent process.  This process is created when a factory loads a container from
-// a persisted state.
-type restoredProcess struct {
-	processPid       int
-	processStartTime string
-}
-
-func (p *restoredProcess) start() error {
-	return newGenericError(fmt.Errorf("restored process cannot be started"), SystemError)
-}
-
-func (p *restoredProcess) pid() int {
-	return p.processPid
-}
-
-func (p *restoredProcess) terminate() error {
-	return newGenericError(fmt.Errorf("restored process cannot be terminated"), SystemError)
-}
-
-func (p *restoredProcess) wait() (*os.ProcessState, error) {
-	return nil, newGenericError(fmt.Errorf("restored process cannot be waited on"), SystemError)
-}
-
-func (p *restoredProcess) startTime() (string, error) {
-	return p.processStartTime, nil
-}
-
-func (p *restoredProcess) signal(s os.Signal) error {
-	return newGenericError(fmt.Errorf("restored process cannot be signaled"), SystemError)
-}

+ 163 - 0
vendor/src/github.com/docker/libcontainer/integration/checkpoint_test.go

@@ -0,0 +1,163 @@
+package integration
+
+import (
+	"bytes"
+	"io/ioutil"
+	"os"
+	"strings"
+	"testing"
+
+	"github.com/docker/libcontainer"
+)
+
+func TestCheckpoint(t *testing.T) {
+	if testing.Short() {
+		return
+	}
+	root, err := newTestRoot()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(root)
+
+	rootfs, err := newRootfs()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer remove(rootfs)
+
+	config := newTemplateConfig(rootfs)
+
+	factory, err := libcontainer.New(root, libcontainer.Cgroupfs)
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	container, err := factory.Create("test", config)
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer container.Destroy()
+
+	stdinR, stdinW, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	var stdout bytes.Buffer
+
+	pconfig := libcontainer.Process{
+		Args:  []string{"cat"},
+		Env:   standardEnvironment,
+		Stdin: stdinR,
+		Stdout: &stdout,
+	}
+
+	err = container.Start(&pconfig)
+	stdinR.Close()
+	defer stdinW.Close()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	pid, err := pconfig.Pid()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	process, err := os.FindProcess(pid)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	imagesDir, err := ioutil.TempDir("", "criu")
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer os.RemoveAll(imagesDir)
+
+	checkpointOpts := &libcontainer.CriuOpts{
+		ImagesDirectory: imagesDir,
+		WorkDirectory: imagesDir,
+	}
+
+	if err := container.Checkpoint(checkpointOpts); err != nil {
+		t.Fatal(err)
+	}
+
+	state, err := container.Status()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if state != libcontainer.Checkpointed {
+		t.Fatal("Unexpected state: ", state)
+	}
+
+	stdinW.Close()
+	_, err = process.Wait()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// reload the container
+	container, err = factory.Load("test")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	restoreStdinR, restoreStdinW, err := os.Pipe()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	restoreProcessConfig := &libcontainer.Process{
+		Stdin:  restoreStdinR,
+		Stdout: &stdout,
+	}
+
+	err = container.Restore(restoreProcessConfig, &libcontainer.CriuOpts{
+		ImagesDirectory: imagesDir,
+	})
+	restoreStdinR.Close()
+	defer restoreStdinW.Close()
+
+	state, err = container.Status()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if state != libcontainer.Running {
+		t.Fatal("Unexpected state: ", state)
+	}
+
+	pid, err = restoreProcessConfig.Pid()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	process, err = os.FindProcess(pid)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	_, err = restoreStdinW.WriteString("Hello!")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	restoreStdinW.Close()
+	s, err := process.Wait()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if !s.Success() {
+		t.Fatal(s.String(), pid)
+	}
+
+	output := string(stdout.Bytes())
+	if !strings.Contains(output, "Hello!") {
+		t.Fatal("Did not restore the pipe correctly:", output)
+	}
+}

+ 5 - 24
vendor/src/github.com/docker/libcontainer/integration/exec_test.go

@@ -182,14 +182,6 @@ func newTestRoot() (string, error) {
 	return dir, nil
 }
 
-func waitProcess(p *libcontainer.Process, t *testing.T) {
-	status, err := p.Wait()
-	ok(t, err)
-	if !status.Success() {
-		t.Fatal(status)
-	}
-}
-
 func TestEnter(t *testing.T) {
 	if testing.Short() {
 		return
@@ -430,22 +422,16 @@ func testFreeze(t *testing.T, systemd bool) {
 	stdinR, stdinW, err := os.Pipe()
 	ok(t, err)
 
-	pconfig := libcontainer.Process{
+	pconfig := &libcontainer.Process{
 		Args:  []string{"cat"},
 		Env:   standardEnvironment,
 		Stdin: stdinR,
 	}
-	err = container.Start(&pconfig)
+	err = container.Start(pconfig)
 	stdinR.Close()
 	defer stdinW.Close()
 	ok(t, err)
 
-	pid, err := pconfig.Pid()
-	ok(t, err)
-
-	process, err := os.FindProcess(pid)
-	ok(t, err)
-
 	err = container.Pause()
 	ok(t, err)
 	state, err := container.Status()
@@ -457,12 +443,7 @@ func testFreeze(t *testing.T, systemd bool) {
 	}
 
 	stdinW.Close()
-	s, err := process.Wait()
-	ok(t, err)
-
-	if !s.Success() {
-		t.Fatal(s.String())
-	}
+	waitProcess(pconfig, t)
 }
 
 func TestCpuShares(t *testing.T) {
@@ -547,7 +528,7 @@ func TestContainerState(t *testing.T) {
 		t.Fatal(err)
 	}
 	stdinR.Close()
-	defer p.Signal(os.Kill)
+	defer stdinW.Close()
 
 	st, err := container.State()
 	if err != nil {
@@ -562,7 +543,7 @@ func TestContainerState(t *testing.T) {
 		t.Fatal("Container using non-host ipc namespace")
 	}
 	stdinW.Close()
-	p.Wait()
+	waitProcess(p, t)
 }
 
 func TestPassExtraFiles(t *testing.T) {

+ 16 - 22
vendor/src/github.com/docker/libcontainer/integration/execin_test.go

@@ -44,14 +44,13 @@ func TestExecIn(t *testing.T) {
 		Stdout: buffers.Stdout,
 		Stderr: buffers.Stderr,
 	}
+
 	err = container.Start(ps)
 	ok(t, err)
-	_, err = ps.Wait()
-	ok(t, err)
+	waitProcess(ps, t)
 	stdinW.Close()
-	if _, err := process.Wait(); err != nil {
-		t.Log(err)
-	}
+	waitProcess(process, t)
+
 	out := buffers.Stdout.String()
 	if !strings.Contains(out, "cat") || !strings.Contains(out, "ps") {
 		t.Fatalf("unexpected running process, output %q", out)
@@ -92,12 +91,11 @@ func TestExecInRlimit(t *testing.T) {
 	}
 	err = container.Start(ps)
 	ok(t, err)
-	_, err = ps.Wait()
-	ok(t, err)
+	waitProcess(ps, t)
+
 	stdinW.Close()
-	if _, err := process.Wait(); err != nil {
-		t.Log(err)
-	}
+	waitProcess(process, t)
+
 	out := buffers.Stdout.String()
 	if limit := strings.TrimSpace(out); limit != "1025" {
 		t.Fatalf("expected rlimit to be 1025, got %s", limit)
@@ -191,12 +189,11 @@ func TestExecInTTY(t *testing.T) {
 		t.Fatal("Waiting for copy timed out")
 	case <-copy:
 	}
-	_, err = ps.Wait()
-	ok(t, err)
+	waitProcess(ps, t)
+
 	stdinW.Close()
-	if _, err := process.Wait(); err != nil {
-		t.Log(err)
-	}
+	waitProcess(process, t)
+
 	out := stdout.String()
 	if !strings.Contains(out, "cat") || !strings.Contains(string(out), "ps") {
 		t.Fatalf("unexpected running process, output %q", out)
@@ -243,14 +240,11 @@ func TestExecInEnvironment(t *testing.T) {
 	}
 	err = container.Start(process2)
 	ok(t, err)
-	if _, err := process2.Wait(); err != nil {
-		out := buffers.Stdout.String()
-		t.Fatal(err, out)
-	}
+	waitProcess(process2, t)
+
 	stdinW.Close()
-	if _, err := process.Wait(); err != nil {
-		t.Log(err)
-	}
+	waitProcess(process, t)
+
 	out := buffers.Stdout.String()
 	// check execin's process environment
 	if !strings.Contains(out, "DEBUG=false") ||

+ 13 - 0
vendor/src/github.com/docker/libcontainer/integration/utils_test.go

@@ -49,6 +49,19 @@ func ok(t testing.TB, err error) {
 	}
 }
 
+func waitProcess(p *libcontainer.Process, t *testing.T) {
+	_, file, line, _ := runtime.Caller(1)
+	status, err := p.Wait()
+
+	if err != nil {
+		t.Fatalf("%s:%d: unexpected error: %s\n\n", filepath.Base(file), line, err.Error())
+	}
+
+	if !status.Success() {
+		t.Fatalf("%s:%d: unexpected status: %s\n\n", filepath.Base(file), line, status.String())
+	}
+}
+
 // newRootfs creates a new tmp directory and copies the busybox root filesystem
 func newRootfs() (string, error) {
 	dir, err := ioutil.TempDir("", "")

+ 19 - 5
vendor/src/github.com/docker/libcontainer/netlink/netlink_linux.go

@@ -9,6 +9,7 @@ import (
 	"os"
 	"sync/atomic"
 	"syscall"
+	"time"
 	"unsafe"
 )
 
@@ -26,6 +27,7 @@ const (
 	SIOC_BRADDBR      = 0x89a0
 	SIOC_BRDELBR      = 0x89a1
 	SIOC_BRADDIF      = 0x89a2
+	SIOC_BRDELIF      = 0x89a3
 )
 
 const (
@@ -54,6 +56,8 @@ type ifreqFlags struct {
 
 var native binary.ByteOrder
 
+var rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
+
 func init() {
 	var x uint32 = 0x01020304
 	if *(*byte)(unsafe.Pointer(&x)) == 0x01 {
@@ -1188,9 +1192,7 @@ func DeleteBridge(name string) error {
 	return nil
 }
 
-// Add a slave to abridge device.  This is more backward-compatible than
-// netlink.NetworkSetMaster and works on RHEL 6.
-func AddToBridge(iface, master *net.Interface) error {
+func ifIoctBridge(iface, master *net.Interface, op uintptr) error {
 	if len(master.Name) >= IFNAMSIZ {
 		return fmt.Errorf("Interface name %s too long", master.Name)
 	}
@@ -1205,17 +1207,29 @@ func AddToBridge(iface, master *net.Interface) error {
 	copy(ifr.IfrnName[:len(ifr.IfrnName)-1], master.Name)
 	ifr.IfruIndex = int32(iface.Index)
 
-	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), SIOC_BRADDIF, uintptr(unsafe.Pointer(&ifr))); err != 0 {
+	if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(s), op, uintptr(unsafe.Pointer(&ifr))); err != 0 {
 		return err
 	}
 
 	return nil
 }
 
+// Add a slave to a bridge device.  This is more backward-compatible than
+// netlink.NetworkSetMaster and works on RHEL 6.
+func AddToBridge(iface, master *net.Interface) error {
+	return ifIoctBridge(iface, master, SIOC_BRADDIF)
+}
+
+// Detach a slave from a bridge device.  This is more backward-compatible than
+// netlink.NetworkSetMaster and works on RHEL 6.
+func DelFromBridge(iface, master *net.Interface) error {
+	return ifIoctBridge(iface, master, SIOC_BRDELIF)
+}
+
 func randMacAddr() string {
 	hw := make(net.HardwareAddr, 6)
 	for i := 0; i < 6; i++ {
-		hw[i] = byte(rand.Intn(255))
+		hw[i] = byte(rnd.Intn(255))
 	}
 	hw[0] &^= 0x1 // clear multicast bit
 	hw[0] |= 0x2  // set local assignment bit (IEEE802)

+ 49 - 14
vendor/src/github.com/docker/libcontainer/network_linux.go

@@ -10,6 +10,7 @@ import (
 	"strconv"
 	"strings"
 
+	"github.com/docker/libcontainer/configs"
 	"github.com/docker/libcontainer/netlink"
 	"github.com/docker/libcontainer/utils"
 )
@@ -24,6 +25,8 @@ var strategies = map[string]networkStrategy{
 type networkStrategy interface {
 	create(*network, int) error
 	initialize(*network) error
+	detach(*configs.Network) error
+	attach(*configs.Network) error
 }
 
 // getStrategy returns the specific network strategy for the
@@ -97,32 +100,39 @@ func (l *loopback) initialize(config *network) error {
 	return netlink.NetworkLinkUp(iface)
 }
 
+func (l *loopback) attach(n *configs.Network) (err error) {
+	return nil
+}
+
+func (l *loopback) detach(n *configs.Network) (err error) {
+	return nil
+}
+
 // veth is a network strategy that uses a bridge and creates
 // a veth pair, one that is attached to the bridge on the host and the other
 // is placed inside the container's namespace
 type veth struct {
 }
 
-func (v *veth) create(n *network, nspid int) (err error) {
-	tmpName, err := v.generateTempPeerName()
+func (v *veth) detach(n *configs.Network) (err error) {
+	bridge, err := net.InterfaceByName(n.Bridge)
 	if err != nil {
 		return err
 	}
-	n.TempVethPeerName = tmpName
-	defer func() {
-		if err != nil {
-			netlink.NetworkLinkDel(n.HostInterfaceName)
-			netlink.NetworkLinkDel(n.TempVethPeerName)
-		}
-	}()
-	if n.Bridge == "" {
-		return fmt.Errorf("bridge is not specified")
-	}
-	bridge, err := net.InterfaceByName(n.Bridge)
+	host, err := net.InterfaceByName(n.HostInterfaceName)
 	if err != nil {
 		return err
 	}
-	if err := netlink.NetworkCreateVethPair(n.HostInterfaceName, n.TempVethPeerName, n.TxQueueLen); err != nil {
+	if err := netlink.DelFromBridge(host, bridge); err != nil {
+		return err
+	}
+	return nil
+}
+
+// attach a container network interface to an external network
+func (v *veth) attach(n *configs.Network) (err error) {
+	bridge, err := net.InterfaceByName(n.Bridge)
+	if err != nil {
 		return err
 	}
 	host, err := net.InterfaceByName(n.HostInterfaceName)
@@ -143,6 +153,31 @@ func (v *veth) create(n *network, nspid int) (err error) {
 	if err := netlink.NetworkLinkUp(host); err != nil {
 		return err
 	}
+
+	return nil
+}
+
+func (v *veth) create(n *network, nspid int) (err error) {
+	tmpName, err := v.generateTempPeerName()
+	if err != nil {
+		return err
+	}
+	n.TempVethPeerName = tmpName
+	defer func() {
+		if err != nil {
+			netlink.NetworkLinkDel(n.HostInterfaceName)
+			netlink.NetworkLinkDel(n.TempVethPeerName)
+		}
+	}()
+	if n.Bridge == "" {
+		return fmt.Errorf("bridge is not specified")
+	}
+	if err := netlink.NetworkCreateVethPair(n.HostInterfaceName, n.TempVethPeerName, n.TxQueueLen); err != nil {
+		return err
+	}
+	if err := v.attach(&n.Network); err != nil {
+		return err
+	}
 	child, err := net.InterfaceByName(n.TempVethPeerName)
 	if err != nil {
 		return err

+ 2 - 0
vendor/src/github.com/docker/libcontainer/nsenter/nsenter_unsupported.go

@@ -1,3 +1,5 @@
 // +build !linux !cgo
 
 package nsenter
+
+import "C"

+ 67 - 0
vendor/src/github.com/docker/libcontainer/nsinit/checkpoint.go

@@ -0,0 +1,67 @@
+package main
+
+import (
+	"fmt"
+	"github.com/codegangsta/cli"
+	"github.com/docker/libcontainer"
+	"strconv"
+	"strings"
+)
+
+var checkpointCommand = cli.Command{
+	Name:  "checkpoint",
+	Usage: "checkpoint a running container",
+	Flags: []cli.Flag{
+		cli.StringFlag{Name: "id", Value: "nsinit", Usage: "specify the ID for a container"},
+		cli.StringFlag{Name: "image-path", Value: "", Usage: "path for saving criu image files"},
+		cli.StringFlag{Name: "work-path", Value: "", Usage: "path for saving work files and logs"},
+		cli.BoolFlag{Name: "leave-running", Usage: "leave the process running after checkpointing"},
+		cli.BoolFlag{Name: "tcp-established", Usage: "allow open tcp connections"},
+		cli.BoolFlag{Name: "ext-unix-sk", Usage: "allow external unix sockets"},
+		cli.BoolFlag{Name: "shell-job", Usage: "allow shell jobs"},
+		cli.StringFlag{Name: "page-server", Value: "", Usage: "ADDRESS:PORT of the page server"},
+	},
+	Action: func(context *cli.Context) {
+		imagePath := context.String("image-path")
+		if imagePath == "" {
+			fatal(fmt.Errorf("The --image-path option isn't specified"))
+		}
+
+		container, err := getContainer(context)
+		if err != nil {
+			fatal(err)
+		}
+
+		// these are the mandatory criu options for a container
+		criuOpts := &libcontainer.CriuOpts{
+			ImagesDirectory:         imagePath,
+			WorkDirectory:           context.String("work-path"),
+			LeaveRunning:            context.Bool("leave-running"),
+			TcpEstablished:          context.Bool("tcp-established"),
+			ExternalUnixConnections: context.Bool("ext-unix-sk"),
+			ShellJob:                context.Bool("shell-job"),
+		}
+
+		// xxx following criu opts are optional
+		// The dump image can be sent to a criu page server
+		if psOpt := context.String("page-server"); psOpt != "" {
+			addressPort := strings.Split(psOpt, ":")
+			if len(addressPort) != 2 {
+				fatal(fmt.Errorf("Use --page-server ADDRESS:PORT to specify page server"))
+			}
+
+			port_int, err := strconv.Atoi(addressPort[1])
+			if err != nil {
+				fatal(fmt.Errorf("Invalid port number"))
+			}
+			criuOpts.PageServer = libcontainer.CriuPageServerInfo{
+				Address: addressPort[0],
+				Port:    int32(port_int),
+			}
+		}
+
+		if err := container.Checkpoint(criuOpts); err != nil {
+			fatal(err)
+		}
+	},
+}

+ 9 - 0
vendor/src/github.com/docker/libcontainer/nsinit/config.go

@@ -44,6 +44,7 @@ var createFlags = []cli.Flag{
 	cli.StringFlag{Name: "veth-gateway", Usage: "veth gateway address"},
 	cli.IntFlag{Name: "veth-mtu", Usage: "veth mtu"},
 	cli.BoolFlag{Name: "cgroup", Usage: "mount the cgroup data for the container"},
+	cli.StringSliceFlag{Name: "sysctl", Value: &cli.StringSlice{}, Usage: "set system properties in the container"},
 }
 
 var configCommand = cli.Command{
@@ -111,6 +112,14 @@ func modify(config *configs.Config, context *cli.Context) {
 			node.Gid = uint32(userns_uid)
 		}
 	}
+	config.SystemProperties = make(map[string]string)
+	for _, sysProp := range context.StringSlice("sysctl") {
+		parts := strings.SplitN(sysProp, "=", 2)
+		if len(parts) != 2 {
+			logrus.Fatalf("invalid system property %s", sysProp)
+		}
+		config.SystemProperties[parts[0]] = parts[1]
+	}
 	for _, rawBind := range context.StringSlice("bind") {
 		mount := &configs.Mount{
 			Device: "bind",

+ 8 - 1
vendor/src/github.com/docker/libcontainer/nsinit/exec.go

@@ -93,10 +93,17 @@ func execAction(context *cli.Context) {
 		}
 	}
 	if created {
-		if err := container.Destroy(); err != nil {
+		status, err := container.Status()
+		if err != nil {
 			tty.Close()
 			fatal(err)
 		}
+		if status != libcontainer.Checkpointed {
+			if err := container.Destroy(); err != nil {
+				tty.Close()
+				fatal(err)
+			}
+		}
 	}
 	tty.Close()
 	os.Exit(utils.ExitStatus(status.Sys().(syscall.WaitStatus)))

+ 6 - 3
vendor/src/github.com/docker/libcontainer/nsinit/main.go

@@ -13,19 +13,22 @@ func main() {
 	app.Version = "2"
 	app.Author = "libcontainer maintainers"
 	app.Flags = []cli.Flag{
-		cli.StringFlag{Name: "root", Value: "/var/run/nsinit", Usage: "root directory for containers"},
-		cli.StringFlag{Name: "log-file", Value: "", Usage: "set the log file to output logs to"},
 		cli.BoolFlag{Name: "debug", Usage: "enable debug output in the logs"},
+		cli.StringFlag{Name: "root", Value: "/var/run/nsinit", Usage: "root directory for containers"},
+		cli.StringFlag{Name: "log-file", Usage: "set the log file to output logs to"},
+		cli.StringFlag{Name: "criu", Value: "criu", Usage: "path to the criu binary for checkpoint and restore"},
 	}
 	app.Commands = []cli.Command{
+		checkpointCommand,
 		configCommand,
 		execCommand,
 		initCommand,
 		oomCommand,
 		pauseCommand,
+		stateCommand,
 		statsCommand,
 		unpauseCommand,
-		stateCommand,
+		restoreCommand,
 	}
 	app.Before = func(context *cli.Context) error {
 		if context.GlobalBool("debug") {

+ 120 - 0
vendor/src/github.com/docker/libcontainer/nsinit/restore.go

@@ -0,0 +1,120 @@
+package main
+
+import (
+	"fmt"
+	"os"
+	"os/exec"
+	"syscall"
+
+	"github.com/codegangsta/cli"
+	"github.com/docker/libcontainer"
+	"github.com/docker/libcontainer/utils"
+)
+
+var restoreCommand = cli.Command{
+	Name:  "restore",
+	Usage: "restore a container from a previous checkpoint",
+	Flags: []cli.Flag{
+		cli.StringFlag{Name: "id", Value: "nsinit", Usage: "specify the ID for a container"},
+		cli.StringFlag{Name: "image-path", Value: "", Usage: "path to criu image files for restoring"},
+		cli.StringFlag{Name: "work-path", Value: "", Usage: "path for saving work files and logs"},
+		cli.BoolFlag{Name: "tcp-established", Usage: "allow open tcp connections"},
+		cli.BoolFlag{Name: "ext-unix-sk", Usage: "allow external unix sockets"},
+		cli.BoolFlag{Name: "shell-job", Usage: "allow shell jobs"},
+	},
+	Action: func(context *cli.Context) {
+		imagePath := context.String("image-path")
+		if imagePath == "" {
+			fatal(fmt.Errorf("The --image-path option isn't specified"))
+		}
+
+		var (
+			container libcontainer.Container
+			err       error
+		)
+
+		factory, err := loadFactory(context)
+		if err != nil {
+			fatal(err)
+		}
+
+		config, err := loadConfig(context)
+		if err != nil {
+			fatal(err)
+		}
+
+		created := false
+		container, err = factory.Load(context.String("id"))
+		if err != nil {
+			created = true
+			if container, err = factory.Create(context.String("id"), config); err != nil {
+				fatal(err)
+			}
+		}
+
+		process := &libcontainer.Process{
+			Stdin:  os.Stdin,
+			Stdout: os.Stdout,
+			Stderr: os.Stderr,
+		}
+		//rootuid, err := config.HostUID()
+		//if err != nil {
+		//fatal(err)
+		//}
+		rootuid := 0 // XXX
+		tty, err := newTty(context, process, rootuid)
+		if err != nil {
+			fatal(err)
+		}
+		if err := tty.attach(process); err != nil {
+			fatal(err)
+		}
+		go handleSignals(process, tty)
+
+		err = container.Restore(process, &libcontainer.CriuOpts{
+			ImagesDirectory:         imagePath,
+			WorkDirectory:           context.String("work-path"),
+			TcpEstablished:          context.Bool("tcp-established"),
+			ExternalUnixConnections: context.Bool("ext-unix-sk"),
+			ShellJob:                context.Bool("shell-job"),
+		})
+		if err != nil {
+			tty.Close()
+			if created {
+				container.Destroy()
+			}
+			fatal(err)
+		}
+
+		status, err := process.Wait()
+		if err != nil {
+			exitError, ok := err.(*exec.ExitError)
+			if ok {
+				status = exitError.ProcessState
+			} else {
+				tty.Close()
+				if created {
+					container.Destroy()
+				}
+				fatal(err)
+			}
+		}
+
+		if created {
+			status, err := container.Status()
+			if err != nil {
+				tty.Close()
+				fatal(err)
+			}
+			if status != libcontainer.Checkpointed {
+				if err := container.Destroy(); err != nil {
+					tty.Close()
+					fatal(err)
+				}
+			}
+		}
+
+		tty.Close()
+		os.Exit(utils.ExitStatus(status.Sys().(syscall.WaitStatus)))
+	},
+}

+ 31 - 2
vendor/src/github.com/docker/libcontainer/nsinit/tty.go

@@ -17,6 +17,9 @@ func newTty(context *cli.Context, p *libcontainer.Process, rootuid int) (*tty, e
 		}
 		return &tty{
 			console: console,
+			closers: []io.Closer{
+				console,
+			},
 		}, nil
 	}
 	return &tty{}, nil
@@ -25,11 +28,12 @@ func newTty(context *cli.Context, p *libcontainer.Process, rootuid int) (*tty, e
 type tty struct {
 	console libcontainer.Console
 	state   *term.State
+	closers []io.Closer
 }
 
 func (t *tty) Close() error {
-	if t.console != nil {
-		t.console.Close()
+	for _, c := range t.closers {
+		c.Close()
 	}
 	if t.state != nil {
 		term.RestoreTerminal(os.Stdin.Fd(), t.state)
@@ -49,10 +53,35 @@ func (t *tty) attach(process *libcontainer.Process) error {
 		process.Stderr = nil
 		process.Stdout = nil
 		process.Stdin = nil
+	} else {
+		// setup standard pipes so that the TTY of the calling nsinit process
+		// is not inherited by the container.
+		r, w, err := os.Pipe()
+		if err != nil {
+			return err
+		}
+		go io.Copy(w, os.Stdin)
+		t.closers = append(t.closers, w)
+		process.Stdin = r
+		if r, w, err = os.Pipe(); err != nil {
+			return err
+		}
+		go io.Copy(os.Stdout, r)
+		process.Stdout = w
+		t.closers = append(t.closers, r)
+		if r, w, err = os.Pipe(); err != nil {
+			return err
+		}
+		go io.Copy(os.Stderr, r)
+		process.Stderr = w
+		t.closers = append(t.closers, r)
 	}
 	return nil
 }
 
+func (t *tty) setupPipe() {
+}
+
 func (t *tty) resize() error {
 	if t.console == nil {
 		return nil

+ 12 - 2
vendor/src/github.com/docker/libcontainer/nsinit/utils.go

@@ -3,8 +3,10 @@ package main
 import (
 	"encoding/json"
 	"fmt"
-	"github.com/Sirupsen/logrus"
 	"os"
+	"path/filepath"
+
+	"github.com/Sirupsen/logrus"
 
 	"github.com/codegangsta/cli"
 	"github.com/docker/libcontainer"
@@ -39,7 +41,15 @@ func loadFactory(context *cli.Context) (libcontainer.Factory, error) {
 			logrus.Warn("systemd cgroup flag passed, but systemd support for managing cgroups is not available.")
 		}
 	}
-	return libcontainer.New(context.GlobalString("root"), cgm)
+	root := context.GlobalString("root")
+	abs, err := filepath.Abs(root)
+	if err != nil {
+		return nil, err
+	}
+	return libcontainer.New(abs, cgm, func(l *libcontainer.LinuxFactory) error {
+		l.CriuPath = context.GlobalString("criu")
+		return nil
+	})
 }
 
 func getContainer(context *cli.Context) (libcontainer.Container, error) {

+ 51 - 0
vendor/src/github.com/docker/libcontainer/process_linux.go

@@ -8,6 +8,8 @@ import (
 	"io"
 	"os"
 	"os/exec"
+	"path/filepath"
+	"strconv"
 	"syscall"
 
 	"github.com/docker/libcontainer/cgroups"
@@ -31,6 +33,10 @@ type parentProcess interface {
 	startTime() (string, error)
 
 	signal(os.Signal) error
+
+	externalDescriptors() []string
+
+	setExternalDescriptors(fds []string)
 }
 
 type setnsProcess struct {
@@ -39,6 +45,7 @@ type setnsProcess struct {
 	childPipe   *os.File
 	cgroupPaths map[string]string
 	config      *initConfig
+	fds         []string
 }
 
 func (p *setnsProcess) startTime() (string, error) {
@@ -142,18 +149,32 @@ func (p *setnsProcess) pid() int {
 	return p.cmd.Process.Pid
 }
 
+func (p *setnsProcess) externalDescriptors() []string {
+	return p.fds
+}
+
+func (p *setnsProcess) setExternalDescriptors(newFds []string) {
+	p.fds = newFds
+}
+
 type initProcess struct {
 	cmd        *exec.Cmd
 	parentPipe *os.File
 	childPipe  *os.File
 	config     *initConfig
 	manager    cgroups.Manager
+	container  *linuxContainer
+	fds        []string
 }
 
 func (p *initProcess) pid() int {
 	return p.cmd.Process.Pid
 }
 
+func (p *initProcess) externalDescriptors() []string {
+	return p.fds
+}
+
 func (p *initProcess) start() error {
 	defer p.parentPipe.Close()
 	err := p.cmd.Start()
@@ -161,6 +182,15 @@ func (p *initProcess) start() error {
 	if err != nil {
 		return newSystemError(err)
 	}
+	// Save the standard descriptor names before the container process
+	// can potentially move them (e.g., via dup2()).  If we don't do this now,
+	// we won't know at checkpoint time which file descriptor to look up.
+	fds, err := getPipeFds(p.pid())
+	if err != nil {
+		return newSystemError(err)
+	}
+	p.setExternalDescriptors(fds)
+
 	// Do this before syncing with child so that no children
 	// can escape the cgroup
 	if err := p.manager.Apply(p.pid()); err != nil {
@@ -250,3 +280,24 @@ func (p *initProcess) signal(sig os.Signal) error {
 	}
 	return syscall.Kill(p.cmd.Process.Pid, s)
 }
+
+func (p *initProcess) setExternalDescriptors(newFds []string) {
+	p.fds = newFds
+}
+
+func getPipeFds(pid int) ([]string, error) {
+	var fds []string
+
+	fds = make([]string, 3)
+
+	dirPath := filepath.Join("/proc", strconv.Itoa(pid), "/fd")
+	for i := 0; i < 3; i++ {
+		f := filepath.Join(dirPath, strconv.Itoa(i))
+		target, err := os.Readlink(f)
+		if err != nil {
+			return fds, err
+		}
+		fds[i] = target
+	}
+	return fds, nil
+}

+ 118 - 0
vendor/src/github.com/docker/libcontainer/restored_process.go

@@ -0,0 +1,118 @@
+// +build linux
+
+package libcontainer
+
+import (
+	"fmt"
+	"os"
+
+	"github.com/docker/libcontainer/system"
+)
+
+func newRestoredProcess(pid int, fds []string) (*restoredProcess, error) {
+	var (
+		err error
+	)
+	proc, err := os.FindProcess(pid)
+	if err != nil {
+		return nil, err
+	}
+	started, err := system.GetProcessStartTime(pid)
+	if err != nil {
+		return nil, err
+	}
+	return &restoredProcess{
+		proc:             proc,
+		processStartTime: started,
+		fds:              fds,
+	}, nil
+}
+
+type restoredProcess struct {
+	proc             *os.Process
+	processStartTime string
+	fds              []string
+}
+
+func (p *restoredProcess) start() error {
+	return newGenericError(fmt.Errorf("restored process cannot be started"), SystemError)
+}
+
+func (p *restoredProcess) pid() int {
+	return p.proc.Pid
+}
+
+func (p *restoredProcess) terminate() error {
+	err := p.proc.Kill()
+	if _, werr := p.wait(); err == nil {
+		err = werr
+	}
+	return err
+}
+
+func (p *restoredProcess) wait() (*os.ProcessState, error) {
+	// TODO: how do we wait on the actual process?
+	// maybe use --exec-cmd in criu
+	st, err := p.proc.Wait()
+	if err != nil {
+		return nil, err
+	}
+	return st, nil
+}
+
+func (p *restoredProcess) startTime() (string, error) {
+	return p.processStartTime, nil
+}
+
+func (p *restoredProcess) signal(s os.Signal) error {
+	return p.proc.Signal(s)
+}
+
+func (p *restoredProcess) externalDescriptors() []string {
+	return p.fds
+}
+
+func (p *restoredProcess) setExternalDescriptors(newFds []string) {
+	p.fds = newFds
+}
+
+// nonChildProcess represents a process where the calling process is not
+// the parent process.  This process is created when a factory loads a container from
+// a persisted state.
+type nonChildProcess struct {
+	processPid       int
+	processStartTime string
+	fds              []string
+}
+
+func (p *nonChildProcess) start() error {
+	return newGenericError(fmt.Errorf("restored process cannot be started"), SystemError)
+}
+
+func (p *nonChildProcess) pid() int {
+	return p.processPid
+}
+
+func (p *nonChildProcess) terminate() error {
+	return newGenericError(fmt.Errorf("restored process cannot be terminated"), SystemError)
+}
+
+func (p *nonChildProcess) wait() (*os.ProcessState, error) {
+	return nil, newGenericError(fmt.Errorf("restored process cannot be waited on"), SystemError)
+}
+
+func (p *nonChildProcess) startTime() (string, error) {
+	return p.processStartTime, nil
+}
+
+func (p *nonChildProcess) signal(s os.Signal) error {
+	return newGenericError(fmt.Errorf("restored process cannot be signaled"), SystemError)
+}
+
+func (p *nonChildProcess) externalDescriptors() []string {
+	return p.fds
+}
+
+func (p *nonChildProcess) setExternalDescriptors(newFds []string) {
+	p.fds = newFds
+}

+ 3 - 0
vendor/src/github.com/docker/libcontainer/stacktrace/frame.go

@@ -9,6 +9,9 @@ import (
 // NewFrame returns a new stack frame for the provided information
 func NewFrame(pc uintptr, file string, line int) Frame {
 	fn := runtime.FuncForPC(pc)
+	if fn == nil {
+		return Frame{}
+	}
 	pack, name := parseFunctionName(fn.Name())
 	return Frame{
 		Line:     line,

+ 0 - 7
vendor/src/github.com/docker/libcontainer/stats.go

@@ -1,12 +1,5 @@
 package libcontainer
 
-import "github.com/docker/libcontainer/cgroups"
-
-type Stats struct {
-	Interfaces  []*NetworkInterface
-	CgroupStats *cgroups.Stats
-}
-
 type NetworkInterface struct {
 	// Name is the name of the network interface.
 	Name string

+ 8 - 0
vendor/src/github.com/docker/libcontainer/stats_linux.go

@@ -0,0 +1,8 @@
+package libcontainer
+
+import "github.com/docker/libcontainer/cgroups"
+
+type Stats struct {
+	Interfaces  []*NetworkInterface
+	CgroupStats *cgroups.Stats
+}

+ 5 - 0
vendor/src/github.com/docker/libcontainer/stats_windows.go

@@ -0,0 +1,5 @@
+package libcontainer
+
+type Stats struct {
+	Interfaces []*NetworkInterface
+}

+ 1 - 1
vendor/src/github.com/docker/libcontainer/system/sysconfig.go

@@ -1,4 +1,4 @@
-// +build cgo
+// +build cgo,linux
 
 package system
 

+ 8 - 1
vendor/src/github.com/docker/libcontainer/system/sysconfig_notcgo.go

@@ -1,8 +1,15 @@
-// +build !cgo
+// +build !cgo windows
 
 package system
 
 func GetClockTicks() int {
 	// TODO figure out a better alternative for platforms where we're missing cgo
+	//
+	// TODO Windows. This could be implemented using Win32 QueryPerformanceFrequency().
+	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644905(v=vs.85).aspx
+	//
+	// An example of its usage can be found here.
+	// https://msdn.microsoft.com/en-us/library/windows/desktop/dn553408(v=vs.85).aspx
+
 	return 100
 }

+ 2 - 1
vendor/src/github.com/docker/libcontainer/update-vendor.sh

@@ -44,6 +44,7 @@ clone git github.com/codegangsta/cli 1.1.0
 clone git github.com/coreos/go-systemd v2
 clone git github.com/godbus/dbus v2
 clone git github.com/Sirupsen/logrus v0.7.3
-clone git github.com/syndtr/gocapability 66ef2aa
+clone git github.com/syndtr/gocapability 8e4cdcb
+clone git github.com/golang/protobuf 655cdfa588ea
 
 # intentionally not vendoring Docker itself...  that'd be a circle :)

+ 17 - 0
vendor/src/github.com/golang/protobuf/.gitignore

@@ -0,0 +1,17 @@
+.DS_Store
+*.[568ao]
+*.pb.go
+*.ao
+*.so
+*.pyc
+._*
+.nfs.*
+[568a].out
+*~
+*.orig
+core
+_obj
+_test
+_testmain.go
+compiler/protoc-gen-go
+compiler/testdata/extension_test

+ 3 - 0
vendor/src/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/src/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.

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

@@ -0,0 +1,31 @@
+Go support for Protocol Buffers - Google's data interchange format
+
+Copyright 2010 The Go Authors.  All rights reserved.
+https://github.com/golang/protobuf
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+

+ 40 - 0
vendor/src/github.com/golang/protobuf/Make.protobuf

@@ -0,0 +1,40 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  All rights reserved.
+# https://github.com/golang/protobuf
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# Includable Makefile to add a rule for generating .pb.go files from .proto files
+# (Google protocol buffer descriptions).
+# Typical use if myproto.proto is a file in package mypackage in this directory:
+#
+#	include $(GOROOT)/src/pkg/github.com/golang/protobuf/Make.protobuf
+
+%.pb.go:	%.proto
+	protoc --go_out=. $<
+

+ 52 - 0
vendor/src/github.com/golang/protobuf/Makefile

@@ -0,0 +1,52 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  All rights reserved.
+# https://github.com/golang/protobuf
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+
+all:	install
+
+install:
+	go install ./proto
+	go install ./protoc-gen-go
+
+test:
+	go test ./proto
+	make -C protoc-gen-go/testdata test
+
+clean:
+	go clean ./...
+
+nuke:
+	go clean -i ./...
+
+regenerate:
+	make -C protoc-gen-go/descriptor regenerate
+	make -C protoc-gen-go/plugin regenerate
+	make -C proto/testdata regenerate

+ 148 - 0
vendor/src/github.com/golang/protobuf/README

@@ -0,0 +1,148 @@
+Go support for Protocol Buffers - Google's data interchange format
+Copyright 2010 The Go Authors.
+https://github.com/golang/protobuf
+
+This package and the code it generates requires at least Go 1.2.
+
+This software implements Go bindings for protocol buffers.  For
+information about protocol buffers themselves, see
+	https://developers.google.com/protocol-buffers/
+To use this software, you must first install the standard C++
+implementation of protocol buffers from
+	https://developers.google.com/protocol-buffers/
+And of course you must also install the Go compiler and tools from
+	https://golang.org/
+See
+	https://golang.org/doc/install
+for details or, if you are using gccgo, follow the instructions at
+	https://golang.org/doc/install/gccgo
+
+This software has two parts: a 'protocol compiler plugin' that
+generates Go source files that, once compiled, can access and manage
+protocol buffers; and a library that implements run-time support for
+encoding (marshaling), decoding (unmarshaling), and accessing protocol
+buffers.
+
+There is no support for RPC in Go using protocol buffers.  It may come
+once a standard RPC protocol develops for protobufs.
+
+There are no insertion points in the plugin.
+
+To install this code:
+
+The simplest way is to run go get.
+
+	# Grab the code from the repository and install the proto package.
+	go get -u github.com/golang/protobuf/{proto,protoc-gen-go}
+
+The compiler plugin, protoc-gen-go, will be installed in $GOBIN,
+defaulting to $GOPATH/bin.  It must be in your $PATH for the protocol
+compiler, protoc, to find it.
+
+Once the software is installed, there are two steps to using it.
+First you must compile the protocol buffer definitions and then import
+them, with the support library, into your program.
+
+To compile the protocol buffer definition, run protoc with the --go_out
+parameter set to the directory you want to output the Go code to.
+
+	protoc --go_out=. *.proto
+
+The generated files will be suffixed .pb.go.  See the Test code below
+for an example using such a file.
+
+
+The package comment for the proto library contains text describing
+the interface provided in Go for protocol buffers. Here is an edited
+version.
+
+==========
+
+The proto package converts data structures to and from the
+wire format of protocol buffers.  It works in concert with the
+Go source code generated for .proto files by the protocol compiler.
+
+A summary of the properties of the protocol buffer interface
+for a protocol buffer variable v:
+
+  - Names are turned from camel_case to CamelCase for export.
+  - There are no methods on v to set fields; just treat
+  	them as structure fields.
+  - There are getters that return a field's value if set,
+	and return the field's default value if unset.
+	The getters work even if the receiver is a nil message.
+  - The zero value for a struct is its correct initialization state.
+	All desired fields must be set before marshaling.
+  - A Reset() method will restore a protobuf struct to its zero state.
+  - Non-repeated fields are pointers to the values; nil means unset.
+	That is, optional or required field int32 f becomes F *int32.
+  - Repeated fields are slices.
+  - Helper functions are available to aid the setting of fields.
+	Helpers for getting values are superseded by the
+	GetFoo methods and their use is deprecated.
+		msg.Foo = proto.String("hello") // set field
+  - Constants are defined to hold the default values of all fields that
+	have them.  They have the form Default_StructName_FieldName.
+	Because the getter methods handle defaulted values,
+	direct use of these constants should be rare.
+  - Enums are given type names and maps from names to values.
+	Enum values are prefixed with the enum's type name. Enum types have
+	a String method, and a Enum method to assist in message construction.
+  - Nested groups and enums have type names prefixed with the name of
+  	the surrounding message type.
+  - Extensions are given descriptor names that start with E_,
+	followed by an underscore-delimited list of the nested messages
+	that contain it (if any) followed by the CamelCased name of the
+	extension field itself.  HasExtension, ClearExtension, GetExtension
+	and SetExtension are functions for manipulating extensions.
+  - Marshal and Unmarshal are functions to encode and decode the wire format.
+
+Consider file test.proto, containing
+
+	package example;
+	
+	enum FOO { X = 17; };
+	
+	message Test {
+	  required string label = 1;
+	  optional int32 type = 2 [default=77];
+	  repeated int64 reps = 3;
+	  optional group OptionalGroup = 4 {
+	    required string RequiredField = 5;
+	  }
+	}
+
+To create and play with a Test object from the example package,
+
+	package main
+
+	import (
+		"log"
+
+		"github.com/golang/protobuf/proto"
+		"path/to/example"
+	)
+
+	func main() {
+		test := &example.Test {
+			Label: proto.String("hello"),
+			Type:  proto.Int32(17),
+			Optionalgroup: &example.Test_OptionalGroup {
+				RequiredField: proto.String("good bye"),
+			},
+		}
+		data, err := proto.Marshal(test)
+		if err != nil {
+			log.Fatal("marshaling error: ", err)
+		}
+		newTest := &example.Test{}
+		err = proto.Unmarshal(data, newTest)
+		if err != nil {
+			log.Fatal("unmarshaling error: ", err)
+		}
+		// Now test and newTest contain the same data.
+		if test.GetLabel() != newTest.GetLabel() {
+			log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
+		}
+		// etc.
+	}

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

@@ -0,0 +1,43 @@
+# Go support for Protocol Buffers - Google's data interchange format
+#
+# Copyright 2010 The Go Authors.  All rights reserved.
+# https://github.com/golang/protobuf
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+#     * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#     * Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following disclaimer
+# in the documentation and/or other materials provided with the
+# distribution.
+#     * Neither the name of Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+install:
+	go install
+
+test: install generate-test-pbs
+	go test
+
+
+generate-test-pbs:
+	make install
+	make -C testdata
+	protoc --go_out=Mtestdata/test.proto=github.com/golang/protobuf/proto/testdata:. proto3_proto/proto3.proto
+	make

+ 2071 - 0
vendor/src/github.com/golang/protobuf/proto/all_test.go

@@ -0,0 +1,2071 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto_test
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"math"
+	"math/rand"
+	"reflect"
+	"runtime/debug"
+	"strings"
+	"testing"
+	"time"
+
+	. "github.com/golang/protobuf/proto"
+	. "github.com/golang/protobuf/proto/testdata"
+)
+
+var globalO *Buffer
+
+func old() *Buffer {
+	if globalO == nil {
+		globalO = NewBuffer(nil)
+	}
+	globalO.Reset()
+	return globalO
+}
+
+func equalbytes(b1, b2 []byte, t *testing.T) {
+	if len(b1) != len(b2) {
+		t.Errorf("wrong lengths: 2*%d != %d", len(b1), len(b2))
+		return
+	}
+	for i := 0; i < len(b1); i++ {
+		if b1[i] != b2[i] {
+			t.Errorf("bad byte[%d]:%x %x: %s %s", i, b1[i], b2[i], b1, b2)
+		}
+	}
+}
+
+func initGoTestField() *GoTestField {
+	f := new(GoTestField)
+	f.Label = String("label")
+	f.Type = String("type")
+	return f
+}
+
+// These are all structurally equivalent but the tag numbers differ.
+// (It's remarkable that required, optional, and repeated all have
+// 8 letters.)
+func initGoTest_RequiredGroup() *GoTest_RequiredGroup {
+	return &GoTest_RequiredGroup{
+		RequiredField: String("required"),
+	}
+}
+
+func initGoTest_OptionalGroup() *GoTest_OptionalGroup {
+	return &GoTest_OptionalGroup{
+		RequiredField: String("optional"),
+	}
+}
+
+func initGoTest_RepeatedGroup() *GoTest_RepeatedGroup {
+	return &GoTest_RepeatedGroup{
+		RequiredField: String("repeated"),
+	}
+}
+
+func initGoTest(setdefaults bool) *GoTest {
+	pb := new(GoTest)
+	if setdefaults {
+		pb.F_BoolDefaulted = Bool(Default_GoTest_F_BoolDefaulted)
+		pb.F_Int32Defaulted = Int32(Default_GoTest_F_Int32Defaulted)
+		pb.F_Int64Defaulted = Int64(Default_GoTest_F_Int64Defaulted)
+		pb.F_Fixed32Defaulted = Uint32(Default_GoTest_F_Fixed32Defaulted)
+		pb.F_Fixed64Defaulted = Uint64(Default_GoTest_F_Fixed64Defaulted)
+		pb.F_Uint32Defaulted = Uint32(Default_GoTest_F_Uint32Defaulted)
+		pb.F_Uint64Defaulted = Uint64(Default_GoTest_F_Uint64Defaulted)
+		pb.F_FloatDefaulted = Float32(Default_GoTest_F_FloatDefaulted)
+		pb.F_DoubleDefaulted = Float64(Default_GoTest_F_DoubleDefaulted)
+		pb.F_StringDefaulted = String(Default_GoTest_F_StringDefaulted)
+		pb.F_BytesDefaulted = Default_GoTest_F_BytesDefaulted
+		pb.F_Sint32Defaulted = Int32(Default_GoTest_F_Sint32Defaulted)
+		pb.F_Sint64Defaulted = Int64(Default_GoTest_F_Sint64Defaulted)
+	}
+
+	pb.Kind = GoTest_TIME.Enum()
+	pb.RequiredField = initGoTestField()
+	pb.F_BoolRequired = Bool(true)
+	pb.F_Int32Required = Int32(3)
+	pb.F_Int64Required = Int64(6)
+	pb.F_Fixed32Required = Uint32(32)
+	pb.F_Fixed64Required = Uint64(64)
+	pb.F_Uint32Required = Uint32(3232)
+	pb.F_Uint64Required = Uint64(6464)
+	pb.F_FloatRequired = Float32(3232)
+	pb.F_DoubleRequired = Float64(6464)
+	pb.F_StringRequired = String("string")
+	pb.F_BytesRequired = []byte("bytes")
+	pb.F_Sint32Required = Int32(-32)
+	pb.F_Sint64Required = Int64(-64)
+	pb.Requiredgroup = initGoTest_RequiredGroup()
+
+	return pb
+}
+
+func fail(msg string, b *bytes.Buffer, s string, t *testing.T) {
+	data := b.Bytes()
+	ld := len(data)
+	ls := len(s) / 2
+
+	fmt.Printf("fail %s ld=%d ls=%d\n", msg, ld, ls)
+
+	// find the interesting spot - n
+	n := ls
+	if ld < ls {
+		n = ld
+	}
+	j := 0
+	for i := 0; i < n; i++ {
+		bs := hex(s[j])*16 + hex(s[j+1])
+		j += 2
+		if data[i] == bs {
+			continue
+		}
+		n = i
+		break
+	}
+	l := n - 10
+	if l < 0 {
+		l = 0
+	}
+	h := n + 10
+
+	// find the interesting spot - n
+	fmt.Printf("is[%d]:", l)
+	for i := l; i < h; i++ {
+		if i >= ld {
+			fmt.Printf(" --")
+			continue
+		}
+		fmt.Printf(" %.2x", data[i])
+	}
+	fmt.Printf("\n")
+
+	fmt.Printf("sb[%d]:", l)
+	for i := l; i < h; i++ {
+		if i >= ls {
+			fmt.Printf(" --")
+			continue
+		}
+		bs := hex(s[j])*16 + hex(s[j+1])
+		j += 2
+		fmt.Printf(" %.2x", bs)
+	}
+	fmt.Printf("\n")
+
+	t.Fail()
+
+	//	t.Errorf("%s: \ngood: %s\nbad: %x", msg, s, b.Bytes())
+	// Print the output in a partially-decoded format; can
+	// be helpful when updating the test.  It produces the output
+	// that is pasted, with minor edits, into the argument to verify().
+	//	data := b.Bytes()
+	//	nesting := 0
+	//	for b.Len() > 0 {
+	//		start := len(data) - b.Len()
+	//		var u uint64
+	//		u, err := DecodeVarint(b)
+	//		if err != nil {
+	//			fmt.Printf("decode error on varint:", err)
+	//			return
+	//		}
+	//		wire := u & 0x7
+	//		tag := u >> 3
+	//		switch wire {
+	//		case WireVarint:
+	//			v, err := DecodeVarint(b)
+	//			if err != nil {
+	//				fmt.Printf("decode error on varint:", err)
+	//				return
+	//			}
+	//			fmt.Printf("\t\t\"%x\"  // field %d, encoding %d, value %d\n",
+	//				data[start:len(data)-b.Len()], tag, wire, v)
+	//		case WireFixed32:
+	//			v, err := DecodeFixed32(b)
+	//			if err != nil {
+	//				fmt.Printf("decode error on fixed32:", err)
+	//				return
+	//			}
+	//			fmt.Printf("\t\t\"%x\"  // field %d, encoding %d, value %d\n",
+	//				data[start:len(data)-b.Len()], tag, wire, v)
+	//		case WireFixed64:
+	//			v, err := DecodeFixed64(b)
+	//			if err != nil {
+	//				fmt.Printf("decode error on fixed64:", err)
+	//				return
+	//			}
+	//			fmt.Printf("\t\t\"%x\"  // field %d, encoding %d, value %d\n",
+	//				data[start:len(data)-b.Len()], tag, wire, v)
+	//		case WireBytes:
+	//			nb, err := DecodeVarint(b)
+	//			if err != nil {
+	//				fmt.Printf("decode error on bytes:", err)
+	//				return
+	//			}
+	//			after_tag := len(data) - b.Len()
+	//			str := make([]byte, nb)
+	//			_, err = b.Read(str)
+	//			if err != nil {
+	//				fmt.Printf("decode error on bytes:", err)
+	//				return
+	//			}
+	//			fmt.Printf("\t\t\"%x\" \"%x\"  // field %d, encoding %d (FIELD)\n",
+	//				data[start:after_tag], str, tag, wire)
+	//		case WireStartGroup:
+	//			nesting++
+	//			fmt.Printf("\t\t\"%x\"\t\t// start group field %d level %d\n",
+	//				data[start:len(data)-b.Len()], tag, nesting)
+	//		case WireEndGroup:
+	//			fmt.Printf("\t\t\"%x\"\t\t// end group field %d level %d\n",
+	//				data[start:len(data)-b.Len()], tag, nesting)
+	//			nesting--
+	//		default:
+	//			fmt.Printf("unrecognized wire type %d\n", wire)
+	//			return
+	//		}
+	//	}
+}
+
+func hex(c uint8) uint8 {
+	if '0' <= c && c <= '9' {
+		return c - '0'
+	}
+	if 'a' <= c && c <= 'f' {
+		return 10 + c - 'a'
+	}
+	if 'A' <= c && c <= 'F' {
+		return 10 + c - 'A'
+	}
+	return 0
+}
+
+func equal(b []byte, s string, t *testing.T) bool {
+	if 2*len(b) != len(s) {
+		//		fail(fmt.Sprintf("wrong lengths: 2*%d != %d", len(b), len(s)), b, s, t)
+		fmt.Printf("wrong lengths: 2*%d != %d\n", len(b), len(s))
+		return false
+	}
+	for i, j := 0, 0; i < len(b); i, j = i+1, j+2 {
+		x := hex(s[j])*16 + hex(s[j+1])
+		if b[i] != x {
+			//			fail(fmt.Sprintf("bad byte[%d]:%x %x", i, b[i], x), b, s, t)
+			fmt.Printf("bad byte[%d]:%x %x", i, b[i], x)
+			return false
+		}
+	}
+	return true
+}
+
+func overify(t *testing.T, pb *GoTest, expected string) {
+	o := old()
+	err := o.Marshal(pb)
+	if err != nil {
+		fmt.Printf("overify marshal-1 err = %v", err)
+		o.DebugPrint("", o.Bytes())
+		t.Fatalf("expected = %s", expected)
+	}
+	if !equal(o.Bytes(), expected, t) {
+		o.DebugPrint("overify neq 1", o.Bytes())
+		t.Fatalf("expected = %s", expected)
+	}
+
+	// Now test Unmarshal by recreating the original buffer.
+	pbd := new(GoTest)
+	err = o.Unmarshal(pbd)
+	if err != nil {
+		t.Fatalf("overify unmarshal err = %v", err)
+		o.DebugPrint("", o.Bytes())
+		t.Fatalf("string = %s", expected)
+	}
+	o.Reset()
+	err = o.Marshal(pbd)
+	if err != nil {
+		t.Errorf("overify marshal-2 err = %v", err)
+		o.DebugPrint("", o.Bytes())
+		t.Fatalf("string = %s", expected)
+	}
+	if !equal(o.Bytes(), expected, t) {
+		o.DebugPrint("overify neq 2", o.Bytes())
+		t.Fatalf("string = %s", expected)
+	}
+}
+
+// Simple tests for numeric encode/decode primitives (varint, etc.)
+func TestNumericPrimitives(t *testing.T) {
+	for i := uint64(0); i < 1e6; i += 111 {
+		o := old()
+		if o.EncodeVarint(i) != nil {
+			t.Error("EncodeVarint")
+			break
+		}
+		x, e := o.DecodeVarint()
+		if e != nil {
+			t.Fatal("DecodeVarint")
+		}
+		if x != i {
+			t.Fatal("varint decode fail:", i, x)
+		}
+
+		o = old()
+		if o.EncodeFixed32(i) != nil {
+			t.Fatal("encFixed32")
+		}
+		x, e = o.DecodeFixed32()
+		if e != nil {
+			t.Fatal("decFixed32")
+		}
+		if x != i {
+			t.Fatal("fixed32 decode fail:", i, x)
+		}
+
+		o = old()
+		if o.EncodeFixed64(i*1234567) != nil {
+			t.Error("encFixed64")
+			break
+		}
+		x, e = o.DecodeFixed64()
+		if e != nil {
+			t.Error("decFixed64")
+			break
+		}
+		if x != i*1234567 {
+			t.Error("fixed64 decode fail:", i*1234567, x)
+			break
+		}
+
+		o = old()
+		i32 := int32(i - 12345)
+		if o.EncodeZigzag32(uint64(i32)) != nil {
+			t.Fatal("EncodeZigzag32")
+		}
+		x, e = o.DecodeZigzag32()
+		if e != nil {
+			t.Fatal("DecodeZigzag32")
+		}
+		if x != uint64(uint32(i32)) {
+			t.Fatal("zigzag32 decode fail:", i32, x)
+		}
+
+		o = old()
+		i64 := int64(i - 12345)
+		if o.EncodeZigzag64(uint64(i64)) != nil {
+			t.Fatal("EncodeZigzag64")
+		}
+		x, e = o.DecodeZigzag64()
+		if e != nil {
+			t.Fatal("DecodeZigzag64")
+		}
+		if x != uint64(i64) {
+			t.Fatal("zigzag64 decode fail:", i64, x)
+		}
+	}
+}
+
+// fakeMarshaler is a simple struct implementing Marshaler and Message interfaces.
+type fakeMarshaler struct {
+	b   []byte
+	err error
+}
+
+func (f fakeMarshaler) Marshal() ([]byte, error) {
+	return f.b, f.err
+}
+
+func (f fakeMarshaler) String() string {
+	return fmt.Sprintf("Bytes: %v Error: %v", f.b, f.err)
+}
+
+func (f fakeMarshaler) ProtoMessage() {}
+
+func (f fakeMarshaler) Reset() {}
+
+// Simple tests for proto messages that implement the Marshaler interface.
+func TestMarshalerEncoding(t *testing.T) {
+	tests := []struct {
+		name    string
+		m       Message
+		want    []byte
+		wantErr error
+	}{
+		{
+			name: "Marshaler that fails",
+			m: fakeMarshaler{
+				err: errors.New("some marshal err"),
+				b:   []byte{5, 6, 7},
+			},
+			// Since there's an error, nothing should be written to buffer.
+			want:    nil,
+			wantErr: errors.New("some marshal err"),
+		},
+		{
+			name: "Marshaler that succeeds",
+			m: fakeMarshaler{
+				b: []byte{0, 1, 2, 3, 4, 127, 255},
+			},
+			want:    []byte{0, 1, 2, 3, 4, 127, 255},
+			wantErr: nil,
+		},
+	}
+	for _, test := range tests {
+		b := NewBuffer(nil)
+		err := b.Marshal(test.m)
+		if !reflect.DeepEqual(test.wantErr, err) {
+			t.Errorf("%s: got err %v wanted %v", test.name, err, test.wantErr)
+		}
+		if !reflect.DeepEqual(test.want, b.Bytes()) {
+			t.Errorf("%s: got bytes %v wanted %v", test.name, b.Bytes(), test.want)
+		}
+	}
+}
+
+// Simple tests for bytes
+func TestBytesPrimitives(t *testing.T) {
+	o := old()
+	bytes := []byte{'n', 'o', 'w', ' ', 'i', 's', ' ', 't', 'h', 'e', ' ', 't', 'i', 'm', 'e'}
+	if o.EncodeRawBytes(bytes) != nil {
+		t.Error("EncodeRawBytes")
+	}
+	decb, e := o.DecodeRawBytes(false)
+	if e != nil {
+		t.Error("DecodeRawBytes")
+	}
+	equalbytes(bytes, decb, t)
+}
+
+// Simple tests for strings
+func TestStringPrimitives(t *testing.T) {
+	o := old()
+	s := "now is the time"
+	if o.EncodeStringBytes(s) != nil {
+		t.Error("enc_string")
+	}
+	decs, e := o.DecodeStringBytes()
+	if e != nil {
+		t.Error("dec_string")
+	}
+	if s != decs {
+		t.Error("string encode/decode fail:", s, decs)
+	}
+}
+
+// Do we catch the "required bit not set" case?
+func TestRequiredBit(t *testing.T) {
+	o := old()
+	pb := new(GoTest)
+	err := o.Marshal(pb)
+	if err == nil {
+		t.Error("did not catch missing required fields")
+	} else if strings.Index(err.Error(), "Kind") < 0 {
+		t.Error("wrong error type:", err)
+	}
+}
+
+// Check that all fields are nil.
+// Clearly silly, and a residue from a more interesting test with an earlier,
+// different initialization property, but it once caught a compiler bug so
+// it lives.
+func checkInitialized(pb *GoTest, t *testing.T) {
+	if pb.F_BoolDefaulted != nil {
+		t.Error("New or Reset did not set boolean:", *pb.F_BoolDefaulted)
+	}
+	if pb.F_Int32Defaulted != nil {
+		t.Error("New or Reset did not set int32:", *pb.F_Int32Defaulted)
+	}
+	if pb.F_Int64Defaulted != nil {
+		t.Error("New or Reset did not set int64:", *pb.F_Int64Defaulted)
+	}
+	if pb.F_Fixed32Defaulted != nil {
+		t.Error("New or Reset did not set fixed32:", *pb.F_Fixed32Defaulted)
+	}
+	if pb.F_Fixed64Defaulted != nil {
+		t.Error("New or Reset did not set fixed64:", *pb.F_Fixed64Defaulted)
+	}
+	if pb.F_Uint32Defaulted != nil {
+		t.Error("New or Reset did not set uint32:", *pb.F_Uint32Defaulted)
+	}
+	if pb.F_Uint64Defaulted != nil {
+		t.Error("New or Reset did not set uint64:", *pb.F_Uint64Defaulted)
+	}
+	if pb.F_FloatDefaulted != nil {
+		t.Error("New or Reset did not set float:", *pb.F_FloatDefaulted)
+	}
+	if pb.F_DoubleDefaulted != nil {
+		t.Error("New or Reset did not set double:", *pb.F_DoubleDefaulted)
+	}
+	if pb.F_StringDefaulted != nil {
+		t.Error("New or Reset did not set string:", *pb.F_StringDefaulted)
+	}
+	if pb.F_BytesDefaulted != nil {
+		t.Error("New or Reset did not set bytes:", string(pb.F_BytesDefaulted))
+	}
+	if pb.F_Sint32Defaulted != nil {
+		t.Error("New or Reset did not set int32:", *pb.F_Sint32Defaulted)
+	}
+	if pb.F_Sint64Defaulted != nil {
+		t.Error("New or Reset did not set int64:", *pb.F_Sint64Defaulted)
+	}
+}
+
+// Does Reset() reset?
+func TestReset(t *testing.T) {
+	pb := initGoTest(true)
+	// muck with some values
+	pb.F_BoolDefaulted = Bool(false)
+	pb.F_Int32Defaulted = Int32(237)
+	pb.F_Int64Defaulted = Int64(12346)
+	pb.F_Fixed32Defaulted = Uint32(32000)
+	pb.F_Fixed64Defaulted = Uint64(666)
+	pb.F_Uint32Defaulted = Uint32(323232)
+	pb.F_Uint64Defaulted = nil
+	pb.F_FloatDefaulted = nil
+	pb.F_DoubleDefaulted = Float64(0)
+	pb.F_StringDefaulted = String("gotcha")
+	pb.F_BytesDefaulted = []byte("asdfasdf")
+	pb.F_Sint32Defaulted = Int32(123)
+	pb.F_Sint64Defaulted = Int64(789)
+	pb.Reset()
+	checkInitialized(pb, t)
+}
+
+// All required fields set, no defaults provided.
+func TestEncodeDecode1(t *testing.T) {
+	pb := initGoTest(false)
+	overify(t, pb,
+		"0807"+ // field 1, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
+			"5001"+ // field 10, encoding 0, value 1
+			"5803"+ // field 11, encoding 0, value 3
+			"6006"+ // field 12, encoding 0, value 6
+			"6d20000000"+ // field 13, encoding 5, value 0x20
+			"714000000000000000"+ // field 14, encoding 1, value 0x40
+			"78a019"+ // field 15, encoding 0, value 0xca0 = 3232
+			"8001c032"+ // field 16, encoding 0, value 0x1940 = 6464
+			"8d0100004a45"+ // field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+ // field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+ // field 19, encoding 2, string "string"
+			"b304"+ // field 70, encoding 3, start group
+			"ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
+			"b404"+ // field 70, encoding 4, end group
+			"aa0605"+"6279746573"+ // field 101, encoding 2, string "bytes"
+			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
+			"b8067f") // field 103, encoding 0, 0x7f zigzag64
+}
+
+// All required fields set, defaults provided.
+func TestEncodeDecode2(t *testing.T) {
+	pb := initGoTest(true)
+	overify(t, pb,
+		"0807"+ // field 1, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
+			"5001"+ // field 10, encoding 0, value 1
+			"5803"+ // field 11, encoding 0, value 3
+			"6006"+ // field 12, encoding 0, value 6
+			"6d20000000"+ // field 13, encoding 5, value 32
+			"714000000000000000"+ // field 14, encoding 1, value 64
+			"78a019"+ // field 15, encoding 0, value 3232
+			"8001c032"+ // field 16, encoding 0, value 6464
+			"8d0100004a45"+ // field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+ // field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
+			"c00201"+ // field 40, encoding 0, value 1
+			"c80220"+ // field 41, encoding 0, value 32
+			"d00240"+ // field 42, encoding 0, value 64
+			"dd0240010000"+ // field 43, encoding 5, value 320
+			"e1028002000000000000"+ // field 44, encoding 1, value 640
+			"e8028019"+ // field 45, encoding 0, value 3200
+			"f0028032"+ // field 46, encoding 0, value 6400
+			"fd02e0659948"+ // field 47, encoding 5, value 314159.0
+			"81030000000050971041"+ // field 48, encoding 1, value 271828.0
+			"8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
+			"b304"+ // start group field 70 level 1
+			"ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
+			"b404"+ // end group field 70 level 1
+			"aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
+			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
+			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
+			"90193f"+ // field 402, encoding 0, value 63
+			"98197f") // field 403, encoding 0, value 127
+
+}
+
+// All default fields set to their default value by hand
+func TestEncodeDecode3(t *testing.T) {
+	pb := initGoTest(false)
+	pb.F_BoolDefaulted = Bool(true)
+	pb.F_Int32Defaulted = Int32(32)
+	pb.F_Int64Defaulted = Int64(64)
+	pb.F_Fixed32Defaulted = Uint32(320)
+	pb.F_Fixed64Defaulted = Uint64(640)
+	pb.F_Uint32Defaulted = Uint32(3200)
+	pb.F_Uint64Defaulted = Uint64(6400)
+	pb.F_FloatDefaulted = Float32(314159)
+	pb.F_DoubleDefaulted = Float64(271828)
+	pb.F_StringDefaulted = String("hello, \"world!\"\n")
+	pb.F_BytesDefaulted = []byte("Bignose")
+	pb.F_Sint32Defaulted = Int32(-32)
+	pb.F_Sint64Defaulted = Int64(-64)
+
+	overify(t, pb,
+		"0807"+ // field 1, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
+			"5001"+ // field 10, encoding 0, value 1
+			"5803"+ // field 11, encoding 0, value 3
+			"6006"+ // field 12, encoding 0, value 6
+			"6d20000000"+ // field 13, encoding 5, value 32
+			"714000000000000000"+ // field 14, encoding 1, value 64
+			"78a019"+ // field 15, encoding 0, value 3232
+			"8001c032"+ // field 16, encoding 0, value 6464
+			"8d0100004a45"+ // field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+ // field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
+			"c00201"+ // field 40, encoding 0, value 1
+			"c80220"+ // field 41, encoding 0, value 32
+			"d00240"+ // field 42, encoding 0, value 64
+			"dd0240010000"+ // field 43, encoding 5, value 320
+			"e1028002000000000000"+ // field 44, encoding 1, value 640
+			"e8028019"+ // field 45, encoding 0, value 3200
+			"f0028032"+ // field 46, encoding 0, value 6400
+			"fd02e0659948"+ // field 47, encoding 5, value 314159.0
+			"81030000000050971041"+ // field 48, encoding 1, value 271828.0
+			"8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
+			"b304"+ // start group field 70 level 1
+			"ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
+			"b404"+ // end group field 70 level 1
+			"aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
+			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
+			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
+			"90193f"+ // field 402, encoding 0, value 63
+			"98197f") // field 403, encoding 0, value 127
+
+}
+
+// All required fields set, defaults provided, all non-defaulted optional fields have values.
+func TestEncodeDecode4(t *testing.T) {
+	pb := initGoTest(true)
+	pb.Table = String("hello")
+	pb.Param = Int32(7)
+	pb.OptionalField = initGoTestField()
+	pb.F_BoolOptional = Bool(true)
+	pb.F_Int32Optional = Int32(32)
+	pb.F_Int64Optional = Int64(64)
+	pb.F_Fixed32Optional = Uint32(3232)
+	pb.F_Fixed64Optional = Uint64(6464)
+	pb.F_Uint32Optional = Uint32(323232)
+	pb.F_Uint64Optional = Uint64(646464)
+	pb.F_FloatOptional = Float32(32.)
+	pb.F_DoubleOptional = Float64(64.)
+	pb.F_StringOptional = String("hello")
+	pb.F_BytesOptional = []byte("Bignose")
+	pb.F_Sint32Optional = Int32(-32)
+	pb.F_Sint64Optional = Int64(-64)
+	pb.Optionalgroup = initGoTest_OptionalGroup()
+
+	overify(t, pb,
+		"0807"+ // field 1, encoding 0, value 7
+			"1205"+"68656c6c6f"+ // field 2, encoding 2, string "hello"
+			"1807"+ // field 3, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
+			"320d"+"0a056c6162656c120474797065"+ // field 6, encoding 2 (GoTestField)
+			"5001"+ // field 10, encoding 0, value 1
+			"5803"+ // field 11, encoding 0, value 3
+			"6006"+ // field 12, encoding 0, value 6
+			"6d20000000"+ // field 13, encoding 5, value 32
+			"714000000000000000"+ // field 14, encoding 1, value 64
+			"78a019"+ // field 15, encoding 0, value 3232
+			"8001c032"+ // field 16, encoding 0, value 6464
+			"8d0100004a45"+ // field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+ // field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
+			"f00101"+ // field 30, encoding 0, value 1
+			"f80120"+ // field 31, encoding 0, value 32
+			"800240"+ // field 32, encoding 0, value 64
+			"8d02a00c0000"+ // field 33, encoding 5, value 3232
+			"91024019000000000000"+ // field 34, encoding 1, value 6464
+			"9802a0dd13"+ // field 35, encoding 0, value 323232
+			"a002c0ba27"+ // field 36, encoding 0, value 646464
+			"ad0200000042"+ // field 37, encoding 5, value 32.0
+			"b1020000000000005040"+ // field 38, encoding 1, value 64.0
+			"ba0205"+"68656c6c6f"+ // field 39, encoding 2, string "hello"
+			"c00201"+ // field 40, encoding 0, value 1
+			"c80220"+ // field 41, encoding 0, value 32
+			"d00240"+ // field 42, encoding 0, value 64
+			"dd0240010000"+ // field 43, encoding 5, value 320
+			"e1028002000000000000"+ // field 44, encoding 1, value 640
+			"e8028019"+ // field 45, encoding 0, value 3200
+			"f0028032"+ // field 46, encoding 0, value 6400
+			"fd02e0659948"+ // field 47, encoding 5, value 314159.0
+			"81030000000050971041"+ // field 48, encoding 1, value 271828.0
+			"8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
+			"b304"+ // start group field 70 level 1
+			"ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
+			"b404"+ // end group field 70 level 1
+			"d305"+ // start group field 90 level 1
+			"da0508"+"6f7074696f6e616c"+ // field 91, encoding 2, string "optional"
+			"d405"+ // end group field 90 level 1
+			"aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
+			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
+			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"ea1207"+"4269676e6f7365"+ // field 301, encoding 2, string "Bignose"
+			"f0123f"+ // field 302, encoding 0, value 63
+			"f8127f"+ // field 303, encoding 0, value 127
+			"8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
+			"90193f"+ // field 402, encoding 0, value 63
+			"98197f") // field 403, encoding 0, value 127
+
+}
+
+// All required fields set, defaults provided, all repeated fields given two values.
+func TestEncodeDecode5(t *testing.T) {
+	pb := initGoTest(true)
+	pb.RepeatedField = []*GoTestField{initGoTestField(), initGoTestField()}
+	pb.F_BoolRepeated = []bool{false, true}
+	pb.F_Int32Repeated = []int32{32, 33}
+	pb.F_Int64Repeated = []int64{64, 65}
+	pb.F_Fixed32Repeated = []uint32{3232, 3333}
+	pb.F_Fixed64Repeated = []uint64{6464, 6565}
+	pb.F_Uint32Repeated = []uint32{323232, 333333}
+	pb.F_Uint64Repeated = []uint64{646464, 656565}
+	pb.F_FloatRepeated = []float32{32., 33.}
+	pb.F_DoubleRepeated = []float64{64., 65.}
+	pb.F_StringRepeated = []string{"hello", "sailor"}
+	pb.F_BytesRepeated = [][]byte{[]byte("big"), []byte("nose")}
+	pb.F_Sint32Repeated = []int32{32, -32}
+	pb.F_Sint64Repeated = []int64{64, -64}
+	pb.Repeatedgroup = []*GoTest_RepeatedGroup{initGoTest_RepeatedGroup(), initGoTest_RepeatedGroup()}
+
+	overify(t, pb,
+		"0807"+ // field 1, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
+			"2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField)
+			"2a0d"+"0a056c6162656c120474797065"+ // field 5, encoding 2 (GoTestField)
+			"5001"+ // field 10, encoding 0, value 1
+			"5803"+ // field 11, encoding 0, value 3
+			"6006"+ // field 12, encoding 0, value 6
+			"6d20000000"+ // field 13, encoding 5, value 32
+			"714000000000000000"+ // field 14, encoding 1, value 64
+			"78a019"+ // field 15, encoding 0, value 3232
+			"8001c032"+ // field 16, encoding 0, value 6464
+			"8d0100004a45"+ // field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+ // field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
+			"a00100"+ // field 20, encoding 0, value 0
+			"a00101"+ // field 20, encoding 0, value 1
+			"a80120"+ // field 21, encoding 0, value 32
+			"a80121"+ // field 21, encoding 0, value 33
+			"b00140"+ // field 22, encoding 0, value 64
+			"b00141"+ // field 22, encoding 0, value 65
+			"bd01a00c0000"+ // field 23, encoding 5, value 3232
+			"bd01050d0000"+ // field 23, encoding 5, value 3333
+			"c1014019000000000000"+ // field 24, encoding 1, value 6464
+			"c101a519000000000000"+ // field 24, encoding 1, value 6565
+			"c801a0dd13"+ // field 25, encoding 0, value 323232
+			"c80195ac14"+ // field 25, encoding 0, value 333333
+			"d001c0ba27"+ // field 26, encoding 0, value 646464
+			"d001b58928"+ // field 26, encoding 0, value 656565
+			"dd0100000042"+ // field 27, encoding 5, value 32.0
+			"dd0100000442"+ // field 27, encoding 5, value 33.0
+			"e1010000000000005040"+ // field 28, encoding 1, value 64.0
+			"e1010000000000405040"+ // field 28, encoding 1, value 65.0
+			"ea0105"+"68656c6c6f"+ // field 29, encoding 2, string "hello"
+			"ea0106"+"7361696c6f72"+ // field 29, encoding 2, string "sailor"
+			"c00201"+ // field 40, encoding 0, value 1
+			"c80220"+ // field 41, encoding 0, value 32
+			"d00240"+ // field 42, encoding 0, value 64
+			"dd0240010000"+ // field 43, encoding 5, value 320
+			"e1028002000000000000"+ // field 44, encoding 1, value 640
+			"e8028019"+ // field 45, encoding 0, value 3200
+			"f0028032"+ // field 46, encoding 0, value 6400
+			"fd02e0659948"+ // field 47, encoding 5, value 314159.0
+			"81030000000050971041"+ // field 48, encoding 1, value 271828.0
+			"8a0310"+"68656c6c6f2c2022776f726c6421220a"+ // field 49, encoding 2 string "hello, \"world!\"\n"
+			"b304"+ // start group field 70 level 1
+			"ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
+			"b404"+ // end group field 70 level 1
+			"8305"+ // start group field 80 level 1
+			"8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated"
+			"8405"+ // end group field 80 level 1
+			"8305"+ // start group field 80 level 1
+			"8a0508"+"7265706561746564"+ // field 81, encoding 2, string "repeated"
+			"8405"+ // end group field 80 level 1
+			"aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
+			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
+			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"ca0c03"+"626967"+ // field 201, encoding 2, string "big"
+			"ca0c04"+"6e6f7365"+ // field 201, encoding 2, string "nose"
+			"d00c40"+ // field 202, encoding 0, value 32
+			"d00c3f"+ // field 202, encoding 0, value -32
+			"d80c8001"+ // field 203, encoding 0, value 64
+			"d80c7f"+ // field 203, encoding 0, value -64
+			"8a1907"+"4269676e6f7365"+ // field 401, encoding 2, string "Bignose"
+			"90193f"+ // field 402, encoding 0, value 63
+			"98197f") // field 403, encoding 0, value 127
+
+}
+
+// All required fields set, all packed repeated fields given two values.
+func TestEncodeDecode6(t *testing.T) {
+	pb := initGoTest(false)
+	pb.F_BoolRepeatedPacked = []bool{false, true}
+	pb.F_Int32RepeatedPacked = []int32{32, 33}
+	pb.F_Int64RepeatedPacked = []int64{64, 65}
+	pb.F_Fixed32RepeatedPacked = []uint32{3232, 3333}
+	pb.F_Fixed64RepeatedPacked = []uint64{6464, 6565}
+	pb.F_Uint32RepeatedPacked = []uint32{323232, 333333}
+	pb.F_Uint64RepeatedPacked = []uint64{646464, 656565}
+	pb.F_FloatRepeatedPacked = []float32{32., 33.}
+	pb.F_DoubleRepeatedPacked = []float64{64., 65.}
+	pb.F_Sint32RepeatedPacked = []int32{32, -32}
+	pb.F_Sint64RepeatedPacked = []int64{64, -64}
+
+	overify(t, pb,
+		"0807"+ // field 1, encoding 0, value 7
+			"220d"+"0a056c6162656c120474797065"+ // field 4, encoding 2 (GoTestField)
+			"5001"+ // field 10, encoding 0, value 1
+			"5803"+ // field 11, encoding 0, value 3
+			"6006"+ // field 12, encoding 0, value 6
+			"6d20000000"+ // field 13, encoding 5, value 32
+			"714000000000000000"+ // field 14, encoding 1, value 64
+			"78a019"+ // field 15, encoding 0, value 3232
+			"8001c032"+ // field 16, encoding 0, value 6464
+			"8d0100004a45"+ // field 17, encoding 5, value 3232.0
+			"9101000000000040b940"+ // field 18, encoding 1, value 6464.0
+			"9a0106"+"737472696e67"+ // field 19, encoding 2 string "string"
+			"9203020001"+ // field 50, encoding 2, 2 bytes, value 0, value 1
+			"9a03022021"+ // field 51, encoding 2, 2 bytes, value 32, value 33
+			"a203024041"+ // field 52, encoding 2, 2 bytes, value 64, value 65
+			"aa0308"+ // field 53, encoding 2, 8 bytes
+			"a00c0000050d0000"+ // value 3232, value 3333
+			"b20310"+ // field 54, encoding 2, 16 bytes
+			"4019000000000000a519000000000000"+ // value 6464, value 6565
+			"ba0306"+ // field 55, encoding 2, 6 bytes
+			"a0dd1395ac14"+ // value 323232, value 333333
+			"c20306"+ // field 56, encoding 2, 6 bytes
+			"c0ba27b58928"+ // value 646464, value 656565
+			"ca0308"+ // field 57, encoding 2, 8 bytes
+			"0000004200000442"+ // value 32.0, value 33.0
+			"d20310"+ // field 58, encoding 2, 16 bytes
+			"00000000000050400000000000405040"+ // value 64.0, value 65.0
+			"b304"+ // start group field 70 level 1
+			"ba0408"+"7265717569726564"+ // field 71, encoding 2, string "required"
+			"b404"+ // end group field 70 level 1
+			"aa0605"+"6279746573"+ // field 101, encoding 2 string "bytes"
+			"b0063f"+ // field 102, encoding 0, 0x3f zigzag32
+			"b8067f"+ // field 103, encoding 0, 0x7f zigzag64
+			"b21f02"+ // field 502, encoding 2, 2 bytes
+			"403f"+ // value 32, value -32
+			"ba1f03"+ // field 503, encoding 2, 3 bytes
+			"80017f") // value 64, value -64
+}
+
+// Test that we can encode empty bytes fields.
+func TestEncodeDecodeBytes1(t *testing.T) {
+	pb := initGoTest(false)
+
+	// Create our bytes
+	pb.F_BytesRequired = []byte{}
+	pb.F_BytesRepeated = [][]byte{{}}
+	pb.F_BytesOptional = []byte{}
+
+	d, err := Marshal(pb)
+	if err != nil {
+		t.Error(err)
+	}
+
+	pbd := new(GoTest)
+	if err := Unmarshal(d, pbd); err != nil {
+		t.Error(err)
+	}
+
+	if pbd.F_BytesRequired == nil || len(pbd.F_BytesRequired) != 0 {
+		t.Error("required empty bytes field is incorrect")
+	}
+	if pbd.F_BytesRepeated == nil || len(pbd.F_BytesRepeated) == 1 && pbd.F_BytesRepeated[0] == nil {
+		t.Error("repeated empty bytes field is incorrect")
+	}
+	if pbd.F_BytesOptional == nil || len(pbd.F_BytesOptional) != 0 {
+		t.Error("optional empty bytes field is incorrect")
+	}
+}
+
+// Test that we encode nil-valued fields of a repeated bytes field correctly.
+// Since entries in a repeated field cannot be nil, nil must mean empty value.
+func TestEncodeDecodeBytes2(t *testing.T) {
+	pb := initGoTest(false)
+
+	// Create our bytes
+	pb.F_BytesRepeated = [][]byte{nil}
+
+	d, err := Marshal(pb)
+	if err != nil {
+		t.Error(err)
+	}
+
+	pbd := new(GoTest)
+	if err := Unmarshal(d, pbd); err != nil {
+		t.Error(err)
+	}
+
+	if len(pbd.F_BytesRepeated) != 1 || pbd.F_BytesRepeated[0] == nil {
+		t.Error("Unexpected value for repeated bytes field")
+	}
+}
+
+// All required fields set, defaults provided, all repeated fields given two values.
+func TestSkippingUnrecognizedFields(t *testing.T) {
+	o := old()
+	pb := initGoTestField()
+
+	// Marshal it normally.
+	o.Marshal(pb)
+
+	// Now new a GoSkipTest record.
+	skip := &GoSkipTest{
+		SkipInt32:   Int32(32),
+		SkipFixed32: Uint32(3232),
+		SkipFixed64: Uint64(6464),
+		SkipString:  String("skipper"),
+		Skipgroup: &GoSkipTest_SkipGroup{
+			GroupInt32:  Int32(75),
+			GroupString: String("wxyz"),
+		},
+	}
+
+	// Marshal it into same buffer.
+	o.Marshal(skip)
+
+	pbd := new(GoTestField)
+	o.Unmarshal(pbd)
+
+	// The __unrecognized field should be a marshaling of GoSkipTest
+	skipd := new(GoSkipTest)
+
+	o.SetBuf(pbd.XXX_unrecognized)
+	o.Unmarshal(skipd)
+
+	if *skipd.SkipInt32 != *skip.SkipInt32 {
+		t.Error("skip int32", skipd.SkipInt32)
+	}
+	if *skipd.SkipFixed32 != *skip.SkipFixed32 {
+		t.Error("skip fixed32", skipd.SkipFixed32)
+	}
+	if *skipd.SkipFixed64 != *skip.SkipFixed64 {
+		t.Error("skip fixed64", skipd.SkipFixed64)
+	}
+	if *skipd.SkipString != *skip.SkipString {
+		t.Error("skip string", *skipd.SkipString)
+	}
+	if *skipd.Skipgroup.GroupInt32 != *skip.Skipgroup.GroupInt32 {
+		t.Error("skip group int32", skipd.Skipgroup.GroupInt32)
+	}
+	if *skipd.Skipgroup.GroupString != *skip.Skipgroup.GroupString {
+		t.Error("skip group string", *skipd.Skipgroup.GroupString)
+	}
+}
+
+// Check that unrecognized fields of a submessage are preserved.
+func TestSubmessageUnrecognizedFields(t *testing.T) {
+	nm := &NewMessage{
+		Nested: &NewMessage_Nested{
+			Name:      String("Nigel"),
+			FoodGroup: String("carbs"),
+		},
+	}
+	b, err := Marshal(nm)
+	if err != nil {
+		t.Fatalf("Marshal of NewMessage: %v", err)
+	}
+
+	// Unmarshal into an OldMessage.
+	om := new(OldMessage)
+	if err := Unmarshal(b, om); err != nil {
+		t.Fatalf("Unmarshal to OldMessage: %v", err)
+	}
+	exp := &OldMessage{
+		Nested: &OldMessage_Nested{
+			Name: String("Nigel"),
+			// normal protocol buffer users should not do this
+			XXX_unrecognized: []byte("\x12\x05carbs"),
+		},
+	}
+	if !Equal(om, exp) {
+		t.Errorf("om = %v, want %v", om, exp)
+	}
+
+	// Clone the OldMessage.
+	om = Clone(om).(*OldMessage)
+	if !Equal(om, exp) {
+		t.Errorf("Clone(om) = %v, want %v", om, exp)
+	}
+
+	// Marshal the OldMessage, then unmarshal it into an empty NewMessage.
+	if b, err = Marshal(om); err != nil {
+		t.Fatalf("Marshal of OldMessage: %v", err)
+	}
+	t.Logf("Marshal(%v) -> %q", om, b)
+	nm2 := new(NewMessage)
+	if err := Unmarshal(b, nm2); err != nil {
+		t.Fatalf("Unmarshal to NewMessage: %v", err)
+	}
+	if !Equal(nm, nm2) {
+		t.Errorf("NewMessage round-trip: %v => %v", nm, nm2)
+	}
+}
+
+// Check that an int32 field can be upgraded to an int64 field.
+func TestNegativeInt32(t *testing.T) {
+	om := &OldMessage{
+		Num: Int32(-1),
+	}
+	b, err := Marshal(om)
+	if err != nil {
+		t.Fatalf("Marshal of OldMessage: %v", err)
+	}
+
+	// Check the size. It should be 11 bytes;
+	// 1 for the field/wire type, and 10 for the negative number.
+	if len(b) != 11 {
+		t.Errorf("%v marshaled as %q, wanted 11 bytes", om, b)
+	}
+
+	// Unmarshal into a NewMessage.
+	nm := new(NewMessage)
+	if err := Unmarshal(b, nm); err != nil {
+		t.Fatalf("Unmarshal to NewMessage: %v", err)
+	}
+	want := &NewMessage{
+		Num: Int64(-1),
+	}
+	if !Equal(nm, want) {
+		t.Errorf("nm = %v, want %v", nm, want)
+	}
+}
+
+// Check that we can grow an array (repeated field) to have many elements.
+// This test doesn't depend only on our encoding; for variety, it makes sure
+// we create, encode, and decode the correct contents explicitly.  It's therefore
+// a bit messier.
+// This test also uses (and hence tests) the Marshal/Unmarshal functions
+// instead of the methods.
+func TestBigRepeated(t *testing.T) {
+	pb := initGoTest(true)
+
+	// Create the arrays
+	const N = 50 // Internally the library starts much smaller.
+	pb.Repeatedgroup = make([]*GoTest_RepeatedGroup, N)
+	pb.F_Sint64Repeated = make([]int64, N)
+	pb.F_Sint32Repeated = make([]int32, N)
+	pb.F_BytesRepeated = make([][]byte, N)
+	pb.F_StringRepeated = make([]string, N)
+	pb.F_DoubleRepeated = make([]float64, N)
+	pb.F_FloatRepeated = make([]float32, N)
+	pb.F_Uint64Repeated = make([]uint64, N)
+	pb.F_Uint32Repeated = make([]uint32, N)
+	pb.F_Fixed64Repeated = make([]uint64, N)
+	pb.F_Fixed32Repeated = make([]uint32, N)
+	pb.F_Int64Repeated = make([]int64, N)
+	pb.F_Int32Repeated = make([]int32, N)
+	pb.F_BoolRepeated = make([]bool, N)
+	pb.RepeatedField = make([]*GoTestField, N)
+
+	// Fill in the arrays with checkable values.
+	igtf := initGoTestField()
+	igtrg := initGoTest_RepeatedGroup()
+	for i := 0; i < N; i++ {
+		pb.Repeatedgroup[i] = igtrg
+		pb.F_Sint64Repeated[i] = int64(i)
+		pb.F_Sint32Repeated[i] = int32(i)
+		s := fmt.Sprint(i)
+		pb.F_BytesRepeated[i] = []byte(s)
+		pb.F_StringRepeated[i] = s
+		pb.F_DoubleRepeated[i] = float64(i)
+		pb.F_FloatRepeated[i] = float32(i)
+		pb.F_Uint64Repeated[i] = uint64(i)
+		pb.F_Uint32Repeated[i] = uint32(i)
+		pb.F_Fixed64Repeated[i] = uint64(i)
+		pb.F_Fixed32Repeated[i] = uint32(i)
+		pb.F_Int64Repeated[i] = int64(i)
+		pb.F_Int32Repeated[i] = int32(i)
+		pb.F_BoolRepeated[i] = i%2 == 0
+		pb.RepeatedField[i] = igtf
+	}
+
+	// Marshal.
+	buf, _ := Marshal(pb)
+
+	// Now test Unmarshal by recreating the original buffer.
+	pbd := new(GoTest)
+	Unmarshal(buf, pbd)
+
+	// Check the checkable values
+	for i := uint64(0); i < N; i++ {
+		if pbd.Repeatedgroup[i] == nil { // TODO: more checking?
+			t.Error("pbd.Repeatedgroup bad")
+		}
+		var x uint64
+		x = uint64(pbd.F_Sint64Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Sint64Repeated bad", x, i)
+		}
+		x = uint64(pbd.F_Sint32Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Sint32Repeated bad", x, i)
+		}
+		s := fmt.Sprint(i)
+		equalbytes(pbd.F_BytesRepeated[i], []byte(s), t)
+		if pbd.F_StringRepeated[i] != s {
+			t.Error("pbd.F_Sint32Repeated bad", pbd.F_StringRepeated[i], i)
+		}
+		x = uint64(pbd.F_DoubleRepeated[i])
+		if x != i {
+			t.Error("pbd.F_DoubleRepeated bad", x, i)
+		}
+		x = uint64(pbd.F_FloatRepeated[i])
+		if x != i {
+			t.Error("pbd.F_FloatRepeated bad", x, i)
+		}
+		x = pbd.F_Uint64Repeated[i]
+		if x != i {
+			t.Error("pbd.F_Uint64Repeated bad", x, i)
+		}
+		x = uint64(pbd.F_Uint32Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Uint32Repeated bad", x, i)
+		}
+		x = pbd.F_Fixed64Repeated[i]
+		if x != i {
+			t.Error("pbd.F_Fixed64Repeated bad", x, i)
+		}
+		x = uint64(pbd.F_Fixed32Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Fixed32Repeated bad", x, i)
+		}
+		x = uint64(pbd.F_Int64Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Int64Repeated bad", x, i)
+		}
+		x = uint64(pbd.F_Int32Repeated[i])
+		if x != i {
+			t.Error("pbd.F_Int32Repeated bad", x, i)
+		}
+		if pbd.F_BoolRepeated[i] != (i%2 == 0) {
+			t.Error("pbd.F_BoolRepeated bad", x, i)
+		}
+		if pbd.RepeatedField[i] == nil { // TODO: more checking?
+			t.Error("pbd.RepeatedField bad")
+		}
+	}
+}
+
+// Verify we give a useful message when decoding to the wrong structure type.
+func TestTypeMismatch(t *testing.T) {
+	pb1 := initGoTest(true)
+
+	// Marshal
+	o := old()
+	o.Marshal(pb1)
+
+	// Now Unmarshal it to the wrong type.
+	pb2 := initGoTestField()
+	err := o.Unmarshal(pb2)
+	if err == nil {
+		t.Error("expected error, got no error")
+	} else if !strings.Contains(err.Error(), "bad wiretype") {
+		t.Error("expected bad wiretype error, got", err)
+	}
+}
+
+func encodeDecode(t *testing.T, in, out Message, msg string) {
+	buf, err := Marshal(in)
+	if err != nil {
+		t.Fatalf("failed marshaling %v: %v", msg, err)
+	}
+	if err := Unmarshal(buf, out); err != nil {
+		t.Fatalf("failed unmarshaling %v: %v", msg, err)
+	}
+}
+
+func TestPackedNonPackedDecoderSwitching(t *testing.T) {
+	np, p := new(NonPackedTest), new(PackedTest)
+
+	// non-packed -> packed
+	np.A = []int32{0, 1, 1, 2, 3, 5}
+	encodeDecode(t, np, p, "non-packed -> packed")
+	if !reflect.DeepEqual(np.A, p.B) {
+		t.Errorf("failed non-packed -> packed; np.A=%+v, p.B=%+v", np.A, p.B)
+	}
+
+	// packed -> non-packed
+	np.Reset()
+	p.B = []int32{3, 1, 4, 1, 5, 9}
+	encodeDecode(t, p, np, "packed -> non-packed")
+	if !reflect.DeepEqual(p.B, np.A) {
+		t.Errorf("failed packed -> non-packed; p.B=%+v, np.A=%+v", p.B, np.A)
+	}
+}
+
+func TestProto1RepeatedGroup(t *testing.T) {
+	pb := &MessageList{
+		Message: []*MessageList_Message{
+			{
+				Name:  String("blah"),
+				Count: Int32(7),
+			},
+			// NOTE: pb.Message[1] is a nil
+			nil,
+		},
+	}
+
+	o := old()
+	err := o.Marshal(pb)
+	if err == nil || !strings.Contains(err.Error(), "repeated field Message has nil") {
+		t.Fatalf("unexpected or no error when marshaling: %v", err)
+	}
+}
+
+// Test that enums work.  Checks for a bug introduced by making enums
+// named types instead of int32: newInt32FromUint64 would crash with
+// a type mismatch in reflect.PointTo.
+func TestEnum(t *testing.T) {
+	pb := new(GoEnum)
+	pb.Foo = FOO_FOO1.Enum()
+	o := old()
+	if err := o.Marshal(pb); err != nil {
+		t.Fatal("error encoding enum:", err)
+	}
+	pb1 := new(GoEnum)
+	if err := o.Unmarshal(pb1); err != nil {
+		t.Fatal("error decoding enum:", err)
+	}
+	if *pb1.Foo != FOO_FOO1 {
+		t.Error("expected 7 but got ", *pb1.Foo)
+	}
+}
+
+// Enum types have String methods. Check that enum fields can be printed.
+// We don't care what the value actually is, just as long as it doesn't crash.
+func TestPrintingNilEnumFields(t *testing.T) {
+	pb := new(GoEnum)
+	fmt.Sprintf("%+v", pb)
+}
+
+// Verify that absent required fields cause Marshal/Unmarshal to return errors.
+func TestRequiredFieldEnforcement(t *testing.T) {
+	pb := new(GoTestField)
+	_, err := Marshal(pb)
+	if err == nil {
+		t.Error("marshal: expected error, got nil")
+	} else if strings.Index(err.Error(), "Label") < 0 {
+		t.Errorf("marshal: bad error type: %v", err)
+	}
+
+	// A slightly sneaky, yet valid, proto. It encodes the same required field twice,
+	// so simply counting the required fields is insufficient.
+	// field 1, encoding 2, value "hi"
+	buf := []byte("\x0A\x02hi\x0A\x02hi")
+	err = Unmarshal(buf, pb)
+	if err == nil {
+		t.Error("unmarshal: expected error, got nil")
+	} else if strings.Index(err.Error(), "{Unknown}") < 0 {
+		t.Errorf("unmarshal: bad error type: %v", err)
+	}
+}
+
+func TestTypedNilMarshal(t *testing.T) {
+	// A typed nil should return ErrNil and not crash.
+	_, err := Marshal((*GoEnum)(nil))
+	if err != ErrNil {
+		t.Errorf("Marshal: got err %v, want ErrNil", err)
+	}
+}
+
+// A type that implements the Marshaler interface, but is not nillable.
+type nonNillableInt uint64
+
+func (nni nonNillableInt) Marshal() ([]byte, error) {
+	return EncodeVarint(uint64(nni)), nil
+}
+
+type NNIMessage struct {
+	nni nonNillableInt
+}
+
+func (*NNIMessage) Reset()         {}
+func (*NNIMessage) String() string { return "" }
+func (*NNIMessage) ProtoMessage()  {}
+
+// A type that implements the Marshaler interface and is nillable.
+type nillableMessage struct {
+	x uint64
+}
+
+func (nm *nillableMessage) Marshal() ([]byte, error) {
+	return EncodeVarint(nm.x), nil
+}
+
+type NMMessage struct {
+	nm *nillableMessage
+}
+
+func (*NMMessage) Reset()         {}
+func (*NMMessage) String() string { return "" }
+func (*NMMessage) ProtoMessage()  {}
+
+// Verify a type that uses the Marshaler interface, but has a nil pointer.
+func TestNilMarshaler(t *testing.T) {
+	// Try a struct with a Marshaler field that is nil.
+	// It should be directly marshable.
+	nmm := new(NMMessage)
+	if _, err := Marshal(nmm); err != nil {
+		t.Error("unexpected error marshaling nmm: ", err)
+	}
+
+	// Try a struct with a Marshaler field that is not nillable.
+	nnim := new(NNIMessage)
+	nnim.nni = 7
+	var _ Marshaler = nnim.nni // verify it is truly a Marshaler
+	if _, err := Marshal(nnim); err != nil {
+		t.Error("unexpected error marshaling nnim: ", err)
+	}
+}
+
+func TestAllSetDefaults(t *testing.T) {
+	// Exercise SetDefaults with all scalar field types.
+	m := &Defaults{
+		// NaN != NaN, so override that here.
+		F_Nan: Float32(1.7),
+	}
+	expected := &Defaults{
+		F_Bool:    Bool(true),
+		F_Int32:   Int32(32),
+		F_Int64:   Int64(64),
+		F_Fixed32: Uint32(320),
+		F_Fixed64: Uint64(640),
+		F_Uint32:  Uint32(3200),
+		F_Uint64:  Uint64(6400),
+		F_Float:   Float32(314159),
+		F_Double:  Float64(271828),
+		F_String:  String(`hello, "world!"` + "\n"),
+		F_Bytes:   []byte("Bignose"),
+		F_Sint32:  Int32(-32),
+		F_Sint64:  Int64(-64),
+		F_Enum:    Defaults_GREEN.Enum(),
+		F_Pinf:    Float32(float32(math.Inf(1))),
+		F_Ninf:    Float32(float32(math.Inf(-1))),
+		F_Nan:     Float32(1.7),
+		StrZero:   String(""),
+	}
+	SetDefaults(m)
+	if !Equal(m, expected) {
+		t.Errorf("SetDefaults failed\n got %v\nwant %v", m, expected)
+	}
+}
+
+func TestSetDefaultsWithSetField(t *testing.T) {
+	// Check that a set value is not overridden.
+	m := &Defaults{
+		F_Int32: Int32(12),
+	}
+	SetDefaults(m)
+	if v := m.GetF_Int32(); v != 12 {
+		t.Errorf("m.FInt32 = %v, want 12", v)
+	}
+}
+
+func TestSetDefaultsWithSubMessage(t *testing.T) {
+	m := &OtherMessage{
+		Key: Int64(123),
+		Inner: &InnerMessage{
+			Host: String("gopher"),
+		},
+	}
+	expected := &OtherMessage{
+		Key: Int64(123),
+		Inner: &InnerMessage{
+			Host: String("gopher"),
+			Port: Int32(4000),
+		},
+	}
+	SetDefaults(m)
+	if !Equal(m, expected) {
+		t.Errorf("\n got %v\nwant %v", m, expected)
+	}
+}
+
+func TestSetDefaultsWithRepeatedSubMessage(t *testing.T) {
+	m := &MyMessage{
+		RepInner: []*InnerMessage{{}},
+	}
+	expected := &MyMessage{
+		RepInner: []*InnerMessage{{
+			Port: Int32(4000),
+		}},
+	}
+	SetDefaults(m)
+	if !Equal(m, expected) {
+		t.Errorf("\n got %v\nwant %v", m, expected)
+	}
+}
+
+func TestSetDefaultWithRepeatedNonMessage(t *testing.T) {
+	m := &MyMessage{
+		Pet: []string{"turtle", "wombat"},
+	}
+	expected := Clone(m)
+	SetDefaults(m)
+	if !Equal(m, expected) {
+		t.Errorf("\n got %v\nwant %v", m, expected)
+	}
+}
+
+func TestMaximumTagNumber(t *testing.T) {
+	m := &MaxTag{
+		LastField: String("natural goat essence"),
+	}
+	buf, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("proto.Marshal failed: %v", err)
+	}
+	m2 := new(MaxTag)
+	if err := Unmarshal(buf, m2); err != nil {
+		t.Fatalf("proto.Unmarshal failed: %v", err)
+	}
+	if got, want := m2.GetLastField(), *m.LastField; got != want {
+		t.Errorf("got %q, want %q", got, want)
+	}
+}
+
+func TestJSON(t *testing.T) {
+	m := &MyMessage{
+		Count: Int32(4),
+		Pet:   []string{"bunny", "kitty"},
+		Inner: &InnerMessage{
+			Host: String("cauchy"),
+		},
+		Bikeshed: MyMessage_GREEN.Enum(),
+	}
+	const expected = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":1}`
+
+	b, err := json.Marshal(m)
+	if err != nil {
+		t.Fatalf("json.Marshal failed: %v", err)
+	}
+	s := string(b)
+	if s != expected {
+		t.Errorf("got  %s\nwant %s", s, expected)
+	}
+
+	received := new(MyMessage)
+	if err := json.Unmarshal(b, received); err != nil {
+		t.Fatalf("json.Unmarshal failed: %v", err)
+	}
+	if !Equal(received, m) {
+		t.Fatalf("got %s, want %s", received, m)
+	}
+
+	// Test unmarshalling of JSON with symbolic enum name.
+	const old = `{"count":4,"pet":["bunny","kitty"],"inner":{"host":"cauchy"},"bikeshed":"GREEN"}`
+	received.Reset()
+	if err := json.Unmarshal([]byte(old), received); err != nil {
+		t.Fatalf("json.Unmarshal failed: %v", err)
+	}
+	if !Equal(received, m) {
+		t.Fatalf("got %s, want %s", received, m)
+	}
+}
+
+func TestBadWireType(t *testing.T) {
+	b := []byte{7<<3 | 6} // field 7, wire type 6
+	pb := new(OtherMessage)
+	if err := Unmarshal(b, pb); err == nil {
+		t.Errorf("Unmarshal did not fail")
+	} else if !strings.Contains(err.Error(), "unknown wire type") {
+		t.Errorf("wrong error: %v", err)
+	}
+}
+
+func TestBytesWithInvalidLength(t *testing.T) {
+	// If a byte sequence has an invalid (negative) length, Unmarshal should not panic.
+	b := []byte{2<<3 | WireBytes, 0xff, 0xff, 0xff, 0xff, 0xff, 0}
+	Unmarshal(b, new(MyMessage))
+}
+
+func TestLengthOverflow(t *testing.T) {
+	// Overflowing a length should not panic.
+	b := []byte{2<<3 | WireBytes, 1, 1, 3<<3 | WireBytes, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x01}
+	Unmarshal(b, new(MyMessage))
+}
+
+func TestVarintOverflow(t *testing.T) {
+	// Overflowing a 64-bit length should not be allowed.
+	b := []byte{1<<3 | WireVarint, 0x01, 3<<3 | WireBytes, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01}
+	if err := Unmarshal(b, new(MyMessage)); err == nil {
+		t.Fatalf("Overflowed uint64 length without error")
+	}
+}
+
+func TestUnmarshalFuzz(t *testing.T) {
+	const N = 1000
+	seed := time.Now().UnixNano()
+	t.Logf("RNG seed is %d", seed)
+	rng := rand.New(rand.NewSource(seed))
+	buf := make([]byte, 20)
+	for i := 0; i < N; i++ {
+		for j := range buf {
+			buf[j] = byte(rng.Intn(256))
+		}
+		fuzzUnmarshal(t, buf)
+	}
+}
+
+func TestMergeMessages(t *testing.T) {
+	pb := &MessageList{Message: []*MessageList_Message{{Name: String("x"), Count: Int32(1)}}}
+	data, err := Marshal(pb)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+
+	pb1 := new(MessageList)
+	if err := Unmarshal(data, pb1); err != nil {
+		t.Fatalf("first Unmarshal: %v", err)
+	}
+	if err := Unmarshal(data, pb1); err != nil {
+		t.Fatalf("second Unmarshal: %v", err)
+	}
+	if len(pb1.Message) != 1 {
+		t.Errorf("two Unmarshals produced %d Messages, want 1", len(pb1.Message))
+	}
+
+	pb2 := new(MessageList)
+	if err := UnmarshalMerge(data, pb2); err != nil {
+		t.Fatalf("first UnmarshalMerge: %v", err)
+	}
+	if err := UnmarshalMerge(data, pb2); err != nil {
+		t.Fatalf("second UnmarshalMerge: %v", err)
+	}
+	if len(pb2.Message) != 2 {
+		t.Errorf("two UnmarshalMerges produced %d Messages, want 2", len(pb2.Message))
+	}
+}
+
+func TestExtensionMarshalOrder(t *testing.T) {
+	m := &MyMessage{Count: Int(123)}
+	if err := SetExtension(m, E_Ext_More, &Ext{Data: String("alpha")}); err != nil {
+		t.Fatalf("SetExtension: %v", err)
+	}
+	if err := SetExtension(m, E_Ext_Text, String("aleph")); err != nil {
+		t.Fatalf("SetExtension: %v", err)
+	}
+	if err := SetExtension(m, E_Ext_Number, Int32(1)); err != nil {
+		t.Fatalf("SetExtension: %v", err)
+	}
+
+	// Serialize m several times, and check we get the same bytes each time.
+	var orig []byte
+	for i := 0; i < 100; i++ {
+		b, err := Marshal(m)
+		if err != nil {
+			t.Fatalf("Marshal: %v", err)
+		}
+		if i == 0 {
+			orig = b
+			continue
+		}
+		if !bytes.Equal(b, orig) {
+			t.Errorf("Bytes differ on attempt #%d", i)
+		}
+	}
+}
+
+// Many extensions, because small maps might not iterate differently on each iteration.
+var exts = []*ExtensionDesc{
+	E_X201,
+	E_X202,
+	E_X203,
+	E_X204,
+	E_X205,
+	E_X206,
+	E_X207,
+	E_X208,
+	E_X209,
+	E_X210,
+	E_X211,
+	E_X212,
+	E_X213,
+	E_X214,
+	E_X215,
+	E_X216,
+	E_X217,
+	E_X218,
+	E_X219,
+	E_X220,
+	E_X221,
+	E_X222,
+	E_X223,
+	E_X224,
+	E_X225,
+	E_X226,
+	E_X227,
+	E_X228,
+	E_X229,
+	E_X230,
+	E_X231,
+	E_X232,
+	E_X233,
+	E_X234,
+	E_X235,
+	E_X236,
+	E_X237,
+	E_X238,
+	E_X239,
+	E_X240,
+	E_X241,
+	E_X242,
+	E_X243,
+	E_X244,
+	E_X245,
+	E_X246,
+	E_X247,
+	E_X248,
+	E_X249,
+	E_X250,
+}
+
+func TestMessageSetMarshalOrder(t *testing.T) {
+	m := &MyMessageSet{}
+	for _, x := range exts {
+		if err := SetExtension(m, x, &Empty{}); err != nil {
+			t.Fatalf("SetExtension: %v", err)
+		}
+	}
+
+	buf, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+
+	// Serialize m several times, and check we get the same bytes each time.
+	for i := 0; i < 10; i++ {
+		b1, err := Marshal(m)
+		if err != nil {
+			t.Fatalf("Marshal: %v", err)
+		}
+		if !bytes.Equal(b1, buf) {
+			t.Errorf("Bytes differ on re-Marshal #%d", i)
+		}
+
+		m2 := &MyMessageSet{}
+		if err := Unmarshal(buf, m2); err != nil {
+			t.Errorf("Unmarshal: %v", err)
+		}
+		b2, err := Marshal(m2)
+		if err != nil {
+			t.Errorf("re-Marshal: %v", err)
+		}
+		if !bytes.Equal(b2, buf) {
+			t.Errorf("Bytes differ on round-trip #%d", i)
+		}
+	}
+}
+
+func TestUnmarshalMergesMessages(t *testing.T) {
+	// If a nested message occurs twice in the input,
+	// the fields should be merged when decoding.
+	a := &OtherMessage{
+		Key: Int64(123),
+		Inner: &InnerMessage{
+			Host: String("polhode"),
+			Port: Int32(1234),
+		},
+	}
+	aData, err := Marshal(a)
+	if err != nil {
+		t.Fatalf("Marshal(a): %v", err)
+	}
+	b := &OtherMessage{
+		Weight: Float32(1.2),
+		Inner: &InnerMessage{
+			Host:      String("herpolhode"),
+			Connected: Bool(true),
+		},
+	}
+	bData, err := Marshal(b)
+	if err != nil {
+		t.Fatalf("Marshal(b): %v", err)
+	}
+	want := &OtherMessage{
+		Key:    Int64(123),
+		Weight: Float32(1.2),
+		Inner: &InnerMessage{
+			Host:      String("herpolhode"),
+			Port:      Int32(1234),
+			Connected: Bool(true),
+		},
+	}
+	got := new(OtherMessage)
+	if err := Unmarshal(append(aData, bData...), got); err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	if !Equal(got, want) {
+		t.Errorf("\n got %v\nwant %v", got, want)
+	}
+}
+
+func TestEncodingSizes(t *testing.T) {
+	tests := []struct {
+		m Message
+		n int
+	}{
+		{&Defaults{F_Int32: Int32(math.MaxInt32)}, 6},
+		{&Defaults{F_Int32: Int32(math.MinInt32)}, 11},
+		{&Defaults{F_Uint32: Uint32(uint32(math.MaxInt32) + 1)}, 6},
+		{&Defaults{F_Uint32: Uint32(math.MaxUint32)}, 6},
+	}
+	for _, test := range tests {
+		b, err := Marshal(test.m)
+		if err != nil {
+			t.Errorf("Marshal(%v): %v", test.m, err)
+			continue
+		}
+		if len(b) != test.n {
+			t.Errorf("Marshal(%v) yielded %d bytes, want %d bytes", test.m, len(b), test.n)
+		}
+	}
+}
+
+func TestRequiredNotSetError(t *testing.T) {
+	pb := initGoTest(false)
+	pb.RequiredField.Label = nil
+	pb.F_Int32Required = nil
+	pb.F_Int64Required = nil
+
+	expected := "0807" + // field 1, encoding 0, value 7
+		"2206" + "120474797065" + // field 4, encoding 2 (GoTestField)
+		"5001" + // field 10, encoding 0, value 1
+		"6d20000000" + // field 13, encoding 5, value 0x20
+		"714000000000000000" + // field 14, encoding 1, value 0x40
+		"78a019" + // field 15, encoding 0, value 0xca0 = 3232
+		"8001c032" + // field 16, encoding 0, value 0x1940 = 6464
+		"8d0100004a45" + // field 17, encoding 5, value 3232.0
+		"9101000000000040b940" + // field 18, encoding 1, value 6464.0
+		"9a0106" + "737472696e67" + // field 19, encoding 2, string "string"
+		"b304" + // field 70, encoding 3, start group
+		"ba0408" + "7265717569726564" + // field 71, encoding 2, string "required"
+		"b404" + // field 70, encoding 4, end group
+		"aa0605" + "6279746573" + // field 101, encoding 2, string "bytes"
+		"b0063f" + // field 102, encoding 0, 0x3f zigzag32
+		"b8067f" // field 103, encoding 0, 0x7f zigzag64
+
+	o := old()
+	bytes, err := Marshal(pb)
+	if _, ok := err.(*RequiredNotSetError); !ok {
+		fmt.Printf("marshal-1 err = %v, want *RequiredNotSetError", err)
+		o.DebugPrint("", bytes)
+		t.Fatalf("expected = %s", expected)
+	}
+	if strings.Index(err.Error(), "RequiredField.Label") < 0 {
+		t.Errorf("marshal-1 wrong err msg: %v", err)
+	}
+	if !equal(bytes, expected, t) {
+		o.DebugPrint("neq 1", bytes)
+		t.Fatalf("expected = %s", expected)
+	}
+
+	// Now test Unmarshal by recreating the original buffer.
+	pbd := new(GoTest)
+	err = Unmarshal(bytes, pbd)
+	if _, ok := err.(*RequiredNotSetError); !ok {
+		t.Fatalf("unmarshal err = %v, want *RequiredNotSetError", err)
+		o.DebugPrint("", bytes)
+		t.Fatalf("string = %s", expected)
+	}
+	if strings.Index(err.Error(), "RequiredField.{Unknown}") < 0 {
+		t.Errorf("unmarshal wrong err msg: %v", err)
+	}
+	bytes, err = Marshal(pbd)
+	if _, ok := err.(*RequiredNotSetError); !ok {
+		t.Errorf("marshal-2 err = %v, want *RequiredNotSetError", err)
+		o.DebugPrint("", bytes)
+		t.Fatalf("string = %s", expected)
+	}
+	if strings.Index(err.Error(), "RequiredField.Label") < 0 {
+		t.Errorf("marshal-2 wrong err msg: %v", err)
+	}
+	if !equal(bytes, expected, t) {
+		o.DebugPrint("neq 2", bytes)
+		t.Fatalf("string = %s", expected)
+	}
+}
+
+func fuzzUnmarshal(t *testing.T, data []byte) {
+	defer func() {
+		if e := recover(); e != nil {
+			t.Errorf("These bytes caused a panic: %+v", data)
+			t.Logf("Stack:\n%s", debug.Stack())
+			t.FailNow()
+		}
+	}()
+
+	pb := new(MyMessage)
+	Unmarshal(data, pb)
+}
+
+func TestMapFieldMarshal(t *testing.T) {
+	m := &MessageWithMap{
+		NameMapping: map[int32]string{
+			1: "Rob",
+			4: "Ian",
+			8: "Dave",
+		},
+	}
+	b, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+
+	// b should be the concatenation of these three byte sequences in some order.
+	parts := []string{
+		"\n\a\b\x01\x12\x03Rob",
+		"\n\a\b\x04\x12\x03Ian",
+		"\n\b\b\x08\x12\x04Dave",
+	}
+	ok := false
+	for i := range parts {
+		for j := range parts {
+			if j == i {
+				continue
+			}
+			for k := range parts {
+				if k == i || k == j {
+					continue
+				}
+				try := parts[i] + parts[j] + parts[k]
+				if bytes.Equal(b, []byte(try)) {
+					ok = true
+					break
+				}
+			}
+		}
+	}
+	if !ok {
+		t.Fatalf("Incorrect Marshal output.\n got %q\nwant %q (or a permutation of that)", b, parts[0]+parts[1]+parts[2])
+	}
+	t.Logf("FYI b: %q", b)
+
+	(new(Buffer)).DebugPrint("Dump of b", b)
+}
+
+func TestMapFieldRoundTrips(t *testing.T) {
+	m := &MessageWithMap{
+		NameMapping: map[int32]string{
+			1: "Rob",
+			4: "Ian",
+			8: "Dave",
+		},
+		MsgMapping: map[int64]*FloatingPoint{
+			0x7001: &FloatingPoint{F: Float64(2.0)},
+		},
+		ByteMapping: map[bool][]byte{
+			false: []byte("that's not right!"),
+			true:  []byte("aye, 'tis true!"),
+		},
+	}
+	b, err := Marshal(m)
+	if err != nil {
+		t.Fatalf("Marshal: %v", err)
+	}
+	t.Logf("FYI b: %q", b)
+	m2 := new(MessageWithMap)
+	if err := Unmarshal(b, m2); err != nil {
+		t.Fatalf("Unmarshal: %v", err)
+	}
+	for _, pair := range [][2]interface{}{
+		{m.NameMapping, m2.NameMapping},
+		{m.MsgMapping, m2.MsgMapping},
+		{m.ByteMapping, m2.ByteMapping},
+	} {
+		if !reflect.DeepEqual(pair[0], pair[1]) {
+			t.Errorf("Map did not survive a round trip.\ninitial: %v\n  final: %v", pair[0], pair[1])
+		}
+	}
+}
+
+// Benchmarks
+
+func testMsg() *GoTest {
+	pb := initGoTest(true)
+	const N = 1000 // Internally the library starts much smaller.
+	pb.F_Int32Repeated = make([]int32, N)
+	pb.F_DoubleRepeated = make([]float64, N)
+	for i := 0; i < N; i++ {
+		pb.F_Int32Repeated[i] = int32(i)
+		pb.F_DoubleRepeated[i] = float64(i)
+	}
+	return pb
+}
+
+func bytesMsg() *GoTest {
+	pb := initGoTest(true)
+	buf := make([]byte, 4000)
+	for i := range buf {
+		buf[i] = byte(i)
+	}
+	pb.F_BytesDefaulted = buf
+	return pb
+}
+
+func benchmarkMarshal(b *testing.B, pb Message, marshal func(Message) ([]byte, error)) {
+	d, _ := marshal(pb)
+	b.SetBytes(int64(len(d)))
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		marshal(pb)
+	}
+}
+
+func benchmarkBufferMarshal(b *testing.B, pb Message) {
+	p := NewBuffer(nil)
+	benchmarkMarshal(b, pb, func(pb0 Message) ([]byte, error) {
+		p.Reset()
+		err := p.Marshal(pb0)
+		return p.Bytes(), err
+	})
+}
+
+func benchmarkSize(b *testing.B, pb Message) {
+	benchmarkMarshal(b, pb, func(pb0 Message) ([]byte, error) {
+		Size(pb)
+		return nil, nil
+	})
+}
+
+func newOf(pb Message) Message {
+	in := reflect.ValueOf(pb)
+	if in.IsNil() {
+		return pb
+	}
+	return reflect.New(in.Type().Elem()).Interface().(Message)
+}
+
+func benchmarkUnmarshal(b *testing.B, pb Message, unmarshal func([]byte, Message) error) {
+	d, _ := Marshal(pb)
+	b.SetBytes(int64(len(d)))
+	pbd := newOf(pb)
+
+	b.ResetTimer()
+	for i := 0; i < b.N; i++ {
+		unmarshal(d, pbd)
+	}
+}
+
+func benchmarkBufferUnmarshal(b *testing.B, pb Message) {
+	p := NewBuffer(nil)
+	benchmarkUnmarshal(b, pb, func(d []byte, pb0 Message) error {
+		p.SetBuf(d)
+		return p.Unmarshal(pb0)
+	})
+}
+
+// Benchmark{Marshal,BufferMarshal,Size,Unmarshal,BufferUnmarshal}{,Bytes}
+
+func BenchmarkMarshal(b *testing.B) {
+	benchmarkMarshal(b, testMsg(), Marshal)
+}
+
+func BenchmarkBufferMarshal(b *testing.B) {
+	benchmarkBufferMarshal(b, testMsg())
+}
+
+func BenchmarkSize(b *testing.B) {
+	benchmarkSize(b, testMsg())
+}
+
+func BenchmarkUnmarshal(b *testing.B) {
+	benchmarkUnmarshal(b, testMsg(), Unmarshal)
+}
+
+func BenchmarkBufferUnmarshal(b *testing.B) {
+	benchmarkBufferUnmarshal(b, testMsg())
+}
+
+func BenchmarkMarshalBytes(b *testing.B) {
+	benchmarkMarshal(b, bytesMsg(), Marshal)
+}
+
+func BenchmarkBufferMarshalBytes(b *testing.B) {
+	benchmarkBufferMarshal(b, bytesMsg())
+}
+
+func BenchmarkSizeBytes(b *testing.B) {
+	benchmarkSize(b, bytesMsg())
+}
+
+func BenchmarkUnmarshalBytes(b *testing.B) {
+	benchmarkUnmarshal(b, bytesMsg(), Unmarshal)
+}
+
+func BenchmarkBufferUnmarshalBytes(b *testing.B) {
+	benchmarkBufferUnmarshal(b, bytesMsg())
+}
+
+func BenchmarkUnmarshalUnrecognizedFields(b *testing.B) {
+	b.StopTimer()
+	pb := initGoTestField()
+	skip := &GoSkipTest{
+		SkipInt32:   Int32(32),
+		SkipFixed32: Uint32(3232),
+		SkipFixed64: Uint64(6464),
+		SkipString:  String("skipper"),
+		Skipgroup: &GoSkipTest_SkipGroup{
+			GroupInt32:  Int32(75),
+			GroupString: String("wxyz"),
+		},
+	}
+
+	pbd := new(GoTestField)
+	p := NewBuffer(nil)
+	p.Marshal(pb)
+	p.Marshal(skip)
+	p2 := NewBuffer(nil)
+
+	b.StartTimer()
+	for i := 0; i < b.N; i++ {
+		p2.SetBuf(p.Bytes())
+		p2.Unmarshal(pbd)
+	}
+}

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

@@ -0,0 +1,197 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Protocol buffer deep copy and merge.
+// TODO: MessageSet and RawMessage.
+
+package proto
+
+import (
+	"log"
+	"reflect"
+	"strings"
+)
+
+// Clone returns a deep copy of a protocol buffer.
+func Clone(pb Message) Message {
+	in := reflect.ValueOf(pb)
+	if in.IsNil() {
+		return pb
+	}
+
+	out := reflect.New(in.Type().Elem())
+	// out is empty so a merge is a deep copy.
+	mergeStruct(out.Elem(), in.Elem())
+	return out.Interface().(Message)
+}
+
+// Merge merges src into dst.
+// Required and optional fields that are set in src will be set to that value in dst.
+// Elements of repeated fields will be appended.
+// Merge panics if src and dst are not the same type, or if dst is nil.
+func Merge(dst, src Message) {
+	in := reflect.ValueOf(src)
+	out := reflect.ValueOf(dst)
+	if out.IsNil() {
+		panic("proto: nil destination")
+	}
+	if in.Type() != out.Type() {
+		// Explicit test prior to mergeStruct so that mistyped nils will fail
+		panic("proto: type mismatch")
+	}
+	if in.IsNil() {
+		// Merging nil into non-nil is a quiet no-op
+		return
+	}
+	mergeStruct(out.Elem(), in.Elem())
+}
+
+func mergeStruct(out, in reflect.Value) {
+	for i := 0; i < in.NumField(); i++ {
+		f := in.Type().Field(i)
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		mergeAny(out.Field(i), in.Field(i))
+	}
+
+	if emIn, ok := in.Addr().Interface().(extendableProto); ok {
+		emOut := out.Addr().Interface().(extendableProto)
+		mergeExtension(emOut.ExtensionMap(), emIn.ExtensionMap())
+	}
+
+	uf := in.FieldByName("XXX_unrecognized")
+	if !uf.IsValid() {
+		return
+	}
+	uin := uf.Bytes()
+	if len(uin) > 0 {
+		out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...))
+	}
+}
+
+func mergeAny(out, in reflect.Value) {
+	if in.Type() == protoMessageType {
+		if !in.IsNil() {
+			if out.IsNil() {
+				out.Set(reflect.ValueOf(Clone(in.Interface().(Message))))
+			} else {
+				Merge(out.Interface().(Message), in.Interface().(Message))
+			}
+		}
+		return
+	}
+	switch in.Kind() {
+	case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
+		reflect.String, reflect.Uint32, reflect.Uint64:
+		out.Set(in)
+	case reflect.Map:
+		if in.Len() == 0 {
+			return
+		}
+		if out.IsNil() {
+			out.Set(reflect.MakeMap(in.Type()))
+		}
+		// For maps with value types of *T or []byte we need to deep copy each value.
+		elemKind := in.Type().Elem().Kind()
+		for _, key := range in.MapKeys() {
+			var val reflect.Value
+			switch elemKind {
+			case reflect.Ptr:
+				val = reflect.New(in.Type().Elem().Elem())
+				mergeAny(val, in.MapIndex(key))
+			case reflect.Slice:
+				val = in.MapIndex(key)
+				val = reflect.ValueOf(append([]byte{}, val.Bytes()...))
+			default:
+				val = in.MapIndex(key)
+			}
+			out.SetMapIndex(key, val)
+		}
+	case reflect.Ptr:
+		if in.IsNil() {
+			return
+		}
+		if out.IsNil() {
+			out.Set(reflect.New(in.Elem().Type()))
+		}
+		mergeAny(out.Elem(), in.Elem())
+	case reflect.Slice:
+		if in.IsNil() {
+			return
+		}
+		if in.Type().Elem().Kind() == reflect.Uint8 {
+			// []byte is a scalar bytes field, not a repeated field.
+			// Make a deep copy.
+			// Append to []byte{} instead of []byte(nil) so that we never end up
+			// with a nil result.
+			out.SetBytes(append([]byte{}, in.Bytes()...))
+			return
+		}
+		n := in.Len()
+		if out.IsNil() {
+			out.Set(reflect.MakeSlice(in.Type(), 0, n))
+		}
+		switch in.Type().Elem().Kind() {
+		case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64,
+			reflect.String, reflect.Uint32, reflect.Uint64:
+			out.Set(reflect.AppendSlice(out, in))
+		default:
+			for i := 0; i < n; i++ {
+				x := reflect.Indirect(reflect.New(in.Type().Elem()))
+				mergeAny(x, in.Index(i))
+				out.Set(reflect.Append(out, x))
+			}
+		}
+	case reflect.Struct:
+		mergeStruct(out, in)
+	default:
+		// unknown type, so not a protocol buffer
+		log.Printf("proto: don't know how to copy %v", in)
+	}
+}
+
+func mergeExtension(out, in map[int32]Extension) {
+	for extNum, eIn := range in {
+		eOut := Extension{desc: eIn.desc}
+		if eIn.value != nil {
+			v := reflect.New(reflect.TypeOf(eIn.value)).Elem()
+			mergeAny(v, reflect.ValueOf(eIn.value))
+			eOut.value = v.Interface()
+		}
+		if eIn.enc != nil {
+			eOut.enc = make([]byte, len(eIn.enc))
+			copy(eOut.enc, eIn.enc)
+		}
+
+		out[extNum] = eOut
+	}
+}

+ 227 - 0
vendor/src/github.com/golang/protobuf/proto/clone_test.go

@@ -0,0 +1,227 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto_test
+
+import (
+	"testing"
+
+	"github.com/golang/protobuf/proto"
+
+	pb "github.com/golang/protobuf/proto/testdata"
+)
+
+var cloneTestMessage = &pb.MyMessage{
+	Count: proto.Int32(42),
+	Name:  proto.String("Dave"),
+	Pet:   []string{"bunny", "kitty", "horsey"},
+	Inner: &pb.InnerMessage{
+		Host:      proto.String("niles"),
+		Port:      proto.Int32(9099),
+		Connected: proto.Bool(true),
+	},
+	Others: []*pb.OtherMessage{
+		{
+			Value: []byte("some bytes"),
+		},
+	},
+	Somegroup: &pb.MyMessage_SomeGroup{
+		GroupField: proto.Int32(6),
+	},
+	RepBytes: [][]byte{[]byte("sham"), []byte("wow")},
+}
+
+func init() {
+	ext := &pb.Ext{
+		Data: proto.String("extension"),
+	}
+	if err := proto.SetExtension(cloneTestMessage, pb.E_Ext_More, ext); err != nil {
+		panic("SetExtension: " + err.Error())
+	}
+}
+
+func TestClone(t *testing.T) {
+	m := proto.Clone(cloneTestMessage).(*pb.MyMessage)
+	if !proto.Equal(m, cloneTestMessage) {
+		t.Errorf("Clone(%v) = %v", cloneTestMessage, m)
+	}
+
+	// Verify it was a deep copy.
+	*m.Inner.Port++
+	if proto.Equal(m, cloneTestMessage) {
+		t.Error("Mutating clone changed the original")
+	}
+	// Byte fields and repeated fields should be copied.
+	if &m.Pet[0] == &cloneTestMessage.Pet[0] {
+		t.Error("Pet: repeated field not copied")
+	}
+	if &m.Others[0] == &cloneTestMessage.Others[0] {
+		t.Error("Others: repeated field not copied")
+	}
+	if &m.Others[0].Value[0] == &cloneTestMessage.Others[0].Value[0] {
+		t.Error("Others[0].Value: bytes field not copied")
+	}
+	if &m.RepBytes[0] == &cloneTestMessage.RepBytes[0] {
+		t.Error("RepBytes: repeated field not copied")
+	}
+	if &m.RepBytes[0][0] == &cloneTestMessage.RepBytes[0][0] {
+		t.Error("RepBytes[0]: bytes field not copied")
+	}
+}
+
+func TestCloneNil(t *testing.T) {
+	var m *pb.MyMessage
+	if c := proto.Clone(m); !proto.Equal(m, c) {
+		t.Errorf("Clone(%v) = %v", m, c)
+	}
+}
+
+var mergeTests = []struct {
+	src, dst, want proto.Message
+}{
+	{
+		src: &pb.MyMessage{
+			Count: proto.Int32(42),
+		},
+		dst: &pb.MyMessage{
+			Name: proto.String("Dave"),
+		},
+		want: &pb.MyMessage{
+			Count: proto.Int32(42),
+			Name:  proto.String("Dave"),
+		},
+	},
+	{
+		src: &pb.MyMessage{
+			Inner: &pb.InnerMessage{
+				Host:      proto.String("hey"),
+				Connected: proto.Bool(true),
+			},
+			Pet: []string{"horsey"},
+			Others: []*pb.OtherMessage{
+				{
+					Value: []byte("some bytes"),
+				},
+			},
+		},
+		dst: &pb.MyMessage{
+			Inner: &pb.InnerMessage{
+				Host: proto.String("niles"),
+				Port: proto.Int32(9099),
+			},
+			Pet: []string{"bunny", "kitty"},
+			Others: []*pb.OtherMessage{
+				{
+					Key: proto.Int64(31415926535),
+				},
+				{
+					// Explicitly test a src=nil field
+					Inner: nil,
+				},
+			},
+		},
+		want: &pb.MyMessage{
+			Inner: &pb.InnerMessage{
+				Host:      proto.String("hey"),
+				Connected: proto.Bool(true),
+				Port:      proto.Int32(9099),
+			},
+			Pet: []string{"bunny", "kitty", "horsey"},
+			Others: []*pb.OtherMessage{
+				{
+					Key: proto.Int64(31415926535),
+				},
+				{},
+				{
+					Value: []byte("some bytes"),
+				},
+			},
+		},
+	},
+	{
+		src: &pb.MyMessage{
+			RepBytes: [][]byte{[]byte("wow")},
+		},
+		dst: &pb.MyMessage{
+			Somegroup: &pb.MyMessage_SomeGroup{
+				GroupField: proto.Int32(6),
+			},
+			RepBytes: [][]byte{[]byte("sham")},
+		},
+		want: &pb.MyMessage{
+			Somegroup: &pb.MyMessage_SomeGroup{
+				GroupField: proto.Int32(6),
+			},
+			RepBytes: [][]byte{[]byte("sham"), []byte("wow")},
+		},
+	},
+	// Check that a scalar bytes field replaces rather than appends.
+	{
+		src:  &pb.OtherMessage{Value: []byte("foo")},
+		dst:  &pb.OtherMessage{Value: []byte("bar")},
+		want: &pb.OtherMessage{Value: []byte("foo")},
+	},
+	{
+		src: &pb.MessageWithMap{
+			NameMapping: map[int32]string{6: "Nigel"},
+			MsgMapping: map[int64]*pb.FloatingPoint{
+				0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)},
+			},
+			ByteMapping: map[bool][]byte{true: []byte("wowsa")},
+		},
+		dst: &pb.MessageWithMap{
+			NameMapping: map[int32]string{
+				6: "Bruce", // should be overwritten
+				7: "Andrew",
+			},
+		},
+		want: &pb.MessageWithMap{
+			NameMapping: map[int32]string{
+				6: "Nigel",
+				7: "Andrew",
+			},
+			MsgMapping: map[int64]*pb.FloatingPoint{
+				0x4001: &pb.FloatingPoint{F: proto.Float64(2.0)},
+			},
+			ByteMapping: map[bool][]byte{true: []byte("wowsa")},
+		},
+	},
+}
+
+func TestMerge(t *testing.T) {
+	for _, m := range mergeTests {
+		got := proto.Clone(m.dst)
+		proto.Merge(got, m.src)
+		if !proto.Equal(got, m.want) {
+			t.Errorf("Merge(%v, %v)\n got %v\nwant %v\n", m.dst, m.src, got, m.want)
+		}
+	}
+}

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

@@ -0,0 +1,821 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+/*
+ * Routines for decoding protocol buffer data to construct in-memory representations.
+ */
+
+import (
+	"errors"
+	"fmt"
+	"io"
+	"os"
+	"reflect"
+)
+
+// errOverflow is returned when an integer is too large to be represented.
+var errOverflow = errors.New("proto: integer overflow")
+
+// The fundamental decoders that interpret bytes on the wire.
+// Those that take integer types all return uint64 and are
+// therefore of type valueDecoder.
+
+// DecodeVarint reads a varint-encoded integer from the slice.
+// It returns the integer and the number of bytes consumed, or
+// zero if there is not enough.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func DecodeVarint(buf []byte) (x uint64, n int) {
+	// x, n already 0
+	for shift := uint(0); shift < 64; shift += 7 {
+		if n >= len(buf) {
+			return 0, 0
+		}
+		b := uint64(buf[n])
+		n++
+		x |= (b & 0x7F) << shift
+		if (b & 0x80) == 0 {
+			return x, n
+		}
+	}
+
+	// The number is too large to represent in a 64-bit value.
+	return 0, 0
+}
+
+// DecodeVarint reads a varint-encoded integer from the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (p *Buffer) DecodeVarint() (x uint64, err error) {
+	// x, err already 0
+
+	i := p.index
+	l := len(p.buf)
+
+	for shift := uint(0); shift < 64; shift += 7 {
+		if i >= l {
+			err = io.ErrUnexpectedEOF
+			return
+		}
+		b := p.buf[i]
+		i++
+		x |= (uint64(b) & 0x7F) << shift
+		if b < 0x80 {
+			p.index = i
+			return
+		}
+	}
+
+	// The number is too large to represent in a 64-bit value.
+	err = errOverflow
+	return
+}
+
+// DecodeFixed64 reads a 64-bit integer from the Buffer.
+// This is the format for the
+// fixed64, sfixed64, and double protocol buffer types.
+func (p *Buffer) DecodeFixed64() (x uint64, err error) {
+	// x, err already 0
+	i := p.index + 8
+	if i < 0 || i > len(p.buf) {
+		err = io.ErrUnexpectedEOF
+		return
+	}
+	p.index = i
+
+	x = uint64(p.buf[i-8])
+	x |= uint64(p.buf[i-7]) << 8
+	x |= uint64(p.buf[i-6]) << 16
+	x |= uint64(p.buf[i-5]) << 24
+	x |= uint64(p.buf[i-4]) << 32
+	x |= uint64(p.buf[i-3]) << 40
+	x |= uint64(p.buf[i-2]) << 48
+	x |= uint64(p.buf[i-1]) << 56
+	return
+}
+
+// DecodeFixed32 reads a 32-bit integer from the Buffer.
+// This is the format for the
+// fixed32, sfixed32, and float protocol buffer types.
+func (p *Buffer) DecodeFixed32() (x uint64, err error) {
+	// x, err already 0
+	i := p.index + 4
+	if i < 0 || i > len(p.buf) {
+		err = io.ErrUnexpectedEOF
+		return
+	}
+	p.index = i
+
+	x = uint64(p.buf[i-4])
+	x |= uint64(p.buf[i-3]) << 8
+	x |= uint64(p.buf[i-2]) << 16
+	x |= uint64(p.buf[i-1]) << 24
+	return
+}
+
+// DecodeZigzag64 reads a zigzag-encoded 64-bit integer
+// from the Buffer.
+// This is the format used for the sint64 protocol buffer type.
+func (p *Buffer) DecodeZigzag64() (x uint64, err error) {
+	x, err = p.DecodeVarint()
+	if err != nil {
+		return
+	}
+	x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63)
+	return
+}
+
+// DecodeZigzag32 reads a zigzag-encoded 32-bit integer
+// from  the Buffer.
+// This is the format used for the sint32 protocol buffer type.
+func (p *Buffer) DecodeZigzag32() (x uint64, err error) {
+	x, err = p.DecodeVarint()
+	if err != nil {
+		return
+	}
+	x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31))
+	return
+}
+
+// These are not ValueDecoders: they produce an array of bytes or a string.
+// bytes, embedded messages
+
+// DecodeRawBytes reads a count-delimited byte buffer from the Buffer.
+// This is the format used for the bytes protocol buffer
+// type and for embedded messages.
+func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) {
+	n, err := p.DecodeVarint()
+	if err != nil {
+		return nil, err
+	}
+
+	nb := int(n)
+	if nb < 0 {
+		return nil, fmt.Errorf("proto: bad byte length %d", nb)
+	}
+	end := p.index + nb
+	if end < p.index || end > len(p.buf) {
+		return nil, io.ErrUnexpectedEOF
+	}
+
+	if !alloc {
+		// todo: check if can get more uses of alloc=false
+		buf = p.buf[p.index:end]
+		p.index += nb
+		return
+	}
+
+	buf = make([]byte, nb)
+	copy(buf, p.buf[p.index:])
+	p.index += nb
+	return
+}
+
+// DecodeStringBytes reads an encoded string from the Buffer.
+// This is the format used for the proto2 string type.
+func (p *Buffer) DecodeStringBytes() (s string, err error) {
+	buf, err := p.DecodeRawBytes(false)
+	if err != nil {
+		return
+	}
+	return string(buf), nil
+}
+
+// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
+// If the protocol buffer has extensions, and the field matches, add it as an extension.
+// Otherwise, if the XXX_unrecognized field exists, append the skipped data there.
+func (o *Buffer) skipAndSave(t reflect.Type, tag, wire int, base structPointer, unrecField field) error {
+	oi := o.index
+
+	err := o.skip(t, tag, wire)
+	if err != nil {
+		return err
+	}
+
+	if !unrecField.IsValid() {
+		return nil
+	}
+
+	ptr := structPointer_Bytes(base, unrecField)
+
+	// Add the skipped field to struct field
+	obuf := o.buf
+
+	o.buf = *ptr
+	o.EncodeVarint(uint64(tag<<3 | wire))
+	*ptr = append(o.buf, obuf[oi:o.index]...)
+
+	o.buf = obuf
+
+	return nil
+}
+
+// Skip the next item in the buffer. Its wire type is decoded and presented as an argument.
+func (o *Buffer) skip(t reflect.Type, tag, wire int) error {
+
+	var u uint64
+	var err error
+
+	switch wire {
+	case WireVarint:
+		_, err = o.DecodeVarint()
+	case WireFixed64:
+		_, err = o.DecodeFixed64()
+	case WireBytes:
+		_, err = o.DecodeRawBytes(false)
+	case WireFixed32:
+		_, err = o.DecodeFixed32()
+	case WireStartGroup:
+		for {
+			u, err = o.DecodeVarint()
+			if err != nil {
+				break
+			}
+			fwire := int(u & 0x7)
+			if fwire == WireEndGroup {
+				break
+			}
+			ftag := int(u >> 3)
+			err = o.skip(t, ftag, fwire)
+			if err != nil {
+				break
+			}
+		}
+	default:
+		err = fmt.Errorf("proto: can't skip unknown wire type %d for %s", wire, t)
+	}
+	return err
+}
+
+// Unmarshaler is the interface representing objects that can
+// unmarshal themselves.  The method should reset the receiver before
+// decoding starts.  The argument points to data that may be
+// overwritten, so implementations should not keep references to the
+// buffer.
+type Unmarshaler interface {
+	Unmarshal([]byte) error
+}
+
+// Unmarshal parses the protocol buffer representation in buf and places the
+// decoded result in pb.  If the struct underlying pb does not match
+// the data in buf, the results can be unpredictable.
+//
+// Unmarshal resets pb before starting to unmarshal, so any
+// existing data in pb is always removed. Use UnmarshalMerge
+// to preserve and append to existing data.
+func Unmarshal(buf []byte, pb Message) error {
+	pb.Reset()
+	return UnmarshalMerge(buf, pb)
+}
+
+// UnmarshalMerge parses the protocol buffer representation in buf and
+// writes the decoded result to pb.  If the struct underlying pb does not match
+// the data in buf, the results can be unpredictable.
+//
+// UnmarshalMerge merges into existing data in pb.
+// Most code should use Unmarshal instead.
+func UnmarshalMerge(buf []byte, pb Message) error {
+	// If the object can unmarshal itself, let it.
+	if u, ok := pb.(Unmarshaler); ok {
+		return u.Unmarshal(buf)
+	}
+	return NewBuffer(buf).Unmarshal(pb)
+}
+
+// Unmarshal parses the protocol buffer representation in the
+// Buffer and places the decoded result in pb.  If the struct
+// underlying pb does not match the data in the buffer, the results can be
+// unpredictable.
+func (p *Buffer) Unmarshal(pb Message) error {
+	// If the object can unmarshal itself, let it.
+	if u, ok := pb.(Unmarshaler); ok {
+		err := u.Unmarshal(p.buf[p.index:])
+		p.index = len(p.buf)
+		return err
+	}
+
+	typ, base, err := getbase(pb)
+	if err != nil {
+		return err
+	}
+
+	err = p.unmarshalType(typ.Elem(), GetProperties(typ.Elem()), false, base)
+
+	if collectStats {
+		stats.Decode++
+	}
+
+	return err
+}
+
+// unmarshalType does the work of unmarshaling a structure.
+func (o *Buffer) unmarshalType(st reflect.Type, prop *StructProperties, is_group bool, base structPointer) error {
+	var state errorState
+	required, reqFields := prop.reqCount, uint64(0)
+
+	var err error
+	for err == nil && o.index < len(o.buf) {
+		oi := o.index
+		var u uint64
+		u, err = o.DecodeVarint()
+		if err != nil {
+			break
+		}
+		wire := int(u & 0x7)
+		if wire == WireEndGroup {
+			if is_group {
+				return nil // input is satisfied
+			}
+			return fmt.Errorf("proto: %s: wiretype end group for non-group", st)
+		}
+		tag := int(u >> 3)
+		if tag <= 0 {
+			return fmt.Errorf("proto: %s: illegal tag %d (wire type %d)", st, tag, wire)
+		}
+		fieldnum, ok := prop.decoderTags.get(tag)
+		if !ok {
+			// Maybe it's an extension?
+			if prop.extendable {
+				if e := structPointer_Interface(base, st).(extendableProto); isExtensionField(e, int32(tag)) {
+					if err = o.skip(st, tag, wire); err == nil {
+						ext := e.ExtensionMap()[int32(tag)] // may be missing
+						ext.enc = append(ext.enc, o.buf[oi:o.index]...)
+						e.ExtensionMap()[int32(tag)] = ext
+					}
+					continue
+				}
+			}
+			err = o.skipAndSave(st, tag, wire, base, prop.unrecField)
+			continue
+		}
+		p := prop.Prop[fieldnum]
+
+		if p.dec == nil {
+			fmt.Fprintf(os.Stderr, "proto: no protobuf decoder for %s.%s\n", st, st.Field(fieldnum).Name)
+			continue
+		}
+		dec := p.dec
+		if wire != WireStartGroup && wire != p.WireType {
+			if wire == WireBytes && p.packedDec != nil {
+				// a packable field
+				dec = p.packedDec
+			} else {
+				err = fmt.Errorf("proto: bad wiretype for field %s.%s: got wiretype %d, want %d", st, st.Field(fieldnum).Name, wire, p.WireType)
+				continue
+			}
+		}
+		decErr := dec(o, p, base)
+		if decErr != nil && !state.shouldContinue(decErr, p) {
+			err = decErr
+		}
+		if err == nil && p.Required {
+			// Successfully decoded a required field.
+			if tag <= 64 {
+				// use bitmap for fields 1-64 to catch field reuse.
+				var mask uint64 = 1 << uint64(tag-1)
+				if reqFields&mask == 0 {
+					// new required field
+					reqFields |= mask
+					required--
+				}
+			} else {
+				// This is imprecise. It can be fooled by a required field
+				// with a tag > 64 that is encoded twice; that's very rare.
+				// A fully correct implementation would require allocating
+				// a data structure, which we would like to avoid.
+				required--
+			}
+		}
+	}
+	if err == nil {
+		if is_group {
+			return io.ErrUnexpectedEOF
+		}
+		if state.err != nil {
+			return state.err
+		}
+		if required > 0 {
+			// Not enough information to determine the exact field. If we use extra
+			// CPU, we could determine the field only if the missing required field
+			// has a tag <= 64 and we check reqFields.
+			return &RequiredNotSetError{"{Unknown}"}
+		}
+	}
+	return err
+}
+
+// Individual type decoders
+// For each,
+//	u is the decoded value,
+//	v is a pointer to the field (pointer) in the struct
+
+// Sizes of the pools to allocate inside the Buffer.
+// The goal is modest amortization and allocation
+// on at least 16-byte boundaries.
+const (
+	boolPoolSize   = 16
+	uint32PoolSize = 8
+	uint64PoolSize = 4
+)
+
+// Decode a bool.
+func (o *Buffer) dec_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	if len(o.bools) == 0 {
+		o.bools = make([]bool, boolPoolSize)
+	}
+	o.bools[0] = u != 0
+	*structPointer_Bool(base, p.field) = &o.bools[0]
+	o.bools = o.bools[1:]
+	return nil
+}
+
+func (o *Buffer) dec_proto3_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	*structPointer_BoolVal(base, p.field) = u != 0
+	return nil
+}
+
+// Decode an int32.
+func (o *Buffer) dec_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word32_Set(structPointer_Word32(base, p.field), o, uint32(u))
+	return nil
+}
+
+func (o *Buffer) dec_proto3_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word32Val_Set(structPointer_Word32Val(base, p.field), uint32(u))
+	return nil
+}
+
+// Decode an int64.
+func (o *Buffer) dec_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word64_Set(structPointer_Word64(base, p.field), o, u)
+	return nil
+}
+
+func (o *Buffer) dec_proto3_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	word64Val_Set(structPointer_Word64Val(base, p.field), o, u)
+	return nil
+}
+
+// Decode a string.
+func (o *Buffer) dec_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	*structPointer_String(base, p.field) = &s
+	return nil
+}
+
+func (o *Buffer) dec_proto3_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	*structPointer_StringVal(base, p.field) = s
+	return nil
+}
+
+// Decode a slice of bytes ([]byte).
+func (o *Buffer) dec_slice_byte(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	*structPointer_Bytes(base, p.field) = b
+	return nil
+}
+
+// Decode a slice of bools ([]bool).
+func (o *Buffer) dec_slice_bool(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	v := structPointer_BoolSlice(base, p.field)
+	*v = append(*v, u != 0)
+	return nil
+}
+
+// Decode a slice of bools ([]bool) in packed format.
+func (o *Buffer) dec_slice_packed_bool(p *Properties, base structPointer) error {
+	v := structPointer_BoolSlice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded bools
+
+	y := *v
+	for i := 0; i < nb; i++ {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		y = append(y, u != 0)
+	}
+
+	*v = y
+	return nil
+}
+
+// Decode a slice of int32s ([]int32).
+func (o *Buffer) dec_slice_int32(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+	structPointer_Word32Slice(base, p.field).Append(uint32(u))
+	return nil
+}
+
+// Decode a slice of int32s ([]int32) in packed format.
+func (o *Buffer) dec_slice_packed_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Slice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded int32s
+
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
+	for o.index < fin {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		v.Append(uint32(u))
+	}
+	return nil
+}
+
+// Decode a slice of int64s ([]int64).
+func (o *Buffer) dec_slice_int64(p *Properties, base structPointer) error {
+	u, err := p.valDec(o)
+	if err != nil {
+		return err
+	}
+
+	structPointer_Word64Slice(base, p.field).Append(u)
+	return nil
+}
+
+// Decode a slice of int64s ([]int64) in packed format.
+func (o *Buffer) dec_slice_packed_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64Slice(base, p.field)
+
+	nn, err := o.DecodeVarint()
+	if err != nil {
+		return err
+	}
+	nb := int(nn) // number of bytes of encoded int64s
+
+	fin := o.index + nb
+	if fin < o.index {
+		return errOverflow
+	}
+	for o.index < fin {
+		u, err := p.valDec(o)
+		if err != nil {
+			return err
+		}
+		v.Append(u)
+	}
+	return nil
+}
+
+// Decode a slice of strings ([]string).
+func (o *Buffer) dec_slice_string(p *Properties, base structPointer) error {
+	s, err := o.DecodeStringBytes()
+	if err != nil {
+		return err
+	}
+	v := structPointer_StringSlice(base, p.field)
+	*v = append(*v, s)
+	return nil
+}
+
+// Decode a slice of slice of bytes ([][]byte).
+func (o *Buffer) dec_slice_slice_byte(p *Properties, base structPointer) error {
+	b, err := o.DecodeRawBytes(true)
+	if err != nil {
+		return err
+	}
+	v := structPointer_BytesSlice(base, p.field)
+	*v = append(*v, b)
+	return nil
+}
+
+// Decode a map field.
+func (o *Buffer) dec_new_map(p *Properties, base structPointer) error {
+	raw, err := o.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+	oi := o.index       // index at the end of this map entry
+	o.index -= len(raw) // move buffer back to start of map entry
+
+	mptr := structPointer_Map(base, p.field, p.mtype) // *map[K]V
+	if mptr.Elem().IsNil() {
+		mptr.Elem().Set(reflect.MakeMap(mptr.Type().Elem()))
+	}
+	v := mptr.Elem() // map[K]V
+
+	// Prepare addressable doubly-indirect placeholders for the key and value types.
+	// See enc_new_map for why.
+	keyptr := reflect.New(reflect.PtrTo(p.mtype.Key())).Elem() // addressable *K
+	keybase := toStructPointer(keyptr.Addr())                  // **K
+
+	var valbase structPointer
+	var valptr reflect.Value
+	switch p.mtype.Elem().Kind() {
+	case reflect.Slice:
+		// []byte
+		var dummy []byte
+		valptr = reflect.ValueOf(&dummy)  // *[]byte
+		valbase = toStructPointer(valptr) // *[]byte
+	case reflect.Ptr:
+		// message; valptr is **Msg; need to allocate the intermediate pointer
+		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
+		valptr.Set(reflect.New(valptr.Type().Elem()))
+		valbase = toStructPointer(valptr)
+	default:
+		// everything else
+		valptr = reflect.New(reflect.PtrTo(p.mtype.Elem())).Elem() // addressable *V
+		valbase = toStructPointer(valptr.Addr())                   // **V
+	}
+
+	// Decode.
+	// This parses a restricted wire format, namely the encoding of a message
+	// with two fields. See enc_new_map for the format.
+	for o.index < oi {
+		// tagcode for key and value properties are always a single byte
+		// because they have tags 1 and 2.
+		tagcode := o.buf[o.index]
+		o.index++
+		switch tagcode {
+		case p.mkeyprop.tagcode[0]:
+			if err := p.mkeyprop.dec(o, p.mkeyprop, keybase); err != nil {
+				return err
+			}
+		case p.mvalprop.tagcode[0]:
+			if err := p.mvalprop.dec(o, p.mvalprop, valbase); err != nil {
+				return err
+			}
+		default:
+			// TODO: Should we silently skip this instead?
+			return fmt.Errorf("proto: bad map data tag %d", raw[0])
+		}
+	}
+
+	v.SetMapIndex(keyptr.Elem(), valptr.Elem())
+	return nil
+}
+
+// Decode a group.
+func (o *Buffer) dec_struct_group(p *Properties, base structPointer) error {
+	bas := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(bas) {
+		// allocate new nested message
+		bas = toStructPointer(reflect.New(p.stype))
+		structPointer_SetStructPointer(base, p.field, bas)
+	}
+	return o.unmarshalType(p.stype, p.sprop, true, bas)
+}
+
+// Decode an embedded message.
+func (o *Buffer) dec_struct_message(p *Properties, base structPointer) (err error) {
+	raw, e := o.DecodeRawBytes(false)
+	if e != nil {
+		return e
+	}
+
+	bas := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(bas) {
+		// allocate new nested message
+		bas = toStructPointer(reflect.New(p.stype))
+		structPointer_SetStructPointer(base, p.field, bas)
+	}
+
+	// If the object can unmarshal itself, let it.
+	if p.isUnmarshaler {
+		iv := structPointer_Interface(bas, p.stype)
+		return iv.(Unmarshaler).Unmarshal(raw)
+	}
+
+	obuf := o.buf
+	oi := o.index
+	o.buf = raw
+	o.index = 0
+
+	err = o.unmarshalType(p.stype, p.sprop, false, bas)
+	o.buf = obuf
+	o.index = oi
+
+	return err
+}
+
+// Decode a slice of embedded messages.
+func (o *Buffer) dec_slice_struct_message(p *Properties, base structPointer) error {
+	return o.dec_slice_struct(p, false, base)
+}
+
+// Decode a slice of embedded groups.
+func (o *Buffer) dec_slice_struct_group(p *Properties, base structPointer) error {
+	return o.dec_slice_struct(p, true, base)
+}
+
+// Decode a slice of structs ([]*struct).
+func (o *Buffer) dec_slice_struct(p *Properties, is_group bool, base structPointer) error {
+	v := reflect.New(p.stype)
+	bas := toStructPointer(v)
+	structPointer_StructPointerSlice(base, p.field).Append(bas)
+
+	if is_group {
+		err := o.unmarshalType(p.stype, p.sprop, is_group, bas)
+		return err
+	}
+
+	raw, err := o.DecodeRawBytes(false)
+	if err != nil {
+		return err
+	}
+
+	// If the object can unmarshal itself, let it.
+	if p.isUnmarshaler {
+		iv := v.Interface()
+		return iv.(Unmarshaler).Unmarshal(raw)
+	}
+
+	obuf := o.buf
+	oi := o.index
+	o.buf = raw
+	o.index = 0
+
+	err = o.unmarshalType(p.stype, p.sprop, is_group, bas)
+
+	o.buf = obuf
+	o.index = oi
+
+	return err
+}

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

@@ -0,0 +1,1288 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+/*
+ * Routines for encoding data into the wire format for protocol buffers.
+ */
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"sort"
+)
+
+// RequiredNotSetError is the error returned if Marshal is called with
+// a protocol buffer struct whose required fields have not
+// all been initialized. It is also the error returned if Unmarshal is
+// called with an encoded protocol buffer that does not include all the
+// required fields.
+//
+// When printed, RequiredNotSetError reports the first unset required field in a
+// message. If the field cannot be precisely determined, it is reported as
+// "{Unknown}".
+type RequiredNotSetError struct {
+	field string
+}
+
+func (e *RequiredNotSetError) Error() string {
+	return fmt.Sprintf("proto: required field %q not set", e.field)
+}
+
+var (
+	// errRepeatedHasNil is the error returned if Marshal is called with
+	// a struct with a repeated field containing a nil element.
+	errRepeatedHasNil = errors.New("proto: repeated field has nil element")
+
+	// ErrNil is the error returned if Marshal is called with nil.
+	ErrNil = errors.New("proto: Marshal called with nil")
+)
+
+// The fundamental encoders that put bytes on the wire.
+// Those that take integer types all accept uint64 and are
+// therefore of type valueEncoder.
+
+const maxVarintBytes = 10 // maximum length of a varint
+
+// EncodeVarint returns the varint encoding of x.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+// Not used by the package itself, but helpful to clients
+// wishing to use the same encoding.
+func EncodeVarint(x uint64) []byte {
+	var buf [maxVarintBytes]byte
+	var n int
+	for n = 0; x > 127; n++ {
+		buf[n] = 0x80 | uint8(x&0x7F)
+		x >>= 7
+	}
+	buf[n] = uint8(x)
+	n++
+	return buf[0:n]
+}
+
+// EncodeVarint writes a varint-encoded integer to the Buffer.
+// This is the format for the
+// int32, int64, uint32, uint64, bool, and enum
+// protocol buffer types.
+func (p *Buffer) EncodeVarint(x uint64) error {
+	for x >= 1<<7 {
+		p.buf = append(p.buf, uint8(x&0x7f|0x80))
+		x >>= 7
+	}
+	p.buf = append(p.buf, uint8(x))
+	return nil
+}
+
+func sizeVarint(x uint64) (n int) {
+	for {
+		n++
+		x >>= 7
+		if x == 0 {
+			break
+		}
+	}
+	return n
+}
+
+// EncodeFixed64 writes a 64-bit integer to the Buffer.
+// This is the format for the
+// fixed64, sfixed64, and double protocol buffer types.
+func (p *Buffer) EncodeFixed64(x uint64) error {
+	p.buf = append(p.buf,
+		uint8(x),
+		uint8(x>>8),
+		uint8(x>>16),
+		uint8(x>>24),
+		uint8(x>>32),
+		uint8(x>>40),
+		uint8(x>>48),
+		uint8(x>>56))
+	return nil
+}
+
+func sizeFixed64(x uint64) int {
+	return 8
+}
+
+// EncodeFixed32 writes a 32-bit integer to the Buffer.
+// This is the format for the
+// fixed32, sfixed32, and float protocol buffer types.
+func (p *Buffer) EncodeFixed32(x uint64) error {
+	p.buf = append(p.buf,
+		uint8(x),
+		uint8(x>>8),
+		uint8(x>>16),
+		uint8(x>>24))
+	return nil
+}
+
+func sizeFixed32(x uint64) int {
+	return 4
+}
+
+// EncodeZigzag64 writes a zigzag-encoded 64-bit integer
+// to the Buffer.
+// This is the format used for the sint64 protocol buffer type.
+func (p *Buffer) EncodeZigzag64(x uint64) error {
+	// use signed number to get arithmetic right shift.
+	return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+
+func sizeZigzag64(x uint64) int {
+	return sizeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63))))
+}
+
+// EncodeZigzag32 writes a zigzag-encoded 32-bit integer
+// to the Buffer.
+// This is the format used for the sint32 protocol buffer type.
+func (p *Buffer) EncodeZigzag32(x uint64) error {
+	// use signed number to get arithmetic right shift.
+	return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
+}
+
+func sizeZigzag32(x uint64) int {
+	return sizeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31))))
+}
+
+// EncodeRawBytes writes a count-delimited byte buffer to the Buffer.
+// This is the format used for the bytes protocol buffer
+// type and for embedded messages.
+func (p *Buffer) EncodeRawBytes(b []byte) error {
+	p.EncodeVarint(uint64(len(b)))
+	p.buf = append(p.buf, b...)
+	return nil
+}
+
+func sizeRawBytes(b []byte) int {
+	return sizeVarint(uint64(len(b))) +
+		len(b)
+}
+
+// EncodeStringBytes writes an encoded string to the Buffer.
+// This is the format used for the proto2 string type.
+func (p *Buffer) EncodeStringBytes(s string) error {
+	p.EncodeVarint(uint64(len(s)))
+	p.buf = append(p.buf, s...)
+	return nil
+}
+
+func sizeStringBytes(s string) int {
+	return sizeVarint(uint64(len(s))) +
+		len(s)
+}
+
+// Marshaler is the interface representing objects that can marshal themselves.
+type Marshaler interface {
+	Marshal() ([]byte, error)
+}
+
+// Marshal takes the protocol buffer
+// and encodes it into the wire format, returning the data.
+func Marshal(pb Message) ([]byte, error) {
+	// Can the object marshal itself?
+	if m, ok := pb.(Marshaler); ok {
+		return m.Marshal()
+	}
+	p := NewBuffer(nil)
+	err := p.Marshal(pb)
+	var state errorState
+	if err != nil && !state.shouldContinue(err, nil) {
+		return nil, err
+	}
+	if p.buf == nil && err == nil {
+		// Return a non-nil slice on success.
+		return []byte{}, nil
+	}
+	return p.buf, err
+}
+
+// Marshal takes the protocol buffer
+// and encodes it into the wire format, writing the result to the
+// Buffer.
+func (p *Buffer) Marshal(pb Message) error {
+	// Can the object marshal itself?
+	if m, ok := pb.(Marshaler); ok {
+		data, err := m.Marshal()
+		if err != nil {
+			return err
+		}
+		p.buf = append(p.buf, data...)
+		return nil
+	}
+
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return ErrNil
+	}
+	if err == nil {
+		err = p.enc_struct(GetProperties(t.Elem()), base)
+	}
+
+	if collectStats {
+		stats.Encode++
+	}
+
+	return err
+}
+
+// Size returns the encoded size of a protocol buffer.
+func Size(pb Message) (n int) {
+	// Can the object marshal itself?  If so, Size is slow.
+	// TODO: add Size to Marshaler, or add a Sizer interface.
+	if m, ok := pb.(Marshaler); ok {
+		b, _ := m.Marshal()
+		return len(b)
+	}
+
+	t, base, err := getbase(pb)
+	if structPointer_IsNil(base) {
+		return 0
+	}
+	if err == nil {
+		n = size_struct(GetProperties(t.Elem()), base)
+	}
+
+	if collectStats {
+		stats.Size++
+	}
+
+	return
+}
+
+// Individual type encoders.
+
+// Encode a bool.
+func (o *Buffer) enc_bool(p *Properties, base structPointer) error {
+	v := *structPointer_Bool(base, p.field)
+	if v == nil {
+		return ErrNil
+	}
+	x := 0
+	if *v {
+		x = 1
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func (o *Buffer) enc_proto3_bool(p *Properties, base structPointer) error {
+	v := *structPointer_BoolVal(base, p.field)
+	if !v {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, 1)
+	return nil
+}
+
+func size_bool(p *Properties, base structPointer) int {
+	v := *structPointer_Bool(base, p.field)
+	if v == nil {
+		return 0
+	}
+	return len(p.tagcode) + 1 // each bool takes exactly one byte
+}
+
+func size_proto3_bool(p *Properties, base structPointer) int {
+	v := *structPointer_BoolVal(base, p.field)
+	if !v {
+		return 0
+	}
+	return len(p.tagcode) + 1 // each bool takes exactly one byte
+}
+
+// Encode an int32.
+func (o *Buffer) enc_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return ErrNil
+	}
+	x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func (o *Buffer) enc_proto3_int32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Val(base, p.field)
+	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
+	if x == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_int32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return 0
+	}
+	x := int32(word32_Get(v)) // permit sign extension to use full 64-bit range
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+func size_proto3_int32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32Val(base, p.field)
+	x := int32(word32Val_Get(v)) // permit sign extension to use full 64-bit range
+	if x == 0 {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+// Encode a uint32.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_uint32(p *Properties, base structPointer) error {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return ErrNil
+	}
+	x := word32_Get(v)
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func (o *Buffer) enc_proto3_uint32(p *Properties, base structPointer) error {
+	v := structPointer_Word32Val(base, p.field)
+	x := word32Val_Get(v)
+	if x == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, uint64(x))
+	return nil
+}
+
+func size_uint32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32(base, p.field)
+	if word32_IsNil(v) {
+		return 0
+	}
+	x := word32_Get(v)
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+func size_proto3_uint32(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word32Val(base, p.field)
+	x := word32Val_Get(v)
+	if x == 0 {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += p.valSize(uint64(x))
+	return
+}
+
+// Encode an int64.
+func (o *Buffer) enc_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64(base, p.field)
+	if word64_IsNil(v) {
+		return ErrNil
+	}
+	x := word64_Get(v)
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, x)
+	return nil
+}
+
+func (o *Buffer) enc_proto3_int64(p *Properties, base structPointer) error {
+	v := structPointer_Word64Val(base, p.field)
+	x := word64Val_Get(v)
+	if x == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	p.valEnc(o, x)
+	return nil
+}
+
+func size_int64(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word64(base, p.field)
+	if word64_IsNil(v) {
+		return 0
+	}
+	x := word64_Get(v)
+	n += len(p.tagcode)
+	n += p.valSize(x)
+	return
+}
+
+func size_proto3_int64(p *Properties, base structPointer) (n int) {
+	v := structPointer_Word64Val(base, p.field)
+	x := word64Val_Get(v)
+	if x == 0 {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += p.valSize(x)
+	return
+}
+
+// Encode a string.
+func (o *Buffer) enc_string(p *Properties, base structPointer) error {
+	v := *structPointer_String(base, p.field)
+	if v == nil {
+		return ErrNil
+	}
+	x := *v
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeStringBytes(x)
+	return nil
+}
+
+func (o *Buffer) enc_proto3_string(p *Properties, base structPointer) error {
+	v := *structPointer_StringVal(base, p.field)
+	if v == "" {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeStringBytes(v)
+	return nil
+}
+
+func size_string(p *Properties, base structPointer) (n int) {
+	v := *structPointer_String(base, p.field)
+	if v == nil {
+		return 0
+	}
+	x := *v
+	n += len(p.tagcode)
+	n += sizeStringBytes(x)
+	return
+}
+
+func size_proto3_string(p *Properties, base structPointer) (n int) {
+	v := *structPointer_StringVal(base, p.field)
+	if v == "" {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeStringBytes(v)
+	return
+}
+
+// All protocol buffer fields are nillable, but be careful.
+func isNil(v reflect.Value) bool {
+	switch v.Kind() {
+	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
+		return v.IsNil()
+	}
+	return false
+}
+
+// Encode a message struct.
+func (o *Buffer) enc_struct_message(p *Properties, base structPointer) error {
+	var state errorState
+	structp := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(structp) {
+		return ErrNil
+	}
+
+	// Can the object marshal itself?
+	if p.isMarshaler {
+		m := structPointer_Interface(structp, p.stype).(Marshaler)
+		data, err := m.Marshal()
+		if err != nil && !state.shouldContinue(err, nil) {
+			return err
+		}
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(data)
+		return nil
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	return o.enc_len_struct(p.sprop, structp, &state)
+}
+
+func size_struct_message(p *Properties, base structPointer) int {
+	structp := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(structp) {
+		return 0
+	}
+
+	// Can the object marshal itself?
+	if p.isMarshaler {
+		m := structPointer_Interface(structp, p.stype).(Marshaler)
+		data, _ := m.Marshal()
+		n0 := len(p.tagcode)
+		n1 := sizeRawBytes(data)
+		return n0 + n1
+	}
+
+	n0 := len(p.tagcode)
+	n1 := size_struct(p.sprop, structp)
+	n2 := sizeVarint(uint64(n1)) // size of encoded length
+	return n0 + n1 + n2
+}
+
+// Encode a group struct.
+func (o *Buffer) enc_struct_group(p *Properties, base structPointer) error {
+	var state errorState
+	b := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(b) {
+		return ErrNil
+	}
+
+	o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
+	err := o.enc_struct(p.sprop, b)
+	if err != nil && !state.shouldContinue(err, nil) {
+		return err
+	}
+	o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	return state.err
+}
+
+func size_struct_group(p *Properties, base structPointer) (n int) {
+	b := structPointer_GetStructPointer(base, p.field)
+	if structPointer_IsNil(b) {
+		return 0
+	}
+
+	n += sizeVarint(uint64((p.Tag << 3) | WireStartGroup))
+	n += size_struct(p.sprop, b)
+	n += sizeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	return
+}
+
+// Encode a slice of bools ([]bool).
+func (o *Buffer) enc_slice_bool(p *Properties, base structPointer) error {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return ErrNil
+	}
+	for _, x := range s {
+		o.buf = append(o.buf, p.tagcode...)
+		v := uint64(0)
+		if x {
+			v = 1
+		}
+		p.valEnc(o, v)
+	}
+	return nil
+}
+
+func size_slice_bool(p *Properties, base structPointer) int {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return 0
+	}
+	return l * (len(p.tagcode) + 1) // each bool takes exactly one byte
+}
+
+// Encode a slice of bools ([]bool) in packed format.
+func (o *Buffer) enc_slice_packed_bool(p *Properties, base structPointer) error {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(l)) // each bool takes exactly one byte
+	for _, x := range s {
+		v := uint64(0)
+		if x {
+			v = 1
+		}
+		p.valEnc(o, v)
+	}
+	return nil
+}
+
+func size_slice_packed_bool(p *Properties, base structPointer) (n int) {
+	s := *structPointer_BoolSlice(base, p.field)
+	l := len(s)
+	if l == 0 {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(l))
+	n += l // each bool takes exactly one byte
+	return
+}
+
+// Encode a slice of bytes ([]byte).
+func (o *Buffer) enc_slice_byte(p *Properties, base structPointer) error {
+	s := *structPointer_Bytes(base, p.field)
+	if s == nil {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(s)
+	return nil
+}
+
+func (o *Buffer) enc_proto3_slice_byte(p *Properties, base structPointer) error {
+	s := *structPointer_Bytes(base, p.field)
+	if len(s) == 0 {
+		return ErrNil
+	}
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeRawBytes(s)
+	return nil
+}
+
+func size_slice_byte(p *Properties, base structPointer) (n int) {
+	s := *structPointer_Bytes(base, p.field)
+	if s == nil {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeRawBytes(s)
+	return
+}
+
+func size_proto3_slice_byte(p *Properties, base structPointer) (n int) {
+	s := *structPointer_Bytes(base, p.field)
+	if len(s) == 0 {
+		return 0
+	}
+	n += len(p.tagcode)
+	n += sizeRawBytes(s)
+	return
+}
+
+// Encode a slice of int32s ([]int32).
+func (o *Buffer) enc_slice_int32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		p.valEnc(o, uint64(x))
+	}
+	return nil
+}
+
+func size_slice_int32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		n += p.valSize(uint64(x))
+	}
+	return
+}
+
+// Encode a slice of int32s ([]int32) in packed format.
+func (o *Buffer) enc_slice_packed_int32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		p.valEnc(buf, uint64(x))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_int32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		x := int32(s.Index(i)) // permit sign extension to use full 64-bit range
+		bufSize += p.valSize(uint64(x))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of uint32s ([]uint32).
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_uint32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		x := s.Index(i)
+		p.valEnc(o, uint64(x))
+	}
+	return nil
+}
+
+func size_slice_uint32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		x := s.Index(i)
+		n += p.valSize(uint64(x))
+	}
+	return
+}
+
+// Encode a slice of uint32s ([]uint32) in packed format.
+// Exactly the same as int32, except for no sign extension.
+func (o *Buffer) enc_slice_packed_uint32(p *Properties, base structPointer) error {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		p.valEnc(buf, uint64(s.Index(i)))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_uint32(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word32Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		bufSize += p.valSize(uint64(s.Index(i)))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of int64s ([]int64).
+func (o *Buffer) enc_slice_int64(p *Properties, base structPointer) error {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		p.valEnc(o, s.Index(i))
+	}
+	return nil
+}
+
+func size_slice_int64(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	for i := 0; i < l; i++ {
+		n += len(p.tagcode)
+		n += p.valSize(s.Index(i))
+	}
+	return
+}
+
+// Encode a slice of int64s ([]int64) in packed format.
+func (o *Buffer) enc_slice_packed_int64(p *Properties, base structPointer) error {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return ErrNil
+	}
+	// TODO: Reuse a Buffer.
+	buf := NewBuffer(nil)
+	for i := 0; i < l; i++ {
+		p.valEnc(buf, s.Index(i))
+	}
+
+	o.buf = append(o.buf, p.tagcode...)
+	o.EncodeVarint(uint64(len(buf.buf)))
+	o.buf = append(o.buf, buf.buf...)
+	return nil
+}
+
+func size_slice_packed_int64(p *Properties, base structPointer) (n int) {
+	s := structPointer_Word64Slice(base, p.field)
+	l := s.Len()
+	if l == 0 {
+		return 0
+	}
+	var bufSize int
+	for i := 0; i < l; i++ {
+		bufSize += p.valSize(s.Index(i))
+	}
+
+	n += len(p.tagcode)
+	n += sizeVarint(uint64(bufSize))
+	n += bufSize
+	return
+}
+
+// Encode a slice of slice of bytes ([][]byte).
+func (o *Buffer) enc_slice_slice_byte(p *Properties, base structPointer) error {
+	ss := *structPointer_BytesSlice(base, p.field)
+	l := len(ss)
+	if l == 0 {
+		return ErrNil
+	}
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeRawBytes(ss[i])
+	}
+	return nil
+}
+
+func size_slice_slice_byte(p *Properties, base structPointer) (n int) {
+	ss := *structPointer_BytesSlice(base, p.field)
+	l := len(ss)
+	if l == 0 {
+		return 0
+	}
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		n += sizeRawBytes(ss[i])
+	}
+	return
+}
+
+// Encode a slice of strings ([]string).
+func (o *Buffer) enc_slice_string(p *Properties, base structPointer) error {
+	ss := *structPointer_StringSlice(base, p.field)
+	l := len(ss)
+	for i := 0; i < l; i++ {
+		o.buf = append(o.buf, p.tagcode...)
+		o.EncodeStringBytes(ss[i])
+	}
+	return nil
+}
+
+func size_slice_string(p *Properties, base structPointer) (n int) {
+	ss := *structPointer_StringSlice(base, p.field)
+	l := len(ss)
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		n += sizeStringBytes(ss[i])
+	}
+	return
+}
+
+// Encode a slice of message structs ([]*struct).
+func (o *Buffer) enc_slice_struct_message(p *Properties, base structPointer) error {
+	var state errorState
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	for i := 0; i < l; i++ {
+		structp := s.Index(i)
+		if structPointer_IsNil(structp) {
+			return errRepeatedHasNil
+		}
+
+		// Can the object marshal itself?
+		if p.isMarshaler {
+			m := structPointer_Interface(structp, p.stype).(Marshaler)
+			data, err := m.Marshal()
+			if err != nil && !state.shouldContinue(err, nil) {
+				return err
+			}
+			o.buf = append(o.buf, p.tagcode...)
+			o.EncodeRawBytes(data)
+			continue
+		}
+
+		o.buf = append(o.buf, p.tagcode...)
+		err := o.enc_len_struct(p.sprop, structp, &state)
+		if err != nil && !state.shouldContinue(err, nil) {
+			if err == ErrNil {
+				return errRepeatedHasNil
+			}
+			return err
+		}
+	}
+	return state.err
+}
+
+func size_slice_struct_message(p *Properties, base structPointer) (n int) {
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+	n += l * len(p.tagcode)
+	for i := 0; i < l; i++ {
+		structp := s.Index(i)
+		if structPointer_IsNil(structp) {
+			return // return the size up to this point
+		}
+
+		// Can the object marshal itself?
+		if p.isMarshaler {
+			m := structPointer_Interface(structp, p.stype).(Marshaler)
+			data, _ := m.Marshal()
+			n += len(p.tagcode)
+			n += sizeRawBytes(data)
+			continue
+		}
+
+		n0 := size_struct(p.sprop, structp)
+		n1 := sizeVarint(uint64(n0)) // size of encoded length
+		n += n0 + n1
+	}
+	return
+}
+
+// Encode a slice of group structs ([]*struct).
+func (o *Buffer) enc_slice_struct_group(p *Properties, base structPointer) error {
+	var state errorState
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	for i := 0; i < l; i++ {
+		b := s.Index(i)
+		if structPointer_IsNil(b) {
+			return errRepeatedHasNil
+		}
+
+		o.EncodeVarint(uint64((p.Tag << 3) | WireStartGroup))
+
+		err := o.enc_struct(p.sprop, b)
+
+		if err != nil && !state.shouldContinue(err, nil) {
+			if err == ErrNil {
+				return errRepeatedHasNil
+			}
+			return err
+		}
+
+		o.EncodeVarint(uint64((p.Tag << 3) | WireEndGroup))
+	}
+	return state.err
+}
+
+func size_slice_struct_group(p *Properties, base structPointer) (n int) {
+	s := structPointer_StructPointerSlice(base, p.field)
+	l := s.Len()
+
+	n += l * sizeVarint(uint64((p.Tag<<3)|WireStartGroup))
+	n += l * sizeVarint(uint64((p.Tag<<3)|WireEndGroup))
+	for i := 0; i < l; i++ {
+		b := s.Index(i)
+		if structPointer_IsNil(b) {
+			return // return size up to this point
+		}
+
+		n += size_struct(p.sprop, b)
+	}
+	return
+}
+
+// Encode an extension map.
+func (o *Buffer) enc_map(p *Properties, base structPointer) error {
+	v := *structPointer_ExtMap(base, p.field)
+	if err := encodeExtensionMap(v); err != nil {
+		return err
+	}
+	// Fast-path for common cases: zero or one extensions.
+	if len(v) <= 1 {
+		for _, e := range v {
+			o.buf = append(o.buf, e.enc...)
+		}
+		return nil
+	}
+
+	// Sort keys to provide a deterministic encoding.
+	keys := make([]int, 0, len(v))
+	for k := range v {
+		keys = append(keys, int(k))
+	}
+	sort.Ints(keys)
+
+	for _, k := range keys {
+		o.buf = append(o.buf, v[int32(k)].enc...)
+	}
+	return nil
+}
+
+func size_map(p *Properties, base structPointer) int {
+	v := *structPointer_ExtMap(base, p.field)
+	return sizeExtensionMap(v)
+}
+
+// Encode a map field.
+func (o *Buffer) enc_new_map(p *Properties, base structPointer) error {
+	var state errorState // XXX: or do we need to plumb this through?
+
+	/*
+		A map defined as
+			map<key_type, value_type> map_field = N;
+		is encoded in the same way as
+			message MapFieldEntry {
+				key_type key = 1;
+				value_type value = 2;
+			}
+			repeated MapFieldEntry map_field = N;
+	*/
+
+	v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
+	if v.Len() == 0 {
+		return nil
+	}
+
+	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
+
+	enc := func() error {
+		if err := p.mkeyprop.enc(o, p.mkeyprop, keybase); err != nil {
+			return err
+		}
+		if err := p.mvalprop.enc(o, p.mvalprop, valbase); err != nil {
+			return err
+		}
+		return nil
+	}
+
+	keys := v.MapKeys()
+	sort.Sort(mapKeys(keys))
+	for _, key := range keys {
+		val := v.MapIndex(key)
+
+		keycopy.Set(key)
+		valcopy.Set(val)
+
+		o.buf = append(o.buf, p.tagcode...)
+		if err := o.enc_len_thing(enc, &state); err != nil {
+			return err
+		}
+	}
+	return nil
+}
+
+func size_new_map(p *Properties, base structPointer) int {
+	v := structPointer_Map(base, p.field, p.mtype).Elem() // map[K]V
+
+	keycopy, valcopy, keybase, valbase := mapEncodeScratch(p.mtype)
+
+	n := 0
+	for _, key := range v.MapKeys() {
+		val := v.MapIndex(key)
+		keycopy.Set(key)
+		valcopy.Set(val)
+
+		// Tag codes 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
+				}
+			}
+		}
+	}
+
+	// Add unrecognized fields at the end.
+	if prop.unrecField.IsValid() {
+		v := *structPointer_Bytes(base, prop.unrecField)
+		if len(v) > 0 {
+			o.buf = append(o.buf, v...)
+		}
+	}
+
+	return state.err
+}
+
+func size_struct(prop *StructProperties, base structPointer) (n int) {
+	for _, i := range prop.order {
+		p := prop.Prop[i]
+		if p.size != nil {
+			n += p.size(p, base)
+		}
+	}
+
+	// Add unrecognized fields at the end.
+	if prop.unrecField.IsValid() {
+		v := *structPointer_Bytes(base, prop.unrecField)
+		n += len(v)
+	}
+
+	return
+}
+
+var zeroes [20]byte // longer than any conceivable sizeVarint
+
+// Encode a struct, preceded by its encoded length (as a varint).
+func (o *Buffer) enc_len_struct(prop *StructProperties, base structPointer, state *errorState) error {
+	return o.enc_len_thing(func() error { return o.enc_struct(prop, base) }, state)
+}
+
+// Encode something, preceded by its encoded length (as a varint).
+func (o *Buffer) enc_len_thing(enc func() error, state *errorState) error {
+	iLen := len(o.buf)
+	o.buf = append(o.buf, 0, 0, 0, 0) // reserve four bytes for length
+	iMsg := len(o.buf)
+	err := enc()
+	if err != nil && !state.shouldContinue(err, nil) {
+		return err
+	}
+	lMsg := len(o.buf) - iMsg
+	lLen := sizeVarint(uint64(lMsg))
+	switch x := lLen - (iMsg - iLen); {
+	case x > 0: // actual length is x bytes larger than the space we reserved
+		// Move msg x bytes right.
+		o.buf = append(o.buf, zeroes[:x]...)
+		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
+	case x < 0: // actual length is x bytes smaller than the space we reserved
+		// Move msg x bytes left.
+		copy(o.buf[iMsg+x:], o.buf[iMsg:iMsg+lMsg])
+		o.buf = o.buf[:len(o.buf)+x] // x is negative
+	}
+	// Encode the length in the reserved space.
+	o.buf = o.buf[:iLen]
+	o.EncodeVarint(uint64(lMsg))
+	o.buf = o.buf[:len(o.buf)+lMsg]
+	return state.err
+}
+
+// errorState maintains the first error that occurs and updates that error
+// with additional context.
+type errorState struct {
+	err error
+}
+
+// shouldContinue reports whether encoding should continue upon encountering the
+// given error. If the error is RequiredNotSetError, shouldContinue returns true
+// and, if this is the first appearance of that error, remembers it for future
+// reporting.
+//
+// If prop is not nil, it may update any error with additional context about the
+// field with the error.
+func (s *errorState) shouldContinue(err error, prop *Properties) bool {
+	// Ignore unset required fields.
+	reqNotSet, ok := err.(*RequiredNotSetError)
+	if !ok {
+		return false
+	}
+	if s.err == nil {
+		if prop != nil {
+			err = &RequiredNotSetError{prop.Name + "." + reqNotSet.field}
+		}
+		s.err = err
+	}
+	return true
+}

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

@@ -0,0 +1,256 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Protocol buffer comparison.
+// TODO: MessageSet.
+
+package proto
+
+import (
+	"bytes"
+	"log"
+	"reflect"
+	"strings"
+)
+
+/*
+Equal returns true iff protocol buffers a and b are equal.
+The arguments must both be pointers to protocol buffer structs.
+
+Equality is defined in this way:
+  - Two messages are equal iff they are the same type,
+    corresponding fields are equal, unknown field sets
+    are equal, and extensions sets are equal.
+  - Two set scalar fields are equal iff their values are equal.
+    If the fields are of a floating-point type, remember that
+    NaN != x for all x, including NaN.
+  - Two repeated fields are equal iff their lengths are the same,
+    and their corresponding elements are equal (a "bytes" field,
+    although represented by []byte, is not a repeated field)
+  - Two unset fields are equal.
+  - Two unknown field sets are equal if their current
+    encoded state is equal.
+  - Two extension sets are equal iff they have corresponding
+    elements that are pairwise equal.
+  - Every other combination of things are not equal.
+
+The return value is undefined if a and b are not protocol buffers.
+*/
+func Equal(a, b Message) bool {
+	if a == nil || b == nil {
+		return a == b
+	}
+	v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b)
+	if v1.Type() != v2.Type() {
+		return false
+	}
+	if v1.Kind() == reflect.Ptr {
+		if v1.IsNil() {
+			return v2.IsNil()
+		}
+		if v2.IsNil() {
+			return false
+		}
+		v1, v2 = v1.Elem(), v2.Elem()
+	}
+	if v1.Kind() != reflect.Struct {
+		return false
+	}
+	return equalStruct(v1, v2)
+}
+
+// v1 and v2 are known to have the same type.
+func equalStruct(v1, v2 reflect.Value) bool {
+	for i := 0; i < v1.NumField(); i++ {
+		f := v1.Type().Field(i)
+		if strings.HasPrefix(f.Name, "XXX_") {
+			continue
+		}
+		f1, f2 := v1.Field(i), v2.Field(i)
+		if f.Type.Kind() == reflect.Ptr {
+			if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 {
+				// both unset
+				continue
+			} else if n1 != n2 {
+				// set/unset mismatch
+				return false
+			}
+			b1, ok := f1.Interface().(raw)
+			if ok {
+				b2 := f2.Interface().(raw)
+				// RawMessage
+				if !bytes.Equal(b1.Bytes(), b2.Bytes()) {
+					return false
+				}
+				continue
+			}
+			f1, f2 = f1.Elem(), f2.Elem()
+		}
+		if !equalAny(f1, f2) {
+			return false
+		}
+	}
+
+	if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() {
+		em2 := v2.FieldByName("XXX_extensions")
+		if !equalExtensions(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) {
+			return false
+		}
+	}
+
+	uf := v1.FieldByName("XXX_unrecognized")
+	if !uf.IsValid() {
+		return true
+	}
+
+	u1 := uf.Bytes()
+	u2 := v2.FieldByName("XXX_unrecognized").Bytes()
+	if !bytes.Equal(u1, u2) {
+		return false
+	}
+
+	return true
+}
+
+// v1 and v2 are known to have the same type.
+func equalAny(v1, v2 reflect.Value) bool {
+	if v1.Type() == protoMessageType {
+		m1, _ := v1.Interface().(Message)
+		m2, _ := v2.Interface().(Message)
+		return Equal(m1, m2)
+	}
+	switch v1.Kind() {
+	case reflect.Bool:
+		return v1.Bool() == v2.Bool()
+	case reflect.Float32, reflect.Float64:
+		return v1.Float() == v2.Float()
+	case reflect.Int32, reflect.Int64:
+		return v1.Int() == v2.Int()
+	case reflect.Map:
+		if v1.Len() != v2.Len() {
+			return false
+		}
+		for _, key := range v1.MapKeys() {
+			val2 := v2.MapIndex(key)
+			if !val2.IsValid() {
+				// This key was not found in the second map.
+				return false
+			}
+			if !equalAny(v1.MapIndex(key), val2) {
+				return false
+			}
+		}
+		return true
+	case reflect.Ptr:
+		return equalAny(v1.Elem(), v2.Elem())
+	case reflect.Slice:
+		if v1.Type().Elem().Kind() == reflect.Uint8 {
+			// short circuit: []byte
+			if v1.IsNil() != v2.IsNil() {
+				return false
+			}
+			return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte))
+		}
+
+		if v1.Len() != v2.Len() {
+			return false
+		}
+		for i := 0; i < v1.Len(); i++ {
+			if !equalAny(v1.Index(i), v2.Index(i)) {
+				return false
+			}
+		}
+		return true
+	case reflect.String:
+		return v1.Interface().(string) == v2.Interface().(string)
+	case reflect.Struct:
+		return equalStruct(v1, v2)
+	case reflect.Uint32, reflect.Uint64:
+		return v1.Uint() == v2.Uint()
+	}
+
+	// unknown type, so not a protocol buffer
+	log.Printf("proto: don't know how to compare %v", v1)
+	return false
+}
+
+// base is the struct type that the extensions are based on.
+// em1 and em2 are extension maps.
+func equalExtensions(base reflect.Type, em1, em2 map[int32]Extension) bool {
+	if len(em1) != len(em2) {
+		return false
+	}
+
+	for extNum, e1 := range em1 {
+		e2, ok := em2[extNum]
+		if !ok {
+			return false
+		}
+
+		m1, m2 := e1.value, e2.value
+
+		if m1 != nil && m2 != nil {
+			// Both are unencoded.
+			if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) {
+				return false
+			}
+			continue
+		}
+
+		// At least one is encoded. To do a semantically correct comparison
+		// we need to unmarshal them first.
+		var desc *ExtensionDesc
+		if m := extensionMaps[base]; m != nil {
+			desc = m[extNum]
+		}
+		if desc == nil {
+			log.Printf("proto: don't know how to compare extension %d of %v", extNum, base)
+			continue
+		}
+		var err error
+		if m1 == nil {
+			m1, err = decodeExtension(e1.enc, desc)
+		}
+		if m2 == nil && err == nil {
+			m2, err = decodeExtension(e2.enc, desc)
+		}
+		if err != nil {
+			// The encoded form is invalid.
+			log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err)
+			return false
+		}
+		if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2)) {
+			return false
+		}
+	}
+
+	return true
+}

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

@@ -0,0 +1,191 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2011 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto_test
+
+import (
+	"testing"
+
+	. "github.com/golang/protobuf/proto"
+	pb "github.com/golang/protobuf/proto/testdata"
+)
+
+// Four identical base messages.
+// The init function adds extensions to some of them.
+var messageWithoutExtension = &pb.MyMessage{Count: Int32(7)}
+var messageWithExtension1a = &pb.MyMessage{Count: Int32(7)}
+var messageWithExtension1b = &pb.MyMessage{Count: Int32(7)}
+var messageWithExtension2 = &pb.MyMessage{Count: Int32(7)}
+
+// Two messages with non-message extensions.
+var messageWithInt32Extension1 = &pb.MyMessage{Count: Int32(8)}
+var messageWithInt32Extension2 = &pb.MyMessage{Count: Int32(8)}
+
+func init() {
+	ext1 := &pb.Ext{Data: String("Kirk")}
+	ext2 := &pb.Ext{Data: String("Picard")}
+
+	// messageWithExtension1a has ext1, but never marshals it.
+	if err := SetExtension(messageWithExtension1a, pb.E_Ext_More, ext1); err != nil {
+		panic("SetExtension on 1a failed: " + err.Error())
+	}
+
+	// messageWithExtension1b is the unmarshaled form of messageWithExtension1a.
+	if err := SetExtension(messageWithExtension1b, pb.E_Ext_More, ext1); err != nil {
+		panic("SetExtension on 1b failed: " + err.Error())
+	}
+	buf, err := Marshal(messageWithExtension1b)
+	if err != nil {
+		panic("Marshal of 1b failed: " + err.Error())
+	}
+	messageWithExtension1b.Reset()
+	if err := Unmarshal(buf, messageWithExtension1b); err != nil {
+		panic("Unmarshal of 1b failed: " + err.Error())
+	}
+
+	// messageWithExtension2 has ext2.
+	if err := SetExtension(messageWithExtension2, pb.E_Ext_More, ext2); err != nil {
+		panic("SetExtension on 2 failed: " + err.Error())
+	}
+
+	if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(23)); err != nil {
+		panic("SetExtension on Int32-1 failed: " + err.Error())
+	}
+	if err := SetExtension(messageWithInt32Extension1, pb.E_Ext_Number, Int32(24)); err != nil {
+		panic("SetExtension on Int32-2 failed: " + err.Error())
+	}
+}
+
+var EqualTests = []struct {
+	desc string
+	a, b Message
+	exp  bool
+}{
+	{"different types", &pb.GoEnum{}, &pb.GoTestField{}, false},
+	{"equal empty", &pb.GoEnum{}, &pb.GoEnum{}, true},
+	{"nil vs nil", nil, nil, true},
+	{"typed nil vs typed nil", (*pb.GoEnum)(nil), (*pb.GoEnum)(nil), true},
+	{"typed nil vs empty", (*pb.GoEnum)(nil), &pb.GoEnum{}, false},
+	{"different typed nil", (*pb.GoEnum)(nil), (*pb.GoTestField)(nil), false},
+
+	{"one set field, one unset field", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{}, false},
+	{"one set field zero, one unset field", &pb.GoTest{Param: Int32(0)}, &pb.GoTest{}, false},
+	{"different set fields", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("bar")}, false},
+	{"equal set", &pb.GoTestField{Label: String("foo")}, &pb.GoTestField{Label: String("foo")}, true},
+
+	{"repeated, one set", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{}, false},
+	{"repeated, different length", &pb.GoTest{F_Int32Repeated: []int32{2, 3}}, &pb.GoTest{F_Int32Repeated: []int32{2}}, false},
+	{"repeated, different value", &pb.GoTest{F_Int32Repeated: []int32{2}}, &pb.GoTest{F_Int32Repeated: []int32{3}}, false},
+	{"repeated, equal", &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, &pb.GoTest{F_Int32Repeated: []int32{2, 4}}, true},
+	{"repeated, nil equal nil", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: nil}, true},
+	{"repeated, nil equal empty", &pb.GoTest{F_Int32Repeated: nil}, &pb.GoTest{F_Int32Repeated: []int32{}}, true},
+	{"repeated, empty equal nil", &pb.GoTest{F_Int32Repeated: []int32{}}, &pb.GoTest{F_Int32Repeated: nil}, true},
+
+	{
+		"nested, different",
+		&pb.GoTest{RequiredField: &pb.GoTestField{Label: String("foo")}},
+		&pb.GoTest{RequiredField: &pb.GoTestField{Label: String("bar")}},
+		false,
+	},
+	{
+		"nested, equal",
+		&pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}},
+		&pb.GoTest{RequiredField: &pb.GoTestField{Label: String("wow")}},
+		true,
+	},
+
+	{"bytes", &pb.OtherMessage{Value: []byte("foo")}, &pb.OtherMessage{Value: []byte("foo")}, true},
+	{"bytes, empty", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: []byte{}}, true},
+	{"bytes, empty vs nil", &pb.OtherMessage{Value: []byte{}}, &pb.OtherMessage{Value: nil}, false},
+	{
+		"repeated bytes",
+		&pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}},
+		&pb.MyMessage{RepBytes: [][]byte{[]byte("sham"), []byte("wow")}},
+		true,
+	},
+
+	{"extension vs. no extension", messageWithoutExtension, messageWithExtension1a, false},
+	{"extension vs. same extension", messageWithExtension1a, messageWithExtension1b, true},
+	{"extension vs. different extension", messageWithExtension1a, messageWithExtension2, false},
+
+	{"int32 extension vs. itself", messageWithInt32Extension1, messageWithInt32Extension1, true},
+	{"int32 extension vs. a different int32", messageWithInt32Extension1, messageWithInt32Extension2, false},
+
+	{
+		"message with group",
+		&pb.MyMessage{
+			Count: Int32(1),
+			Somegroup: &pb.MyMessage_SomeGroup{
+				GroupField: Int32(5),
+			},
+		},
+		&pb.MyMessage{
+			Count: Int32(1),
+			Somegroup: &pb.MyMessage_SomeGroup{
+				GroupField: Int32(5),
+			},
+		},
+		true,
+	},
+
+	{
+		"map same",
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
+		true,
+	},
+	{
+		"map different entry",
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
+		&pb.MessageWithMap{NameMapping: map[int32]string{2: "Rob"}},
+		false,
+	},
+	{
+		"map different key only",
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
+		&pb.MessageWithMap{NameMapping: map[int32]string{2: "Ken"}},
+		false,
+	},
+	{
+		"map different value only",
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Ken"}},
+		&pb.MessageWithMap{NameMapping: map[int32]string{1: "Rob"}},
+		false,
+	},
+}
+
+func TestEqual(t *testing.T) {
+	for _, tc := range EqualTests {
+		if res := Equal(tc.a, tc.b); res != tc.exp {
+			t.Errorf("%v: Equal(%v, %v) = %v, want %v", tc.desc, tc.a, tc.b, res, tc.exp)
+		}
+	}
+}

+ 362 - 0
vendor/src/github.com/golang/protobuf/proto/extensions.go

@@ -0,0 +1,362 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+/*
+ * Types and routines for supporting protocol buffer extensions.
+ */
+
+import (
+	"errors"
+	"fmt"
+	"reflect"
+	"strconv"
+	"sync"
+)
+
+// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message.
+var ErrMissingExtension = errors.New("proto: missing extension")
+
+// ExtensionRange represents a range of message extensions for a protocol buffer.
+// Used in code generated by the protocol compiler.
+type ExtensionRange struct {
+	Start, End int32 // both inclusive
+}
+
+// extendableProto is an interface implemented by any protocol buffer that may be extended.
+type extendableProto interface {
+	Message
+	ExtensionRangeArray() []ExtensionRange
+	ExtensionMap() map[int32]Extension
+}
+
+var extendableProtoType = reflect.TypeOf((*extendableProto)(nil)).Elem()
+
+// ExtensionDesc represents an extension specification.
+// Used in generated code from the protocol compiler.
+type ExtensionDesc struct {
+	ExtendedType  Message     // nil pointer to the type that is being extended
+	ExtensionType interface{} // nil pointer to the extension type
+	Field         int32       // field number
+	Name          string      // fully-qualified name of extension, for text formatting
+	Tag           string      // protobuf tag style
+}
+
+func (ed *ExtensionDesc) repeated() bool {
+	t := reflect.TypeOf(ed.ExtensionType)
+	return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8
+}
+
+// Extension represents an extension in a message.
+type Extension struct {
+	// When an extension is stored in a message using SetExtension
+	// only desc and value are set. When the message is marshaled
+	// enc will be set to the encoded form of the message.
+	//
+	// When a message is unmarshaled and contains extensions, each
+	// extension will have only enc set. When such an extension is
+	// accessed using GetExtension (or GetExtensions) desc and value
+	// will be set.
+	desc  *ExtensionDesc
+	value interface{}
+	enc   []byte
+}
+
+// SetRawExtension is for testing only.
+func SetRawExtension(base extendableProto, id int32, b []byte) {
+	base.ExtensionMap()[id] = Extension{enc: b}
+}
+
+// isExtensionField returns true iff the given field number is in an extension range.
+func isExtensionField(pb extendableProto, field int32) bool {
+	for _, er := range pb.ExtensionRangeArray() {
+		if er.Start <= field && field <= er.End {
+			return true
+		}
+	}
+	return false
+}
+
+// checkExtensionTypes checks that the given extension is valid for pb.
+func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error {
+	// Check the extended type.
+	if a, b := reflect.TypeOf(pb), reflect.TypeOf(extension.ExtendedType); a != b {
+		return errors.New("proto: bad extended type; " + b.String() + " does not extend " + a.String())
+	}
+	// Check the range.
+	if !isExtensionField(pb, extension.Field) {
+		return errors.New("proto: bad extension number; not in declared ranges")
+	}
+	return nil
+}
+
+// extPropKey is sufficient to uniquely identify an extension.
+type extPropKey struct {
+	base  reflect.Type
+	field int32
+}
+
+var extProp = struct {
+	sync.RWMutex
+	m map[extPropKey]*Properties
+}{
+	m: make(map[extPropKey]*Properties),
+}
+
+func extensionProperties(ed *ExtensionDesc) *Properties {
+	key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field}
+
+	extProp.RLock()
+	if prop, ok := extProp.m[key]; ok {
+		extProp.RUnlock()
+		return prop
+	}
+	extProp.RUnlock()
+
+	extProp.Lock()
+	defer extProp.Unlock()
+	// Check again.
+	if prop, ok := extProp.m[key]; ok {
+		return prop
+	}
+
+	prop := new(Properties)
+	prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil)
+	extProp.m[key] = prop
+	return prop
+}
+
+// encodeExtensionMap encodes any unmarshaled (unencoded) extensions in m.
+func encodeExtensionMap(m map[int32]Extension) error {
+	for k, e := range m {
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		et := reflect.TypeOf(e.desc.ExtensionType)
+		props := extensionProperties(e.desc)
+
+		p := NewBuffer(nil)
+		// If e.value has type T, the encoder expects a *struct{ X T }.
+		// Pass a *T with a zero field and hope it all works out.
+		x := reflect.New(et)
+		x.Elem().Set(reflect.ValueOf(e.value))
+		if err := props.enc(p, props, toStructPointer(x)); err != nil {
+			return err
+		}
+		e.enc = p.buf
+		m[k] = e
+	}
+	return nil
+}
+
+func sizeExtensionMap(m map[int32]Extension) (n int) {
+	for _, e := range m {
+		if e.value == nil || e.desc == nil {
+			// Extension is only in its encoded form.
+			n += len(e.enc)
+			continue
+		}
+
+		// We don't skip extensions that have an encoded form set,
+		// because the extension value may have been mutated after
+		// the last time this function was called.
+
+		et := reflect.TypeOf(e.desc.ExtensionType)
+		props := extensionProperties(e.desc)
+
+		// If e.value has type T, the encoder expects a *struct{ X T }.
+		// Pass a *T with a zero field and hope it all works out.
+		x := reflect.New(et)
+		x.Elem().Set(reflect.ValueOf(e.value))
+		n += props.size(props, toStructPointer(x))
+	}
+	return
+}
+
+// HasExtension returns whether the given extension is present in pb.
+func HasExtension(pb extendableProto, extension *ExtensionDesc) bool {
+	// TODO: Check types, field numbers, etc.?
+	_, ok := pb.ExtensionMap()[extension.Field]
+	return ok
+}
+
+// ClearExtension removes the given extension from pb.
+func ClearExtension(pb extendableProto, extension *ExtensionDesc) {
+	// TODO: Check types, field numbers, etc.?
+	delete(pb.ExtensionMap(), extension.Field)
+}
+
+// GetExtension parses and returns the given extension of pb.
+// If the extension is not present it returns ErrMissingExtension.
+func GetExtension(pb extendableProto, extension *ExtensionDesc) (interface{}, error) {
+	if err := checkExtensionTypes(pb, extension); err != nil {
+		return nil, err
+	}
+
+	emap := pb.ExtensionMap()
+	e, ok := emap[extension.Field]
+	if !ok {
+		return nil, ErrMissingExtension
+	}
+	if e.value != nil {
+		// Already decoded. Check the descriptor, though.
+		if e.desc != extension {
+			// This shouldn't happen. If it does, it means that
+			// GetExtension was called twice with two different
+			// descriptors with the same field number.
+			return nil, errors.New("proto: descriptor conflict")
+		}
+		return e.value, nil
+	}
+
+	v, err := decodeExtension(e.enc, extension)
+	if err != nil {
+		return nil, err
+	}
+
+	// Remember the decoded version and drop the encoded version.
+	// That way it is safe to mutate what we return.
+	e.value = v
+	e.desc = extension
+	e.enc = nil
+	emap[extension.Field] = e
+	return e.value, nil
+}
+
+// decodeExtension decodes an extension encoded in b.
+func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) {
+	o := NewBuffer(b)
+
+	t := reflect.TypeOf(extension.ExtensionType)
+	rep := extension.repeated()
+
+	props := extensionProperties(extension)
+
+	// t is a pointer to a struct, pointer to basic type or a slice.
+	// Allocate a "field" to store the pointer/slice itself; the
+	// pointer/slice will be stored here. We pass
+	// the address of this field to props.dec.
+	// This passes a zero field and a *t and lets props.dec
+	// interpret it as a *struct{ x t }.
+	value := reflect.New(t).Elem()
+
+	for {
+		// Discard wire type and field number varint. It isn't needed.
+		if _, err := o.DecodeVarint(); err != nil {
+			return nil, err
+		}
+
+		if err := props.dec(o, props, toStructPointer(value.Addr())); err != nil {
+			return nil, err
+		}
+
+		if !rep || o.index >= len(o.buf) {
+			break
+		}
+	}
+	return value.Interface(), nil
+}
+
+// GetExtensions returns a slice of the extensions present in pb that are also listed in es.
+// The returned slice has the same length as es; missing extensions will appear as nil elements.
+func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) {
+	epb, ok := pb.(extendableProto)
+	if !ok {
+		err = errors.New("proto: not an extendable proto")
+		return
+	}
+	extensions = make([]interface{}, len(es))
+	for i, e := range es {
+		extensions[i], err = GetExtension(epb, e)
+		if err == ErrMissingExtension {
+			err = nil
+		}
+		if err != nil {
+			return
+		}
+	}
+	return
+}
+
+// SetExtension sets the specified extension of pb to the specified value.
+func SetExtension(pb extendableProto, extension *ExtensionDesc, value interface{}) error {
+	if err := checkExtensionTypes(pb, extension); err != nil {
+		return err
+	}
+	typ := reflect.TypeOf(extension.ExtensionType)
+	if typ != reflect.TypeOf(value) {
+		return errors.New("proto: bad extension value type")
+	}
+	// nil extension values need to be caught early, because the
+	// encoder can't distinguish an ErrNil due to a nil extension
+	// from an ErrNil due to a missing field. Extensions are
+	// always optional, so the encoder would just swallow the error
+	// and drop all the extensions from the encoded message.
+	if reflect.ValueOf(value).IsNil() {
+		return fmt.Errorf("proto: SetExtension called with nil value of type %T", value)
+	}
+
+	pb.ExtensionMap()[extension.Field] = Extension{desc: extension, value: value}
+	return nil
+}
+
+// A global registry of extensions.
+// The generated code will register the generated descriptors by calling RegisterExtension.
+
+var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc)
+
+// RegisterExtension is called from the generated code.
+func RegisterExtension(desc *ExtensionDesc) {
+	st := reflect.TypeOf(desc.ExtendedType).Elem()
+	m := extensionMaps[st]
+	if m == nil {
+		m = make(map[int32]*ExtensionDesc)
+		extensionMaps[st] = m
+	}
+	if _, ok := m[desc.Field]; ok {
+		panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field)))
+	}
+	m[desc.Field] = desc
+}
+
+// RegisteredExtensions returns a map of the registered extensions of a
+// protocol buffer struct, indexed by the extension number.
+// The argument pb should be a nil pointer to the struct type.
+func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc {
+	return extensionMaps[reflect.TypeOf(pb).Elem()]
+}

+ 153 - 0
vendor/src/github.com/golang/protobuf/proto/extensions_test.go

@@ -0,0 +1,153 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2014 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto_test
+
+import (
+	"testing"
+
+	"github.com/golang/protobuf/proto"
+	pb "github.com/golang/protobuf/proto/testdata"
+)
+
+func TestGetExtensionsWithMissingExtensions(t *testing.T) {
+	msg := &pb.MyMessage{}
+	ext1 := &pb.Ext{}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
+		t.Fatalf("Could not set ext1: %s", ext1)
+	}
+	exts, err := proto.GetExtensions(msg, []*proto.ExtensionDesc{
+		pb.E_Ext_More,
+		pb.E_Ext_Text,
+	})
+	if err != nil {
+		t.Fatalf("GetExtensions() failed: %s", err)
+	}
+	if exts[0] != ext1 {
+		t.Errorf("ext1 not in returned extensions: %T %v", exts[0], exts[0])
+	}
+	if exts[1] != nil {
+		t.Errorf("ext2 in returned extensions: %T %v", exts[1], exts[1])
+	}
+}
+
+func TestGetExtensionStability(t *testing.T) {
+	check := func(m *pb.MyMessage) bool {
+		ext1, err := proto.GetExtension(m, pb.E_Ext_More)
+		if err != nil {
+			t.Fatalf("GetExtension() failed: %s", err)
+		}
+		ext2, err := proto.GetExtension(m, pb.E_Ext_More)
+		if err != nil {
+			t.Fatalf("GetExtension() failed: %s", err)
+		}
+		return ext1 == ext2
+	}
+	msg := &pb.MyMessage{Count: proto.Int32(4)}
+	ext0 := &pb.Ext{}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext0); err != nil {
+		t.Fatalf("Could not set ext1: %s", ext0)
+	}
+	if !check(msg) {
+		t.Errorf("GetExtension() not stable before marshaling")
+	}
+	bb, err := proto.Marshal(msg)
+	if err != nil {
+		t.Fatalf("Marshal() failed: %s", err)
+	}
+	msg1 := &pb.MyMessage{}
+	err = proto.Unmarshal(bb, msg1)
+	if err != nil {
+		t.Fatalf("Unmarshal() failed: %s", err)
+	}
+	if !check(msg1) {
+		t.Errorf("GetExtension() not stable after unmarshaling")
+	}
+}
+
+func TestExtensionsRoundTrip(t *testing.T) {
+	msg := &pb.MyMessage{}
+	ext1 := &pb.Ext{
+		Data: proto.String("hi"),
+	}
+	ext2 := &pb.Ext{
+		Data: proto.String("there"),
+	}
+	exists := proto.HasExtension(msg, pb.E_Ext_More)
+	if exists {
+		t.Error("Extension More present unexpectedly")
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext1); err != nil {
+		t.Error(err)
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, ext2); err != nil {
+		t.Error(err)
+	}
+	e, err := proto.GetExtension(msg, pb.E_Ext_More)
+	if err != nil {
+		t.Error(err)
+	}
+	x, ok := e.(*pb.Ext)
+	if !ok {
+		t.Errorf("e has type %T, expected testdata.Ext", e)
+	} else if *x.Data != "there" {
+		t.Errorf("SetExtension failed to overwrite, got %+v, not 'there'", x)
+	}
+	proto.ClearExtension(msg, pb.E_Ext_More)
+	if _, err = proto.GetExtension(msg, pb.E_Ext_More); err != proto.ErrMissingExtension {
+		t.Errorf("got %v, expected ErrMissingExtension", e)
+	}
+	if _, err := proto.GetExtension(msg, pb.E_X215); err == nil {
+		t.Error("expected bad extension error, got nil")
+	}
+	if err := proto.SetExtension(msg, pb.E_X215, 12); err == nil {
+		t.Error("expected extension err")
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, 12); err == nil {
+		t.Error("expected some sort of type mismatch error, got nil")
+	}
+}
+
+func TestNilExtension(t *testing.T) {
+	msg := &pb.MyMessage{
+		Count: proto.Int32(1),
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_Text, proto.String("hello")); err != nil {
+		t.Fatal(err)
+	}
+	if err := proto.SetExtension(msg, pb.E_Ext_More, (*pb.Ext)(nil)); err == nil {
+		t.Error("expected SetExtension to fail due to a nil extension")
+	} else if want := "proto: SetExtension called with nil value of type *testdata.Ext"; err.Error() != want {
+		t.Errorf("expected error %v, got %v", want, err)
+	}
+	// Note: if the behavior of Marshal is ever changed to ignore nil extensions, update
+	// this test to verify that E_Ext_Text is properly propagated through marshal->unmarshal.
+}

+ 790 - 0
vendor/src/github.com/golang/protobuf/proto/lib.go

@@ -0,0 +1,790 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/*
+	Package proto converts data structures to and from the wire format of
+	protocol buffers.  It works in concert with the Go source code generated
+	for .proto files by the protocol compiler.
+
+	A summary of the properties of the protocol buffer interface
+	for a protocol buffer variable v:
+
+	  - Names are turned from camel_case to CamelCase for export.
+	  - There are no methods on v to set fields; just treat
+		them as structure fields.
+	  - There are getters that return a field's value if set,
+		and return the field's default value if unset.
+		The getters work even if the receiver is a nil message.
+	  - The zero value for a struct is its correct initialization state.
+		All desired fields must be set before marshaling.
+	  - A Reset() method will restore a protobuf struct to its zero state.
+	  - Non-repeated fields are pointers to the values; nil means unset.
+		That is, optional or required field int32 f becomes F *int32.
+	  - Repeated fields are slices.
+	  - Helper functions are available to aid the setting of fields.
+		msg.Foo = proto.String("hello") // set field
+	  - Constants are defined to hold the default values of all fields that
+		have them.  They have the form Default_StructName_FieldName.
+		Because the getter methods handle defaulted values,
+		direct use of these constants should be rare.
+	  - Enums are given type names and maps from names to values.
+		Enum values are prefixed by the enclosing message's name, or by the
+		enum's type name if it is a top-level enum. Enum types have a String
+		method, and a Enum method to assist in message construction.
+	  - Nested messages, groups and enums have type names prefixed with the name of
+	  	the surrounding message type.
+	  - Extensions are given descriptor names that start with E_,
+		followed by an underscore-delimited list of the nested messages
+		that contain it (if any) followed by the CamelCased name of the
+		extension field itself.  HasExtension, ClearExtension, GetExtension
+		and SetExtension are functions for manipulating extensions.
+	  - Marshal and Unmarshal are functions to encode and decode the wire format.
+
+	The simplest way to describe this is to see an example.
+	Given file test.proto, containing
+
+		package example;
+
+		enum FOO { X = 17; }
+
+		message Test {
+		  required string label = 1;
+		  optional int32 type = 2 [default=77];
+		  repeated int64 reps = 3;
+		  optional group OptionalGroup = 4 {
+		    required string RequiredField = 5;
+		  }
+		}
+
+	The resulting file, test.pb.go, is:
+
+		package example
+
+		import proto "github.com/golang/protobuf/proto"
+		import math "math"
+
+		type FOO int32
+		const (
+			FOO_X FOO = 17
+		)
+		var FOO_name = map[int32]string{
+			17: "X",
+		}
+		var FOO_value = map[string]int32{
+			"X": 17,
+		}
+
+		func (x FOO) Enum() *FOO {
+			p := new(FOO)
+			*p = x
+			return p
+		}
+		func (x FOO) String() string {
+			return proto.EnumName(FOO_name, int32(x))
+		}
+		func (x *FOO) UnmarshalJSON(data []byte) error {
+			value, err := proto.UnmarshalJSONEnum(FOO_value, data)
+			if err != nil {
+				return err
+			}
+			*x = FOO(value)
+			return nil
+		}
+
+		type Test struct {
+			Label            *string             `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
+			Type             *int32              `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
+			Reps             []int64             `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
+			Optionalgroup    *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
+			XXX_unrecognized []byte              `json:"-"`
+		}
+		func (m *Test) Reset()         { *m = Test{} }
+		func (m *Test) String() string { return proto.CompactTextString(m) }
+		func (*Test) ProtoMessage()    {}
+		const Default_Test_Type int32 = 77
+
+		func (m *Test) GetLabel() string {
+			if m != nil && m.Label != nil {
+				return *m.Label
+			}
+			return ""
+		}
+
+		func (m *Test) GetType() int32 {
+			if m != nil && m.Type != nil {
+				return *m.Type
+			}
+			return Default_Test_Type
+		}
+
+		func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
+			if m != nil {
+				return m.Optionalgroup
+			}
+			return nil
+		}
+
+		type Test_OptionalGroup struct {
+			RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"`
+		}
+		func (m *Test_OptionalGroup) Reset()         { *m = Test_OptionalGroup{} }
+		func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
+
+		func (m *Test_OptionalGroup) GetRequiredField() string {
+			if m != nil && m.RequiredField != nil {
+				return *m.RequiredField
+			}
+			return ""
+		}
+
+		func init() {
+			proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
+		}
+
+	To create and play with a Test object:
+
+		package main
+
+		import (
+			"log"
+
+			"github.com/golang/protobuf/proto"
+			pb "./example.pb"
+		)
+
+		func main() {
+			test := &pb.Test{
+				Label: proto.String("hello"),
+				Type:  proto.Int32(17),
+				Optionalgroup: &pb.Test_OptionalGroup{
+					RequiredField: proto.String("good bye"),
+				},
+			}
+			data, err := proto.Marshal(test)
+			if err != nil {
+				log.Fatal("marshaling error: ", err)
+			}
+			newTest := &pb.Test{}
+			err = proto.Unmarshal(data, newTest)
+			if err != nil {
+				log.Fatal("unmarshaling error: ", err)
+			}
+			// Now test and newTest contain the same data.
+			if test.GetLabel() != newTest.GetLabel() {
+				log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
+			}
+			// etc.
+		}
+*/
+package proto
+
+import (
+	"encoding/json"
+	"fmt"
+	"log"
+	"reflect"
+	"strconv"
+	"sync"
+)
+
+// Message is implemented by generated protocol buffer messages.
+type Message interface {
+	Reset()
+	String() string
+	ProtoMessage()
+}
+
+// Stats records allocation details about the protocol buffer encoders
+// and decoders.  Useful for tuning the library itself.
+type Stats struct {
+	Emalloc uint64 // mallocs in encode
+	Dmalloc uint64 // mallocs in decode
+	Encode  uint64 // number of encodes
+	Decode  uint64 // number of decodes
+	Chit    uint64 // number of cache hits
+	Cmiss   uint64 // number of cache misses
+	Size    uint64 // number of sizes
+}
+
+// Set to true to enable stats collection.
+const collectStats = false
+
+var stats Stats
+
+// GetStats returns a copy of the global Stats structure.
+func GetStats() Stats { return stats }
+
+// A Buffer is a buffer manager for marshaling and unmarshaling
+// protocol buffers.  It may be reused between invocations to
+// reduce memory usage.  It is not necessary to use a Buffer;
+// the global functions Marshal and Unmarshal create a
+// temporary Buffer and are fine for most applications.
+type Buffer struct {
+	buf   []byte // encode/decode byte stream
+	index int    // write point
+
+	// pools of basic types to amortize allocation.
+	bools   []bool
+	uint32s []uint32
+	uint64s []uint64
+
+	// extra pools, only used with pointer_reflect.go
+	int32s   []int32
+	int64s   []int64
+	float32s []float32
+	float64s []float64
+}
+
+// NewBuffer allocates a new Buffer and initializes its internal data to
+// the contents of the argument slice.
+func NewBuffer(e []byte) *Buffer {
+	return &Buffer{buf: e}
+}
+
+// Reset resets the Buffer, ready for marshaling a new protocol buffer.
+func (p *Buffer) Reset() {
+	p.buf = p.buf[0:0] // for reading/writing
+	p.index = 0        // for reading
+}
+
+// SetBuf replaces the internal buffer with the slice,
+// ready for unmarshaling the contents of the slice.
+func (p *Buffer) SetBuf(s []byte) {
+	p.buf = s
+	p.index = 0
+}
+
+// Bytes returns the contents of the Buffer.
+func (p *Buffer) Bytes() []byte { return p.buf }
+
+/*
+ * Helper routines for simplifying the creation of optional fields of basic type.
+ */
+
+// Bool is a helper routine that allocates a new bool value
+// to store v and returns a pointer to it.
+func Bool(v bool) *bool {
+	return &v
+}
+
+// Int32 is a helper routine that allocates a new int32 value
+// to store v and returns a pointer to it.
+func Int32(v int32) *int32 {
+	return &v
+}
+
+// Int is a helper routine that allocates a new int32 value
+// to store v and returns a pointer to it, but unlike Int32
+// its argument value is an int.
+func Int(v int) *int32 {
+	p := new(int32)
+	*p = int32(v)
+	return p
+}
+
+// Int64 is a helper routine that allocates a new int64 value
+// to store v and returns a pointer to it.
+func Int64(v int64) *int64 {
+	return &v
+}
+
+// Float32 is a helper routine that allocates a new float32 value
+// to store v and returns a pointer to it.
+func Float32(v float32) *float32 {
+	return &v
+}
+
+// Float64 is a helper routine that allocates a new float64 value
+// to store v and returns a pointer to it.
+func Float64(v float64) *float64 {
+	return &v
+}
+
+// Uint32 is a helper routine that allocates a new uint32 value
+// to store v and returns a pointer to it.
+func Uint32(v uint32) *uint32 {
+	return &v
+}
+
+// Uint64 is a helper routine that allocates a new uint64 value
+// to store v and returns a pointer to it.
+func Uint64(v uint64) *uint64 {
+	return &v
+}
+
+// String is a helper routine that allocates a new string value
+// to store v and returns a pointer to it.
+func String(v string) *string {
+	return &v
+}
+
+// EnumName is a helper function to simplify printing protocol buffer enums
+// by name.  Given an enum map and a value, it returns a useful string.
+func EnumName(m map[int32]string, v int32) string {
+	s, ok := m[v]
+	if ok {
+		return s
+	}
+	return strconv.Itoa(int(v))
+}
+
+// UnmarshalJSONEnum is a helper function to simplify recovering enum int values
+// from their JSON-encoded representation. Given a map from the enum's symbolic
+// names to its int values, and a byte buffer containing the JSON-encoded
+// value, it returns an int32 that can be cast to the enum type by the caller.
+//
+// The function can deal with both JSON representations, numeric and symbolic.
+func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) {
+	if data[0] == '"' {
+		// New style: enums are strings.
+		var repr string
+		if err := json.Unmarshal(data, &repr); err != nil {
+			return -1, err
+		}
+		val, ok := m[repr]
+		if !ok {
+			return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr)
+		}
+		return val, nil
+	}
+	// Old style: enums are ints.
+	var val int32
+	if err := json.Unmarshal(data, &val); err != nil {
+		return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName)
+	}
+	return val, nil
+}
+
+// DebugPrint dumps the encoded data in b in a debugging format with a header
+// including the string s. Used in testing but made available for general debugging.
+func (o *Buffer) DebugPrint(s string, b []byte) {
+	var u uint64
+
+	obuf := o.buf
+	index := o.index
+	o.buf = b
+	o.index = 0
+	depth := 0
+
+	fmt.Printf("\n--- %s ---\n", s)
+
+out:
+	for {
+		for i := 0; i < depth; i++ {
+			fmt.Print("  ")
+		}
+
+		index := o.index
+		if index == len(o.buf) {
+			break
+		}
+
+		op, err := o.DecodeVarint()
+		if err != nil {
+			fmt.Printf("%3d: fetching op err %v\n", index, err)
+			break out
+		}
+		tag := op >> 3
+		wire := op & 7
+
+		switch wire {
+		default:
+			fmt.Printf("%3d: t=%3d unknown wire=%d\n",
+				index, tag, wire)
+			break out
+
+		case WireBytes:
+			var r []byte
+
+			r, err = o.DecodeRawBytes(false)
+			if err != nil {
+				break out
+			}
+			fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r))
+			if len(r) <= 6 {
+				for i := 0; i < len(r); i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+			} else {
+				for i := 0; i < 3; i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+				fmt.Printf(" ..")
+				for i := len(r) - 3; i < len(r); i++ {
+					fmt.Printf(" %.2x", r[i])
+				}
+			}
+			fmt.Printf("\n")
+
+		case WireFixed32:
+			u, err = o.DecodeFixed32()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
+
+		case WireFixed64:
+			u, err = o.DecodeFixed64()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
+			break
+
+		case WireVarint:
+			u, err = o.DecodeVarint()
+			if err != nil {
+				fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
+
+		case WireStartGroup:
+			if err != nil {
+				fmt.Printf("%3d: t=%3d start err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d start\n", index, tag)
+			depth++
+
+		case WireEndGroup:
+			depth--
+			if err != nil {
+				fmt.Printf("%3d: t=%3d end err %v\n", index, tag, err)
+				break out
+			}
+			fmt.Printf("%3d: t=%3d end\n", index, tag)
+		}
+	}
+
+	if depth != 0 {
+		fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth)
+	}
+	fmt.Printf("\n")
+
+	o.buf = obuf
+	o.index = index
+}
+
+// SetDefaults sets unset protocol buffer fields to their default values.
+// It only modifies fields that are both unset and have defined defaults.
+// It recursively sets default values in any non-nil sub-messages.
+func SetDefaults(pb Message) {
+	setDefaults(reflect.ValueOf(pb), true, false)
+}
+
+// v is a pointer to a struct.
+func setDefaults(v reflect.Value, recur, zeros bool) {
+	v = v.Elem()
+
+	defaultMu.RLock()
+	dm, ok := defaults[v.Type()]
+	defaultMu.RUnlock()
+	if !ok {
+		dm = buildDefaultMessage(v.Type())
+		defaultMu.Lock()
+		defaults[v.Type()] = dm
+		defaultMu.Unlock()
+	}
+
+	for _, sf := range dm.scalars {
+		f := v.Field(sf.index)
+		if !f.IsNil() {
+			// field already set
+			continue
+		}
+		dv := sf.value
+		if dv == nil && !zeros {
+			// no explicit default, and don't want to set zeros
+			continue
+		}
+		fptr := f.Addr().Interface() // **T
+		// TODO: Consider batching the allocations we do here.
+		switch sf.kind {
+		case reflect.Bool:
+			b := new(bool)
+			if dv != nil {
+				*b = dv.(bool)
+			}
+			*(fptr.(**bool)) = b
+		case reflect.Float32:
+			f := new(float32)
+			if dv != nil {
+				*f = dv.(float32)
+			}
+			*(fptr.(**float32)) = f
+		case reflect.Float64:
+			f := new(float64)
+			if dv != nil {
+				*f = dv.(float64)
+			}
+			*(fptr.(**float64)) = f
+		case reflect.Int32:
+			// might be an enum
+			if ft := f.Type(); ft != int32PtrType {
+				// enum
+				f.Set(reflect.New(ft.Elem()))
+				if dv != nil {
+					f.Elem().SetInt(int64(dv.(int32)))
+				}
+			} else {
+				// int32 field
+				i := new(int32)
+				if dv != nil {
+					*i = dv.(int32)
+				}
+				*(fptr.(**int32)) = i
+			}
+		case reflect.Int64:
+			i := new(int64)
+			if dv != nil {
+				*i = dv.(int64)
+			}
+			*(fptr.(**int64)) = i
+		case reflect.String:
+			s := new(string)
+			if dv != nil {
+				*s = dv.(string)
+			}
+			*(fptr.(**string)) = s
+		case reflect.Uint8:
+			// exceptional case: []byte
+			var b []byte
+			if dv != nil {
+				db := dv.([]byte)
+				b = make([]byte, len(db))
+				copy(b, db)
+			} else {
+				b = []byte{}
+			}
+			*(fptr.(*[]byte)) = b
+		case reflect.Uint32:
+			u := new(uint32)
+			if dv != nil {
+				*u = dv.(uint32)
+			}
+			*(fptr.(**uint32)) = u
+		case reflect.Uint64:
+			u := new(uint64)
+			if dv != nil {
+				*u = dv.(uint64)
+			}
+			*(fptr.(**uint64)) = u
+		default:
+			log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind)
+		}
+	}
+
+	for _, ni := range dm.nested {
+		f := v.Field(ni)
+		// f is *T or []*T or map[T]*T
+		switch f.Kind() {
+		case reflect.Ptr:
+			if f.IsNil() {
+				continue
+			}
+			setDefaults(f, recur, zeros)
+
+		case reflect.Slice:
+			for i := 0; i < f.Len(); i++ {
+				e := f.Index(i)
+				if e.IsNil() {
+					continue
+				}
+				setDefaults(e, recur, zeros)
+			}
+
+		case reflect.Map:
+			for _, k := range f.MapKeys() {
+				e := f.MapIndex(k)
+				if e.IsNil() {
+					continue
+				}
+				setDefaults(e, recur, zeros)
+			}
+		}
+	}
+}
+
+var (
+	// defaults maps a protocol buffer struct type to a slice of the fields,
+	// with its scalar fields set to their proto-declared non-zero default values.
+	defaultMu sync.RWMutex
+	defaults  = make(map[reflect.Type]defaultMessage)
+
+	int32PtrType = reflect.TypeOf((*int32)(nil))
+)
+
+// defaultMessage represents information about the default values of a message.
+type defaultMessage struct {
+	scalars []scalarField
+	nested  []int // struct field index of nested messages
+}
+
+type scalarField struct {
+	index int          // struct field index
+	kind  reflect.Kind // element type (the T in *T or []T)
+	value interface{}  // the proto-declared default value, or nil
+}
+
+// t is a struct type.
+func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
+	sprop := GetProperties(t)
+	for _, prop := range sprop.Prop {
+		fi, ok := sprop.decoderTags.get(prop.Tag)
+		if !ok {
+			// XXX_unrecognized
+			continue
+		}
+		ft := t.Field(fi).Type
+
+		var canHaveDefault, nestedMessage bool
+		switch ft.Kind() {
+		case reflect.Ptr:
+			if ft.Elem().Kind() == reflect.Struct {
+				nestedMessage = true
+			} else {
+				canHaveDefault = true // proto2 scalar field
+			}
+
+		case reflect.Slice:
+			switch ft.Elem().Kind() {
+			case reflect.Ptr:
+				nestedMessage = true // repeated message
+			case reflect.Uint8:
+				canHaveDefault = true // bytes field
+			}
+
+		case reflect.Map:
+			if ft.Elem().Kind() == reflect.Ptr {
+				nestedMessage = true // map with message values
+			}
+		}
+
+		if !canHaveDefault {
+			if nestedMessage {
+				dm.nested = append(dm.nested, fi)
+			}
+			continue
+		}
+
+		sf := scalarField{
+			index: fi,
+			kind:  ft.Elem().Kind(),
+		}
+
+		// scalar fields without defaults
+		if !prop.HasDefault {
+			dm.scalars = append(dm.scalars, sf)
+			continue
+		}
+
+		// a scalar field: either *T or []byte
+		switch ft.Elem().Kind() {
+		case reflect.Bool:
+			x, err := strconv.ParseBool(prop.Default)
+			if err != nil {
+				log.Printf("proto: bad default bool %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = x
+		case reflect.Float32:
+			x, err := strconv.ParseFloat(prop.Default, 32)
+			if err != nil {
+				log.Printf("proto: bad default float32 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = float32(x)
+		case reflect.Float64:
+			x, err := strconv.ParseFloat(prop.Default, 64)
+			if err != nil {
+				log.Printf("proto: bad default float64 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = x
+		case reflect.Int32:
+			x, err := strconv.ParseInt(prop.Default, 10, 32)
+			if err != nil {
+				log.Printf("proto: bad default int32 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = int32(x)
+		case reflect.Int64:
+			x, err := strconv.ParseInt(prop.Default, 10, 64)
+			if err != nil {
+				log.Printf("proto: bad default int64 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = x
+		case reflect.String:
+			sf.value = prop.Default
+		case reflect.Uint8:
+			// []byte (not *uint8)
+			sf.value = []byte(prop.Default)
+		case reflect.Uint32:
+			x, err := strconv.ParseUint(prop.Default, 10, 32)
+			if err != nil {
+				log.Printf("proto: bad default uint32 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = uint32(x)
+		case reflect.Uint64:
+			x, err := strconv.ParseUint(prop.Default, 10, 64)
+			if err != nil {
+				log.Printf("proto: bad default uint64 %q: %v", prop.Default, err)
+				continue
+			}
+			sf.value = x
+		default:
+			log.Printf("proto: unhandled def kind %v", ft.Elem().Kind())
+			continue
+		}
+
+		dm.scalars = append(dm.scalars, sf)
+	}
+
+	return dm
+}
+
+// Map fields may have key types of non-float scalars, strings and enums.
+// The easiest way to sort them in some deterministic order is to use fmt.
+// If this turns out to be inefficient we can always consider other options,
+// such as doing a Schwartzian transform.
+
+type mapKeys []reflect.Value
+
+func (s mapKeys) Len() int      { return len(s) }
+func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+func (s mapKeys) Less(i, j int) bool {
+	return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface())
+}

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

@@ -0,0 +1,287 @@
+// Go support for Protocol Buffers - Google's data interchange format
+//
+// Copyright 2010 The Go Authors.  All rights reserved.
+// https://github.com/golang/protobuf
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+package proto
+
+/*
+ * Support for message sets.
+ */
+
+import (
+	"bytes"
+	"encoding/json"
+	"errors"
+	"fmt"
+	"reflect"
+	"sort"
+)
+
+// ErrNoMessageTypeId occurs when a protocol buffer does not have a message type ID.
+// A message type ID is required for storing a protocol buffer in a message set.
+var ErrNoMessageTypeId = errors.New("proto does not have a message type ID")
+
+// The first two types (_MessageSet_Item and MessageSet)
+// model what the protocol compiler produces for the following protocol message:
+//   message MessageSet {
+//     repeated group Item = 1 {
+//       required int32 type_id = 2;
+//       required string message = 3;
+//     };
+//   }
+// That is the MessageSet wire format. We can't use a proto to generate these
+// because that would introduce a circular dependency between it and this package.
+//
+// When a proto1 proto has a field that looks like:
+//   optional message<MessageSet> info = 3;
+// the protocol compiler produces a field in the generated struct that looks like:
+//   Info *_proto_.MessageSet  `protobuf:"bytes,3,opt,name=info"`
+// The package is automatically inserted so there is no need for that proto file to
+// import this package.
+
+type _MessageSet_Item struct {
+	TypeId  *int32 `protobuf:"varint,2,req,name=type_id"`
+	Message []byte `protobuf:"bytes,3,req,name=message"`
+}
+
+type MessageSet struct {
+	Item             []*_MessageSet_Item `protobuf:"group,1,rep"`
+	XXX_unrecognized []byte
+	// TODO: caching?
+}
+
+// Make sure MessageSet is a Message.
+var _ Message = (*MessageSet)(nil)
+
+// messageTypeIder is an interface satisfied by a protocol buffer type
+// that may be stored in a MessageSet.
+type messageTypeIder interface {
+	MessageTypeId() int32
+}
+
+func (ms *MessageSet) find(pb Message) *_MessageSet_Item {
+	mti, ok := pb.(messageTypeIder)
+	if !ok {
+		return nil
+	}
+	id := mti.MessageTypeId()
+	for _, item := range ms.Item {
+		if *item.TypeId == id {
+			return item
+		}
+	}
+	return nil
+}
+
+func (ms *MessageSet) Has(pb Message) bool {
+	if ms.find(pb) != nil {
+		return true
+	}
+	return false
+}
+
+func (ms *MessageSet) Unmarshal(pb Message) error {
+	if item := ms.find(pb); item != nil {
+		return Unmarshal(item.Message, pb)
+	}
+	if _, ok := pb.(messageTypeIder); !ok {
+		return ErrNoMessageTypeId
+	}
+	return nil // TODO: return error instead?
+}
+
+func (ms *MessageSet) Marshal(pb Message) error {
+	msg, err := Marshal(pb)
+	if err != nil {
+		return err
+	}
+	if item := ms.find(pb); item != nil {
+		// reuse existing item
+		item.Message = msg
+		return nil
+	}
+
+	mti, ok := pb.(messageTypeIder)
+	if !ok {
+		return ErrNoMessageTypeId
+	}
+
+	mtid := mti.MessageTypeId()
+	ms.Item = append(ms.Item, &_MessageSet_Item{
+		TypeId:  &mtid,
+		Message: msg,
+	})
+	return nil
+}
+
+func (ms *MessageSet) Reset()         { *ms = MessageSet{} }
+func (ms *MessageSet) String() string { return CompactTextString(ms) }
+func (*MessageSet) ProtoMessage()     {}
+
+// Support for the message_set_wire_format message option.
+
+func skipVarint(buf []byte) []byte {
+	i := 0
+	for ; buf[i]&0x80 != 0; i++ {
+	}
+	return buf[i+1:]
+}
+
+// MarshalMessageSet encodes the extension map represented by m in the message set wire format.
+// It is called by generated Marshal methods on protocol buffer messages with the message_set_wire_format option.
+func MarshalMessageSet(m map[int32]Extension) ([]byte, error) {
+	if err := encodeExtensionMap(m); err != nil {
+		return nil, err
+	}
+
+	// Sort extension IDs to provide a deterministic encoding.
+	// See also enc_map in encode.go.
+	ids := make([]int, 0, len(m))
+	for id := range m {
+		ids = append(ids, int(id))
+	}
+	sort.Ints(ids)
+
+	ms := &MessageSet{Item: make([]*_MessageSet_Item, 0, len(m))}
+	for _, id := range ids {
+		e := m[int32(id)]
+		// Remove the wire type and field number varint, as well as the length varint.
+		msg := skipVarint(skipVarint(e.enc))
+
+		ms.Item = append(ms.Item, &_MessageSet_Item{
+			TypeId:  Int32(int32(id)),
+			Message: msg,
+		})
+	}
+	return Marshal(ms)
+}
+
+// UnmarshalMessageSet decodes the extension map encoded in buf in the message set wire format.
+// It is called by generated Unmarshal methods on protocol buffer messages with the message_set_wire_format option.
+func UnmarshalMessageSet(buf []byte, m map[int32]Extension) error {
+	ms := new(MessageSet)
+	if err := Unmarshal(buf, ms); err != nil {
+		return err
+	}
+	for _, item := range ms.Item {
+		id := *item.TypeId
+		msg := item.Message
+
+		// Restore wire type and field number varint, plus length varint.
+		// Be careful to preserve duplicate items.
+		b := EncodeVarint(uint64(id)<<3 | WireBytes)
+		if ext, ok := m[id]; ok {
+			// Existing data; rip off the tag and length varint
+			// so we join the new data correctly.
+			// We can assume that ext.enc is set because we are unmarshaling.
+			o := ext.enc[len(b):]   // skip wire type and field number
+			_, n := DecodeVarint(o) // calculate length of length varint
+			o = o[n:]               // skip length varint
+			msg = append(o, msg...) // join old data and new data
+		}
+		b = append(b, EncodeVarint(uint64(len(msg)))...)
+		b = append(b, msg...)
+
+		m[id] = Extension{enc: b}
+	}
+	return nil
+}
+
+// MarshalMessageSetJSON encodes the extension map represented by m in JSON format.
+// It is called by generated MarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
+func MarshalMessageSetJSON(m map[int32]Extension) ([]byte, error) {
+	var b bytes.Buffer
+	b.WriteByte('{')
+
+	// Process the map in key order for deterministic output.
+	ids := make([]int32, 0, len(m))
+	for id := range m {
+		ids = append(ids, id)
+	}
+	sort.Sort(int32Slice(ids)) // int32Slice defined in text.go
+
+	for i, id := range ids {
+		ext := m[id]
+		if i > 0 {
+			b.WriteByte(',')
+		}
+
+		msd, ok := messageSetMap[id]
+		if !ok {
+			// Unknown type; we can't render it, so skip it.
+			continue
+		}
+		fmt.Fprintf(&b, `"[%s]":`, msd.name)
+
+		x := ext.value
+		if x == nil {
+			x = reflect.New(msd.t.Elem()).Interface()
+			if err := Unmarshal(ext.enc, x.(Message)); err != nil {
+				return nil, err
+			}
+		}
+		d, err := json.Marshal(x)
+		if err != nil {
+			return nil, err
+		}
+		b.Write(d)
+	}
+	b.WriteByte('}')
+	return b.Bytes(), nil
+}
+
+// UnmarshalMessageSetJSON decodes the extension map encoded in buf in JSON format.
+// It is called by generated UnmarshalJSON methods on protocol buffer messages with the message_set_wire_format option.
+func UnmarshalMessageSetJSON(buf []byte, m map[int32]Extension) error {
+	// Common-case fast path.
+	if len(buf) == 0 || bytes.Equal(buf, []byte("{}")) {
+		return nil
+	}
+
+	// This is fairly tricky, and it's not clear that it is needed.
+	return errors.New("TODO: UnmarshalMessageSetJSON not yet implemented")
+}
+
+// A global registry of types that can be used in a MessageSet.
+
+var messageSetMap = make(map[int32]messageSetDesc)
+
+type messageSetDesc struct {
+	t    reflect.Type // pointer to struct
+	name string
+}
+
+// RegisterMessageSetType is called from the generated code.
+func RegisterMessageSetType(m Message, fieldNum int32, name string) {
+	messageSetMap[fieldNum] = messageSetDesc{
+		t:    reflect.TypeOf(m),
+		name: name,
+	}
+}

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików