Merge pull request #20831 from jonboulle/yifan-gu-bump_rkt

Auto commit by PR queue bot
This commit is contained in:
k8s-merge-robot
2016-02-09 05:41:56 -08:00
132 changed files with 6920 additions and 2855 deletions

207
Godeps/Godeps.json generated
View File

@@ -135,10 +135,6 @@
"Comment": "v1.1.0-65-gee4a088", "Comment": "v1.1.0-65-gee4a088",
"Rev": "ee4a0888a9abe7eefe5a0992ca4cb06864839873" "Rev": "ee4a0888a9abe7eefe5a0992ca4cb06864839873"
}, },
{
"ImportPath": "github.com/bradfitz/http2",
"Rev": "3e36af6d3af0e56fa3da71099f864933dea3d9fb"
},
{ {
"ImportPath": "github.com/camlistore/go4/errorutil", "ImportPath": "github.com/camlistore/go4/errorutil",
"Rev": "3b6feb5cf32f573fb124905de36a54c24ee14ac1" "Rev": "3b6feb5cf32f573fb124905de36a54c24ee14ac1"
@@ -150,123 +146,123 @@
}, },
{ {
"ImportPath": "github.com/coreos/etcd/client", "ImportPath": "github.com/coreos/etcd/client",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/discovery", "ImportPath": "github.com/coreos/etcd/discovery",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/error", "ImportPath": "github.com/coreos/etcd/error",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/etcdserver", "ImportPath": "github.com/coreos/etcd/etcdserver",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/crc", "ImportPath": "github.com/coreos/etcd/pkg/crc",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/fileutil", "ImportPath": "github.com/coreos/etcd/pkg/fileutil",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/httputil", "ImportPath": "github.com/coreos/etcd/pkg/httputil",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/idutil", "ImportPath": "github.com/coreos/etcd/pkg/idutil",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/ioutil", "ImportPath": "github.com/coreos/etcd/pkg/ioutil",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/netutil", "ImportPath": "github.com/coreos/etcd/pkg/netutil",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/pathutil", "ImportPath": "github.com/coreos/etcd/pkg/pathutil",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/pbutil", "ImportPath": "github.com/coreos/etcd/pkg/pbutil",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/runtime", "ImportPath": "github.com/coreos/etcd/pkg/runtime",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/timeutil", "ImportPath": "github.com/coreos/etcd/pkg/timeutil",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/transport", "ImportPath": "github.com/coreos/etcd/pkg/transport",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/types", "ImportPath": "github.com/coreos/etcd/pkg/types",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/pkg/wait", "ImportPath": "github.com/coreos/etcd/pkg/wait",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/raft", "ImportPath": "github.com/coreos/etcd/raft",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/rafthttp", "ImportPath": "github.com/coreos/etcd/rafthttp",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/snap", "ImportPath": "github.com/coreos/etcd/snap",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/storage", "ImportPath": "github.com/coreos/etcd/storage",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/store", "ImportPath": "github.com/coreos/etcd/store",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/version", "ImportPath": "github.com/coreos/etcd/version",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/etcd/wal", "ImportPath": "github.com/coreos/etcd/wal",
"Comment": "v2.2.2-4-ge0c7768", "Comment": "v2.2.5",
"Rev": "e0c7768f94cdc268b2fce31ada1dea823f11f505" "Rev": "bc9ddf260115d2680191c46977ae72b837785472"
}, },
{ {
"ImportPath": "github.com/coreos/go-etcd/etcd", "ImportPath": "github.com/coreos/go-etcd/etcd",
@@ -340,8 +336,8 @@
}, },
{ {
"ImportPath": "github.com/coreos/rkt/api/v1alpha", "ImportPath": "github.com/coreos/rkt/api/v1alpha",
"Comment": "v0.15.0-22-g8ac03ac", "Comment": "v1.0.0",
"Rev": "8ac03ace42034b4d6b31af9e3ef574b9e71ccc1a" "Rev": "1ddc36601c8688ff207210bc9ecbf973d09573fa"
}, },
{ {
"ImportPath": "github.com/cpuguy83/go-md2man/md2man", "ImportPath": "github.com/cpuguy83/go-md2man/md2man",
@@ -425,7 +421,6 @@
}, },
{ {
"ImportPath": "github.com/fsouza/go-dockerclient", "ImportPath": "github.com/fsouza/go-dockerclient",
"Comment": "0.2.1-860-g25bc220",
"Rev": "25bc220b299845ae5489fd19bf89c5278864b050" "Rev": "25bc220b299845ae5489fd19bf89c5278864b050"
}, },
{ {
@@ -452,118 +447,118 @@
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/gogoproto", "ImportPath": "github.com/gogo/protobuf/gogoproto",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/defaultcheck", "ImportPath": "github.com/gogo/protobuf/plugin/defaultcheck",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/description", "ImportPath": "github.com/gogo/protobuf/plugin/description",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/embedcheck", "ImportPath": "github.com/gogo/protobuf/plugin/embedcheck",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/enumstringer", "ImportPath": "github.com/gogo/protobuf/plugin/enumstringer",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/equal", "ImportPath": "github.com/gogo/protobuf/plugin/equal",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/face", "ImportPath": "github.com/gogo/protobuf/plugin/face",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/gostring", "ImportPath": "github.com/gogo/protobuf/plugin/gostring",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/grpc", "ImportPath": "github.com/gogo/protobuf/plugin/grpc",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/marshalto", "ImportPath": "github.com/gogo/protobuf/plugin/marshalto",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/oneofcheck", "ImportPath": "github.com/gogo/protobuf/plugin/oneofcheck",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/populate", "ImportPath": "github.com/gogo/protobuf/plugin/populate",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/size", "ImportPath": "github.com/gogo/protobuf/plugin/size",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/stringer", "ImportPath": "github.com/gogo/protobuf/plugin/stringer",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/testgen", "ImportPath": "github.com/gogo/protobuf/plugin/testgen",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/union", "ImportPath": "github.com/gogo/protobuf/plugin/union",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/plugin/unmarshal", "ImportPath": "github.com/gogo/protobuf/plugin/unmarshal",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/proto", "ImportPath": "github.com/gogo/protobuf/proto",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor", "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/descriptor",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/generator", "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/generator",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/plugin", "ImportPath": "github.com/gogo/protobuf/protoc-gen-gogo/plugin",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/sortkeys", "ImportPath": "github.com/gogo/protobuf/sortkeys",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/gogo/protobuf/vanity", "ImportPath": "github.com/gogo/protobuf/vanity",
"Comment": "v0.1-108-g9dc5109", "Comment": "v0.1-125-g82d16f7",
"Rev": "9dc510915846dd5a05607d3b5bf41f5ca5cce972" "Rev": "82d16f734d6d871204a3feb1a73cb220cc92574c"
}, },
{ {
"ImportPath": "github.com/golang/glog", "ImportPath": "github.com/golang/glog",
@@ -575,7 +570,7 @@
}, },
{ {
"ImportPath": "github.com/golang/protobuf/proto", "ImportPath": "github.com/golang/protobuf/proto",
"Rev": "7f07925444bb51fa4cf9dfe6f7661876f8852275" "Rev": "b982704f8bb716bb608144408cff30e15fbde841"
}, },
{ {
"ImportPath": "github.com/google/btree", "ImportPath": "github.com/google/btree",
@@ -970,6 +965,10 @@
"ImportPath": "golang.org/x/net/html", "ImportPath": "golang.org/x/net/html",
"Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e" "Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e"
}, },
{
"ImportPath": "golang.org/x/net/http2",
"Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e"
},
{ {
"ImportPath": "golang.org/x/net/internal/timeseries", "ImportPath": "golang.org/x/net/internal/timeseries",
"Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e" "Rev": "c2528b2dd8352441850638a8bb678c2ad056fd3e"
@@ -1028,7 +1027,7 @@
}, },
{ {
"ImportPath": "google.golang.org/grpc", "ImportPath": "google.golang.org/grpc",
"Rev": "4bd040ce23a624ff9a1d07b0e729ee189bddd51c" "Rev": "933601d8cd6418a8a891bd9075a7161b0a67badb"
}, },
{ {
"ImportPath": "gopkg.in/natefinch/lumberjack.v2", "ImportPath": "gopkg.in/natefinch/lumberjack.v2",
@@ -1041,7 +1040,7 @@
}, },
{ {
"ImportPath": "k8s.io/heapster/api/v1/types", "ImportPath": "k8s.io/heapster/api/v1/types",
"Comment": "v0.19.1", "Comment": "v0.19.1-44-g0991ac5",
"Rev": "0991ac528ea24aae194e45d6dcf01896cb42cbea" "Rev": "0991ac528ea24aae194e45d6dcf01896cb42cbea"
}, },
{ {

3
Godeps/LICENSES.md generated
View File

@@ -13,7 +13,6 @@ github.com/aws/aws-sdk-go | Apache-2
github.com/beorn7/perks/quantile | MIT? github.com/beorn7/perks/quantile | MIT?
github.com/blang/semver | MITname github.com/blang/semver | MITname
github.com/boltdb/bolt | MITname github.com/boltdb/bolt | MITname
github.com/bradfitz/http2 | BSDlikeRef
github.com/camlistore/go4 | Apache-2 github.com/camlistore/go4 | Apache-2
github.com/ClusterHQ/flocker-go | UNKNOWN github.com/ClusterHQ/flocker-go | UNKNOWN
github.com/codegangsta/negroni | MITname github.com/codegangsta/negroni | MITname
@@ -23,7 +22,7 @@ github.com/coreos/go-oidc | Apache-2
github.com/coreos/go-semver | Apache-2 github.com/coreos/go-semver | Apache-2
github.com/coreos/go-systemd | Apache-2 github.com/coreos/go-systemd | Apache-2
github.com/coreos/pkg | Apache-2 github.com/coreos/pkg | Apache-2
github.com/coreos/rkt | Apache-2 github.com/coreos/rkt | MITname
github.com/cpuguy83/go-md2man | MITname github.com/cpuguy83/go-md2man | MITname
github.com/davecgh/go-spew | MIToldwithoutSellandNoDocumentationRequi github.com/davecgh/go-spew | MIToldwithoutSellandNoDocumentationRequi
github.com/daviddengcn/go-colortext | BSD? github.com/daviddengcn/go-colortext | BSD?

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -24,6 +24,7 @@ import (
"net/url" "net/url"
"reflect" "reflect"
"sort" "sort"
"strconv"
"sync" "sync"
"time" "time"
@@ -99,6 +100,8 @@ type Config struct {
// watch start. But if server is behind some kind of proxy, the response // watch start. But if server is behind some kind of proxy, the response
// header may be cached at proxy, and Client cannot rely on this behavior. // header may be cached at proxy, and Client cannot rely on this behavior.
// //
// Especially, wait request will ignore this timeout.
//
// One API call may send multiple requests to different etcd servers until it // One API call may send multiple requests to different etcd servers until it
// succeeds. Use context of the API to specify the overall timeout. // succeeds. Use context of the API to specify the overall timeout.
// //
@@ -162,6 +165,11 @@ type Client interface {
// this may differ from the initial Endpoints provided in the Config. // this may differ from the initial Endpoints provided in the Config.
Endpoints() []string Endpoints() []string
// SetEndpoints sets the set of API endpoints used by Client to resolve
// HTTP requests. If the given endpoints are not valid, an error will be
// returned
SetEndpoints(eps []string) error
httpClient httpClient
} }
@@ -176,7 +184,7 @@ func New(cfg Config) (Client, error) {
password: cfg.Password, password: cfg.Password,
} }
} }
if err := c.reset(cfg.Endpoints); err != nil { if err := c.SetEndpoints(cfg.Endpoints); err != nil {
return nil, err return nil, err
} }
return c, nil return c, nil
@@ -219,7 +227,7 @@ type httpClusterClient struct {
rand *rand.Rand rand *rand.Rand
} }
func (c *httpClusterClient) reset(eps []string) error { func (c *httpClusterClient) SetEndpoints(eps []string) error {
if len(eps) == 0 { if len(eps) == 0 {
return ErrNoEndpoints return ErrNoEndpoints
} }
@@ -341,7 +349,7 @@ func (c *httpClusterClient) Sync(ctx context.Context) error {
return nil return nil
} }
return c.reset(eps) return c.SetEndpoints(eps)
} }
func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration) error { func (c *httpClusterClient) AutoSync(ctx context.Context, interval time.Duration) error {
@@ -378,9 +386,21 @@ func (c *simpleHTTPClient) Do(ctx context.Context, act httpAction) (*http.Respon
return nil, nil, err return nil, nil, err
} }
isWait := false
if req != nil && req.URL != nil {
ws := req.URL.Query().Get("wait")
if len(ws) != 0 {
var err error
isWait, err = strconv.ParseBool(ws)
if err != nil {
return nil, nil, fmt.Errorf("wrong wait value %s (%v for %+v)", ws, err, req)
}
}
}
var hctx context.Context var hctx context.Context
var hcancel context.CancelFunc var hcancel context.CancelFunc
if c.headerTimeout > 0 { if !isWait && c.headerTimeout > 0 {
hctx, hcancel = context.WithTimeout(ctx, c.headerTimeout) hctx, hcancel = context.WithTimeout(ctx, c.headerTimeout)
} else { } else {
hctx, hcancel = context.WithCancel(ctx) hctx, hcancel = context.WithCancel(ctx)

View File

@@ -95,8 +95,7 @@ type store struct {
timeout time.Duration timeout time.Duration
ensuredOnce bool ensuredOnce bool
mu sync.Mutex // protect enabled mu sync.Mutex
enabled *bool
} }
type User struct { type User struct {
@@ -409,8 +408,6 @@ func (s *store) EnableAuth() error {
} }
err = s.enableAuth() err = s.enableAuth()
if err == nil { if err == nil {
b := true
s.enabled = &b
plog.Noticef("auth: enabled auth") plog.Noticef("auth: enabled auth")
} else { } else {
plog.Errorf("error enabling auth (%v)", err) plog.Errorf("error enabling auth (%v)", err)
@@ -428,8 +425,6 @@ func (s *store) DisableAuth() error {
err := s.disableAuth() err := s.disableAuth()
if err == nil { if err == nil {
b := false
s.enabled = &b
plog.Noticef("auth: disabled auth") plog.Noticef("auth: disabled auth")
} else { } else {
plog.Errorf("error disabling auth (%v)", err) plog.Errorf("error disabling auth (%v)", err)

View File

@@ -85,15 +85,10 @@ func (s *store) detectAuth() bool {
if s.server == nil { if s.server == nil {
return false return false
} }
if s.enabled != nil {
return *s.enabled
}
value, err := s.requestResource("/enabled", false) value, err := s.requestResource("/enabled", false)
if err != nil { if err != nil {
if e, ok := err.(*etcderr.Error); ok { if e, ok := err.(*etcderr.Error); ok {
if e.ErrorCode == etcderr.EcodeKeyNotFound { if e.ErrorCode == etcderr.EcodeKeyNotFound {
b := false
s.enabled = &b
return false return false
} }
} }
@@ -107,7 +102,6 @@ func (s *store) detectAuth() bool {
plog.Errorf("internal bookkeeping value for enabled isn't valid JSON (%v)", err) plog.Errorf("internal bookkeeping value for enabled isn't valid JSON (%v)", err)
return false return false
} }
s.enabled = &u
return u return u
} }

View File

@@ -13,38 +13,56 @@
It has these top-level messages: It has these top-level messages:
Request Request
Metadata Metadata
InternalRaftRequest
ResponseHeader
RangeRequest
RangeResponse
PutRequest
PutResponse
DeleteRangeRequest
DeleteRangeResponse
RequestUnion
ResponseUnion
Compare
TxnRequest
TxnResponse
CompactionRequest
CompactionResponse
*/ */
package etcdserverpb package etcdserverpb
import proto "github.com/gogo/protobuf/proto" import (
"fmt"
proto "github.com/gogo/protobuf/proto"
)
import math "math" import math "math"
// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto"
import io "io" import io "io"
import fmt "fmt"
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf var _ = math.Inf
type Request struct { type Request struct {
ID uint64 `protobuf:"varint,1,opt" json:"ID"` ID uint64 `protobuf:"varint,1,opt,name=ID" json:"ID"`
Method string `protobuf:"bytes,2,opt" json:"Method"` Method string `protobuf:"bytes,2,opt,name=Method" json:"Method"`
Path string `protobuf:"bytes,3,opt" json:"Path"` Path string `protobuf:"bytes,3,opt,name=Path" json:"Path"`
Val string `protobuf:"bytes,4,opt" json:"Val"` Val string `protobuf:"bytes,4,opt,name=Val" json:"Val"`
Dir bool `protobuf:"varint,5,opt" json:"Dir"` Dir bool `protobuf:"varint,5,opt,name=Dir" json:"Dir"`
PrevValue string `protobuf:"bytes,6,opt" json:"PrevValue"` PrevValue string `protobuf:"bytes,6,opt,name=PrevValue" json:"PrevValue"`
PrevIndex uint64 `protobuf:"varint,7,opt" json:"PrevIndex"` PrevIndex uint64 `protobuf:"varint,7,opt,name=PrevIndex" json:"PrevIndex"`
PrevExist *bool `protobuf:"varint,8,opt" json:"PrevExist,omitempty"` PrevExist *bool `protobuf:"varint,8,opt,name=PrevExist" json:"PrevExist,omitempty"`
Expiration int64 `protobuf:"varint,9,opt" json:"Expiration"` Expiration int64 `protobuf:"varint,9,opt,name=Expiration" json:"Expiration"`
Wait bool `protobuf:"varint,10,opt" json:"Wait"` Wait bool `protobuf:"varint,10,opt,name=Wait" json:"Wait"`
Since uint64 `protobuf:"varint,11,opt" json:"Since"` Since uint64 `protobuf:"varint,11,opt,name=Since" json:"Since"`
Recursive bool `protobuf:"varint,12,opt" json:"Recursive"` Recursive bool `protobuf:"varint,12,opt,name=Recursive" json:"Recursive"`
Sorted bool `protobuf:"varint,13,opt" json:"Sorted"` Sorted bool `protobuf:"varint,13,opt,name=Sorted" json:"Sorted"`
Quorum bool `protobuf:"varint,14,opt" json:"Quorum"` Quorum bool `protobuf:"varint,14,opt,name=Quorum" json:"Quorum"`
Time int64 `protobuf:"varint,15,opt" json:"Time"` Time int64 `protobuf:"varint,15,opt,name=Time" json:"Time"`
Stream bool `protobuf:"varint,16,opt" json:"Stream"` Stream bool `protobuf:"varint,16,opt,name=Stream" json:"Stream"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
} }
@@ -53,8 +71,8 @@ func (m *Request) String() string { return proto.CompactTextString(m) }
func (*Request) ProtoMessage() {} func (*Request) ProtoMessage() {}
type Metadata struct { type Metadata struct {
NodeID uint64 `protobuf:"varint,1,opt" json:"NodeID"` NodeID uint64 `protobuf:"varint,1,opt,name=NodeID" json:"NodeID"`
ClusterID uint64 `protobuf:"varint,2,opt" json:"ClusterID"` ClusterID uint64 `protobuf:"varint,2,opt,name=ClusterID" json:"ClusterID"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
} }
@@ -62,6 +80,10 @@ func (m *Metadata) Reset() { *m = Metadata{} }
func (m *Metadata) String() string { return proto.CompactTextString(m) } func (m *Metadata) String() string { return proto.CompactTextString(m) }
func (*Metadata) ProtoMessage() {} func (*Metadata) ProtoMessage() {}
func init() {
proto.RegisterType((*Request)(nil), "etcdserverpb.Request")
proto.RegisterType((*Metadata)(nil), "etcdserverpb.Metadata")
}
func (m *Request) Marshal() (data []byte, err error) { func (m *Request) Marshal() (data []byte, err error) {
size := m.Size() size := m.Size()
data = make([]byte, size) data = make([]byte, size)
@@ -287,8 +309,12 @@ func (m *Request) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -301,6 +327,12 @@ func (m *Request) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Request: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Request: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -308,6 +340,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
m.ID = 0 m.ID = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -324,6 +359,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var stringLen uint64 var stringLen uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -350,6 +388,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var stringLen uint64 var stringLen uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -376,6 +417,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var stringLen uint64 var stringLen uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -402,6 +446,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var v int var v int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -419,6 +466,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var stringLen uint64 var stringLen uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -445,6 +495,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
m.PrevIndex = 0 m.PrevIndex = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -461,6 +514,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var v int var v int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -479,6 +535,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
m.Expiration = 0 m.Expiration = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -495,6 +554,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var v int var v int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -512,6 +574,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
m.Since = 0 m.Since = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -528,6 +593,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var v int var v int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -545,6 +613,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var v int var v int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -562,6 +633,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var v int var v int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -579,6 +653,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
m.Time = 0 m.Time = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -595,6 +672,9 @@ func (m *Request) Unmarshal(data []byte) error {
} }
var v int var v int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -607,15 +687,7 @@ func (m *Request) Unmarshal(data []byte) error {
} }
m.Stream = bool(v != 0) m.Stream = bool(v != 0)
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipEtcdserver(data[iNdEx:]) skippy, err := skipEtcdserver(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -631,14 +703,21 @@ func (m *Request) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func (m *Metadata) Unmarshal(data []byte) error { func (m *Metadata) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -651,6 +730,12 @@ func (m *Metadata) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Metadata: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Metadata: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -658,6 +743,9 @@ func (m *Metadata) Unmarshal(data []byte) error {
} }
m.NodeID = 0 m.NodeID = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -674,6 +762,9 @@ func (m *Metadata) Unmarshal(data []byte) error {
} }
m.ClusterID = 0 m.ClusterID = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -685,15 +776,7 @@ func (m *Metadata) Unmarshal(data []byte) error {
} }
} }
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipEtcdserver(data[iNdEx:]) skippy, err := skipEtcdserver(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -709,6 +792,9 @@ func (m *Metadata) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func skipEtcdserver(data []byte) (n int, err error) { func skipEtcdserver(data []byte) (n int, err error) {
@@ -717,6 +803,9 @@ func skipEtcdserver(data []byte) (n int, err error) {
for iNdEx < l { for iNdEx < l {
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -730,7 +819,10 @@ func skipEtcdserver(data []byte) (n int, err error) {
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
switch wireType { switch wireType {
case 0: case 0:
for { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -746,6 +838,9 @@ func skipEtcdserver(data []byte) (n int, err error) {
case 2: case 2:
var length int var length int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -766,6 +861,9 @@ func skipEtcdserver(data []byte) (n int, err error) {
var innerWire uint64 var innerWire uint64
var start int = iNdEx var start int = iNdEx
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowEtcdserver
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -801,4 +899,5 @@ func skipEtcdserver(data []byte) (n int, err error) {
var ( var (
ErrInvalidLengthEtcdserver = fmt.Errorf("proto: negative length found during unmarshaling") ErrInvalidLengthEtcdserver = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowEtcdserver = fmt.Errorf("proto: integer overflow")
) )

View File

@@ -4,15 +4,20 @@
package etcdserverpb package etcdserverpb
import proto "github.com/gogo/protobuf/proto" import (
"fmt"
// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto" proto "github.com/gogo/protobuf/proto"
)
import math "math"
import io "io" import io "io"
import fmt "fmt"
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// An InternalRaftRequest is the union of all requests which can be // An InternalRaftRequest is the union of all requests which can be
// sent via raft. // sent via raft.
@@ -28,6 +33,9 @@ func (m *InternalRaftRequest) Reset() { *m = InternalRaftRequest{} }
func (m *InternalRaftRequest) String() string { return proto.CompactTextString(m) } func (m *InternalRaftRequest) String() string { return proto.CompactTextString(m) }
func (*InternalRaftRequest) ProtoMessage() {} func (*InternalRaftRequest) ProtoMessage() {}
func init() {
proto.RegisterType((*InternalRaftRequest)(nil), "etcdserverpb.InternalRaftRequest")
}
func (m *InternalRaftRequest) Marshal() (data []byte, err error) { func (m *InternalRaftRequest) Marshal() (data []byte, err error) {
size := m.Size() size := m.Size()
data = make([]byte, size) data = make([]byte, size)
@@ -162,48 +170,16 @@ func sovRaftInternal(x uint64) (n int) {
func sozRaftInternal(x uint64) (n int) { func sozRaftInternal(x uint64) (n int) {
return sovRaftInternal(uint64((x << 1) ^ uint64((int64(x) >> 63)))) return sovRaftInternal(uint64((x << 1) ^ uint64((int64(x) >> 63))))
} }
func (this *InternalRaftRequest) GetValue() interface{} {
if this.V2 != nil {
return this.V2
}
if this.Range != nil {
return this.Range
}
if this.Put != nil {
return this.Put
}
if this.DeleteRange != nil {
return this.DeleteRange
}
if this.Txn != nil {
return this.Txn
}
return nil
}
func (this *InternalRaftRequest) SetValue(value interface{}) bool {
switch vt := value.(type) {
case *Request:
this.V2 = vt
case *RangeRequest:
this.Range = vt
case *PutRequest:
this.Put = vt
case *DeleteRangeRequest:
this.DeleteRange = vt
case *TxnRequest:
this.Txn = vt
default:
return false
}
return true
}
func (m *InternalRaftRequest) Unmarshal(data []byte) error { func (m *InternalRaftRequest) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaftInternal
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -216,6 +192,12 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: InternalRaftRequest: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: InternalRaftRequest: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 2 { if wireType != 2 {
@@ -223,6 +205,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaftInternal
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -253,6 +238,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaftInternal
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -283,6 +271,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaftInternal
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -313,6 +304,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaftInternal
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -343,6 +337,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaftInternal
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -368,15 +365,7 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
} }
iNdEx = postIndex iNdEx = postIndex
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipRaftInternal(data[iNdEx:]) skippy, err := skipRaftInternal(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -391,6 +380,9 @@ func (m *InternalRaftRequest) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func skipRaftInternal(data []byte) (n int, err error) { func skipRaftInternal(data []byte) (n int, err error) {
@@ -399,6 +391,9 @@ func skipRaftInternal(data []byte) (n int, err error) {
for iNdEx < l { for iNdEx < l {
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRaftInternal
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -412,7 +407,10 @@ func skipRaftInternal(data []byte) (n int, err error) {
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
switch wireType { switch wireType {
case 0: case 0:
for { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRaftInternal
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -428,6 +426,9 @@ func skipRaftInternal(data []byte) (n int, err error) {
case 2: case 2:
var length int var length int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRaftInternal
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -448,6 +449,9 @@ func skipRaftInternal(data []byte) (n int, err error) {
var innerWire uint64 var innerWire uint64
var start int = iNdEx var start int = iNdEx
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRaftInternal
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -483,4 +487,5 @@ func skipRaftInternal(data []byte) (n int, err error) {
var ( var (
ErrInvalidLengthRaftInternal = fmt.Errorf("proto: negative length found during unmarshaling") ErrInvalidLengthRaftInternal = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowRaftInternal = fmt.Errorf("proto: integer overflow")
) )

View File

@@ -13,12 +13,9 @@ option (gogoproto.goproto_getters_all) = false;
// An InternalRaftRequest is the union of all requests which can be // An InternalRaftRequest is the union of all requests which can be
// sent via raft. // sent via raft.
message InternalRaftRequest { message InternalRaftRequest {
option (gogoproto.onlyone) = true;
oneof value {
Request v2 = 1; Request v2 = 1;
RangeRequest range = 2; RangeRequest range = 2;
PutRequest put = 3; PutRequest put = 3;
DeleteRangeRequest delete_range = 4; DeleteRangeRequest delete_range = 4;
TxnRequest txn = 5; TxnRequest txn = 5;
}
} }

File diff suppressed because it is too large Load Diff

View File

@@ -174,12 +174,17 @@ type EtcdServer struct {
// configuration is considered static for the lifetime of the EtcdServer. // configuration is considered static for the lifetime of the EtcdServer.
func NewServer(cfg *ServerConfig) (*EtcdServer, error) { func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
st := store.New(StoreClusterPrefix, StoreKeysPrefix) st := store.New(StoreClusterPrefix, StoreKeysPrefix)
var w *wal.WAL var w *wal.WAL
var n raft.Node var n raft.Node
var s *raft.MemoryStorage var s *raft.MemoryStorage
var id types.ID var id types.ID
var cl *cluster var cl *cluster
if terr := fileutil.TouchDirAll(cfg.DataDir); terr != nil {
return nil, fmt.Errorf("cannot access data directory: %v", terr)
}
// Run the migrations. // Run the migrations.
dataVer, err := version.DetectDataDir(cfg.DataDir) dataVer, err := version.DetectDataDir(cfg.DataDir)
if err != nil { if err != nil {
@@ -189,11 +194,6 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
return nil, err return nil, err
} }
err = os.MkdirAll(cfg.MemberDir(), privateDirMode)
if err != nil && err != os.ErrExist {
return nil, err
}
haveWAL := wal.Exist(cfg.WALDir()) haveWAL := wal.Exist(cfg.WALDir())
ss := snap.New(cfg.SnapDir()) ss := snap.New(cfg.SnapDir())
@@ -255,10 +255,6 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
cfg.PrintWithInitial() cfg.PrintWithInitial()
id, n, s, w = startNode(cfg, cl, cl.MemberIDs()) id, n, s, w = startNode(cfg, cl, cl.MemberIDs())
case haveWAL: case haveWAL:
if err := fileutil.IsDirWriteable(cfg.DataDir); err != nil {
return nil, fmt.Errorf("cannot write to data directory: %v", err)
}
if err := fileutil.IsDirWriteable(cfg.MemberDir()); err != nil { if err := fileutil.IsDirWriteable(cfg.MemberDir()); err != nil {
return nil, fmt.Errorf("cannot write to member directory: %v", err) return nil, fmt.Errorf("cannot write to member directory: %v", err)
} }
@@ -295,6 +291,10 @@ func NewServer(cfg *ServerConfig) (*EtcdServer, error) {
return nil, fmt.Errorf("unsupported bootstrap config") return nil, fmt.Errorf("unsupported bootstrap config")
} }
if terr := fileutil.TouchDirAll(cfg.MemberDir()); terr != nil {
return nil, fmt.Errorf("cannot access member directory: %v", terr)
}
sstats := &stats.ServerStats{ sstats := &stats.ServerStats{
Name: cfg.Name, Name: cfg.Name,
ID: id.String(), ID: id.String(),

View File

@@ -19,6 +19,7 @@ import (
pb "github.com/coreos/etcd/etcdserver/etcdserverpb" pb "github.com/coreos/etcd/etcdserver/etcdserverpb"
dstorage "github.com/coreos/etcd/storage" dstorage "github.com/coreos/etcd/storage"
"github.com/coreos/etcd/storage/storagepb"
"github.com/gogo/protobuf/proto" "github.com/gogo/protobuf/proto"
"golang.org/x/net/context" "golang.org/x/net/context"
) )
@@ -106,17 +107,24 @@ func doTxn(kv dstorage.KV, rt *pb.TxnRequest) *pb.TxnResponse {
} }
func doUnion(kv dstorage.KV, union *pb.RequestUnion) *pb.ResponseUnion { func doUnion(kv dstorage.KV, union *pb.RequestUnion) *pb.ResponseUnion {
switch { switch tv := union.Request.(type) {
case union.RequestRange != nil: case *pb.RequestUnion_RequestRange:
return &pb.ResponseUnion{ResponseRange: doRange(kv, union.RequestRange)} if tv.RequestRange != nil {
case union.RequestPut != nil: return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponseRange{ResponseRange: doRange(kv, tv.RequestRange)}}
return &pb.ResponseUnion{ResponsePut: doPut(kv, union.RequestPut)} }
case union.RequestDeleteRange != nil: case *pb.RequestUnion_RequestPut:
return &pb.ResponseUnion{ResponseDeleteRange: doDeleteRange(kv, union.RequestDeleteRange)} if tv.RequestPut != nil {
return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponsePut{ResponsePut: doPut(kv, tv.RequestPut)}}
}
case *pb.RequestUnion_RequestDeleteRange:
if tv.RequestDeleteRange != nil {
return &pb.ResponseUnion{Response: &pb.ResponseUnion_ResponseDeleteRange{ResponseDeleteRange: doDeleteRange(kv, tv.RequestDeleteRange)}}
}
default: default:
// empty union // empty union
return nil return nil
} }
return nil
} }
func doCompare(kv dstorage.KV, c *pb.Compare) (int64, bool) { func doCompare(kv dstorage.KV, c *pb.Compare) (int64, bool) {
@@ -124,20 +132,35 @@ func doCompare(kv dstorage.KV, c *pb.Compare) (int64, bool) {
if err != nil { if err != nil {
return rev, false return rev, false
} }
var ckv storagepb.KeyValue
ckv := ckvs[0] if len(ckvs) != 0 {
ckv = ckvs[0]
}
// -1 is less, 0 is equal, 1 is greater // -1 is less, 0 is equal, 1 is greater
var result int var result int
switch c.Target { switch c.Target {
case pb.Compare_VALUE: case pb.Compare_VALUE:
result = bytes.Compare(ckv.Value, c.Value) tv, _ := c.TargetUnion.(*pb.Compare_Value)
if tv != nil {
result = bytes.Compare(ckv.Value, tv.Value)
}
case pb.Compare_CREATE: case pb.Compare_CREATE:
result = compareInt64(ckv.CreateRevision, c.CreateRevision) tv, _ := c.TargetUnion.(*pb.Compare_CreateRevision)
if tv != nil {
result = compareInt64(ckv.CreateRevision, tv.CreateRevision)
}
case pb.Compare_MOD: case pb.Compare_MOD:
result = compareInt64(ckv.ModRevision, c.ModRevision) tv, _ := c.TargetUnion.(*pb.Compare_ModRevision)
if tv != nil {
result = compareInt64(ckv.ModRevision, tv.ModRevision)
}
case pb.Compare_VERSION: case pb.Compare_VERSION:
result = compareInt64(ckv.Version, c.Version) tv, _ := c.TargetUnion.(*pb.Compare_Version)
if tv != nil {
result = compareInt64(ckv.Version, tv.Version)
}
} }
switch c.Result { switch c.Result {

View File

@@ -25,6 +25,8 @@ import (
const ( const (
privateFileMode = 0600 privateFileMode = 0600
// owner can make/remove files inside the directory
privateDirMode = 0700
) )
var ( var (
@@ -55,3 +57,13 @@ func ReadDir(dirpath string) ([]string, error) {
sort.Strings(names) sort.Strings(names)
return names, nil return names, nil
} }
// TouchDirAll is simliar to os.MkdirAll. It creates directories with 0700 permission if any directory
// does not exists. TouchDirAll also ensures the given directory is writable.
func TouchDirAll(dir string) error {
err := os.MkdirAll(dir, privateDirMode)
if err != nil && err != os.ErrExist {
return err
}
return IsDirWriteable(dir)
}

View File

@@ -0,0 +1,41 @@
// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package ioutil
import (
"io"
"os"
)
// WriteAndSyncFile behaviors just like ioutil.WriteFile in standard library
// but calls Sync before closing the file. WriteAndSyncFile guarantees the data
// is synced if there is no error returned.
func WriteAndSyncFile(filename string, data []byte, perm os.FileMode) error {
f, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm)
if err != nil {
return err
}
n, err := f.Write(data)
if err == nil && n < len(data) {
err = io.ErrShortWrite
}
if err == nil {
err = f.Sync()
}
if err1 := f.Close(); err == nil {
err = err1
}
return err
}

View File

@@ -21,17 +21,19 @@ import (
"time" "time"
) )
// NewKeepAliveListener returns a listener that listens on the given address. type keepAliveConn interface {
// http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html SetKeepAlive(bool) error
func NewKeepAliveListener(addr string, scheme string, info TLSInfo) (net.Listener, error) { SetKeepAlivePeriod(d time.Duration) error
l, err := net.Listen("tcp", addr) }
if err != nil {
return nil, err
}
// NewKeepAliveListener returns a listener that listens on the given address.
// Be careful when wrap around KeepAliveListener with another Listener if TLSInfo is not nil.
// Some pkgs (like go/http) might expect Listener to return TLSConn type to start TLS handshake.
// http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/overview.html
func NewKeepAliveListener(l net.Listener, scheme string, info TLSInfo) (net.Listener, error) {
if scheme == "https" { if scheme == "https" {
if info.Empty() { if info.Empty() {
return nil, fmt.Errorf("cannot listen on TLS for %s: KeyFile and CertFile are not presented", scheme+"://"+addr) return nil, fmt.Errorf("cannot listen on TLS for given listener: KeyFile and CertFile are not presented")
} }
cfg, err := info.ServerConfig() cfg, err := info.ServerConfig()
if err != nil { if err != nil {
@@ -53,13 +55,13 @@ func (kln *keepaliveListener) Accept() (net.Conn, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
tcpc := c.(*net.TCPConn) kac := c.(keepAliveConn)
// detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl // detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl
// default on linux: 30 + 8 * 30 // default on linux: 30 + 8 * 30
// default on osx: 30 + 8 * 75 // default on osx: 30 + 8 * 75
tcpc.SetKeepAlive(true) kac.SetKeepAlive(true)
tcpc.SetKeepAlivePeriod(30 * time.Second) kac.SetKeepAlivePeriod(30 * time.Second)
return tcpc, nil return c, nil
} }
// A tlsKeepaliveListener implements a network listener (net.Listener) for TLS connections. // A tlsKeepaliveListener implements a network listener (net.Listener) for TLS connections.
@@ -75,12 +77,12 @@ func (l *tlsKeepaliveListener) Accept() (c net.Conn, err error) {
if err != nil { if err != nil {
return return
} }
tcpc := c.(*net.TCPConn) kac := c.(keepAliveConn)
// detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl // detection time: tcp_keepalive_time + tcp_keepalive_probes + tcp_keepalive_intvl
// default on linux: 30 + 8 * 30 // default on linux: 30 + 8 * 30
// default on osx: 30 + 8 * 75 // default on osx: 30 + 8 * 75
tcpc.SetKeepAlive(true) kac.SetKeepAlive(true)
tcpc.SetKeepAlivePeriod(30 * time.Second) kac.SetKeepAlivePeriod(30 * time.Second)
c = tls.Server(c, l.config) c = tls.Server(c, l.config)
return return
} }

View File

@@ -0,0 +1,70 @@
// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package netutil provides network utility functions, complementing the more
// common ones in the net package.
package transport
import (
"errors"
"net"
"sync"
"time"
)
var (
ErrNotTCP = errors.New("only tcp connections have keepalive")
)
// LimitListener returns a Listener that accepts at most n simultaneous
// connections from the provided Listener.
func LimitListener(l net.Listener, n int) net.Listener {
return &limitListener{l, make(chan struct{}, n)}
}
type limitListener struct {
net.Listener
sem chan struct{}
}
func (l *limitListener) acquire() { l.sem <- struct{}{} }
func (l *limitListener) release() { <-l.sem }
func (l *limitListener) Accept() (net.Conn, error) {
l.acquire()
c, err := l.Listener.Accept()
if err != nil {
l.release()
return nil, err
}
return &limitListenerConn{Conn: c, release: l.release}, nil
}
type limitListenerConn struct {
net.Conn
releaseOnce sync.Once
release func()
}
func (l *limitListenerConn) Close() error {
err := l.Conn.Close()
l.releaseOnce.Do(l.release)
return err
}
func (l *limitListenerConn) SetKeepAlive(doKeepAlive bool) error {
tcpc, ok := l.Conn.(*net.TCPConn)
if !ok {
return ErrNotTCP
}
return tcpc.SetKeepAlive(doKeepAlive)
}
func (l *limitListenerConn) SetKeepAlivePeriod(d time.Duration) error {
tcpc, ok := l.Conn.(*net.TCPConn)
if !ok {
return ErrNotTCP
}
return tcpc.SetKeepAlivePeriod(d)
}

View File

@@ -19,16 +19,19 @@
*/ */
package raftpb package raftpb
import proto "github.com/gogo/protobuf/proto" import (
"fmt"
proto "github.com/gogo/protobuf/proto"
)
import math "math" import math "math"
// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto"
import io "io" import io "io"
import fmt "fmt"
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf var _ = math.Inf
type EntryType int32 type EntryType int32
@@ -164,10 +167,10 @@ func (x *ConfChangeType) UnmarshalJSON(data []byte) error {
} }
type Entry struct { type Entry struct {
Type EntryType `protobuf:"varint,1,opt,enum=raftpb.EntryType" json:"Type"` Type EntryType `protobuf:"varint,1,opt,name=Type,enum=raftpb.EntryType" json:"Type"`
Term uint64 `protobuf:"varint,2,opt" json:"Term"` Term uint64 `protobuf:"varint,2,opt,name=Term" json:"Term"`
Index uint64 `protobuf:"varint,3,opt" json:"Index"` Index uint64 `protobuf:"varint,3,opt,name=Index" json:"Index"`
Data []byte `protobuf:"bytes,4,opt" json:"Data,omitempty"` Data []byte `protobuf:"bytes,4,opt,name=Data" json:"Data,omitempty"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
} }
@@ -236,10 +239,10 @@ func (m *ConfState) String() string { return proto.CompactTextString(m) }
func (*ConfState) ProtoMessage() {} func (*ConfState) ProtoMessage() {}
type ConfChange struct { type ConfChange struct {
ID uint64 `protobuf:"varint,1,opt" json:"ID"` ID uint64 `protobuf:"varint,1,opt,name=ID" json:"ID"`
Type ConfChangeType `protobuf:"varint,2,opt,enum=raftpb.ConfChangeType" json:"Type"` Type ConfChangeType `protobuf:"varint,2,opt,name=Type,enum=raftpb.ConfChangeType" json:"Type"`
NodeID uint64 `protobuf:"varint,3,opt" json:"NodeID"` NodeID uint64 `protobuf:"varint,3,opt,name=NodeID" json:"NodeID"`
Context []byte `protobuf:"bytes,4,opt" json:"Context,omitempty"` Context []byte `protobuf:"bytes,4,opt,name=Context" json:"Context,omitempty"`
XXX_unrecognized []byte `json:"-"` XXX_unrecognized []byte `json:"-"`
} }
@@ -248,6 +251,13 @@ func (m *ConfChange) String() string { return proto.CompactTextString(m) }
func (*ConfChange) ProtoMessage() {} func (*ConfChange) ProtoMessage() {}
func init() { func init() {
proto.RegisterType((*Entry)(nil), "raftpb.Entry")
proto.RegisterType((*SnapshotMetadata)(nil), "raftpb.SnapshotMetadata")
proto.RegisterType((*Snapshot)(nil), "raftpb.Snapshot")
proto.RegisterType((*Message)(nil), "raftpb.Message")
proto.RegisterType((*HardState)(nil), "raftpb.HardState")
proto.RegisterType((*ConfState)(nil), "raftpb.ConfState")
proto.RegisterType((*ConfChange)(nil), "raftpb.ConfChange")
proto.RegisterEnum("raftpb.EntryType", EntryType_name, EntryType_value) proto.RegisterEnum("raftpb.EntryType", EntryType_name, EntryType_value)
proto.RegisterEnum("raftpb.MessageType", MessageType_name, MessageType_value) proto.RegisterEnum("raftpb.MessageType", MessageType_name, MessageType_value)
proto.RegisterEnum("raftpb.ConfChangeType", ConfChangeType_name, ConfChangeType_value) proto.RegisterEnum("raftpb.ConfChangeType", ConfChangeType_name, ConfChangeType_value)
@@ -681,8 +691,12 @@ func (m *Entry) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -695,6 +709,12 @@ func (m *Entry) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Entry: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Entry: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -702,6 +722,9 @@ func (m *Entry) Unmarshal(data []byte) error {
} }
m.Type = 0 m.Type = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -718,6 +741,9 @@ func (m *Entry) Unmarshal(data []byte) error {
} }
m.Term = 0 m.Term = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -734,6 +760,9 @@ func (m *Entry) Unmarshal(data []byte) error {
} }
m.Index = 0 m.Index = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -750,6 +779,9 @@ func (m *Entry) Unmarshal(data []byte) error {
} }
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -767,18 +799,13 @@ func (m *Entry) Unmarshal(data []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Data = append([]byte{}, data[iNdEx:postIndex]...) m.Data = append(m.Data[:0], data[iNdEx:postIndex]...)
if m.Data == nil {
m.Data = []byte{}
}
iNdEx = postIndex iNdEx = postIndex
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipRaft(data[iNdEx:]) skippy, err := skipRaft(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -794,14 +821,21 @@ func (m *Entry) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func (m *SnapshotMetadata) Unmarshal(data []byte) error { func (m *SnapshotMetadata) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -814,6 +848,12 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: SnapshotMetadata: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: SnapshotMetadata: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 2 { if wireType != 2 {
@@ -821,6 +861,9 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error {
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -848,6 +891,9 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error {
} }
m.Index = 0 m.Index = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -864,6 +910,9 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error {
} }
m.Term = 0 m.Term = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -875,15 +924,7 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error {
} }
} }
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipRaft(data[iNdEx:]) skippy, err := skipRaft(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -899,14 +940,21 @@ func (m *SnapshotMetadata) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func (m *Snapshot) Unmarshal(data []byte) error { func (m *Snapshot) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -919,6 +967,12 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Snapshot: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Snapshot: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 2 { if wireType != 2 {
@@ -926,6 +980,9 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -943,7 +1000,10 @@ func (m *Snapshot) Unmarshal(data []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Data = append([]byte{}, data[iNdEx:postIndex]...) m.Data = append(m.Data[:0], data[iNdEx:postIndex]...)
if m.Data == nil {
m.Data = []byte{}
}
iNdEx = postIndex iNdEx = postIndex
case 2: case 2:
if wireType != 2 { if wireType != 2 {
@@ -951,6 +1011,9 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -973,15 +1036,7 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
iNdEx = postIndex iNdEx = postIndex
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipRaft(data[iNdEx:]) skippy, err := skipRaft(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -997,14 +1052,21 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func (m *Message) Unmarshal(data []byte) error { func (m *Message) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1017,6 +1079,12 @@ func (m *Message) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Message: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Message: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -1024,6 +1092,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
m.Type = 0 m.Type = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1040,6 +1111,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
m.To = 0 m.To = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1056,6 +1130,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
m.From = 0 m.From = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1072,6 +1149,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
m.Term = 0 m.Term = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1088,6 +1168,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
m.LogTerm = 0 m.LogTerm = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1104,6 +1187,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
m.Index = 0 m.Index = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1120,6 +1206,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1148,6 +1237,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
m.Commit = 0 m.Commit = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1164,6 +1256,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1191,6 +1286,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
var v int var v int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1208,6 +1306,9 @@ func (m *Message) Unmarshal(data []byte) error {
} }
m.RejectHint = 0 m.RejectHint = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1219,15 +1320,7 @@ func (m *Message) Unmarshal(data []byte) error {
} }
} }
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipRaft(data[iNdEx:]) skippy, err := skipRaft(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -1243,14 +1336,21 @@ func (m *Message) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func (m *HardState) Unmarshal(data []byte) error { func (m *HardState) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1263,6 +1363,12 @@ func (m *HardState) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: HardState: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: HardState: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -1270,6 +1376,9 @@ func (m *HardState) Unmarshal(data []byte) error {
} }
m.Term = 0 m.Term = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1286,6 +1395,9 @@ func (m *HardState) Unmarshal(data []byte) error {
} }
m.Vote = 0 m.Vote = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1302,6 +1414,9 @@ func (m *HardState) Unmarshal(data []byte) error {
} }
m.Commit = 0 m.Commit = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1313,15 +1428,7 @@ func (m *HardState) Unmarshal(data []byte) error {
} }
} }
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipRaft(data[iNdEx:]) skippy, err := skipRaft(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -1337,14 +1444,21 @@ func (m *HardState) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func (m *ConfState) Unmarshal(data []byte) error { func (m *ConfState) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1357,6 +1471,12 @@ func (m *ConfState) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ConfState: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ConfState: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -1364,6 +1484,9 @@ func (m *ConfState) Unmarshal(data []byte) error {
} }
var v uint64 var v uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1376,15 +1499,7 @@ func (m *ConfState) Unmarshal(data []byte) error {
} }
m.Nodes = append(m.Nodes, v) m.Nodes = append(m.Nodes, v)
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipRaft(data[iNdEx:]) skippy, err := skipRaft(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -1400,14 +1515,21 @@ func (m *ConfState) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func (m *ConfChange) Unmarshal(data []byte) error { func (m *ConfChange) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1420,6 +1542,12 @@ func (m *ConfChange) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: ConfChange: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: ConfChange: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -1427,6 +1555,9 @@ func (m *ConfChange) Unmarshal(data []byte) error {
} }
m.ID = 0 m.ID = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1443,6 +1574,9 @@ func (m *ConfChange) Unmarshal(data []byte) error {
} }
m.Type = 0 m.Type = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1459,6 +1593,9 @@ func (m *ConfChange) Unmarshal(data []byte) error {
} }
m.NodeID = 0 m.NodeID = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1475,6 +1612,9 @@ func (m *ConfChange) Unmarshal(data []byte) error {
} }
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -1492,18 +1632,13 @@ func (m *ConfChange) Unmarshal(data []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Context = append([]byte{}, data[iNdEx:postIndex]...) m.Context = append(m.Context[:0], data[iNdEx:postIndex]...)
if m.Context == nil {
m.Context = []byte{}
}
iNdEx = postIndex iNdEx = postIndex
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipRaft(data[iNdEx:]) skippy, err := skipRaft(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -1519,6 +1654,9 @@ func (m *ConfChange) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func skipRaft(data []byte) (n int, err error) { func skipRaft(data []byte) (n int, err error) {
@@ -1527,6 +1665,9 @@ func skipRaft(data []byte) (n int, err error) {
for iNdEx < l { for iNdEx < l {
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -1540,7 +1681,10 @@ func skipRaft(data []byte) (n int, err error) {
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
switch wireType { switch wireType {
case 0: case 0:
for { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -1556,6 +1700,9 @@ func skipRaft(data []byte) (n int, err error) {
case 2: case 2:
var length int var length int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -1576,6 +1723,9 @@ func skipRaft(data []byte) (n int, err error) {
var innerWire uint64 var innerWire uint64
var start int = iNdEx var start int = iNdEx
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRaft
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -1611,4 +1761,5 @@ func skipRaft(data []byte) (n int, err error) {
var ( var (
ErrInvalidLengthRaft = fmt.Errorf("proto: negative length found during unmarshaling") ErrInvalidLengthRaft = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowRaft = fmt.Errorf("proto: integer overflow")
) )

View File

@@ -13,16 +13,19 @@
*/ */
package snappb package snappb
import proto "github.com/gogo/protobuf/proto" import (
"fmt"
proto "github.com/gogo/protobuf/proto"
)
import math "math" import math "math"
// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto"
import io "io" import io "io"
import fmt "fmt"
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf var _ = math.Inf
type Snapshot struct { type Snapshot struct {
@@ -35,6 +38,9 @@ func (m *Snapshot) Reset() { *m = Snapshot{} }
func (m *Snapshot) String() string { return proto.CompactTextString(m) } func (m *Snapshot) String() string { return proto.CompactTextString(m) }
func (*Snapshot) ProtoMessage() {} func (*Snapshot) ProtoMessage() {}
func init() {
proto.RegisterType((*Snapshot)(nil), "snappb.snapshot")
}
func (m *Snapshot) Marshal() (data []byte, err error) { func (m *Snapshot) Marshal() (data []byte, err error) {
size := m.Size() size := m.Size()
data = make([]byte, size) data = make([]byte, size)
@@ -123,8 +129,12 @@ func (m *Snapshot) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSnap
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -137,6 +147,12 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: snapshot: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: snapshot: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -144,6 +160,9 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
m.Crc = 0 m.Crc = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSnap
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -160,6 +179,9 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowSnap
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -177,18 +199,13 @@ func (m *Snapshot) Unmarshal(data []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Data = append([]byte{}, data[iNdEx:postIndex]...) m.Data = append(m.Data[:0], data[iNdEx:postIndex]...)
if m.Data == nil {
m.Data = []byte{}
}
iNdEx = postIndex iNdEx = postIndex
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipSnap(data[iNdEx:]) skippy, err := skipSnap(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -204,6 +221,9 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func skipSnap(data []byte) (n int, err error) { func skipSnap(data []byte) (n int, err error) {
@@ -212,6 +232,9 @@ func skipSnap(data []byte) (n int, err error) {
for iNdEx < l { for iNdEx < l {
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowSnap
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -225,7 +248,10 @@ func skipSnap(data []byte) (n int, err error) {
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
switch wireType { switch wireType {
case 0: case 0:
for { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowSnap
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -241,6 +267,9 @@ func skipSnap(data []byte) (n int, err error) {
case 2: case 2:
var length int var length int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowSnap
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -261,6 +290,9 @@ func skipSnap(data []byte) (n int, err error) {
var innerWire uint64 var innerWire uint64
var start int = iNdEx var start int = iNdEx
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowSnap
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -296,4 +328,5 @@ func skipSnap(data []byte) (n int, err error) {
var ( var (
ErrInvalidLengthSnap = fmt.Errorf("proto: negative length found during unmarshaling") ErrInvalidLengthSnap = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowSnap = fmt.Errorf("proto: integer overflow")
) )

View File

@@ -14,15 +14,20 @@
*/ */
package storagepb package storagepb
import proto "github.com/gogo/protobuf/proto" import (
"fmt"
// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto" proto "github.com/gogo/protobuf/proto"
)
import math "math"
import io "io" import io "io"
import fmt "fmt"
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
type Event_EventType int32 type Event_EventType int32
@@ -76,6 +81,8 @@ func (m *Event) String() string { return proto.CompactTextString(m) }
func (*Event) ProtoMessage() {} func (*Event) ProtoMessage() {}
func init() { func init() {
proto.RegisterType((*KeyValue)(nil), "storagepb.KeyValue")
proto.RegisterType((*Event)(nil), "storagepb.Event")
proto.RegisterEnum("storagepb.Event_EventType", Event_EventType_name, Event_EventType_value) proto.RegisterEnum("storagepb.Event_EventType", Event_EventType_name, Event_EventType_value)
} }
func (m *KeyValue) Marshal() (data []byte, err error) { func (m *KeyValue) Marshal() (data []byte, err error) {
@@ -244,8 +251,12 @@ func (m *KeyValue) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -258,6 +269,12 @@ func (m *KeyValue) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: KeyValue: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: KeyValue: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 2 { if wireType != 2 {
@@ -265,6 +282,9 @@ func (m *KeyValue) Unmarshal(data []byte) error {
} }
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -282,7 +302,10 @@ func (m *KeyValue) Unmarshal(data []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Key = append([]byte{}, data[iNdEx:postIndex]...) m.Key = append(m.Key[:0], data[iNdEx:postIndex]...)
if m.Key == nil {
m.Key = []byte{}
}
iNdEx = postIndex iNdEx = postIndex
case 2: case 2:
if wireType != 0 { if wireType != 0 {
@@ -290,6 +313,9 @@ func (m *KeyValue) Unmarshal(data []byte) error {
} }
m.CreateRevision = 0 m.CreateRevision = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -306,6 +332,9 @@ func (m *KeyValue) Unmarshal(data []byte) error {
} }
m.ModRevision = 0 m.ModRevision = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -322,6 +351,9 @@ func (m *KeyValue) Unmarshal(data []byte) error {
} }
m.Version = 0 m.Version = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -338,6 +370,9 @@ func (m *KeyValue) Unmarshal(data []byte) error {
} }
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -355,18 +390,13 @@ func (m *KeyValue) Unmarshal(data []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Value = append([]byte{}, data[iNdEx:postIndex]...) m.Value = append(m.Value[:0], data[iNdEx:postIndex]...)
if m.Value == nil {
m.Value = []byte{}
}
iNdEx = postIndex iNdEx = postIndex
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipKv(data[iNdEx:]) skippy, err := skipKv(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -381,14 +411,21 @@ func (m *KeyValue) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func (m *Event) Unmarshal(data []byte) error { func (m *Event) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -401,6 +438,12 @@ func (m *Event) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Event: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Event: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -408,6 +451,9 @@ func (m *Event) Unmarshal(data []byte) error {
} }
m.Type = 0 m.Type = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -424,6 +470,9 @@ func (m *Event) Unmarshal(data []byte) error {
} }
var msglen int var msglen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -449,15 +498,7 @@ func (m *Event) Unmarshal(data []byte) error {
} }
iNdEx = postIndex iNdEx = postIndex
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipKv(data[iNdEx:]) skippy, err := skipKv(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -472,6 +513,9 @@ func (m *Event) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func skipKv(data []byte) (n int, err error) { func skipKv(data []byte) (n int, err error) {
@@ -480,6 +524,9 @@ func skipKv(data []byte) (n int, err error) {
for iNdEx < l { for iNdEx < l {
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -493,7 +540,10 @@ func skipKv(data []byte) (n int, err error) {
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
switch wireType { switch wireType {
case 0: case 0:
for { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -509,6 +559,9 @@ func skipKv(data []byte) (n int, err error) {
case 2: case 2:
var length int var length int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -529,6 +582,9 @@ func skipKv(data []byte) (n int, err error) {
var innerWire uint64 var innerWire uint64
var start int = iNdEx var start int = iNdEx
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowKv
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -564,4 +620,5 @@ func skipKv(data []byte) (n int, err error) {
var ( var (
ErrInvalidLengthKv = fmt.Errorf("proto: negative length found during unmarshaling") ErrInvalidLengthKv = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowKv = fmt.Errorf("proto: integer overflow")
) )

View File

@@ -27,7 +27,7 @@ import (
var ( var (
// MinClusterVersion is the min cluster version this etcd binary is compatible with. // MinClusterVersion is the min cluster version this etcd binary is compatible with.
MinClusterVersion = "2.1.0" MinClusterVersion = "2.1.0"
Version = "2.2.2+git" Version = "2.2.5"
// Git SHA Value will be set during build // Git SHA Value will be set during build
GitSHA = "Not provided (use ./build instead of go build)" GitSHA = "Not provided (use ./build instead of go build)"

View File

@@ -14,16 +14,19 @@
*/ */
package walpb package walpb
import proto "github.com/gogo/protobuf/proto" import (
"fmt"
proto "github.com/gogo/protobuf/proto"
)
import math "math" import math "math"
// discarding unused import gogoproto "github.com/coreos/etcd/Godeps/_workspace/src/gogoproto"
import io "io" import io "io"
import fmt "fmt"
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf var _ = math.Inf
type Record struct { type Record struct {
@@ -47,6 +50,10 @@ func (m *Snapshot) Reset() { *m = Snapshot{} }
func (m *Snapshot) String() string { return proto.CompactTextString(m) } func (m *Snapshot) String() string { return proto.CompactTextString(m) }
func (*Snapshot) ProtoMessage() {} func (*Snapshot) ProtoMessage() {}
func init() {
proto.RegisterType((*Record)(nil), "walpb.Record")
proto.RegisterType((*Snapshot)(nil), "walpb.Snapshot")
}
func (m *Record) Marshal() (data []byte, err error) { func (m *Record) Marshal() (data []byte, err error) {
size := m.Size() size := m.Size()
data = make([]byte, size) data = make([]byte, size)
@@ -177,8 +184,12 @@ func (m *Record) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -191,6 +202,12 @@ func (m *Record) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Record: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Record: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -198,6 +215,9 @@ func (m *Record) Unmarshal(data []byte) error {
} }
m.Type = 0 m.Type = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -214,6 +234,9 @@ func (m *Record) Unmarshal(data []byte) error {
} }
m.Crc = 0 m.Crc = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -230,6 +253,9 @@ func (m *Record) Unmarshal(data []byte) error {
} }
var byteLen int var byteLen int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -247,18 +273,13 @@ func (m *Record) Unmarshal(data []byte) error {
if postIndex > l { if postIndex > l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
m.Data = append([]byte{}, data[iNdEx:postIndex]...) m.Data = append(m.Data[:0], data[iNdEx:postIndex]...)
if m.Data == nil {
m.Data = []byte{}
}
iNdEx = postIndex iNdEx = postIndex
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipRecord(data[iNdEx:]) skippy, err := skipRecord(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -274,14 +295,21 @@ func (m *Record) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func (m *Snapshot) Unmarshal(data []byte) error { func (m *Snapshot) Unmarshal(data []byte) error {
l := len(data) l := len(data)
iNdEx := 0 iNdEx := 0
for iNdEx < l { for iNdEx < l {
preIndex := iNdEx
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -294,6 +322,12 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
fieldNum := int32(wire >> 3) fieldNum := int32(wire >> 3)
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
if wireType == 4 {
return fmt.Errorf("proto: Snapshot: wiretype end group for non-group")
}
if fieldNum <= 0 {
return fmt.Errorf("proto: Snapshot: illegal tag %d (wire type %d)", fieldNum, wire)
}
switch fieldNum { switch fieldNum {
case 1: case 1:
if wireType != 0 { if wireType != 0 {
@@ -301,6 +335,9 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
m.Index = 0 m.Index = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -317,6 +354,9 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
m.Term = 0 m.Term = 0
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return io.ErrUnexpectedEOF return io.ErrUnexpectedEOF
} }
@@ -328,15 +368,7 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
} }
default: default:
var sizeOfWire int iNdEx = preIndex
for {
sizeOfWire++
wire >>= 7
if wire == 0 {
break
}
}
iNdEx -= sizeOfWire
skippy, err := skipRecord(data[iNdEx:]) skippy, err := skipRecord(data[iNdEx:])
if err != nil { if err != nil {
return err return err
@@ -352,6 +384,9 @@ func (m *Snapshot) Unmarshal(data []byte) error {
} }
} }
if iNdEx > l {
return io.ErrUnexpectedEOF
}
return nil return nil
} }
func skipRecord(data []byte) (n int, err error) { func skipRecord(data []byte) (n int, err error) {
@@ -360,6 +395,9 @@ func skipRecord(data []byte) (n int, err error) {
for iNdEx < l { for iNdEx < l {
var wire uint64 var wire uint64
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -373,7 +411,10 @@ func skipRecord(data []byte) (n int, err error) {
wireType := int(wire & 0x7) wireType := int(wire & 0x7)
switch wireType { switch wireType {
case 0: case 0:
for { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -389,6 +430,9 @@ func skipRecord(data []byte) (n int, err error) {
case 2: case 2:
var length int var length int
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -409,6 +453,9 @@ func skipRecord(data []byte) (n int, err error) {
var innerWire uint64 var innerWire uint64
var start int = iNdEx var start int = iNdEx
for shift := uint(0); ; shift += 7 { for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return 0, ErrIntOverflowRecord
}
if iNdEx >= l { if iNdEx >= l {
return 0, io.ErrUnexpectedEOF return 0, io.ErrUnexpectedEOF
} }
@@ -444,4 +491,5 @@ func skipRecord(data []byte) (n int, err error) {
var ( var (
ErrInvalidLengthRecord = fmt.Errorf("proto: negative length found during unmarshaling") ErrInvalidLengthRecord = fmt.Errorf("proto: negative length found during unmarshaling")
ErrIntOverflowRecord = fmt.Errorf("proto: integer overflow")
) )

View File

@@ -200,3 +200,28 @@ Apache License
See the License for the specific language governing permissions and See the License for the specific language governing permissions and
limitations under the License. limitations under the License.
Third Party Sources Bundled
This project includes code derived from the MIT licensed naegelejd/go-acl
project. Here's a copy of its license:
Copyright (c) 2015 Joseph Naegele
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -2,8 +2,6 @@
The API defined here is proposed, experimental, and (for now) subject to change at any time. The API defined here is proposed, experimental, and (for now) subject to change at any time.
**Do not use it.**
If you think you want to use it, or for any other queries, contact <rkt-dev@googlegroups.com> or file an [issue](https://github.com/coreos/rkt/issues/new) If you think you want to use it, or for any other queries, contact <rkt-dev@googlegroups.com> or file an [issue](https://github.com/coreos/rkt/issues/new)
For more information, see: For more information, see:

View File

@@ -51,6 +51,10 @@ var _ = proto.Marshal
var _ = fmt.Errorf var _ = fmt.Errorf
var _ = math.Inf var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
const _ = proto.ProtoPackageIsVersion1
// ImageType defines the supported image type. // ImageType defines the supported image type.
type ImageType int32 type ImageType int32
@@ -77,6 +81,7 @@ var ImageType_value = map[string]int32{
func (x ImageType) String() string { func (x ImageType) String() string {
return proto.EnumName(ImageType_name, int32(x)) return proto.EnumName(ImageType_name, int32(x))
} }
func (ImageType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
// AppState defines the possible states of the app. // AppState defines the possible states of the app.
type AppState int32 type AppState int32
@@ -101,6 +106,7 @@ var AppState_value = map[string]int32{
func (x AppState) String() string { func (x AppState) String() string {
return proto.EnumName(AppState_name, int32(x)) return proto.EnumName(AppState_name, int32(x))
} }
func (AppState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
// PodState defines the possible states of the pod. // PodState defines the possible states of the pod.
// See https://github.com/coreos/rkt/blob/master/Documentation/devel/pod-lifecycle.md for a detailed // See https://github.com/coreos/rkt/blob/master/Documentation/devel/pod-lifecycle.md for a detailed
@@ -148,6 +154,7 @@ var PodState_value = map[string]int32{
func (x PodState) String() string { func (x PodState) String() string {
return proto.EnumName(PodState_name, int32(x)) return proto.EnumName(PodState_name, int32(x))
} }
func (PodState) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
// EventType defines the type of the events that will be received via ListenEvents(). // EventType defines the type of the events that will be received via ListenEvents().
type EventType int32 type EventType int32
@@ -196,6 +203,7 @@ var EventType_value = map[string]int32{
func (x EventType) String() string { func (x EventType) String() string {
return proto.EnumName(EventType_name, int32(x)) return proto.EnumName(EventType_name, int32(x))
} }
func (EventType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
// ImageFormat defines the format of the image. // ImageFormat defines the format of the image.
type ImageFormat struct { type ImageFormat struct {
@@ -205,9 +213,10 @@ type ImageFormat struct {
Version string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"` Version string `protobuf:"bytes,2,opt,name=version" json:"version,omitempty"`
} }
func (m *ImageFormat) Reset() { *m = ImageFormat{} } func (m *ImageFormat) Reset() { *m = ImageFormat{} }
func (m *ImageFormat) String() string { return proto.CompactTextString(m) } func (m *ImageFormat) String() string { return proto.CompactTextString(m) }
func (*ImageFormat) ProtoMessage() {} func (*ImageFormat) ProtoMessage() {}
func (*ImageFormat) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
// Image describes the image's information. // Image describes the image's information.
type Image struct { type Image struct {
@@ -232,9 +241,10 @@ type Image struct {
Annotations []*KeyValue `protobuf:"bytes,8,rep,name=annotations" json:"annotations,omitempty"` Annotations []*KeyValue `protobuf:"bytes,8,rep,name=annotations" json:"annotations,omitempty"`
} }
func (m *Image) Reset() { *m = Image{} } func (m *Image) Reset() { *m = Image{} }
func (m *Image) String() string { return proto.CompactTextString(m) } func (m *Image) String() string { return proto.CompactTextString(m) }
func (*Image) ProtoMessage() {} func (*Image) ProtoMessage() {}
func (*Image) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
func (m *Image) GetBaseFormat() *ImageFormat { func (m *Image) GetBaseFormat() *ImageFormat {
if m != nil { if m != nil {
@@ -260,9 +270,10 @@ type Network struct {
Ipv6 string `protobuf:"bytes,3,opt,name=ipv6" json:"ipv6,omitempty"` Ipv6 string `protobuf:"bytes,3,opt,name=ipv6" json:"ipv6,omitempty"`
} }
func (m *Network) Reset() { *m = Network{} } func (m *Network) Reset() { *m = Network{} }
func (m *Network) String() string { return proto.CompactTextString(m) } func (m *Network) String() string { return proto.CompactTextString(m) }
func (*Network) ProtoMessage() {} func (*Network) ProtoMessage() {}
func (*Network) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
// App describes the information of an app that's running in a pod. // App describes the information of an app that's running in a pod.
type App struct { type App struct {
@@ -280,9 +291,10 @@ type App struct {
Annotations []*KeyValue `protobuf:"bytes,5,rep,name=annotations" json:"annotations,omitempty"` Annotations []*KeyValue `protobuf:"bytes,5,rep,name=annotations" json:"annotations,omitempty"`
} }
func (m *App) Reset() { *m = App{} } func (m *App) Reset() { *m = App{} }
func (m *App) String() string { return proto.CompactTextString(m) } func (m *App) String() string { return proto.CompactTextString(m) }
func (*App) ProtoMessage() {} func (*App) ProtoMessage() {}
func (*App) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
func (m *App) GetImage() *Image { func (m *App) GetImage() *Image {
if m != nil { if m != nil {
@@ -327,9 +339,10 @@ type Pod struct {
Annotations []*KeyValue `protobuf:"bytes,7,rep,name=annotations" json:"annotations,omitempty"` Annotations []*KeyValue `protobuf:"bytes,7,rep,name=annotations" json:"annotations,omitempty"`
} }
func (m *Pod) Reset() { *m = Pod{} } func (m *Pod) Reset() { *m = Pod{} }
func (m *Pod) String() string { return proto.CompactTextString(m) } func (m *Pod) String() string { return proto.CompactTextString(m) }
func (*Pod) ProtoMessage() {} func (*Pod) ProtoMessage() {}
func (*Pod) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
func (m *Pod) GetApps() []*App { func (m *Pod) GetApps() []*App {
if m != nil { if m != nil {
@@ -354,14 +367,15 @@ func (m *Pod) GetAnnotations() []*KeyValue {
type KeyValue struct { type KeyValue struct {
// Key part of the key-value pair. // Key part of the key-value pair.
Key string `protobuf:"bytes,1,opt" json:"Key,omitempty"` Key string `protobuf:"bytes,1,opt,name=Key" json:"Key,omitempty"`
// Value part of the key-value pair. // Value part of the key-value pair.
Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"` Value string `protobuf:"bytes,2,opt,name=value" json:"value,omitempty"`
} }
func (m *KeyValue) Reset() { *m = KeyValue{} } func (m *KeyValue) Reset() { *m = KeyValue{} }
func (m *KeyValue) String() string { return proto.CompactTextString(m) } func (m *KeyValue) String() string { return proto.CompactTextString(m) }
func (*KeyValue) ProtoMessage() {} func (*KeyValue) ProtoMessage() {}
func (*KeyValue) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
// PodFilter defines the condition that the returned pods need to satisfy in ListPods(). // PodFilter defines the condition that the returned pods need to satisfy in ListPods().
// The conditions are combined by 'AND', and different filters are combined by 'OR'. // The conditions are combined by 'AND', and different filters are combined by 'OR'.
@@ -380,9 +394,10 @@ type PodFilter struct {
Annotations []*KeyValue `protobuf:"bytes,6,rep,name=annotations" json:"annotations,omitempty"` Annotations []*KeyValue `protobuf:"bytes,6,rep,name=annotations" json:"annotations,omitempty"`
} }
func (m *PodFilter) Reset() { *m = PodFilter{} } func (m *PodFilter) Reset() { *m = PodFilter{} }
func (m *PodFilter) String() string { return proto.CompactTextString(m) } func (m *PodFilter) String() string { return proto.CompactTextString(m) }
func (*PodFilter) ProtoMessage() {} func (*PodFilter) ProtoMessage() {}
func (*PodFilter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
func (m *PodFilter) GetAnnotations() []*KeyValue { func (m *PodFilter) GetAnnotations() []*KeyValue {
if m != nil { if m != nil {
@@ -413,11 +428,14 @@ type ImageFilter struct {
ImportedBefore int64 `protobuf:"varint,7,opt,name=imported_before" json:"imported_before,omitempty"` ImportedBefore int64 `protobuf:"varint,7,opt,name=imported_before" json:"imported_before,omitempty"`
// If not empty, the images that have all of the annotations will be returned. // If not empty, the images that have all of the annotations will be returned.
Annotations []*KeyValue `protobuf:"bytes,8,rep,name=annotations" json:"annotations,omitempty"` Annotations []*KeyValue `protobuf:"bytes,8,rep,name=annotations" json:"annotations,omitempty"`
// If not empty, the images that have any of the exact full names will be returned.
FullNames []string `protobuf:"bytes,9,rep,name=full_names" json:"full_names,omitempty"`
} }
func (m *ImageFilter) Reset() { *m = ImageFilter{} } func (m *ImageFilter) Reset() { *m = ImageFilter{} }
func (m *ImageFilter) String() string { return proto.CompactTextString(m) } func (m *ImageFilter) String() string { return proto.CompactTextString(m) }
func (*ImageFilter) ProtoMessage() {} func (*ImageFilter) ProtoMessage() {}
func (*ImageFilter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *ImageFilter) GetLabels() []*KeyValue { func (m *ImageFilter) GetLabels() []*KeyValue {
if m != nil { if m != nil {
@@ -443,9 +461,10 @@ type Info struct {
ApiVersion string `protobuf:"bytes,3,opt,name=api_version" json:"api_version,omitempty"` ApiVersion string `protobuf:"bytes,3,opt,name=api_version" json:"api_version,omitempty"`
} }
func (m *Info) Reset() { *m = Info{} } func (m *Info) Reset() { *m = Info{} }
func (m *Info) String() string { return proto.CompactTextString(m) } func (m *Info) String() string { return proto.CompactTextString(m) }
func (*Info) ProtoMessage() {} func (*Info) ProtoMessage() {}
func (*Info) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
// Event describes the events that will be received via ListenEvents(). // Event describes the events that will be received via ListenEvents().
type Event struct { type Event struct {
@@ -466,9 +485,10 @@ type Event struct {
Data []*KeyValue `protobuf:"bytes,5,rep,name=data" json:"data,omitempty"` Data []*KeyValue `protobuf:"bytes,5,rep,name=data" json:"data,omitempty"`
} }
func (m *Event) Reset() { *m = Event{} } func (m *Event) Reset() { *m = Event{} }
func (m *Event) String() string { return proto.CompactTextString(m) } func (m *Event) String() string { return proto.CompactTextString(m) }
func (*Event) ProtoMessage() {} func (*Event) ProtoMessage() {}
func (*Event) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
func (m *Event) GetData() []*KeyValue { func (m *Event) GetData() []*KeyValue {
if m != nil { if m != nil {
@@ -495,26 +515,29 @@ type EventFilter struct {
UntilTime int64 `protobuf:"varint,5,opt,name=until_time" json:"until_time,omitempty"` UntilTime int64 `protobuf:"varint,5,opt,name=until_time" json:"until_time,omitempty"`
} }
func (m *EventFilter) Reset() { *m = EventFilter{} } func (m *EventFilter) Reset() { *m = EventFilter{} }
func (m *EventFilter) String() string { return proto.CompactTextString(m) } func (m *EventFilter) String() string { return proto.CompactTextString(m) }
func (*EventFilter) ProtoMessage() {} func (*EventFilter) ProtoMessage() {}
func (*EventFilter) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
// Request for GetInfo(). // Request for GetInfo().
type GetInfoRequest struct { type GetInfoRequest struct {
} }
func (m *GetInfoRequest) Reset() { *m = GetInfoRequest{} } func (m *GetInfoRequest) Reset() { *m = GetInfoRequest{} }
func (m *GetInfoRequest) String() string { return proto.CompactTextString(m) } func (m *GetInfoRequest) String() string { return proto.CompactTextString(m) }
func (*GetInfoRequest) ProtoMessage() {} func (*GetInfoRequest) ProtoMessage() {}
func (*GetInfoRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
// Response for GetInfo(). // Response for GetInfo().
type GetInfoResponse struct { type GetInfoResponse struct {
Info *Info `protobuf:"bytes,1,opt,name=info" json:"info,omitempty"` Info *Info `protobuf:"bytes,1,opt,name=info" json:"info,omitempty"`
} }
func (m *GetInfoResponse) Reset() { *m = GetInfoResponse{} } func (m *GetInfoResponse) Reset() { *m = GetInfoResponse{} }
func (m *GetInfoResponse) String() string { return proto.CompactTextString(m) } func (m *GetInfoResponse) String() string { return proto.CompactTextString(m) }
func (*GetInfoResponse) ProtoMessage() {} func (*GetInfoResponse) ProtoMessage() {}
func (*GetInfoResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
func (m *GetInfoResponse) GetInfo() *Info { func (m *GetInfoResponse) GetInfo() *Info {
if m != nil { if m != nil {
@@ -529,9 +552,10 @@ type ListPodsRequest struct {
Detail bool `protobuf:"varint,2,opt,name=detail" json:"detail,omitempty"` Detail bool `protobuf:"varint,2,opt,name=detail" json:"detail,omitempty"`
} }
func (m *ListPodsRequest) Reset() { *m = ListPodsRequest{} } func (m *ListPodsRequest) Reset() { *m = ListPodsRequest{} }
func (m *ListPodsRequest) String() string { return proto.CompactTextString(m) } func (m *ListPodsRequest) String() string { return proto.CompactTextString(m) }
func (*ListPodsRequest) ProtoMessage() {} func (*ListPodsRequest) ProtoMessage() {}
func (*ListPodsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
func (m *ListPodsRequest) GetFilters() []*PodFilter { func (m *ListPodsRequest) GetFilters() []*PodFilter {
if m != nil { if m != nil {
@@ -545,9 +569,10 @@ type ListPodsResponse struct {
Pods []*Pod `protobuf:"bytes,1,rep,name=pods" json:"pods,omitempty"` Pods []*Pod `protobuf:"bytes,1,rep,name=pods" json:"pods,omitempty"`
} }
func (m *ListPodsResponse) Reset() { *m = ListPodsResponse{} } func (m *ListPodsResponse) Reset() { *m = ListPodsResponse{} }
func (m *ListPodsResponse) String() string { return proto.CompactTextString(m) } func (m *ListPodsResponse) String() string { return proto.CompactTextString(m) }
func (*ListPodsResponse) ProtoMessage() {} func (*ListPodsResponse) ProtoMessage() {}
func (*ListPodsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{14} }
func (m *ListPodsResponse) GetPods() []*Pod { func (m *ListPodsResponse) GetPods() []*Pod {
if m != nil { if m != nil {
@@ -562,18 +587,20 @@ type InspectPodRequest struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
} }
func (m *InspectPodRequest) Reset() { *m = InspectPodRequest{} } func (m *InspectPodRequest) Reset() { *m = InspectPodRequest{} }
func (m *InspectPodRequest) String() string { return proto.CompactTextString(m) } func (m *InspectPodRequest) String() string { return proto.CompactTextString(m) }
func (*InspectPodRequest) ProtoMessage() {} func (*InspectPodRequest) ProtoMessage() {}
func (*InspectPodRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{15} }
// Response for InspectPod(). // Response for InspectPod().
type InspectPodResponse struct { type InspectPodResponse struct {
Pod *Pod `protobuf:"bytes,1,opt,name=pod" json:"pod,omitempty"` Pod *Pod `protobuf:"bytes,1,opt,name=pod" json:"pod,omitempty"`
} }
func (m *InspectPodResponse) Reset() { *m = InspectPodResponse{} } func (m *InspectPodResponse) Reset() { *m = InspectPodResponse{} }
func (m *InspectPodResponse) String() string { return proto.CompactTextString(m) } func (m *InspectPodResponse) String() string { return proto.CompactTextString(m) }
func (*InspectPodResponse) ProtoMessage() {} func (*InspectPodResponse) ProtoMessage() {}
func (*InspectPodResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{16} }
func (m *InspectPodResponse) GetPod() *Pod { func (m *InspectPodResponse) GetPod() *Pod {
if m != nil { if m != nil {
@@ -588,9 +615,10 @@ type ListImagesRequest struct {
Detail bool `protobuf:"varint,2,opt,name=detail" json:"detail,omitempty"` Detail bool `protobuf:"varint,2,opt,name=detail" json:"detail,omitempty"`
} }
func (m *ListImagesRequest) Reset() { *m = ListImagesRequest{} } func (m *ListImagesRequest) Reset() { *m = ListImagesRequest{} }
func (m *ListImagesRequest) String() string { return proto.CompactTextString(m) } func (m *ListImagesRequest) String() string { return proto.CompactTextString(m) }
func (*ListImagesRequest) ProtoMessage() {} func (*ListImagesRequest) ProtoMessage() {}
func (*ListImagesRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{17} }
func (m *ListImagesRequest) GetFilters() []*ImageFilter { func (m *ListImagesRequest) GetFilters() []*ImageFilter {
if m != nil { if m != nil {
@@ -604,9 +632,10 @@ type ListImagesResponse struct {
Images []*Image `protobuf:"bytes,1,rep,name=images" json:"images,omitempty"` Images []*Image `protobuf:"bytes,1,rep,name=images" json:"images,omitempty"`
} }
func (m *ListImagesResponse) Reset() { *m = ListImagesResponse{} } func (m *ListImagesResponse) Reset() { *m = ListImagesResponse{} }
func (m *ListImagesResponse) String() string { return proto.CompactTextString(m) } func (m *ListImagesResponse) String() string { return proto.CompactTextString(m) }
func (*ListImagesResponse) ProtoMessage() {} func (*ListImagesResponse) ProtoMessage() {}
func (*ListImagesResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{18} }
func (m *ListImagesResponse) GetImages() []*Image { func (m *ListImagesResponse) GetImages() []*Image {
if m != nil { if m != nil {
@@ -620,18 +649,20 @@ type InspectImageRequest struct {
Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"` Id string `protobuf:"bytes,1,opt,name=id" json:"id,omitempty"`
} }
func (m *InspectImageRequest) Reset() { *m = InspectImageRequest{} } func (m *InspectImageRequest) Reset() { *m = InspectImageRequest{} }
func (m *InspectImageRequest) String() string { return proto.CompactTextString(m) } func (m *InspectImageRequest) String() string { return proto.CompactTextString(m) }
func (*InspectImageRequest) ProtoMessage() {} func (*InspectImageRequest) ProtoMessage() {}
func (*InspectImageRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{19} }
// Response for InspectImage(). // Response for InspectImage().
type InspectImageResponse struct { type InspectImageResponse struct {
Image *Image `protobuf:"bytes,1,opt,name=image" json:"image,omitempty"` Image *Image `protobuf:"bytes,1,opt,name=image" json:"image,omitempty"`
} }
func (m *InspectImageResponse) Reset() { *m = InspectImageResponse{} } func (m *InspectImageResponse) Reset() { *m = InspectImageResponse{} }
func (m *InspectImageResponse) String() string { return proto.CompactTextString(m) } func (m *InspectImageResponse) String() string { return proto.CompactTextString(m) }
func (*InspectImageResponse) ProtoMessage() {} func (*InspectImageResponse) ProtoMessage() {}
func (*InspectImageResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{20} }
func (m *InspectImageResponse) GetImage() *Image { func (m *InspectImageResponse) GetImage() *Image {
if m != nil { if m != nil {
@@ -645,9 +676,10 @@ type ListenEventsRequest struct {
Filter *EventFilter `protobuf:"bytes,1,opt,name=filter" json:"filter,omitempty"` Filter *EventFilter `protobuf:"bytes,1,opt,name=filter" json:"filter,omitempty"`
} }
func (m *ListenEventsRequest) Reset() { *m = ListenEventsRequest{} } func (m *ListenEventsRequest) Reset() { *m = ListenEventsRequest{} }
func (m *ListenEventsRequest) String() string { return proto.CompactTextString(m) } func (m *ListenEventsRequest) String() string { return proto.CompactTextString(m) }
func (*ListenEventsRequest) ProtoMessage() {} func (*ListenEventsRequest) ProtoMessage() {}
func (*ListenEventsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{21} }
func (m *ListenEventsRequest) GetFilter() *EventFilter { func (m *ListenEventsRequest) GetFilter() *EventFilter {
if m != nil { if m != nil {
@@ -662,9 +694,10 @@ type ListenEventsResponse struct {
Events []*Event `protobuf:"bytes,1,rep,name=events" json:"events,omitempty"` Events []*Event `protobuf:"bytes,1,rep,name=events" json:"events,omitempty"`
} }
func (m *ListenEventsResponse) Reset() { *m = ListenEventsResponse{} } func (m *ListenEventsResponse) Reset() { *m = ListenEventsResponse{} }
func (m *ListenEventsResponse) String() string { return proto.CompactTextString(m) } func (m *ListenEventsResponse) String() string { return proto.CompactTextString(m) }
func (*ListenEventsResponse) ProtoMessage() {} func (*ListenEventsResponse) ProtoMessage() {}
func (*ListenEventsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{22} }
func (m *ListenEventsResponse) GetEvents() []*Event { func (m *ListenEventsResponse) GetEvents() []*Event {
if m != nil { if m != nil {
@@ -694,9 +727,10 @@ type GetLogsRequest struct {
UntilTime int64 `protobuf:"varint,6,opt,name=until_time" json:"until_time,omitempty"` UntilTime int64 `protobuf:"varint,6,opt,name=until_time" json:"until_time,omitempty"`
} }
func (m *GetLogsRequest) Reset() { *m = GetLogsRequest{} } func (m *GetLogsRequest) Reset() { *m = GetLogsRequest{} }
func (m *GetLogsRequest) String() string { return proto.CompactTextString(m) } func (m *GetLogsRequest) String() string { return proto.CompactTextString(m) }
func (*GetLogsRequest) ProtoMessage() {} func (*GetLogsRequest) ProtoMessage() {}
func (*GetLogsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{23} }
// Response for GetLogs(). // Response for GetLogs().
type GetLogsResponse struct { type GetLogsResponse struct {
@@ -704,11 +738,37 @@ type GetLogsResponse struct {
Lines []string `protobuf:"bytes,1,rep,name=lines" json:"lines,omitempty"` Lines []string `protobuf:"bytes,1,rep,name=lines" json:"lines,omitempty"`
} }
func (m *GetLogsResponse) Reset() { *m = GetLogsResponse{} } func (m *GetLogsResponse) Reset() { *m = GetLogsResponse{} }
func (m *GetLogsResponse) String() string { return proto.CompactTextString(m) } func (m *GetLogsResponse) String() string { return proto.CompactTextString(m) }
func (*GetLogsResponse) ProtoMessage() {} func (*GetLogsResponse) ProtoMessage() {}
func (*GetLogsResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{24} }
func init() { func init() {
proto.RegisterType((*ImageFormat)(nil), "v1alpha.ImageFormat")
proto.RegisterType((*Image)(nil), "v1alpha.Image")
proto.RegisterType((*Network)(nil), "v1alpha.Network")
proto.RegisterType((*App)(nil), "v1alpha.App")
proto.RegisterType((*Pod)(nil), "v1alpha.Pod")
proto.RegisterType((*KeyValue)(nil), "v1alpha.KeyValue")
proto.RegisterType((*PodFilter)(nil), "v1alpha.PodFilter")
proto.RegisterType((*ImageFilter)(nil), "v1alpha.ImageFilter")
proto.RegisterType((*Info)(nil), "v1alpha.Info")
proto.RegisterType((*Event)(nil), "v1alpha.Event")
proto.RegisterType((*EventFilter)(nil), "v1alpha.EventFilter")
proto.RegisterType((*GetInfoRequest)(nil), "v1alpha.GetInfoRequest")
proto.RegisterType((*GetInfoResponse)(nil), "v1alpha.GetInfoResponse")
proto.RegisterType((*ListPodsRequest)(nil), "v1alpha.ListPodsRequest")
proto.RegisterType((*ListPodsResponse)(nil), "v1alpha.ListPodsResponse")
proto.RegisterType((*InspectPodRequest)(nil), "v1alpha.InspectPodRequest")
proto.RegisterType((*InspectPodResponse)(nil), "v1alpha.InspectPodResponse")
proto.RegisterType((*ListImagesRequest)(nil), "v1alpha.ListImagesRequest")
proto.RegisterType((*ListImagesResponse)(nil), "v1alpha.ListImagesResponse")
proto.RegisterType((*InspectImageRequest)(nil), "v1alpha.InspectImageRequest")
proto.RegisterType((*InspectImageResponse)(nil), "v1alpha.InspectImageResponse")
proto.RegisterType((*ListenEventsRequest)(nil), "v1alpha.ListenEventsRequest")
proto.RegisterType((*ListenEventsResponse)(nil), "v1alpha.ListenEventsResponse")
proto.RegisterType((*GetLogsRequest)(nil), "v1alpha.GetLogsRequest")
proto.RegisterType((*GetLogsResponse)(nil), "v1alpha.GetLogsResponse")
proto.RegisterEnum("v1alpha.ImageType", ImageType_name, ImageType_value) proto.RegisterEnum("v1alpha.ImageType", ImageType_name, ImageType_value)
proto.RegisterEnum("v1alpha.AppState", AppState_name, AppState_value) proto.RegisterEnum("v1alpha.AppState", AppState_name, AppState_value)
proto.RegisterEnum("v1alpha.PodState", PodState_name, PodState_value) proto.RegisterEnum("v1alpha.PodState", PodState_name, PodState_value)
@@ -890,9 +950,9 @@ func RegisterPublicAPIServer(s *grpc.Server, srv PublicAPIServer) {
s.RegisterService(&_PublicAPI_serviceDesc, srv) s.RegisterService(&_PublicAPI_serviceDesc, srv)
} }
func _PublicAPI_GetInfo_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { func _PublicAPI_GetInfo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
in := new(GetInfoRequest) in := new(GetInfoRequest)
if err := codec.Unmarshal(buf, in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
out, err := srv.(PublicAPIServer).GetInfo(ctx, in) out, err := srv.(PublicAPIServer).GetInfo(ctx, in)
@@ -902,9 +962,9 @@ func _PublicAPI_GetInfo_Handler(srv interface{}, ctx context.Context, codec grpc
return out, nil return out, nil
} }
func _PublicAPI_ListPods_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { func _PublicAPI_ListPods_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
in := new(ListPodsRequest) in := new(ListPodsRequest)
if err := codec.Unmarshal(buf, in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
out, err := srv.(PublicAPIServer).ListPods(ctx, in) out, err := srv.(PublicAPIServer).ListPods(ctx, in)
@@ -914,9 +974,9 @@ func _PublicAPI_ListPods_Handler(srv interface{}, ctx context.Context, codec grp
return out, nil return out, nil
} }
func _PublicAPI_InspectPod_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { func _PublicAPI_InspectPod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
in := new(InspectPodRequest) in := new(InspectPodRequest)
if err := codec.Unmarshal(buf, in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
out, err := srv.(PublicAPIServer).InspectPod(ctx, in) out, err := srv.(PublicAPIServer).InspectPod(ctx, in)
@@ -926,9 +986,9 @@ func _PublicAPI_InspectPod_Handler(srv interface{}, ctx context.Context, codec g
return out, nil return out, nil
} }
func _PublicAPI_ListImages_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { func _PublicAPI_ListImages_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
in := new(ListImagesRequest) in := new(ListImagesRequest)
if err := codec.Unmarshal(buf, in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
out, err := srv.(PublicAPIServer).ListImages(ctx, in) out, err := srv.(PublicAPIServer).ListImages(ctx, in)
@@ -938,9 +998,9 @@ func _PublicAPI_ListImages_Handler(srv interface{}, ctx context.Context, codec g
return out, nil return out, nil
} }
func _PublicAPI_InspectImage_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { func _PublicAPI_InspectImage_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
in := new(InspectImageRequest) in := new(InspectImageRequest)
if err := codec.Unmarshal(buf, in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
out, err := srv.(PublicAPIServer).InspectImage(ctx, in) out, err := srv.(PublicAPIServer).InspectImage(ctx, in)
@@ -1030,3 +1090,90 @@ var _PublicAPI_serviceDesc = grpc.ServiceDesc{
}, },
}, },
} }
var fileDescriptor0 = []byte{
// 1318 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0x94, 0x57, 0x4d, 0x72, 0xdb, 0x46,
0x13, 0x35, 0x08, 0x82, 0x3f, 0x4d, 0x9a, 0x02, 0x47, 0xb2, 0x45, 0xd3, 0x7f, 0x32, 0xbe, 0x2f,
0x2e, 0x47, 0x0b, 0x25, 0x91, 0x1d, 0x6f, 0x52, 0x95, 0x32, 0x25, 0x41, 0x2a, 0xc6, 0x12, 0xc9,
0xa2, 0x69, 0x55, 0xbc, 0x42, 0x41, 0xe2, 0xd0, 0x41, 0x89, 0x04, 0x10, 0x02, 0x92, 0xad, 0x2c,
0x73, 0x81, 0x5c, 0x21, 0xb7, 0x48, 0x55, 0x36, 0xb9, 0x41, 0x6e, 0x91, 0x7b, 0xa4, 0x67, 0x30,
0x00, 0x06, 0x20, 0xb8, 0xc8, 0x8e, 0xe8, 0xee, 0x79, 0xfd, 0xba, 0x7b, 0xfa, 0x01, 0x84, 0xba,
0xed, 0x3b, 0x7b, 0xfe, 0xd2, 0x0b, 0x3d, 0x52, 0xbd, 0xf9, 0xc6, 0x9e, 0xfb, 0x3f, 0xd9, 0xc6,
0x1b, 0x68, 0xf4, 0x17, 0xf6, 0x47, 0x7a, 0xec, 0x2d, 0x17, 0x76, 0x48, 0x76, 0xa0, 0x1c, 0xde,
0xfa, 0xb4, 0xa3, 0xec, 0x28, 0x2f, 0x5a, 0xfb, 0x64, 0x4f, 0x84, 0xed, 0xf1, 0x98, 0x09, 0x7a,
0xc8, 0x06, 0x54, 0x6f, 0xe8, 0x32, 0x70, 0x3c, 0xb7, 0x53, 0xc2, 0xa0, 0xba, 0xf1, 0x97, 0x02,
0x1a, 0x77, 0x93, 0x2f, 0xa1, 0x71, 0x61, 0x07, 0xd4, 0x9a, 0x71, 0x2c, 0x8e, 0xd1, 0xd8, 0xdf,
0xca, 0x62, 0x88, 0x3c, 0x00, 0x25, 0x67, 0x1a, 0x01, 0x90, 0x26, 0x94, 0x5d, 0x7b, 0x41, 0x3b,
0x2a, 0x7f, 0x92, 0xf0, 0xcb, 0xdc, 0xd0, 0x01, 0xdd, 0x59, 0xf8, 0xde, 0x32, 0xb4, 0x42, 0x67,
0x41, 0x83, 0xd0, 0x5e, 0xf8, 0x1d, 0x0d, 0x3d, 0x2a, 0xd1, 0xa1, 0xb6, 0xb0, 0x5d, 0x67, 0x86,
0xc6, 0x4e, 0x05, 0x2d, 0x4d, 0x06, 0x15, 0x38, 0xbf, 0xd0, 0x4e, 0x95, 0xfb, 0x9f, 0x43, 0xc3,
0x76, 0x5d, 0x2f, 0xb4, 0x43, 0x44, 0x0b, 0x3a, 0xb5, 0x1d, 0x15, 0xf9, 0xb4, 0x13, 0x3e, 0x6f,
0xe9, 0xed, 0xb9, 0x3d, 0xbf, 0xa6, 0xc6, 0x4b, 0xa8, 0x0e, 0x68, 0xf8, 0xc9, 0x5b, 0x5e, 0x25,
0x5c, 0x94, 0x98, 0x99, 0xe3, 0xdf, 0xbc, 0x4a, 0x79, 0xe2, 0xd3, 0xeb, 0x88, 0xa7, 0xf1, 0x9b,
0x02, 0x6a, 0xcf, 0xf7, 0x73, 0x27, 0x1e, 0x83, 0xe6, 0xb0, 0x32, 0xf9, 0x91, 0xc6, 0x7e, 0x2b,
0x5b, 0x3c, 0xb6, 0x57, 0xc3, 0x02, 0xc2, 0xa8, 0xd6, 0x96, 0xc4, 0x05, 0x91, 0xde, 0x31, 0x07,
0x69, 0x43, 0x9d, 0x7e, 0x76, 0x42, 0xeb, 0xd2, 0x9b, 0x52, 0xde, 0x80, 0x76, 0xbe, 0x0c, 0x6d,
0x5d, 0x19, 0x7f, 0x22, 0xa3, 0x91, 0x37, 0x15, 0xbd, 0x8d, 0xf8, 0x34, 0x40, 0xf5, 0x45, 0xa3,
0xdb, 0xeb, 0xb3, 0xe3, 0xa9, 0x28, 0x7b, 0x17, 0xca, 0xb6, 0xef, 0x07, 0x98, 0x98, 0xe5, 0x68,
0xca, 0xf4, 0x88, 0x01, 0x35, 0x37, 0xea, 0x52, 0xcc, 0x41, 0x4f, 0xfc, 0x71, 0xfb, 0x56, 0x27,
0x92, 0x23, 0x5f, 0x5d, 0x47, 0xfe, 0x39, 0xd4, 0xe2, 0xdf, 0x8c, 0x34, 0xfe, 0x16, 0x15, 0xdc,
0x05, 0xed, 0x86, 0x59, 0xc5, 0x6d, 0xfb, 0x5d, 0x81, 0x3a, 0xd2, 0x3d, 0x76, 0xe6, 0x21, 0x5d,
0xb2, 0x48, 0x67, 0x1a, 0x60, 0xa4, 0x8a, 0x91, 0xcf, 0xa0, 0xc2, 0xcb, 0x0b, 0x30, 0x54, 0x2d,
0xae, 0xaf, 0xcd, 0x76, 0xc0, 0xb7, 0xd8, 0xc0, 0x02, 0xec, 0x02, 0x3b, 0x85, 0x26, 0x3e, 0x31,
0x8b, 0x01, 0x95, 0xb9, 0xe9, 0x1e, 0xdc, 0x15, 0x95, 0x8a, 0x48, 0x8d, 0x9b, 0x73, 0xa5, 0x54,
0xd6, 0x95, 0xf2, 0xb7, 0x12, 0xef, 0x54, 0x01, 0x49, 0xec, 0x90, 0xbf, 0xa4, 0x33, 0xe7, 0xb3,
0xa0, 0x59, 0x27, 0x38, 0x2f, 0xbe, 0x35, 0x32, 0x29, 0x8c, 0xba, 0xa2, 0xb7, 0xc8, 0x20, 0xe1,
0x84, 0xc5, 0xcd, 0xed, 0x0b, 0x3a, 0x5f, 0x3f, 0x7f, 0x72, 0x1f, 0x5a, 0xd1, 0xa2, 0xd0, 0xa9,
0x65, 0xcf, 0x30, 0x33, 0x1f, 0x81, 0x4a, 0xb6, 0x61, 0x23, 0xb1, 0x5f, 0x50, 0x5c, 0xce, 0xff,
0xba, 0x1f, 0xc7, 0x50, 0xee, 0xbb, 0x33, 0x8f, 0x6c, 0x42, 0x63, 0x79, 0x15, 0x5a, 0xf1, 0x7a,
0x46, 0xf3, 0xd9, 0x82, 0x26, 0xb6, 0xf4, 0xd2, 0xca, 0x88, 0x02, 0x0b, 0x45, 0xb1, 0x49, 0x8c,
0xd1, 0xca, 0x2c, 0x41, 0x33, 0x6f, 0xa8, 0xbb, 0x5e, 0x65, 0xb8, 0x97, 0xab, 0x4c, 0x4e, 0x1f,
0x66, 0x4b, 0x6f, 0x21, 0xf4, 0x01, 0x9f, 0x98, 0x0e, 0xf0, 0xdd, 0x50, 0xc9, 0x53, 0x28, 0x4f,
0xed, 0xd0, 0x5e, 0xbf, 0x14, 0x21, 0x34, 0x38, 0xaa, 0x98, 0xc5, 0x33, 0xd0, 0x58, 0xe6, 0x68,
0x1a, 0xc5, 0xa9, 0xc5, 0xb8, 0xa2, 0xe1, 0xe0, 0xed, 0x93, 0xe7, 0x82, 0xbc, 0x02, 0xc7, 0xbd,
0xa4, 0x96, 0x44, 0x01, 0x6d, 0xd7, 0x6e, 0xe8, 0xcc, 0x23, 0x1b, 0x57, 0x26, 0x43, 0x87, 0xd6,
0x09, 0x0d, 0x59, 0xd3, 0xc6, 0xf4, 0xe7, 0x6b, 0xdc, 0x06, 0x63, 0x0f, 0x36, 0x12, 0x4b, 0xe0,
0x63, 0xbb, 0x29, 0x79, 0x88, 0x7a, 0x82, 0xcf, 0x42, 0x27, 0xef, 0xa6, 0x52, 0x81, 0x46, 0xec,
0xf9, 0xc6, 0xa9, 0x13, 0x84, 0x78, 0x73, 0x03, 0x01, 0x41, 0xfe, 0x07, 0xd5, 0x19, 0xaf, 0x22,
0x62, 0xdf, 0x90, 0xd8, 0xa7, 0x1b, 0xd1, 0x82, 0xca, 0x94, 0x86, 0xb6, 0x33, 0xe7, 0xcd, 0xab,
0x61, 0x5e, 0x3d, 0xc5, 0x11, 0x89, 0x71, 0xcb, 0x7d, 0x6f, 0x1a, 0xa3, 0x34, 0x65, 0x14, 0xe3,
0x29, 0xb4, 0xfb, 0x6e, 0xe0, 0xd3, 0x4b, 0x76, 0x24, 0xce, 0x2c, 0x29, 0x8a, 0xf1, 0x15, 0x10,
0x39, 0x40, 0x40, 0x3e, 0x40, 0x9d, 0xf1, 0xa6, 0xa2, 0x94, 0x2c, 0xe2, 0x0f, 0xd0, 0x66, 0x0c,
0xf8, 0x46, 0x24, 0xb5, 0x7c, 0x91, 0xaf, 0x25, 0xff, 0x9a, 0x28, 0xae, 0xe6, 0x15, 0x10, 0x19,
0x4b, 0x24, 0x7f, 0x02, 0x15, 0xbe, 0xc2, 0x31, 0x56, 0x4e, 0x75, 0x8d, 0x67, 0xb0, 0x29, 0x28,
0xf3, 0xe7, 0xa2, 0xaa, 0xbe, 0x85, 0xad, 0x6c, 0x88, 0x80, 0x4e, 0xf4, 0x5c, 0x29, 0xd2, 0x73,
0xe3, 0x3b, 0xd8, 0x64, 0x7c, 0xa8, 0xcb, 0xaf, 0x4f, 0x52, 0xdd, 0xff, 0xa1, 0x12, 0x55, 0xb7,
0xf2, 0x0e, 0x94, 0xee, 0xa2, 0xf1, 0x1a, 0xb6, 0xb2, 0x87, 0xd3, 0x72, 0x28, 0xb7, 0xac, 0x94,
0xc3, 0x03, 0x8d, 0x5b, 0x7e, 0xb9, 0x4e, 0xbd, 0x8f, 0x49, 0x3e, 0x6c, 0x13, 0x76, 0xdf, 0x4a,
0x54, 0x1f, 0xe5, 0x23, 0x96, 0x39, 0xb1, 0x43, 0x78, 0x8f, 0xe7, 0x8e, 0xcb, 0xef, 0xb1, 0xf2,
0x42, 0x63, 0x07, 0x66, 0xde, 0x7c, 0xee, 0x7d, 0xe2, 0x77, 0xb8, 0x96, 0xbb, 0xd7, 0x5a, 0xc1,
0xbd, 0xe6, 0x52, 0x62, 0xec, 0xf0, 0x5b, 0x1c, 0xa5, 0x16, 0x6c, 0x13, 0x64, 0xae, 0x6f, 0xbb,
0x14, 0xea, 0xe9, 0xb7, 0x42, 0x07, 0xbb, 0x7a, 0xd6, 0x3b, 0x31, 0xad, 0xc9, 0x87, 0x91, 0x69,
0xbd, 0x1f, 0x1c, 0x99, 0xc7, 0xfd, 0x81, 0x79, 0xa4, 0xdf, 0x41, 0x7d, 0xd8, 0x90, 0x3c, 0xbd,
0xd1, 0xe8, 0x50, 0x57, 0x50, 0x77, 0xdb, 0x92, 0xf1, 0x68, 0x78, 0xf8, 0xd6, 0x1c, 0xeb, 0x25,
0x24, 0xd2, 0x92, 0xcc, 0xc3, 0xc3, 0xbe, 0xae, 0xee, 0x8e, 0xa0, 0x96, 0xbc, 0x32, 0xb7, 0x61,
0x13, 0x01, 0xac, 0x77, 0x93, 0xde, 0x24, 0x9b, 0x04, 0xf1, 0x52, 0xc7, 0xf8, 0xfd, 0x60, 0xd0,
0x1f, 0x9c, 0x60, 0x9a, 0x2d, 0xd0, 0x53, 0xb3, 0xf9, 0x63, 0x7f, 0x82, 0xc1, 0xa5, 0xdd, 0x7f,
0x14, 0xa8, 0x25, 0xef, 0x09, 0x84, 0x1c, 0x0d, 0x8f, 0x0a, 0x20, 0xf1, 0x6c, 0xea, 0x30, 0xcf,
0x0e, 0xc6, 0x1f, 0x86, 0x88, 0x98, 0x09, 0x1f, 0x8d, 0xcd, 0x51, 0x6f, 0xcc, 0x52, 0x95, 0x50,
0x92, 0x49, 0xde, 0x81, 0x30, 0x2a, 0x63, 0x96, 0xda, 0x63, 0x66, 0x65, 0xbc, 0x6d, 0x0f, 0x52,
0x73, 0xef, 0x60, 0x38, 0x46, 0x6a, 0xf1, 0x31, 0x5d, 0xcb, 0x25, 0x8f, 0x88, 0x57, 0xb2, 0x39,
0x8e, 0xcc, 0x53, 0x73, 0xc2, 0xc0, 0xaa, 0xd9, 0x1c, 0x27, 0xbd, 0xf1, 0x01, 0xb6, 0x50, 0xaf,
0xed, 0xfe, 0x51, 0x82, 0x7a, 0x2a, 0x76, 0x38, 0x21, 0xf3, 0xdc, 0x1c, 0x4c, 0x56, 0x27, 0xf4,
0x10, 0xb6, 0x25, 0x0f, 0x43, 0x4a, 0xf8, 0x2b, 0xf8, 0x2d, 0xf0, 0xa4, 0xd8, 0x19, 0xb3, 0xc6,
0xda, 0xbb, 0x70, 0x3f, 0x17, 0x83, 0x54, 0xb8, 0x4f, 0x45, 0xb9, 0xb8, 0x97, 0xf3, 0x89, 0x72,
0xca, 0xb8, 0x3b, 0x3b, 0x39, 0x97, 0xe0, 0x6e, 0x1d, 0x0e, 0x4f, 0x4f, 0xcd, 0x43, 0x16, 0xa5,
0xe5, 0xc0, 0xc5, 0x38, 0xc7, 0x51, 0x43, 0xb2, 0xe0, 0xcc, 0x27, 0xc0, 0xab, 0xac, 0xc1, 0x92,
0x2b, 0xba, 0x55, 0xfd, 0xb3, 0x51, 0x44, 0xb9, 0x46, 0x1e, 0x41, 0x67, 0xc5, 0x3d, 0x36, 0xcf,
0x86, 0xe7, 0xe8, 0xad, 0xef, 0xff, 0x5a, 0xc6, 0x4f, 0x8f, 0xeb, 0x8b, 0xb9, 0x73, 0xd9, 0x1b,
0xf5, 0xc9, 0xf7, 0x50, 0x15, 0x82, 0x4e, 0xb6, 0x93, 0x05, 0xcd, 0x8a, 0x7e, 0xb7, 0xb3, 0xea,
0x88, 0xb6, 0xc6, 0xb8, 0x43, 0x7a, 0x50, 0x8b, 0x85, 0x99, 0xa4, 0x71, 0x39, 0xcd, 0xef, 0x3e,
0x28, 0xf0, 0x24, 0x10, 0x27, 0x00, 0xa9, 0x14, 0x93, 0xae, 0xf4, 0x02, 0xc9, 0x09, 0x78, 0xf7,
0x61, 0xa1, 0x4f, 0x06, 0x4a, 0x65, 0x55, 0x02, 0x5a, 0xd1, 0x6d, 0x09, 0x68, 0x55, 0x87, 0x11,
0xe8, 0x0c, 0x9a, 0xb2, 0x8c, 0x92, 0x47, 0xf9, 0xbc, 0xb2, 0x00, 0x77, 0x1f, 0xaf, 0xf1, 0x26,
0x70, 0x43, 0x68, 0xca, 0x0a, 0x29, 0xc1, 0x15, 0xa8, 0xae, 0x04, 0x57, 0x24, 0xab, 0xc6, 0x9d,
0xaf, 0x15, 0xf2, 0x86, 0x0f, 0x8d, 0xe9, 0x57, 0x76, 0x68, 0x92, 0x98, 0x66, 0x87, 0x26, 0x4b,
0x1d, 0x43, 0xb8, 0xa8, 0xf0, 0xff, 0x4f, 0x2f, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x84, 0xa0,
0x2b, 0xe3, 0x4c, 0x0d, 0x00, 0x00,
}

View File

@@ -21,8 +21,6 @@
// The API defined here is proposed, experimental, // // The API defined here is proposed, experimental, //
// and (for now) subject to change at any time. // // and (for now) subject to change at any time. //
// // // //
// Do not use it. //
// //
// If you think you want to use it, or for any other // // If you think you want to use it, or for any other //
// queries, contact <rkt-dev@googlegroups.com> // // queries, contact <rkt-dev@googlegroups.com> //
// or file an issue on github.com/coreos/rkt // // or file an issue on github.com/coreos/rkt //
@@ -234,6 +232,9 @@ message ImageFilter {
// If not empty, the images that have all of the annotations will be returned. // If not empty, the images that have all of the annotations will be returned.
repeated KeyValue annotations = 8; repeated KeyValue annotations = 8;
// If not empty, the images that have any of the exact full names will be returned.
repeated string full_names = 9;
} }
// Info describes the information of rkt on the machine. // Info describes the information of rkt on the machine.

View File

@@ -20,8 +20,6 @@ import (
"fmt" "fmt"
"os" "os"
// Note that if your project uses Godep to manage dependencies, then
// you need to change following the import paths.
"github.com/coreos/rkt/api/v1alpha" "github.com/coreos/rkt/api/v1alpha"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"

View File

@@ -230,6 +230,14 @@ var E_GogoprotoImport = &proto.ExtensionDesc{
Tag: "varint,63027,opt,name=gogoproto_import", Tag: "varint,63027,opt,name=gogoproto_import",
} }
var E_ProtosizerAll = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FileOptions)(nil),
ExtensionType: (*bool)(nil),
Field: 63028,
Name: "gogoproto.protosizer_all",
Tag: "varint,63028,opt,name=protosizer_all",
}
var E_GoprotoGetters = &proto.ExtensionDesc{ var E_GoprotoGetters = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.MessageOptions)(nil), ExtendedType: (*google_protobuf.MessageOptions)(nil),
ExtensionType: (*bool)(nil), ExtensionType: (*bool)(nil),
@@ -382,6 +390,14 @@ var E_GoprotoUnrecognized = &proto.ExtensionDesc{
Tag: "varint,64026,opt,name=goproto_unrecognized", Tag: "varint,64026,opt,name=goproto_unrecognized",
} }
var E_Protosizer = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.MessageOptions)(nil),
ExtensionType: (*bool)(nil),
Field: 64028,
Name: "gogoproto.protosizer",
Tag: "varint,64028,opt,name=protosizer",
}
var E_Nullable = &proto.ExtensionDesc{ var E_Nullable = &proto.ExtensionDesc{
ExtendedType: (*google_protobuf.FieldOptions)(nil), ExtendedType: (*google_protobuf.FieldOptions)(nil),
ExtensionType: (*bool)(nil), ExtensionType: (*bool)(nil),
@@ -481,6 +497,7 @@ func init() {
proto.RegisterExtension(E_GoprotoExtensionsMapAll) proto.RegisterExtension(E_GoprotoExtensionsMapAll)
proto.RegisterExtension(E_GoprotoUnrecognizedAll) proto.RegisterExtension(E_GoprotoUnrecognizedAll)
proto.RegisterExtension(E_GogoprotoImport) proto.RegisterExtension(E_GogoprotoImport)
proto.RegisterExtension(E_ProtosizerAll)
proto.RegisterExtension(E_GoprotoGetters) proto.RegisterExtension(E_GoprotoGetters)
proto.RegisterExtension(E_GoprotoStringer) proto.RegisterExtension(E_GoprotoStringer)
proto.RegisterExtension(E_VerboseEqual) proto.RegisterExtension(E_VerboseEqual)
@@ -500,6 +517,7 @@ func init() {
proto.RegisterExtension(E_UnsafeUnmarshaler) proto.RegisterExtension(E_UnsafeUnmarshaler)
proto.RegisterExtension(E_GoprotoExtensionsMap) proto.RegisterExtension(E_GoprotoExtensionsMap)
proto.RegisterExtension(E_GoprotoUnrecognized) proto.RegisterExtension(E_GoprotoUnrecognized)
proto.RegisterExtension(E_Protosizer)
proto.RegisterExtension(E_Nullable) proto.RegisterExtension(E_Nullable)
proto.RegisterExtension(E_Embed) proto.RegisterExtension(E_Embed)
proto.RegisterExtension(E_Customtype) proto.RegisterExtension(E_Customtype)

View File

@@ -67,6 +67,8 @@ extend google.protobuf.FileOptions {
optional bool goproto_extensions_map_all = 63025; optional bool goproto_extensions_map_all = 63025;
optional bool goproto_unrecognized_all = 63026; optional bool goproto_unrecognized_all = 63026;
optional bool gogoproto_import = 63027; optional bool gogoproto_import = 63027;
optional bool protosizer_all = 63028;
} }
extend google.protobuf.MessageOptions { extend google.protobuf.MessageOptions {
@@ -93,6 +95,8 @@ extend google.protobuf.MessageOptions {
optional bool goproto_extensions_map = 64025; optional bool goproto_extensions_map = 64025;
optional bool goproto_unrecognized = 64026; optional bool goproto_unrecognized = 64026;
optional bool protosizer = 64028;
} }
extend google.protobuf.FieldOptions { extend google.protobuf.FieldOptions {

View File

@@ -213,6 +213,10 @@ func IsSizer(file *google_protobuf.FileDescriptorProto, message *google_protobuf
return proto.GetBoolExtension(message.Options, E_Sizer, proto.GetBoolExtension(file.Options, E_SizerAll, false)) return proto.GetBoolExtension(message.Options, E_Sizer, proto.GetBoolExtension(file.Options, E_SizerAll, false))
} }
func IsProtoSizer(file *google_protobuf.FileDescriptorProto, message *google_protobuf.DescriptorProto) bool {
return proto.GetBoolExtension(message.Options, E_Protosizer, proto.GetBoolExtension(file.Options, E_ProtosizerAll, false))
}
func IsGoEnumStringer(file *google_protobuf.FileDescriptorProto, enum *google_protobuf.EnumDescriptorProto) bool { func IsGoEnumStringer(file *google_protobuf.FileDescriptorProto, enum *google_protobuf.EnumDescriptorProto) bool {
return proto.GetBoolExtension(enum.Options, E_GoprotoEnumStringer, proto.GetBoolExtension(file.Options, E_GoprotoEnumStringerAll, true)) return proto.GetBoolExtension(enum.Options, E_GoprotoEnumStringer, proto.GetBoolExtension(file.Options, E_GoprotoEnumStringerAll, true))
} }

View File

@@ -80,7 +80,8 @@ var overwriters []map[string]gogoproto.EnableFunc = []map[string]gogoproto.Enabl
"verboseequal": gogoproto.HasVerboseEqual, "verboseequal": gogoproto.HasVerboseEqual,
}, },
{ {
"size": gogoproto.IsSizer, "size": gogoproto.IsSizer,
"protosizer": gogoproto.IsProtoSizer,
}, },
{ {
"unmarshaler": gogoproto.IsUnmarshaler, "unmarshaler": gogoproto.IsUnmarshaler,

View File

@@ -303,12 +303,12 @@ func wireToType(wire string) int {
panic("unreachable") panic("unreachable")
} }
func (p *marshalto) mapField(numGen NumGen, fieldTyp descriptor.FieldDescriptorProto_Type, varName string) { func (p *marshalto) mapField(numGen NumGen, fieldTyp descriptor.FieldDescriptorProto_Type, varName string, protoSizer bool) {
switch fieldTyp { switch fieldTyp {
case descriptor.FieldDescriptorProto_TYPE_DOUBLE: case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
p.callFixed64(p.mathPkg.Use(), `.Float64bits(`, varName, `)`) p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(`, varName, `))`)
case descriptor.FieldDescriptorProto_TYPE_FLOAT: case descriptor.FieldDescriptorProto_TYPE_FLOAT:
p.callFixed32(p.mathPkg.Use(), `.Float32bits(`, varName, `)`) p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(`, varName, `))`)
case descriptor.FieldDescriptorProto_TYPE_INT64, case descriptor.FieldDescriptorProto_TYPE_INT64,
descriptor.FieldDescriptorProto_TYPE_UINT64, descriptor.FieldDescriptorProto_TYPE_UINT64,
descriptor.FieldDescriptorProto_TYPE_INT32, descriptor.FieldDescriptorProto_TYPE_INT32,
@@ -341,7 +341,11 @@ func (p *marshalto) mapField(numGen NumGen, fieldTyp descriptor.FieldDescriptorP
case descriptor.FieldDescriptorProto_TYPE_SINT64: case descriptor.FieldDescriptorProto_TYPE_SINT64:
p.callVarint(`(uint64(`, varName, `) << 1) ^ uint64((`, varName, ` >> 63))`) p.callVarint(`(uint64(`, varName, `) << 1) ^ uint64((`, varName, ` >> 63))`)
case descriptor.FieldDescriptorProto_TYPE_MESSAGE: case descriptor.FieldDescriptorProto_TYPE_MESSAGE:
p.callVarint(varName, `.Size()`) if protoSizer {
p.callVarint(varName, `.ProtoSize()`)
} else {
p.callVarint(varName, `.Size()`)
}
p.P(`n`, numGen.Next(), `, err := `, varName, `.MarshalTo(data[i:])`) p.P(`n`, numGen.Next(), `, err := `, varName, `.MarshalTo(data[i:])`)
p.P(`if err != nil {`) p.P(`if err != nil {`)
p.In() p.In()
@@ -371,6 +375,8 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
nullable := gogoproto.IsNullable(field) nullable := gogoproto.IsNullable(field)
repeated := field.IsRepeated() repeated := field.IsRepeated()
required := field.IsRequired() required := field.IsRequired()
protoSizer := gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto)
if required && nullable { if required && nullable {
p.P(`if m.`, fieldname, `== nil {`) p.P(`if m.`, fieldname, `== nil {`)
p.In() p.In()
@@ -397,13 +403,13 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
} }
switch *field.Type { switch *field.Type {
case descriptor.FieldDescriptorProto_TYPE_DOUBLE: case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
if !p.unsafe { if !p.unsafe || gogoproto.IsCastType(field) {
if packed { if packed {
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callVarint(`len(m.`, fieldname, `) * 8`) p.callVarint(`len(m.`, fieldname, `) * 8`)
p.P(`for _, num := range m.`, fieldname, ` {`) p.P(`for _, num := range m.`, fieldname, ` {`)
p.In() p.In()
p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(num)`) p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(num))`)
p.encodeFixed64("f" + numGen.Current()) p.encodeFixed64("f" + numGen.Current())
p.Out() p.Out()
p.P(`}`) p.P(`}`)
@@ -411,7 +417,7 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
p.P(`for _, num := range m.`, fieldname, ` {`) p.P(`for _, num := range m.`, fieldname, ` {`)
p.In() p.In()
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(num)`) p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float64bits(float64(num))`)
p.encodeFixed64("f" + numGen.Current()) p.encodeFixed64("f" + numGen.Current())
p.Out() p.Out()
p.P(`}`) p.P(`}`)
@@ -419,15 +425,15 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
p.P(`if m.`, fieldname, ` != 0 {`) p.P(`if m.`, fieldname, ` != 0 {`)
p.In() p.In()
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callFixed64(p.mathPkg.Use(), `.Float64bits(m.`+fieldname, `)`) p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`)
p.Out() p.Out()
p.P(`}`) p.P(`}`)
} else if !nullable { } else if !nullable {
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callFixed64(p.mathPkg.Use(), `.Float64bits(m.`+fieldname, `)`) p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(m.`+fieldname, `))`)
} else { } else {
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callFixed64(p.mathPkg.Use(), `.Float64bits(*m.`+fieldname, `)`) p.callFixed64(p.mathPkg.Use(), `.Float64bits(float64(*m.`+fieldname, `))`)
} }
} else { } else {
if packed { if packed {
@@ -461,13 +467,13 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
} }
} }
case descriptor.FieldDescriptorProto_TYPE_FLOAT: case descriptor.FieldDescriptorProto_TYPE_FLOAT:
if !p.unsafe { if !p.unsafe || gogoproto.IsCastType(field) {
if packed { if packed {
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callVarint(`len(m.`, fieldname, `) * 4`) p.callVarint(`len(m.`, fieldname, `) * 4`)
p.P(`for _, num := range m.`, fieldname, ` {`) p.P(`for _, num := range m.`, fieldname, ` {`)
p.In() p.In()
p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(num)`) p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(num))`)
p.encodeFixed32("f" + numGen.Current()) p.encodeFixed32("f" + numGen.Current())
p.Out() p.Out()
p.P(`}`) p.P(`}`)
@@ -475,7 +481,7 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
p.P(`for _, num := range m.`, fieldname, ` {`) p.P(`for _, num := range m.`, fieldname, ` {`)
p.In() p.In()
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(num)`) p.P(`f`, numGen.Next(), ` := `, p.mathPkg.Use(), `.Float32bits(float32(num))`)
p.encodeFixed32("f" + numGen.Current()) p.encodeFixed32("f" + numGen.Current())
p.Out() p.Out()
p.P(`}`) p.P(`}`)
@@ -483,15 +489,15 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
p.P(`if m.`, fieldname, ` != 0 {`) p.P(`if m.`, fieldname, ` != 0 {`)
p.In() p.In()
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callFixed32(p.mathPkg.Use(), `.Float32bits(m.`+fieldname, `)`) p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`)
p.Out() p.Out()
p.P(`}`) p.P(`}`)
} else if !nullable { } else if !nullable {
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callFixed32(p.mathPkg.Use(), `.Float32bits(m.`+fieldname, `)`) p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(m.`+fieldname, `))`)
} else { } else {
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callFixed32(p.mathPkg.Use(), `.Float32bits(*m.`+fieldname, `)`) p.callFixed32(p.mathPkg.Use(), `.Float32bits(float32(*m.`+fieldname, `))`)
} }
} else { } else {
if packed { if packed {
@@ -896,22 +902,30 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
} else if !nullable { } else if !nullable {
accessor = `(&v)` accessor = `(&v)`
} }
p.P(`msgSize := `, accessor, `.Size()`) if protoSizer {
p.P(`msgSize := `, accessor, `.ProtoSize()`)
} else {
p.P(`msgSize := `, accessor, `.Size()`)
}
sum = append(sum, `msgSize + sov`+p.localName+`(uint64(msgSize))`) sum = append(sum, `msgSize + sov`+p.localName+`(uint64(msgSize))`)
} }
p.P(`mapSize := `, strings.Join(sum, " + ")) p.P(`mapSize := `, strings.Join(sum, " + "))
p.callVarint("mapSize") p.callVarint("mapSize")
p.encodeKey(1, wireToType(keywire)) p.encodeKey(1, wireToType(keywire))
p.mapField(numGen, m.KeyField.GetType(), "k") p.mapField(numGen, m.KeyField.GetType(), "k", protoSizer)
p.encodeKey(2, wireToType(valuewire)) p.encodeKey(2, wireToType(valuewire))
p.mapField(numGen, m.ValueField.GetType(), accessor) p.mapField(numGen, m.ValueField.GetType(), accessor, protoSizer)
p.Out() p.Out()
p.P(`}`) p.P(`}`)
} else if repeated { } else if repeated {
p.P(`for _, msg := range m.`, fieldname, ` {`) p.P(`for _, msg := range m.`, fieldname, ` {`)
p.In() p.In()
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callVarint("msg.Size()") if protoSizer {
p.callVarint("msg.ProtoSize()")
} else {
p.callVarint("msg.Size()")
}
p.P(`n, err := msg.MarshalTo(data[i:])`) p.P(`n, err := msg.MarshalTo(data[i:])`)
p.P(`if err != nil {`) p.P(`if err != nil {`)
p.In() p.In()
@@ -923,7 +937,11 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
p.P(`}`) p.P(`}`)
} else { } else {
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callVarint(`m.`, fieldname, `.Size()`) if protoSizer {
p.callVarint(`m.`, fieldname, `.ProtoSize()`)
} else {
p.callVarint(`m.`, fieldname, `.Size()`)
}
p.P(`n`, numGen.Next(), `, err := m.`, fieldname, `.MarshalTo(data[i:])`) p.P(`n`, numGen.Next(), `, err := m.`, fieldname, `.MarshalTo(data[i:])`)
p.P(`if err != nil {`) p.P(`if err != nil {`)
p.In() p.In()
@@ -960,7 +978,11 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
p.P(`for _, msg := range m.`, fieldname, ` {`) p.P(`for _, msg := range m.`, fieldname, ` {`)
p.In() p.In()
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callVarint(`msg.Size()`) if protoSizer {
p.callVarint(`msg.ProtoSize()`)
} else {
p.callVarint(`msg.Size()`)
}
p.P(`n, err := msg.MarshalTo(data[i:])`) p.P(`n, err := msg.MarshalTo(data[i:])`)
p.P(`if err != nil {`) p.P(`if err != nil {`)
p.In() p.In()
@@ -972,7 +994,11 @@ func (p *marshalto) generateField(proto3 bool, numGen NumGen, file *generator.Fi
p.P(`}`) p.P(`}`)
} else { } else {
p.encodeKey(fieldNumber, wireType) p.encodeKey(fieldNumber, wireType)
p.callVarint(`m.`, fieldname, `.Size()`) if protoSizer {
p.callVarint(`m.`, fieldname, `.ProtoSize()`)
} else {
p.callVarint(`m.`, fieldname, `.Size()`)
}
p.P(`n`, numGen.Next(), `, err := m.`, fieldname, `.MarshalTo(data[i:])`) p.P(`n`, numGen.Next(), `, err := m.`, fieldname, `.MarshalTo(data[i:])`)
p.P(`if err != nil {`) p.P(`if err != nil {`)
p.In() p.In()
@@ -1126,7 +1152,11 @@ func (p *marshalto) Generate(file *generator.FileDescriptor) {
p.P(`func (m *`, ccTypeName, `) Marshal() (data []byte, err error) {`) p.P(`func (m *`, ccTypeName, `) Marshal() (data []byte, err error) {`)
p.In() p.In()
p.P(`size := m.Size()`) if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
p.P(`size := m.ProtoSize()`)
} else {
p.P(`size := m.Size()`)
}
p.P(`data = make([]byte, size)`) p.P(`data = make([]byte, size)`)
p.P(`n, err := m.MarshalTo(data)`) p.P(`n, err := m.MarshalTo(data)`)
p.P(`if err != nil {`) p.P(`if err != nil {`)

View File

@@ -290,7 +290,7 @@ func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generato
} else if field.IsMessage() || p.IsGroup(field) { } else if field.IsMessage() || p.IsGroup(field) {
funcCall := getFuncCall(goTypName) funcCall := getFuncCall(goTypName)
if field.IsRepeated() { if field.IsRepeated() {
p.P(p.varGen.Next(), ` := r.Intn(10)`) p.P(p.varGen.Next(), ` := r.Intn(5)`)
p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
p.In() p.In()
@@ -346,7 +346,7 @@ func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generato
} }
} else if field.IsBytes() { } else if field.IsBytes() {
if field.IsRepeated() { if field.IsRepeated() {
p.P(p.varGen.Next(), ` := r.Intn(100)`) p.P(p.varGen.Next(), ` := r.Intn(10)`)
p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
p.In() p.In()
@@ -387,7 +387,7 @@ func (p *plugin) GenerateField(file *generator.FileDescriptor, message *generato
} else { } else {
typName := generator.GoTypeToName(goTyp) typName := generator.GoTypeToName(goTyp)
if field.IsRepeated() { if field.IsRepeated() {
p.P(p.varGen.Next(), ` := r.Intn(100)`) p.P(p.varGen.Next(), ` := r.Intn(10)`)
p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`) p.P(`this.`, fieldname, ` = make(`, goTyp, `, `, p.varGen.Current(), `)`)
p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`) p.P(`for i := 0; i < `, p.varGen.Current(), `; i++ {`)
p.In() p.In()

View File

@@ -25,7 +25,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/* /*
The size plugin generates a Size method for each message. The size plugin generates a Size or ProtoSize method for each message.
This is useful with the MarshalTo method generated by the marshalto plugin and the This is useful with the MarshalTo method generated by the marshalto plugin and the
gogoproto.marshaler and gogoproto.marshaler_all extensions. gogoproto.marshaler and gogoproto.marshaler_all extensions.
@@ -33,6 +33,8 @@ It is enabled by the following extensions:
- sizer - sizer
- sizer_all - sizer_all
- protosizer
- protosizer_all
The size plugin also generates a test given it is enabled using one of the following extensions: The size plugin also generates a test given it is enabled using one of the following extensions:
@@ -195,7 +197,7 @@ func (p *size) sizeZigZag() {
}`) }`)
} }
func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto) { func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, message *generator.Descriptor, field *descriptor.FieldDescriptorProto, sizeName string) {
fieldname := p.GetOneOfFieldName(message, field) fieldname := p.GetOneOfFieldName(message, field)
nullable := gogoproto.IsNullable(field) nullable := gogoproto.IsNullable(field)
repeated := field.IsRepeated() repeated := field.IsRepeated()
@@ -393,17 +395,17 @@ func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, messag
p.P(`if v != nil {`) p.P(`if v != nil {`)
p.In() p.In()
if valuegoTyp != valuegoAliasTyp { if valuegoTyp != valuegoAliasTyp {
p.P(`l = ((`, valuegoTyp, `)(v)).Size()`) p.P(`l = ((`, valuegoTyp, `)(v)).`, sizeName, `()`)
} else { } else {
p.P(`l = v.Size()`) p.P(`l = v.`, sizeName, `()`)
} }
p.Out() p.Out()
p.P(`}`) p.P(`}`)
} else { } else {
if valuegoTyp != valuegoAliasTyp { if valuegoTyp != valuegoAliasTyp {
p.P(`l = ((*`, valuegoTyp, `)(&v)).Size()`) p.P(`l = ((*`, valuegoTyp, `)(&v)).`, sizeName, `()`)
} else { } else {
p.P(`l = v.Size()`) p.P(`l = v.`, sizeName, `()`)
} }
} }
sum = append(sum, `l+sov`+p.localName+`(uint64(l))`) sum = append(sum, `l+sov`+p.localName+`(uint64(l))`)
@@ -415,12 +417,12 @@ func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, messag
} else if repeated { } else if repeated {
p.P(`for _, e := range m.`, fieldname, ` { `) p.P(`for _, e := range m.`, fieldname, ` { `)
p.In() p.In()
p.P(`l=e.Size()`) p.P(`l=e.`, sizeName, `()`)
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
p.Out() p.Out()
p.P(`}`) p.P(`}`)
} else { } else {
p.P(`l=m.`, fieldname, `.Size()`) p.P(`l=m.`, fieldname, `.`, sizeName, `()`)
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
} }
case descriptor.FieldDescriptorProto_TYPE_BYTES: case descriptor.FieldDescriptorProto_TYPE_BYTES:
@@ -447,12 +449,12 @@ func (p *size) generateField(proto3 bool, file *generator.FileDescriptor, messag
if repeated { if repeated {
p.P(`for _, e := range m.`, fieldname, ` { `) p.P(`for _, e := range m.`, fieldname, ` { `)
p.In() p.In()
p.P(`l=e.Size()`) p.P(`l=e.`, sizeName, `()`)
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
p.Out() p.Out()
p.P(`}`) p.P(`}`)
} else { } else {
p.P(`l=m.`, fieldname, `.Size()`) p.P(`l=m.`, fieldname, `.`, sizeName, `()`)
p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`) p.P(`n+=`, strconv.Itoa(key), `+l+sov`, p.localName, `(uint64(l))`)
} }
} }
@@ -501,7 +503,12 @@ func (p *size) Generate(file *generator.FileDescriptor) {
protoPkg = p.NewImport("github.com/golang/protobuf/proto") protoPkg = p.NewImport("github.com/golang/protobuf/proto")
} }
for _, message := range file.Messages() { for _, message := range file.Messages() {
if !gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) { sizeName := ""
if gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) {
sizeName = "Size"
} else if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
sizeName = "ProtoSize"
} else {
continue continue
} }
if message.DescriptorProto.GetOptions().GetMapEntry() { if message.DescriptorProto.GetOptions().GetMapEntry() {
@@ -509,7 +516,7 @@ func (p *size) Generate(file *generator.FileDescriptor) {
} }
p.atleastOne = true p.atleastOne = true
ccTypeName := generator.CamelCaseSlice(message.TypeName()) ccTypeName := generator.CamelCaseSlice(message.TypeName())
p.P(`func (m *`, ccTypeName, `) Size() (n int) {`) p.P(`func (m *`, ccTypeName, `) `, sizeName, `() (n int) {`)
p.In() p.In()
p.P(`var l int`) p.P(`var l int`)
p.P(`_ = l`) p.P(`_ = l`)
@@ -518,7 +525,7 @@ func (p *size) Generate(file *generator.FileDescriptor) {
oneof := field.OneofIndex != nil oneof := field.OneofIndex != nil
if !oneof { if !oneof {
proto3 := gogoproto.IsProto3(file.FileDescriptorProto) proto3 := gogoproto.IsProto3(file.FileDescriptorProto)
p.generateField(proto3, file, message, field) p.generateField(proto3, file, message, field, sizeName)
} else { } else {
fieldname := p.GetFieldName(message, field) fieldname := p.GetFieldName(message, field)
if _, ok := oneofs[fieldname]; ok { if _, ok := oneofs[fieldname]; ok {
@@ -528,7 +535,7 @@ func (p *size) Generate(file *generator.FileDescriptor) {
} }
p.P(`if m.`, fieldname, ` != nil {`) p.P(`if m.`, fieldname, ` != nil {`)
p.In() p.In()
p.P(`n+=m.`, fieldname, `.Size()`) p.P(`n+=m.`, fieldname, `.`, sizeName, `()`)
p.Out() p.Out()
p.P(`}`) p.P(`}`)
} }
@@ -564,12 +571,12 @@ func (p *size) Generate(file *generator.FileDescriptor) {
continue continue
} }
ccTypeName := p.OneOfTypeName(message, f) ccTypeName := p.OneOfTypeName(message, f)
p.P(`func (m *`, ccTypeName, `) Size() (n int) {`) p.P(`func (m *`, ccTypeName, `) `, sizeName, `() (n int) {`)
p.In() p.In()
p.P(`var l int`) p.P(`var l int`)
p.P(`_ = l`) p.P(`_ = l`)
vanity.TurnOffNullableForNativeTypesWithoutDefaultsOnly(f) vanity.TurnOffNullableForNativeTypesWithoutDefaultsOnly(f)
p.generateField(false, file, message, f) p.generateField(false, file, message, f, sizeName)
p.P(`return n`) p.P(`return n`)
p.Out() p.Out()
p.P(`}`) p.P(`}`)

View File

@@ -51,7 +51,12 @@ func (p *test) Generate(imports generator.PluginImports, file *generator.FileDes
} }
for _, message := range file.Messages() { for _, message := range file.Messages() {
ccTypeName := generator.CamelCaseSlice(message.TypeName()) ccTypeName := generator.CamelCaseSlice(message.TypeName())
if !gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) { sizeName := ""
if gogoproto.IsSizer(file.FileDescriptorProto, message.DescriptorProto) {
sizeName = "Size"
} else if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
sizeName = "ProtoSize"
} else {
continue continue
} }
if message.DescriptorProto.GetOptions().GetMapEntry() { if message.DescriptorProto.GetOptions().GetMapEntry() {
@@ -60,7 +65,7 @@ func (p *test) Generate(imports generator.PluginImports, file *generator.FileDes
if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) { if gogoproto.HasTestGen(file.FileDescriptorProto, message.DescriptorProto) {
used = true used = true
p.P(`func Test`, ccTypeName, `Size(t *`, testingPkg.Use(), `.T) {`) p.P(`func Test`, ccTypeName, sizeName, `(t *`, testingPkg.Use(), `.T) {`)
p.In() p.In()
p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`) p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`)
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`) p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`)
@@ -72,7 +77,7 @@ func (p *test) Generate(imports generator.PluginImports, file *generator.FileDes
p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`) p.P(`t.Fatalf("seed = %d, err = %v", seed, err)`)
p.Out() p.Out()
p.P(`}`) p.P(`}`)
p.P(`size := p.Size()`) p.P(`size := p.`, sizeName, `()`)
p.P(`if len(data) != size {`) p.P(`if len(data) != size {`)
p.In() p.In()
p.P(`t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data))`) p.P(`t.Errorf("seed = %d, size %v != marshalled size %v", seed, size, len(data))`)
@@ -96,7 +101,7 @@ func (p *test) Generate(imports generator.PluginImports, file *generator.FileDes
if gogoproto.HasBenchGen(file.FileDescriptorProto, message.DescriptorProto) { if gogoproto.HasBenchGen(file.FileDescriptorProto, message.DescriptorProto) {
used = true used = true
p.P(`func Benchmark`, ccTypeName, `Size(b *`, testingPkg.Use(), `.B) {`) p.P(`func Benchmark`, ccTypeName, sizeName, `(b *`, testingPkg.Use(), `.B) {`)
p.In() p.In()
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(616))`) p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(616))`)
p.P(`total := 0`) p.P(`total := 0`)
@@ -109,7 +114,7 @@ func (p *test) Generate(imports generator.PluginImports, file *generator.FileDes
p.P(`b.ResetTimer()`) p.P(`b.ResetTimer()`)
p.P(`for i := 0; i < b.N; i++ {`) p.P(`for i := 0; i < b.N; i++ {`)
p.In() p.In()
p.P(`total += pops[i%1000].Size()`) p.P(`total += pops[i%1000].`, sizeName, `()`)
p.Out() p.Out()
p.P(`}`) p.P(`}`)
p.P(`b.SetBytes(int64(total / b.N))`) p.P(`b.SetBytes(int64(total / b.N))`)

View File

@@ -341,7 +341,11 @@ func (p *testProto) Generate(imports generator.PluginImports, file *generator.Fi
p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`) p.P(`seed := `, timePkg.Use(), `.Now().UnixNano()`)
p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`) p.P(`popr := `, randPkg.Use(), `.New(`, randPkg.Use(), `.NewSource(seed))`)
p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`) p.P(`p := NewPopulated`, ccTypeName, `(popr, false)`)
p.P(`size := p.Size()`) if gogoproto.IsProtoSizer(file.FileDescriptorProto, message.DescriptorProto) {
p.P(`size := p.ProtoSize()`)
} else {
p.P(`size := p.Size()`)
}
p.P(`data := make([]byte, size)`) p.P(`data := make([]byte, size)`)
p.P(`for i := range data {`) p.P(`for i := range data {`)
p.In() p.In()

View File

@@ -419,7 +419,7 @@ func (p *unmarshal) noStarOrSliceType(msg *generator.Descriptor, field *descript
return typ return typ
} }
func (p *unmarshal) field(file *descriptor.FileDescriptorProto, msg *generator.Descriptor, field *descriptor.FieldDescriptorProto, fieldname string, proto3 bool) { func (p *unmarshal) field(file *generator.FileDescriptor, msg *generator.Descriptor, field *descriptor.FieldDescriptorProto, fieldname string, proto3 bool) {
repeated := field.IsRepeated() repeated := field.IsRepeated()
nullable := gogoproto.IsNullable(field) nullable := gogoproto.IsNullable(field)
typ := p.noStarOrSliceType(msg, field) typ := p.noStarOrSliceType(msg, field)
@@ -676,7 +676,7 @@ func (p *unmarshal) field(file *descriptor.FileDescriptorProto, msg *generator.D
p.Out() p.Out()
p.P(`}`) p.P(`}`)
p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`) p.P(`m.`, fieldname, ` = &`, p.OneOfTypeName(msg, field), `{v}`)
} else if generator.IsMap(file, field) { } else if generator.IsMap(file.FileDescriptorProto, field) {
m := p.GoMapType(nil, field) m := p.GoMapType(nil, field)
keygoTyp, _ := p.GoType(nil, m.KeyField) keygoTyp, _ := p.GoType(nil, m.KeyField)
@@ -773,7 +773,12 @@ func (p *unmarshal) field(file *descriptor.FileDescriptorProto, msg *generator.D
p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, make([]byte, postIndex-iNdEx))`) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `, make([]byte, postIndex-iNdEx))`)
p.P(`copy(m.`, fieldname, `[len(m.`, fieldname, `)-1], data[iNdEx:postIndex])`) p.P(`copy(m.`, fieldname, `[len(m.`, fieldname, `)-1], data[iNdEx:postIndex])`)
} else { } else {
p.P(`m.`, fieldname, ` = append([]byte{}`, `, data[iNdEx:postIndex]...)`) p.P(`m.`, fieldname, ` = append(m.`, fieldname, `[:0] , data[iNdEx:postIndex]...)`)
p.P(`if m.`, fieldname, ` == nil {`)
p.In()
p.P(`m.`, fieldname, ` = []byte{}`)
p.Out()
p.P(`}`)
} }
} else { } else {
_, ctyp, err := generator.GetCustomType(field) _, ctyp, err := generator.GetCustomType(field)
@@ -1061,13 +1066,13 @@ func (p *unmarshal) Generate(file *generator.FileDescriptor) {
p.P(`}`) p.P(`}`)
p.P(`for iNdEx < postIndex {`) p.P(`for iNdEx < postIndex {`)
p.In() p.In()
p.field(file.FileDescriptorProto, message, field, fieldname, false) p.field(file, message, field, fieldname, false)
p.Out() p.Out()
p.P(`}`) p.P(`}`)
p.Out() p.Out()
p.P(`} else if wireType == `, strconv.Itoa(wireType), `{`) p.P(`} else if wireType == `, strconv.Itoa(wireType), `{`)
p.In() p.In()
p.field(file.FileDescriptorProto, message, field, fieldname, false) p.field(file, message, field, fieldname, false)
p.Out() p.Out()
p.P(`} else {`) p.P(`} else {`)
p.In() p.In()
@@ -1080,7 +1085,7 @@ func (p *unmarshal) Generate(file *generator.FileDescriptor) {
p.P(`return ` + fmtPkg.Use() + `.Errorf("proto: wrong wireType = %d for field ` + errFieldname + `", wireType)`) p.P(`return ` + fmtPkg.Use() + `.Errorf("proto: wrong wireType = %d for field ` + errFieldname + `", wireType)`)
p.Out() p.Out()
p.P(`}`) p.P(`}`)
p.field(file.FileDescriptorProto, message, field, fieldname, proto3) p.field(file, message, field, fieldname, proto3)
} }
if field.IsRequired() { if field.IsRequired() {

View File

@@ -601,7 +601,7 @@ func (g *Generator) CommandLineParameters(parameter string) {
if pluginList == "none" { if pluginList == "none" {
pluginList = "" pluginList = ""
} }
gogoPluginNames := []string{"unmarshal", "unsafeunmarshaler", "union", "stringer", "size", "populate", "marshalto", "unsafemarshaler", "gostring", "face", "equal", "enumstringer", "embedcheck", "description", "defaultcheck", "oneofcheck"} gogoPluginNames := []string{"unmarshal", "unsafeunmarshaler", "union", "stringer", "size", "protosizer", "populate", "marshalto", "unsafemarshaler", "gostring", "face", "equal", "enumstringer", "embedcheck", "description", "defaultcheck", "oneofcheck"}
pluginList = strings.Join(append(gogoPluginNames, pluginList), "+") pluginList = strings.Join(append(gogoPluginNames, pluginList), "+")
if pluginList != "" { if pluginList != "" {
// Amend the set of plugins. // Amend the set of plugins.
@@ -1857,11 +1857,11 @@ var methodNames = [...]string{
"ExtensionRangeArray", "ExtensionRangeArray",
"ExtensionMap", "ExtensionMap",
"Descriptor", "Descriptor",
"Size",
"MarshalTo", "MarshalTo",
"Equal", "Equal",
"VerboseEqual", "VerboseEqual",
"GoString", "GoString",
"ProtoSize",
} }
// Generate the type and default constant definitions for this Descriptor. // Generate the type and default constant definitions for this Descriptor.
@@ -1875,6 +1875,9 @@ func (g *Generator) generateMessage(message *Descriptor) {
for _, n := range methodNames { for _, n := range methodNames {
usedNames[n] = true usedNames[n] = true
} }
if !gogoproto.IsProtoSizer(message.file, message.DescriptorProto) {
usedNames["Size"] = true
}
fieldNames := make(map[*descriptor.FieldDescriptorProto]string) fieldNames := make(map[*descriptor.FieldDescriptorProto]string)
fieldGetterNames := make(map[*descriptor.FieldDescriptorProto]string) fieldGetterNames := make(map[*descriptor.FieldDescriptorProto]string)
fieldTypes := make(map[*descriptor.FieldDescriptorProto]string) fieldTypes := make(map[*descriptor.FieldDescriptorProto]string)
@@ -2210,6 +2213,9 @@ func (g *Generator) generateMessage(message *Descriptor) {
if gogoproto.IsSizer(g.file.FileDescriptorProto, message.DescriptorProto) { if gogoproto.IsSizer(g.file.FileDescriptorProto, message.DescriptorProto) {
g.P(`Size() int`) g.P(`Size() int`)
} }
if gogoproto.IsProtoSizer(g.file.FileDescriptorProto, message.DescriptorProto) {
g.P(`ProtoSize() int`)
}
g.Out() g.Out()
g.P("}") g.P("}")
} }

View File

@@ -181,6 +181,11 @@ func (g *Generator) GetFieldName(message *Descriptor, field *descriptor.FieldDes
return fieldname + "_" return fieldname + "_"
} }
} }
if !gogoproto.IsProtoSizer(message.file, message.DescriptorProto) {
if fieldname == "Size" {
return fieldname + "_"
}
}
return fieldname return fieldname
} }
@@ -198,6 +203,11 @@ func (g *Generator) GetOneOfFieldName(message *Descriptor, field *descriptor.Fie
return fieldname + "_" return fieldname + "_"
} }
} }
if !gogoproto.IsProtoSizer(message.file, message.DescriptorProto) {
if fieldname == "Size" {
return fieldname + "_"
}
}
return fieldname return fieldname
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -30,171 +30,237 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
/* /*
Package proto converts data structures to and from the wire format of Package proto converts data structures to and from the wire format of
protocol buffers. It works in concert with the Go source code generated protocol buffers. It works in concert with the Go source code generated
for .proto files by the protocol compiler. for .proto files by the protocol compiler.
A summary of the properties of the protocol buffer interface A summary of the properties of the protocol buffer interface
for a protocol buffer variable v: for a protocol buffer variable v:
- Names are turned from camel_case to CamelCase for export. - Names are turned from camel_case to CamelCase for export.
- There are no methods on v to set fields; just treat - There are no methods on v to set fields; just treat
them as structure fields. them as structure fields.
- There are getters that return a field's value if set, - There are getters that return a field's value if set,
and return the field's default value if unset. and return the field's default value if unset.
The getters work even if the receiver is a nil message. The getters work even if the receiver is a nil message.
- The zero value for a struct is its correct initialization state. - The zero value for a struct is its correct initialization state.
All desired fields must be set before marshaling. All desired fields must be set before marshaling.
- A Reset() method will restore a protobuf struct to its zero state. - A Reset() method will restore a protobuf struct to its zero state.
- Non-repeated fields are pointers to the values; nil means unset. - Non-repeated fields are pointers to the values; nil means unset.
That is, optional or required field int32 f becomes F *int32. That is, optional or required field int32 f becomes F *int32.
- Repeated fields are slices. - Repeated fields are slices.
- Helper functions are available to aid the setting of fields. - Helper functions are available to aid the setting of fields.
Helpers for getting values are superseded by the msg.Foo = proto.String("hello") // set field
GetFoo methods and their use is deprecated. - Constants are defined to hold the default values of all fields that
msg.Foo = proto.String("hello") // set field have them. They have the form Default_StructName_FieldName.
- Constants are defined to hold the default values of all fields that Because the getter methods handle defaulted values,
have them. They have the form Default_StructName_FieldName. direct use of these constants should be rare.
Because the getter methods handle defaulted values, - Enums are given type names and maps from names to values.
direct use of these constants should be rare. Enum values are prefixed by the enclosing message's name, or by the
- Enums are given type names and maps from names to values. enum's type name if it is a top-level enum. Enum types have a String
Enum values are prefixed with the enum's type name. Enum types have method, and a Enum method to assist in message construction.
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
- Nested groups and enums have type names prefixed with the name of the surrounding message type.
the surrounding message type. - Extensions are given descriptor names that start with E_,
- Extensions are given descriptor names that start with E_, followed by an underscore-delimited list of the nested messages
followed by an underscore-delimited list of the nested messages that contain it (if any) followed by the CamelCased name of the
that contain it (if any) followed by the CamelCased name of the extension field itself. HasExtension, ClearExtension, GetExtension
extension field itself. HasExtension, ClearExtension, GetExtension and SetExtension are functions for manipulating extensions.
and SetExtension are functions for manipulating extensions. - Oneof field sets are given a single field in their message,
- Marshal and Unmarshal are functions to encode and decode the wire format. with distinguished wrapper types for each possible field value.
- Marshal and Unmarshal are functions to encode and decode the wire format.
The simplest way to describe this is to see an example. When the .proto file specifies `syntax="proto3"`, there are some differences:
Given file test.proto, containing
package example; - Non-repeated fields of non-message type are values instead of pointers.
- Getters are only generated for message and oneof fields.
- Enum types do not get an Enum method.
enum FOO { X = 17; }; The simplest way to describe this is to see an example.
Given file test.proto, containing
message Test { package example;
required string label = 1;
optional int32 type = 2 [default=77]; enum FOO { X = 17; }
repeated int64 reps = 3;
optional group OptionalGroup = 4 { message Test {
required string RequiredField = 5; required string label = 1;
} optional int32 type = 2 [default=77];
repeated int64 reps = 3;
optional group OptionalGroup = 4 {
required string RequiredField = 5;
}
oneof union {
int32 number = 6;
string name = 7;
}
}
The resulting file, test.pb.go, is:
package example
import proto "github.com/golang/protobuf/proto"
import math "math"
type FOO int32
const (
FOO_X FOO = 17
)
var FOO_name = map[int32]string{
17: "X",
}
var FOO_value = map[string]int32{
"X": 17,
}
func (x FOO) Enum() *FOO {
p := new(FOO)
*p = x
return p
}
func (x FOO) String() string {
return proto.EnumName(FOO_name, int32(x))
}
func (x *FOO) UnmarshalJSON(data []byte) error {
value, err := proto.UnmarshalJSONEnum(FOO_value, data)
if err != nil {
return err
} }
*x = FOO(value)
return nil
}
The resulting file, test.pb.go, is: type Test struct {
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"`
Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"`
Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"`
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"`
// Types that are valid to be assigned to Union:
// *Test_Number
// *Test_Name
Union isTest_Union `protobuf_oneof:"union"`
XXX_unrecognized []byte `json:"-"`
}
func (m *Test) Reset() { *m = Test{} }
func (m *Test) String() string { return proto.CompactTextString(m) }
func (*Test) ProtoMessage() {}
package example type isTest_Union interface {
isTest_Union()
}
import "github.com/golang/protobuf/proto" type Test_Number struct {
Number int32 `protobuf:"varint,6,opt,name=number"`
}
type Test_Name struct {
Name string `protobuf:"bytes,7,opt,name=name"`
}
type FOO int32 func (*Test_Number) isTest_Union() {}
const ( func (*Test_Name) isTest_Union() {}
FOO_X FOO = 17
) func (m *Test) GetUnion() isTest_Union {
var FOO_name = map[int32]string{ if m != nil {
17: "X", return m.Union
} }
var FOO_value = map[string]int32{ return nil
"X": 17, }
const Default_Test_Type int32 = 77
func (m *Test) GetLabel() string {
if m != nil && m.Label != nil {
return *m.Label
} }
return ""
}
func (x FOO) Enum() *FOO { func (m *Test) GetType() int32 {
p := new(FOO) if m != nil && m.Type != nil {
*p = x return *m.Type
return p
} }
func (x FOO) String() string { return Default_Test_Type
return proto.EnumName(FOO_name, int32(x)) }
func (m *Test) GetOptionalgroup() *Test_OptionalGroup {
if m != nil {
return m.Optionalgroup
} }
return nil
}
type Test struct { type Test_OptionalGroup struct {
Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,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"` func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} }
Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) }
XXX_unrecognized []byte `json:"-"`
func (m *Test_OptionalGroup) GetRequiredField() string {
if m != nil && m.RequiredField != nil {
return *m.RequiredField
} }
func (this *Test) Reset() { *this = Test{} } return ""
func (this *Test) String() string { return proto.CompactTextString(this) } }
const Default_Test_Type int32 = 77
func (this *Test) GetLabel() string { func (m *Test) GetNumber() int32 {
if this != nil && this.Label != nil { if x, ok := m.GetUnion().(*Test_Number); ok {
return *this.Label return x.Number
}
return ""
} }
return 0
}
func (this *Test) GetType() int32 { func (m *Test) GetName() string {
if this != nil && this.Type != nil { if x, ok := m.GetUnion().(*Test_Name); ok {
return *this.Type return x.Name
}
return Default_Test_Type
} }
return ""
}
func (this *Test) GetOptionalgroup() *Test_OptionalGroup { func init() {
if this != nil { proto.RegisterEnum("example.FOO", FOO_name, FOO_value)
return this.Optionalgroup }
}
return nil 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),
Reps: []int64{1, 2, 3},
Optionalgroup: &pb.Test_OptionalGroup{
RequiredField: proto.String("good bye"),
},
Union: &pb.Test_Name{"fred"},
} }
data, err := proto.Marshal(test)
type Test_OptionalGroup struct { if err != nil {
RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` log.Fatal("marshaling error: ", err)
XXX_unrecognized []byte `json:"-"`
} }
func (this *Test_OptionalGroup) Reset() { *this = Test_OptionalGroup{} } newTest := &pb.Test{}
func (this *Test_OptionalGroup) String() string { return proto.CompactTextString(this) } err = proto.Unmarshal(data, newTest)
if err != nil {
func (this *Test_OptionalGroup) GetRequiredField() string { log.Fatal("unmarshaling error: ", err)
if this != nil && this.RequiredField != nil {
return *this.RequiredField
}
return ""
} }
// Now test and newTest contain the same data.
func init() { if test.GetLabel() != newTest.GetLabel() {
proto.RegisterEnum("example.FOO", FOO_name, FOO_value) log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel())
} }
// Use a type switch to determine which oneof was set.
To create and play with a Test object: switch u := test.Union.(type) {
case *pb.Test_Number: // u.Number contains the number.
package main case *pb.Test_Name: // u.Name contains the string.
import (
"log"
"github.com/golang/protobuf/proto"
"./example.pb"
)
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 := new(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.
} }
// etc.
}
*/ */
package proto package proto
@@ -203,6 +269,7 @@ import (
"fmt" "fmt"
"log" "log"
"reflect" "reflect"
"sort"
"strconv" "strconv"
"sync" "sync"
) )
@@ -377,13 +444,13 @@ func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32,
// DebugPrint dumps the encoded data in b in a debugging format with a header // DebugPrint dumps the encoded data in b in a debugging format with a header
// including the string s. Used in testing but made available for general debugging. // including the string s. Used in testing but made available for general debugging.
func (o *Buffer) DebugPrint(s string, b []byte) { func (p *Buffer) DebugPrint(s string, b []byte) {
var u uint64 var u uint64
obuf := o.buf obuf := p.buf
index := o.index index := p.index
o.buf = b p.buf = b
o.index = 0 p.index = 0
depth := 0 depth := 0
fmt.Printf("\n--- %s ---\n", s) fmt.Printf("\n--- %s ---\n", s)
@@ -394,12 +461,12 @@ out:
fmt.Print(" ") fmt.Print(" ")
} }
index := o.index index := p.index
if index == len(o.buf) { if index == len(p.buf) {
break break
} }
op, err := o.DecodeVarint() op, err := p.DecodeVarint()
if err != nil { if err != nil {
fmt.Printf("%3d: fetching op err %v\n", index, err) fmt.Printf("%3d: fetching op err %v\n", index, err)
break out break out
@@ -416,7 +483,7 @@ out:
case WireBytes: case WireBytes:
var r []byte var r []byte
r, err = o.DecodeRawBytes(false) r, err = p.DecodeRawBytes(false)
if err != nil { if err != nil {
break out break out
} }
@@ -437,7 +504,7 @@ out:
fmt.Printf("\n") fmt.Printf("\n")
case WireFixed32: case WireFixed32:
u, err = o.DecodeFixed32() u, err = p.DecodeFixed32()
if err != nil { if err != nil {
fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err)
break out break out
@@ -445,16 +512,15 @@ out:
fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u)
case WireFixed64: case WireFixed64:
u, err = o.DecodeFixed64() u, err = p.DecodeFixed64()
if err != nil { if err != nil {
fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err)
break out break out
} }
fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u)
break
case WireVarint: case WireVarint:
u, err = o.DecodeVarint() u, err = p.DecodeVarint()
if err != nil { if err != nil {
fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err)
break out break out
@@ -462,30 +528,22 @@ out:
fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u)
case WireStartGroup: case WireStartGroup:
if err != nil {
fmt.Printf("%3d: t=%3d start err %v\n", index, tag, err)
break out
}
fmt.Printf("%3d: t=%3d start\n", index, tag) fmt.Printf("%3d: t=%3d start\n", index, tag)
depth++ depth++
case WireEndGroup: case WireEndGroup:
depth-- depth--
if err != nil {
fmt.Printf("%3d: t=%3d end err %v\n", index, tag, err)
break out
}
fmt.Printf("%3d: t=%3d end\n", index, tag) fmt.Printf("%3d: t=%3d end\n", index, tag)
} }
} }
if depth != 0 { if depth != 0 {
fmt.Printf("%3d: start-end not balanced %d\n", o.index, depth) fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth)
} }
fmt.Printf("\n") fmt.Printf("\n")
o.buf = obuf p.buf = obuf
o.index = index p.index = index
} }
// SetDefaults sets unset protocol buffer fields to their default values. // SetDefaults sets unset protocol buffer fields to their default values.
@@ -599,13 +657,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
for _, ni := range dm.nested { for _, ni := range dm.nested {
f := v.Field(ni) f := v.Field(ni)
if f.IsNil() { // f is *T or []*T or map[T]*T
continue switch f.Kind() {
} case reflect.Ptr:
// f is *T or []*T if f.IsNil() {
if f.Kind() == reflect.Ptr { continue
}
setDefaults(f, recur, zeros) setDefaults(f, recur, zeros)
} else {
case reflect.Slice:
for i := 0; i < f.Len(); i++ { for i := 0; i < f.Len(); i++ {
e := f.Index(i) e := f.Index(i)
if e.IsNil() { if e.IsNil() {
@@ -613,6 +673,15 @@ func setDefaults(v reflect.Value, recur, zeros bool) {
} }
setDefaults(e, recur, zeros) setDefaults(e, recur, zeros)
} }
case reflect.Map:
for _, k := range f.MapKeys() {
e := f.MapIndex(k)
if e.IsNil() {
continue
}
setDefaults(e, recur, zeros)
}
} }
} }
} }
@@ -638,10 +707,6 @@ type scalarField struct {
value interface{} // the proto-declared default value, or nil value interface{} // the proto-declared default value, or nil
} }
func ptrToStruct(t reflect.Type) bool {
return t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Struct
}
// t is a struct type. // t is a struct type.
func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
sprop := GetProperties(t) sprop := GetProperties(t)
@@ -653,99 +718,177 @@ func buildDefaultMessage(t reflect.Type) (dm defaultMessage) {
} }
ft := t.Field(fi).Type ft := t.Field(fi).Type
// nested messages sf, nested, err := fieldDefault(ft, prop)
if ptrToStruct(ft) || (ft.Kind() == reflect.Slice && ptrToStruct(ft.Elem())) { switch {
case err != nil:
log.Print(err)
case nested:
dm.nested = append(dm.nested, fi) dm.nested = append(dm.nested, fi)
continue case sf != nil:
sf.index = fi
dm.scalars = append(dm.scalars, *sf)
} }
sf := scalarField{
index: fi,
kind: ft.Elem().Kind(),
}
// 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 return dm
} }
// fieldDefault returns the scalarField for field type ft.
// sf will be nil if the field can not have a default.
// nestedMessage will be true if this is a nested message.
// Note that sf.index is not set on return.
func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) {
var canHaveDefault bool
switch ft.Kind() {
case reflect.Ptr:
if ft.Elem().Kind() == reflect.Struct {
nestedMessage = true
} else {
canHaveDefault = true // proto2 scalar field
}
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 {
return nil, true, nil
}
return nil, false, nil
}
// We now know that ft is a pointer or slice.
sf = &scalarField{kind: ft.Elem().Kind()}
// scalar fields without defaults
if !prop.HasDefault {
return sf, false, nil
}
// a scalar field: either *T or []byte
switch ft.Elem().Kind() {
case reflect.Bool:
x, err := strconv.ParseBool(prop.Default)
if err != nil {
return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err)
}
sf.value = x
case reflect.Float32:
x, err := strconv.ParseFloat(prop.Default, 32)
if err != nil {
return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err)
}
sf.value = float32(x)
case reflect.Float64:
x, err := strconv.ParseFloat(prop.Default, 64)
if err != nil {
return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err)
}
sf.value = x
case reflect.Int32:
x, err := strconv.ParseInt(prop.Default, 10, 32)
if err != nil {
return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err)
}
sf.value = int32(x)
case reflect.Int64:
x, err := strconv.ParseInt(prop.Default, 10, 64)
if err != nil {
return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err)
}
sf.value = x
case reflect.String:
sf.value = prop.Default
case reflect.Uint8:
// []byte (not *uint8)
sf.value = []byte(prop.Default)
case reflect.Uint32:
x, err := strconv.ParseUint(prop.Default, 10, 32)
if err != nil {
return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err)
}
sf.value = uint32(x)
case reflect.Uint64:
x, err := strconv.ParseUint(prop.Default, 10, 64)
if err != nil {
return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err)
}
sf.value = x
default:
return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind())
}
return sf, false, nil
}
// Map fields may have key types of non-float scalars, strings and enums. // Map fields may have key types of non-float scalars, strings and enums.
// The easiest way to sort them in some deterministic order is to use fmt. // 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, // If this turns out to be inefficient we can always consider other options,
// such as doing a Schwartzian transform. // such as doing a Schwartzian transform.
type mapKeys []reflect.Value func mapKeys(vs []reflect.Value) sort.Interface {
s := mapKeySorter{
vs: vs,
// default Less function: textual comparison
less: func(a, b reflect.Value) bool {
return fmt.Sprint(a.Interface()) < fmt.Sprint(b.Interface())
},
}
func (s mapKeys) Len() int { return len(s) } // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps;
func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } // numeric keys are sorted numerically.
func (s mapKeys) Less(i, j int) bool { if len(vs) == 0 {
return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) return s
}
switch vs[0].Kind() {
case reflect.Int32, reflect.Int64:
s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() }
case reflect.Uint32, reflect.Uint64:
s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() }
}
return s
} }
type mapKeySorter struct {
vs []reflect.Value
less func(a, b reflect.Value) bool
}
func (s mapKeySorter) Len() int { return len(s.vs) }
func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] }
func (s mapKeySorter) Less(i, j int) bool {
return s.less(s.vs[i], s.vs[j])
}
// isProto3Zero reports whether v is a zero proto3 value.
func isProto3Zero(v reflect.Value) bool {
switch v.Kind() {
case reflect.Bool:
return !v.Bool()
case reflect.Int32, reflect.Int64:
return v.Int() == 0
case reflect.Uint32, reflect.Uint64:
return v.Uint() == 0
case reflect.Float32, reflect.Float64:
return v.Float() == 0
case reflect.String:
return v.String() == ""
}
return false
}
// ProtoPackageIsVersion1 is referenced from generated protocol buffer files
// to assert that that code is compatible with this version of the proto package.
const ProtoPackageIsVersion1 = true

View File

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

View File

@@ -29,7 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// +build appengine,!appenginevm // +build appengine
// This file contains an implementation of proto field accesses using package reflect. // This file contains an implementation of proto field accesses using package reflect.
// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can // It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can
@@ -144,8 +144,8 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
return structPointer_ifield(p, f).(*map[int32]Extension) return structPointer_ifield(p, f).(*map[int32]Extension)
} }
// Map returns the reflect.Value for the address of a map field in the struct. // NewAt returns the reflect.Value for a pointer to a field in the struct.
func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value { func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
return structPointer_field(p, f).Addr() return structPointer_field(p, f).Addr()
} }

View File

@@ -29,7 +29,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// +build !appengine appenginevm // +build !appengine
// This file contains the implementation of the proto field accesses using package unsafe. // This file contains the implementation of the proto field accesses using package unsafe.
@@ -130,8 +130,8 @@ func structPointer_ExtMap(p structPointer, f field) *map[int32]Extension {
return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f))) return (*map[int32]Extension)(unsafe.Pointer(uintptr(p) + uintptr(f)))
} }
// Map returns the reflect.Value for the address of a map field in the struct. // NewAt returns the reflect.Value for a pointer to a field in the struct.
func structPointer_Map(p structPointer, f field, typ reflect.Type) reflect.Value { func structPointer_NewAt(p structPointer, f field, typ reflect.Type) reflect.Value {
return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f))) return reflect.NewAt(typ, unsafe.Pointer(uintptr(p)+uintptr(f)))
} }

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -119,6 +119,14 @@ func isWhitespace(c byte) bool {
return false return false
} }
func isQuote(c byte) bool {
switch c {
case '"', '\'':
return true
}
return false
}
func (p *textParser) skipWhitespace() { func (p *textParser) skipWhitespace() {
i := 0 i := 0
for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') {
@@ -174,7 +182,7 @@ func (p *textParser) advance() {
} }
unq, err := unquoteC(p.s[1:i], rune(p.s[0])) unq, err := unquoteC(p.s[1:i], rune(p.s[0]))
if err != nil { if err != nil {
p.errorf("invalid quoted string %v", p.s[0:i+1]) p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err)
return return
} }
p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)]
@@ -333,13 +341,13 @@ func (p *textParser) next() *token {
p.advance() p.advance()
if p.done { if p.done {
p.cur.value = "" p.cur.value = ""
} else if len(p.cur.value) > 0 && p.cur.value[0] == '"' { } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) {
// Look for multiple quoted strings separated by whitespace, // Look for multiple quoted strings separated by whitespace,
// and concatenate them. // and concatenate them.
cat := p.cur cat := p.cur
for { for {
p.skipWhitespace() p.skipWhitespace()
if p.done || p.s[0] != '"' { if p.done || !isQuote(p.s[0]) {
break break
} }
p.advance() p.advance()
@@ -385,8 +393,7 @@ func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSet
} }
// Returns the index in the struct for the named field, as well as the parsed tag properties. // Returns the index in the struct for the named field, as well as the parsed tag properties.
func structFieldByName(st reflect.Type, name string) (int, *Properties, bool) { func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) {
sprops := GetProperties(st)
i, ok := sprops.decoderOrigNames[name] i, ok := sprops.decoderOrigNames[name]
if ok { if ok {
return i, sprops.Prop[i], true return i, sprops.Prop[i], true
@@ -438,7 +445,8 @@ func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseEr
func (p *textParser) readStruct(sv reflect.Value, terminator string) error { func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
st := sv.Type() st := sv.Type()
reqCount := GetProperties(st).reqCount sprops := GetProperties(st)
reqCount := sprops.reqCount
var reqFieldErr error var reqFieldErr error
fieldSet := make(map[string]bool) fieldSet := make(map[string]bool)
// A struct is a sequence of "name: value", terminated by one of // A struct is a sequence of "name: value", terminated by one of
@@ -520,99 +528,113 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
sl = reflect.Append(sl, ext) sl = reflect.Append(sl, ext)
SetExtension(ep, desc, sl.Interface()) SetExtension(ep, desc, sl.Interface())
} }
} else { if err := p.consumeOptionalSeparator(); err != nil {
// This is a normal, non-extension field. return err
name := tok.value
fi, props, ok := structFieldByName(st, name)
if !ok {
return p.errorf("unknown field name %q in %v", name, st)
} }
continue
}
dst := sv.Field(fi) // This is a normal, non-extension field.
name := tok.value
var dst reflect.Value
fi, props, ok := structFieldByName(sprops, name)
if ok {
dst = sv.Field(fi)
} else if oop, ok := sprops.OneofTypes[name]; ok {
// It is a oneof.
props = oop.Prop
nv := reflect.New(oop.Type.Elem())
dst = nv.Elem().Field(0)
sv.Field(oop.Field).Set(nv)
}
if !dst.IsValid() {
return p.errorf("unknown field name %q in %v", name, st)
}
if dst.Kind() == reflect.Map { if dst.Kind() == reflect.Map {
// Consume any colon. // Consume any colon.
if err := p.checkForColon(props, dst.Type()); err != nil { if err := p.checkForColon(props, dst.Type()); err != nil {
return err
}
// Construct the map if it doesn't already exist.
if dst.IsNil() {
dst.Set(reflect.MakeMap(dst.Type()))
}
key := reflect.New(dst.Type().Key()).Elem()
val := reflect.New(dst.Type().Elem()).Elem()
// The map entry should be this sequence of tokens:
// < key : KEY value : VALUE >
// Technically the "key" and "value" could come in any order,
// but in practice they won't.
tok := p.next()
var terminator string
switch tok.value {
case "<":
terminator = ">"
case "{":
terminator = "}"
default:
return p.errorf("expected '{' or '<', found %q", tok.value)
}
if err := p.consumeToken("key"); err != nil {
return err
}
if err := p.consumeToken(":"); err != nil {
return err
}
if err := p.readAny(key, props.mkeyprop); err != nil {
return err
}
if err := p.consumeToken("value"); err != nil {
return err
}
if err := p.consumeToken(":"); err != nil {
return err
}
if err := p.readAny(val, props.mvalprop); err != nil {
return err
}
if err := p.consumeToken(terminator); err != nil {
return err
}
dst.SetMapIndex(key, val)
continue
}
// Check that it's not already set if it's not a repeated field.
if !props.Repeated && fieldSet[name] {
return p.errorf("non-repeated field %q was repeated", name)
}
if err := p.checkForColon(props, st.Field(fi).Type); err != nil {
return err return err
} }
// Parse into the field. // Construct the map if it doesn't already exist.
fieldSet[name] = true if dst.IsNil() {
if err := p.readAny(dst, props); err != nil { dst.Set(reflect.MakeMap(dst.Type()))
if _, ok := err.(*RequiredNotSetError); !ok {
return err
}
reqFieldErr = err
} else if props.Required {
reqCount--
} }
key := reflect.New(dst.Type().Key()).Elem()
val := reflect.New(dst.Type().Elem()).Elem()
// The map entry should be this sequence of tokens:
// < key : KEY value : VALUE >
// Technically the "key" and "value" could come in any order,
// but in practice they won't.
tok := p.next()
var terminator string
switch tok.value {
case "<":
terminator = ">"
case "{":
terminator = "}"
default:
return p.errorf("expected '{' or '<', found %q", tok.value)
}
if err := p.consumeToken("key"); err != nil {
return err
}
if err := p.consumeToken(":"); err != nil {
return err
}
if err := p.readAny(key, props.mkeyprop); err != nil {
return err
}
if err := p.consumeOptionalSeparator(); err != nil {
return err
}
if err := p.consumeToken("value"); err != nil {
return err
}
if err := p.checkForColon(props.mvalprop, dst.Type().Elem()); err != nil {
return err
}
if err := p.readAny(val, props.mvalprop); err != nil {
return err
}
if err := p.consumeOptionalSeparator(); err != nil {
return err
}
if err := p.consumeToken(terminator); err != nil {
return err
}
dst.SetMapIndex(key, val)
continue
} }
// For backward compatibility, permit a semicolon or comma after a field. // Check that it's not already set if it's not a repeated field.
tok = p.next() if !props.Repeated && fieldSet[name] {
if tok.err != nil { return p.errorf("non-repeated field %q was repeated", name)
return tok.err
} }
if tok.value != ";" && tok.value != "," {
p.back() if err := p.checkForColon(props, dst.Type()); err != nil {
return err
} }
// Parse into the field.
fieldSet[name] = true
if err := p.readAny(dst, props); err != nil {
if _, ok := err.(*RequiredNotSetError); !ok {
return err
}
reqFieldErr = err
} else if props.Required {
reqCount--
}
if err := p.consumeOptionalSeparator(); err != nil {
return err
}
} }
if reqCount > 0 { if reqCount > 0 {
@@ -621,6 +643,19 @@ func (p *textParser) readStruct(sv reflect.Value, terminator string) error {
return reqFieldErr return reqFieldErr
} }
// consumeOptionalSeparator consumes an optional semicolon or comma.
// It is used in readStruct to provide backward compatibility.
func (p *textParser) consumeOptionalSeparator() error {
tok := p.next()
if tok.err != nil {
return tok.err
}
if tok.value != ";" && tok.value != "," {
p.back()
}
return nil
}
func (p *textParser) readAny(v reflect.Value, props *Properties) error { func (p *textParser) readAny(v reflect.Value, props *Properties) error {
tok := p.next() tok := p.next()
if tok.err != nil { if tok.err != nil {
@@ -645,18 +680,32 @@ func (p *textParser) readAny(v reflect.Value, props *Properties) error {
fv.Set(reflect.ValueOf(bytes)) fv.Set(reflect.ValueOf(bytes))
return nil return nil
} }
// Repeated field. May already exist. // Repeated field.
flen := fv.Len() if tok.value == "[" {
if flen == fv.Cap() { // Repeated field with list notation, like [1,2,3].
nav := reflect.MakeSlice(at, flen, 2*flen+1) for {
reflect.Copy(nav, fv) fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
fv.Set(nav) err := p.readAny(fv.Index(fv.Len()-1), props)
if err != nil {
return err
}
tok := p.next()
if tok.err != nil {
return tok.err
}
if tok.value == "]" {
break
}
if tok.value != "," {
return p.errorf("Expected ']' or ',' found %q", tok.value)
}
}
return nil
} }
fv.SetLen(flen + 1) // One value of the repeated field.
// Read one.
p.back() p.back()
return p.readAny(fv.Index(flen), props) fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem()))
return p.readAny(fv.Index(fv.Len()-1), props)
case reflect.Bool: case reflect.Bool:
// Either "true", "false", 1 or 0. // Either "true", "false", 1 or 0.
switch tok.value { switch tok.value {

View File

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

View File

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

View File

@@ -19,8 +19,9 @@ type buffer struct {
} }
var ( var (
errReadEmpty = errors.New("read from empty buffer") errReadEmpty = errors.New("read from empty buffer")
errWriteFull = errors.New("write on full buffer") errWriteClosed = errors.New("write on closed buffer")
errWriteFull = errors.New("write on full buffer")
) )
// Read copies bytes from the buffer into p. // Read copies bytes from the buffer into p.
@@ -45,7 +46,7 @@ func (b *buffer) Len() int {
// It is an error to write more data than the buffer can hold. // It is an error to write more data than the buffer can hold.
func (b *buffer) Write(p []byte) (n int, err error) { func (b *buffer) Write(p []byte) (n int, err error) {
if b.closed { if b.closed {
return 0, errors.New("closed") return 0, errWriteClosed
} }
// Slide existing data to beginning. // Slide existing data to beginning.

View File

@@ -85,8 +85,8 @@ const (
// Continuation Frame // Continuation Frame
FlagContinuationEndHeaders Flags = 0x4 FlagContinuationEndHeaders Flags = 0x4
FlagPushPromiseEndHeaders = 0x4 FlagPushPromiseEndHeaders Flags = 0x4
FlagPushPromisePadded = 0x8 FlagPushPromisePadded Flags = 0x8
) )
var flagName = map[FrameType]map[Flags]string{ var flagName = map[FrameType]map[Flags]string{

View File

@@ -14,16 +14,20 @@ import (
"bytes" "bytes"
"errors" "errors"
"fmt" "fmt"
"os"
"runtime" "runtime"
"strconv" "strconv"
"sync" "sync"
) )
var DebugGoroutines = false var DebugGoroutines = os.Getenv("DEBUG_HTTP2_GOROUTINES") == "1"
type goroutineLock uint64 type goroutineLock uint64
func newGoroutineLock() goroutineLock { func newGoroutineLock() goroutineLock {
if !DebugGoroutines {
return 0
}
return goroutineLock(curGoroutineID()) return goroutineLock(curGoroutineID())
} }

View File

@@ -31,7 +31,7 @@ import (
"camlistore.org/pkg/googlestorage" "camlistore.org/pkg/googlestorage"
"camlistore.org/pkg/singleflight" "camlistore.org/pkg/singleflight"
"github.com/bradfitz/http2" "golang.org/x/net/http2"
) )
var ( var (
@@ -51,7 +51,7 @@ func homeOldHTTP(w http.ResponseWriter, r *http.Request) {
<li>Use Firefox Nightly or go to <b>about:config</b> and enable "network.http.spdy.enabled.http2draft"</li> <li>Use Firefox Nightly or go to <b>about:config</b> and enable "network.http.spdy.enabled.http2draft"</li>
<li>Use Google Chrome Canary and/or go to <b>chrome://flags/#enable-spdy4</b> to <i>Enable SPDY/4</i> (Chrome's name for HTTP/2)</li> <li>Use Google Chrome Canary and/or go to <b>chrome://flags/#enable-spdy4</b> to <i>Enable SPDY/4</i> (Chrome's name for HTTP/2)</li>
</ul> </ul>
<p>See code & instructions for connecting at <a href="https://github.com/bradfitz/http2">https://github.com/bradfitz/http2</a>.</p> <p>See code & instructions for connecting at <a href="https://github.com/golang/net/tree/master/http2">https://github.com/golang/net/tree/master/http2</a>.</p>
</body></html>`) </body></html>`)
} }
@@ -73,12 +73,12 @@ href="https://http2.github.io/">HTTP/2</a> demo & interop server.</p>
<p>This server exists for others in the HTTP/2 community to test their HTTP/2 client implementations and point out flaws in our server.</p> <p>This server exists for others in the HTTP/2 community to test their HTTP/2 client implementations and point out flaws in our server.</p>
<p> The code is currently at <a <p> The code is currently at <a
href="https://github.com/bradfitz/http2">github.com/bradfitz/http2</a> href="https://golang.org/x/net/http2">github.com/bradfitz/http2</a>
but will move to the Go standard library at some point in the future but will move to the Go standard library at some point in the future
(enabled by default, without users needing to change their code).</p> (enabled by default, without users needing to change their code).</p>
<p>Contact info: <i>bradfitz@golang.org</i>, or <a <p>Contact info: <i>bradfitz@golang.org</i>, or <a
href="https://github.com/bradfitz/http2/issues">file a bug</a>.</p> href="https://golang.org/x/net/http2/issues">file a bug</a>.</p>
<h2>Handlers for testing</h2> <h2>Handlers for testing</h2>
<ul> <ul>
@@ -287,7 +287,7 @@ func newGopherTilesHandler() http.Handler {
return return
} }
} }
io.WriteString(w, "<html><body>") io.WriteString(w, "<html><body onload='showtimes()'>")
fmt.Fprintf(w, "A grid of %d tiled images is below. Compare:<p>", xt*yt) fmt.Fprintf(w, "A grid of %d tiled images is below. Compare:<p>", xt*yt)
for _, ms := range []int{0, 30, 200, 1000} { for _, ms := range []int{0, 30, 200, 1000} {
d := time.Duration(ms) * nanosPerMilli d := time.Duration(ms) * nanosPerMilli
@@ -305,7 +305,16 @@ func newGopherTilesHandler() http.Handler {
} }
io.WriteString(w, "<br/>\n") io.WriteString(w, "<br/>\n")
} }
io.WriteString(w, "<hr><a href='/'>&lt;&lt Back to Go HTTP/2 demo server</a></body></html>") io.WriteString(w, `<p><div id='loadtimes'></div></p>
<script>
function showtimes() {
var times = 'Times from connection start:<br>'
times += 'DOM loaded: ' + (window.performance.timing.domContentLoadedEventEnd - window.performance.timing.connectStart) + 'ms<br>'
times += 'DOM complete (images loaded): ' + (window.performance.timing.domComplete - window.performance.timing.connectStart) + 'ms<br>'
document.getElementById('loadtimes').innerHTML = times
}
</script>
<hr><a href='/'>&lt;&lt Back to Go HTTP/2 demo server</a></body></html>`)
}) })
} }

View File

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

View File

@@ -0,0 +1,97 @@
# h2i
**h2i** is an interactive HTTP/2 ("h2") console debugger. Miss the good ol'
days of telnetting to your HTTP/1.n servers? We're bringing you
back.
Features:
- send raw HTTP/2 frames
- PING
- SETTINGS
- HEADERS
- etc
- type in HTTP/1.n and have it auto-HPACK/frame-ify it for HTTP/2
- pretty print all received HTTP/2 frames from the peer (including HPACK decoding)
- tab completion of commands, options
Not yet features, but soon:
- unnecessary CONTINUATION frames on short boundaries, to test peer implementations
- request bodies (DATA frames)
- send invalid frames for testing server implementations (supported by underlying Framer)
Later:
- act like a server
## Installation
```
$ go get golang.org/x/net/http2/h2i
$ h2i <host>
```
## Demo
```
$ h2i
Usage: h2i <hostname>
-insecure
Whether to skip TLS cert validation
-nextproto string
Comma-separated list of NPN/ALPN protocol names to negotiate. (default "h2,h2-14")
$ h2i google.com
Connecting to google.com:443 ...
Connected to 74.125.224.41:443
Negotiated protocol "h2-14"
[FrameHeader SETTINGS len=18]
[MAX_CONCURRENT_STREAMS = 100]
[INITIAL_WINDOW_SIZE = 1048576]
[MAX_FRAME_SIZE = 16384]
[FrameHeader WINDOW_UPDATE len=4]
Window-Increment = 983041
h2i> PING h2iSayHI
[FrameHeader PING flags=ACK len=8]
Data = "h2iSayHI"
h2i> headers
(as HTTP/1.1)> GET / HTTP/1.1
(as HTTP/1.1)> Host: ip.appspot.com
(as HTTP/1.1)> User-Agent: h2i/brad-n-blake
(as HTTP/1.1)>
Opening Stream-ID 1:
:authority = ip.appspot.com
:method = GET
:path = /
:scheme = https
user-agent = h2i/brad-n-blake
[FrameHeader HEADERS flags=END_HEADERS stream=1 len=77]
:status = "200"
alternate-protocol = "443:quic,p=1"
content-length = "15"
content-type = "text/html"
date = "Fri, 01 May 2015 23:06:56 GMT"
server = "Google Frontend"
[FrameHeader DATA flags=END_STREAM stream=1 len=15]
"173.164.155.78\n"
[FrameHeader PING len=8]
Data = "\x00\x00\x00\x00\x00\x00\x00\x00"
h2i> ping
[FrameHeader PING flags=ACK len=8]
Data = "h2i_ping"
h2i> ping
[FrameHeader PING flags=ACK len=8]
Data = "h2i_ping"
h2i> ping
[FrameHeader GOAWAY len=22]
Last-Stream-ID = 1; Error-Code = PROTOCOL_ERROR (1)
ReadFrame: EOF
```
## Status
Quick few hour hack. So much yet to do. Feel free to file issues for
bugs or wishlist items, but [@bmizerany](https://github.com/bmizerany/)
and I aren't yet accepting pull requests until things settle down.

489
Godeps/_workspace/src/golang.org/x/net/http2/h2i/h2i.go generated vendored Normal file
View File

@@ -0,0 +1,489 @@
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// See https://code.google.com/p/go/source/browse/CONTRIBUTORS
// Licensed under the same terms as Go itself:
// https://code.google.com/p/go/source/browse/LICENSE
/*
The h2i command is an interactive HTTP/2 console.
Usage:
$ h2i [flags] <hostname>
Interactive commands in the console: (all parts case-insensitive)
ping [data]
settings ack
settings FOO=n BAR=z
headers (open a new stream by typing HTTP/1.1)
*/
package main
import (
"bufio"
"bytes"
"crypto/tls"
"errors"
"flag"
"fmt"
"io"
"log"
"net"
"net/http"
"os"
"regexp"
"strconv"
"strings"
"golang.org/x/crypto/ssh/terminal"
"golang.org/x/net/http2"
"golang.org/x/net/http2/hpack"
)
// Flags
var (
flagNextProto = flag.String("nextproto", "h2,h2-14", "Comma-separated list of NPN/ALPN protocol names to negotiate.")
flagInsecure = flag.Bool("insecure", false, "Whether to skip TLS cert validation")
)
type command struct {
run func(*h2i, []string) error // required
// complete optionally specifies tokens (case-insensitive) which are
// valid for this subcommand.
complete func() []string
}
var commands = map[string]command{
"ping": command{run: (*h2i).cmdPing},
"settings": command{
run: (*h2i).cmdSettings,
complete: func() []string {
return []string{
"ACK",
http2.SettingHeaderTableSize.String(),
http2.SettingEnablePush.String(),
http2.SettingMaxConcurrentStreams.String(),
http2.SettingInitialWindowSize.String(),
http2.SettingMaxFrameSize.String(),
http2.SettingMaxHeaderListSize.String(),
}
},
},
"quit": command{run: (*h2i).cmdQuit},
"headers": command{run: (*h2i).cmdHeaders},
}
func usage() {
fmt.Fprintf(os.Stderr, "Usage: h2i <hostname>\n\n")
flag.PrintDefaults()
os.Exit(1)
}
// withPort adds ":443" if another port isn't already present.
func withPort(host string) string {
if _, _, err := net.SplitHostPort(host); err != nil {
return net.JoinHostPort(host, "443")
}
return host
}
// h2i is the app's state.
type h2i struct {
host string
tc *tls.Conn
framer *http2.Framer
term *terminal.Terminal
// owned by the command loop:
streamID uint32
hbuf bytes.Buffer
henc *hpack.Encoder
// owned by the readFrames loop:
peerSetting map[http2.SettingID]uint32
hdec *hpack.Decoder
}
func main() {
flag.Usage = usage
flag.Parse()
if flag.NArg() != 1 {
usage()
}
log.SetFlags(0)
host := flag.Arg(0)
app := &h2i{
host: host,
peerSetting: make(map[http2.SettingID]uint32),
}
app.henc = hpack.NewEncoder(&app.hbuf)
if err := app.Main(); err != nil {
if app.term != nil {
app.logf("%v\n", err)
} else {
fmt.Fprintf(os.Stderr, "%v\n", err)
}
os.Exit(1)
}
fmt.Fprintf(os.Stdout, "\n")
}
func (app *h2i) Main() error {
cfg := &tls.Config{
ServerName: app.host,
NextProtos: strings.Split(*flagNextProto, ","),
InsecureSkipVerify: *flagInsecure,
}
hostAndPort := withPort(app.host)
log.Printf("Connecting to %s ...", hostAndPort)
tc, err := tls.Dial("tcp", hostAndPort, cfg)
if err != nil {
return fmt.Errorf("Error dialing %s: %v", withPort(app.host), err)
}
log.Printf("Connected to %v", tc.RemoteAddr())
defer tc.Close()
if err := tc.Handshake(); err != nil {
return fmt.Errorf("TLS handshake: %v", err)
}
if !*flagInsecure {
if err := tc.VerifyHostname(app.host); err != nil {
return fmt.Errorf("VerifyHostname: %v", err)
}
}
state := tc.ConnectionState()
log.Printf("Negotiated protocol %q", state.NegotiatedProtocol)
if !state.NegotiatedProtocolIsMutual || state.NegotiatedProtocol == "" {
return fmt.Errorf("Could not negotiate protocol mutually")
}
if _, err := io.WriteString(tc, http2.ClientPreface); err != nil {
return err
}
app.framer = http2.NewFramer(tc, tc)
oldState, err := terminal.MakeRaw(0)
if err != nil {
return err
}
defer terminal.Restore(0, oldState)
var screen = struct {
io.Reader
io.Writer
}{os.Stdin, os.Stdout}
app.term = terminal.NewTerminal(screen, "h2i> ")
lastWord := regexp.MustCompile(`.+\W(\w+)$`)
app.term.AutoCompleteCallback = func(line string, pos int, key rune) (newLine string, newPos int, ok bool) {
if key != '\t' {
return
}
if pos != len(line) {
// TODO: we're being lazy for now, only supporting tab completion at the end.
return
}
// Auto-complete for the command itself.
if !strings.Contains(line, " ") {
var name string
name, _, ok = lookupCommand(line)
if !ok {
return
}
return name, len(name), true
}
_, c, ok := lookupCommand(line[:strings.IndexByte(line, ' ')])
if !ok || c.complete == nil {
return
}
if strings.HasSuffix(line, " ") {
app.logf("%s", strings.Join(c.complete(), " "))
return line, pos, true
}
m := lastWord.FindStringSubmatch(line)
if m == nil {
return line, len(line), true
}
soFar := m[1]
var match []string
for _, cand := range c.complete() {
if len(soFar) > len(cand) || !strings.EqualFold(cand[:len(soFar)], soFar) {
continue
}
match = append(match, cand)
}
if len(match) == 0 {
return
}
if len(match) > 1 {
// TODO: auto-complete any common prefix
app.logf("%s", strings.Join(match, " "))
return line, pos, true
}
newLine = line[:len(line)-len(soFar)] + match[0]
return newLine, len(newLine), true
}
errc := make(chan error, 2)
go func() { errc <- app.readFrames() }()
go func() { errc <- app.readConsole() }()
return <-errc
}
func (app *h2i) logf(format string, args ...interface{}) {
fmt.Fprintf(app.term, format+"\n", args...)
}
func (app *h2i) readConsole() error {
for {
line, err := app.term.ReadLine()
if err == io.EOF {
return nil
}
if err != nil {
return fmt.Errorf("terminal.ReadLine: %v", err)
}
f := strings.Fields(line)
if len(f) == 0 {
continue
}
cmd, args := f[0], f[1:]
if _, c, ok := lookupCommand(cmd); ok {
err = c.run(app, args)
} else {
app.logf("Unknown command %q", line)
}
if err == errExitApp {
return nil
}
if err != nil {
return err
}
}
}
func lookupCommand(prefix string) (name string, c command, ok bool) {
prefix = strings.ToLower(prefix)
if c, ok = commands[prefix]; ok {
return prefix, c, ok
}
for full, candidate := range commands {
if strings.HasPrefix(full, prefix) {
if c.run != nil {
return "", command{}, false // ambiguous
}
c = candidate
name = full
}
}
return name, c, c.run != nil
}
var errExitApp = errors.New("internal sentinel error value to quit the console reading loop")
func (a *h2i) cmdQuit(args []string) error {
if len(args) > 0 {
a.logf("the QUIT command takes no argument")
return nil
}
return errExitApp
}
func (a *h2i) cmdSettings(args []string) error {
if len(args) == 1 && strings.EqualFold(args[0], "ACK") {
return a.framer.WriteSettingsAck()
}
var settings []http2.Setting
for _, arg := range args {
if strings.EqualFold(arg, "ACK") {
a.logf("Error: ACK must be only argument with the SETTINGS command")
return nil
}
eq := strings.Index(arg, "=")
if eq == -1 {
a.logf("Error: invalid argument %q (expected SETTING_NAME=nnnn)", arg)
return nil
}
sid, ok := settingByName(arg[:eq])
if !ok {
a.logf("Error: unknown setting name %q", arg[:eq])
return nil
}
val, err := strconv.ParseUint(arg[eq+1:], 10, 32)
if err != nil {
a.logf("Error: invalid argument %q (expected SETTING_NAME=nnnn)", arg)
return nil
}
settings = append(settings, http2.Setting{
ID: sid,
Val: uint32(val),
})
}
a.logf("Sending: %v", settings)
return a.framer.WriteSettings(settings...)
}
func settingByName(name string) (http2.SettingID, bool) {
for _, sid := range [...]http2.SettingID{
http2.SettingHeaderTableSize,
http2.SettingEnablePush,
http2.SettingMaxConcurrentStreams,
http2.SettingInitialWindowSize,
http2.SettingMaxFrameSize,
http2.SettingMaxHeaderListSize,
} {
if strings.EqualFold(sid.String(), name) {
return sid, true
}
}
return 0, false
}
func (app *h2i) cmdPing(args []string) error {
if len(args) > 1 {
app.logf("invalid PING usage: only accepts 0 or 1 args")
return nil // nil means don't end the program
}
var data [8]byte
if len(args) == 1 {
copy(data[:], args[0])
} else {
copy(data[:], "h2i_ping")
}
return app.framer.WritePing(false, data)
}
func (app *h2i) cmdHeaders(args []string) error {
if len(args) > 0 {
app.logf("Error: HEADERS doesn't yet take arguments.")
// TODO: flags for restricting window size, to force CONTINUATION
// frames.
return nil
}
var h1req bytes.Buffer
app.term.SetPrompt("(as HTTP/1.1)> ")
defer app.term.SetPrompt("h2i> ")
for {
line, err := app.term.ReadLine()
if err != nil {
return err
}
h1req.WriteString(line)
h1req.WriteString("\r\n")
if line == "" {
break
}
}
req, err := http.ReadRequest(bufio.NewReader(&h1req))
if err != nil {
app.logf("Invalid HTTP/1.1 request: %v", err)
return nil
}
if app.streamID == 0 {
app.streamID = 1
} else {
app.streamID += 2
}
app.logf("Opening Stream-ID %d:", app.streamID)
hbf := app.encodeHeaders(req)
if len(hbf) > 16<<10 {
app.logf("TODO: h2i doesn't yet write CONTINUATION frames. Copy it from transport.go")
return nil
}
return app.framer.WriteHeaders(http2.HeadersFrameParam{
StreamID: app.streamID,
BlockFragment: hbf,
EndStream: req.Method == "GET" || req.Method == "HEAD", // good enough for now
EndHeaders: true, // for now
})
}
func (app *h2i) readFrames() error {
for {
f, err := app.framer.ReadFrame()
if err != nil {
return fmt.Errorf("ReadFrame: %v", err)
}
app.logf("%v", f)
switch f := f.(type) {
case *http2.PingFrame:
app.logf(" Data = %q", f.Data)
case *http2.SettingsFrame:
f.ForeachSetting(func(s http2.Setting) error {
app.logf(" %v", s)
app.peerSetting[s.ID] = s.Val
return nil
})
case *http2.WindowUpdateFrame:
app.logf(" Window-Increment = %v\n", f.Increment)
case *http2.GoAwayFrame:
app.logf(" Last-Stream-ID = %d; Error-Code = %v (%d)\n", f.LastStreamID, f.ErrCode, f.ErrCode)
case *http2.DataFrame:
app.logf(" %q", f.Data())
case *http2.HeadersFrame:
if f.HasPriority() {
app.logf(" PRIORITY = %v", f.Priority)
}
if app.hdec == nil {
// TODO: if the user uses h2i to send a SETTINGS frame advertising
// something larger, we'll need to respect SETTINGS_HEADER_TABLE_SIZE
// and stuff here instead of using the 4k default. But for now:
tableSize := uint32(4 << 10)
app.hdec = hpack.NewDecoder(tableSize, app.onNewHeaderField)
}
app.hdec.Write(f.HeaderBlockFragment())
}
}
}
// called from readLoop
func (app *h2i) onNewHeaderField(f hpack.HeaderField) {
if f.Sensitive {
app.logf(" %s = %q (SENSITIVE)", f.Name, f.Value)
}
app.logf(" %s = %q", f.Name, f.Value)
}
func (app *h2i) encodeHeaders(req *http.Request) []byte {
app.hbuf.Reset()
// TODO(bradfitz): figure out :authority-vs-Host stuff between http2 and Go
host := req.Host
if host == "" {
host = req.URL.Host
}
path := req.URL.Path
if path == "" {
path = "/"
}
app.writeHeader(":authority", host) // probably not right for all sites
app.writeHeader(":method", req.Method)
app.writeHeader(":path", path)
app.writeHeader(":scheme", "https")
for k, vv := range req.Header {
lowKey := strings.ToLower(k)
if lowKey == "host" {
continue
}
for _, v := range vv {
app.writeHeader(lowKey, v)
}
}
return app.hbuf.Bytes()
}
func (app *h2i) writeHeader(name, value string) {
app.henc.WriteField(hpack.HeaderField{Name: name, Value: value})
app.logf(" %s = %s", name, value)
}

View File

@@ -13,7 +13,7 @@
// ConfigureServer. That ConfigureServer call will likely be automatic // ConfigureServer. That ConfigureServer call will likely be automatic
// or available via an empty import in the future. // or available via an empty import in the future.
// //
// This package currently targets draft-14. See http://http2.github.io/ // See http://http2.github.io/
package http2 package http2
import ( import (

View File

@@ -55,7 +55,7 @@ import (
"sync" "sync"
"time" "time"
"github.com/bradfitz/http2/hpack" "golang.org/x/net/http2/hpack"
) )
const ( const (
@@ -631,6 +631,9 @@ func (sc *serverConn) serve() {
case wm := <-sc.wantWriteFrameCh: case wm := <-sc.wantWriteFrameCh:
sc.writeFrame(wm) sc.writeFrame(wm)
case <-sc.wroteFrameCh: case <-sc.wroteFrameCh:
if sc.writingFrame != true {
panic("internal error: expected to be already writing a frame")
}
sc.writingFrame = false sc.writingFrame = false
sc.scheduleFrameWrite() sc.scheduleFrameWrite()
case fg, ok := <-sc.readFrameCh: case fg, ok := <-sc.readFrameCh:
@@ -752,6 +755,7 @@ func (sc *serverConn) startFrameWrite(wm frameWriteMsg) {
if sc.writingFrame { if sc.writingFrame {
panic("internal error: can only be writing one frame at a time") panic("internal error: can only be writing one frame at a time")
} }
sc.writingFrame = true
st := wm.stream st := wm.stream
if st != nil { if st != nil {
@@ -768,7 +772,6 @@ func (sc *serverConn) startFrameWrite(wm frameWriteMsg) {
} }
} }
sc.writingFrame = true
sc.needsFrameFlush = true sc.needsFrameFlush = true
if endsStream(wm.write) { if endsStream(wm.write) {
if st == nil { if st == nil {

View File

@@ -19,7 +19,7 @@ import (
"strings" "strings"
"sync" "sync"
"github.com/bradfitz/http2/hpack" "golang.org/x/net/http2/hpack"
) )
type Transport struct { type Transport struct {
@@ -186,7 +186,7 @@ func (t *Transport) newClientConn(host, port, key string) (*clientConn, error) {
NextProtos: []string{NextProtoTLS}, NextProtos: []string{NextProtoTLS},
InsecureSkipVerify: t.InsecureTLSDial, InsecureSkipVerify: t.InsecureTLSDial,
} }
tconn, err := tls.Dial("tcp", host+":"+port, cfg) tconn, err := tls.Dial("tcp", net.JoinHostPort(host, port), cfg)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@@ -13,7 +13,7 @@ import (
"net/http" "net/http"
"time" "time"
"github.com/bradfitz/http2/hpack" "golang.org/x/net/http2/hpack"
) )
// writeFramer is implemented by any type that is used to write frames. // writeFramer is implemented by any type that is used to write frames.

View File

@@ -1,4 +1,14 @@
language: go language: go
before_install:
- go get github.com/axw/gocov/gocov
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
install:
- mkdir -p "$GOPATH/src/google.golang.org"
- mv "$TRAVIS_BUILD_DIR" "$GOPATH/src/google.golang.org/grpc"
script: script:
- make test testrace - make test testrace
- make coverage

View File

@@ -1,6 +1,6 @@
# Authentication # Authentication
As outlined <a href="https://github.com/grpc/grpc/blob/master/doc/grpc-auth-support.md">here</a> gRPC supports a number of different mechanisms for asserting identity between an client and server. We'll present some code-samples here demonstrating how to provide TLS support encryption and identity assertions as well as passing OAuth2 tokens to services that support it. As outlined in the [gRPC authentication guide](http://www.grpc.io/docs/guides/auth.html) there are a number of different mechanisms for asserting identity between an client and server. We'll present some code-samples here demonstrating how to provide TLS support encryption and identity assertions as well as passing OAuth2 tokens to services that support it.
# Enabling TLS on a gRPC client # Enabling TLS on a gRPC client

View File

@@ -45,3 +45,6 @@ testrace: testdeps
clean: clean:
go clean google.golang.org/grpc/... go clean google.golang.org/grpc/...
coverage: testdeps
./coverage.sh --coveralls

View File

@@ -2,12 +2,12 @@
[![Build Status](https://travis-ci.org/grpc/grpc-go.svg)](https://travis-ci.org/grpc/grpc-go) [![GoDoc](https://godoc.org/google.golang.org/grpc?status.svg)](https://godoc.org/google.golang.org/grpc) [![Build Status](https://travis-ci.org/grpc/grpc-go.svg)](https://travis-ci.org/grpc/grpc-go) [![GoDoc](https://godoc.org/google.golang.org/grpc?status.svg)](https://godoc.org/google.golang.org/grpc)
The Go implementation of [gRPC](https://github.com/grpc/grpc) The Go implementation of [gRPC](http://www.grpc.io/): A high performance, open source, general RPC framework that puts mobile and HTTP/2 first. For more information see the [gRPC Quick Start](http://www.grpc.io/docs/) guide.
Installation Installation
------------ ------------
To install this package, you need to install Go 1.4 and setup your Go workspace on your computer. The simplest way to install the library is to run: To install this package, you need to install Go 1.4 or above and setup your Go workspace on your computer. The simplest way to install the library is to run:
``` ```
$ go get google.golang.org/grpc $ go get google.golang.org/grpc
@@ -18,11 +18,15 @@ Prerequisites
This requires Go 1.4 or above. This requires Go 1.4 or above.
Constraints
-----------
The grpc package should only depend on standard Go packages and a small number of exceptions. If your contribution introduces new dependencies which are NOT in the [list](http://godoc.org/google.golang.org/grpc?imports), you need a discussion with gRPC-Go authors and consultants.
Documentation Documentation
------------- -------------
You can find more detailed documentation and examples in the [examples directory](examples/). See [API documentation](https://godoc.org/google.golang.org/grpc) for package and API descriptions and find examples in the [examples directory](examples/).
Status Status
------ ------
Alpha - ready for early adopters. Beta release

View File

@@ -92,13 +92,6 @@ func closeLoopUnary() {
func closeLoopStream() { func closeLoopStream() {
s, conn, tc := buildConnection() s, conn, tc := buildConnection()
stream, err := tc.StreamingCall(context.Background())
if err != nil {
grpclog.Fatalf("%v.StreamingCall(_) = _, %v", tc, err)
}
for i := 0; i < 100; i++ {
streamCaller(tc, stream)
}
ch := make(chan int, *maxConcurrentRPCs*4) ch := make(chan int, *maxConcurrentRPCs*4)
var ( var (
mu sync.Mutex mu sync.Mutex
@@ -108,7 +101,15 @@ func closeLoopStream() {
// Distribute RPCs over maxConcurrentCalls workers. // Distribute RPCs over maxConcurrentCalls workers.
for i := 0; i < *maxConcurrentRPCs; i++ { for i := 0; i < *maxConcurrentRPCs; i++ {
go func() { go func() {
for _ = range ch { stream, err := tc.StreamingCall(context.Background())
if err != nil {
grpclog.Fatalf("%v.StreamingCall(_) = _, %v", tc, err)
}
// Do some warm up.
for i := 0; i < 100; i++ {
streamCaller(tc, stream)
}
for range ch {
start := time.Now() start := time.Now()
streamCaller(tc, stream) streamCaller(tc, stream)
elapse := time.Since(start) elapse := time.Since(start)

View File

@@ -27,18 +27,22 @@ It has these top-level messages:
package grpc_testing package grpc_testing
import proto "github.com/golang/protobuf/proto" import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import ( import (
context "golang.org/x/net/context" context "golang.org/x/net/context"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
) )
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf
// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
const _ = proto.ProtoPackageIsVersion1
type PayloadType int32 type PayloadType int32
@@ -65,6 +69,7 @@ var PayloadType_value = map[string]int32{
func (x PayloadType) String() string { func (x PayloadType) String() string {
return proto.EnumName(PayloadType_name, int32(x)) return proto.EnumName(PayloadType_name, int32(x))
} }
func (PayloadType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
type ClientType int32 type ClientType int32
@@ -85,6 +90,7 @@ var ClientType_value = map[string]int32{
func (x ClientType) String() string { func (x ClientType) String() string {
return proto.EnumName(ClientType_name, int32(x)) return proto.EnumName(ClientType_name, int32(x))
} }
func (ClientType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type ServerType int32 type ServerType int32
@@ -105,6 +111,7 @@ var ServerType_value = map[string]int32{
func (x ServerType) String() string { func (x ServerType) String() string {
return proto.EnumName(ServerType_name, int32(x)) return proto.EnumName(ServerType_name, int32(x))
} }
func (ServerType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
type RpcType int32 type RpcType int32
@@ -125,15 +132,17 @@ var RpcType_value = map[string]int32{
func (x RpcType) String() string { func (x RpcType) String() string {
return proto.EnumName(RpcType_name, int32(x)) return proto.EnumName(RpcType_name, int32(x))
} }
func (RpcType) EnumDescriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
type StatsRequest struct { type StatsRequest struct {
// run number // run number
TestNum int32 `protobuf:"varint,1,opt,name=test_num" json:"test_num,omitempty"` TestNum int32 `protobuf:"varint,1,opt,name=test_num" json:"test_num,omitempty"`
} }
func (m *StatsRequest) Reset() { *m = StatsRequest{} } func (m *StatsRequest) Reset() { *m = StatsRequest{} }
func (m *StatsRequest) String() string { return proto.CompactTextString(m) } func (m *StatsRequest) String() string { return proto.CompactTextString(m) }
func (*StatsRequest) ProtoMessage() {} func (*StatsRequest) ProtoMessage() {}
func (*StatsRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{0} }
type ServerStats struct { type ServerStats struct {
// wall clock time // wall clock time
@@ -144,9 +153,10 @@ type ServerStats struct {
TimeSystem float64 `protobuf:"fixed64,3,opt,name=time_system" json:"time_system,omitempty"` TimeSystem float64 `protobuf:"fixed64,3,opt,name=time_system" json:"time_system,omitempty"`
} }
func (m *ServerStats) Reset() { *m = ServerStats{} } func (m *ServerStats) Reset() { *m = ServerStats{} }
func (m *ServerStats) String() string { return proto.CompactTextString(m) } func (m *ServerStats) String() string { return proto.CompactTextString(m) }
func (*ServerStats) ProtoMessage() {} func (*ServerStats) ProtoMessage() {}
func (*ServerStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{1} }
type Payload struct { type Payload struct {
// The type of data in body. // The type of data in body.
@@ -155,9 +165,10 @@ type Payload struct {
Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"` Body []byte `protobuf:"bytes,2,opt,name=body,proto3" json:"body,omitempty"`
} }
func (m *Payload) Reset() { *m = Payload{} } func (m *Payload) Reset() { *m = Payload{} }
func (m *Payload) String() string { return proto.CompactTextString(m) } func (m *Payload) String() string { return proto.CompactTextString(m) }
func (*Payload) ProtoMessage() {} func (*Payload) ProtoMessage() {}
func (*Payload) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{2} }
type HistogramData struct { type HistogramData struct {
Bucket []uint32 `protobuf:"varint,1,rep,name=bucket" json:"bucket,omitempty"` Bucket []uint32 `protobuf:"varint,1,rep,name=bucket" json:"bucket,omitempty"`
@@ -168,9 +179,10 @@ type HistogramData struct {
Count float64 `protobuf:"fixed64,6,opt,name=count" json:"count,omitempty"` Count float64 `protobuf:"fixed64,6,opt,name=count" json:"count,omitempty"`
} }
func (m *HistogramData) Reset() { *m = HistogramData{} } func (m *HistogramData) Reset() { *m = HistogramData{} }
func (m *HistogramData) String() string { return proto.CompactTextString(m) } func (m *HistogramData) String() string { return proto.CompactTextString(m) }
func (*HistogramData) ProtoMessage() {} func (*HistogramData) ProtoMessage() {}
func (*HistogramData) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{3} }
type ClientConfig struct { type ClientConfig struct {
ServerTargets []string `protobuf:"bytes,1,rep,name=server_targets" json:"server_targets,omitempty"` ServerTargets []string `protobuf:"bytes,1,rep,name=server_targets" json:"server_targets,omitempty"`
@@ -184,41 +196,141 @@ type ClientConfig struct {
RpcType RpcType `protobuf:"varint,8,opt,name=rpc_type,enum=grpc.testing.RpcType" json:"rpc_type,omitempty"` RpcType RpcType `protobuf:"varint,8,opt,name=rpc_type,enum=grpc.testing.RpcType" json:"rpc_type,omitempty"`
} }
func (m *ClientConfig) Reset() { *m = ClientConfig{} } func (m *ClientConfig) Reset() { *m = ClientConfig{} }
func (m *ClientConfig) String() string { return proto.CompactTextString(m) } func (m *ClientConfig) String() string { return proto.CompactTextString(m) }
func (*ClientConfig) ProtoMessage() {} func (*ClientConfig) ProtoMessage() {}
func (*ClientConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{4} }
// Request current stats // Request current stats
type Mark struct { type Mark struct {
} }
func (m *Mark) Reset() { *m = Mark{} } func (m *Mark) Reset() { *m = Mark{} }
func (m *Mark) String() string { return proto.CompactTextString(m) } func (m *Mark) String() string { return proto.CompactTextString(m) }
func (*Mark) ProtoMessage() {} func (*Mark) ProtoMessage() {}
func (*Mark) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{5} }
type ClientArgs struct { type ClientArgs struct {
Setup *ClientConfig `protobuf:"bytes,1,opt,name=setup" json:"setup,omitempty"` // Types that are valid to be assigned to Argtype:
Mark *Mark `protobuf:"bytes,2,opt,name=mark" json:"mark,omitempty"` // *ClientArgs_Setup
// *ClientArgs_Mark
Argtype isClientArgs_Argtype `protobuf_oneof:"argtype"`
} }
func (m *ClientArgs) Reset() { *m = ClientArgs{} } func (m *ClientArgs) Reset() { *m = ClientArgs{} }
func (m *ClientArgs) String() string { return proto.CompactTextString(m) } func (m *ClientArgs) String() string { return proto.CompactTextString(m) }
func (*ClientArgs) ProtoMessage() {} func (*ClientArgs) ProtoMessage() {}
func (*ClientArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{6} }
type isClientArgs_Argtype interface {
isClientArgs_Argtype()
}
type ClientArgs_Setup struct {
Setup *ClientConfig `protobuf:"bytes,1,opt,name=setup,oneof"`
}
type ClientArgs_Mark struct {
Mark *Mark `protobuf:"bytes,2,opt,name=mark,oneof"`
}
func (*ClientArgs_Setup) isClientArgs_Argtype() {}
func (*ClientArgs_Mark) isClientArgs_Argtype() {}
func (m *ClientArgs) GetArgtype() isClientArgs_Argtype {
if m != nil {
return m.Argtype
}
return nil
}
func (m *ClientArgs) GetSetup() *ClientConfig { func (m *ClientArgs) GetSetup() *ClientConfig {
if m != nil { if x, ok := m.GetArgtype().(*ClientArgs_Setup); ok {
return m.Setup return x.Setup
} }
return nil return nil
} }
func (m *ClientArgs) GetMark() *Mark { func (m *ClientArgs) GetMark() *Mark {
if m != nil { if x, ok := m.GetArgtype().(*ClientArgs_Mark); ok {
return m.Mark return x.Mark
} }
return nil return nil
} }
// XXX_OneofFuncs is for the internal use of the proto package.
func (*ClientArgs) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _ClientArgs_OneofMarshaler, _ClientArgs_OneofUnmarshaler, _ClientArgs_OneofSizer, []interface{}{
(*ClientArgs_Setup)(nil),
(*ClientArgs_Mark)(nil),
}
}
func _ClientArgs_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
m := msg.(*ClientArgs)
// argtype
switch x := m.Argtype.(type) {
case *ClientArgs_Setup:
b.EncodeVarint(1<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Setup); err != nil {
return err
}
case *ClientArgs_Mark:
b.EncodeVarint(2<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Mark); err != nil {
return err
}
case nil:
default:
return fmt.Errorf("ClientArgs.Argtype has unexpected type %T", x)
}
return nil
}
func _ClientArgs_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
m := msg.(*ClientArgs)
switch tag {
case 1: // argtype.setup
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(ClientConfig)
err := b.DecodeMessage(msg)
m.Argtype = &ClientArgs_Setup{msg}
return true, err
case 2: // argtype.mark
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(Mark)
err := b.DecodeMessage(msg)
m.Argtype = &ClientArgs_Mark{msg}
return true, err
default:
return false, nil
}
}
func _ClientArgs_OneofSizer(msg proto.Message) (n int) {
m := msg.(*ClientArgs)
// argtype
switch x := m.Argtype.(type) {
case *ClientArgs_Setup:
s := proto.Size(x.Setup)
n += proto.SizeVarint(1<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *ClientArgs_Mark:
s := proto.Size(x.Mark)
n += proto.SizeVarint(2<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
}
return n
}
type ClientStats struct { type ClientStats struct {
Latencies *HistogramData `protobuf:"bytes,1,opt,name=latencies" json:"latencies,omitempty"` Latencies *HistogramData `protobuf:"bytes,1,opt,name=latencies" json:"latencies,omitempty"`
TimeElapsed float64 `protobuf:"fixed64,3,opt,name=time_elapsed" json:"time_elapsed,omitempty"` TimeElapsed float64 `protobuf:"fixed64,3,opt,name=time_elapsed" json:"time_elapsed,omitempty"`
@@ -226,9 +338,10 @@ type ClientStats struct {
TimeSystem float64 `protobuf:"fixed64,5,opt,name=time_system" json:"time_system,omitempty"` TimeSystem float64 `protobuf:"fixed64,5,opt,name=time_system" json:"time_system,omitempty"`
} }
func (m *ClientStats) Reset() { *m = ClientStats{} } func (m *ClientStats) Reset() { *m = ClientStats{} }
func (m *ClientStats) String() string { return proto.CompactTextString(m) } func (m *ClientStats) String() string { return proto.CompactTextString(m) }
func (*ClientStats) ProtoMessage() {} func (*ClientStats) ProtoMessage() {}
func (*ClientStats) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *ClientStats) GetLatencies() *HistogramData { func (m *ClientStats) GetLatencies() *HistogramData {
if m != nil { if m != nil {
@@ -241,9 +354,10 @@ type ClientStatus struct {
Stats *ClientStats `protobuf:"bytes,1,opt,name=stats" json:"stats,omitempty"` Stats *ClientStats `protobuf:"bytes,1,opt,name=stats" json:"stats,omitempty"`
} }
func (m *ClientStatus) Reset() { *m = ClientStatus{} } func (m *ClientStatus) Reset() { *m = ClientStatus{} }
func (m *ClientStatus) String() string { return proto.CompactTextString(m) } func (m *ClientStatus) String() string { return proto.CompactTextString(m) }
func (*ClientStatus) ProtoMessage() {} func (*ClientStatus) ProtoMessage() {}
func (*ClientStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{8} }
func (m *ClientStatus) GetStats() *ClientStats { func (m *ClientStatus) GetStats() *ClientStats {
if m != nil { if m != nil {
@@ -258,41 +372,141 @@ type ServerConfig struct {
EnableSsl bool `protobuf:"varint,3,opt,name=enable_ssl" json:"enable_ssl,omitempty"` EnableSsl bool `protobuf:"varint,3,opt,name=enable_ssl" json:"enable_ssl,omitempty"`
} }
func (m *ServerConfig) Reset() { *m = ServerConfig{} } func (m *ServerConfig) Reset() { *m = ServerConfig{} }
func (m *ServerConfig) String() string { return proto.CompactTextString(m) } func (m *ServerConfig) String() string { return proto.CompactTextString(m) }
func (*ServerConfig) ProtoMessage() {} func (*ServerConfig) ProtoMessage() {}
func (*ServerConfig) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{9} }
type ServerArgs struct { type ServerArgs struct {
Setup *ServerConfig `protobuf:"bytes,1,opt,name=setup" json:"setup,omitempty"` // Types that are valid to be assigned to Argtype:
Mark *Mark `protobuf:"bytes,2,opt,name=mark" json:"mark,omitempty"` // *ServerArgs_Setup
// *ServerArgs_Mark
Argtype isServerArgs_Argtype `protobuf_oneof:"argtype"`
} }
func (m *ServerArgs) Reset() { *m = ServerArgs{} } func (m *ServerArgs) Reset() { *m = ServerArgs{} }
func (m *ServerArgs) String() string { return proto.CompactTextString(m) } func (m *ServerArgs) String() string { return proto.CompactTextString(m) }
func (*ServerArgs) ProtoMessage() {} func (*ServerArgs) ProtoMessage() {}
func (*ServerArgs) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
type isServerArgs_Argtype interface {
isServerArgs_Argtype()
}
type ServerArgs_Setup struct {
Setup *ServerConfig `protobuf:"bytes,1,opt,name=setup,oneof"`
}
type ServerArgs_Mark struct {
Mark *Mark `protobuf:"bytes,2,opt,name=mark,oneof"`
}
func (*ServerArgs_Setup) isServerArgs_Argtype() {}
func (*ServerArgs_Mark) isServerArgs_Argtype() {}
func (m *ServerArgs) GetArgtype() isServerArgs_Argtype {
if m != nil {
return m.Argtype
}
return nil
}
func (m *ServerArgs) GetSetup() *ServerConfig { func (m *ServerArgs) GetSetup() *ServerConfig {
if m != nil { if x, ok := m.GetArgtype().(*ServerArgs_Setup); ok {
return m.Setup return x.Setup
} }
return nil return nil
} }
func (m *ServerArgs) GetMark() *Mark { func (m *ServerArgs) GetMark() *Mark {
if m != nil { if x, ok := m.GetArgtype().(*ServerArgs_Mark); ok {
return m.Mark return x.Mark
} }
return nil return nil
} }
// XXX_OneofFuncs is for the internal use of the proto package.
func (*ServerArgs) XXX_OneofFuncs() (func(msg proto.Message, b *proto.Buffer) error, func(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error), func(msg proto.Message) (n int), []interface{}) {
return _ServerArgs_OneofMarshaler, _ServerArgs_OneofUnmarshaler, _ServerArgs_OneofSizer, []interface{}{
(*ServerArgs_Setup)(nil),
(*ServerArgs_Mark)(nil),
}
}
func _ServerArgs_OneofMarshaler(msg proto.Message, b *proto.Buffer) error {
m := msg.(*ServerArgs)
// argtype
switch x := m.Argtype.(type) {
case *ServerArgs_Setup:
b.EncodeVarint(1<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Setup); err != nil {
return err
}
case *ServerArgs_Mark:
b.EncodeVarint(2<<3 | proto.WireBytes)
if err := b.EncodeMessage(x.Mark); err != nil {
return err
}
case nil:
default:
return fmt.Errorf("ServerArgs.Argtype has unexpected type %T", x)
}
return nil
}
func _ServerArgs_OneofUnmarshaler(msg proto.Message, tag, wire int, b *proto.Buffer) (bool, error) {
m := msg.(*ServerArgs)
switch tag {
case 1: // argtype.setup
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(ServerConfig)
err := b.DecodeMessage(msg)
m.Argtype = &ServerArgs_Setup{msg}
return true, err
case 2: // argtype.mark
if wire != proto.WireBytes {
return true, proto.ErrInternalBadWireType
}
msg := new(Mark)
err := b.DecodeMessage(msg)
m.Argtype = &ServerArgs_Mark{msg}
return true, err
default:
return false, nil
}
}
func _ServerArgs_OneofSizer(msg proto.Message) (n int) {
m := msg.(*ServerArgs)
// argtype
switch x := m.Argtype.(type) {
case *ServerArgs_Setup:
s := proto.Size(x.Setup)
n += proto.SizeVarint(1<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case *ServerArgs_Mark:
s := proto.Size(x.Mark)
n += proto.SizeVarint(2<<3 | proto.WireBytes)
n += proto.SizeVarint(uint64(s))
n += s
case nil:
default:
panic(fmt.Sprintf("proto: unexpected type %T in oneof", x))
}
return n
}
type ServerStatus struct { type ServerStatus struct {
Stats *ServerStats `protobuf:"bytes,1,opt,name=stats" json:"stats,omitempty"` Stats *ServerStats `protobuf:"bytes,1,opt,name=stats" json:"stats,omitempty"`
Port int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"` Port int32 `protobuf:"varint,2,opt,name=port" json:"port,omitempty"`
} }
func (m *ServerStatus) Reset() { *m = ServerStatus{} } func (m *ServerStatus) Reset() { *m = ServerStatus{} }
func (m *ServerStatus) String() string { return proto.CompactTextString(m) } func (m *ServerStatus) String() string { return proto.CompactTextString(m) }
func (*ServerStatus) ProtoMessage() {} func (*ServerStatus) ProtoMessage() {}
func (*ServerStatus) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{11} }
func (m *ServerStatus) GetStats() *ServerStats { func (m *ServerStatus) GetStats() *ServerStats {
if m != nil { if m != nil {
@@ -312,9 +526,10 @@ type SimpleRequest struct {
Payload *Payload `protobuf:"bytes,3,opt,name=payload" json:"payload,omitempty"` Payload *Payload `protobuf:"bytes,3,opt,name=payload" json:"payload,omitempty"`
} }
func (m *SimpleRequest) Reset() { *m = SimpleRequest{} } func (m *SimpleRequest) Reset() { *m = SimpleRequest{} }
func (m *SimpleRequest) String() string { return proto.CompactTextString(m) } func (m *SimpleRequest) String() string { return proto.CompactTextString(m) }
func (*SimpleRequest) ProtoMessage() {} func (*SimpleRequest) ProtoMessage() {}
func (*SimpleRequest) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{12} }
func (m *SimpleRequest) GetPayload() *Payload { func (m *SimpleRequest) GetPayload() *Payload {
if m != nil { if m != nil {
@@ -327,9 +542,10 @@ type SimpleResponse struct {
Payload *Payload `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"` Payload *Payload `protobuf:"bytes,1,opt,name=payload" json:"payload,omitempty"`
} }
func (m *SimpleResponse) Reset() { *m = SimpleResponse{} } func (m *SimpleResponse) Reset() { *m = SimpleResponse{} }
func (m *SimpleResponse) String() string { return proto.CompactTextString(m) } func (m *SimpleResponse) String() string { return proto.CompactTextString(m) }
func (*SimpleResponse) ProtoMessage() {} func (*SimpleResponse) ProtoMessage() {}
func (*SimpleResponse) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{13} }
func (m *SimpleResponse) GetPayload() *Payload { func (m *SimpleResponse) GetPayload() *Payload {
if m != nil { if m != nil {
@@ -339,12 +555,30 @@ func (m *SimpleResponse) GetPayload() *Payload {
} }
func init() { func init() {
proto.RegisterType((*StatsRequest)(nil), "grpc.testing.StatsRequest")
proto.RegisterType((*ServerStats)(nil), "grpc.testing.ServerStats")
proto.RegisterType((*Payload)(nil), "grpc.testing.Payload")
proto.RegisterType((*HistogramData)(nil), "grpc.testing.HistogramData")
proto.RegisterType((*ClientConfig)(nil), "grpc.testing.ClientConfig")
proto.RegisterType((*Mark)(nil), "grpc.testing.Mark")
proto.RegisterType((*ClientArgs)(nil), "grpc.testing.ClientArgs")
proto.RegisterType((*ClientStats)(nil), "grpc.testing.ClientStats")
proto.RegisterType((*ClientStatus)(nil), "grpc.testing.ClientStatus")
proto.RegisterType((*ServerConfig)(nil), "grpc.testing.ServerConfig")
proto.RegisterType((*ServerArgs)(nil), "grpc.testing.ServerArgs")
proto.RegisterType((*ServerStatus)(nil), "grpc.testing.ServerStatus")
proto.RegisterType((*SimpleRequest)(nil), "grpc.testing.SimpleRequest")
proto.RegisterType((*SimpleResponse)(nil), "grpc.testing.SimpleResponse")
proto.RegisterEnum("grpc.testing.PayloadType", PayloadType_name, PayloadType_value) proto.RegisterEnum("grpc.testing.PayloadType", PayloadType_name, PayloadType_value)
proto.RegisterEnum("grpc.testing.ClientType", ClientType_name, ClientType_value) proto.RegisterEnum("grpc.testing.ClientType", ClientType_name, ClientType_value)
proto.RegisterEnum("grpc.testing.ServerType", ServerType_name, ServerType_value) proto.RegisterEnum("grpc.testing.ServerType", ServerType_name, ServerType_value)
proto.RegisterEnum("grpc.testing.RpcType", RpcType_name, RpcType_value) proto.RegisterEnum("grpc.testing.RpcType", RpcType_name, RpcType_value)
} }
// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn
// Client API for TestService service // Client API for TestService service
type TestServiceClient interface { type TestServiceClient interface {
@@ -419,9 +653,9 @@ func RegisterTestServiceServer(s *grpc.Server, srv TestServiceServer) {
s.RegisterService(&_TestService_serviceDesc, srv) s.RegisterService(&_TestService_serviceDesc, srv)
} }
func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, codec grpc.Codec, buf []byte) (interface{}, error) { func _TestService_UnaryCall_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error) (interface{}, error) {
in := new(SimpleRequest) in := new(SimpleRequest)
if err := codec.Unmarshal(buf, in); err != nil { if err := dec(in); err != nil {
return nil, err return nil, err
} }
out, err := srv.(TestServiceServer).UnaryCall(ctx, in) out, err := srv.(TestServiceServer).UnaryCall(ctx, in)
@@ -639,3 +873,69 @@ var _Worker_serviceDesc = grpc.ServiceDesc{
}, },
}, },
} }
var fileDescriptor0 = []byte{
// 988 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xa4, 0x56, 0x5f, 0x6f, 0x1b, 0x45,
0x10, 0xef, 0xc5, 0xff, 0xe2, 0x39, 0x27, 0x44, 0xab, 0x52, 0x39, 0x69, 0x11, 0x70, 0x05, 0x11,
0x22, 0x91, 0x56, 0x46, 0x42, 0xea, 0x0b, 0x91, 0xeb, 0x1a, 0x52, 0x29, 0x71, 0xa2, 0xbd, 0x04,
0xd4, 0xa7, 0xd3, 0xc6, 0xde, 0xb8, 0xa7, 0x9c, 0xef, 0xae, 0xb7, 0x7b, 0xa8, 0xe6, 0x09, 0xf1,
0x19, 0xf8, 0x0a, 0x3c, 0x20, 0xbe, 0x24, 0xb3, 0xb3, 0x7b, 0x89, 0x9d, 0x9a, 0x36, 0x52, 0x9f,
0x72, 0x3b, 0xf3, 0x9b, 0xdf, 0xce, 0xfe, 0xe6, 0x8f, 0x03, 0xa0, 0xa5, 0xd2, 0xfb, 0x79, 0x91,
0xe9, 0x8c, 0x75, 0xa6, 0x45, 0x3e, 0xde, 0x37, 0x86, 0x38, 0x9d, 0x06, 0xdf, 0x42, 0x27, 0xd4,
0x42, 0x2b, 0x2e, 0xdf, 0x94, 0x68, 0x62, 0xdb, 0xb0, 0x6e, 0x5c, 0x51, 0x5a, 0xce, 0xba, 0xde,
0x17, 0xde, 0x6e, 0x83, 0xb7, 0xcc, 0x79, 0x54, 0xce, 0x82, 0x14, 0xfc, 0x50, 0x16, 0xbf, 0xc9,
0x82, 0x02, 0xd8, 0x97, 0xd0, 0xd1, 0xf1, 0x4c, 0x46, 0x32, 0x11, 0xb9, 0x92, 0x13, 0x42, 0x7b,
0xdc, 0x37, 0xb6, 0xa1, 0x35, 0xb1, 0x87, 0xd0, 0x26, 0x48, 0xa9, 0x64, 0xd1, 0x5d, 0x23, 0xff,
0xba, 0x31, 0x9c, 0xe3, 0x99, 0x7d, 0x0e, 0x84, 0x8d, 0xd4, 0x5c, 0x69, 0x39, 0xeb, 0xd6, 0xc8,
0x0d, 0xc6, 0x14, 0x92, 0x25, 0x38, 0x82, 0xd6, 0xa9, 0x98, 0x27, 0x99, 0x98, 0xb0, 0xef, 0xa0,
0xae, 0xe7, 0xb9, 0xa4, 0x3b, 0x36, 0x7b, 0xdb, 0xfb, 0x8b, 0x4f, 0xd8, 0x77, 0xa0, 0x33, 0x04,
0x70, 0x82, 0x31, 0x06, 0xf5, 0x8b, 0x6c, 0x32, 0xa7, 0x2b, 0x3b, 0x9c, 0xbe, 0x83, 0x7f, 0x3d,
0xd8, 0x38, 0x8c, 0x95, 0xce, 0xa6, 0x85, 0x98, 0xbd, 0x10, 0x5a, 0xb0, 0x07, 0xd0, 0xbc, 0x28,
0xc7, 0x57, 0x52, 0x23, 0x6d, 0x6d, 0x77, 0x83, 0xbb, 0x93, 0x91, 0x60, 0x16, 0xa7, 0x91, 0x92,
0x32, 0x75, 0x49, 0xb7, 0xf0, 0x1c, 0xe2, 0x91, 0x5c, 0xe2, 0xad, 0x75, 0xd5, 0x9c, 0x4b, 0xbc,
0x25, 0xd7, 0x16, 0xd4, 0x14, 0x6a, 0x56, 0x27, 0xab, 0xf9, 0x64, 0x5f, 0xc1, 0x26, 0xfe, 0x89,
0xb2, 0xcb, 0x48, 0xbd, 0x29, 0x45, 0x21, 0x55, 0xb7, 0x41, 0xce, 0x0e, 0x5a, 0x4f, 0x2e, 0x43,
0x6b, 0x63, 0xf7, 0xa1, 0x31, 0xce, 0xca, 0x54, 0x77, 0x9b, 0xe4, 0xb4, 0x87, 0xe0, 0x8f, 0x1a,
0x74, 0x06, 0x49, 0x2c, 0x53, 0x3d, 0xc8, 0xd2, 0xcb, 0x78, 0xca, 0xbe, 0x46, 0x32, 0x12, 0x3f,
0xd2, 0xa2, 0x98, 0x4a, 0xad, 0x28, 0xe9, 0x36, 0xdf, 0xb0, 0xd6, 0x33, 0x6b, 0x64, 0xcf, 0xc0,
0x1f, 0x53, 0x58, 0x44, 0x7a, 0xad, 0x91, 0x5e, 0xdd, 0x65, 0xbd, 0x2c, 0x2f, 0xc9, 0x05, 0xe3,
0xeb, 0x6f, 0xf6, 0x19, 0x80, 0x4c, 0xc5, 0x45, 0x82, 0x15, 0x51, 0x09, 0xbd, 0x6e, 0x9d, 0xb7,
0xad, 0x25, 0x54, 0x09, 0x3b, 0x80, 0x47, 0x59, 0xa9, 0x95, 0x16, 0xe9, 0x04, 0x49, 0x22, 0x24,
0x54, 0x51, 0x8e, 0xe9, 0x8c, 0x5f, 0x8b, 0x34, 0x95, 0x09, 0x3d, 0xbc, 0xc1, 0xb7, 0x17, 0x30,
0x1c, 0x21, 0xa7, 0xb2, 0x18, 0x58, 0x00, 0xfb, 0x06, 0x3e, 0x71, 0xa9, 0xb9, 0x10, 0xab, 0x47,
0x83, 0x6f, 0x5a, 0xb3, 0xc3, 0x51, 0x63, 0xe5, 0xb6, 0xa4, 0x91, 0x8a, 0x7f, 0x97, 0x24, 0x4c,
0x83, 0xfb, 0xce, 0x16, 0xa2, 0x89, 0x3d, 0x85, 0xfb, 0x42, 0xcd, 0xd3, 0x71, 0x54, 0x3d, 0xf6,
0x75, 0x21, 0xc5, 0x44, 0x75, 0x5b, 0x04, 0x65, 0xe4, 0x73, 0xcf, 0xb4, 0x1e, 0x8c, 0x58, 0xc7,
0x94, 0xad, 0x2a, 0xeb, 0xa4, 0xca, 0xa7, 0xcb, 0xaa, 0x60, 0xb6, 0x24, 0x49, 0xab, 0xb0, 0x1f,
0x41, 0x13, 0xea, 0xc7, 0xa2, 0xb8, 0x0a, 0x4a, 0x00, 0x4b, 0xd5, 0x2f, 0xa6, 0x8a, 0xf5, 0xa0,
0xa1, 0xa4, 0x2e, 0x73, 0x6a, 0x45, 0xbf, 0xb7, 0xb3, 0x4a, 0x5a, 0x5b, 0xb2, 0xc3, 0x7b, 0xdc,
0x42, 0xd9, 0x2e, 0xd4, 0x67, 0xc8, 0x44, 0xd5, 0xf0, 0x7b, 0x6c, 0x39, 0xc4, 0xdc, 0x81, 0x50,
0x42, 0x3c, 0x6f, 0x43, 0x0b, 0x0b, 0x69, 0x92, 0x0c, 0xfe, 0xf1, 0xc0, 0xb7, 0x74, 0x76, 0xdc,
0x9e, 0x41, 0x3b, 0x11, 0x5a, 0xa6, 0xe3, 0x58, 0x2a, 0x77, 0xf9, 0xc3, 0x65, 0xa6, 0xa5, 0xee,
0xe6, 0x37, 0xe8, 0x77, 0x26, 0xb5, 0xf6, 0x81, 0x49, 0xad, 0xbf, 0x7f, 0x52, 0x1b, 0xef, 0x4c,
0xea, 0x41, 0xd5, 0xac, 0x26, 0xd5, 0x52, 0xb1, 0x27, 0x28, 0x92, 0x49, 0xda, 0xe5, 0xb9, 0xbd,
0x4a, 0x24, 0xbb, 0x75, 0x2c, 0x2e, 0xf8, 0xd3, 0xc3, 0x35, 0x44, 0x8d, 0xec, 0xda, 0x1d, 0xfb,
0xb8, 0x6a, 0xf7, 0x9b, 0xb9, 0xbf, 0xd5, 0xc7, 0x36, 0xc0, 0xf6, 0xb1, 0xba, 0xfe, 0x66, 0x5d,
0x68, 0x55, 0xed, 0xb0, 0xe6, 0x16, 0x98, 0xeb, 0x81, 0xf7, 0x77, 0xb8, 0x29, 0xb4, 0xa5, 0xbc,
0x43, 0xa1, 0x17, 0x93, 0xfd, 0xc8, 0x42, 0x87, 0xd5, 0xd3, 0xef, 0x24, 0xde, 0xc2, 0x06, 0x76,
0xe2, 0x99, 0x6d, 0x97, 0x67, 0x85, 0x76, 0xaf, 0xa5, 0xef, 0xe0, 0x6f, 0xdc, 0x76, 0x61, 0x3c,
0xcb, 0x13, 0x59, 0x2d, 0xf6, 0x1f, 0x61, 0x03, 0xd7, 0x4d, 0x9e, 0xa5, 0x4a, 0x46, 0x77, 0xdb,
0xa5, 0x9d, 0x0a, 0x4f, 0xb2, 0x3e, 0x5e, 0x88, 0xa7, 0xb1, 0xb4, 0xd7, 0x5d, 0x83, 0x68, 0x2e,
0x9f, 0x40, 0xcb, 0x8d, 0x29, 0xc9, 0xeb, 0xdf, 0x1e, 0x32, 0x47, 0xcf, 0x2b, 0x54, 0xd0, 0x87,
0xcd, 0x2a, 0x4d, 0x4b, 0xb3, 0x48, 0xe1, 0xdd, 0x85, 0x62, 0xef, 0x00, 0xfc, 0x85, 0xac, 0x71,
0x0f, 0x77, 0x06, 0x27, 0xc7, 0xa7, 0x7c, 0x18, 0x86, 0xfd, 0xe7, 0x47, 0xc3, 0xad, 0x7b, 0xa8,
0xcf, 0xe6, 0xf9, 0x68, 0xc9, 0xe6, 0x31, 0x80, 0x26, 0xef, 0x8f, 0x5e, 0x9c, 0x1c, 0x6f, 0xad,
0xed, 0xfd, 0x50, 0x0d, 0x38, 0xc5, 0x3f, 0x00, 0x16, 0xbe, 0x1a, 0x0d, 0x0e, 0xf9, 0xc9, 0xe8,
0xe4, 0x3c, 0x8c, 0x06, 0x47, 0x2f, 0x87, 0xa3, 0x33, 0x64, 0x41, 0xde, 0xbe, 0x71, 0x54, 0x16,
0xcf, 0xc4, 0xdd, 0xb4, 0xe0, 0xed, 0xb8, 0x70, 0xc8, 0x7f, 0x19, 0xf2, 0xc5, 0x38, 0x67, 0xf1,
0xf6, 0x1e, 0x43, 0xcb, 0x2d, 0x1b, 0xd6, 0x86, 0xc6, 0xf9, 0xa8, 0xcf, 0x5f, 0x21, 0x6e, 0x03,
0xda, 0xe1, 0x19, 0x1f, 0xf6, 0x8f, 0x5f, 0x8e, 0x7e, 0xde, 0xf2, 0x7a, 0x58, 0x40, 0xff, 0x0c,
0x9f, 0x6c, 0x6e, 0x88, 0xc7, 0x92, 0xfd, 0x04, 0xed, 0xf3, 0x54, 0x14, 0xf3, 0x81, 0x48, 0x12,
0x76, 0x6b, 0xf0, 0x97, 0x0a, 0xbd, 0xf3, 0x68, 0xb5, 0xd3, 0xc9, 0x3b, 0xc2, 0xbe, 0xd0, 0x38,
0x0e, 0xf8, 0x8b, 0x36, 0xfd, 0x48, 0xae, 0x5d, 0xef, 0xa9, 0xd7, 0xfb, 0xcb, 0x83, 0xe6, 0xaf,
0x59, 0x71, 0x85, 0x6b, 0x62, 0x80, 0xef, 0x2a, 0x53, 0x93, 0x34, 0x5b, 0xf9, 0x8b, 0x63, 0xc6,
0x6a, 0x67, 0xe7, 0xff, 0x76, 0x41, 0xa9, 0x0c, 0x1f, 0x1b, 0x42, 0x1b, 0x49, 0xac, 0xae, 0x6c,
0xe5, 0xc0, 0xaf, 0xa2, 0x59, 0x1c, 0x20, 0x43, 0x73, 0xd1, 0xa4, 0xff, 0x75, 0xbe, 0xff, 0x2f,
0x00, 0x00, 0xff, 0xff, 0xe3, 0xb1, 0x00, 0x4d, 0xf9, 0x08, 0x00, 0x00,
}

View File

@@ -17,7 +17,7 @@ enum PayloadType {
message StatsRequest { message StatsRequest {
// run number // run number
optional int32 test_num = 1; int32 test_num = 1;
} }
message ServerStats { message ServerStats {

View File

@@ -34,13 +34,13 @@
package grpc package grpc
import ( import (
"bytes"
"io" "io"
"time" "time"
"golang.org/x/net/context" "golang.org/x/net/context"
"golang.org/x/net/trace" "golang.org/x/net/trace"
"google.golang.org/grpc/codes" "google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/transport" "google.golang.org/grpc/transport"
) )
@@ -48,7 +48,7 @@ import (
// On error, it returns the error and indicates whether the call should be retried. // On error, it returns the error and indicates whether the call should be retried.
// //
// TODO(zhaoq): Check whether the received message sequence is valid. // TODO(zhaoq): Check whether the received message sequence is valid.
func recvResponse(codec Codec, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) error { func recvResponse(dopts dialOptions, t transport.ClientTransport, c *callInfo, stream *transport.Stream, reply interface{}) error {
// Try to acquire header metadata from the server if there is any. // Try to acquire header metadata from the server if there is any.
var err error var err error
c.headerMD, err = stream.Header() c.headerMD, err = stream.Header()
@@ -57,7 +57,7 @@ func recvResponse(codec Codec, t transport.ClientTransport, c *callInfo, stream
} }
p := &parser{s: stream} p := &parser{s: stream}
for { for {
if err = recv(p, codec, reply); err != nil { if err = recv(p, dopts.codec, stream, dopts.dc, reply); err != nil {
if err == io.EOF { if err == io.EOF {
break break
} }
@@ -69,7 +69,7 @@ func recvResponse(codec Codec, t transport.ClientTransport, c *callInfo, stream
} }
// sendRequest writes out various information of an RPC such as Context and Message. // sendRequest writes out various information of an RPC such as Context and Message.
func sendRequest(ctx context.Context, codec Codec, callHdr *transport.CallHdr, t transport.ClientTransport, args interface{}, opts *transport.Options) (_ *transport.Stream, err error) { func sendRequest(ctx context.Context, codec Codec, compressor Compressor, callHdr *transport.CallHdr, t transport.ClientTransport, args interface{}, opts *transport.Options) (_ *transport.Stream, err error) {
stream, err := t.NewStream(ctx, callHdr) stream, err := t.NewStream(ctx, callHdr)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -81,8 +81,11 @@ func sendRequest(ctx context.Context, codec Codec, callHdr *transport.CallHdr, t
} }
} }
}() }()
// TODO(zhaoq): Support compression. var cbuf *bytes.Buffer
outBuf, err := encode(codec, args, compressionNone) if compressor != nil {
cbuf = new(bytes.Buffer)
}
outBuf, err := encode(codec, args, compressor, cbuf)
if err != nil { if err != nil {
return nil, transport.StreamErrorf(codes.Internal, "grpc: %v", err) return nil, transport.StreamErrorf(codes.Internal, "grpc: %v", err)
} }
@@ -94,14 +97,6 @@ func sendRequest(ctx context.Context, codec Codec, callHdr *transport.CallHdr, t
return stream, nil return stream, nil
} }
// callInfo contains all related configuration and information about an RPC.
type callInfo struct {
failFast bool
headerMD metadata.MD
trailerMD metadata.MD
traceInfo traceInfo // in trace.go
}
// Invoke is called by the generated code. It sends the RPC request on the // Invoke is called by the generated code. It sends the RPC request on the
// wire and returns after response is received. // wire and returns after response is received.
func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (err error) { func Invoke(ctx context.Context, method string, args, reply interface{}, cc *ClientConn, opts ...CallOption) (err error) {
@@ -116,7 +111,6 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
o.after(&c) o.after(&c)
} }
}() }()
if EnableTracing { if EnableTracing {
c.traceInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method) c.traceInfo.tr = trace.New("grpc.Sent."+methodFamily(method), method)
defer c.traceInfo.tr.Finish() defer c.traceInfo.tr.Finish()
@@ -133,16 +127,11 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
} }
}() }()
} }
callHdr := &transport.CallHdr{
Host: cc.authority,
Method: method,
}
topts := &transport.Options{ topts := &transport.Options{
Last: true, Last: true,
Delay: false, Delay: false,
} }
var ( var (
ts int // track the transport sequence number
lastErr error // record the error that happened lastErr error // record the error that happened
) )
for { for {
@@ -155,7 +144,14 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
if lastErr != nil && c.failFast { if lastErr != nil && c.failFast {
return toRPCErr(lastErr) return toRPCErr(lastErr)
} }
t, ts, err = cc.wait(ctx, ts) callHdr := &transport.CallHdr{
Host: cc.authority,
Method: method,
}
if cc.dopts.cp != nil {
callHdr.SendCompress = cc.dopts.cp.Type()
}
t, err = cc.dopts.picker.Pick(ctx)
if err != nil { if err != nil {
if lastErr != nil { if lastErr != nil {
// This was a retry; return the error from the last attempt. // This was a retry; return the error from the last attempt.
@@ -166,7 +162,7 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
if c.traceInfo.tr != nil { if c.traceInfo.tr != nil {
c.traceInfo.tr.LazyLog(&payload{sent: true, msg: args}, true) c.traceInfo.tr.LazyLog(&payload{sent: true, msg: args}, true)
} }
stream, err = sendRequest(ctx, cc.dopts.codec, callHdr, t, args, topts) stream, err = sendRequest(ctx, cc.dopts.codec, cc.dopts.cp, callHdr, t, args, topts)
if err != nil { if err != nil {
if _, ok := err.(transport.ConnectionError); ok { if _, ok := err.(transport.ConnectionError); ok {
lastErr = err lastErr = err
@@ -178,7 +174,7 @@ func Invoke(ctx context.Context, method string, args, reply interface{}, cc *Cli
return toRPCErr(err) return toRPCErr(err)
} }
// Receive the response // Receive the response
lastErr = recvResponse(cc.dopts.codec, t, &c, stream, reply) lastErr = recvResponse(cc.dopts, t, &c, stream, reply)
if _, ok := lastErr.(transport.ConnectionError); ok { if _, ok := lastErr.(transport.ConnectionError); ok {
continue continue
} }

View File

@@ -42,6 +42,7 @@ import (
"time" "time"
"golang.org/x/net/context" "golang.org/x/net/context"
"golang.org/x/net/trace"
"google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials"
"google.golang.org/grpc/grpclog" "google.golang.org/grpc/grpclog"
"google.golang.org/grpc/transport" "google.golang.org/grpc/transport"
@@ -72,6 +73,9 @@ var (
// values passed to Dial. // values passed to Dial.
type dialOptions struct { type dialOptions struct {
codec Codec codec Codec
cp Compressor
dc Decompressor
picker Picker
block bool block bool
insecure bool insecure bool
copts transport.ConnectOptions copts transport.ConnectOptions
@@ -87,6 +91,29 @@ func WithCodec(c Codec) DialOption {
} }
} }
// WithCompressor returns a DialOption which sets a CompressorGenerator for generating message
// compressor.
func WithCompressor(cp Compressor) DialOption {
return func(o *dialOptions) {
o.cp = cp
}
}
// WithDecompressor returns a DialOption which sets a DecompressorGenerator for generating
// message decompressor.
func WithDecompressor(dc Decompressor) DialOption {
return func(o *dialOptions) {
o.dc = dc
}
}
// WithPicker returns a DialOption which sets a picker for connection selection.
func WithPicker(p Picker) DialOption {
return func(o *dialOptions) {
o.picker = p
}
}
// WithBlock returns a DialOption which makes caller of Dial blocks until the underlying // WithBlock returns a DialOption which makes caller of Dial blocks until the underlying
// connection is up. Without this, Dial returns immediately and connecting the server // connection is up. Without this, Dial returns immediately and connecting the server
// happens in background. // happens in background.
@@ -96,6 +123,8 @@ func WithBlock() DialOption {
} }
} }
// WithInsecure returns a DialOption which disables transport security for this ClientConn.
// Note that transport security is required unless WithInsecure is set.
func WithInsecure() DialOption { func WithInsecure() DialOption {
return func(o *dialOptions) { return func(o *dialOptions) {
o.insecure = true o.insecure = true
@@ -141,62 +170,29 @@ func WithUserAgent(s string) DialOption {
// Dial creates a client connection the given target. // Dial creates a client connection the given target.
func Dial(target string, opts ...DialOption) (*ClientConn, error) { func Dial(target string, opts ...DialOption) (*ClientConn, error) {
if target == "" {
return nil, ErrUnspecTarget
}
cc := &ClientConn{ cc := &ClientConn{
target: target, target: target,
shutdownChan: make(chan struct{}),
} }
for _, opt := range opts { for _, opt := range opts {
opt(&cc.dopts) opt(&cc.dopts)
} }
if !cc.dopts.insecure { if cc.dopts.codec == nil {
var ok bool // Set the default codec.
for _, c := range cc.dopts.copts.AuthOptions { cc.dopts.codec = protoCodec{}
if _, ok := c.(credentials.TransportAuthenticator); !ok { }
continue if cc.dopts.picker == nil {
} cc.dopts.picker = &unicastPicker{
ok = true target: target,
}
if !ok {
return nil, ErrNoTransportSecurity
}
} else {
for _, c := range cc.dopts.copts.AuthOptions {
if c.RequireTransportSecurity() {
return nil, ErrCredentialsMisuse
}
} }
} }
if err := cc.dopts.picker.Init(cc); err != nil {
return nil, err
}
colonPos := strings.LastIndex(target, ":") colonPos := strings.LastIndex(target, ":")
if colonPos == -1 { if colonPos == -1 {
colonPos = len(target) colonPos = len(target)
} }
cc.authority = target[:colonPos] cc.authority = target[:colonPos]
if cc.dopts.codec == nil {
// Set the default codec.
cc.dopts.codec = protoCodec{}
}
cc.stateCV = sync.NewCond(&cc.mu)
if cc.dopts.block {
if err := cc.resetTransport(false); err != nil {
cc.Close()
return nil, err
}
// Start to monitor the error status of transport.
go cc.transportMonitor()
} else {
// Start a goroutine connecting to the server asynchronously.
go func() {
if err := cc.resetTransport(false); err != nil {
grpclog.Printf("Failed to dial %s: %v; please retry.", target, err)
cc.Close()
return
}
go cc.transportMonitor()
}()
}
return cc, nil return cc, nil
} }
@@ -212,7 +208,7 @@ const (
Ready Ready
// TransientFailure indicates the ClientConn has seen a failure but expects to recover. // TransientFailure indicates the ClientConn has seen a failure but expects to recover.
TransientFailure TransientFailure
// Shutdown indicates the ClientConn has stated shutting down. // Shutdown indicates the ClientConn has started shutting down.
Shutdown Shutdown
) )
@@ -235,50 +231,137 @@ func (s ConnectivityState) String() string {
// ClientConn represents a client connection to an RPC service. // ClientConn represents a client connection to an RPC service.
type ClientConn struct { type ClientConn struct {
target string
authority string
dopts dialOptions
}
// State returns the connectivity state of cc.
// This is EXPERIMENTAL API.
func (cc *ClientConn) State() (ConnectivityState, error) {
return cc.dopts.picker.State()
}
// WaitForStateChange blocks until the state changes to something other than the sourceState.
// It returns the new state or error.
// This is EXPERIMENTAL API.
func (cc *ClientConn) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) {
return cc.dopts.picker.WaitForStateChange(ctx, sourceState)
}
// Close starts to tear down the ClientConn.
func (cc *ClientConn) Close() error {
return cc.dopts.picker.Close()
}
// Conn is a client connection to a single destination.
type Conn struct {
target string target string
authority string
dopts dialOptions dopts dialOptions
resetChan chan int
shutdownChan chan struct{} shutdownChan chan struct{}
events trace.EventLog
mu sync.Mutex mu sync.Mutex
state ConnectivityState state ConnectivityState
stateCV *sync.Cond stateCV *sync.Cond
// ready is closed and becomes nil when a new transport is up or failed // ready is closed and becomes nil when a new transport is up or failed
// due to timeout. // due to timeout.
ready chan struct{} ready chan struct{}
// Every time a new transport is created, this is incremented by 1. Used transport transport.ClientTransport
// to avoid trying to recreate a transport while the new one is already
// under construction.
transportSeq int
transport transport.ClientTransport
} }
// State returns the connectivity state of the ClientConn // NewConn creates a Conn.
func (cc *ClientConn) State() ConnectivityState { func NewConn(cc *ClientConn) (*Conn, error) {
if cc.target == "" {
return nil, ErrUnspecTarget
}
c := &Conn{
target: cc.target,
dopts: cc.dopts,
resetChan: make(chan int, 1),
shutdownChan: make(chan struct{}),
}
if EnableTracing {
c.events = trace.NewEventLog("grpc.ClientConn", c.target)
}
if !c.dopts.insecure {
var ok bool
for _, cd := range c.dopts.copts.AuthOptions {
if _, ok := cd.(credentials.TransportAuthenticator); !ok {
continue
}
ok = true
}
if !ok {
return nil, ErrNoTransportSecurity
}
} else {
for _, cd := range c.dopts.copts.AuthOptions {
if cd.RequireTransportSecurity() {
return nil, ErrCredentialsMisuse
}
}
}
c.stateCV = sync.NewCond(&c.mu)
if c.dopts.block {
if err := c.resetTransport(false); err != nil {
c.Close()
return nil, err
}
// Start to monitor the error status of transport.
go c.transportMonitor()
} else {
// Start a goroutine connecting to the server asynchronously.
go func() {
if err := c.resetTransport(false); err != nil {
grpclog.Printf("Failed to dial %s: %v; please retry.", c.target, err)
c.Close()
return
}
c.transportMonitor()
}()
}
return c, nil
}
// printf records an event in cc's event log, unless cc has been closed.
// REQUIRES cc.mu is held.
func (cc *Conn) printf(format string, a ...interface{}) {
if cc.events != nil {
cc.events.Printf(format, a...)
}
}
// errorf records an error in cc's event log, unless cc has been closed.
// REQUIRES cc.mu is held.
func (cc *Conn) errorf(format string, a ...interface{}) {
if cc.events != nil {
cc.events.Errorf(format, a...)
}
}
// State returns the connectivity state of the Conn
func (cc *Conn) State() ConnectivityState {
cc.mu.Lock() cc.mu.Lock()
defer cc.mu.Unlock() defer cc.mu.Unlock()
return cc.state return cc.state
} }
// WaitForStateChange blocks until the state changes to something other than the sourceState // WaitForStateChange blocks until the state changes to something other than the sourceState.
// or timeout fires. It returns false if timeout fires and true otherwise. func (cc *Conn) WaitForStateChange(ctx context.Context, sourceState ConnectivityState) (ConnectivityState, error) {
func (cc *ClientConn) WaitForStateChange(timeout time.Duration, sourceState ConnectivityState) bool {
start := time.Now()
cc.mu.Lock() cc.mu.Lock()
defer cc.mu.Unlock() defer cc.mu.Unlock()
if sourceState != cc.state { if sourceState != cc.state {
return true return cc.state, nil
}
expired := timeout <= time.Since(start)
if expired {
return false
} }
done := make(chan struct{}) done := make(chan struct{})
var err error
go func() { go func() {
select { select {
case <-time.After(timeout - time.Since(start)): case <-ctx.Done():
cc.mu.Lock() cc.mu.Lock()
expired = true err = ctx.Err()
cc.stateCV.Broadcast() cc.stateCV.Broadcast()
cc.mu.Unlock() cc.mu.Unlock()
case <-done: case <-done:
@@ -287,31 +370,38 @@ func (cc *ClientConn) WaitForStateChange(timeout time.Duration, sourceState Conn
defer close(done) defer close(done)
for sourceState == cc.state { for sourceState == cc.state {
cc.stateCV.Wait() cc.stateCV.Wait()
if expired { if err != nil {
return false return cc.state, err
} }
} }
return true return cc.state, nil
} }
func (cc *ClientConn) resetTransport(closeTransport bool) error { // NotifyReset tries to signal the underlying transport needs to be reset due to
// for example a name resolution change in flight.
func (cc *Conn) NotifyReset() {
select {
case cc.resetChan <- 0:
default:
}
}
func (cc *Conn) resetTransport(closeTransport bool) error {
var retries int var retries int
start := time.Now() start := time.Now()
for { for {
cc.mu.Lock() cc.mu.Lock()
cc.state = Connecting cc.printf("connecting")
cc.stateCV.Broadcast()
t := cc.transport
ts := cc.transportSeq
// Avoid wait() picking up a dying transport unnecessarily.
cc.transportSeq = 0
if cc.state == Shutdown { if cc.state == Shutdown {
// cc.Close() has been invoked.
cc.mu.Unlock() cc.mu.Unlock()
return ErrClientConnClosing return ErrClientConnClosing
} }
cc.state = Connecting
cc.stateCV.Broadcast()
cc.mu.Unlock() cc.mu.Unlock()
if closeTransport { if closeTransport {
t.Close() cc.transport.Close()
} }
// Adjust timeout for the current try. // Adjust timeout for the current try.
copts := cc.dopts.copts copts := cc.dopts.copts
@@ -335,11 +425,25 @@ func (cc *ClientConn) resetTransport(closeTransport bool) error {
copts.Timeout = timeout copts.Timeout = timeout
} }
connectTime := time.Now() connectTime := time.Now()
newTransport, err := transport.NewClientTransport(cc.target, &copts) addr, err := cc.dopts.picker.PickAddr()
var newTransport transport.ClientTransport
if err == nil {
newTransport, err = transport.NewClientTransport(addr, &copts)
}
if err != nil { if err != nil {
cc.mu.Lock() cc.mu.Lock()
if cc.state == Shutdown {
// cc.Close() has been invoked.
cc.mu.Unlock()
return ErrClientConnClosing
}
cc.errorf("transient failure: %v", err)
cc.state = TransientFailure cc.state = TransientFailure
cc.stateCV.Broadcast() cc.stateCV.Broadcast()
if cc.ready != nil {
close(cc.ready)
cc.ready = nil
}
cc.mu.Unlock() cc.mu.Unlock()
sleepTime -= time.Since(connectTime) sleepTime -= time.Since(connectTime)
if sleepTime < 0 { if sleepTime < 0 {
@@ -347,16 +451,20 @@ func (cc *ClientConn) resetTransport(closeTransport bool) error {
} }
// Fail early before falling into sleep. // Fail early before falling into sleep.
if cc.dopts.copts.Timeout > 0 && cc.dopts.copts.Timeout < sleepTime+time.Since(start) { if cc.dopts.copts.Timeout > 0 && cc.dopts.copts.Timeout < sleepTime+time.Since(start) {
cc.mu.Lock()
cc.errorf("connection timeout")
cc.mu.Unlock()
cc.Close() cc.Close()
return ErrClientConnTimeout return ErrClientConnTimeout
} }
closeTransport = false closeTransport = false
time.Sleep(sleepTime) time.Sleep(sleepTime)
retries++ retries++
grpclog.Printf("grpc: ClientConn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, cc.target) grpclog.Printf("grpc: Conn.resetTransport failed to create client transport: %v; Reconnecting to %q", err, cc.target)
continue continue
} }
cc.mu.Lock() cc.mu.Lock()
cc.printf("ready")
if cc.state == Shutdown { if cc.state == Shutdown {
// cc.Close() has been invoked. // cc.Close() has been invoked.
cc.mu.Unlock() cc.mu.Unlock()
@@ -366,7 +474,6 @@ func (cc *ClientConn) resetTransport(closeTransport bool) error {
cc.state = Ready cc.state = Ready
cc.stateCV.Broadcast() cc.stateCV.Broadcast()
cc.transport = newTransport cc.transport = newTransport
cc.transportSeq = ts + 1
if cc.ready != nil { if cc.ready != nil {
close(cc.ready) close(cc.ready)
cc.ready = nil cc.ready = nil
@@ -376,44 +483,64 @@ func (cc *ClientConn) resetTransport(closeTransport bool) error {
} }
} }
func (cc *Conn) reconnect() bool {
cc.mu.Lock()
if cc.state == Shutdown {
// cc.Close() has been invoked.
cc.mu.Unlock()
return false
}
cc.state = TransientFailure
cc.stateCV.Broadcast()
cc.mu.Unlock()
if err := cc.resetTransport(true); err != nil {
// The ClientConn is closing.
cc.mu.Lock()
cc.printf("transport exiting: %v", err)
cc.mu.Unlock()
grpclog.Printf("grpc: Conn.transportMonitor exits due to: %v", err)
return false
}
return true
}
// Run in a goroutine to track the error in transport and create the // Run in a goroutine to track the error in transport and create the
// new transport if an error happens. It returns when the channel is closing. // new transport if an error happens. It returns when the channel is closing.
func (cc *ClientConn) transportMonitor() { func (cc *Conn) transportMonitor() {
for { for {
select { select {
// shutdownChan is needed to detect the teardown when // shutdownChan is needed to detect the teardown when
// the ClientConn is idle (i.e., no RPC in flight). // the ClientConn is idle (i.e., no RPC in flight).
case <-cc.shutdownChan: case <-cc.shutdownChan:
return return
case <-cc.transport.Error(): case <-cc.resetChan:
cc.mu.Lock() if !cc.reconnect() {
cc.state = TransientFailure
cc.stateCV.Broadcast()
cc.mu.Unlock()
if err := cc.resetTransport(true); err != nil {
// The ClientConn is closing.
grpclog.Printf("grpc: ClientConn.transportMonitor exits due to: %v", err)
return return
} }
continue case <-cc.transport.Error():
if !cc.reconnect() {
return
}
// Tries to drain reset signal if there is any since it is out-dated.
select {
case <-cc.resetChan:
default:
}
} }
} }
} }
// When wait returns, either the new transport is up or ClientConn is // Wait blocks until i) the new transport is up or ii) ctx is done or iii) cc is closed.
// closing. Used to avoid working on a dying transport. It updates and func (cc *Conn) Wait(ctx context.Context) (transport.ClientTransport, error) {
// returns the transport and its version when there is no error.
func (cc *ClientConn) wait(ctx context.Context, ts int) (transport.ClientTransport, int, error) {
for { for {
cc.mu.Lock() cc.mu.Lock()
switch { switch {
case cc.state == Shutdown: case cc.state == Shutdown:
cc.mu.Unlock() cc.mu.Unlock()
return nil, 0, ErrClientConnClosing return nil, ErrClientConnClosing
case ts < cc.transportSeq: case cc.state == Ready:
// Worked on a dying transport. Try the new one immediately. cc.mu.Unlock()
defer cc.mu.Unlock() return cc.transport, nil
return cc.transport, cc.transportSeq, nil
default: default:
ready := cc.ready ready := cc.ready
if ready == nil { if ready == nil {
@@ -423,7 +550,7 @@ func (cc *ClientConn) wait(ctx context.Context, ts int) (transport.ClientTranspo
cc.mu.Unlock() cc.mu.Unlock()
select { select {
case <-ctx.Done(): case <-ctx.Done():
return nil, 0, transport.ContextErr(ctx.Err()) return nil, transport.ContextErr(ctx.Err())
// Wait until the new transport is ready or failed. // Wait until the new transport is ready or failed.
case <-ready: case <-ready:
} }
@@ -431,12 +558,12 @@ func (cc *ClientConn) wait(ctx context.Context, ts int) (transport.ClientTranspo
} }
} }
// Close starts to tear down the ClientConn. Returns ErrClientConnClosing if // Close starts to tear down the Conn. Returns ErrClientConnClosing if
// it has been closed (mostly due to dial time-out). // it has been closed (mostly due to dial time-out).
// TODO(zhaoq): Make this synchronous to avoid unbounded memory consumption in // TODO(zhaoq): Make this synchronous to avoid unbounded memory consumption in
// some edge cases (e.g., the caller opens and closes many ClientConn's in a // some edge cases (e.g., the caller opens and closes many ClientConn's in a
// tight loop. // tight loop.
func (cc *ClientConn) Close() error { func (cc *Conn) Close() error {
cc.mu.Lock() cc.mu.Lock()
defer cc.mu.Unlock() defer cc.mu.Unlock()
if cc.state == Shutdown { if cc.state == Shutdown {
@@ -444,6 +571,10 @@ func (cc *ClientConn) Close() error {
} }
cc.state = Shutdown cc.state = Shutdown
cc.stateCV.Broadcast() cc.stateCV.Broadcast()
if cc.events != nil {
cc.events.Finish()
cc.events = nil
}
if cc.ready != nil { if cc.ready != nil {
close(cc.ready) close(cc.ready)
cc.ready = nil cc.ready = nil

View File

@@ -0,0 +1,47 @@
#!/bin/bash
set -e
workdir=.cover
profile="$workdir/cover.out"
mode=set
end2endtest="google.golang.org/grpc/test"
generate_cover_data() {
rm -rf "$workdir"
mkdir "$workdir"
for pkg in "$@"; do
if [ $pkg == "google.golang.org/grpc" -o $pkg == "google.golang.org/grpc/transport" -o $pkg == "google.golang.org/grpc/metadata" -o $pkg == "google.golang.org/grpc/credentials" ]
then
f="$workdir/$(echo $pkg | tr / -)"
go test -covermode="$mode" -coverprofile="$f.cover" "$pkg"
go test -covermode="$mode" -coverpkg "$pkg" -coverprofile="$f.e2e.cover" "$end2endtest"
fi
done
echo "mode: $mode" >"$profile"
grep -h -v "^mode:" "$workdir"/*.cover >>"$profile"
}
show_cover_report() {
go tool cover -${1}="$profile"
}
push_to_coveralls() {
goveralls -coverprofile="$profile"
}
generate_cover_data $(go list ./...)
show_cover_report func
case "$1" in
"")
;;
--html)
show_cover_report html ;;
--coveralls)
push_to_coveralls ;;
*)
echo >&2 "error: invalid option: $1" ;;
esac
rm -rf "$workdir"

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