vendor: update google.golang.org/genproto from fc8f55426688 to da6875a35672

This commit is contained in:
Aliaksandr Valialkin 2020-03-12 18:11:27 +02:00
parent 8a853778d7
commit 92d67e2592
75 changed files with 1209 additions and 2211 deletions

5
go.mod
View file

@ -1,12 +1,14 @@
module github.com/VictoriaMetrics/VictoriaMetrics
require (
cloud.google.com/go v0.54.0 // indirect
cloud.google.com/go/storage v1.6.0
github.com/VictoriaMetrics/fastcache v1.5.7
github.com/VictoriaMetrics/metrics v1.11.0
github.com/aws/aws-sdk-go v1.29.22
github.com/cespare/xxhash/v2 v2.1.1
github.com/golang/snappy v0.0.1
github.com/jmespath/go-jmespath v0.0.0-20200310193758-2437e8417af5 // indirect
github.com/klauspost/compress v1.10.3
github.com/valyala/fasthttp v1.9.0
github.com/valyala/fastjson v1.5.0
@ -17,7 +19,8 @@ require (
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527
golang.org/x/tools v0.0.0-20200312153518-5e2df02acb1e // indirect
google.golang.org/api v0.20.0
google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688 // indirect
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672 // indirect
google.golang.org/grpc v1.28.0 // indirect
gopkg.in/yaml.v2 v2.2.8
)

26
go.sum
View file

@ -9,6 +9,8 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0 h1:MZQCQQaRwOrAcuKjiHWHrgKykt4fZyuwF2dtiG3fGW8=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go v0.54.0 h1:3ithwDMr7/3vpAMXiH+ZQnYbuIsh+OPhUPMFC9enmn0=
cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0 h1:sAbMqjY1PEQKZBWfbu6Y6bsupJ9c4QdHnzg/VvYTLcE=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
@ -47,10 +49,13 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
@ -67,12 +72,15 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
@ -89,6 +97,7 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OI
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
@ -98,6 +107,8 @@ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmespath/go-jmespath v0.0.0-20200310193758-2437e8417af5 h1:uHQ3zN9bw90YSNUeGWrboinB/fjXSDA7dNSg7Dznw18=
github.com/jmespath/go-jmespath v0.0.0-20200310193758-2437e8417af5/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
@ -124,6 +135,8 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasthttp v1.2.0/go.mod h1:4vX61m6KN+xDduDNwXrhIAVZaZaZiQ1luJk8LWSxF3s=
@ -175,6 +188,8 @@ golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNT
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
@ -204,6 +219,8 @@ golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -275,6 +292,7 @@ golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapK
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/tools v0.0.0-20200312153518-5e2df02acb1e h1:bQaoCUKSo4FqzkHQQxNMOY9NXAZm/8d11bD7PGEzOfE=
golang.org/x/tools v0.0.0-20200312153518-5e2df02acb1e/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@ -318,17 +336,21 @@ google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce h1:1mbrb1tUU+Zmt5C94IGKADBTJZjZXAd+BubWi7r9EiI=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688 h1:1+0Z5cgv1eDXJD9z2tdQF9PSSQnJXwism490hJydMRI=
google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672 h1:jiDSspVssiikoRPFHT6pYrL+CL6/yIc3b9AuHO/4xik=
google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
google.golang.org/grpc v1.26.0 h1:2dTRdpdFEEhJYQD8EMLB61nnrzSCTbG38PhqdhvOltg=
google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk=
google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4=
google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=

View file

@ -1,5 +1,17 @@
# Changes
## v0.54.0
- all:
- remove unused golang.org/x/exp from mod file
- update godoc.org links to pkg.go.dev
- compute/metadata:
- use defaultClient when http.Client is nil
- remove subscribeClient
- iam:
- add support for v3 policy and IAM conditions
- Various updates to autogenerated clients.
## v0.53.0
- all: most clients now use transport/grpc.DialPool rather than Dial (see #1777 for outliers).

View file

@ -22,7 +22,7 @@ to install the code reviewing tool.
1. If you would like, you may want to set up aliases for `git-codereview`,
such that `git codereview change` becomes `git change`. See the
[godoc](https://godoc.org/golang.org/x/review/git-codereview) for details.
[godoc](https://pkg.go.dev/golang.org/x/review/git-codereview) for details.
* Should you run into issues with the `git-codereview` tool, please note
that all error messages will assume that you have set up these aliases.

90
vendor/cloud.google.com/go/README.md generated vendored
View file

@ -1,6 +1,6 @@
# Google Cloud Client Libraries for Go
[![GoDoc](https://godoc.org/cloud.google.com/go?status.svg)](https://godoc.org/cloud.google.com/go)
[![GoDoc](https://pkg.go.dev/cloud.google.com/go?status.svg)](https://pkg.go.dev/cloud.google.com/go)
Go packages for [Google Cloud Platform](https://cloud.google.com) services.
@ -31,46 +31,46 @@ make backwards-incompatible changes.
Google API | Status | Package
------------------------------------------------|--------------|-----------------------------------------------------------
[Asset][cloud-asset] | alpha | [`cloud.google.com/go/asset/v1beta`](https://godoc.org/cloud.google.com/go/asset/v1beta)
[Automl][cloud-automl] | stable | [`cloud.google.com/go/automl/apiv1`](https://godoc.org/cloud.google.com/go/automl/apiv1)
[BigQuery][cloud-bigquery] | stable | [`cloud.google.com/go/bigquery`](https://godoc.org/cloud.google.com/go/bigquery)
[Bigtable][cloud-bigtable] | stable | [`cloud.google.com/go/bigtable`](https://godoc.org/cloud.google.com/go/bigtable)
[Cloudbuild][cloud-build] | stable | [`cloud.google.com/go/cloudbuild/apiv1`](https://godoc.org/cloud.google.com/go/cloudbuild/apiv1)
[Cloudtasks][cloud-tasks] | stable | [`cloud.google.com/go/cloudtasks/apiv2`](https://godoc.org/cloud.google.com/go/cloudtasks/apiv2)
[Container][cloud-container] | stable | [`cloud.google.com/go/container/apiv1`](https://godoc.org/cloud.google.com/go/container/apiv1)
[ContainerAnalysis][cloud-containeranalysis] | beta | [`cloud.google.com/go/containeranalysis/apiv1`](https://godoc.org/cloud.google.com/go/containeranalysis/apiv1)
[Dataproc][cloud-dataproc] | stable | [`cloud.google.com/go/dataproc/apiv1`](https://godoc.org/cloud.google.com/go/dataproc/apiv1)
[Datastore][cloud-datastore] | stable | [`cloud.google.com/go/datastore`](https://godoc.org/cloud.google.com/go/datastore)
[Debugger][cloud-debugger] | stable | [`cloud.google.com/go/debugger/apiv2`](https://godoc.org/cloud.google.com/go/debugger/apiv2)
[Dialogflow][cloud-dialogflow] | stable | [`cloud.google.com/go/dialogflow/apiv2`](https://godoc.org/cloud.google.com/go/dialogflow/apiv2)
[Data Loss Prevention][cloud-dlp] | stable | [`cloud.google.com/go/dlp/apiv2`](https://godoc.org/cloud.google.com/go/dlp/apiv2)
[ErrorReporting][cloud-errors] | alpha | [`cloud.google.com/go/errorreporting`](https://godoc.org/cloud.google.com/go/errorreporting)
[Firestore][cloud-firestore] | stable | [`cloud.google.com/go/firestore`](https://godoc.org/cloud.google.com/go/firestore)
[IAM][cloud-iam] | stable | [`cloud.google.com/go/iam`](https://godoc.org/cloud.google.com/go/iam)
[IoT][cloud-iot] | stable | [`cloud.google.com/go/iot/apiv1`](https://godoc.org/cloud.google.com/go/iot/apiv1)
[IRM][cloud-irm] | alpha | [`cloud.google.com/go/irm/apiv1alpha2`](https://godoc.org/cloud.google.com/go/irm/apiv1alpha2)
[KMS][cloud-kms] | stable | [`cloud.google.com/go/kms/apiv1`](https://godoc.org/cloud.google.com/go/kms/apiv1)
[Natural Language][cloud-natural-language] | stable | [`cloud.google.com/go/language/apiv1`](https://godoc.org/cloud.google.com/go/language/apiv1)
[Logging][cloud-logging] | stable | [`cloud.google.com/go/logging`](https://godoc.org/cloud.google.com/go/logging)
[Memorystore][cloud-memorystore] | alpha | [`cloud.google.com/go/redis/apiv1`](https://godoc.org/cloud.google.com/go/redis/apiv1)
[Monitoring][cloud-monitoring] | alpha | [`cloud.google.com/go/monitoring/apiv3`](https://godoc.org/cloud.google.com/go/monitoring/apiv3)
[OS Login][cloud-oslogin] | alpha | [`cloud.google.com/go/oslogin/apiv1`](https://godoc.org/cloud.google.com/go/oslogin/apiv1)
[Pub/Sub][cloud-pubsub] | stable | [`cloud.google.com/go/pubsub`](https://godoc.org/cloud.google.com/go/pubsub)
[Phishing Protection][cloud-phishingprotection] | alpha | [`cloud.google.com/go/phishingprotection/apiv1beta1`](https://godoc.org/cloud.google.com/go/phishingprotection/apiv1beta1)
[reCAPTCHA Enterprise][cloud-recaptcha] | alpha | [`cloud.google.com/go/recaptchaenterprise/apiv1beta1`](https://godoc.org/cloud.google.com/go/recaptchaenterprise/apiv1beta1)
[Recommender][cloud-recommender] | beta | [`cloud.google.com/go/recommender/apiv1beta1`](https://godoc.org/cloud.google.com/go/recommender/apiv1beta1)
[Scheduler][cloud-scheduler] | stable | [`cloud.google.com/go/scheduler/apiv1`](https://godoc.org/cloud.google.com/go/scheduler/apiv1)
[Securitycenter][cloud-securitycenter] | alpha | [`cloud.google.com/go/securitycenter/apiv1`](https://godoc.org/cloud.google.com/go/securitycenter/apiv1)
[Spanner][cloud-spanner] | stable | [`cloud.google.com/go/spanner`](https://godoc.org/cloud.google.com/go/spanner)
[Speech][cloud-speech] | stable | [`cloud.google.com/go/speech/apiv1`](https://godoc.org/cloud.google.com/go/speech/apiv1)
[Storage][cloud-storage] | stable | [`cloud.google.com/go/storage`](https://godoc.org/cloud.google.com/go/storage)
[Talent][cloud-talent] | alpha | [`cloud.google.com/go/talent/apiv4beta1`](https://godoc.org/cloud.google.com/go/talent/apiv4beta1)
[Text To Speech][cloud-texttospeech] | alpha | [`cloud.google.com/go/texttospeech/apiv1`](https://godoc.org/cloud.google.com/go/texttospeech/apiv1)
[Trace][cloud-trace] | alpha | [`cloud.google.com/go/trace/apiv2`](https://godoc.org/cloud.google.com/go/trace/apiv2)
[Translate][cloud-translate] | stable | [`cloud.google.com/go/translate`](https://godoc.org/cloud.google.com/go/translate)
[Video Intelligence][cloud-video] | alpha | [`cloud.google.com/go/videointelligence/apiv1beta1`](https://godoc.org/cloud.google.com/go/videointelligence/apiv1beta1)
[Vision][cloud-vision] | stable | [`cloud.google.com/go/vision/apiv1`](https://godoc.org/cloud.google.com/go/vision/apiv1)
[Webrisk][cloud-webrisk] | alpha | [`cloud.google.com/go/webrisk/apiv1beta1`](https://godoc.org/cloud.google.com/go/webrisk/apiv1beta1)
[Asset][cloud-asset] | stable | [`cloud.google.com/go/asset/apiv1`](https://pkg.go.dev/cloud.google.com/go/asset/v1beta)
[Automl][cloud-automl] | stable | [`cloud.google.com/go/automl/apiv1`](https://pkg.go.dev/cloud.google.com/go/automl/apiv1)
[BigQuery][cloud-bigquery] | stable | [`cloud.google.com/go/bigquery`](https://pkg.go.dev/cloud.google.com/go/bigquery)
[Bigtable][cloud-bigtable] | stable | [`cloud.google.com/go/bigtable`](https://pkg.go.dev/cloud.google.com/go/bigtable)
[Cloudbuild][cloud-build] | stable | [`cloud.google.com/go/cloudbuild/apiv1`](https://pkg.go.dev/cloud.google.com/go/cloudbuild/apiv1)
[Cloudtasks][cloud-tasks] | stable | [`cloud.google.com/go/cloudtasks/apiv2`](https://pkg.go.dev/cloud.google.com/go/cloudtasks/apiv2)
[Container][cloud-container] | stable | [`cloud.google.com/go/container/apiv1`](https://pkg.go.dev/cloud.google.com/go/container/apiv1)
[ContainerAnalysis][cloud-containeranalysis] | beta | [`cloud.google.com/go/containeranalysis/apiv1`](https://pkg.go.dev/cloud.google.com/go/containeranalysis/apiv1)
[Dataproc][cloud-dataproc] | stable | [`cloud.google.com/go/dataproc/apiv1`](https://pkg.go.dev/cloud.google.com/go/dataproc/apiv1)
[Datastore][cloud-datastore] | stable | [`cloud.google.com/go/datastore`](https://pkg.go.dev/cloud.google.com/go/datastore)
[Debugger][cloud-debugger] | stable | [`cloud.google.com/go/debugger/apiv2`](https://pkg.go.dev/cloud.google.com/go/debugger/apiv2)
[Dialogflow][cloud-dialogflow] | stable | [`cloud.google.com/go/dialogflow/apiv2`](https://pkg.go.dev/cloud.google.com/go/dialogflow/apiv2)
[Data Loss Prevention][cloud-dlp] | stable | [`cloud.google.com/go/dlp/apiv2`](https://pkg.go.dev/cloud.google.com/go/dlp/apiv2)
[ErrorReporting][cloud-errors] | alpha | [`cloud.google.com/go/errorreporting`](https://pkg.go.dev/cloud.google.com/go/errorreporting)
[Firestore][cloud-firestore] | stable | [`cloud.google.com/go/firestore`](https://pkg.go.dev/cloud.google.com/go/firestore)
[IAM][cloud-iam] | stable | [`cloud.google.com/go/iam`](https://pkg.go.dev/cloud.google.com/go/iam)
[IoT][cloud-iot] | stable | [`cloud.google.com/go/iot/apiv1`](https://pkg.go.dev/cloud.google.com/go/iot/apiv1)
[IRM][cloud-irm] | alpha | [`cloud.google.com/go/irm/apiv1alpha2`](https://pkg.go.dev/cloud.google.com/go/irm/apiv1alpha2)
[KMS][cloud-kms] | stable | [`cloud.google.com/go/kms/apiv1`](https://pkg.go.dev/cloud.google.com/go/kms/apiv1)
[Natural Language][cloud-natural-language] | stable | [`cloud.google.com/go/language/apiv1`](https://pkg.go.dev/cloud.google.com/go/language/apiv1)
[Logging][cloud-logging] | stable | [`cloud.google.com/go/logging`](https://pkg.go.dev/cloud.google.com/go/logging)
[Memorystore][cloud-memorystore] | alpha | [`cloud.google.com/go/redis/apiv1`](https://pkg.go.dev/cloud.google.com/go/redis/apiv1)
[Monitoring][cloud-monitoring] | stable | [`cloud.google.com/go/monitoring/apiv3`](https://pkg.go.dev/cloud.google.com/go/monitoring/apiv3)
[OS Login][cloud-oslogin] | stable | [`cloud.google.com/go/oslogin/apiv1`](https://pkg.go.dev/cloud.google.com/go/oslogin/apiv1)
[Pub/Sub][cloud-pubsub] | stable | [`cloud.google.com/go/pubsub`](https://pkg.go.dev/cloud.google.com/go/pubsub)
[Phishing Protection][cloud-phishingprotection] | alpha | [`cloud.google.com/go/phishingprotection/apiv1beta1`](https://pkg.go.dev/cloud.google.com/go/phishingprotection/apiv1beta1)
[reCAPTCHA Enterprise][cloud-recaptcha] | alpha | [`cloud.google.com/go/recaptchaenterprise/apiv1beta1`](https://pkg.go.dev/cloud.google.com/go/recaptchaenterprise/apiv1beta1)
[Recommender][cloud-recommender] | beta | [`cloud.google.com/go/recommender/apiv1beta1`](https://pkg.go.dev/cloud.google.com/go/recommender/apiv1beta1)
[Scheduler][cloud-scheduler] | stable | [`cloud.google.com/go/scheduler/apiv1`](https://pkg.go.dev/cloud.google.com/go/scheduler/apiv1)
[Securitycenter][cloud-securitycenter] | stable | [`cloud.google.com/go/securitycenter/apiv1`](https://pkg.go.dev/cloud.google.com/go/securitycenter/apiv1)
[Spanner][cloud-spanner] | stable | [`cloud.google.com/go/spanner`](https://pkg.go.dev/cloud.google.com/go/spanner)
[Speech][cloud-speech] | stable | [`cloud.google.com/go/speech/apiv1`](https://pkg.go.dev/cloud.google.com/go/speech/apiv1)
[Storage][cloud-storage] | stable | [`cloud.google.com/go/storage`](https://pkg.go.dev/cloud.google.com/go/storage)
[Talent][cloud-talent] | alpha | [`cloud.google.com/go/talent/apiv4beta1`](https://pkg.go.dev/cloud.google.com/go/talent/apiv4beta1)
[Text To Speech][cloud-texttospeech] | stable | [`cloud.google.com/go/texttospeech/apiv1`](https://pkg.go.dev/cloud.google.com/go/texttospeech/apiv1)
[Trace][cloud-trace] | stable | [`cloud.google.com/go/trace/apiv2`](https://pkg.go.dev/cloud.google.com/go/trace/apiv2)
[Translate][cloud-translate] | stable | [`cloud.google.com/go/translate`](https://pkg.go.dev/cloud.google.com/go/translate)
[Video Intelligence][cloud-video] | beta | [`cloud.google.com/go/videointelligence/apiv1beta2`](https://pkg.go.dev/cloud.google.com/go/videointelligence/apiv1beta2)
[Vision][cloud-vision] | stable | [`cloud.google.com/go/vision/apiv1`](https://pkg.go.dev/cloud.google.com/go/vision/apiv1)
[Webrisk][cloud-webrisk] | alpha | [`cloud.google.com/go/webrisk/apiv1beta1`](https://pkg.go.dev/cloud.google.com/go/webrisk/apiv1beta1)
> **Alpha status**: the API is still being actively developed. As a
> result, it might change in backward-incompatible ways and is not recommended
@ -83,7 +83,7 @@ Google API | Status | Package
> **Stable status**: the API is mature and ready for production use. We will
> continue addressing bugs and feature requests.
Documentation and examples are available at [godoc.org/cloud.google.com/go](https://godoc.org/cloud.google.com/go)
Documentation and examples are available at [pkg.go.dev/cloud.google.com/go](https://pkg.go.dev/cloud.google.com/go)
## Go Versions Supported
@ -104,7 +104,7 @@ client, err := storage.NewClient(ctx)
To authorize using a
[JSON key file](https://cloud.google.com/iam/docs/managing-service-account-keys),
pass
[`option.WithCredentialsFile`](https://godoc.org/google.golang.org/api/option#WithCredentialsFile)
[`option.WithCredentialsFile`](https://pkg.go.dev/google.golang.org/api/option#WithCredentialsFile)
to the `NewClient` function of the desired package. For example:
[snip]:# (auth-JSON)
@ -113,9 +113,9 @@ client, err := storage.NewClient(ctx, option.WithCredentialsFile("path/to/keyfil
```
You can exert more control over authorization by using the
[`golang.org/x/oauth2`](https://godoc.org/golang.org/x/oauth2) package to
[`golang.org/x/oauth2`](https://pkg.go.dev/golang.org/x/oauth2) package to
create an `oauth2.TokenSource`. Then pass
[`option.WithTokenSource`](https://godoc.org/google.golang.org/api/option#WithTokenSource)
[`option.WithTokenSource`](https://pkg.go.dev/google.golang.org/api/option#WithTokenSource)
to the `NewClient` function:
[snip]:# (auth-ts)
```go

View file

@ -18,7 +18,7 @@ to install the code reviewing tool.
1. If you would like, you may want to set up aliases for `git-codereview`,
such that `git codereview change` becomes `git change`. See the
[godoc](https://godoc.org/golang.org/x/review/git-codereview) for details.
[godoc](https://pkg.go.dev/golang.org/x/review/git-codereview) for details.
* Should you run into issues with the `git-codereview` tool, please note
that all error messages will assume that you have set up these aliases.

View file

@ -61,8 +61,7 @@ var (
instID = &cachedValue{k: "instance/id", trim: true}
)
var (
defaultClient = &Client{hc: &http.Client{
var defaultClient = &Client{hc: &http.Client{
Transport: &http.Transport{
Dial: (&net.Dialer{
Timeout: 2 * time.Second,
@ -70,15 +69,6 @@ var (
}).Dial,
},
}}
subscribeClient = &Client{hc: &http.Client{
Transport: &http.Transport{
Dial: (&net.Dialer{
Timeout: 2 * time.Second,
KeepAlive: 30 * time.Second,
}).Dial,
},
}}
)
// NotDefinedError is returned when requested metadata is not defined.
//
@ -205,10 +195,9 @@ func systemInfoSuggestsGCE() bool {
return name == "Google" || name == "Google Compute Engine"
}
// Subscribe calls Client.Subscribe on a client designed for subscribing (one with no
// ResponseHeaderTimeout).
// Subscribe calls Client.Subscribe on the default client.
func Subscribe(suffix string, fn func(v string, ok bool) error) error {
return subscribeClient.Subscribe(suffix, fn)
return defaultClient.Subscribe(suffix, fn)
}
// Get calls Client.Get on the default client.
@ -279,9 +268,14 @@ type Client struct {
hc *http.Client
}
// NewClient returns a Client that can be used to fetch metadata. All HTTP requests
// will use the given http.Client instead of the default client.
// NewClient returns a Client that can be used to fetch metadata.
// Returns the client that uses the specified http.Client for HTTP requests.
// If nil is specified, returns the default client.
func NewClient(c *http.Client) *Client {
if c == nil {
return defaultClient
}
return &Client{hc: c}
}

31
vendor/cloud.google.com/go/go.mod generated vendored
View file

@ -3,29 +3,26 @@ module cloud.google.com/go
go 1.11
require (
cloud.google.com/go/bigquery v1.3.0
cloud.google.com/go/datastore v1.0.0
cloud.google.com/go/pubsub v1.1.0
cloud.google.com/go/storage v1.5.0
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/mock v1.4.0
github.com/golang/protobuf v1.3.3
cloud.google.com/go/bigquery v1.4.0
cloud.google.com/go/datastore v1.1.0
cloud.google.com/go/pubsub v1.2.0
cloud.google.com/go/storage v1.6.0
github.com/golang/mock v1.4.1
github.com/golang/protobuf v1.3.4
github.com/google/go-cmp v0.4.0
github.com/google/martian v2.1.0+incompatible
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3
github.com/googleapis/gax-go/v2 v2.0.5
github.com/jstemmer/go-junit-report v0.9.1
go.opencensus.io v0.22.3
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd
golang.org/x/lint v0.0.0-20200130185559-910be7a94367
golang.org/x/mod v0.2.0 // indirect
golang.org/x/net v0.0.0-20200202094626-16171245cfb2
golang.org/x/lint v0.0.0-20200302205851-738671d3881b
golang.org/x/net v0.0.0-20200301022130-244492dfa37a
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 // indirect
golang.org/x/text v0.3.2
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56
google.golang.org/api v0.17.0
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb
google.golang.org/api v0.20.0
google.golang.org/genproto v0.0.0-20200305110556-506484158171
google.golang.org/grpc v1.27.1
honnef.co/go/tools v0.0.1-2019.2.3
honnef.co/go/tools v0.0.1-2020.1.3
)

66
vendor/cloud.google.com/go/go.sum generated vendored
View file

@ -6,26 +6,37 @@ cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxK
cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=
cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=
cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=
cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=
cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=
cloud.google.com/go/bigquery v1.0.1 h1:hL+ycaJpVE9M7nLoiXb/Pn10ENE2u+oddxbD8uu0ZVU=
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
cloud.google.com/go/bigquery v1.3.0 h1:sAbMqjY1PEQKZBWfbu6Y6bsupJ9c4QdHnzg/VvYTLcE=
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
cloud.google.com/go/bigquery v1.4.0 h1:xE3CPsOgttP4ACBePh79zTKALtXwn/Edhcr16R5hMWU=
cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=
cloud.google.com/go/datastore v1.0.0 h1:Kt+gOPPp2LEPWp8CSfxhsM8ik9CcyE/gYu+0r+RnZvM=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ=
cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=
cloud.google.com/go/pubsub v1.0.1 h1:W9tAK3E57P75u0XLLR82LZyw8VpAnhmyTOxW9qzmyj8=
cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=
cloud.google.com/go/pubsub v1.1.0 h1:9/vpR43S4aJaROxqQHQ3nH9lfyKKV0dC3vOmnw8ebQQ=
cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=
cloud.google.com/go/pubsub v1.2.0 h1:Lpy6hKgdcl7a3WGSfJIFmxmcdjSpP6OmBEfcOv1Y680=
cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=
cloud.google.com/go/storage v1.0.0 h1:VV2nUM3wwLLGh9lSABFgZMjInyUbJeaRSE64WuAIQ+4=
cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=
cloud.google.com/go/storage v1.5.0 h1:RPUcBvDeYgQFMfQu1eBMq6piD1SXmLH+vK3qjewZPus=
cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=
cloud.google.com/go/storage v1.6.0 h1:UDpwYIwla4jHGzZJaEJYx1tOejbgSoNqsAfHAUYe2r8=
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@ -34,6 +45,7 @@ github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.m
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@ -47,6 +59,8 @@ github.com/golang/mock v1.3.1 h1:qGJ6qTW+x6xX/my+8YUVl4WNpX9B7+/l2tRsHGZ7f2s=
github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=
github.com/golang/mock v1.4.0 h1:Rd1kQnQu0Hq3qvJppYSG0HtP+f5LPPUiDswTLiEegLg=
github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/mock v1.4.1 h1:ocYkMQY5RrXTYgXl7ICpV0IXwlEQGwKIsery4gyXa1U=
github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
@ -54,6 +68,8 @@ github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk=
github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c h1:964Od4U6p2jUkFxvCydnIczKteheJEzHRToSGK3Bnlw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
@ -71,8 +87,10 @@ github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57 h1:eqyIo2HjKhKe/mJzTG
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f h1:Jnx61latede7zDD3DiiP4gmNz33uK0U5HDUaF0a/HVQ=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12 h1:TgXhFz35pKlZuUz1pNlOKk1UCSXPpuUIc144Wd7SxCA=
github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3 h1:SRgJV+IoxM5MKyFdlSUeNy6/ycRUF2yBAKdAQswoHUk=
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/googleapis/gax-go/v2 v2.0.4 h1:hU4mGcQI4DaAYW+IbTun+2qEZVFxK0ySjQLTbS0VQKc=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
@ -82,6 +100,7 @@ github.com/hashicorp/golang-lru v0.5.0 h1:CL2msUPvZTLb5O648aiLNJw3hnBxN2+1Jq8rCO
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6 h1:UDMh68UUwekSh5iP2OMhRRZJiiBccgV7axzUG8vi56c=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024 h1:rBMNdlhTLzJjJSDIjNEXX1Pz3Hmwmz91v+zycvx9PJc=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
@ -119,8 +138,10 @@ golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm0
golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=
golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd h1:zkO/Lhoka23X63N9OSzpSeROEUQ5ODw47tM3YWjygbs=
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6 h1:QE6XYQK6naiK1EPAe1g/ILLxN5RBoH5xkJk3CqlMI/Y=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@ -136,12 +157,15 @@ golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHl
golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367 h1:0IiAsCRByjO2QjX7ZPkw5oU9x+n1YqRL802rjC0c3Aw=
golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b h1:Wh+f8QHJXR411sJR8/vRBTZ7YapZaRvUcLFFJhusH0k=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=
golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee h1:WG0RUwxtNT4qqaXX3DPA8zHFNm/D9xaBpxzHt1WcA/E=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -159,8 +183,12 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwL
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 h1:CCH4IOTTfewWjGOlSp+zGcjutRKlBEZQ6wTn8ozI/nI=
golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a h1:GuSPYbZzB5/dcLNCwLQLsg3obCJtX9IJhpXkvY7kzk0=
golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421 h1:Wo7BWFiOk0QRFMLYMqJGFMd9CgUAcGx7V+qEg/h5IBI=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -190,10 +218,17 @@ golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0 h1:HyfiK1WMnHj5FXFXatD+Qs1A/xC2Run6RzeW1SyHxpc=
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 h1:sfkvUWPNGwSV+8/fNqctR5lS2AqCSqYwXdrjCxp/dXo=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527 h1:uYVVQ9WP/Ds2ROhcaGPeIdVq0RIXVLwsHlnvJ+cT1So=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2 h1:z99zHgr7hKfrUcX/KsoJk5FJfjTceCKIp96+biqP4To=
@ -204,6 +239,7 @@ golang.org/x/time v0.0.0-20181108054448-85acf8d2951c h1:fqgJT0MGcGpPgpWU7VRdRjuA
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
@ -227,12 +263,18 @@ golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56 h1:DFtSed2q3HtNuVazwVDZ4nSRS/JrZEig0gz2BY4VNrg=
golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb h1:iKlO7ROJc6SttHKlxzwGytRtBUqX4VARrNTgP2YLX5M=
golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4=
@ -249,6 +291,9 @@ google.golang.org/api v0.15.0 h1:yzlyyDW/J0w8yNFJIhiAJy4kq74S+1DOLdawELNxFMA=
google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=
google.golang.org/api v0.17.0 h1:0q95w+VuFtv4PAx4PZVQdBMmYbaCHbnfKaEiDIcVyag=
google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/api v0.20.0 h1:jz2KixHX7EcCPiQrySzPdnYT7DbINAypCqKZ1Z7GM40=
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
@ -275,8 +320,13 @@ google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvx
google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce h1:1mbrb1tUU+Zmt5C94IGKADBTJZjZXAd+BubWi7r9EiI=
google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=
google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=
google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/genproto v0.0.0-20200305110556-506484158171 h1:xes2Q2k+d/+YNXVw0FpZkIDJiaux4OVrRKXRAzH6A0U=
google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1 h1:Hz2g2wirWK7H0qIIhGIqRGTuMwTE8HEKFnDZZ7lm9NU=
@ -303,7 +353,11 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
honnef.co/go/tools v0.0.1-2020.1.3 h1:sXmLre5bzIR6ypkjXCDI3jHPssRhc8KD/Ome589sc3U=
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4=
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=

View file

@ -38,6 +38,7 @@ type client interface {
Get(ctx context.Context, resource string) (*pb.Policy, error)
Set(ctx context.Context, resource string, p *pb.Policy) error
Test(ctx context.Context, resource string, perms []string) ([]string, error)
GetWithVersion(ctx context.Context, resource string, requestedPolicyVersion int32) (*pb.Policy, error)
}
// grpcClient implements client for the standard gRPC-based IAMPolicy service.
@ -57,13 +58,22 @@ var withRetry = gax.WithRetry(func() gax.Retryer {
})
func (g *grpcClient) Get(ctx context.Context, resource string) (*pb.Policy, error) {
return g.GetWithVersion(ctx, resource, 1)
}
func (g *grpcClient) GetWithVersion(ctx context.Context, resource string, requestedPolicyVersion int32) (*pb.Policy, error) {
var proto *pb.Policy
md := metadata.Pairs("x-goog-request-params", fmt.Sprintf("%s=%v", "resource", resource))
ctx = insertMetadata(ctx, md)
err := gax.Invoke(ctx, func(ctx context.Context, _ gax.CallSettings) error {
var err error
proto, err = g.c.GetIamPolicy(ctx, &pb.GetIamPolicyRequest{Resource: resource})
proto, err = g.c.GetIamPolicy(ctx, &pb.GetIamPolicyRequest{
Resource: resource,
Options: &pb.GetPolicyOptions{
RequestedPolicyVersion: requestedPolicyVersion,
},
})
return err
}, withRetry)
if err != nil {
@ -110,11 +120,18 @@ type Handle struct {
resource string
}
// A Handle3 provides IAM operations for a resource. It is similar to a Handle, but provides access to newer IAM features (e.g., conditions).
type Handle3 struct {
c client
resource string
version int32
}
// InternalNewHandle is for use by the Google Cloud Libraries only.
//
// InternalNewHandle returns a Handle for resource.
// The conn parameter refers to a server that must support the IAMPolicy service.
func InternalNewHandle(conn *grpc.ClientConn, resource string) *Handle {
func InternalNewHandle(conn grpc.ClientConnInterface, resource string) *Handle {
return InternalNewHandleGRPCClient(pb.NewIAMPolicyClient(conn), resource)
}
@ -137,6 +154,17 @@ func InternalNewHandleClient(c client, resource string) *Handle {
}
}
// V3 returns a Handle3, which is like Handle except it sets
// requestedPolicyVersion to 3 when retrieving a policy and policy.version to 3
// when storing a policy.
func (h *Handle) V3() *Handle3 {
return &Handle3{
c: h.c,
resource: h.resource,
version: 3,
}
}
// Policy retrieves the IAM policy for the resource.
func (h *Handle) Policy(ctx context.Context) (*Policy, error) {
proto, err := h.c.Get(ctx, h.resource)
@ -313,3 +341,47 @@ func insertMetadata(ctx context.Context, mds ...metadata.MD) context.Context {
}
return metadata.NewOutgoingContext(ctx, out)
}
// A Policy3 is a list of Bindings representing roles granted to members.
//
// The zero Policy3 is a valid policy with no bindings.
//
// It is similar to a Policy, except a Policy3 provides direct access to the
// list of Bindings.
//
// The policy version is always set to 3.
type Policy3 struct {
etag []byte
Bindings []*pb.Binding
}
// Policy retrieves the IAM policy for the resource.
//
// requestedPolicyVersion is always set to 3.
func (h *Handle3) Policy(ctx context.Context) (*Policy3, error) {
proto, err := h.c.GetWithVersion(ctx, h.resource, h.version)
if err != nil {
return nil, err
}
return &Policy3{
Bindings: proto.Bindings,
etag: proto.Etag,
}, nil
}
// SetPolicy replaces the resource's current policy with the supplied Policy.
//
// If policy was created from a prior call to Get, then the modification will
// only succeed if the policy has not changed since the Get.
func (h *Handle3) SetPolicy(ctx context.Context, policy *Policy3) error {
return h.c.Set(ctx, h.resource, &pb.Policy{
Bindings: policy.Bindings,
Etag: policy.etag,
Version: h.version,
})
}
// TestPermissions returns the subset of permissions that the caller has on the resource.
func (h *Handle3) TestPermissions(ctx context.Context, permissions []string) ([]string, error) {
return h.c.Test(ctx, h.resource, permissions)
}

View file

@ -5,7 +5,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/asset/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/asset/apiv1beta1": {
"distribution_name": "cloud.google.com/go/asset/apiv1beta1",
@ -28,7 +28,7 @@
"description": "Cloud AutoML API",
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/loud.google.com/go/automl/apiv1",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/automl/apiv1",
"release_level": "ga"
},
"cloud.google.com/go/automl/apiv1beta1": {
@ -36,7 +36,7 @@
"description": "Cloud AutoML API",
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/loud.google.com/go/automl/apiv1beta1",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/automl/apiv1beta1",
"release_level": "beta"
},
"cloud.google.com/go/bigquery": {
@ -53,7 +53,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/bigquery/datatransfer/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/bigquery/reservation/apiv1beta1": {
"distribution_name": "cloud.google.com/go/bigquery/reservation/apiv1beta1",
@ -165,7 +165,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/dataproc/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/dataproc/apiv1beta2": {
"distribution_name": "cloud.google.com/go/dataproc/apiv1beta2",
@ -245,7 +245,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/firestore/apiv1",
"release_level": "beta"
"release_level": "ga"
},
"cloud.google.com/go/firestore/apiv1/admin": {
"distribution_name": "cloud.google.com/go/firestore/apiv1/admin",
@ -253,7 +253,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/firestore/apiv1/admin",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/firestore/apiv1beta1": {
"distribution_name": "cloud.google.com/go/firestore/apiv1beta1",
@ -277,7 +277,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/iam/credentials/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/iot/apiv1": {
"distribution_name": "cloud.google.com/go/iot/apiv1",
@ -309,7 +309,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/language/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/language/apiv1beta2": {
"distribution_name": "cloud.google.com/go/language/apiv1beta2",
@ -333,7 +333,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/logging/apiv2",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/longrunning/autogen": {
"distribution_name": "cloud.google.com/go/longrunning/autogen",
@ -343,13 +343,21 @@
"docs_url": "https://pkg.go.dev/cloud.google.com/go/longrunning/autogen",
"release_level": "alpha"
},
"cloud.google.com/go/memcache/apiv1beta2": {
"distribution_name": "cloud.google.com/go/memcache/apiv1beta2",
"description": "Cloud Memorystore for Memcached API",
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/memcache/apiv1beta2",
"release_level": "beta"
},
"cloud.google.com/go/monitoring/apiv3": {
"distribution_name": "cloud.google.com/go/monitoring/apiv3",
"description": "Stackdriver Monitoring API",
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/monitoring/apiv3",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/osconfig/agentendpoint/apiv1beta": {
"distribution_name": "cloud.google.com/go/osconfig/agentendpoint/apiv1beta",
@ -373,7 +381,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/oslogin/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/oslogin/apiv1beta": {
"distribution_name": "cloud.google.com/go/oslogin/apiv1beta",
@ -399,6 +407,14 @@
"docs_url": "https://pkg.go.dev/cloud.google.com/go/pubsub",
"release_level": "ga"
},
"cloud.google.com/go/pubsub/apiv1": {
"distribution_name": "cloud.google.com/go/pubsub/apiv1",
"description": "Cloud Pub/Sub API",
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/pubsub/apiv1",
"release_level": "ga"
},
"cloud.google.com/go/recaptchaenterprise/apiv1beta1": {
"distribution_name": "cloud.google.com/go/recaptchaenterprise/apiv1beta1",
"description": "reCAPTCHA Enterprise API",
@ -429,7 +445,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/redis/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/redis/apiv1beta1": {
"distribution_name": "cloud.google.com/go/redis/apiv1beta1",
@ -439,6 +455,14 @@
"docs_url": "https://pkg.go.dev/cloud.google.com/go/redis/apiv1beta1",
"release_level": "beta"
},
"cloud.google.com/go/rpcreplay": {
"distribution_name": "cloud.google.com/go/rpcreplay",
"description": "RPC Replay",
"language": "Go",
"client_library_type": "manual",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/rpcreplay",
"release_level": "ga"
},
"cloud.google.com/go/scheduler/apiv1": {
"distribution_name": "cloud.google.com/go/scheduler/apiv1",
"description": "Cloud Scheduler API",
@ -455,6 +479,14 @@
"docs_url": "https://pkg.go.dev/cloud.google.com/go/scheduler/apiv1beta1",
"release_level": "beta"
},
"cloud.google.com/go/secretmanager/apiv1": {
"distribution_name": "cloud.google.com/go/secretmanager/apiv1",
"description": "Secret Manager API",
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/secretmanager/apiv1",
"release_level": "beta"
},
"cloud.google.com/go/secretmanager/apiv1beta1": {
"distribution_name": "cloud.google.com/go/secretmanager/apiv1beta1",
"description": "Secret Manager API",
@ -469,7 +501,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/securitycenter/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/securitycenter/apiv1beta1": {
"distribution_name": "cloud.google.com/go/securitycenter/apiv1beta1",
@ -501,7 +533,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/spanner/admin/database/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/spanner/admin/instance/apiv1": {
"distribution_name": "cloud.google.com/go/spanner/admin/instance/apiv1",
@ -509,7 +541,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/spanner/admin/instance/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/spanner/apiv1": {
"distribution_name": "cloud.google.com/go/spanner/apiv1",
@ -548,7 +580,7 @@
"description": "Cloud Talent Solution API",
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/loud.google.com/go/talent/apiv4beta1",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/talent/apiv4beta1",
"release_level": "beta"
},
"cloud.google.com/go/texttospeech/apiv1": {
@ -557,7 +589,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/texttospeech/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/trace": {
"distribution_name": "cloud.google.com/go/trace",
@ -573,7 +605,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/trace/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/trace/apiv2": {
"distribution_name": "cloud.google.com/go/trace/apiv2",
@ -581,7 +613,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/trace/apiv2",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/translate/apiv3": {
"distribution_name": "cloud.google.com/go/translate/apiv3",
@ -597,7 +629,7 @@
"language": "Go",
"client_library_type": "generated",
"docs_url": "https://pkg.go.dev/cloud.google.com/go/videointelligence/apiv1",
"release_level": "alpha"
"release_level": "ga"
},
"cloud.google.com/go/videointelligence/apiv1beta2": {
"distribution_name": "cloud.google.com/go/videointelligence/apiv1beta2",

View file

@ -26,7 +26,7 @@ import (
// Repo is the current version of the client libraries in this
// repo. It should be a date in YYYYMMDD format.
const Repo = "20200212"
const Repo = "20200228"
// Go returns the Go runtime version. The returned string
// has no whitespace.

View file

@ -26,7 +26,6 @@ package cloud
import (
_ "github.com/golang/protobuf/protoc-gen-go"
_ "github.com/jstemmer/go-junit-report"
_ "golang.org/x/exp/cmd/apidiff"
_ "golang.org/x/lint/golint"
_ "golang.org/x/tools/cmd/goimports"
_ "honnef.co/go/tools/cmd/staticcheck"

View file

@ -1376,8 +1376,8 @@ type FileOptions struct {
// determining the namespace.
PhpNamespace *string `protobuf:"bytes,41,opt,name=php_namespace,json=phpNamespace" json:"php_namespace,omitempty"`
// Use this option to change the namespace of php generated metadata classes.
// Default is empty. When this option is empty, the proto file name will be used
// for determining the namespace.
// Default is empty. When this option is empty, the proto file name will be
// used for determining the namespace.
PhpMetadataNamespace *string `protobuf:"bytes,44,opt,name=php_metadata_namespace,json=phpMetadataNamespace" json:"php_metadata_namespace,omitempty"`
// Use this option to change the package of ruby generated classes. Default
// is empty. When this option is not set, the package name will be used for
@ -1627,7 +1627,7 @@ type MessageOptions struct {
//
// Implementations may choose not to generate the map_entry=true message, but
// use a native map in the target language to hold the keys and values.
// The reflection APIs in such implementions still need to work as
// The reflection APIs in such implementations still need to work as
// if the field is a repeated message field.
//
// NOTE: Do not set the option in .proto files. Always use the maps syntax
@ -2377,7 +2377,7 @@ type SourceCodeInfo struct {
// beginning of the "extend" block and is shared by all extensions within
// the block.
// - Just because a location's span is a subset of some other location's span
// does not mean that it is a descendent. For example, a "group" defines
// does not mean that it is a descendant. For example, a "group" defines
// both a type and a field in a single declaration. Thus, the locations
// corresponding to the type and field and their components will overlap.
// - Code which tries to interpret locations should probably be designed to
@ -2718,7 +2718,9 @@ func init() {
proto.RegisterType((*GeneratedCodeInfo_Annotation)(nil), "google.protobuf.GeneratedCodeInfo.Annotation")
}
func init() { proto.RegisterFile("google/protobuf/descriptor.proto", fileDescriptor_e5baabe45344a177) }
func init() {
proto.RegisterFile("google/protobuf/descriptor.proto", fileDescriptor_e5baabe45344a177)
}
var fileDescriptor_e5baabe45344a177 = []byte{
// 2589 bytes of a gzipped FileDescriptorProto

View file

@ -40,6 +40,7 @@
syntax = "proto2";
package google.protobuf;
option go_package = "github.com/golang/protobuf/protoc-gen-go/descriptor;descriptor";
option java_package = "com.google.protobuf";
option java_outer_classname = "DescriptorProtos";
@ -100,8 +101,8 @@ message DescriptorProto {
repeated EnumDescriptorProto enum_type = 4;
message ExtensionRange {
optional int32 start = 1;
optional int32 end = 2;
optional int32 start = 1; // Inclusive.
optional int32 end = 2; // Exclusive.
optional ExtensionRangeOptions options = 3;
}
@ -165,14 +166,14 @@ message FieldDescriptorProto {
TYPE_SFIXED64 = 16;
TYPE_SINT32 = 17; // Uses ZigZag encoding.
TYPE_SINT64 = 18; // Uses ZigZag encoding.
};
}
enum Label {
// 0 is reserved for errors
LABEL_OPTIONAL = 1;
LABEL_REQUIRED = 2;
LABEL_REPEATED = 3;
};
}
optional string name = 1;
optional int32 number = 3;
@ -314,7 +315,6 @@ message MethodDescriptorProto {
// If this turns out to be popular, a web service will be set up
// to automatically assign option numbers.
message FileOptions {
// Sets the Java package where classes generated from this .proto will be
@ -369,6 +369,7 @@ message FileOptions {
// Should generic services be generated in each language? "Generic" services
// are not specific to any particular RPC system. They are generated by the
// main code generators in each language (without additional plugins).
@ -417,10 +418,9 @@ message FileOptions {
// determining the namespace.
optional string php_namespace = 41;
// Use this option to change the namespace of php generated metadata classes.
// Default is empty. When this option is empty, the proto file name will be used
// for determining the namespace.
// Default is empty. When this option is empty, the proto file name will be
// used for determining the namespace.
optional string php_metadata_namespace = 44;
// Use this option to change the package of ruby generated classes. Default
@ -428,6 +428,7 @@ message FileOptions {
// determining the ruby package.
optional string ruby_package = 45;
// The parser stores options it doesn't recognize here.
// See the documentation for the "Options" section above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -486,7 +487,7 @@ message MessageOptions {
//
// Implementations may choose not to generate the map_entry=true message, but
// use a native map in the target language to hold the keys and values.
// The reflection APIs in such implementions still need to work as
// The reflection APIs in such implementations still need to work as
// if the field is a repeated message field.
//
// NOTE: Do not set the option in .proto files. Always use the maps syntax
@ -497,6 +498,7 @@ message MessageOptions {
reserved 8; // javalite_serializable
reserved 9; // javanano_as_lite
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -681,8 +683,8 @@ message MethodOptions {
NO_SIDE_EFFECTS = 1; // implies idempotent
IDEMPOTENT = 2; // idempotent, but may have side effects
}
optional IdempotencyLevel idempotency_level =
34 [default=IDEMPOTENCY_UNKNOWN];
optional IdempotencyLevel idempotency_level = 34
[default = IDEMPOTENCY_UNKNOWN];
// The parser stores options it doesn't recognize here. See above.
repeated UninterpretedOption uninterpreted_option = 999;
@ -763,7 +765,7 @@ message SourceCodeInfo {
// beginning of the "extend" block and is shared by all extensions within
// the block.
// - Just because a location's span is a subset of some other location's span
// does not mean that it is a descendent. For example, a "group" defines
// does not mean that it is a descendant. For example, a "group" defines
// both a type and a field in a single declaration. Thus, the locations
// corresponding to the type and field and their components will overlap.
// - Code which tries to interpret locations should probably be designed to

View file

@ -2609,7 +2609,9 @@ func (g *Generator) generateFileDescriptor(file *FileDescriptor) {
v := file.VarName()
g.P()
g.P("func init() { ", g.Pkg["proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ") }")
g.P("func init() {")
g.P(g.Pkg["proto"], ".RegisterFile(", strconv.Quote(*file.Name), ", ", v, ")")
g.P("}")
g.P("var ", v, " = []byte{")
g.P("// ", len(b), " bytes of a gzipped FileDescriptorProto")
for len(b) > 0 {

View file

@ -102,7 +102,8 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
//
type Any struct {
// A URL/resource name that uniquely identifies the type of the serialized
// protocol buffer message. The last segment of the URL's path must represent
// protocol buffer message. This string must contain at least
// one "/" character. The last segment of the URL's path must represent
// the fully qualified name of the type (as in
// `path/google.protobuf.Duration`). The name should be in a canonical form
// (e.g., leading "." is not accepted).
@ -181,7 +182,9 @@ func init() {
proto.RegisterType((*Any)(nil), "google.protobuf.Any")
}
func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_b53526c13ae22eb4) }
func init() {
proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_b53526c13ae22eb4)
}
var fileDescriptor_b53526c13ae22eb4 = []byte{
// 185 bytes of a gzipped FileDescriptorProto

View file

@ -121,7 +121,8 @@ option objc_class_prefix = "GPB";
//
message Any {
// A URL/resource name that uniquely identifies the type of the serialized
// protocol buffer message. The last segment of the URL's path must represent
// protocol buffer message. This string must contain at least
// one "/" character. The last segment of the URL's path must represent
// the fully qualified name of the type (as in
// `path/google.protobuf.Duration`). The name should be in a canonical form
// (e.g., leading "." is not accepted).

View file

@ -41,7 +41,7 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// if (duration.seconds < 0 && duration.nanos > 0) {
// duration.seconds += 1;
// duration.nanos -= 1000000000;
// } else if (durations.seconds > 0 && duration.nanos < 0) {
// } else if (duration.seconds > 0 && duration.nanos < 0) {
// duration.seconds -= 1;
// duration.nanos += 1000000000;
// }
@ -142,7 +142,9 @@ func init() {
proto.RegisterType((*Duration)(nil), "google.protobuf.Duration")
}
func init() { proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_23597b2ebd7ac6c5) }
func init() {
proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_23597b2ebd7ac6c5)
}
var fileDescriptor_23597b2ebd7ac6c5 = []byte{
// 190 bytes of a gzipped FileDescriptorProto

View file

@ -61,7 +61,7 @@ option objc_class_prefix = "GPB";
// if (duration.seconds < 0 && duration.nanos > 0) {
// duration.seconds += 1;
// duration.nanos -= 1000000000;
// } else if (durations.seconds > 0 && duration.nanos < 0) {
// } else if (duration.seconds > 0 && duration.nanos < 0) {
// duration.seconds -= 1;
// duration.nanos += 1000000000;
// }
@ -101,7 +101,6 @@ option objc_class_prefix = "GPB";
//
//
message Duration {
// Signed seconds of the span of time. Must be from -315,576,000,000
// to +315,576,000,000 inclusive. Note: these bounds are computed from:
// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years

View file

@ -20,17 +20,19 @@ var _ = math.Inf
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// A Timestamp represents a point in time independent of any time zone
// or calendar, represented as seconds and fractions of seconds at
// nanosecond resolution in UTC Epoch time. It is encoded using the
// Proleptic Gregorian Calendar which extends the Gregorian calendar
// backwards to year one. It is encoded assuming all minutes are 60
// seconds long, i.e. leap seconds are "smeared" so that no leap second
// table is needed for interpretation. Range is from
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
// By restricting to that range, we ensure that we can convert to
// and from RFC 3339 date strings.
// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
// A Timestamp represents a point in time independent of any time zone or local
// calendar, encoded as a count of seconds and fractions of seconds at
// nanosecond resolution. The count is relative to an epoch at UTC midnight on
// January 1, 1970, in the proleptic Gregorian calendar which extends the
// Gregorian calendar backwards to year one.
//
// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
// second table is needed for interpretation, using a [24-hour linear
// smear](https://developers.google.com/time/smear).
//
// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
// restricting to that range, we ensure that we can convert to and from [RFC
// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
//
// # Examples
//
@ -91,12 +93,14 @@ const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package
// 01:30 UTC on January 15, 2017.
//
// In JavaScript, one can convert a Date object to this format using the
// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString]
// standard
// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
// method. In Python, a standard `datetime.datetime` object can be converted
// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--
// to this format using
// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
// the Joda Time's [`ISODateTimeFormat.dateTime()`](
// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
// ) to obtain a formatter capable of generating timestamps in this format.
//
//
@ -160,7 +164,9 @@ func init() {
proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp")
}
func init() { proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_292007bbfe81227e) }
func init() {
proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_292007bbfe81227e)
}
var fileDescriptor_292007bbfe81227e = []byte{
// 191 bytes of a gzipped FileDescriptorProto

View file

@ -40,17 +40,19 @@ option java_outer_classname = "TimestampProto";
option java_multiple_files = true;
option objc_class_prefix = "GPB";
// A Timestamp represents a point in time independent of any time zone
// or calendar, represented as seconds and fractions of seconds at
// nanosecond resolution in UTC Epoch time. It is encoded using the
// Proleptic Gregorian Calendar which extends the Gregorian calendar
// backwards to year one. It is encoded assuming all minutes are 60
// seconds long, i.e. leap seconds are "smeared" so that no leap second
// table is needed for interpretation. Range is from
// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z.
// By restricting to that range, we ensure that we can convert to
// and from RFC 3339 date strings.
// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt).
// A Timestamp represents a point in time independent of any time zone or local
// calendar, encoded as a count of seconds and fractions of seconds at
// nanosecond resolution. The count is relative to an epoch at UTC midnight on
// January 1, 1970, in the proleptic Gregorian calendar which extends the
// Gregorian calendar backwards to year one.
//
// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
// second table is needed for interpretation, using a [24-hour linear
// smear](https://developers.google.com/time/smear).
//
// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
// restricting to that range, we ensure that we can convert to and from [RFC
// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
//
// # Examples
//
@ -111,17 +113,18 @@ option objc_class_prefix = "GPB";
// 01:30 UTC on January 15, 2017.
//
// In JavaScript, one can convert a Date object to this format using the
// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString]
// standard
// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
// method. In Python, a standard `datetime.datetime` object can be converted
// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime)
// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one
// can use the Joda Time's [`ISODateTimeFormat.dateTime()`](
// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime--
// to this format using
// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
// the Joda Time's [`ISODateTimeFormat.dateTime()`](
// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
// ) to obtain a formatter capable of generating timestamps in this format.
//
//
message Timestamp {
// Represents seconds of UTC time since Unix epoch
// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
// 9999-12-31T23:59:59Z inclusive.

View file

@ -3,7 +3,20 @@ language: go
sudo: false
go:
- 1.4
- 1.5.x
- 1.6.x
- 1.7.x
- 1.8.x
- 1.9.x
- 1.10.x
- 1.11.x
- 1.12.x
- 1.13.x
- 1.14.x
- tip
allow_failures:
- go: tip
install: go get -v -t ./...
script: make test

View file

@ -4,4 +4,84 @@
See http://jmespath.org for more info.
go-jmespath is a GO implementation of JMESPath,
which is a query language for JSON. It will take a JSON
document and transform it into another JSON document
through a JMESPath expression.
Using go-jmespath is really easy. There's a single function
you use, `jmespath.search`:
```go
> import "github.com/jmespath/go-jmespath"
>
> var jsondata = []byte(`{"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}}`) // your data
> var data interface{}
> err := json.Unmarshal(jsondata, &data)
> result, err := jmespath.Search("foo.bar.baz[2]", data)
result = 2
```
In the example we gave the ``search`` function input data of
`{"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}}` as well as the JMESPath
expression `foo.bar.baz[2]`, and the `search` function evaluated
the expression against the input data to produce the result ``2``.
The JMESPath language can do a lot more than select an element
from a list. Here are a few more examples:
```go
> var jsondata = []byte(`{"foo": {"bar": {"baz": [0, 1, 2, 3, 4]}}}`) // your data
> var data interface{}
> err := json.Unmarshal(jsondata, &data)
> result, err := jmespath.search("foo.bar", data)
result = { "baz": [ 0, 1, 2, 3, 4 ] }
> var jsondata = []byte(`{"foo": [{"first": "a", "last": "b"},
{"first": "c", "last": "d"}]}`) // your data
> var data interface{}
> err := json.Unmarshal(jsondata, &data)
> result, err := jmespath.search({"foo[*].first", data)
result [ 'a', 'c' ]
> var jsondata = []byte(`{"foo": [{"age": 20}, {"age": 25},
{"age": 30}, {"age": 35},
{"age": 40}]}`) // your data
> var data interface{}
> err := json.Unmarshal(jsondata, &data)
> result, err := jmespath.search("foo[?age > `30`]")
result = [ { age: 35 }, { age: 40 } ]
```
You can also pre-compile your query. This is usefull if
you are going to run multiple searches with it:
```go
> var jsondata = []byte(`{"foo": "bar"}`)
> var data interface{}
> err := json.Unmarshal(jsondata, &data)
> precompiled, err := Compile("foo")
> if err != nil{
> // ... handle the error
> }
> result, err := precompiled.Search(data)
result = "bar"
```
## More Resources
The example above only show a small amount of what
a JMESPath expression can do. If you want to take a
tour of the language, the *best* place to go is the
[JMESPath Tutorial](http://jmespath.org/tutorial.html).
One of the best things about JMESPath is that it is
implemented in many different programming languages including
python, ruby, php, lua, etc. To see a complete list of libraries,
check out the [JMESPath libraries page](http://jmespath.org/libraries.html).
And finally, the full JMESPath specification can be found
on the [JMESPath site](http://jmespath.org/specification.html).

View file

@ -2,7 +2,7 @@ package jmespath
import "strconv"
// JMESPath is the epresentation of a compiled JMES path query. A JMESPath is
// JMESPath is the representation of a compiled JMES path query. A JMESPath is
// safe for concurrent use by multiple goroutines.
type JMESPath struct {
ast ASTNode

5
vendor/github.com/jmespath/go-jmespath/go.mod generated vendored Normal file
View file

@ -0,0 +1,5 @@
module github.com/jmespath/go-jmespath
go 1.14
require github.com/stretchr/testify v1.5.1

11
vendor/github.com/jmespath/go-jmespath/go.sum generated vendored Normal file
View file

@ -0,0 +1,11 @@
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View file

@ -137,7 +137,7 @@ func (p *Parser) Parse(expression string) (ASTNode, error) {
}
if p.current() != tEOF {
return ASTNode{}, p.syntaxError(fmt.Sprintf(
"Unexpected token at the end of the expresssion: %s", p.current()))
"Unexpected token at the end of the expression: %s", p.current()))
}
return parsed, nil
}

3
vendor/golang.org/x/exp/AUTHORS generated vendored
View file

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

View file

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

27
vendor/golang.org/x/exp/LICENSE generated vendored
View file

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

22
vendor/golang.org/x/exp/PATENTS generated vendored
View file

@ -1,22 +0,0 @@
Additional IP Rights Grant (Patents)
"This implementation" means the copyrightable works distributed by
Google as part of the Go project.
Google hereby grants to You a perpetual, worldwide, non-exclusive,
no-charge, royalty-free, irrevocable (except as stated in this section)
patent license to make, have made, use, offer to sell, sell, import,
transfer and otherwise run, modify and propagate the contents of this
implementation of Go, where such license applies only to those patent
claims, both currently owned or controlled by Google and acquired in
the future, licensable by Google that are necessarily infringed by this
implementation of Go. This grant does not include claims that would be
infringed only as a consequence of further modification of this
implementation. If you or your agent or exclusive licensee institute or
order or agree to the institution of patent litigation against any
entity (including a cross-claim or counterclaim in a lawsuit) alleging
that this implementation of Go or any code incorporated within this
implementation of Go constitutes direct or contributory patent
infringement, or inducement of patent infringement, then any patent
rights granted to you under this License for this implementation of Go
shall terminate as of the date such litigation is filed.

View file

@ -1,624 +0,0 @@
# Checking Go Package API Compatibility
The `apidiff` tool in this directory determines whether two versions of the same
package are compatible. The goal is to help the developer make an informed
choice of semantic version after they have changed the code of their module.
`apidiff` reports two kinds of changes: incompatible ones, which require
incrementing the major part of the semantic version, and compatible ones, which
require a minor version increment. If no API changes are reported but there are
code changes that could affect client code, then the patch version should
be incremented.
Because `apidiff` ignores package import paths, it may be used to display API
differences between any two packages, not just different versions of the same
package.
The current version of `apidiff` compares only packages, not modules.
## Compatibility Desiderata
Any tool that checks compatibility can offer only an approximation. No tool can
detect behavioral changes; and even if it could, whether a behavioral change is
a breaking change or not depends on many factors, such as whether it closes a
security hole or fixes a bug. Even a change that causes some code to fail to
compile may not be considered a breaking change by the developers or their
users. It may only affect code marked as experimental or unstable, for
example, or the break may only manifest in unlikely cases.
For a tool to be useful, its notion of compatibility must be relaxed enough to
allow reasonable changes, like adding a field to a struct, but strict enough to
catch significant breaking changes. A tool that is too lax will miss important
incompatibilities, and users will stop trusting it; one that is too strict may
generate so much noise that users will ignore it.
To a first approximation, this tool reports a change as incompatible if it could
cause client code to stop compiling. But `apidiff` ignores five ways in which
code may fail to compile after a change. Three of them are mentioned in the
[Go 1 Compatibility Guarantee](https://golang.org/doc/go1compat).
### Unkeyed Struct Literals
Code that uses an unkeyed struct literal would fail to compile if a field was
added to the struct, making any such addition an incompatible change. An example:
```
// old
type Point struct { X, Y int }
// new
type Point struct { X, Y, Z int }
// client
p := pkg.Point{1, 2} // fails in new because there are more fields than expressions
```
Here and below, we provide three snippets: the code in the old version of the
package, the code in the new version, and the code written in a client of the package,
which refers to it by the name `pkg`. The client code compiles against the old
code but not the new.
### Embedding and Shadowing
Adding an exported field to a struct can break code that embeds that struct,
because the newly added field may conflict with an identically named field
at the same struct depth. A selector referring to the latter would become
ambiguous and thus erroneous.
```
// old
type Point struct { X, Y int }
// new
type Point struct { X, Y, Z int }
// client
type z struct { Z int }
var v struct {
pkg.Point
z
}
_ = v.Z // fails in new
```
In the new version, the last line fails to compile because there are two embedded `Z`
fields at the same depth, one from `z` and one from `pkg.Point`.
### Using an Identical Type Externally
If it is possible for client code to write a type expression representing the
underlying type of a defined type in a package, then external code can use it in
assignments involving the package type, making any change to that type incompatible.
```
// old
type Point struct { X, Y int }
// new
type Point struct { X, Y, Z int }
// client
var p struct { X, Y int } = pkg.Point{} // fails in new because of Point's extra field
```
Here, the external code could have used the provided name `Point`, but chose not
to. I'll have more to say about this and related examples later.
### unsafe.Sizeof and Friends
Since `unsafe.Sizeof`, `unsafe.Offsetof` and `unsafe.Alignof` are constant
expressions, they can be used in an array type literal:
```
// old
type S struct{ X int }
// new
type S struct{ X, y int }
// client
var a [unsafe.Sizeof(pkg.S{})]int = [8]int{} // fails in new because S's size is not 8
```
Use of these operations could make many changes to a type potentially incompatible.
### Type Switches
A package change that merges two different types (with same underlying type)
into a single new type may break type switches in clients that refer to both
original types:
```
// old
type T1 int
type T2 int
// new
type T1 int
type T2 = T1
// client
switch x.(type) {
case T1:
case T2:
} // fails with new because two cases have the same type
```
This sort of incompatibility is sufficiently esoteric to ignore; the tool allows
merging types.
## First Attempt at a Definition
Our first attempt at defining compatibility captures the idea that all the
exported names in the old package must have compatible equivalents in the new
package.
A new package is compatible with an old one if and only if:
- For every exported package-level name in the old package, the same name is
declared in the new at package level, and
- the names denote the same kind of object (e.g. both are variables), and
- the types of the objects are compatible.
We will work out the details (and make some corrections) below, but it is clear
already that we will need to determine what makes two types compatible. And
whatever the definition of type compatibility, it's certainly true that if two
types are the same, they are compatible. So we will need to decide what makes an
old and new type the same. We will call this sameness relation _correspondence_.
## Type Correspondence
Go already has a definition of when two types are the same:
[type identity](https://golang.org/ref/spec#Type_identity).
But identity isn't adequate for our purpose: it says that two defined
types are identical if they arise from the same definition, but it's unclear
what "same" means when talking about two different packages (or two versions of
a single package).
The obvious change to the definition of identity is to require that old and new
[defined types](https://golang.org/ref/spec#Type_definitions)
have the same name instead. But that doesn't work either, for two
reasons. First, type aliases can equate two defined types with different names:
```
// old
type E int
// new
type t int
type E = t
```
Second, an unexported type can be renamed:
```
// old
type u1 int
var V u1
// new
type u2 int
var V u2
```
Here, even though `u1` and `u2` are unexported, their exported fields and
methods are visible to clients, so they are part of the API. But since the name
`u1` is not visible to clients, it can be changed compatibly. We say that `u1`
and `u2` are _exposed_: a type is exposed if a client package can declare variables of that type.
We will say that an old defined type _corresponds_ to a new one if they have the
same name, or one can be renamed to the other without otherwise changing the
API. In the first example above, old `E` and new `t` correspond. In the second,
old `u1` and new `u2` correspond.
Two or more old defined types can correspond to a single new type: we consider
"merging" two types into one to be a compatible change. As mentioned above,
code that uses both names in a type switch will fail, but we deliberately ignore
this case. However, a single old type can correspond to only one new type.
So far, we've explained what correspondence means for defined types. To extend
the definition to all types, we parallel the language's definition of type
identity. So, for instance, an old and a new slice type correspond if their
element types correspond.
## Definition of Compatibility
We can now present the definition of compatibility used by `apidiff`.
### Package Compatibility
> A new package is compatible with an old one if:
>1. Each exported name in the old package's scope also appears in the new
>package's scope, and the object (constant, variable, function or type) denoted
>by that name in the old package is compatible with the object denoted by the
>name in the new package, and
>2. For every exposed type that implements an exposed interface in the old package,
> its corresponding type should implement the corresponding interface in the new package.
>
>Otherwise the packages are incompatible.
As an aside, the tool also finds exported names in the new package that are not
exported in the old, and marks them as compatible changes.
Clause 2 is discussed further in "Whole-Package Compatibility."
### Object Compatibility
This section provides compatibility rules for constants, variables, functions
and types.
#### Constants
>A new exported constant is compatible with an old one of the same name if and only if
>1. Their types correspond, and
>2. Their values are identical.
It is tempting to allow changing a typed constant to an untyped one. That may
seem harmless, but it can break code like this:
```
// old
const C int64 = 1
// new
const C = 1
// client
var x = C // old type is int64, new is int
var y int64 = x // fails with new: different types in assignment
```
A change to the value of a constant can break compatibility if the value is used
in an array type:
```
// old
const C = 1
// new
const C = 2
// client
var a [C]int = [1]int{} // fails with new because [2]int and [1]int are different types
```
Changes to constant values are rare, and determining whether they are compatible
or not is better left to the user, so the tool reports them.
#### Variables
>A new exported variable is compatible with an old one of the same name if and
>only if their types correspond.
Correspondence doesn't look past names, so this rule does not prevent adding a
field to `MyStruct` if the package declares `var V MyStruct`. It does, however, mean that
```
var V struct { X int }
```
is incompatible with
```
var V struct { X, Y int }
```
I discuss this at length below in the section "Compatibility, Types and Names."
#### Functions
>A new exported function or variable is compatible with an old function of the
>same name if and only if their types (signatures) correspond.
This rule captures the fact that, although many signature changes are compatible
for all call sites, none are compatible for assignment:
```
var v func(int) = pkg.F
```
Here, `F` must be of type `func(int)` and not, for instance, `func(...int)` or `func(interface{})`.
Note that the rule permits changing a function to a variable. This is a common
practice, usually done for test stubbing, and cannot break any code at compile
time.
#### Exported Types
> A new exported type is compatible with an old one if and only if their
> names are the same and their types correspond.
This rule seems far too strict. But, ignoring aliases for the moment, it demands only
that the old and new _defined_ types correspond. Consider:
```
// old
type T struct { X int }
// new
type T struct { X, Y int }
```
The addition of `Y` is a compatible change, because this rule does not require
that the struct literals have to correspond, only that the defined types
denoted by `T` must correspond. (Remember that correspondence stops at type
names.)
If one type is an alias that refers to the corresponding defined type, the
situation is the same:
```
// old
type T struct { X int }
// new
type u struct { X, Y int }
type T = u
```
Here, the only requirement is that old `T` corresponds to new `u`, not that the
struct types correspond. (We can't tell from this snippet that the old `T` and
the new `u` do correspond; that depends on whether `u` replaces `T` throughout
the API.)
However, the following change is incompatible, because the names do not
denote corresponding types:
```
// old
type T = struct { X int }
// new
type T = struct { X, Y int }
```
### Type Literal Compatibility
Only five kinds of types can differ compatibly: defined types, structs,
interfaces, channels and numeric types. We only consider the compatibility of
the last four when they are the underlying type of a defined type. See
"Compatibility, Types and Names" for a rationale.
We justify the compatibility rules by enumerating all the ways a type
can be used, and by showing that the allowed changes cannot break any code that
uses values of the type in those ways.
Values of all types can be used in assignments (including argument passing and
function return), but we do not require that old and new types are assignment
compatible. That is because we assume that the old and new packages are never
used together: any given binary will link in either the old package or the new.
So in describing how a type can be used in the sections below, we omit
assignment.
Any type can also be used in a type assertion or conversion. The changes we allow
below may affect the run-time behavior of these operations, but they cannot affect
whether they compile. The only such breaking change would be to change
the type `T` in an assertion `x.T` so that it no longer implements the interface
type of `x`; but the rules for interfaces below disallow that.
> A new type is compatible with an old one if and only if they correspond, or
> one of the cases below applies.
#### Defined Types
Other than assignment, the only ways to use a defined type are to access its
methods, or to make use of the properties of its underlying type. Rule 2 below
covers the latter, and rules 3 and 4 cover the former.
> A new defined type is compatible with an old one if and only if all of the
> following hold:
>1. They correspond.
>2. Their underlying types are compatible.
>3. The new exported value method set is a superset of the old.
>4. The new exported pointer method set is a superset of the old.
An exported method set is a method set with all unexported methods removed.
When comparing methods of a method set, we require identical names and
corresponding signatures.
Removing an exported method is clearly a breaking change. But removing an
unexported one (or changing its signature) can be breaking as well, if it
results in the type no longer implementing an interface. See "Whole-Package
Compatibility," below.
#### Channels
> A new channel type is compatible with an old one if
> 1. The element types correspond, and
> 2. Either the directions are the same, or the new type has no direction.
Other than assignment, the only ways to use values of a channel type are to send
and receive on them, to close them, and to use them as map keys. Changes to a
channel type cannot cause code that closes a channel or uses it as a map key to
fail to compile, so we need not consider those operations.
Rule 1 ensures that any operations on the values sent or received will compile.
Rule 2 captures the fact that any program that compiles with a directed channel
must use either only sends, or only receives, so allowing the other operation
by removing the channel direction cannot break any code.
#### Interfaces
> A new interface is compatible with an old one if and only if:
> 1. The old interface does not have an unexported method, and it corresponds
> to the new interfaces (i.e. they have the same method set), or
> 2. The old interface has an unexported method and the new exported method set is a
> superset of the old.
Other than assignment, the only ways to use an interface are to implement it,
embed it, or call one of its methods. (Interface values can also be used as map
keys, but that cannot cause a compile-time error.)
Certainly, removing an exported method from an interface could break a client
call, so neither rule allows it.
Rule 1 also disallows adding a method to an interface without an existing unexported
method. Such an interface can be implemented in client code. If adding a method
were allowed, a type that implements the old interface could fail to implement
the new one:
```
type I interface { M1() } // old
type I interface { M1(); M2() } // new
// client
type t struct{}
func (t) M1() {}
var i pkg.I = t{} // fails with new, because t lacks M2
```
Rule 2 is based on the observation that if an interface has an unexported
method, the only way a client can implement it is to embed it.
Adding a method is compatible in this case, because the embedding struct will
continue to implement the interface. Adding a method also cannot break any call
sites, since no program that compiles could have any such call sites.
#### Structs
> A new struct is compatible with an old one if all of the following hold:
> 1. The new set of top-level exported fields is a superset of the old.
> 2. The new set of _selectable_ exported fields is a superset of the old.
> 3. If the old struct is comparable, so is the new one.
The set of selectable exported fields is the set of exported fields `F`
such that `x.F` is a valid selector expression for a value `x` of the struct
type. `F` may be at the top level of the struct, or it may be a field of an
embedded struct.
Two fields are the same if they have the same name and corresponding types.
Other than assignment, there are only four ways to use a struct: write a struct
literal, select a field, use a value of the struct as a map key, or compare two
values for equality. The first clause ensures that struct literals compile; the
second, that selections compile; and the third, that equality expressions and
map index expressions compile.
#### Numeric Types
> A new numeric type is compatible with an old one if and only if they are
> both unsigned integers, both signed integers, both floats or both complex
> types, and the new one is at least as large as the old on both 32-bit and
> 64-bit architectures.
Other than in assignments, numeric types appear in arithmetic and comparison
expressions. Since all arithmetic operations but shifts (see below) require that
operand types be identical, and by assumption the old and new types underly
defined types (see "Compatibility, Types and Names," below), there is no way for
client code to write an arithmetic expression that compiles with operands of the
old type but not the new.
Numeric types can also appear in type switches and type assertions. Again, since
the old and new types underly defined types, type switches and type assertions
that compiled using the old defined type will continue to compile with the new
defined type.
Going from an unsigned to a signed integer type is an incompatible change for
the sole reason that only an unsigned type can appear as the right operand of a
shift. If this rule is relaxed, then changes from an unsigned type to a larger
signed type would be compatible. See [this
issue](https://github.com/golang/go/issues/19113).
Only integer types can be used in bitwise and shift operations, and for indexing
slices and arrays. That is why switching from an integer to a floating-point
type--even one that can represent all values of the integer type--is an
incompatible change.
Conversions from floating-point to complex types or vice versa are not permitted
(the predeclared functions real, imag, and complex must be used instead). To
prevent valid floating-point or complex conversions from becoming invalid,
changing a floating-point type to a complex type or vice versa is considered an
incompatible change.
Although conversions between any two integer types are valid, assigning a
constant value to a variable of integer type that is too small to represent the
constant is not permitted. That is why the only compatible changes are to
a new type whose values are a superset of the old. The requirement that the new
set of values must include the old on both 32-bit and 64-bit machines allows
conversions from `int32` to `int` and from `int` to `int64`, but not the other
direction; and similarly for `uint`.
Changing a type to or from `uintptr` is considered an incompatible change. Since
its size is not specified, there is no way to know whether the new type's values
are a superset of the old type's.
## Whole-Package Compatibility
Some changes that are compatible for a single type are not compatible when the
package is considered as a whole. For example, if you remove an unexported
method on a defined type, it may no longer implement an interface of the
package. This can break client code:
```
// old
type T int
func (T) m() {}
type I interface { m() }
// new
type T int // no method m anymore
// client
var i pkg.I = pkg.T{} // fails with new because T lacks m
```
Similarly, adding a method to an interface can cause defined types
in the package to stop implementing it.
The second clause in the definition for package compatibility handles these
cases. To repeat:
> 2. For every exposed type that implements an exposed interface in the old package,
> its corresponding type should implement the corresponding interface in the new package.
Recall that a type is exposed if it is part of the package's API, even if it is
unexported.
Other incompatibilities that involve more than one type in the package can arise
whenever two types with identical underlying types exist in the old or new
package. Here, a change "splits" an identical underlying type into two, breaking
conversions:
```
// old
type B struct { X int }
type C struct { X int }
// new
type B struct { X int }
type C struct { X, Y int }
// client
var b B
_ = C(b) // fails with new: cannot convert B to C
```
Finally, changes that are compatible for the package in which they occur can
break downstream packages. That can happen even if they involve unexported
methods, thanks to embedding.
The definitions given here don't account for these sorts of problems.
## Compatibility, Types and Names
The above definitions state that the only types that can differ compatibly are
defined types and the types that underly them. Changes to other type literals
are considered incompatible. For instance, it is considered an incompatible
change to add a field to the struct in this variable declaration:
```
var V struct { X int }
```
or this alias definition:
```
type T = struct { X int }
```
We make this choice to keep the definition of compatibility (relatively) simple.
A more precise definition could, for instance, distinguish between
```
func F(struct { X int })
```
where any changes to the struct are incompatible, and
```
func F(struct { X, u int })
```
where adding a field is compatible (since clients cannot write the signature,
and thus cannot assign `F` to a variable of the signature type). The definition
should then also allow other function signature changes that only require
call-site compatibility, like
```
func F(struct { X, u int }, ...int)
```
The result would be a much more complex definition with little benefit, since
the examples in this section rarely arise in practice.

View file

@ -1,220 +0,0 @@
// TODO: test swap corresponding types (e.g. u1 <-> u2 and u2 <-> u1)
// TODO: test exported alias refers to something in another package -- does correspondence work then?
// TODO: CODE COVERAGE
// TODO: note that we may miss correspondences because we bail early when we compare a signature (e.g. when lengths differ; we could do up to the shorter)
// TODO: if you add an unexported method to an exposed interface, you have to check that
// every exposed type that previously implemented the interface still does. Otherwise
// an external assignment of the exposed type to the interface type could fail.
// TODO: check constant values: large values aren't representable by some types.
// TODO: Document all the incompatibilities we don't check for.
package apidiff
import (
"fmt"
"go/constant"
"go/token"
"go/types"
)
// Changes reports on the differences between the APIs of the old and new packages.
// It classifies each difference as either compatible or incompatible (breaking.) For
// a detailed discussion of what constitutes an incompatible change, see the package
// documentation.
func Changes(old, new *types.Package) Report {
d := newDiffer(old, new)
d.checkPackage()
r := Report{}
for _, m := range d.incompatibles.collect() {
r.Changes = append(r.Changes, Change{Message: m, Compatible: false})
}
for _, m := range d.compatibles.collect() {
r.Changes = append(r.Changes, Change{Message: m, Compatible: true})
}
return r
}
type differ struct {
old, new *types.Package
// Correspondences between named types.
// Even though it is the named types (*types.Named) that correspond, we use
// *types.TypeName as a map key because they are canonical.
// The values can be either named types or basic types.
correspondMap map[*types.TypeName]types.Type
// Messages.
incompatibles messageSet
compatibles messageSet
}
func newDiffer(old, new *types.Package) *differ {
return &differ{
old: old,
new: new,
correspondMap: map[*types.TypeName]types.Type{},
incompatibles: messageSet{},
compatibles: messageSet{},
}
}
func (d *differ) incompatible(obj types.Object, part, format string, args ...interface{}) {
addMessage(d.incompatibles, obj, part, format, args)
}
func (d *differ) compatible(obj types.Object, part, format string, args ...interface{}) {
addMessage(d.compatibles, obj, part, format, args)
}
func addMessage(ms messageSet, obj types.Object, part, format string, args []interface{}) {
ms.add(obj, part, fmt.Sprintf(format, args...))
}
func (d *differ) checkPackage() {
// Old changes.
for _, name := range d.old.Scope().Names() {
oldobj := d.old.Scope().Lookup(name)
if !oldobj.Exported() {
continue
}
newobj := d.new.Scope().Lookup(name)
if newobj == nil {
d.incompatible(oldobj, "", "removed")
continue
}
d.checkObjects(oldobj, newobj)
}
// New additions.
for _, name := range d.new.Scope().Names() {
newobj := d.new.Scope().Lookup(name)
if newobj.Exported() && d.old.Scope().Lookup(name) == nil {
d.compatible(newobj, "", "added")
}
}
// Whole-package satisfaction.
// For every old exposed interface oIface and its corresponding new interface nIface...
for otn1, nt1 := range d.correspondMap {
oIface, ok := otn1.Type().Underlying().(*types.Interface)
if !ok {
continue
}
nIface, ok := nt1.Underlying().(*types.Interface)
if !ok {
// If nt1 isn't an interface but otn1 is, then that's an incompatibility that
// we've already noticed, so there's no need to do anything here.
continue
}
// For every old type that implements oIface, its corresponding new type must implement
// nIface.
for otn2, nt2 := range d.correspondMap {
if otn1 == otn2 {
continue
}
if types.Implements(otn2.Type(), oIface) && !types.Implements(nt2, nIface) {
d.incompatible(otn2, "", "no longer implements %s", objectString(otn1))
}
}
}
}
func (d *differ) checkObjects(old, new types.Object) {
switch old := old.(type) {
case *types.Const:
if new, ok := new.(*types.Const); ok {
d.constChanges(old, new)
return
}
case *types.Var:
if new, ok := new.(*types.Var); ok {
d.checkCorrespondence(old, "", old.Type(), new.Type())
return
}
case *types.Func:
switch new := new.(type) {
case *types.Func:
d.checkCorrespondence(old, "", old.Type(), new.Type())
return
case *types.Var:
d.compatible(old, "", "changed from func to var")
d.checkCorrespondence(old, "", old.Type(), new.Type())
return
}
case *types.TypeName:
if new, ok := new.(*types.TypeName); ok {
d.checkCorrespondence(old, "", old.Type(), new.Type())
return
}
default:
panic("unexpected obj type")
}
// Here if kind of type changed.
d.incompatible(old, "", "changed from %s to %s",
objectKindString(old), objectKindString(new))
}
// Compare two constants.
func (d *differ) constChanges(old, new *types.Const) {
ot := old.Type()
nt := new.Type()
// Check for change of type.
if !d.correspond(ot, nt) {
d.typeChanged(old, "", ot, nt)
return
}
// Check for change of value.
// We know the types are the same, so constant.Compare shouldn't panic.
if !constant.Compare(old.Val(), token.EQL, new.Val()) {
d.incompatible(old, "", "value changed from %s to %s", old.Val(), new.Val())
}
}
func objectKindString(obj types.Object) string {
switch obj.(type) {
case *types.Const:
return "const"
case *types.Var:
return "var"
case *types.Func:
return "func"
case *types.TypeName:
return "type"
default:
return "???"
}
}
func (d *differ) checkCorrespondence(obj types.Object, part string, old, new types.Type) {
if !d.correspond(old, new) {
d.typeChanged(obj, part, old, new)
}
}
func (d *differ) typeChanged(obj types.Object, part string, old, new types.Type) {
old = removeNamesFromSignature(old)
new = removeNamesFromSignature(new)
olds := types.TypeString(old, types.RelativeTo(d.old))
news := types.TypeString(new, types.RelativeTo(d.new))
d.incompatible(obj, part, "changed from %s to %s", olds, news)
}
// go/types always includes the argument and result names when formatting a signature.
// Since these can change without affecting compatibility, we don't want users to
// be distracted by them, so we remove them.
func removeNamesFromSignature(t types.Type) types.Type {
sig, ok := t.(*types.Signature)
if !ok {
return t
}
dename := func(p *types.Tuple) *types.Tuple {
var vars []*types.Var
for i := 0; i < p.Len(); i++ {
v := p.At(i)
vars = append(vars, types.NewVar(v.Pos(), v.Pkg(), "", v.Type()))
}
return types.NewTuple(vars...)
}
return types.NewSignature(sig.Recv(), dename(sig.Params()), dename(sig.Results()), sig.Variadic())
}

View file

@ -1,361 +0,0 @@
package apidiff
import (
"fmt"
"go/types"
"reflect"
)
func (d *differ) checkCompatible(otn *types.TypeName, old, new types.Type) {
switch old := old.(type) {
case *types.Interface:
if new, ok := new.(*types.Interface); ok {
d.checkCompatibleInterface(otn, old, new)
return
}
case *types.Struct:
if new, ok := new.(*types.Struct); ok {
d.checkCompatibleStruct(otn, old, new)
return
}
case *types.Chan:
if new, ok := new.(*types.Chan); ok {
d.checkCompatibleChan(otn, old, new)
return
}
case *types.Basic:
if new, ok := new.(*types.Basic); ok {
d.checkCompatibleBasic(otn, old, new)
return
}
case *types.Named:
panic("unreachable")
default:
d.checkCorrespondence(otn, "", old, new)
return
}
// Here if old and new are different kinds of types.
d.typeChanged(otn, "", old, new)
}
func (d *differ) checkCompatibleChan(otn *types.TypeName, old, new *types.Chan) {
d.checkCorrespondence(otn, ", element type", old.Elem(), new.Elem())
if old.Dir() != new.Dir() {
if new.Dir() == types.SendRecv {
d.compatible(otn, "", "removed direction")
} else {
d.incompatible(otn, "", "changed direction")
}
}
}
func (d *differ) checkCompatibleBasic(otn *types.TypeName, old, new *types.Basic) {
// Certain changes to numeric types are compatible. Approximately, the info must
// be the same, and the new values must be a superset of the old.
if old.Kind() == new.Kind() {
// old and new are identical
return
}
if compatibleBasics[[2]types.BasicKind{old.Kind(), new.Kind()}] {
d.compatible(otn, "", "changed from %s to %s", old, new)
} else {
d.typeChanged(otn, "", old, new)
}
}
// All pairs (old, new) of compatible basic types.
var compatibleBasics = map[[2]types.BasicKind]bool{
{types.Uint8, types.Uint16}: true,
{types.Uint8, types.Uint32}: true,
{types.Uint8, types.Uint}: true,
{types.Uint8, types.Uint64}: true,
{types.Uint16, types.Uint32}: true,
{types.Uint16, types.Uint}: true,
{types.Uint16, types.Uint64}: true,
{types.Uint32, types.Uint}: true,
{types.Uint32, types.Uint64}: true,
{types.Uint, types.Uint64}: true,
{types.Int8, types.Int16}: true,
{types.Int8, types.Int32}: true,
{types.Int8, types.Int}: true,
{types.Int8, types.Int64}: true,
{types.Int16, types.Int32}: true,
{types.Int16, types.Int}: true,
{types.Int16, types.Int64}: true,
{types.Int32, types.Int}: true,
{types.Int32, types.Int64}: true,
{types.Int, types.Int64}: true,
{types.Float32, types.Float64}: true,
{types.Complex64, types.Complex128}: true,
}
// Interface compatibility:
// If the old interface has an unexported method, the new interface is compatible
// if its exported method set is a superset of the old. (Users could not implement,
// only embed.)
//
// If the old interface did not have an unexported method, the new interface is
// compatible if its exported method set is the same as the old, and it has no
// unexported methods. (Adding an unexported method makes the interface
// unimplementable outside the package.)
//
// TODO: must also check that if any methods were added or removed, every exposed
// type in the package that implemented the interface in old still implements it in
// new. Otherwise external assignments could fail.
func (d *differ) checkCompatibleInterface(otn *types.TypeName, old, new *types.Interface) {
// Method sets are checked in checkCompatibleDefined.
// Does the old interface have an unexported method?
if unexportedMethod(old) != nil {
d.checkMethodSet(otn, old, new, additionsCompatible)
} else {
// Perform an equivalence check, but with more information.
d.checkMethodSet(otn, old, new, additionsIncompatible)
if u := unexportedMethod(new); u != nil {
d.incompatible(otn, u.Name(), "added unexported method")
}
}
}
// Return an unexported method from the method set of t, or nil if there are none.
func unexportedMethod(t *types.Interface) *types.Func {
for i := 0; i < t.NumMethods(); i++ {
if m := t.Method(i); !m.Exported() {
return m
}
}
return nil
}
// We need to check three things for structs:
// 1. The set of exported fields must be compatible. This ensures that keyed struct
// literals continue to compile. (There is no compatibility guarantee for unkeyed
// struct literals.)
// 2. The set of exported *selectable* fields must be compatible. This includes the exported
// fields of all embedded structs. This ensures that selections continue to compile.
// 3. If the old struct is comparable, so must the new one be. This ensures that equality
// expressions and uses of struct values as map keys continue to compile.
//
// An unexported embedded struct can't appear in a struct literal outside the
// package, so it doesn't have to be present, or have the same name, in the new
// struct.
//
// Field tags are ignored: they have no compile-time implications.
func (d *differ) checkCompatibleStruct(obj types.Object, old, new *types.Struct) {
d.checkCompatibleObjectSets(obj, exportedFields(old), exportedFields(new))
d.checkCompatibleObjectSets(obj, exportedSelectableFields(old), exportedSelectableFields(new))
// Removing comparability from a struct is an incompatible change.
if types.Comparable(old) && !types.Comparable(new) {
d.incompatible(obj, "", "old is comparable, new is not")
}
}
// exportedFields collects all the immediate fields of the struct that are exported.
// This is also the set of exported keys for keyed struct literals.
func exportedFields(s *types.Struct) map[string]types.Object {
m := map[string]types.Object{}
for i := 0; i < s.NumFields(); i++ {
f := s.Field(i)
if f.Exported() {
m[f.Name()] = f
}
}
return m
}
// exportedSelectableFields collects all the exported fields of the struct, including
// exported fields of embedded structs.
//
// We traverse the struct breadth-first, because of the rule that a lower-depth field
// shadows one at a higher depth.
func exportedSelectableFields(s *types.Struct) map[string]types.Object {
var (
m = map[string]types.Object{}
next []*types.Struct // embedded structs at the next depth
seen []*types.Struct // to handle recursive embedding
)
for cur := []*types.Struct{s}; len(cur) > 0; cur, next = next, nil {
seen = append(seen, cur...)
// We only want to consider unambiguous fields. Ambiguous fields (where there
// is more than one field of the same name at the same level) are legal, but
// cannot be selected.
for name, f := range unambiguousFields(cur) {
// Record an exported field we haven't seen before. If we have seen it,
// it occurred a lower depth, so it shadows this field.
if f.Exported() && m[name] == nil {
m[name] = f
}
// Remember embedded structs for processing at the next depth,
// but only if we haven't seen the struct at this depth or above.
if !f.Anonymous() {
continue
}
t := f.Type().Underlying()
if p, ok := t.(*types.Pointer); ok {
t = p.Elem().Underlying()
}
if t, ok := t.(*types.Struct); ok && !contains(seen, t) {
next = append(next, t)
}
}
}
return m
}
func contains(ts []*types.Struct, t *types.Struct) bool {
for _, s := range ts {
if types.Identical(s, t) {
return true
}
}
return false
}
// Given a set of structs at the same depth, the unambiguous fields are the ones whose
// names appear exactly once.
func unambiguousFields(structs []*types.Struct) map[string]*types.Var {
fields := map[string]*types.Var{}
seen := map[string]bool{}
for _, s := range structs {
for i := 0; i < s.NumFields(); i++ {
f := s.Field(i)
name := f.Name()
if seen[name] {
delete(fields, name)
} else {
seen[name] = true
fields[name] = f
}
}
}
return fields
}
// Anything removed or change from the old set is an incompatible change.
// Anything added to the new set is a compatible change.
func (d *differ) checkCompatibleObjectSets(obj types.Object, old, new map[string]types.Object) {
for name, oldo := range old {
newo := new[name]
if newo == nil {
d.incompatible(obj, name, "removed")
} else {
d.checkCorrespondence(obj, name, oldo.Type(), newo.Type())
}
}
for name := range new {
if old[name] == nil {
d.compatible(obj, name, "added")
}
}
}
func (d *differ) checkCompatibleDefined(otn *types.TypeName, old *types.Named, new types.Type) {
// We've already checked that old and new correspond.
d.checkCompatible(otn, old.Underlying(), new.Underlying())
// If there are different kinds of types (e.g. struct and interface), don't bother checking
// the method sets.
if reflect.TypeOf(old.Underlying()) != reflect.TypeOf(new.Underlying()) {
return
}
// Interface method sets are checked in checkCompatibleInterface.
if _, ok := old.Underlying().(*types.Interface); ok {
return
}
// A new method set is compatible with an old if the new exported methods are a superset of the old.
d.checkMethodSet(otn, old, new, additionsCompatible)
d.checkMethodSet(otn, types.NewPointer(old), types.NewPointer(new), additionsCompatible)
}
const (
additionsCompatible = true
additionsIncompatible = false
)
func (d *differ) checkMethodSet(otn *types.TypeName, oldt, newt types.Type, addcompat bool) {
// TODO: find a way to use checkCompatibleObjectSets for this.
oldMethodSet := exportedMethods(oldt)
newMethodSet := exportedMethods(newt)
msname := otn.Name()
if _, ok := oldt.(*types.Pointer); ok {
msname = "*" + msname
}
for name, oldMethod := range oldMethodSet {
newMethod := newMethodSet[name]
if newMethod == nil {
var part string
// Due to embedding, it's possible that the method's receiver type is not
// the same as the defined type whose method set we're looking at. So for
// a type T with removed method M that is embedded in some other type U,
// we will generate two "removed" messages for T.M, one for its own type
// T and one for the embedded type U. We want both messages to appear,
// but the messageSet dedup logic will allow only one message for a given
// object. So use the part string to distinguish them.
if receiverNamedType(oldMethod).Obj() != otn {
part = fmt.Sprintf(", method set of %s", msname)
}
d.incompatible(oldMethod, part, "removed")
} else {
obj := oldMethod
// If a value method is changed to a pointer method and has a signature
// change, then we can get two messages for the same method definition: one
// for the value method set that says it's removed, and another for the
// pointer method set that says it changed. To keep both messages (since
// messageSet dedups), use newMethod for the second. (Slight hack.)
if !hasPointerReceiver(oldMethod) && hasPointerReceiver(newMethod) {
obj = newMethod
}
d.checkCorrespondence(obj, "", oldMethod.Type(), newMethod.Type())
}
}
// Check for added methods.
for name, newMethod := range newMethodSet {
if oldMethodSet[name] == nil {
if addcompat {
d.compatible(newMethod, "", "added")
} else {
d.incompatible(newMethod, "", "added")
}
}
}
}
// exportedMethods collects all the exported methods of type's method set.
func exportedMethods(t types.Type) map[string]types.Object {
m := map[string]types.Object{}
ms := types.NewMethodSet(t)
for i := 0; i < ms.Len(); i++ {
obj := ms.At(i).Obj()
if obj.Exported() {
m[obj.Name()] = obj
}
}
return m
}
func receiverType(method types.Object) types.Type {
return method.Type().(*types.Signature).Recv().Type()
}
func receiverNamedType(method types.Object) *types.Named {
switch t := receiverType(method).(type) {
case *types.Pointer:
return t.Elem().(*types.Named)
case *types.Named:
return t
default:
panic("unreachable")
}
}
func hasPointerReceiver(method types.Object) bool {
_, ok := receiverType(method).(*types.Pointer)
return ok
}

View file

@ -1,219 +0,0 @@
package apidiff
import (
"go/types"
"sort"
)
// Two types are correspond if they are identical except for defined types,
// which must correspond.
//
// Two defined types correspond if they can be interchanged in the old and new APIs,
// possibly after a renaming.
//
// This is not a pure function. If we come across named types while traversing,
// we establish correspondence.
func (d *differ) correspond(old, new types.Type) bool {
return d.corr(old, new, nil)
}
// corr determines whether old and new correspond. The argument p is a list of
// known interface identities, to avoid infinite recursion.
//
// corr calls itself recursively as much as possible, to establish more
// correspondences and so check more of the API. E.g. if the new function has more
// parameters than the old, compare all the old ones before returning false.
//
// Compare this to the implementation of go/types.Identical.
func (d *differ) corr(old, new types.Type, p *ifacePair) bool {
// Structure copied from types.Identical.
switch old := old.(type) {
case *types.Basic:
return types.Identical(old, new)
case *types.Array:
if new, ok := new.(*types.Array); ok {
return d.corr(old.Elem(), new.Elem(), p) && old.Len() == new.Len()
}
case *types.Slice:
if new, ok := new.(*types.Slice); ok {
return d.corr(old.Elem(), new.Elem(), p)
}
case *types.Map:
if new, ok := new.(*types.Map); ok {
return d.corr(old.Key(), new.Key(), p) && d.corr(old.Elem(), new.Elem(), p)
}
case *types.Chan:
if new, ok := new.(*types.Chan); ok {
return d.corr(old.Elem(), new.Elem(), p) && old.Dir() == new.Dir()
}
case *types.Pointer:
if new, ok := new.(*types.Pointer); ok {
return d.corr(old.Elem(), new.Elem(), p)
}
case *types.Signature:
if new, ok := new.(*types.Signature); ok {
pe := d.corr(old.Params(), new.Params(), p)
re := d.corr(old.Results(), new.Results(), p)
return old.Variadic() == new.Variadic() && pe && re
}
case *types.Tuple:
if new, ok := new.(*types.Tuple); ok {
for i := 0; i < old.Len(); i++ {
if i >= new.Len() || !d.corr(old.At(i).Type(), new.At(i).Type(), p) {
return false
}
}
return old.Len() == new.Len()
}
case *types.Struct:
if new, ok := new.(*types.Struct); ok {
for i := 0; i < old.NumFields(); i++ {
if i >= new.NumFields() {
return false
}
of := old.Field(i)
nf := new.Field(i)
if of.Anonymous() != nf.Anonymous() ||
old.Tag(i) != new.Tag(i) ||
!d.corr(of.Type(), nf.Type(), p) ||
!d.corrFieldNames(of, nf) {
return false
}
}
return old.NumFields() == new.NumFields()
}
case *types.Interface:
if new, ok := new.(*types.Interface); ok {
// Deal with circularity. See the comment in types.Identical.
q := &ifacePair{old, new, p}
for p != nil {
if p.identical(q) {
return true // same pair was compared before
}
p = p.prev
}
oldms := d.sortedMethods(old)
newms := d.sortedMethods(new)
for i, om := range oldms {
if i >= len(newms) {
return false
}
nm := newms[i]
if d.methodID(om) != d.methodID(nm) || !d.corr(om.Type(), nm.Type(), q) {
return false
}
}
return old.NumMethods() == new.NumMethods()
}
case *types.Named:
if new, ok := new.(*types.Named); ok {
return d.establishCorrespondence(old, new)
}
if new, ok := new.(*types.Basic); ok {
// Basic types are defined types, too, so we have to support them.
return d.establishCorrespondence(old, new)
}
default:
panic("unknown type kind")
}
return false
}
// Compare old and new field names. We are determining correspondence across packages,
// so just compare names, not packages. For an unexported, embedded field of named
// type (non-named embedded fields are possible with aliases), we check that the type
// names correspond. We check the types for correspondence before this is called, so
// we've established correspondence.
func (d *differ) corrFieldNames(of, nf *types.Var) bool {
if of.Anonymous() && nf.Anonymous() && !of.Exported() && !nf.Exported() {
if on, ok := of.Type().(*types.Named); ok {
nn := nf.Type().(*types.Named)
return d.establishCorrespondence(on, nn)
}
}
return of.Name() == nf.Name()
}
// Establish that old corresponds with new if it does not already
// correspond to something else.
func (d *differ) establishCorrespondence(old *types.Named, new types.Type) bool {
oldname := old.Obj()
oldc := d.correspondMap[oldname]
if oldc == nil {
// For now, assume the types don't correspond unless they are from the old
// and new packages, respectively.
//
// This is too conservative. For instance,
// [old] type A = q.B; [new] type A q.C
// could be OK if in package q, B is an alias for C.
// Or, using p as the name of the current old/new packages:
// [old] type A = q.B; [new] type A int
// could be OK if in q,
// [old] type B int; [new] type B = p.A
// In this case, p.A and q.B name the same type in both old and new worlds.
// Note that this case doesn't imply circular package imports: it's possible
// that in the old world, p imports q, but in the new, q imports p.
//
// However, if we didn't do something here, then we'd incorrectly allow cases
// like the first one above in which q.B is not an alias for q.C
//
// What we should do is check that the old type, in the new world's package
// of the same path, doesn't correspond to something other than the new type.
// That is a bit hard, because there is no easy way to find a new package
// matching an old one.
if newn, ok := new.(*types.Named); ok {
if old.Obj().Pkg() != d.old || newn.Obj().Pkg() != d.new {
return old.Obj().Id() == newn.Obj().Id()
}
}
// If there is no correspondence, create one.
d.correspondMap[oldname] = new
// Check that the corresponding types are compatible.
d.checkCompatibleDefined(oldname, old, new)
return true
}
return types.Identical(oldc, new)
}
func (d *differ) sortedMethods(iface *types.Interface) []*types.Func {
ms := make([]*types.Func, iface.NumMethods())
for i := 0; i < iface.NumMethods(); i++ {
ms[i] = iface.Method(i)
}
sort.Slice(ms, func(i, j int) bool { return d.methodID(ms[i]) < d.methodID(ms[j]) })
return ms
}
func (d *differ) methodID(m *types.Func) string {
// If the method belongs to one of the two packages being compared, use
// just its name even if it's unexported. That lets us treat unexported names
// from the old and new packages as equal.
if m.Pkg() == d.old || m.Pkg() == d.new {
return m.Name()
}
return m.Id()
}
// Copied from the go/types package:
// An ifacePair is a node in a stack of interface type pairs compared for identity.
type ifacePair struct {
x, y *types.Interface
prev *ifacePair
}
func (p *ifacePair) identical(q *ifacePair) bool {
return p.x == q.x && p.y == q.y || p.x == q.y && p.y == q.x
}

View file

@ -1,79 +0,0 @@
// TODO: show that two-non-empty dotjoin can happen, by using an anon struct as a field type
// TODO: don't report removed/changed methods for both value and pointer method sets?
package apidiff
import (
"fmt"
"go/types"
"sort"
"strings"
)
// There can be at most one message for each object or part thereof.
// Parts include interface methods and struct fields.
//
// The part thing is necessary. Method (Func) objects have sufficient info, but field
// Vars do not: they just have a field name and a type, without the enclosing struct.
type messageSet map[types.Object]map[string]string
// Add a message for obj and part, overwriting a previous message
// (shouldn't happen).
// obj is required but part can be empty.
func (m messageSet) add(obj types.Object, part, msg string) {
s := m[obj]
if s == nil {
s = map[string]string{}
m[obj] = s
}
if f, ok := s[part]; ok && f != msg {
fmt.Printf("! second, different message for obj %s, part %q\n", obj, part)
fmt.Printf(" first: %s\n", f)
fmt.Printf(" second: %s\n", msg)
}
s[part] = msg
}
func (m messageSet) collect() []string {
var s []string
for obj, parts := range m {
// Format each object name relative to its own package.
objstring := objectString(obj)
for part, msg := range parts {
var p string
if strings.HasPrefix(part, ",") {
p = objstring + part
} else {
p = dotjoin(objstring, part)
}
s = append(s, p+": "+msg)
}
}
sort.Strings(s)
return s
}
func objectString(obj types.Object) string {
if f, ok := obj.(*types.Func); ok {
sig := f.Type().(*types.Signature)
if recv := sig.Recv(); recv != nil {
tn := types.TypeString(recv.Type(), types.RelativeTo(obj.Pkg()))
if tn[0] == '*' {
tn = "(" + tn + ")"
}
return fmt.Sprintf("%s.%s", tn, obj.Name())
}
}
return obj.Name()
}
func dotjoin(s1, s2 string) string {
if s1 == "" {
return s2
}
if s2 == "" {
return s1
}
return s1 + "." + s2
}

View file

@ -1,71 +0,0 @@
package apidiff
import (
"bytes"
"fmt"
"io"
)
// Report describes the changes detected by Changes.
type Report struct {
Changes []Change
}
// A Change describes a single API change.
type Change struct {
Message string
Compatible bool
}
func (r Report) messages(compatible bool) []string {
var msgs []string
for _, c := range r.Changes {
if c.Compatible == compatible {
msgs = append(msgs, c.Message)
}
}
return msgs
}
func (r Report) String() string {
var buf bytes.Buffer
if err := r.Text(&buf); err != nil {
return fmt.Sprintf("!!%v", err)
}
return buf.String()
}
func (r Report) Text(w io.Writer) error {
if err := r.TextIncompatible(w, true); err != nil {
return err
}
return r.TextCompatible(w)
}
func (r Report) TextIncompatible(w io.Writer, withHeader bool) error {
if withHeader {
return r.writeMessages(w, "Incompatible changes:", r.messages(false))
}
return r.writeMessages(w, "", r.messages(false))
}
func (r Report) TextCompatible(w io.Writer) error {
return r.writeMessages(w, "Compatible changes:", r.messages(true))
}
func (r Report) writeMessages(w io.Writer, header string, msgs []string) error {
if len(msgs) == 0 {
return nil
}
if header != "" {
if _, err := fmt.Fprintf(w, "%s\n", header); err != nil {
return err
}
}
for _, m := range msgs {
if _, err := fmt.Fprintf(w, "- %s\n", m); err != nil {
return err
}
}
return nil
}

View file

@ -1,142 +0,0 @@
// Command apidiff determines whether two versions of a package are compatible
package main
import (
"bufio"
"flag"
"fmt"
"go/token"
"go/types"
"os"
"golang.org/x/exp/apidiff"
"golang.org/x/tools/go/gcexportdata"
"golang.org/x/tools/go/packages"
)
var (
exportDataOutfile = flag.String("w", "", "file for export data")
incompatibleOnly = flag.Bool("incompatible", false, "display only incompatible changes")
)
func main() {
flag.Usage = func() {
w := flag.CommandLine.Output()
fmt.Fprintf(w, "usage:\n")
fmt.Fprintf(w, "apidiff OLD NEW\n")
fmt.Fprintf(w, " compares OLD and NEW package APIs\n")
fmt.Fprintf(w, " where OLD and NEW are either import paths or files of export data\n")
fmt.Fprintf(w, "apidiff -w FILE IMPORT_PATH\n")
fmt.Fprintf(w, " writes export data of the package at IMPORT_PATH to FILE\n")
fmt.Fprintf(w, " NOTE: In a GOPATH-less environment, this option consults the\n")
fmt.Fprintf(w, " module cache by default, unless used in the directory that\n")
fmt.Fprintf(w, " contains the go.mod module definition that IMPORT_PATH belongs\n")
fmt.Fprintf(w, " to. In most cases users want the latter behavior, so be sure\n")
fmt.Fprintf(w, " to cd to the exact directory which contains the module\n")
fmt.Fprintf(w, " definition of IMPORT_PATH.\n")
flag.PrintDefaults()
}
flag.Parse()
if *exportDataOutfile != "" {
if len(flag.Args()) != 1 {
flag.Usage()
os.Exit(2)
}
pkg := mustLoadPackage(flag.Arg(0))
if err := writeExportData(pkg, *exportDataOutfile); err != nil {
die("writing export data: %v", err)
}
} else {
if len(flag.Args()) != 2 {
flag.Usage()
os.Exit(2)
}
oldpkg := mustLoadOrRead(flag.Arg(0))
newpkg := mustLoadOrRead(flag.Arg(1))
report := apidiff.Changes(oldpkg, newpkg)
var err error
if *incompatibleOnly {
err = report.TextIncompatible(os.Stdout, false)
} else {
err = report.Text(os.Stdout)
}
if err != nil {
die("writing report: %v", err)
}
}
}
func mustLoadOrRead(importPathOrFile string) *types.Package {
fileInfo, err := os.Stat(importPathOrFile)
if err == nil && fileInfo.Mode().IsRegular() {
pkg, err := readExportData(importPathOrFile)
if err != nil {
die("reading export data from %s: %v", importPathOrFile, err)
}
return pkg
} else {
return mustLoadPackage(importPathOrFile).Types
}
}
func mustLoadPackage(importPath string) *packages.Package {
pkg, err := loadPackage(importPath)
if err != nil {
die("loading %s: %v", importPath, err)
}
return pkg
}
func loadPackage(importPath string) (*packages.Package, error) {
cfg := &packages.Config{Mode: packages.LoadTypes}
pkgs, err := packages.Load(cfg, importPath)
if err != nil {
return nil, err
}
if len(pkgs) == 0 {
return nil, fmt.Errorf("found no packages for import %s", importPath)
}
if len(pkgs[0].Errors) > 0 {
return nil, pkgs[0].Errors[0]
}
return pkgs[0], nil
}
func readExportData(filename string) (*types.Package, error) {
f, err := os.Open(filename)
if err != nil {
return nil, err
}
defer f.Close()
r := bufio.NewReader(f)
m := map[string]*types.Package{}
pkgPath, err := r.ReadString('\n')
if err != nil {
return nil, err
}
pkgPath = pkgPath[:len(pkgPath)-1] // remove delimiter
return gcexportdata.Read(r, token.NewFileSet(), m, pkgPath)
}
func writeExportData(pkg *packages.Package, filename string) error {
f, err := os.Create(filename)
if err != nil {
return err
}
// Include the package path in the file. The exportdata format does
// not record the path of the package being written.
fmt.Fprintln(f, pkg.PkgPath)
err1 := gcexportdata.Write(f, pkg.Fset, pkg.Types)
err2 := f.Close()
if err1 != nil {
return err1
}
return err2
}
func die(format string, args ...interface{}) {
fmt.Fprintf(os.Stderr, format+"\n", args...)
os.Exit(1)
}

1
vendor/golang.org/x/lint/lint.go generated vendored
View file

@ -839,6 +839,7 @@ var commonMethods = map[string]bool{
"ServeHTTP": true,
"String": true,
"Write": true,
"Unwrap": true,
}
// lintFuncDoc examines doc comments on functions and methods.

View file

@ -35,7 +35,9 @@ func init() {
proto.RegisterExtension(E_Http)
}
func init() { proto.RegisterFile("google/api/annotations.proto", fileDescriptor_c591c5aa9fb79aab) }
func init() {
proto.RegisterFile("google/api/annotations.proto", fileDescriptor_c591c5aa9fb79aab)
}
var fileDescriptor_c591c5aa9fb79aab = []byte{
// 208 bytes of a gzipped FileDescriptorProto

View file

@ -55,7 +55,9 @@ func init() {
proto.RegisterExtension(E_OauthScopes)
}
func init() { proto.RegisterFile("google/api/client.proto", fileDescriptor_78f2c6f7c3a942c1) }
func init() {
proto.RegisterFile("google/api/client.proto", fileDescriptor_78f2c6f7c3a942c1)
}
var fileDescriptor_78f2c6f7c3a942c1 = []byte{
// 262 bytes of a gzipped FileDescriptorProto

View file

@ -96,7 +96,9 @@ func init() {
proto.RegisterExtension(E_FieldBehavior)
}
func init() { proto.RegisterFile("google/api/field_behavior.proto", fileDescriptor_4648f18fd5079967) }
func init() {
proto.RegisterFile("google/api/field_behavior.proto", fileDescriptor_4648f18fd5079967)
}
var fileDescriptor_4648f18fd5079967 = []byte{
// 303 bytes of a gzipped FileDescriptorProto

View file

@ -599,7 +599,9 @@ func init() {
proto.RegisterType((*CustomHttpPattern)(nil), "google.api.CustomHttpPattern")
}
func init() { proto.RegisterFile("google/api/http.proto", fileDescriptor_ff9994be407cdcc9) }
func init() {
proto.RegisterFile("google/api/http.proto", fileDescriptor_ff9994be407cdcc9)
}
var fileDescriptor_ff9994be407cdcc9 = []byte{
// 419 bytes of a gzipped FileDescriptorProto

View file

@ -403,7 +403,9 @@ func init() {
proto.RegisterExtension(E_Resource)
}
func init() { proto.RegisterFile("google/api/resource.proto", fileDescriptor_465e9122405d1bb5) }
func init() {
proto.RegisterFile("google/api/resource.proto", fileDescriptor_465e9122405d1bb5)
}
var fileDescriptor_465e9122405d1bb5 = []byte{
// 490 bytes of a gzipped FileDescriptorProto

View file

@ -235,7 +235,9 @@ func init() {
proto.RegisterType((*TestIamPermissionsResponse)(nil), "google.iam.v1.TestIamPermissionsResponse")
}
func init() { proto.RegisterFile("google/iam/v1/iam_policy.proto", fileDescriptor_d2728eb97d748a32) }
func init() {
proto.RegisterFile("google/iam/v1/iam_policy.proto", fileDescriptor_d2728eb97d748a32)
}
var fileDescriptor_d2728eb97d748a32 = []byte{
// 514 bytes of a gzipped FileDescriptorProto

View file

@ -74,7 +74,9 @@ func init() {
proto.RegisterType((*GetPolicyOptions)(nil), "google.iam.v1.GetPolicyOptions")
}
func init() { proto.RegisterFile("google/iam/v1/options.proto", fileDescriptor_19aa09e909092bd1) }
func init() {
proto.RegisterFile("google/iam/v1/options.proto", fileDescriptor_19aa09e909092bd1)
}
var fileDescriptor_19aa09e909092bd1 = []byte{
// 229 bytes of a gzipped FileDescriptorProto

View file

@ -525,7 +525,9 @@ func init() {
proto.RegisterType((*AuditConfigDelta)(nil), "google.iam.v1.AuditConfigDelta")
}
func init() { proto.RegisterFile("google/iam/v1/policy.proto", fileDescriptor_a3cd40b8a66b2a99) }
func init() {
proto.RegisterFile("google/iam/v1/policy.proto", fileDescriptor_a3cd40b8a66b2a99)
}
var fileDescriptor_a3cd40b8a66b2a99 = []byte{
// 550 bytes of a gzipped FileDescriptorProto

View file

@ -222,7 +222,9 @@ func init() {
proto.RegisterEnum("google.rpc.Code", Code_name, Code_value)
}
func init() { proto.RegisterFile("google/rpc/code.proto", fileDescriptor_fe593a732623ccf0) }
func init() {
proto.RegisterFile("google/rpc/code.proto", fileDescriptor_fe593a732623ccf0)
}
var fileDescriptor_fe593a732623ccf0 = []byte{
// 362 bytes of a gzipped FileDescriptorProto

View file

@ -94,7 +94,9 @@ func init() {
proto.RegisterType((*Status)(nil), "google.rpc.Status")
}
func init() { proto.RegisterFile("google/rpc/status.proto", fileDescriptor_24d244abaf643bfe) }
func init() {
proto.RegisterFile("google/rpc/status.proto", fileDescriptor_24d244abaf643bfe)
}
var fileDescriptor_24d244abaf643bfe = []byte{
// 212 bytes of a gzipped FileDescriptorProto

View file

@ -105,7 +105,9 @@ func init() {
proto.RegisterType((*Expr)(nil), "google.type.Expr")
}
func init() { proto.RegisterFile("google/type/expr.proto", fileDescriptor_d7920f1ae7a2722f) }
func init() {
proto.RegisterFile("google/type/expr.proto", fileDescriptor_d7920f1ae7a2722f)
}
var fileDescriptor_d7920f1ae7a2722f = []byte{
// 195 bytes of a gzipped FileDescriptorProto

View file

@ -93,6 +93,22 @@ To build Go code, there are several options:
#### Compiling error, undefined: grpc.SupportPackageIsVersion
##### If you are using Go modules:
Please ensure your gRPC-Go version is `require`d at the appropriate version in
the same module containing the generated `.pb.go` files. For example,
`SupportPackageIsVersion6` needs `v1.27.0`, so in your `go.mod` file:
```
module <your module name>
require (
google.golang.org/grpc v1.27.0
)
```
##### If you are *not* using Go modules:
Please update proto package, gRPC package and rebuild the proto files:
- `go get -u github.com/golang/protobuf/{proto,protoc-gen-go}`
- `go get -u google.golang.org/grpc`

View file

@ -213,6 +213,12 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su
}
return
}
if oldS == connectivity.TransientFailure && s == connectivity.Connecting {
// Once a subconn enters TRANSIENT_FAILURE, ignore subsequent
// CONNECTING transitions to prevent the aggregated state from being
// always CONNECTING when many backends exist but are all down.
return
}
b.scStates[sc] = s
switch s {
case connectivity.Idle:
@ -221,21 +227,19 @@ func (b *baseBalancer) UpdateSubConnState(sc balancer.SubConn, state balancer.Su
// When an address was removed by resolver, b called RemoveSubConn but
// kept the sc's state in scStates. Remove state for this sc here.
delete(b.scStates, sc)
case connectivity.TransientFailure:
// Save error to be reported via picker.
b.connErr = state.ConnectionError
}
oldAggrState := b.state
b.state = b.csEvltr.RecordTransition(oldS, s)
// Set or clear the last connection error accordingly.
b.connErr = state.ConnectionError
// Regenerate picker when one of the following happens:
// - this sc became ready from not-ready
// - this sc became not-ready from ready
// - the aggregated state of balancer became TransientFailure from non-TransientFailure
// - the aggregated state of balancer became non-TransientFailure from TransientFailure
// - this sc entered or left ready
// - the aggregated state of balancer is TransientFailure
// (may need to update error message)
if (s == connectivity.Ready) != (oldS == connectivity.Ready) ||
(b.state == connectivity.TransientFailure) != (oldAggrState == connectivity.TransientFailure) {
b.state == connectivity.TransientFailure {
b.regeneratePicker()
}

View file

@ -24,8 +24,8 @@ import (
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/buffer"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/resolver"
)
@ -245,7 +245,7 @@ func (acbw *acBalancerWrapper) UpdateAddresses(addrs []resolver.Address) {
ac, err := cc.newAddrConn(addrs, opts)
if err != nil {
grpclog.Warningf("acBalancerWrapper: UpdateAddresses: failed to newAddrConn: %v", err)
channelz.Warningf(acbw.ac.channelzID, "acBalancerWrapper: UpdateAddresses: failed to newAddrConn: %v", err)
return
}
acbw.ac = ac

View file

@ -35,10 +35,10 @@ import (
"google.golang.org/grpc/codes"
"google.golang.org/grpc/connectivity"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/backoff"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/internal/grpcutil"
"google.golang.org/grpc/internal/transport"
"google.golang.org/grpc/keepalive"
"google.golang.org/grpc/resolver"
@ -151,7 +151,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
if channelz.IsOn() {
if cc.dopts.channelzParentID != 0 {
cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, cc.dopts.channelzParentID, target)
channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{
channelz.AddTraceEvent(cc.channelzID, 0, &channelz.TraceEventDesc{
Desc: "Channel Created",
Severity: channelz.CtINFO,
Parent: &channelz.TraceEventDesc{
@ -161,10 +161,7 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
})
} else {
cc.channelzID = channelz.RegisterChannel(&channelzChannel{cc}, 0, target)
channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{
Desc: "Channel Created",
Severity: channelz.CtINFO,
})
channelz.Info(cc.channelzID, "Channel Created")
}
cc.csMgr.channelzID = cc.channelzID
}
@ -241,14 +238,14 @@ func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *
}
// Determine the resolver to use.
cc.parsedTarget = parseTarget(cc.target)
grpclog.Infof("parsed scheme: %q", cc.parsedTarget.Scheme)
cc.parsedTarget = grpcutil.ParseTarget(cc.target)
channelz.Infof(cc.channelzID, "parsed scheme: %q", cc.parsedTarget.Scheme)
resolverBuilder := cc.getResolver(cc.parsedTarget.Scheme)
if resolverBuilder == nil {
// If resolver builder is still nil, the parsed target's scheme is
// not registered. Fallback to default resolver and set Endpoint to
// the original target.
grpclog.Infof("scheme %q not registered, fallback to default scheme", cc.parsedTarget.Scheme)
channelz.Infof(cc.channelzID, "scheme %q not registered, fallback to default scheme", cc.parsedTarget.Scheme)
cc.parsedTarget = resolver.Target{
Scheme: resolver.GetDefaultScheme(),
Endpoint: target,
@ -416,12 +413,7 @@ func (csm *connectivityStateManager) updateState(state connectivity.State) {
return
}
csm.state = state
if channelz.IsOn() {
channelz.AddTraceEvent(csm.channelzID, &channelz.TraceEventDesc{
Desc: fmt.Sprintf("Channel Connectivity change to %v", state),
Severity: channelz.CtINFO,
})
}
channelz.Infof(csm.channelzID, "Channel Connectivity change to %v", state)
if csm.notifyChan != nil {
// There are other goroutines waiting on this channel.
close(csm.notifyChan)
@ -671,9 +663,9 @@ func (cc *ClientConn) switchBalancer(name string) {
return
}
grpclog.Infof("ClientConn switching balancer to %q", name)
channelz.Infof(cc.channelzID, "ClientConn switching balancer to %q", name)
if cc.dopts.balancerBuilder != nil {
grpclog.Infoln("ignoring balancer switching: Balancer DialOption used instead")
channelz.Info(cc.channelzID, "ignoring balancer switching: Balancer DialOption used instead")
return
}
if cc.balancerWrapper != nil {
@ -681,22 +673,12 @@ func (cc *ClientConn) switchBalancer(name string) {
}
builder := balancer.Get(name)
if channelz.IsOn() {
if builder == nil {
channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{
Desc: fmt.Sprintf("Channel switches to new LB policy %q due to fallback from invalid balancer name", PickFirstBalancerName),
Severity: channelz.CtWarning,
})
} else {
channelz.AddTraceEvent(cc.channelzID, &channelz.TraceEventDesc{
Desc: fmt.Sprintf("Channel switches to new LB policy %q", name),
Severity: channelz.CtINFO,
})
}
}
if builder == nil {
grpclog.Infof("failed to get balancer builder for: %v, using pick_first instead", name)
channelz.Warningf(cc.channelzID, "Channel switches to new LB policy %q due to fallback from invalid balancer name", PickFirstBalancerName)
channelz.Infof(cc.channelzID, "failed to get balancer builder for: %v, using pick_first instead", name)
builder = newPickfirstBuilder()
} else {
channelz.Infof(cc.channelzID, "Channel switches to new LB policy %q", name)
}
cc.curBalancerName = builder.Name()
@ -720,6 +702,7 @@ func (cc *ClientConn) handleSubConnStateChange(sc balancer.SubConn, s connectivi
// Caller needs to make sure len(addrs) > 0.
func (cc *ClientConn) newAddrConn(addrs []resolver.Address, opts balancer.NewSubConnOptions) (*addrConn, error) {
ac := &addrConn{
state: connectivity.Idle,
cc: cc,
addrs: addrs,
scopts: opts,
@ -736,7 +719,7 @@ func (cc *ClientConn) newAddrConn(addrs []resolver.Address, opts balancer.NewSub
}
if channelz.IsOn() {
ac.channelzID = channelz.RegisterSubChannel(ac, cc.channelzID, "")
channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{
channelz.AddTraceEvent(ac.channelzID, 0, &channelz.TraceEventDesc{
Desc: "Subchannel Created",
Severity: channelz.CtINFO,
Parent: &channelz.TraceEventDesc{
@ -834,7 +817,7 @@ func (ac *addrConn) connect() error {
func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool {
ac.mu.Lock()
defer ac.mu.Unlock()
grpclog.Infof("addrConn: tryUpdateAddrs curAddr: %v, addrs: %v", ac.curAddr, addrs)
channelz.Infof(ac.channelzID, "addrConn: tryUpdateAddrs curAddr: %v, addrs: %v", ac.curAddr, addrs)
if ac.state == connectivity.Shutdown ||
ac.state == connectivity.TransientFailure ||
ac.state == connectivity.Idle {
@ -854,7 +837,7 @@ func (ac *addrConn) tryUpdateAddrs(addrs []resolver.Address) bool {
break
}
}
grpclog.Infof("addrConn: tryUpdateAddrs curAddrFound: %v", curAddrFound)
channelz.Infof(ac.channelzID, "addrConn: tryUpdateAddrs curAddrFound: %v", curAddrFound)
if curAddrFound {
ac.addrs = addrs
}
@ -1025,7 +1008,7 @@ func (cc *ClientConn) Close() error {
Severity: channelz.CtINFO,
}
}
channelz.AddTraceEvent(cc.channelzID, ted)
channelz.AddTraceEvent(cc.channelzID, 0, ted)
// TraceEvent needs to be called before RemoveEntry, as TraceEvent may add trace reference to
// the entity being deleted, and thus prevent it from being deleted right away.
channelz.RemoveEntry(cc.channelzID)
@ -1068,15 +1051,8 @@ func (ac *addrConn) updateConnectivityState(s connectivity.State, lastErr error)
if ac.state == s {
return
}
updateMsg := fmt.Sprintf("Subchannel Connectivity change to %v", s)
ac.state = s
if channelz.IsOn() {
channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{
Desc: updateMsg,
Severity: channelz.CtINFO,
})
}
channelz.Infof(ac.channelzID, "Subchannel Connectivity change to %v", s)
ac.cc.handleSubConnStateChange(ac.acbw, s, lastErr)
}
@ -1213,12 +1189,7 @@ func (ac *addrConn) tryAllAddrs(addrs []resolver.Address, connectDeadline time.T
}
ac.mu.Unlock()
if channelz.IsOn() {
channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{
Desc: fmt.Sprintf("Subchannel picks a new address %q to connect", addr.Addr),
Severity: channelz.CtINFO,
})
}
channelz.Infof(ac.channelzID, "Subchannel picks a new address %q to connect", addr.Addr)
newTr, reconnect, err := ac.createTransport(addr, copts, connectDeadline)
if err == nil {
@ -1300,7 +1271,7 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
newTr, err := transport.NewClientTransport(connectCtx, ac.cc.ctx, target, copts, onPrefaceReceipt, onGoAway, onClose)
if err != nil {
// newTr is either nil, or closed.
grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v. Err :%v. Reconnecting...", addr, err)
channelz.Warningf(ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v. Err: %v. Reconnecting...", addr, err)
return nil, nil, err
}
@ -1308,7 +1279,7 @@ func (ac *addrConn) createTransport(addr resolver.Address, copts transport.Conne
case <-time.After(time.Until(connectDeadline)):
// We didn't get the preface in time.
newTr.Close()
grpclog.Warningf("grpc: addrConn.createTransport failed to connect to %v: didn't receive server preface in time. Reconnecting...", addr)
channelz.Warningf(ac.channelzID, "grpc: addrConn.createTransport failed to connect to %v: didn't receive server preface in time. Reconnecting...", addr)
return nil, nil, errors.New("timed out waiting for server handshake")
case <-prefaceReceived:
// We got the preface - huzzah! things are good.
@ -1355,7 +1326,7 @@ func (ac *addrConn) startHealthCheck(ctx context.Context) {
// The health package is not imported to set health check function.
//
// TODO: add a link to the health check doc in the error message.
grpclog.Error("Health check is requested but health check function is not set.")
channelz.Error(ac.channelzID, "Health check is requested but health check function is not set.")
return
}
@ -1385,15 +1356,9 @@ func (ac *addrConn) startHealthCheck(ctx context.Context) {
err := ac.cc.dopts.healthCheckFunc(ctx, newStream, setConnectivityState, healthCheckConfig.ServiceName)
if err != nil {
if status.Code(err) == codes.Unimplemented {
if channelz.IsOn() {
channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{
Desc: "Subchannel health check is unimplemented at server side, thus health check is disabled",
Severity: channelz.CtError,
})
}
grpclog.Error("Subchannel health check is unimplemented at server side, thus health check is disabled")
channelz.Error(ac.channelzID, "Subchannel health check is unimplemented at server side, thus health check is disabled")
} else {
grpclog.Errorf("HealthCheckFunc exits with unexpected error %v", err)
channelz.Errorf(ac.channelzID, "HealthCheckFunc exits with unexpected error %v", err)
}
}
}()
@ -1458,7 +1423,7 @@ func (ac *addrConn) tearDown(err error) {
ac.mu.Lock()
}
if channelz.IsOn() {
channelz.AddTraceEvent(ac.channelzID, &channelz.TraceEventDesc{
channelz.AddTraceEvent(ac.channelzID, 0, &channelz.TraceEventDesc{
Desc: "Subchannel Deleted",
Severity: channelz.CtINFO,
Parent: &channelz.TraceEventDesc{

View file

@ -100,7 +100,11 @@ type ProtocolInfo struct {
ProtocolVersion string
// SecurityProtocol is the security protocol in use.
SecurityProtocol string
// SecurityVersion is the security protocol version.
// SecurityVersion is the security protocol version. It is a static version string from the
// credentials, not a value that reflects per-connection protocol negotiation. To retrieve
// details about the credentials used for a connection, use the Peer's AuthInfo field instead.
//
// Deprecated: please use Peer.AuthInfo.
SecurityVersion string
// ServerName is the user-configured server name.
ServerName string

View file

@ -3,11 +3,11 @@ module google.golang.org/grpc
go 1.11
require (
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473
github.com/envoyproxy/go-control-plane v0.9.4
github.com/envoyproxy/protoc-gen-validate v0.1.0
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b
github.com/golang/mock v1.1.1
github.com/golang/protobuf v1.3.2
github.com/golang/protobuf v1.3.3
github.com/google/go-cmp v0.2.0
golang.org/x/net v0.0.0-20190311183353-d8887717615a
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be

15
vendor/google.golang.org/grpc/go.sum generated vendored
View file

@ -1,10 +1,15 @@
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrCgN8fCq8E5Xuty6jGbmSNEvSsU=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4 h1:rEvIZUSZ3fx39WIi3JkQqQBitGwpELBIYWeBVh6wn+E=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
@ -14,6 +19,8 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I=
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
@ -21,6 +28,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -40,6 +48,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A=
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
@ -49,5 +58,7 @@ google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2El
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

View file

@ -26,64 +26,70 @@
// verbosity level can be set by GRPC_GO_LOG_VERBOSITY_LEVEL.
package grpclog // import "google.golang.org/grpc/grpclog"
import "os"
import (
"os"
var logger = newLoggerV2()
"google.golang.org/grpc/internal/grpclog"
)
func init() {
SetLoggerV2(newLoggerV2())
}
// V reports whether verbosity level l is at least the requested verbose level.
func V(l int) bool {
return logger.V(l)
return grpclog.Logger.V(l)
}
// Info logs to the INFO log.
func Info(args ...interface{}) {
logger.Info(args...)
grpclog.Logger.Info(args...)
}
// Infof logs to the INFO log. Arguments are handled in the manner of fmt.Printf.
func Infof(format string, args ...interface{}) {
logger.Infof(format, args...)
grpclog.Logger.Infof(format, args...)
}
// Infoln logs to the INFO log. Arguments are handled in the manner of fmt.Println.
func Infoln(args ...interface{}) {
logger.Infoln(args...)
grpclog.Logger.Infoln(args...)
}
// Warning logs to the WARNING log.
func Warning(args ...interface{}) {
logger.Warning(args...)
grpclog.Logger.Warning(args...)
}
// Warningf logs to the WARNING log. Arguments are handled in the manner of fmt.Printf.
func Warningf(format string, args ...interface{}) {
logger.Warningf(format, args...)
grpclog.Logger.Warningf(format, args...)
}
// Warningln logs to the WARNING log. Arguments are handled in the manner of fmt.Println.
func Warningln(args ...interface{}) {
logger.Warningln(args...)
grpclog.Logger.Warningln(args...)
}
// Error logs to the ERROR log.
func Error(args ...interface{}) {
logger.Error(args...)
grpclog.Logger.Error(args...)
}
// Errorf logs to the ERROR log. Arguments are handled in the manner of fmt.Printf.
func Errorf(format string, args ...interface{}) {
logger.Errorf(format, args...)
grpclog.Logger.Errorf(format, args...)
}
// Errorln logs to the ERROR log. Arguments are handled in the manner of fmt.Println.
func Errorln(args ...interface{}) {
logger.Errorln(args...)
grpclog.Logger.Errorln(args...)
}
// Fatal logs to the FATAL log. Arguments are handled in the manner of fmt.Print.
// It calls os.Exit() with exit code 1.
func Fatal(args ...interface{}) {
logger.Fatal(args...)
grpclog.Logger.Fatal(args...)
// Make sure fatal logs will exit.
os.Exit(1)
}
@ -91,7 +97,7 @@ func Fatal(args ...interface{}) {
// Fatalf logs to the FATAL log. Arguments are handled in the manner of fmt.Printf.
// It calls os.Exit() with exit code 1.
func Fatalf(format string, args ...interface{}) {
logger.Fatalf(format, args...)
grpclog.Logger.Fatalf(format, args...)
// Make sure fatal logs will exit.
os.Exit(1)
}
@ -99,7 +105,7 @@ func Fatalf(format string, args ...interface{}) {
// Fatalln logs to the FATAL log. Arguments are handled in the manner of fmt.Println.
// It calle os.Exit()) with exit code 1.
func Fatalln(args ...interface{}) {
logger.Fatalln(args...)
grpclog.Logger.Fatalln(args...)
// Make sure fatal logs will exit.
os.Exit(1)
}
@ -108,19 +114,19 @@ func Fatalln(args ...interface{}) {
//
// Deprecated: use Info.
func Print(args ...interface{}) {
logger.Info(args...)
grpclog.Logger.Info(args...)
}
// Printf prints to the logger. Arguments are handled in the manner of fmt.Printf.
//
// Deprecated: use Infof.
func Printf(format string, args ...interface{}) {
logger.Infof(format, args...)
grpclog.Logger.Infof(format, args...)
}
// Println prints to the logger. Arguments are handled in the manner of fmt.Println.
//
// Deprecated: use Infoln.
func Println(args ...interface{}) {
logger.Infoln(args...)
grpclog.Logger.Infoln(args...)
}

View file

@ -18,6 +18,8 @@
package grpclog
import "google.golang.org/grpc/internal/grpclog"
// Logger mimics golang's standard Logger as an interface.
//
// Deprecated: use LoggerV2.
@ -35,7 +37,7 @@ type Logger interface {
//
// Deprecated: use SetLoggerV2.
func SetLogger(l Logger) {
logger = &loggerWrapper{Logger: l}
grpclog.Logger = &loggerWrapper{Logger: l}
}
// loggerWrapper wraps Logger into a LoggerV2.

View file

@ -24,6 +24,8 @@ import (
"log"
"os"
"strconv"
"google.golang.org/grpc/internal/grpclog"
)
// LoggerV2 does underlying logging work for grpclog.
@ -65,7 +67,8 @@ type LoggerV2 interface {
// SetLoggerV2 sets logger that is used in grpc to a V2 logger.
// Not mutex-protected, should be called before any gRPC functions.
func SetLoggerV2(l LoggerV2) {
logger = l
grpclog.Logger = l
grpclog.DepthLogger, _ = l.(grpclog.DepthLoggerV2)
}
const (
@ -193,3 +196,19 @@ func (g *loggerT) Fatalf(format string, args ...interface{}) {
func (g *loggerT) V(l int) bool {
return l <= g.v
}
// DepthLoggerV2 logs at a specified call frame. If a LoggerV2 also implements
// DepthLoggerV2, the below functions will be called with the appropriate stack
// depth set for trivial functions the logger may ignore.
//
// This API is EXPERIMENTAL.
type DepthLoggerV2 interface {
// InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Print.
InfoDepth(depth int, args ...interface{})
// WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Print.
WarningDepth(depth int, args ...interface{})
// ErrorDetph logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Print.
ErrorDepth(depth int, args ...interface{})
// FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Print.
FatalDepth(depth int, args ...interface{})
}

View file

@ -30,7 +30,7 @@ import (
"sync/atomic"
"time"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/grpclog"
)
const (
@ -216,7 +216,7 @@ func RegisterChannel(c Channel, pid int64, ref string) int64 {
// by pid). It returns the unique channelz tracking id assigned to this subchannel.
func RegisterSubChannel(c Channel, pid int64, ref string) int64 {
if pid == 0 {
grpclog.Error("a SubChannel's parent id cannot be 0")
grpclog.ErrorDepth(0, "a SubChannel's parent id cannot be 0")
return 0
}
id := idGen.genID()
@ -253,7 +253,7 @@ func RegisterServer(s Server, ref string) int64 {
// this listen socket.
func RegisterListenSocket(s Socket, pid int64, ref string) int64 {
if pid == 0 {
grpclog.Error("a ListenSocket's parent id cannot be 0")
grpclog.ErrorDepth(0, "a ListenSocket's parent id cannot be 0")
return 0
}
id := idGen.genID()
@ -268,7 +268,7 @@ func RegisterListenSocket(s Socket, pid int64, ref string) int64 {
// this normal socket.
func RegisterNormalSocket(s Socket, pid int64, ref string) int64 {
if pid == 0 {
grpclog.Error("a NormalSocket's parent id cannot be 0")
grpclog.ErrorDepth(0, "a NormalSocket's parent id cannot be 0")
return 0
}
id := idGen.genID()
@ -294,7 +294,19 @@ type TraceEventDesc struct {
}
// AddTraceEvent adds trace related to the entity with specified id, using the provided TraceEventDesc.
func AddTraceEvent(id int64, desc *TraceEventDesc) {
func AddTraceEvent(id int64, depth int, desc *TraceEventDesc) {
for d := desc; d != nil; d = d.Parent {
switch d.Severity {
case CtUNKNOWN:
grpclog.InfoDepth(depth+1, d.Desc)
case CtINFO:
grpclog.InfoDepth(depth+1, d.Desc)
case CtWarning:
grpclog.WarningDepth(depth+1, d.Desc)
case CtError:
grpclog.ErrorDepth(depth+1, d.Desc)
}
}
if getMaxTraceEntry() == 0 {
return
}

View file

@ -0,0 +1,100 @@
/*
*
* Copyright 2020 gRPC authors.
*
* 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 channelz
import (
"fmt"
"google.golang.org/grpc/internal/grpclog"
)
// Info logs through grpclog.Info and adds a trace event if channelz is on.
func Info(id int64, args ...interface{}) {
if IsOn() {
AddTraceEvent(id, 1, &TraceEventDesc{
Desc: fmt.Sprint(args...),
Severity: CtINFO,
})
} else {
grpclog.InfoDepth(1, args...)
}
}
// Infof logs through grpclog.Infof and adds a trace event if channelz is on.
func Infof(id int64, format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
if IsOn() {
AddTraceEvent(id, 1, &TraceEventDesc{
Desc: msg,
Severity: CtINFO,
})
} else {
grpclog.InfoDepth(1, msg)
}
}
// Warning logs through grpclog.Warning and adds a trace event if channelz is on.
func Warning(id int64, args ...interface{}) {
if IsOn() {
AddTraceEvent(id, 1, &TraceEventDesc{
Desc: fmt.Sprint(args...),
Severity: CtWarning,
})
} else {
grpclog.WarningDepth(1, args...)
}
}
// Warningf logs through grpclog.Warningf and adds a trace event if channelz is on.
func Warningf(id int64, format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
if IsOn() {
AddTraceEvent(id, 1, &TraceEventDesc{
Desc: msg,
Severity: CtWarning,
})
} else {
grpclog.WarningDepth(1, msg)
}
}
// Error logs through grpclog.Error and adds a trace event if channelz is on.
func Error(id int64, args ...interface{}) {
if IsOn() {
AddTraceEvent(id, 1, &TraceEventDesc{
Desc: fmt.Sprint(args...),
Severity: CtError,
})
} else {
grpclog.ErrorDepth(1, args...)
}
}
// Errorf logs through grpclog.Errorf and adds a trace event if channelz is on.
func Errorf(id int64, format string, args ...interface{}) {
msg := fmt.Sprintf(format, args...)
if IsOn() {
AddTraceEvent(id, 1, &TraceEventDesc{
Desc: msg,
Severity: CtError,
})
} else {
grpclog.ErrorDepth(1, msg)
}
}

View file

@ -0,0 +1,118 @@
/*
*
* Copyright 2020 gRPC authors.
*
* 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 grpclog (internal) defines depth logging for grpc.
package grpclog
// Logger is the logger used for the non-depth log functions.
var Logger LoggerV2
// DepthLogger is the logger used for the depth log functions.
var DepthLogger DepthLoggerV2
// InfoDepth logs to the INFO log at the specified depth.
func InfoDepth(depth int, args ...interface{}) {
if DepthLogger != nil {
DepthLogger.InfoDepth(depth, args...)
} else {
Logger.Info(args...)
}
}
// WarningDepth logs to the WARNING log at the specified depth.
func WarningDepth(depth int, args ...interface{}) {
if DepthLogger != nil {
DepthLogger.WarningDepth(depth, args...)
} else {
Logger.Warning(args...)
}
}
// ErrorDepth logs to the ERROR log at the specified depth.
func ErrorDepth(depth int, args ...interface{}) {
if DepthLogger != nil {
DepthLogger.ErrorDepth(depth, args...)
} else {
Logger.Error(args...)
}
}
// FatalDepth logs to the FATAL log at the specified depth.
func FatalDepth(depth int, args ...interface{}) {
if DepthLogger != nil {
DepthLogger.FatalDepth(depth, args...)
} else {
Logger.Fatal(args...)
}
}
// LoggerV2 does underlying logging work for grpclog.
// This is a copy of the LoggerV2 defined in the external grpclog package. It
// is defined here to avoid a circular dependency.
type LoggerV2 interface {
// Info logs to INFO log. Arguments are handled in the manner of fmt.Print.
Info(args ...interface{})
// Infoln logs to INFO log. Arguments are handled in the manner of fmt.Println.
Infoln(args ...interface{})
// Infof logs to INFO log. Arguments are handled in the manner of fmt.Printf.
Infof(format string, args ...interface{})
// Warning logs to WARNING log. Arguments are handled in the manner of fmt.Print.
Warning(args ...interface{})
// Warningln logs to WARNING log. Arguments are handled in the manner of fmt.Println.
Warningln(args ...interface{})
// Warningf logs to WARNING log. Arguments are handled in the manner of fmt.Printf.
Warningf(format string, args ...interface{})
// Error logs to ERROR log. Arguments are handled in the manner of fmt.Print.
Error(args ...interface{})
// Errorln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
Errorln(args ...interface{})
// Errorf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
Errorf(format string, args ...interface{})
// Fatal logs to ERROR log. Arguments are handled in the manner of fmt.Print.
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
// Implementations may also call os.Exit() with a non-zero exit code.
Fatal(args ...interface{})
// Fatalln logs to ERROR log. Arguments are handled in the manner of fmt.Println.
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
// Implementations may also call os.Exit() with a non-zero exit code.
Fatalln(args ...interface{})
// Fatalf logs to ERROR log. Arguments are handled in the manner of fmt.Printf.
// gRPC ensures that all Fatal logs will exit with os.Exit(1).
// Implementations may also call os.Exit() with a non-zero exit code.
Fatalf(format string, args ...interface{})
// V reports whether verbosity level l is at least the requested verbose level.
V(l int) bool
}
// DepthLoggerV2 logs at a specified call frame. If a LoggerV2 also implements
// DepthLoggerV2, the below functions will be called with the appropriate stack
// depth set for trivial functions the logger may ignore.
// This is a copy of the DepthLoggerV2 defined in the external grpclog package.
// It is defined here to avoid a circular dependency.
//
// This API is EXPERIMENTAL.
type DepthLoggerV2 interface {
// InfoDepth logs to INFO log at the specified depth. Arguments are handled in the manner of fmt.Print.
InfoDepth(depth int, args ...interface{})
// WarningDepth logs to WARNING log at the specified depth. Arguments are handled in the manner of fmt.Print.
WarningDepth(depth int, args ...interface{})
// ErrorDetph logs to ERROR log at the specified depth. Arguments are handled in the manner of fmt.Print.
ErrorDepth(depth int, args ...interface{})
// FatalDepth logs to FATAL log at the specified depth. Arguments are handled in the manner of fmt.Print.
FatalDepth(depth int, args ...interface{})
}

View file

@ -0,0 +1,63 @@
/*
*
* Copyright 2020 gRPC authors.
*
* 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 grpclog
// PrefixLogger does logging with a prefix.
//
// Logging method on a nil logs without any prefix.
type PrefixLogger struct {
prefix string
}
// Infof does info logging.
func (pl *PrefixLogger) Infof(format string, args ...interface{}) {
if pl != nil {
// Handle nil, so the tests can pass in a nil logger.
format = pl.prefix + format
}
Logger.Infof(format, args...)
}
// Warningf does warning logging.
func (pl *PrefixLogger) Warningf(format string, args ...interface{}) {
if pl != nil {
format = pl.prefix + format
}
Logger.Warningf(format, args...)
}
// Errorf does error logging.
func (pl *PrefixLogger) Errorf(format string, args ...interface{}) {
if pl != nil {
format = pl.prefix + format
}
Logger.Errorf(format, args...)
}
// Debugf does info logging at verbose level 2.
func (pl *PrefixLogger) Debugf(format string, args ...interface{}) {
if Logger.V(2) {
pl.Infof(format, args...)
}
}
// NewPrefixLogger creates a prefix logger with the given prefix.
func NewPrefixLogger(prefix string) *PrefixLogger {
return &PrefixLogger{prefix: prefix}
}

View file

@ -0,0 +1,55 @@
/*
*
* Copyright 2020 gRPC authors.
*
* 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 grpcutil provides a bunch of utility functions to be used across the
// gRPC codebase.
package grpcutil
import (
"strings"
"google.golang.org/grpc/resolver"
)
// split2 returns the values from strings.SplitN(s, sep, 2).
// If sep is not found, it returns ("", "", false) instead.
func split2(s, sep string) (string, string, bool) {
spl := strings.SplitN(s, sep, 2)
if len(spl) < 2 {
return "", "", false
}
return spl[0], spl[1], true
}
// ParseTarget splits target into a resolver.Target struct containing scheme,
// authority and endpoint.
//
// If target is not a valid scheme://authority/endpoint, it returns {Endpoint:
// target}.
func ParseTarget(target string) (ret resolver.Target) {
var ok bool
ret.Scheme, ret.Endpoint, ok = split2(target, "://")
if !ok {
return resolver.Target{Endpoint: target}
}
ret.Authority, ret.Endpoint, ok = split2(ret.Endpoint, "/")
if !ok {
return resolver.Target{Endpoint: target}
}
return ret
}

View file

@ -338,7 +338,7 @@ func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), trace
Addr: ht.RemoteAddr(),
}
if req.TLS != nil {
pr.AuthInfo = credentials.TLSInfo{State: *req.TLS, CommonAuthInfo: credentials.CommonAuthInfo{credentials.PrivacyAndIntegrity}}
pr.AuthInfo = credentials.TLSInfo{State: *req.TLS, CommonAuthInfo: credentials.CommonAuthInfo{SecurityLevel: credentials.PrivacyAndIntegrity}}
}
ctx = metadata.NewIncomingContext(ctx, ht.headerMD)
s.ctx = peer.NewContext(ctx, pr)

View file

@ -680,14 +680,19 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (_ *Strea
}
}
if t.statsHandler != nil {
header, _, _ := metadata.FromOutgoingContextRaw(ctx)
header, ok := metadata.FromOutgoingContext(ctx)
if ok {
header.Set("user-agent", t.userAgent)
} else {
header = metadata.Pairs("user-agent", t.userAgent)
}
outHeader := &stats.OutHeader{
Client: true,
FullMethod: callHdr.Method,
RemoteAddr: t.remoteAddr,
LocalAddr: t.localAddr,
Compression: callHdr.SendCompress,
Header: header.Copy(),
Header: header,
}
t.statsHandler.HandleRPC(s.ctx, outHeader)
}

View file

@ -26,7 +26,6 @@ import (
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/channelz"
"google.golang.org/grpc/internal/grpcsync"
"google.golang.org/grpc/resolver"
@ -46,34 +45,6 @@ type ccResolverWrapper struct {
polling chan struct{}
}
// split2 returns the values from strings.SplitN(s, sep, 2).
// If sep is not found, it returns ("", "", false) instead.
func split2(s, sep string) (string, string, bool) {
spl := strings.SplitN(s, sep, 2)
if len(spl) < 2 {
return "", "", false
}
return spl[0], spl[1], true
}
// parseTarget splits target into a struct containing scheme, authority and
// endpoint.
//
// If target is not a valid scheme://authority/endpoint, it returns {Endpoint:
// target}.
func parseTarget(target string) (ret resolver.Target) {
var ok bool
ret.Scheme, ret.Endpoint, ok = split2(target, "://")
if !ok {
return resolver.Target{Endpoint: target}
}
ret.Authority, ret.Endpoint, ok = split2(ret.Endpoint, "/")
if !ok {
return resolver.Target{Endpoint: target}
}
return ret
}
// newCCResolverWrapper uses the resolver.Builder to build a Resolver and
// returns a ccResolverWrapper object which wraps the newly built resolver.
func newCCResolverWrapper(cc *ClientConn, rb resolver.Builder) (*ccResolverWrapper, error) {
@ -169,7 +140,7 @@ func (ccr *ccResolverWrapper) UpdateState(s resolver.State) {
if ccr.done.HasFired() {
return
}
grpclog.Infof("ccResolverWrapper: sending update to cc: %v", s)
channelz.Infof(ccr.cc.channelzID, "ccResolverWrapper: sending update to cc: %v", s)
if channelz.IsOn() {
ccr.addChannelzTraceEvent(s)
}
@ -181,13 +152,7 @@ func (ccr *ccResolverWrapper) ReportError(err error) {
if ccr.done.HasFired() {
return
}
grpclog.Warningf("ccResolverWrapper: reporting error to cc: %v", err)
if channelz.IsOn() {
channelz.AddTraceEvent(ccr.cc.channelzID, &channelz.TraceEventDesc{
Desc: fmt.Sprintf("Resolver reported error: %v", err),
Severity: channelz.CtWarning,
})
}
channelz.Warningf(ccr.cc.channelzID, "ccResolverWrapper: reporting error to cc: %v", err)
ccr.poll(ccr.cc.updateResolverState(resolver.State{}, err))
}
@ -196,7 +161,7 @@ func (ccr *ccResolverWrapper) NewAddress(addrs []resolver.Address) {
if ccr.done.HasFired() {
return
}
grpclog.Infof("ccResolverWrapper: sending new addresses to cc: %v", addrs)
channelz.Infof(ccr.cc.channelzID, "ccResolverWrapper: sending new addresses to cc: %v", addrs)
if channelz.IsOn() {
ccr.addChannelzTraceEvent(resolver.State{Addresses: addrs, ServiceConfig: ccr.curState.ServiceConfig})
}
@ -210,20 +175,14 @@ func (ccr *ccResolverWrapper) NewServiceConfig(sc string) {
if ccr.done.HasFired() {
return
}
grpclog.Infof("ccResolverWrapper: got new service config: %v", sc)
channelz.Infof(ccr.cc.channelzID, "ccResolverWrapper: got new service config: %v", sc)
if ccr.cc.dopts.disableServiceConfig {
grpclog.Infof("Service config lookups disabled; ignoring config")
channelz.Info(ccr.cc.channelzID, "Service config lookups disabled; ignoring config")
return
}
scpr := parseServiceConfig(sc)
if scpr.Err != nil {
grpclog.Warningf("ccResolverWrapper: error parsing service config: %v", scpr.Err)
if channelz.IsOn() {
channelz.AddTraceEvent(ccr.cc.channelzID, &channelz.TraceEventDesc{
Desc: fmt.Sprintf("Error parsing service config: %v", scpr.Err),
Severity: channelz.CtWarning,
})
}
channelz.Warningf(ccr.cc.channelzID, "ccResolverWrapper: error parsing service config: %v", scpr.Err)
ccr.poll(balancer.ErrBadResolverState)
return
}
@ -256,7 +215,7 @@ func (ccr *ccResolverWrapper) addChannelzTraceEvent(s resolver.State) {
} else if len(ccr.curState.Addresses) == 0 && len(s.Addresses) > 0 {
updates = append(updates, "resolver returned new addresses")
}
channelz.AddTraceEvent(ccr.cc.channelzID, &channelz.TraceEventDesc{
channelz.AddTraceEvent(ccr.cc.channelzID, 0, &channelz.TraceEventDesc{
Desc: fmt.Sprintf("Resolver state updated: %+v (%v)", s, strings.Join(updates, "; ")),
Severity: channelz.CtINFO,
})

View file

@ -287,13 +287,14 @@ func (o FailFastCallOption) before(c *callInfo) error {
}
func (o FailFastCallOption) after(c *callInfo) {}
// MaxCallRecvMsgSize returns a CallOption which sets the maximum message size the client can receive.
func MaxCallRecvMsgSize(s int) CallOption {
return MaxRecvMsgSizeCallOption{MaxRecvMsgSize: s}
// MaxCallRecvMsgSize returns a CallOption which sets the maximum message size
// in bytes the client can receive.
func MaxCallRecvMsgSize(bytes int) CallOption {
return MaxRecvMsgSizeCallOption{MaxRecvMsgSize: bytes}
}
// MaxRecvMsgSizeCallOption is a CallOption that indicates the maximum message
// size the client can receive.
// size in bytes the client can receive.
// This is an EXPERIMENTAL API.
type MaxRecvMsgSizeCallOption struct {
MaxRecvMsgSize int
@ -305,13 +306,14 @@ func (o MaxRecvMsgSizeCallOption) before(c *callInfo) error {
}
func (o MaxRecvMsgSizeCallOption) after(c *callInfo) {}
// MaxCallSendMsgSize returns a CallOption which sets the maximum message size the client can send.
func MaxCallSendMsgSize(s int) CallOption {
return MaxSendMsgSizeCallOption{MaxSendMsgSize: s}
// MaxCallSendMsgSize returns a CallOption which sets the maximum message size
// in bytes the client can send.
func MaxCallSendMsgSize(bytes int) CallOption {
return MaxSendMsgSizeCallOption{MaxSendMsgSize: bytes}
}
// MaxSendMsgSizeCallOption is a CallOption that indicates the maximum message
// size the client can send.
// size in bytes the client can send.
// This is an EXPERIMENTAL API.
type MaxSendMsgSizeCallOption struct {
MaxSendMsgSize int

View file

@ -116,6 +116,8 @@ type serverOptions struct {
dc Decompressor
unaryInt UnaryServerInterceptor
streamInt StreamServerInterceptor
chainUnaryInts []UnaryServerInterceptor
chainStreamInts []StreamServerInterceptor
inTapHandle tap.ServerInHandle
statsHandler stats.Handler
maxConcurrentStreams uint32
@ -311,6 +313,16 @@ func UnaryInterceptor(i UnaryServerInterceptor) ServerOption {
})
}
// ChainUnaryInterceptor returns a ServerOption that specifies the chained interceptor
// for unary RPCs. The first interceptor will be the outer most,
// while the last interceptor will be the inner most wrapper around the real call.
// All unary interceptors added by this method will be chained.
func ChainUnaryInterceptor(interceptors ...UnaryServerInterceptor) ServerOption {
return newFuncServerOption(func(o *serverOptions) {
o.chainUnaryInts = append(o.chainUnaryInts, interceptors...)
})
}
// StreamInterceptor returns a ServerOption that sets the StreamServerInterceptor for the
// server. Only one stream interceptor can be installed.
func StreamInterceptor(i StreamServerInterceptor) ServerOption {
@ -322,6 +334,16 @@ func StreamInterceptor(i StreamServerInterceptor) ServerOption {
})
}
// ChainStreamInterceptor returns a ServerOption that specifies the chained interceptor
// for stream RPCs. The first interceptor will be the outer most,
// while the last interceptor will be the inner most wrapper around the real call.
// All stream interceptors added by this method will be chained.
func ChainStreamInterceptor(interceptors ...StreamServerInterceptor) ServerOption {
return newFuncServerOption(func(o *serverOptions) {
o.chainStreamInts = append(o.chainStreamInts, interceptors...)
})
}
// InTapHandle returns a ServerOption that sets the tap handle for all the server
// transport to be created. Only one can be installed.
func InTapHandle(h tap.ServerInHandle) ServerOption {
@ -404,6 +426,8 @@ func NewServer(opt ...ServerOption) *Server {
done: grpcsync.NewEvent(),
czData: new(channelzData),
}
chainUnaryServerInterceptors(s)
chainStreamServerInterceptors(s)
s.cv = sync.NewCond(&s.mu)
if EnableTracing {
_, file, line, _ := runtime.Caller(1)
@ -658,7 +682,7 @@ func (s *Server) handleRawConn(rawConn net.Conn) {
s.mu.Lock()
s.errorf("ServerHandshake(%q) failed: %v", rawConn.RemoteAddr(), err)
s.mu.Unlock()
grpclog.Warningf("grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err)
channelz.Warningf(s.channelzID, "grpc: Server.Serve failed to complete security handshake from %q: %v", rawConn.RemoteAddr(), err)
rawConn.Close()
}
rawConn.SetDeadline(time.Time{})
@ -705,7 +729,7 @@ func (s *Server) newHTTP2Transport(c net.Conn, authInfo credentials.AuthInfo) tr
s.errorf("NewServerTransport(%q) failed: %v", c.RemoteAddr(), err)
s.mu.Unlock()
c.Close()
grpclog.Warningln("grpc: Server.Serve failed to create ServerTransport: ", err)
channelz.Warning(s.channelzID, "grpc: Server.Serve failed to create ServerTransport: ", err)
return nil
}
@ -844,12 +868,12 @@ func (s *Server) incrCallsFailed() {
func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Stream, msg interface{}, cp Compressor, opts *transport.Options, comp encoding.Compressor) error {
data, err := encode(s.getCodec(stream.ContentSubtype()), msg)
if err != nil {
grpclog.Errorln("grpc: server failed to encode response: ", err)
channelz.Error(s.channelzID, "grpc: server failed to encode response: ", err)
return err
}
compData, err := compress(data, cp, comp)
if err != nil {
grpclog.Errorln("grpc: server failed to compress response: ", err)
channelz.Error(s.channelzID, "grpc: server failed to compress response: ", err)
return err
}
hdr, payload := msgHeader(data, compData)
@ -864,6 +888,40 @@ func (s *Server) sendResponse(t transport.ServerTransport, stream *transport.Str
return err
}
// chainUnaryServerInterceptors chains all unary server interceptors into one.
func chainUnaryServerInterceptors(s *Server) {
// Prepend opts.unaryInt to the chaining interceptors if it exists, since unaryInt will
// be executed before any other chained interceptors.
interceptors := s.opts.chainUnaryInts
if s.opts.unaryInt != nil {
interceptors = append([]UnaryServerInterceptor{s.opts.unaryInt}, s.opts.chainUnaryInts...)
}
var chainedInt UnaryServerInterceptor
if len(interceptors) == 0 {
chainedInt = nil
} else if len(interceptors) == 1 {
chainedInt = interceptors[0]
} else {
chainedInt = func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (interface{}, error) {
return interceptors[0](ctx, req, info, getChainUnaryHandler(interceptors, 0, info, handler))
}
}
s.opts.unaryInt = chainedInt
}
// getChainUnaryHandler recursively generate the chained UnaryHandler
func getChainUnaryHandler(interceptors []UnaryServerInterceptor, curr int, info *UnaryServerInfo, finalHandler UnaryHandler) UnaryHandler {
if curr == len(interceptors)-1 {
return finalHandler
}
return func(ctx context.Context, req interface{}) (interface{}, error) {
return interceptors[curr+1](ctx, req, info, getChainUnaryHandler(interceptors, curr+1, info, finalHandler))
}
}
func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, md *MethodDesc, trInfo *traceInfo) (err error) {
sh := s.opts.statsHandler
if sh != nil || trInfo != nil || channelz.IsOn() {
@ -989,7 +1047,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
if err != nil {
if st, ok := status.FromError(err); ok {
if e := t.WriteStatus(stream, st); e != nil {
grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status %v", e)
channelz.Warningf(s.channelzID, "grpc: Server.processUnaryRPC failed to write status %v", e)
}
}
return err
@ -1034,7 +1092,7 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
trInfo.tr.SetError()
}
if e := t.WriteStatus(stream, appStatus); e != nil {
grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status: %v", e)
channelz.Warningf(s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e)
}
if binlog != nil {
if h, _ := stream.Header(); h.Len() > 0 {
@ -1061,9 +1119,9 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
// The entire stream is done (for unary RPC only).
return err
}
if s, ok := status.FromError(err); ok {
if e := t.WriteStatus(stream, s); e != nil {
grpclog.Warningf("grpc: Server.processUnaryRPC failed to write status: %v", e)
if sts, ok := status.FromError(err); ok {
if e := t.WriteStatus(stream, sts); e != nil {
channelz.Warningf(s.channelzID, "grpc: Server.processUnaryRPC failed to write status: %v", e)
}
} else {
switch st := err.(type) {
@ -1113,6 +1171,40 @@ func (s *Server) processUnaryRPC(t transport.ServerTransport, stream *transport.
return err
}
// chainStreamServerInterceptors chains all stream server interceptors into one.
func chainStreamServerInterceptors(s *Server) {
// Prepend opts.streamInt to the chaining interceptors if it exists, since streamInt will
// be executed before any other chained interceptors.
interceptors := s.opts.chainStreamInts
if s.opts.streamInt != nil {
interceptors = append([]StreamServerInterceptor{s.opts.streamInt}, s.opts.chainStreamInts...)
}
var chainedInt StreamServerInterceptor
if len(interceptors) == 0 {
chainedInt = nil
} else if len(interceptors) == 1 {
chainedInt = interceptors[0]
} else {
chainedInt = func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error {
return interceptors[0](srv, ss, info, getChainStreamHandler(interceptors, 0, info, handler))
}
}
s.opts.streamInt = chainedInt
}
// getChainStreamHandler recursively generate the chained StreamHandler
func getChainStreamHandler(interceptors []StreamServerInterceptor, curr int, info *StreamServerInfo, finalHandler StreamHandler) StreamHandler {
if curr == len(interceptors)-1 {
return finalHandler
}
return func(srv interface{}, ss ServerStream) error {
return interceptors[curr+1](srv, ss, info, getChainStreamHandler(interceptors, curr+1, info, finalHandler))
}
}
func (s *Server) processStreamingRPC(t transport.ServerTransport, stream *transport.Stream, srv *service, sd *StreamDesc, trInfo *traceInfo) (err error) {
if channelz.IsOn() {
s.incrCallsStarted()
@ -1297,7 +1389,7 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
trInfo.tr.SetError()
}
grpclog.Warningf("grpc: Server.handleStream failed to write status: %v", err)
channelz.Warningf(s.channelzID, "grpc: Server.handleStream failed to write status: %v", err)
}
if trInfo != nil {
trInfo.tr.Finish()
@ -1338,7 +1430,7 @@ func (s *Server) handleStream(t transport.ServerTransport, stream *transport.Str
trInfo.tr.LazyLog(&fmtStringer{"%v", []interface{}{err}}, true)
trInfo.tr.SetError()
}
grpclog.Warningf("grpc: Server.handleStream failed to write status: %v", err)
channelz.Warningf(s.channelzID, "grpc: Server.handleStream failed to write status: %v", err)
}
if trInfo != nil {
trInfo.tr.Finish()

View file

@ -31,7 +31,6 @@ import (
"google.golang.org/grpc/balancer"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/encoding"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/internal/balancerload"
"google.golang.org/grpc/internal/binarylog"
"google.golang.org/grpc/internal/channelz"
@ -498,13 +497,13 @@ func (cs *clientStream) shouldRetry(err error) error {
if len(sps) == 1 {
var e error
if pushback, e = strconv.Atoi(sps[0]); e != nil || pushback < 0 {
grpclog.Infof("Server retry pushback specified to abort (%q).", sps[0])
channelz.Infof(cs.cc.channelzID, "Server retry pushback specified to abort (%q).", sps[0])
cs.retryThrottler.throttle() // This counts as a failure for throttling.
return err
}
hasPushback = true
} else if len(sps) > 1 {
grpclog.Warningf("Server retry pushback specified multiple values (%q); not retrying.", sps)
channelz.Warningf(cs.cc.channelzID, "Server retry pushback specified multiple values (%q); not retrying.", sps)
cs.retryThrottler.throttle() // This counts as a failure for throttling.
return err
}

View file

@ -19,4 +19,4 @@
package grpc
// Version is the current grpc version.
const Version = "1.27.1"
const Version = "1.28.0"

View file

@ -94,7 +94,7 @@ go list -f {{.Dir}} ./... | xargs go run test/go_vet/vet.go
gofmt -s -d -l . 2>&1 | fail_on_output
goimports -l . 2>&1 | (! grep -vE "(_mock|\.pb)\.go")
golint ./... 2>&1 | (! grep -vE "(_mock|\.pb)\.go:")
go vet -all .
go vet -all ./...
misspell -error .
@ -151,6 +151,7 @@ grpc.WithMaxMsgSize
grpc.WithServiceConfig
grpc.WithTimeout
http.CloseNotifier
info.SecurityVersion
naming.Resolver
naming.Update
naming.Watcher

19
vendor/modules.txt vendored
View file

@ -1,4 +1,4 @@
# cloud.google.com/go v0.53.0
# cloud.google.com/go v0.54.0
cloud.google.com/go
cloud.google.com/go/compute/metadata
cloud.google.com/go/iam
@ -63,7 +63,7 @@ github.com/aws/aws-sdk-go/service/sts/stsiface
github.com/cespare/xxhash/v2
# github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e
github.com/golang/groupcache/lru
# github.com/golang/protobuf v1.3.3
# github.com/golang/protobuf v1.3.4
github.com/golang/protobuf/proto
github.com/golang/protobuf/protoc-gen-go
github.com/golang/protobuf/protoc-gen-go/descriptor
@ -79,7 +79,7 @@ github.com/golang/protobuf/ptypes/timestamp
github.com/golang/snappy
# github.com/googleapis/gax-go/v2 v2.0.5
github.com/googleapis/gax-go/v2
# github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af
# github.com/jmespath/go-jmespath v0.0.0-20200310193758-2437e8417af5
github.com/jmespath/go-jmespath
# github.com/jstemmer/go-junit-report v0.9.1
github.com/jstemmer/go-junit-report
@ -128,16 +128,13 @@ go.opencensus.io/trace
go.opencensus.io/trace/internal
go.opencensus.io/trace/propagation
go.opencensus.io/trace/tracestate
# golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6
golang.org/x/exp/apidiff
golang.org/x/exp/cmd/apidiff
# golang.org/x/lint v0.0.0-20200130185559-910be7a94367
# golang.org/x/lint v0.0.0-20200302205851-738671d3881b
golang.org/x/lint
golang.org/x/lint/golint
# golang.org/x/mod v0.2.0
golang.org/x/mod/module
golang.org/x/mod/semver
# golang.org/x/net v0.0.0-20200226121028-0de0cce0169b
# golang.org/x/net v0.0.0-20200301022130-244492dfa37a
golang.org/x/net/context
golang.org/x/net/context/ctxhttp
golang.org/x/net/http/httpguts
@ -206,13 +203,13 @@ google.golang.org/appengine/internal/modules
google.golang.org/appengine/internal/remote_api
google.golang.org/appengine/internal/urlfetch
google.golang.org/appengine/urlfetch
# google.golang.org/genproto v0.0.0-20200225123651-fc8f55426688
# google.golang.org/genproto v0.0.0-20200312145019-da6875a35672
google.golang.org/genproto/googleapis/api/annotations
google.golang.org/genproto/googleapis/iam/v1
google.golang.org/genproto/googleapis/rpc/code
google.golang.org/genproto/googleapis/rpc/status
google.golang.org/genproto/googleapis/type/expr
# google.golang.org/grpc v1.27.1
# google.golang.org/grpc v1.28.0
google.golang.org/grpc
google.golang.org/grpc/attributes
google.golang.org/grpc/backoff
@ -234,8 +231,10 @@ google.golang.org/grpc/internal/binarylog
google.golang.org/grpc/internal/buffer
google.golang.org/grpc/internal/channelz
google.golang.org/grpc/internal/envconfig
google.golang.org/grpc/internal/grpclog
google.golang.org/grpc/internal/grpcrand
google.golang.org/grpc/internal/grpcsync
google.golang.org/grpc/internal/grpcutil
google.golang.org/grpc/internal/resolver/dns
google.golang.org/grpc/internal/resolver/passthrough
google.golang.org/grpc/internal/syscall