diff --git a/go.mod b/go.mod index 6faa6b644..32a01e8da 100644 --- a/go.mod +++ b/go.mod @@ -25,11 +25,9 @@ require ( github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 // indirect github.com/eapache/queue v1.1.0 // indirect github.com/emirpasic/gods v1.12.0 - github.com/frankban/quicktest v1.9.0 // indirect github.com/fsouza/go-dockerclient v1.4.1 github.com/go-kit/kit v0.8.0 - github.com/gogo/protobuf v1.2.1 // indirect - github.com/golang/protobuf v1.3.3 + github.com/golang/protobuf v1.5.0 github.com/gorilla/handlers v1.4.0 github.com/gorilla/mux v1.7.2 github.com/grpc-ecosystem/go-grpc-middleware v1.1.0 @@ -39,15 +37,14 @@ require ( github.com/hyperledger/fabric-config v0.0.5 github.com/hyperledger/fabric-lib-go v1.0.0 github.com/hyperledger/fabric-protos-go v0.0.0-20200506201313-25f6564b9ac4 - github.com/konsorten/go-windows-terminal-sequences v1.0.2 // indirect - github.com/kr/pretty v0.2.0 + github.com/kr/pretty v0.2.1 github.com/magiconair/properties v1.8.1 // indirect github.com/mattn/go-runewidth v0.0.4 // indirect github.com/miekg/pkcs11 v1.0.3 github.com/mitchellh/mapstructure v1.2.2 github.com/onsi/ginkgo v1.8.0 github.com/onsi/gomega v1.9.0 - github.com/opencontainers/runc v1.0.0-rc8 // indirect + github.com/opencontainers/runc v1.1.2 // indirect github.com/pierrec/lz4 v2.5.0+incompatible // indirect github.com/pkg/errors v0.8.1 github.com/prometheus/client_golang v1.1.0 @@ -67,7 +64,6 @@ require ( go.etcd.io/etcd v0.5.0-alpha.5.0.20181228115726-23731bf9ba55 go.uber.org/zap v1.14.1 golang.org/x/crypto v0.0.0-20200221231518-2aa609cf4a9d - golang.org/x/text v0.3.2 // indirect golang.org/x/tools v0.0.0-20200131233409-575de47986ce google.golang.org/grpc v1.29.1 gopkg.in/alecthomas/kingpin.v2 v2.2.6 diff --git a/go.sum b/go.sum index b6964caec..0781aac8c 100644 --- a/go.sum +++ b/go.sum @@ -37,8 +37,11 @@ github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kB github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= 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/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8= github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= @@ -46,9 +49,12 @@ github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3Ee github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a h1:W8b4lQ4tFF21aspRGoBuCNV6V2fFJBF+pm1J6OY8Lys= github.com/coreos/go-systemd v0.0.0-20190620071333-e64a0ec8b42a/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea h1:n2Ltr3SrfQlf/9nOna1DoGKxLx3qTSI8Ttl6Xrqp6mw= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= 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= @@ -78,8 +84,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/frankban/quicktest v1.9.0 h1:jfEA+Psfr/pHsRJYPpHiNu7PGJnGctNxvTaM3K1EyXk= -github.com/frankban/quicktest v1.9.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= +github.com/frankban/quicktest v1.11.3 h1:8sXhOn0uLys67V8EsXLc6eszDs8VXWxL3iRvebPhedY= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsouza/go-dockerclient v1.4.1 h1:W7wuJ3IB48WYZv/UBk9dCTIb9oX805+L9KIm65HcUYs= @@ -92,6 +98,8 @@ github.com/go-logfmt/logfmt v0.4.0 h1:MP4Eh7ZCb31lleYCFuwm0oe4/YGak+5l1vA2NOE80n github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1 h1:/s5zKNz0uPFCZ5hddgPdo2TK2TVrUNMn0OOX8/aZMTE= @@ -103,16 +111,18 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 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.5.0 h1:LUVKkCeviFUMKqHa4tXIIij/lbhnMbP7Fn5wKdKkRh4= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= 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-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= -github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -142,7 +152,6 @@ github.com/hyperledger/fabric-protos-go v0.0.0-20190919234611-2a87503ac7c9/go.mo github.com/hyperledger/fabric-protos-go v0.0.0-20200424173316-dd554ba3746e/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= github.com/hyperledger/fabric-protos-go v0.0.0-20200506201313-25f6564b9ac4 h1:75hBp86WljV3uQ7Q/wbO5w8ahfLAzxH7jfT5kVy2n6g= github.com/hyperledger/fabric-protos-go v0.0.0-20200506201313-25f6564b9ac4/go.mod h1:xVYTjK4DtZRBxZ2D9aE4y6AbLaPwue2o/criQyQbVD0= -github.com/hyperledger/fabric-protos-go v0.0.0-20200819205323-f34c922b9e79 h1:ROrJn/Oax+H3vYzrC8tNwQU25+tEIxWuY2DEYIjViVA= github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd h1:anPrsicrIi2ColgWTVPk+TrN42hJIWlfPHSBP9S0ZkM= github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd/go.mod h1:3LVOLeyx9XVvwPgrt2be44XgSqndprz1G18rSk8KD84= github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= @@ -154,13 +163,11 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.0.0/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= @@ -181,10 +188,12 @@ github.com/miekg/pkcs11 v1.0.3 h1:iMwmD7I5225wv84WxIG/bmxz9AXjWvTWIbM/TYHvWtw= github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= github.com/mitchellh/mapstructure v1.2.2 h1:dxe5oCinTXiTIcfgmZecdCzPmAJKd46KsCWc35r0TV4= github.com/mitchellh/mapstructure v1.2.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= @@ -200,8 +209,10 @@ github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQ github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc8 h1:dDCFes8Hj1r/i5qnypONo5jdOme/8HWZC/aNDyhECt0= -github.com/opencontainers/runc v1.0.0-rc8/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.1.2 h1:2VSZwLx5k/BfsBxMMipG/LYUnmqOD/BPkIVgQUcTlLw= +github.com/opencontainers/runc v1.1.2/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pierrec/lz4 v2.5.0+incompatible h1:MbdIZ43A//duwOjQqK3nP+up+65yraNFyX3Vp6Rwues= github.com/pierrec/lz4 v2.5.0+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= @@ -232,13 +243,16 @@ github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDa github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a h1:9ZKAASQSHhDYGoxY8uLVpewe1GDZ2vu2Tr/vTdVAkFQ= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.0.5/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.3.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -263,7 +277,7 @@ github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/sykesm/zap-logfmt v0.0.2 h1:czSzn+PIXCOAP/4NAIHTTziIKB8201PzoDkKTn+VR/8= github.com/sykesm/zap-logfmt v0.0.2/go.mod h1:TerDJT124HaO8UTpZ2wJCipJRAKQ9XONM1mzUabIh6M= -github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFdE= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/syndtr/goleveldb v1.0.1-0.20190625010220-02440ea7a285 h1:uSDYjYejelKyceA6DiCsngFof9jAyeaSyX9XC5a1a7Q= github.com/syndtr/goleveldb v1.0.1-0.20190625010220-02440ea7a285/go.mod h1:9OrXJhf154huy1nPWmuSrkgjPUtUNhA+Zmy+6AESzuA= github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc h1:LUUe4cdABGrIJAhl1P1ZpWY76AwukVszFdwkVFVLwIk= @@ -271,11 +285,11 @@ github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955u github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ugorji/go v1.1.1/go.mod h1:hnLbHMwcvSihnDhEfx2/BzKp2xb0Y+ErdfYcrs9tkJQ= github.com/urfave/cli v1.18.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc= -github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/willf/bitset v1.1.11 h1:N7Z7E9UvjW+sGsEl7k/SJrvY2reP1A07MrGuCjIOjRE= github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= -github.com/willf/bloom v1.0.0 h1:D857mzMaGe1NU89jxegrN7Feh44FOQqbwzkMbMBdNz0= github.com/willf/bloom v2.0.3+incompatible h1:QDacWdqcAUI1MPOwIQZRy9kOR7yxfyEmxX8Wdm2/JPA= github.com/willf/bloom v2.0.3+incompatible/go.mod h1:MmAltL9pDMNTrvUkxdg0k0q5I0suxmuwp3KbyrZLOZ8= github.com/xiang90/probing v0.0.0-20160813154853-07dd2e8dfe18/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= @@ -317,8 +331,9 @@ golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859 h1:R/3boaszxrf1GEUWTVDzSKVwLmSJpwZ1yqXm8j0v2QI= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b h1:iFwSg7t5GZmB/Q5TjiEAsdoLDrdJRC1RiF2WhuV29Qw= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -327,9 +342,10 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEha golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190920190810-ef0ce1748380 h1:pWpXa9KDLGZQe5bzYO50QaTE0ddH+vzBKtP32311cD8= golang.org/x/sys v0.0.0-20190920190810-ef0ce1748380/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= -golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -358,6 +374,9 @@ google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -375,7 +394,6 @@ gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkep gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= diff --git a/vendor/github.com/emirpasic/gods/README.md b/vendor/github.com/emirpasic/gods/README.md deleted file mode 100644 index 7346b994e..000000000 --- a/vendor/github.com/emirpasic/gods/README.md +++ /dev/null @@ -1,1508 +0,0 @@ -[![GoDoc](https://godoc.org/github.com/emirpasic/gods?status.svg)](https://godoc.org/github.com/emirpasic/gods) [![Build Status](https://travis-ci.org/emirpasic/gods.svg)](https://travis-ci.org/emirpasic/gods) [![Go Report Card](https://goreportcard.com/badge/github.com/emirpasic/gods)](https://goreportcard.com/report/github.com/emirpasic/gods) [![PyPI](https://img.shields.io/pypi/l/Django.svg?maxAge=2592000)](https://github.com/emirpasic/gods/blob/master/LICENSE) - -# GoDS (Go Data Structures) - -Implementation of various data structures and algorithms in Go. - -## Data Structures - -- [Containers](#containers) - - [Lists](#lists) - - [ArrayList](#arraylist) - - [SinglyLinkedList](#singlylinkedlist) - - [DoublyLinkedList](#doublylinkedlist) - - [Sets](#sets) - - [HashSet](#hashset) - - [TreeSet](#treeset) - - [LinkedHashSet](#linkedhashset) - - [Stacks](#stacks) - - [LinkedListStack](#linkedliststack) - - [ArrayStack](#arraystack) - - [Maps](#maps) - - [HashMap](#hashmap) - - [TreeMap](#treemap) - - [LinkedHashMap](#linkedhashmap) - - [HashBidiMap](#hashbidimap) - - [TreeBidiMap](#treebidimap) - - [Trees](#trees) - - [RedBlackTree](#redblacktree) - - [AVLTree](#avltree) - - [BTree](#btree) - - [BinaryHeap](#binaryheap) -- [Functions](#functions) - - [Comparator](#comparator) - - [Iterator](#iterator) - - [IteratorWithIndex](#iteratorwithindex) - - [IteratorWithKey](#iteratorwithkey) - - [ReverseIteratorWithIndex](#reverseiteratorwithindex) - - [ReverseIteratorWithKey](#reverseiteratorwithkey) - - [Enumerable](#enumerable) - - [EnumerableWithIndex](#enumerablewithindex) - - [EnumerableWithKey](#enumerablewithkey) - - [Serialization](#serialization) - - [JSONSerializer](#jsonserializer) - - [JSONDeserializer](#jsondeserializer) - - [Sort](#sort) - - [Container](#container) -- [Appendix](#appendix) - - -## Containers - -All data structures implement the container interface with the following methods: - -```go -type Container interface { - Empty() bool - Size() int - Clear() - Values() []interface{} -} -``` - -Containers are either ordered or unordered. All ordered containers provide [stateful iterators](#iterator) and some of them allow [enumerable functions](#enumerable). - -| **Data** | **Structure** | **Ordered** | **[Iterator](#iterator)** | **[Enumerable](#enumerable)** | **Referenced by** | -| :--- | :--- | :---: | :---: | :---: | :---: | -| [Lists](#lists) | -| | [ArrayList](#arraylist) | yes | yes* | yes | index | -| | [SinglyLinkedList](#singlylinkedlist) | yes | yes | yes | index | -| | [DoublyLinkedList](#doublylinkedlist) | yes | yes* | yes | index | -| [Sets](#sets) | -| | [HashSet](#hashset) | no | no | no | index | -| | [TreeSet](#treeset) | yes | yes* | yes | index | -| | [LinkedHashSet](#linkedhashset) | yes | yes* | yes | index | -| [Stacks](#stacks) | -| | [LinkedListStack](#linkedliststack) | yes | yes | no | index | -| | [ArrayStack](#arraystack) | yes | yes* | no | index | -| [Maps](#maps) | -| | [HashMap](#hashmap) | no | no | no | key | -| | [TreeMap](#treemap) | yes | yes* | yes | key | -| | [LinkedHashMap](#linkedhashmap) | yes | yes* | yes | key | -| | [HashBidiMap](#hashbidimap) | no | no | no | key* | -| | [TreeBidiMap](#treebidimap) | yes | yes* | yes | key* | -| [Trees](#trees) | -| | [RedBlackTree](#redblacktree) | yes | yes* | no | key | -| | [AVLTree](#avltree) | yes | yes* | no | key | -| | [BTree](#btree) | yes | yes* | no | key | -| | [BinaryHeap](#binaryheap) | yes | yes* | no | index | -| | | | *reversible | | *bidirectional | - -### Lists - -A list is a data structure that stores values and may have repeated values. - -Implements [Container](#containers) interface. - -```go -type List interface { - Get(index int) (interface{}, bool) - Remove(index int) - Add(values ...interface{}) - Contains(values ...interface{}) bool - Sort(comparator utils.Comparator) - Swap(index1, index2 int) - Insert(index int, values ...interface{}) - Set(index int, value interface{}) - - containers.Container - // Empty() bool - // Size() int - // Clear() - // Values() []interface{} -} -``` - -#### ArrayList - -A [list](#lists) backed by a dynamic array that grows and shrinks implicitly. - -Implements [List](#lists), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import ( - "github.com/emirpasic/gods/lists/arraylist" - "github.com/emirpasic/gods/utils" -) - -func main() { - list := arraylist.New() - list.Add("a") // ["a"] - list.Add("c", "b") // ["a","c","b"] - list.Sort(utils.StringComparator) // ["a","b","c"] - _, _ = list.Get(0) // "a",true - _, _ = list.Get(100) // nil,false - _ = list.Contains("a", "b", "c") // true - _ = list.Contains("a", "b", "c", "d") // false - list.Swap(0, 1) // ["b","a",c"] - list.Remove(2) // ["b","a"] - list.Remove(1) // ["b"] - list.Remove(0) // [] - list.Remove(0) // [] (ignored) - _ = list.Empty() // true - _ = list.Size() // 0 - list.Add("a") // ["a"] - list.Clear() // [] - list.Insert(0, "b") // ["b"] - list.Insert(0, "a") // ["a","b"] -} -``` - -#### SinglyLinkedList - -A [list](#lists) where each element points to the next element in the list. - -Implements [List](#lists), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import ( - sll "github.com/emirpasic/gods/lists/singlylinkedlist" - "github.com/emirpasic/gods/utils" -) - -func main() { - list := sll.New() - list.Add("a") // ["a"] - list.Add("c", "b") // ["a","c","b"] - list.Sort(utils.StringComparator) // ["a","b","c"] - _, _ = list.Get(0) // "a",true - _, _ = list.Get(100) // nil,false - _ = list.Contains("a", "b", "c") // true - _ = list.Contains("a", "b", "c", "d") // false - list.Swap(0, 1) // ["b","a",c"] - list.Remove(2) // ["b","a"] - list.Remove(1) // ["b"] - list.Remove(0) // [] - list.Remove(0) // [] (ignored) - _ = list.Empty() // true - _ = list.Size() // 0 - list.Add("a") // ["a"] - list.Clear() // [] - list.Insert(0, "b") // ["b"] - list.Insert(0, "a") // ["a","b"] -} -``` - -#### DoublyLinkedList - -A [list](#lists) where each element points to the next and previous elements in the list. - -Implements [List](#lists), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import ( - dll "github.com/emirpasic/gods/lists/doublylinkedlist" - "github.com/emirpasic/gods/utils" -) - -func main() { - list := dll.New() - list.Add("a") // ["a"] - list.Add("c", "b") // ["a","c","b"] - list.Sort(utils.StringComparator) // ["a","b","c"] - _, _ = list.Get(0) // "a",true - _, _ = list.Get(100) // nil,false - _ = list.Contains("a", "b", "c") // true - _ = list.Contains("a", "b", "c", "d") // false - list.Swap(0, 1) // ["b","a",c"] - list.Remove(2) // ["b","a"] - list.Remove(1) // ["b"] - list.Remove(0) // [] - list.Remove(0) // [] (ignored) - _ = list.Empty() // true - _ = list.Size() // 0 - list.Add("a") // ["a"] - list.Clear() // [] - list.Insert(0, "b") // ["b"] - list.Insert(0, "a") // ["a","b"] -} -``` - -### Sets - -A set is a data structure that can store elements and has no repeated values. It is a computer implementation of the mathematical concept of a finite set. Unlike most other collection types, rather than retrieving a specific element from a set, one typically tests an element for membership in a set. This structure is often used to ensure that no duplicates are present in a container. - -Implements [Container](#containers) interface. - -```go -type Set interface { - Add(elements ...interface{}) - Remove(elements ...interface{}) - Contains(elements ...interface{}) bool - - containers.Container - // Empty() bool - // Size() int - // Clear() - // Values() []interface{} -} -``` - -#### HashSet - -A [set](#sets) backed by a hash table (actually a Go's map). It makes no guarantees as to the iteration order of the set. - -Implements [Set](#sets), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import "github.com/emirpasic/gods/sets/hashset" - -func main() { - set := hashset.New() // empty - set.Add(1) // 1 - set.Add(2, 2, 3, 4, 5) // 3, 1, 2, 4, 5 (random order, duplicates ignored) - set.Remove(4) // 5, 3, 2, 1 (random order) - set.Remove(2, 3) // 1, 5 (random order) - set.Contains(1) // true - set.Contains(1, 5) // true - set.Contains(1, 6) // false - _ = set.Values() // []int{5,1} (random order) - set.Clear() // empty - set.Empty() // true - set.Size() // 0 -} -``` - -#### TreeSet - -A [set](#sets) backed by a [red-black tree](#redblacktree) to keep the elements ordered with respect to the [comparator](#comparator). - -Implements [Set](#sets), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import "github.com/emirpasic/gods/sets/treeset" - -func main() { - set := treeset.NewWithIntComparator() // empty (keys are of type int) - set.Add(1) // 1 - set.Add(2, 2, 3, 4, 5) // 1, 2, 3, 4, 5 (in order, duplicates ignored) - set.Remove(4) // 1, 2, 3, 5 (in order) - set.Remove(2, 3) // 1, 5 (in order) - set.Contains(1) // true - set.Contains(1, 5) // true - set.Contains(1, 6) // false - _ = set.Values() // []int{1,5} (in order) - set.Clear() // empty - set.Empty() // true - set.Size() // 0 -} -``` - -#### LinkedHashSet - -A [set](#sets) that preserves insertion-order. Data structure is backed by a hash table to store values and [doubly-linked list](#doublylinkedlist) to store insertion ordering. - -Implements [Set](#sets), [IteratorWithIndex](#iteratorwithindex), [EnumerableWithIndex](#enumerablewithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import "github.com/emirpasic/gods/sets/linkedhashset" - -func main() { - set := linkedhashset.New() // empty - set.Add(5) // 5 - set.Add(4, 4, 3, 2, 1) // 5, 4, 3, 2, 1 (in insertion-order, duplicates ignored) - set.Add(4) // 5, 4, 3, 2, 1 (duplicates ignored, insertion-order unchanged) - set.Remove(4) // 5, 3, 2, 1 (in insertion-order) - set.Remove(2, 3) // 5, 1 (in insertion-order) - set.Contains(1) // true - set.Contains(1, 5) // true - set.Contains(1, 6) // false - _ = set.Values() // []int{5, 1} (in insertion-order) - set.Clear() // empty - set.Empty() // true - set.Size() // 0 -} -``` - -### Stacks - -A stack that represents a last-in-first-out (LIFO) data structure. The usual push and pop operations are provided, as well as a method to peek at the top item on the stack. - -Implements [Container](#containers) interface. - -```go -type Stack interface { - Push(value interface{}) - Pop() (value interface{}, ok bool) - Peek() (value interface{}, ok bool) - - containers.Container - // Empty() bool - // Size() int - // Clear() - // Values() []interface{} -} -``` - -#### LinkedListStack - -A [stack](#stacks) based on a [linked list](#singlylinkedlist). - -Implements [Stack](#stacks), [IteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import lls "github.com/emirpasic/gods/stacks/linkedliststack" - -func main() { - stack := lls.New() // empty - stack.Push(1) // 1 - stack.Push(2) // 1, 2 - stack.Values() // 2, 1 (LIFO order) - _, _ = stack.Peek() // 2,true - _, _ = stack.Pop() // 2, true - _, _ = stack.Pop() // 1, true - _, _ = stack.Pop() // nil, false (nothing to pop) - stack.Push(1) // 1 - stack.Clear() // empty - stack.Empty() // true - stack.Size() // 0 -} -``` - -#### ArrayStack - -A [stack](#stacks) based on a [array list](#arraylist). - -Implements [Stack](#stacks), [IteratorWithIndex](#iteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import "github.com/emirpasic/gods/stacks/arraystack" - -func main() { - stack := arraystack.New() // empty - stack.Push(1) // 1 - stack.Push(2) // 1, 2 - stack.Values() // 2, 1 (LIFO order) - _, _ = stack.Peek() // 2,true - _, _ = stack.Pop() // 2, true - _, _ = stack.Pop() // 1, true - _, _ = stack.Pop() // nil, false (nothing to pop) - stack.Push(1) // 1 - stack.Clear() // empty - stack.Empty() // true - stack.Size() // 0 -} -``` - -### Maps - -A Map is a data structure that maps keys to values. A map cannot contain duplicate keys and each key can map to at most one value. - -Implements [Container](#containers) interface. - -```go -type Map interface { - Put(key interface{}, value interface{}) - Get(key interface{}) (value interface{}, found bool) - Remove(key interface{}) - Keys() []interface{} - - containers.Container - // Empty() bool - // Size() int - // Clear() - // Values() []interface{} -} -``` - -A BidiMap is an extension to the Map. A bidirectional map (BidiMap), also called a hash bag, is an associative data structure in which the key-value pairs form a one-to-one relation. This relation works in both directions by allow the value to also act as a key to key, e.g. a pair (a,b) thus provides a coupling between 'a' and 'b' so that 'b' can be found when 'a' is used as a key and 'a' can be found when 'b' is used as a key. - -```go -type BidiMap interface { - GetKey(value interface{}) (key interface{}, found bool) - - Map -} -``` - -#### HashMap - -A [map](#maps) based on hash tables. Keys are unordered. - -Implements [Map](#maps), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import "github.com/emirpasic/gods/maps/hashmap" - -func main() { - m := hashmap.New() // empty - m.Put(1, "x") // 1->x - m.Put(2, "b") // 2->b, 1->x (random order) - m.Put(1, "a") // 2->b, 1->a (random order) - _, _ = m.Get(2) // b, true - _, _ = m.Get(3) // nil, false - _ = m.Values() // []interface {}{"b", "a"} (random order) - _ = m.Keys() // []interface {}{1, 2} (random order) - m.Remove(1) // 2->b - m.Clear() // empty - m.Empty() // true - m.Size() // 0 -} -``` - -#### TreeMap - -A [map](#maps) based on [red-black tree](#redblacktree). Keys are ordered with respect to the [comparator](#comparator). - -Implements [Map](#maps), [IteratorWithKey](#iteratorwithkey), [EnumerableWithKey](#enumerablewithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import "github.com/emirpasic/gods/maps/treemap" - -func main() { - m := treemap.NewWithIntComparator() // empty (keys are of type int) - m.Put(1, "x") // 1->x - m.Put(2, "b") // 1->x, 2->b (in order) - m.Put(1, "a") // 1->a, 2->b (in order) - _, _ = m.Get(2) // b, true - _, _ = m.Get(3) // nil, false - _ = m.Values() // []interface {}{"a", "b"} (in order) - _ = m.Keys() // []interface {}{1, 2} (in order) - m.Remove(1) // 2->b - m.Clear() // empty - m.Empty() // true - m.Size() // 0 - - // Other: - m.Min() // Returns the minimum key and its value from map. - m.Max() // Returns the maximum key and its value from map. -} -``` - -#### LinkedHashMap - -A [map](#maps) that preserves insertion-order. It is backed by a hash table to store values and [doubly-linked list](doublylinkedlist) to store ordering. - -Implements [Map](#maps), [IteratorWithKey](#iteratorwithkey), [EnumerableWithKey](#enumerablewithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import "github.com/emirpasic/gods/maps/linkedhashmap" - -func main() { - m := linkedhashmap.New() // empty (keys are of type int) - m.Put(2, "b") // 2->b - m.Put(1, "x") // 2->b, 1->x (insertion-order) - m.Put(1, "a") // 2->b, 1->a (insertion-order) - _, _ = m.Get(2) // b, true - _, _ = m.Get(3) // nil, false - _ = m.Values() // []interface {}{"b", "a"} (insertion-order) - _ = m.Keys() // []interface {}{2, 1} (insertion-order) - m.Remove(1) // 2->b - m.Clear() // empty - m.Empty() // true - m.Size() // 0 -} - -``` - -#### HashBidiMap - -A [map](#maps) based on two hashmaps. Keys are unordered. - -Implements [BidiMap](#maps), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import "github.com/emirpasic/gods/maps/hashbidimap" - -func main() { - m := hashbidimap.New() // empty - m.Put(1, "x") // 1->x - m.Put(3, "b") // 1->x, 3->b (random order) - m.Put(1, "a") // 1->a, 3->b (random order) - m.Put(2, "b") // 1->a, 2->b (random order) - _, _ = m.GetKey("a") // 1, true - _, _ = m.Get(2) // b, true - _, _ = m.Get(3) // nil, false - _ = m.Values() // []interface {}{"a", "b"} (random order) - _ = m.Keys() // []interface {}{1, 2} (random order) - m.Remove(1) // 2->b - m.Clear() // empty - m.Empty() // true - m.Size() // 0 -} -``` - -#### TreeBidiMap - -A [map](#maps) based on red-black tree. This map guarantees that the map will be in both ascending key and value order. Other than key and value ordering, the goal with this structure is to avoid duplication of elements (unlike in [HashBidiMap](#hashbidimap)), which can be significant if contained elements are large. - -Implements [BidiMap](#maps), [IteratorWithKey](#iteratorwithkey), [EnumerableWithKey](#enumerablewithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -```go -package main - -import ( - "github.com/emirpasic/gods/maps/treebidimap" - "github.com/emirpasic/gods/utils" -) - -func main() { - m := treebidimap.NewWith(utils.IntComparator, utils.StringComparator) - m.Put(1, "x") // 1->x - m.Put(3, "b") // 1->x, 3->b (ordered) - m.Put(1, "a") // 1->a, 3->b (ordered) - m.Put(2, "b") // 1->a, 2->b (ordered) - _, _ = m.GetKey("a") // 1, true - _, _ = m.Get(2) // b, true - _, _ = m.Get(3) // nil, false - _ = m.Values() // []interface {}{"a", "b"} (ordered) - _ = m.Keys() // []interface {}{1, 2} (ordered) - m.Remove(1) // 2->b - m.Clear() // empty - m.Empty() // true - m.Size() // 0 -} -``` - -### Trees - -A tree is a widely used data data structure that simulates a hierarchical tree structure, with a root value and subtrees of children, represented as a set of linked nodes; thus no cyclic links. - -Implements [Container](#containers) interface. - -```go -type Tree interface { - containers.Container - // Empty() bool - // Size() int - // Clear() - // Values() []interface{} -} -``` - -#### RedBlackTree - -A red–black [tree](#trees) is a binary search tree with an extra bit of data per node, its color, which can be either red or black. The extra bit of storage ensures an approximately balanced tree by constraining how nodes are colored from any path from the root to the leaf. Thus, it is a data structure which is a type of self-balancing binary search tree. - -The balancing of the tree is not perfect but it is good enough to allow it to guarantee searching in O(log n) time, where n is the total number of elements in the tree. The insertion and deletion operations, along with the tree rearrangement and recoloring, are also performed in O(log n) time. [Wikipedia](http://en.wikipedia.org/wiki/Red%E2%80%93black_tree) - -Implements [Tree](#trees), [ReverseIteratorWithKey](#reverseiteratorwithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -

- -```go -package main - -import ( - "fmt" - rbt "github.com/emirpasic/gods/trees/redblacktree" -) - -func main() { - tree := rbt.NewWithIntComparator() // empty (keys are of type int) - - tree.Put(1, "x") // 1->x - tree.Put(2, "b") // 1->x, 2->b (in order) - tree.Put(1, "a") // 1->a, 2->b (in order, replacement) - tree.Put(3, "c") // 1->a, 2->b, 3->c (in order) - tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order) - tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order) - tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order) - - fmt.Println(tree) - // - // RedBlackTree - // │ ┌── 6 - // │ ┌── 5 - // │ ┌── 4 - // │ │ └── 3 - // └── 2 - // └── 1 - - _ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f"} (in order) - _ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6} (in order) - - tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order) - fmt.Println(tree) - // - // RedBlackTree - // │ ┌── 6 - // │ ┌── 5 - // └── 4 - // │ ┌── 3 - // └── 1 - - tree.Clear() // empty - tree.Empty() // true - tree.Size() // 0 - - // Other: - tree.Left() // gets the left-most (min) node - tree.Right() // get the right-most (max) node - tree.Floor(1) // get the floor node - tree.Ceiling(1) // get the ceiling node -} -``` - -Extending the red-black tree's functionality has been demonstrated in the following [example](https://github.com/emirpasic/gods/blob/master/examples/redblacktreeextended/redblacktreeextended.go). - -#### AVLTree - -AVL [tree](#trees) is a self-balancing binary search tree. In an AVL tree, the heights of the two child subtrees of any node differ by at most one; if at any time they differ by more than one, rebalancing is done to restore this property. Lookup, insertion, and deletion all take O(log n) time in both the average and worst cases, where n is the number of nodes in the tree prior to the operation. Insertions and deletions may require the tree to be rebalanced by one or more tree rotations. - -AVL trees are often compared with red–black trees because both support the same set of operations and take O(log n) time for the basic operations. For lookup-intensive applications, AVL trees are faster than red–black trees because they are more strictly balanced. [Wikipedia](https://en.wikipedia.org/wiki/AVL_tree) - -Implements [Tree](#trees), [ReverseIteratorWithKey](#reverseiteratorwithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -


AVL tree with balance factors (green)

- -```go -package main - -import ( - "fmt" - avl "github.com/emirpasic/gods/trees/avltree" -) - -func main() { - tree := avl.NewWithIntComparator() // empty(keys are of type int) - - tree.Put(1, "x") // 1->x - tree.Put(2, "b") // 1->x, 2->b (in order) - tree.Put(1, "a") // 1->a, 2->b (in order, replacement) - tree.Put(3, "c") // 1->a, 2->b, 3->c (in order) - tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order) - tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order) - tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order) - - fmt.Println(tree) - // - // AVLTree - // │ ┌── 6 - // │ ┌── 5 - // └── 4 - // │ ┌── 3 - // └── 2 - // └── 1 - - - _ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f"} (in order) - _ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6} (in order) - - tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order) - fmt.Println(tree) - // - // AVLTree - // │ ┌── 6 - // │ ┌── 5 - // └── 4 - // └── 3 - // └── 1 - - tree.Clear() // empty - tree.Empty() // true - tree.Size() // 0 -} -``` - -#### BTree - -B-tree is a self-balancing tree data structure that keeps data sorted and allows searches, sequential access, insertions, and deletions in logarithmic time. The B-tree is a generalization of a binary search tree in that a node can have more than two children. - -According to Knuth's definition, a B-tree of order m is a tree which satisfies the following properties: - -- Every node has at most m children. -- Every non-leaf node (except root) has at least ⌈m/2⌉ children. -- The root has at least two children if it is not a leaf node. -- A non-leaf node with k children contains k−1 keys. -- All leaves appear in the same level - -Each internal node’s keys act as separation values which divide its subtrees. For example, if an internal node has 3 child nodes (or subtrees) then it must have 2 keys: a1 and a2. All values in the leftmost subtree will be less than a1, all values in the middle subtree will be between a1 and a2, and all values in the rightmost subtree will be greater than a2.[Wikipedia](http://en.wikipedia.org/wiki/Red%E2%80%93black_tree) - -Implements [Tree](#trees), [ReverseIteratorWithKey](#reverseiteratorwithkey), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -

- -```go -package main - -import ( - "fmt" - "github.com/emirpasic/gods/trees/btree" -) - -func main() { - tree := btree.NewWithIntComparator(3) // empty (keys are of type int) - - tree.Put(1, "x") // 1->x - tree.Put(2, "b") // 1->x, 2->b (in order) - tree.Put(1, "a") // 1->a, 2->b (in order, replacement) - tree.Put(3, "c") // 1->a, 2->b, 3->c (in order) - tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order) - tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order) - tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order) - tree.Put(7, "g") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f, 7->g (in order) - - fmt.Println(tree) - // BTree - // 1 - // 2 - // 3 - // 4 - // 5 - // 6 - // 7 - - _ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f", "g"} (in order) - _ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6, 7} (in order) - - tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f, 7->g (in order) - fmt.Println(tree) - // BTree - // 1 - // 3 - // 4 - // 5 - // 6 - // 7 - - tree.Clear() // empty - tree.Empty() // true - tree.Size() // 0 - - // Other: - tree.Height() // gets the height of the tree - tree.Left() // gets the left-most (min) node - tree.LeftKey() // get the left-most (min) node's key - tree.LeftValue() // get the left-most (min) node's value - tree.Right() // get the right-most (max) node - tree.RightKey() // get the right-most (max) node's key - tree.RightValue() // get the right-most (max) node's value -} -``` - -#### BinaryHeap - -A binary heap is a [tree](#trees) created using a binary tree. It can be seen as a binary tree with two additional constraints: - -- Shape property: - - A binary heap is a complete binary tree; that is, all levels of the tree, except possibly the last one (deepest) are fully filled, and, if the last level of the tree is not complete, the nodes of that level are filled from left to right. -- Heap property: - - All nodes are either greater than or equal to or less than or equal to each of its children, according to a comparison predicate defined for the heap. [Wikipedia](http://en.wikipedia.org/wiki/Binary_heap) - -Implements [Tree](#trees), [ReverseIteratorWithIndex](#reverseiteratorwithindex), [JSONSerializer](#jsonserializer) and [JSONDeserializer](#jsondeserializer) interfaces. - -

- -```go -package main - -import ( - "github.com/emirpasic/gods/trees/binaryheap" - "github.com/emirpasic/gods/utils" -) - -func main() { - - // Min-heap - heap := binaryheap.NewWithIntComparator() // empty (min-heap) - heap.Push(2) // 2 - heap.Push(3) // 2, 3 - heap.Push(1) // 1, 3, 2 - heap.Values() // 1, 3, 2 - _, _ = heap.Peek() // 1,true - _, _ = heap.Pop() // 1, true - _, _ = heap.Pop() // 2, true - _, _ = heap.Pop() // 3, true - _, _ = heap.Pop() // nil, false (nothing to pop) - heap.Push(1) // 1 - heap.Clear() // empty - heap.Empty() // true - heap.Size() // 0 - - // Max-heap - inverseIntComparator := func(a, b interface{}) int { - return -utils.IntComparator(a, b) - } - heap = binaryheap.NewWith(inverseIntComparator) // empty (min-heap) - heap.Push(2, 3, 1) // 3, 2, 1 (bulk optimized) - heap.Values() // 3, 2, 1 -} -``` - -## Functions - -Various helper functions used throughout the library. - -### Comparator - -Some data structures (e.g. TreeMap, TreeSet) require a comparator function to automatically keep their elements sorted upon insertion. This comparator is necessary during the initalization. - -Comparator is defined as: - -Return values (int): - -```go -negative , if a < b -zero , if a == b -positive , if a > b -``` - -Comparator signature: - -```go -type Comparator func(a, b interface{}) int -``` - -All common comparators for builtin types are included in the library: - -```go -func StringComparator(a, b interface{}) int - -func IntComparator(a, b interface{}) int - -func Int8Comparator(a, b interface{}) int - -func Int16Comparator(a, b interface{}) int - -func Int32Comparator(a, b interface{}) int - -func Int64Comparator(a, b interface{}) int - -func UIntComparator(a, b interface{}) int - -func UInt8Comparator(a, b interface{}) int - -func UInt16Comparator(a, b interface{}) int - -func UInt32Comparator(a, b interface{}) int - -func UInt64Comparator(a, b interface{}) int - -func Float32Comparator(a, b interface{}) int - -func Float64Comparator(a, b interface{}) int - -func ByteComparator(a, b interface{}) int - -func RuneComparator(a, b interface{}) int - -func TimeComparator(a, b interface{}) int -``` - -Writing custom comparators is easy: - -```go -package main - -import ( - "fmt" - "github.com/emirpasic/gods/sets/treeset" -) - -type User struct { - id int - name string -} - -// Custom comparator (sort by IDs) -func byID(a, b interface{}) int { - - // Type assertion, program will panic if this is not respected - c1 := a.(User) - c2 := b.(User) - - switch { - case c1.id > c2.id: - return 1 - case c1.id < c2.id: - return -1 - default: - return 0 - } -} - -func main() { - set := treeset.NewWith(byID) - - set.Add(User{2, "Second"}) - set.Add(User{3, "Third"}) - set.Add(User{1, "First"}) - set.Add(User{4, "Fourth"}) - - fmt.Println(set) // {1 First}, {2 Second}, {3 Third}, {4 Fourth} -} -``` - -### Iterator - -All ordered containers have stateful iterators. Typically an iterator is obtained by _Iterator()_ function of an ordered container. Once obtained, iterator's _Next()_ function moves the iterator to the next element and returns true if there was a next element. If there was an element, then element's can be obtained by iterator's _Value()_ function. Depending on the ordering type, it's position can be obtained by iterator's _Index()_ or _Key()_ functions. Some containers even provide reversible iterators, essentially the same, but provide another extra _Prev()_ function that moves the iterator to the previous element and returns true if there was a previous element. - -Note: it is unsafe to remove elements from container while iterating. - -#### IteratorWithIndex - -An [iterator](#iterator) whose elements are referenced by an index. - -Typical usage: -```go -it := list.Iterator() -for it.Next() { - index, value := it.Index(), it.Value() - ... -} -``` - -Other usages: -```go -if it.First() { - firstIndex, firstValue := it.Index(), it.Value() - ... -} -``` - -```go -for it.Begin(); it.Next(); { - ... -} -``` - -#### IteratorWithKey - -An [iterator](#iterator) whose elements are referenced by a key. - -Typical usage: -```go -it := tree.Iterator() -for it.Next() { - key, value := it.Key(), it.Value() - ... -} -``` - -Other usages: -```go -if it.First() { - firstKey, firstValue := it.Key(), it.Value() - ... -} -``` - -```go -for it.Begin(); it.Next(); { - ... -} -``` - -#### ReverseIteratorWithIndex - -An [iterator](#iterator) whose elements are referenced by an index. Provides all functions as [IteratorWithIndex](#iteratorwithindex), but can also be used for reverse iteration. - -Typical usage of iteration in reverse: -```go -it := list.Iterator() -for it.End(); it.Prev(); { - index, value := it.Index(), it.Value() - ... -} -``` - -Other usages: -```go -if it.Last() { - lastIndex, lastValue := it.Index(), it.Value() - ... -} -``` - -#### ReverseIteratorWithKey - -An [iterator](#iterator) whose elements are referenced by a key. Provides all functions as [IteratorWithKey](#iteratorwithkey), but can also be used for reverse iteration. - -Typical usage of iteration in reverse: -```go -it := tree.Iterator() -for it.End(); it.Prev(); { - key, value := it.Key(), it.Value() - ... -} -``` - -Other usages: -```go -if it.Last() { - lastKey, lastValue := it.Key(), it.Value() - ... -} -``` - -### Enumerable - -Enumerable functions for ordered containers that implement [EnumerableWithIndex](#enumerablewithindex) or [EnumerableWithKey](#enumerablewithkey) interfaces. - -#### EnumerableWithIndex - -[Enumerable](#enumerable) functions for ordered containers whose values can be fetched by an index. - -**Each** - -Calls the given function once for each element, passing that element's index and value. - -```go -Each(func(index int, value interface{})) -``` - -**Map** - -Invokes the given function once for each element and returns a container containing the values returned by the given function. - -```go -Map(func(index int, value interface{}) interface{}) Container -``` - -**Select** - -Returns a new container containing all elements for which the given function returns a true value. - -```go -Select(func(index int, value interface{}) bool) Container -``` - -**Any** - -Passes each element of the container to the given function and returns true if the function ever returns true for any element. - -```go -Any(func(index int, value interface{}) bool) bool -``` - -**All** - -Passes each element of the container to the given function and returns true if the function returns true for all elements. - -```go -All(func(index int, value interface{}) bool) bool -``` - -**Find** - -Passes each element of the container to the given function and returns the first (index,value) for which the function is true or -1,nil otherwise if no element matches the criteria. - -```go -Find(func(index int, value interface{}) bool) (int, interface{})} -``` - -**Example:** - -```go -package main - -import ( - "fmt" - "github.com/emirpasic/gods/sets/treeset" -) - -func printSet(txt string, set *treeset.Set) { - fmt.Print(txt, "[ ") - set.Each(func(index int, value interface{}) { - fmt.Print(value, " ") - }) - fmt.Println("]") -} - -func main() { - set := treeset.NewWithIntComparator() - set.Add(2, 3, 4, 2, 5, 6, 7, 8) - printSet("Initial", set) // [ 2 3 4 5 6 7 8 ] - - even := set.Select(func(index int, value interface{}) bool { - return value.(int)%2 == 0 - }) - printSet("Even numbers", even) // [ 2 4 6 8 ] - - foundIndex, foundValue := set.Find(func(index int, value interface{}) bool { - return value.(int)%2 == 0 && value.(int)%3 == 0 - }) - if foundIndex != -1 { - fmt.Println("Number divisible by 2 and 3 found is", foundValue, "at index", foundIndex) // value: 6, index: 4 - } - - square := set.Map(func(index int, value interface{}) interface{} { - return value.(int) * value.(int) - }) - printSet("Numbers squared", square) // [ 4 9 16 25 36 49 64 ] - - bigger := set.Any(func(index int, value interface{}) bool { - return value.(int) > 5 - }) - fmt.Println("Set contains a number bigger than 5 is ", bigger) // true - - positive := set.All(func(index int, value interface{}) bool { - return value.(int) > 0 - }) - fmt.Println("All numbers are positive is", positive) // true - - evenNumbersSquared := set.Select(func(index int, value interface{}) bool { - return value.(int)%2 == 0 - }).Map(func(index int, value interface{}) interface{} { - return value.(int) * value.(int) - }) - printSet("Chaining", evenNumbersSquared) // [ 4 16 36 64 ] -} -``` - -#### EnumerableWithKey - -Enumerable functions for ordered containers whose values whose elements are key/value pairs. - -**Each** - -Calls the given function once for each element, passing that element's key and value. - -```go -Each(func(key interface{}, value interface{})) -``` - -**Map** - -Invokes the given function once for each element and returns a container containing the values returned by the given function as key/value pairs. - -```go -Map(func(key interface{}, value interface{}) (interface{}, interface{})) Container -``` - -**Select** - -Returns a new container containing all elements for which the given function returns a true value. - -```go -Select(func(key interface{}, value interface{}) bool) Container -``` - -**Any** - -Passes each element of the container to the given function and returns true if the function ever returns true for any element. - -```go -Any(func(key interface{}, value interface{}) bool) bool -``` - -**All** - -Passes each element of the container to the given function and returns true if the function returns true for all elements. - -```go -All(func(key interface{}, value interface{}) bool) bool -``` - -**Find** - -Passes each element of the container to the given function and returns the first (key,value) for which the function is true or nil,nil otherwise if no element matches the criteria. - -```go -Find(func(key interface{}, value interface{}) bool) (interface{}, interface{}) -``` - -**Example:** - -```go -package main - -import ( - "fmt" - "github.com/emirpasic/gods/maps/treemap" -) - -func printMap(txt string, m *treemap.Map) { - fmt.Print(txt, " { ") - m.Each(func(key interface{}, value interface{}) { - fmt.Print(key, ":", value, " ") - }) - fmt.Println("}") -} - -func main() { - m := treemap.NewWithStringComparator() - m.Put("g", 7) - m.Put("f", 6) - m.Put("e", 5) - m.Put("d", 4) - m.Put("c", 3) - m.Put("b", 2) - m.Put("a", 1) - printMap("Initial", m) // { a:1 b:2 c:3 d:4 e:5 f:6 g:7 } - - even := m.Select(func(key interface{}, value interface{}) bool { - return value.(int) % 2 == 0 - }) - printMap("Elements with even values", even) // { b:2 d:4 f:6 } - - foundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool { - return value.(int) % 2 == 0 && value.(int) % 3 == 0 - }) - if foundKey != nil { - fmt.Println("Element with value divisible by 2 and 3 found is", foundValue, "with key", foundKey) // value: 6, index: 4 - } - - square := m.Map(func(key interface{}, value interface{}) (interface{}, interface{}) { - return key.(string) + key.(string), value.(int) * value.(int) - }) - printMap("Elements' values squared and letters duplicated", square) // { aa:1 bb:4 cc:9 dd:16 ee:25 ff:36 gg:49 } - - bigger := m.Any(func(key interface{}, value interface{}) bool { - return value.(int) > 5 - }) - fmt.Println("Map contains element whose value is bigger than 5 is", bigger) // true - - positive := m.All(func(key interface{}, value interface{}) bool { - return value.(int) > 0 - }) - fmt.Println("All map's elements have positive values is", positive) // true - - evenNumbersSquared := m.Select(func(key interface{}, value interface{}) bool { - return value.(int) % 2 == 0 - }).Map(func(key interface{}, value interface{}) (interface{}, interface{}) { - return key, value.(int) * value.(int) - }) - printMap("Chaining", evenNumbersSquared) // { b:4 d:16 f:36 } -} -``` - -### Serialization - -All data structures can be serialized (marshalled) and deserialized (unmarshalled). Currently only JSON support is available. - -#### JSONSerializer - -Outputs the container into its JSON representation. - -Typical usage for key-value structures: -```go -package main - -import ( - "fmt" - "github.com/emirpasic/gods/maps/hashmap" -) - -func main() { - m := hashmap.New() - m.Put("a", "1") - m.Put("b", "2") - m.Put("c", "3") - - json, err := m.ToJSON() - if err != nil { - fmt.Println(err) - } - fmt.Println(string(json)) // {"a":"1","b":"2","c":"3"} -``` - -Typical usage for value-only structures: -```go -package main - -import ( - "fmt" - "github.com/emirpasic/gods/lists/arraylist" -) - -func main() { - list := arraylist.New() - list.Add("a", "b", "c") - - json, err := list.ToJSON() - if err != nil { - fmt.Println(err) - } - fmt.Println(string(json)) // ["a","b","c"] -} -``` - -#### JSONDeserializer - -Populates the container with elements from the input JSON representation. - -Typical usage for key-value structures: -```go -package main - -import ( - "fmt" - "github.com/emirpasic/gods/maps/hashmap" -) - -func main() { - hm := hashmap.New() - - json := []byte(`{"a":"1","b":"2"}`) - err := hm.FromJSON(json) - if err != nil { - fmt.Println(err) - } - fmt.Println(hm) // HashMap map[b:2 a:1] -} -``` - -Typical usage for value-only structures: -```go -package main - -import ( - "fmt" - "github.com/emirpasic/gods/lists/arraylist" -) - -func main() { - list := arraylist.New() - - json := []byte(`["a","b"]`) - err := list.FromJSON(json) - if err != nil { - fmt.Println(err) - } - fmt.Println(list) // ArrayList ["a","b"] -} -``` - -### Sort - -Sort is a general purpose sort function. - -Lists have an in-place _Sort()_ function and all containers can return their sorted elements via _containers.GetSortedValues()_ function. - -Internally these all use the _utils.Sort()_ method: - -```go -package main - -import "github.com/emirpasic/gods/utils" - -func main() { - strings := []interface{}{} // [] - strings = append(strings, "d") // ["d"] - strings = append(strings, "a") // ["d","a"] - strings = append(strings, "b") // ["d","a",b" - strings = append(strings, "c") // ["d","a",b","c"] - utils.Sort(strings, utils.StringComparator) // ["a","b","c","d"] -} -``` - -### Container - -Container specific operations: - -```go -// Returns sorted container''s elements with respect to the passed comparator. -// Does not effect the ordering of elements within the container. -func GetSortedValues(container Container, comparator utils.Comparator) []interface{} -``` - -Usage: - -```go -package main - -import ( - "github.com/emirpasic/gods/lists/arraylist" - "github.com/emirpasic/gods/utils" -) - -func main() { - list := arraylist.New() - list.Add(2, 1, 3) - values := GetSortedValues(container, utils.StringComparator) // [1, 2, 3] -} -``` - -## Appendix - -### Motivation - -Collections and data structures found in other languages: Java Collections, C++ Standard Template Library (STL) containers, Qt Containers, Ruby Enumerable etc. - -### Goals - -**Fast algorithms**: - - - Based on decades of knowledge and experiences of other libraries mentioned above. - -**Memory efficient algorithms**: - - - Avoiding to consume memory by using optimal algorithms and data structures for the given set of problems, e.g. red-black tree in case of TreeMap to avoid keeping redundant sorted array of keys in memory. - -**Easy to use library**: - - - Well-structured library with minimalistic set of atomic operations from which more complex operations can be crafted. - -**Stable library**: - - - Only additions are permitted keeping the library backward compatible. - -**Solid documentation and examples**: - - - Learning by example. - -**Production ready**: - - - Used in production. - -**No dependencies**: - - - No external imports. - -There is often a tug of war between speed and memory when crafting algorithms. We choose to optimize for speed in most cases within reasonable limits on memory consumption. - -Thread safety is not a concern of this project, this should be handled at a higher level. - -### Testing and Benchmarking - -This takes a while, so test within sub-packages: - -`go test -run=NO_TEST -bench . -benchmem -benchtime 1s ./...` - -

- -### Contributing - -Biggest contribution towards this library is to use it and give us feedback for further improvements and additions. - -For direct contributions, _pull request_ into master branch or ask to become a contributor. - -Coding style: - -```shell -# Install tooling and set path: -go get github.com/golang/lint/golint -go get github.com/fzipp/gocyclo -go get github.com/kisielk/errcheck -export PATH=$PATH:$GOPATH/bin - -# Fix errors and warnings: -go fmt ./... && gofmt -s -w . && go vet ./... && go get ./... && go test ./... && golint ./... && gocyclo -avg -over 15 . && errcheck ./... -``` - -### License - -This library is distributed under the BSD-style license found in the [LICENSE](https://github.com/emirpasic/gods/blob/master/LICENSE) file. - -### Sponsors - -## BrowserStack -[BrowserStack](https://www.browserstack.com/?ref=webhook) is a cloud-based cross-browser testing tool that enables developers to test their websites across various browsers on different operating systems and mobile devices, without requiring users to install virtual machines, devices or emulators. diff --git a/vendor/github.com/emirpasic/gods/containers/containers_test.go b/vendor/github.com/emirpasic/gods/containers/containers_test.go deleted file mode 100644 index 94cf4f802..000000000 --- a/vendor/github.com/emirpasic/gods/containers/containers_test.go +++ /dev/null @@ -1,55 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// All data structures must implement the container structure - -package containers - -import ( - "github.com/emirpasic/gods/utils" - "testing" -) - -// For testing purposes -type ContainerTest struct { - values []interface{} -} - -func (container ContainerTest) Empty() bool { - return len(container.values) == 0 -} - -func (container ContainerTest) Size() int { - return len(container.values) -} - -func (container ContainerTest) Clear() { - container.values = []interface{}{} -} - -func (container ContainerTest) Values() []interface{} { - return container.values -} - -func TestGetSortedValuesInts(t *testing.T) { - container := ContainerTest{} - container.values = []interface{}{5, 1, 3, 2, 4} - values := GetSortedValues(container, utils.IntComparator) - for i := 1; i < container.Size(); i++ { - if values[i-1].(int) > values[i].(int) { - t.Errorf("Not sorted!") - } - } -} - -func TestGetSortedValuesStrings(t *testing.T) { - container := ContainerTest{} - container.values = []interface{}{"g", "a", "d", "e", "f", "c", "b"} - values := GetSortedValues(container, utils.StringComparator) - for i := 1; i < container.Size(); i++ { - if values[i-1].(string) > values[i].(string) { - t.Errorf("Not sorted!") - } - } -} diff --git a/vendor/github.com/emirpasic/gods/examples/README.md b/vendor/github.com/emirpasic/gods/examples/README.md deleted file mode 100644 index 8a1e8caeb..000000000 --- a/vendor/github.com/emirpasic/gods/examples/README.md +++ /dev/null @@ -1,29 +0,0 @@ -# GoDS (Go Data Structures) - -Various examples on how to use data structures. - -## Examples - -- [ArrayList](https://github.com/emirpasic/gods/blob/master/examples/arraylist/arraylist.go) -- [ArrayStack](https://github.com/emirpasic/gods/blob/master/examples/arraystack/arraystack.go) -- [AVLTree](https://github.com/emirpasic/gods/blob/master/examples/avltree/avltree.go) -- [BinaryHeap](https://github.com/emirpasic/gods/blob/master/examples/binaryheap/binaryheap.go) -- [BTree](https://github.com/emirpasic/gods/blob/master/examples/btree/btree.go) -- [Custom Comparator](https://github.com/emirpasic/gods/blob/master/examples/customcomparator/customcomparator.go) -- [DoublyLinkedList](https://github.com/emirpasic/gods/blob/master/examples/doublylinkedlist/doublylinkedlist.go) -- [EnumerableWithIndex](https://github.com/emirpasic/gods/blob/master/examples/enumerablewithindex/enumerablewithindex.go) -- [EnumerableWithKey](https://github.com/emirpasic/gods/blob/master/examples/enumerablewithkey/enumerablewithkey.go) -- [HashBidiMap](https://github.com/emirpasic/gods/blob/master/examples/hashbidimap/hashbidimap.go) -- [HashMap](https://github.com/emirpasic/gods/blob/master/examples/hashmap/hashmap.go) -- [HashSet](https://github.com/emirpasic/gods/blob/master/examples/hashset/hashset.go) -- [IteratorWithIndex](https://github.com/emirpasic/gods/blob/master/examples/iteratorwithindex/iteratorwithindex.go) -- [iteratorwithkey](https://github.com/emirpasic/gods/blob/master/examples/iteratorwithkey/iteratorwithkey.go) -- [IteratorWithKey](https://github.com/emirpasic/gods/blob/master/examples/linkedliststack/linkedliststack.go) -- [RedBlackTree](https://github.com/emirpasic/gods/blob/master/examples/redblacktree/redblacktree.go) -- [RedBlackTreeExtended](https://github.com/emirpasic/gods/blob/master/examples/redblacktreeextended/redblacktreeextended.go) -- [Serialization](https://github.com/emirpasic/gods/blob/master/examples/serialization/serialization.go) -- [SinglyLinkedList](https://github.com/emirpasic/gods/blob/master/examples/singlylinkedlist/singlylinkedlist.go) -- [Sort](https://github.com/emirpasic/gods/blob/master/examples/sort/sort.go) -- [TreeBidiMap](https://github.com/emirpasic/gods/blob/master/examples/treebidimap/treebidimap.go) -- [TreeMap](https://github.com/emirpasic/gods/blob/master/examples/treemap/treemap.go) -- [TreeSet](https://github.com/emirpasic/gods/blob/master/examples/treeset/treeset.go) diff --git a/vendor/github.com/emirpasic/gods/examples/arraylist/arraylist.go b/vendor/github.com/emirpasic/gods/examples/arraylist/arraylist.go deleted file mode 100644 index 4d4fbd906..000000000 --- a/vendor/github.com/emirpasic/gods/examples/arraylist/arraylist.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "github.com/emirpasic/gods/lists/arraylist" - "github.com/emirpasic/gods/utils" -) - -// ArrayListExample to demonstrate basic usage of ArrayList -func main() { - list := arraylist.New() - list.Add("a") // ["a"] - list.Add("c", "b") // ["a","c","b"] - list.Sort(utils.StringComparator) // ["a","b","c"] - _, _ = list.Get(0) // "a",true - _, _ = list.Get(100) // nil,false - _ = list.Contains("a", "b", "c") // true - _ = list.Contains("a", "b", "c", "d") // false - list.Swap(0, 1) // ["b","a",c"] - list.Remove(2) // ["b","a"] - list.Remove(1) // ["b"] - list.Remove(0) // [] - list.Remove(0) // [] (ignored) - _ = list.Empty() // true - _ = list.Size() // 0 - list.Add("a") // ["a"] - list.Clear() // [] -} diff --git a/vendor/github.com/emirpasic/gods/examples/arraystack/arraystack.go b/vendor/github.com/emirpasic/gods/examples/arraystack/arraystack.go deleted file mode 100644 index aa06eaf74..000000000 --- a/vendor/github.com/emirpasic/gods/examples/arraystack/arraystack.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "github.com/emirpasic/gods/stacks/arraystack" - -// ArrayStackExample to demonstrate basic usage of ArrayStack -func main() { - stack := arraystack.New() // empty - stack.Push(1) // 1 - stack.Push(2) // 1, 2 - stack.Values() // 2, 1 (LIFO order) - _, _ = stack.Peek() // 2,true - _, _ = stack.Pop() // 2, true - _, _ = stack.Pop() // 1, true - _, _ = stack.Pop() // nil, false (nothing to pop) - stack.Push(1) // 1 - stack.Clear() // empty - stack.Empty() // true - stack.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/avltree/avltree.go b/vendor/github.com/emirpasic/gods/examples/avltree/avltree.go deleted file mode 100644 index b6d1aabc7..000000000 --- a/vendor/github.com/emirpasic/gods/examples/avltree/avltree.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - avl "github.com/emirpasic/gods/trees/avltree" -) - -// AVLTreeExample to demonstrate basic usage of AVLTree -func main() { - tree := avl.NewWithIntComparator() // empty(keys are of type int) - - tree.Put(1, "x") // 1->x - tree.Put(2, "b") // 1->x, 2->b (in order) - tree.Put(1, "a") // 1->a, 2->b (in order, replacement) - tree.Put(3, "c") // 1->a, 2->b, 3->c (in order) - tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order) - tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order) - tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order) - - fmt.Println(tree) - // - // AVLTree - // │ ┌── 6 - // │ ┌── 5 - // └── 4 - // │ ┌── 3 - // └── 2 - // └── 1 - - _ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f"} (in order) - _ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6} (in order) - - tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order) - fmt.Println(tree) - // - // AVLTree - // │ ┌── 6 - // │ ┌── 5 - // └── 4 - // └── 3 - // └── 1 - - tree.Clear() // empty - tree.Empty() // true - tree.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/binaryheap/binaryheap.go b/vendor/github.com/emirpasic/gods/examples/binaryheap/binaryheap.go deleted file mode 100644 index 4bc93813a..000000000 --- a/vendor/github.com/emirpasic/gods/examples/binaryheap/binaryheap.go +++ /dev/null @@ -1,40 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "github.com/emirpasic/gods/trees/binaryheap" - "github.com/emirpasic/gods/utils" -) - -// BinaryHeapExample to demonstrate basic usage of BinaryHeap -func main() { - - // Min-heap - heap := binaryheap.NewWithIntComparator() // empty (min-heap) - heap.Push(2) // 2 - heap.Push(3) // 2, 3 - heap.Push(1) // 1, 3, 2 - heap.Values() // 1, 3, 2 - _, _ = heap.Peek() // 1,true - _, _ = heap.Pop() // 1, true - _, _ = heap.Pop() // 2, true - _, _ = heap.Pop() // 3, true - _, _ = heap.Pop() // nil, false (nothing to pop) - heap.Push(1) // 1 - heap.Clear() // empty - heap.Empty() // true - heap.Size() // 0 - - // Max-heap - inverseIntComparator := func(a, b interface{}) int { - return -utils.IntComparator(a, b) - } - heap = binaryheap.NewWith(inverseIntComparator) // empty (min-heap) - heap.Push(2) // 2 - heap.Push(3) // 3, 2 - heap.Push(1) // 3, 2, 1 - heap.Values() // 3, 2, 1 -} diff --git a/vendor/github.com/emirpasic/gods/examples/btree/btree.go b/vendor/github.com/emirpasic/gods/examples/btree/btree.go deleted file mode 100644 index ea61b03f9..000000000 --- a/vendor/github.com/emirpasic/gods/examples/btree/btree.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "github.com/emirpasic/gods/trees/btree" -) - -// BTreeExample to demonstrate basic usage of BTree -func main() { - tree := btree.NewWithIntComparator(3) // empty (keys are of type int) - - tree.Put(1, "x") // 1->x - tree.Put(2, "b") // 1->x, 2->b (in order) - tree.Put(1, "a") // 1->a, 2->b (in order, replacement) - tree.Put(3, "c") // 1->a, 2->b, 3->c (in order) - tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order) - tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order) - tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order) - tree.Put(7, "g") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f, 7->g (in order) - - fmt.Println(tree) - // BTree - // 1 - // 2 - // 3 - // 4 - // 5 - // 6 - // 7 - - _ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f", "g"} (in order) - _ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6, 7} (in order) - - tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order) - fmt.Println(tree) - // BTree - // 1 - // 3 - // 4 - // 5 - // 6 - - tree.Clear() // empty - tree.Empty() // true - tree.Size() // 0 - - // Other: - tree.Height() // gets the height of the tree - tree.Left() // gets the left-most (min) node - tree.LeftKey() // get the left-most (min) node's key - tree.LeftValue() // get the left-most (min) node's value - tree.Right() // get the right-most (max) node - tree.RightKey() // get the right-most (max) node's key - tree.RightValue() // get the right-most (max) node's value -} diff --git a/vendor/github.com/emirpasic/gods/examples/customcomparator/customcomparator.go b/vendor/github.com/emirpasic/gods/examples/customcomparator/customcomparator.go deleted file mode 100644 index b61d96983..000000000 --- a/vendor/github.com/emirpasic/gods/examples/customcomparator/customcomparator.go +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "github.com/emirpasic/gods/sets/treeset" -) - -// User model (id and name) -type User struct { - id int - name string -} - -// Comparator function (sort by IDs) -func byID(a, b interface{}) int { - - // Type assertion, program will panic if this is not respected - c1 := a.(User) - c2 := b.(User) - - switch { - case c1.id > c2.id: - return 1 - case c1.id < c2.id: - return -1 - default: - return 0 - } -} - -// CustomComparatorExample to demonstrate basic usage of CustomComparator -func main() { - set := treeset.NewWith(byID) - - set.Add(User{2, "Second"}) - set.Add(User{3, "Third"}) - set.Add(User{1, "First"}) - set.Add(User{4, "Fourth"}) - - fmt.Println(set) // {1 First}, {2 Second}, {3 Third}, {4 Fourth} -} diff --git a/vendor/github.com/emirpasic/gods/examples/doublylinkedlist/doublylinkedlist.go b/vendor/github.com/emirpasic/gods/examples/doublylinkedlist/doublylinkedlist.go deleted file mode 100644 index 99ec995c2..000000000 --- a/vendor/github.com/emirpasic/gods/examples/doublylinkedlist/doublylinkedlist.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - dll "github.com/emirpasic/gods/lists/doublylinkedlist" - "github.com/emirpasic/gods/utils" -) - -// DoublyLinkedListExample to demonstrate basic usage of DoublyLinkedList -func main() { - list := dll.New() - list.Add("a") // ["a"] - list.Append("b") // ["a","b"] (same as Add()) - list.Prepend("c") // ["c","a","b"] - list.Sort(utils.StringComparator) // ["a","b","c"] - _, _ = list.Get(0) // "a",true - _, _ = list.Get(100) // nil,false - _ = list.Contains("a", "b", "c") // true - _ = list.Contains("a", "b", "c", "d") // false - list.Remove(2) // ["a","b"] - list.Remove(1) // ["a"] - list.Remove(0) // [] - list.Remove(0) // [] (ignored) - _ = list.Empty() // true - _ = list.Size() // 0 - list.Add("a") // ["a"] - list.Clear() // [] -} diff --git a/vendor/github.com/emirpasic/gods/examples/enumerablewithindex/enumerablewithindex.go b/vendor/github.com/emirpasic/gods/examples/enumerablewithindex/enumerablewithindex.go deleted file mode 100644 index 95459117b..000000000 --- a/vendor/github.com/emirpasic/gods/examples/enumerablewithindex/enumerablewithindex.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "github.com/emirpasic/gods/sets/treeset" -) - -func printSet(txt string, set *treeset.Set) { - fmt.Print(txt, "[ ") - set.Each(func(index int, value interface{}) { - fmt.Print(value, " ") - }) - fmt.Println("]") -} - -// EnumerableWithIndexExample to demonstrate basic usage of EnumerableWithIndex -func main() { - set := treeset.NewWithIntComparator() - set.Add(2, 3, 4, 2, 5, 6, 7, 8) - printSet("Initial", set) // [ 2 3 4 5 6 7 8 ] - - even := set.Select(func(index int, value interface{}) bool { - return value.(int)%2 == 0 - }) - printSet("Even numbers", even) // [ 2 4 6 8 ] - - foundIndex, foundValue := set.Find(func(index int, value interface{}) bool { - return value.(int)%2 == 0 && value.(int)%3 == 0 - }) - if foundIndex != -1 { - fmt.Println("Number divisible by 2 and 3 found is", foundValue, "at index", foundIndex) // value: 6, index: 4 - } - - square := set.Map(func(index int, value interface{}) interface{} { - return value.(int) * value.(int) - }) - printSet("Numbers squared", square) // [ 4 9 16 25 36 49 64 ] - - bigger := set.Any(func(index int, value interface{}) bool { - return value.(int) > 5 - }) - fmt.Println("Set contains a number bigger than 5 is ", bigger) // true - - positive := set.All(func(index int, value interface{}) bool { - return value.(int) > 0 - }) - fmt.Println("All numbers are positive is", positive) // true - - evenNumbersSquared := set.Select(func(index int, value interface{}) bool { - return value.(int)%2 == 0 - }).Map(func(index int, value interface{}) interface{} { - return value.(int) * value.(int) - }) - printSet("Chaining", evenNumbersSquared) // [ 4 16 36 64 ] -} diff --git a/vendor/github.com/emirpasic/gods/examples/enumerablewithkey/enumerablewithkey.go b/vendor/github.com/emirpasic/gods/examples/enumerablewithkey/enumerablewithkey.go deleted file mode 100644 index 7f05040d2..000000000 --- a/vendor/github.com/emirpasic/gods/examples/enumerablewithkey/enumerablewithkey.go +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "github.com/emirpasic/gods/maps/treemap" -) - -func printMap(txt string, m *treemap.Map) { - fmt.Print(txt, " { ") - m.Each(func(key interface{}, value interface{}) { - fmt.Print(key, ":", value, " ") - }) - fmt.Println("}") -} - -// EunumerableWithKeyExample to demonstrate basic usage of EunumerableWithKey -func main() { - m := treemap.NewWithStringComparator() - m.Put("g", 7) - m.Put("f", 6) - m.Put("e", 5) - m.Put("d", 4) - m.Put("c", 3) - m.Put("b", 2) - m.Put("a", 1) - printMap("Initial", m) // { a:1 b:2 c:3 d:4 e:5 f:6 g:7 } - - even := m.Select(func(key interface{}, value interface{}) bool { - return value.(int)%2 == 0 - }) - printMap("Elements with even values", even) // { b:2 d:4 f:6 } - - foundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool { - return value.(int)%2 == 0 && value.(int)%3 == 0 - }) - if foundKey != nil { - fmt.Println("Element with value divisible by 2 and 3 found is", foundValue, "with key", foundKey) // value: 6, index: 4 - } - - square := m.Map(func(key interface{}, value interface{}) (interface{}, interface{}) { - return key.(string) + key.(string), value.(int) * value.(int) - }) - printMap("Elements' values squared and letters duplicated", square) // { aa:1 bb:4 cc:9 dd:16 ee:25 ff:36 gg:49 } - - bigger := m.Any(func(key interface{}, value interface{}) bool { - return value.(int) > 5 - }) - fmt.Println("Map contains element whose value is bigger than 5 is", bigger) // true - - positive := m.All(func(key interface{}, value interface{}) bool { - return value.(int) > 0 - }) - fmt.Println("All map's elements have positive values is", positive) // true - - evenNumbersSquared := m.Select(func(key interface{}, value interface{}) bool { - return value.(int)%2 == 0 - }).Map(func(key interface{}, value interface{}) (interface{}, interface{}) { - return key, value.(int) * value.(int) - }) - printMap("Chaining", evenNumbersSquared) // { b:4 d:16 f:36 } -} diff --git a/vendor/github.com/emirpasic/gods/examples/godsort/godsort.go b/vendor/github.com/emirpasic/gods/examples/godsort/godsort.go deleted file mode 100644 index 9f0bd2ac0..000000000 --- a/vendor/github.com/emirpasic/gods/examples/godsort/godsort.go +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "github.com/emirpasic/gods/utils" - -// SortExample to demonstrate basic usage of basic sort -func main() { - strings := []interface{}{} // [] - strings = append(strings, "d") // ["d"] - strings = append(strings, "a") // ["d","a"] - strings = append(strings, "b") // ["d","a",b" - strings = append(strings, "c") // ["d","a",b","c"] - utils.Sort(strings, utils.StringComparator) // ["a","b","c","d"] -} diff --git a/vendor/github.com/emirpasic/gods/examples/hashbidimap/hashbidimap.go b/vendor/github.com/emirpasic/gods/examples/hashbidimap/hashbidimap.go deleted file mode 100644 index 26350b8c2..000000000 --- a/vendor/github.com/emirpasic/gods/examples/hashbidimap/hashbidimap.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "github.com/emirpasic/gods/maps/hashbidimap" - -// HashBidiMapExample to demonstrate basic usage of HashMap -func main() { - m := hashbidimap.New() // empty - m.Put(1, "x") // 1->x - m.Put(3, "b") // 1->x, 3->b (random order) - m.Put(1, "a") // 1->a, 3->b (random order) - m.Put(2, "b") // 1->a, 2->b (random order) - _, _ = m.GetKey("a") // 1, true - _, _ = m.Get(2) // b, true - _, _ = m.Get(3) // nil, false - _ = m.Values() // []interface {}{"a", "b"} (random order) - _ = m.Keys() // []interface {}{1, 2} (random order) - m.Remove(1) // 2->b - m.Clear() // empty - m.Empty() // true - m.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/hashmap/hashmap.go b/vendor/github.com/emirpasic/gods/examples/hashmap/hashmap.go deleted file mode 100644 index 2fda79e62..000000000 --- a/vendor/github.com/emirpasic/gods/examples/hashmap/hashmap.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "github.com/emirpasic/gods/maps/hashmap" - -// HashMapExample to demonstrate basic usage of HashMap -func main() { - m := hashmap.New() // empty - m.Put(1, "x") // 1->x - m.Put(2, "b") // 2->b, 1->x (random order) - m.Put(1, "a") // 2->b, 1->a (random order) - _, _ = m.Get(2) // b, true - _, _ = m.Get(3) // nil, false - _ = m.Values() // []interface {}{"b", "a"} (random order) - _ = m.Keys() // []interface {}{1, 2} (random order) - m.Remove(1) // 2->b - m.Clear() // empty - m.Empty() // true - m.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/hashset/hashset.go b/vendor/github.com/emirpasic/gods/examples/hashset/hashset.go deleted file mode 100644 index 6c366e51a..000000000 --- a/vendor/github.com/emirpasic/gods/examples/hashset/hashset.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "github.com/emirpasic/gods/sets/hashset" - -// HashSetExample to demonstrate basic usage of HashSet -func main() { - set := hashset.New() // empty (keys are of type int) - set.Add(1) // 1 - set.Add(2, 2, 3, 4, 5) // 3, 1, 2, 4, 5 (random order, duplicates ignored) - set.Remove(4) // 5, 3, 2, 1 (random order) - set.Remove(2, 3) // 1, 5 (random order) - set.Contains(1) // true - set.Contains(1, 5) // true - set.Contains(1, 6) // false - _ = set.Values() // []int{5,1} (random order) - set.Clear() // empty - set.Empty() // true - set.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/iteratorwithindex/iteratorwithindex.go b/vendor/github.com/emirpasic/gods/examples/iteratorwithindex/iteratorwithindex.go deleted file mode 100644 index d15c439fe..000000000 --- a/vendor/github.com/emirpasic/gods/examples/iteratorwithindex/iteratorwithindex.go +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "github.com/emirpasic/gods/sets/treeset" -) - -// IteratorWithIndexExample to demonstrate basic usage of IteratorWithIndex -func main() { - set := treeset.NewWithStringComparator() - set.Add("a", "b", "c") - it := set.Iterator() - - fmt.Print("\nForward iteration\n") - for it.Next() { - index, value := it.Index(), it.Value() - fmt.Print("[", index, ":", value, "]") // [0:a][1:b][2:c] - } - - fmt.Print("\nForward iteration (again)\n") - for it.Begin(); it.Next(); { - index, value := it.Index(), it.Value() - fmt.Print("[", index, ":", value, "]") // [0:a][1:b][2:c] - } - - fmt.Print("\nBackward iteration\n") - for it.Prev() { - index, value := it.Index(), it.Value() - fmt.Print("[", index, ":", value, "]") // [2:c][1:b][0:a] - } - - fmt.Print("\nBackward iteration (again)\n") - for it.End(); it.Prev(); { - index, value := it.Index(), it.Value() - fmt.Print("[", index, ":", value, "]") // [2:c][1:b][0:a] - } - - if it.First() { - fmt.Print("\nFirst index: ", it.Index()) // First index: 0 - fmt.Print("\nFirst value: ", it.Value()) // First value: a - } - - if it.Last() { - fmt.Print("\nLast index: ", it.Index()) // Last index: 3 - fmt.Print("\nLast value: ", it.Value()) // Last value: c - } -} diff --git a/vendor/github.com/emirpasic/gods/examples/iteratorwithkey/iteratorwithkey.go b/vendor/github.com/emirpasic/gods/examples/iteratorwithkey/iteratorwithkey.go deleted file mode 100644 index 4efeb7e1c..000000000 --- a/vendor/github.com/emirpasic/gods/examples/iteratorwithkey/iteratorwithkey.go +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - "github.com/emirpasic/gods/maps/treemap" -) - -// IteratorWithKeyExample to demonstrate basic usage of IteratorWithKey -func main() { - m := treemap.NewWithIntComparator() - m.Put(1, "a") - m.Put(2, "b") - m.Put(3, "a") - it := m.Iterator() - - fmt.Print("\nForward iteration\n") - for it.Next() { - key, value := it.Key(), it.Value() - fmt.Print("[", key, ":", value, "]") // [0:a][1:b][2:c] - } - - fmt.Print("\nForward iteration (again)\n") - for it.Begin(); it.Next(); { - key, value := it.Key(), it.Value() - fmt.Print("[", key, ":", value, "]") // [0:a][1:b][2:c] - } - - fmt.Print("\nBackward iteration\n") - for it.Prev() { - key, value := it.Key(), it.Value() - fmt.Print("[", key, ":", value, "]") // [2:c][1:b][0:a] - } - - fmt.Print("\nBackward iteration (again)\n") - for it.End(); it.Prev(); { - key, value := it.Key(), it.Value() - fmt.Print("[", key, ":", value, "]") // [2:c][1:b][0:a] - } - - if it.First() { - fmt.Print("\nFirst key: ", it.Key()) // First key: 0 - fmt.Print("\nFirst value: ", it.Value()) // First value: a - } - - if it.Last() { - fmt.Print("\nLast key: ", it.Key()) // Last key: 3 - fmt.Print("\nLast value: ", it.Value()) // Last value: c - } -} diff --git a/vendor/github.com/emirpasic/gods/examples/linkedhashmap/linkedhashmap.go b/vendor/github.com/emirpasic/gods/examples/linkedhashmap/linkedhashmap.go deleted file mode 100644 index 644348178..000000000 --- a/vendor/github.com/emirpasic/gods/examples/linkedhashmap/linkedhashmap.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "github.com/emirpasic/gods/maps/linkedhashmap" - -// LinkedHashMapExample to demonstrate basic usage of LinkedHashMapExample -func main() { - m := linkedhashmap.New() // empty (keys are of type int) - m.Put(2, "b") // 2->b - m.Put(1, "x") // 2->b, 1->x (insertion-order) - m.Put(1, "a") // 2->b, 1->a (insertion-order) - _, _ = m.Get(2) // b, true - _, _ = m.Get(3) // nil, false - _ = m.Values() // []interface {}{"b", "a"} (insertion-order) - _ = m.Keys() // []interface {}{2, 1} (insertion-order) - m.Remove(1) // 2->b - m.Clear() // empty - m.Empty() // true - m.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/linkedhashset/linkedhashset.go b/vendor/github.com/emirpasic/gods/examples/linkedhashset/linkedhashset.go deleted file mode 100644 index 689d212d7..000000000 --- a/vendor/github.com/emirpasic/gods/examples/linkedhashset/linkedhashset.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "github.com/emirpasic/gods/sets/linkedhashset" - -// LinkedHashSetExample to demonstrate basic usage of LinkedHashSet -func main() { - set := linkedhashset.New() // empty - set.Add(5) // 5 - set.Add(4, 4, 3, 2, 1) // 5, 4, 3, 2, 1 (in insertion-order, duplicates ignored) - set.Remove(4) // 5, 3, 2, 1 (in insertion-order) - set.Remove(2, 3) // 5, 1 (in insertion-order) - set.Contains(1) // true - set.Contains(1, 5) // true - set.Contains(1, 6) // false - _ = set.Values() // []int{5, 1} (in insertion-order) - set.Clear() // empty - set.Empty() // true - set.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/linkedliststack/linkedliststack.go b/vendor/github.com/emirpasic/gods/examples/linkedliststack/linkedliststack.go deleted file mode 100644 index e9f1a68e2..000000000 --- a/vendor/github.com/emirpasic/gods/examples/linkedliststack/linkedliststack.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import lls "github.com/emirpasic/gods/stacks/linkedliststack" - -// LinkedListStackExample to demonstrate basic usage of LinkedListStack -func main() { - stack := lls.New() // empty - stack.Push(1) // 1 - stack.Push(2) // 1, 2 - stack.Values() // 2, 1 (LIFO order) - _, _ = stack.Peek() // 2,true - _, _ = stack.Pop() // 2, true - _, _ = stack.Pop() // 1, true - _, _ = stack.Pop() // nil, false (nothing to pop) - stack.Push(1) // 1 - stack.Clear() // empty - stack.Empty() // true - stack.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/redblacktree/redblacktree.go b/vendor/github.com/emirpasic/gods/examples/redblacktree/redblacktree.go deleted file mode 100644 index b7d9803f9..000000000 --- a/vendor/github.com/emirpasic/gods/examples/redblacktree/redblacktree.go +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "fmt" - rbt "github.com/emirpasic/gods/trees/redblacktree" -) - -// RedBlackTreeExample to demonstrate basic usage of RedBlackTree -func main() { - tree := rbt.NewWithIntComparator() // empty(keys are of type int) - - tree.Put(1, "x") // 1->x - tree.Put(2, "b") // 1->x, 2->b (in order) - tree.Put(1, "a") // 1->a, 2->b (in order, replacement) - tree.Put(3, "c") // 1->a, 2->b, 3->c (in order) - tree.Put(4, "d") // 1->a, 2->b, 3->c, 4->d (in order) - tree.Put(5, "e") // 1->a, 2->b, 3->c, 4->d, 5->e (in order) - tree.Put(6, "f") // 1->a, 2->b, 3->c, 4->d, 5->e, 6->f (in order) - - fmt.Println(tree) - // - // RedBlackTree - // │ ┌── 6 - // │ ┌── 5 - // │ ┌── 4 - // │ │ └── 3 - // └── 2 - // └── 1 - - _ = tree.Values() // []interface {}{"a", "b", "c", "d", "e", "f"} (in order) - _ = tree.Keys() // []interface {}{1, 2, 3, 4, 5, 6} (in order) - - tree.Remove(2) // 1->a, 3->c, 4->d, 5->e, 6->f (in order) - fmt.Println(tree) - // - // RedBlackTree - // │ ┌── 6 - // │ ┌── 5 - // └── 4 - // │ ┌── 3 - // └── 1 - - tree.Clear() // empty - tree.Empty() // true - tree.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/redblacktreeextended/redblacktreeextended.go b/vendor/github.com/emirpasic/gods/examples/redblacktreeextended/redblacktreeextended.go deleted file mode 100644 index 6e901299a..000000000 --- a/vendor/github.com/emirpasic/gods/examples/redblacktreeextended/redblacktreeextended.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package redblacktreeextended - -import ( - "fmt" - rbt "github.com/emirpasic/gods/trees/redblacktree" -) - -// RedBlackTreeExtended to demonstrate how to extend a RedBlackTree to include new functions -type RedBlackTreeExtended struct { - *rbt.Tree -} - -// GetMin gets the min value and flag if found -func (tree *RedBlackTreeExtended) GetMin() (value interface{}, found bool) { - node, found := tree.getMinFromNode(tree.Root) - if node != nil { - return node.Value, found - } - return nil, false -} - -// GetMax gets the max value and flag if found -func (tree *RedBlackTreeExtended) GetMax() (value interface{}, found bool) { - node, found := tree.getMaxFromNode(tree.Root) - if node != nil { - return node.Value, found - } - return nil, false -} - -// RemoveMin removes the min value and flag if found -func (tree *RedBlackTreeExtended) RemoveMin() (value interface{}, deleted bool) { - node, found := tree.getMinFromNode(tree.Root) - if found { - tree.Remove(node.Key) - return node.Value, found - } - return nil, false -} - -// RemoveMax removes the max value and flag if found -func (tree *RedBlackTreeExtended) RemoveMax() (value interface{}, deleted bool) { - node, found := tree.getMaxFromNode(tree.Root) - if found { - tree.Remove(node.Key) - return node.Value, found - } - return nil, false -} - -func (tree *RedBlackTreeExtended) getMinFromNode(node *rbt.Node) (foundNode *rbt.Node, found bool) { - if node == nil { - return nil, false - } - if node.Left == nil { - return node, true - } - return tree.getMinFromNode(node.Left) -} - -func (tree *RedBlackTreeExtended) getMaxFromNode(node *rbt.Node) (foundNode *rbt.Node, found bool) { - if node == nil { - return nil, false - } - if node.Right == nil { - return node, true - } - return tree.getMaxFromNode(node.Right) -} - -func print(tree *RedBlackTreeExtended) { - max, _ := tree.GetMax() - min, _ := tree.GetMin() - fmt.Printf("Value for max key: %v \n", max) - fmt.Printf("Value for min key: %v \n", min) - fmt.Println(tree) -} - -// RedBlackTreeExtendedExample main method on how to use the custom red-black tree above -func main() { - tree := RedBlackTreeExtended{rbt.NewWithIntComparator()} - - tree.Put(1, "a") // 1->x (in order) - tree.Put(2, "b") // 1->x, 2->b (in order) - tree.Put(3, "c") // 1->x, 2->b, 3->c (in order) - tree.Put(4, "d") // 1->x, 2->b, 3->c, 4->d (in order) - tree.Put(5, "e") // 1->x, 2->b, 3->c, 4->d, 5->e (in order) - - print(&tree) - // Value for max key: e - // Value for min key: a - // RedBlackTree - // │ ┌── 5 - // │ ┌── 4 - // │ │ └── 3 - // └── 2 - // └── 1 - - tree.RemoveMin() // 2->b, 3->c, 4->d, 5->e (in order) - tree.RemoveMax() // 2->b, 3->c, 4->d (in order) - tree.RemoveMin() // 3->c, 4->d (in order) - tree.RemoveMax() // 3->c (in order) - - print(&tree) - // Value for max key: c - // Value for min key: c - // RedBlackTree - // └── 3 -} diff --git a/vendor/github.com/emirpasic/gods/examples/serialization/serialization.go b/vendor/github.com/emirpasic/gods/examples/serialization/serialization.go deleted file mode 100644 index 2f94c5ed6..000000000 --- a/vendor/github.com/emirpasic/gods/examples/serialization/serialization.go +++ /dev/null @@ -1,51 +0,0 @@ -package serialization - -import ( - "fmt" - "github.com/emirpasic/gods/lists/arraylist" - "github.com/emirpasic/gods/maps/hashmap" -) - -// ListSerializationExample demonstrates how to serialize and deserialize lists to and from JSON -func ListSerializationExample() { - list := arraylist.New() - list.Add("a", "b", "c") - - // Serialization (marshalling) - json, err := list.ToJSON() - if err != nil { - fmt.Println(err) - } - fmt.Println(string(json)) // ["a","b","c"] - - // Deserialization (unmarshalling) - json = []byte(`["a","b"]`) - err = list.FromJSON(json) - if err != nil { - fmt.Println(err) - } - fmt.Println(list) // ArrayList ["a","b"] -} - -// MapSerializationExample demonstrates how to serialize and deserialize maps to and from JSON -func MapSerializationExample() { - m := hashmap.New() - m.Put("a", "1") - m.Put("b", "2") - m.Put("c", "3") - - // Serialization (marshalling) - json, err := m.ToJSON() - if err != nil { - fmt.Println(err) - } - fmt.Println(string(json)) // {"a":"1","b":"2","c":"3"} - - // Deserialization (unmarshalling) - json = []byte(`{"a":"1","b":"2"}`) - err = m.FromJSON(json) - if err != nil { - fmt.Println(err) - } - fmt.Println(m) // HashMap {"a":"1","b":"2"} -} diff --git a/vendor/github.com/emirpasic/gods/examples/singlylinkedlist/singlylinkedlist.go b/vendor/github.com/emirpasic/gods/examples/singlylinkedlist/singlylinkedlist.go deleted file mode 100644 index 93b4ccafc..000000000 --- a/vendor/github.com/emirpasic/gods/examples/singlylinkedlist/singlylinkedlist.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - sll "github.com/emirpasic/gods/lists/singlylinkedlist" - "github.com/emirpasic/gods/utils" -) - -// SinglyLinkedListExample to demonstrate basic usage of SinglyLinkedList -func main() { - list := sll.New() - list.Add("a") // ["a"] - list.Append("b") // ["a","b"] (same as Add()) - list.Prepend("c") // ["c","a","b"] - list.Sort(utils.StringComparator) // ["a","b","c"] - _, _ = list.Get(0) // "a",true - _, _ = list.Get(100) // nil,false - _ = list.Contains("a", "b", "c") // true - _ = list.Contains("a", "b", "c", "d") // false - list.Remove(2) // ["a","b"] - list.Remove(1) // ["a"] - list.Remove(0) // [] - list.Remove(0) // [] (ignored) - _ = list.Empty() // true - _ = list.Size() // 0 - list.Add("a") // ["a"] - list.Clear() // [] -} diff --git a/vendor/github.com/emirpasic/gods/examples/treebidimap/treebidimap.go b/vendor/github.com/emirpasic/gods/examples/treebidimap/treebidimap.go deleted file mode 100644 index 0c63f1225..000000000 --- a/vendor/github.com/emirpasic/gods/examples/treebidimap/treebidimap.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import ( - "github.com/emirpasic/gods/maps/treebidimap" - "github.com/emirpasic/gods/utils" -) - -// TreeBidiMapExample to demonstrate basic usage of TreeBidiMap -func main() { - m := treebidimap.NewWith(utils.IntComparator, utils.StringComparator) - m.Put(1, "x") // 1->x - m.Put(3, "b") // 1->x, 3->b (ordered) - m.Put(1, "a") // 1->a, 3->b (ordered) - m.Put(2, "b") // 1->a, 2->b (ordered) - _, _ = m.GetKey("a") // 1, true - _, _ = m.Get(2) // b, true - _, _ = m.Get(3) // nil, false - _ = m.Values() // []interface {}{"a", "b"} (ordered) - _ = m.Keys() // []interface {}{1, 2} (ordered) - m.Remove(1) // 2->b - m.Clear() // empty - m.Empty() // true - m.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/treemap/treemap.go b/vendor/github.com/emirpasic/gods/examples/treemap/treemap.go deleted file mode 100644 index 66b62cc4f..000000000 --- a/vendor/github.com/emirpasic/gods/examples/treemap/treemap.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "github.com/emirpasic/gods/maps/treemap" - -// TreeMapExample to demonstrate basic usage of TreeMap -func main() { - m := treemap.NewWithIntComparator() // empty (keys are of type int) - m.Put(1, "x") // 1->x - m.Put(2, "b") // 1->x, 2->b (in order) - m.Put(1, "a") // 1->a, 2->b (in order) - _, _ = m.Get(2) // b, true - _, _ = m.Get(3) // nil, false - _ = m.Values() // []interface {}{"a", "b"} (in order) - _ = m.Keys() // []interface {}{1, 2} (in order) - m.Remove(1) // 2->b - m.Clear() // empty - m.Empty() // true - m.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/examples/treeset/treeset.go b/vendor/github.com/emirpasic/gods/examples/treeset/treeset.go deleted file mode 100644 index 15a7f81a2..000000000 --- a/vendor/github.com/emirpasic/gods/examples/treeset/treeset.go +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package main - -import "github.com/emirpasic/gods/sets/treeset" - -// TreeSetExample to demonstrate basic usage of TreeSet -func main() { - set := treeset.NewWithIntComparator() // empty - set.Add(1) // 1 - set.Add(2, 2, 3, 4, 5) // 1, 2, 3, 4, 5 (in order, duplicates ignored) - set.Remove(4) // 1, 2, 3, 5 (in order) - set.Remove(2, 3) // 1, 5 (in order) - set.Contains(1) // true - set.Contains(1, 5) // true - set.Contains(1, 6) // false - _ = set.Values() // []int{1,5} (in order) - set.Clear() // empty - set.Empty() // true - set.Size() // 0 -} diff --git a/vendor/github.com/emirpasic/gods/lists/arraylist/arraylist_test.go b/vendor/github.com/emirpasic/gods/lists/arraylist/arraylist_test.go deleted file mode 100644 index 63d97d41c..000000000 --- a/vendor/github.com/emirpasic/gods/lists/arraylist/arraylist_test.go +++ /dev/null @@ -1,680 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package arraylist - -import ( - "fmt" - "github.com/emirpasic/gods/utils" - "testing" -) - -func TestListNew(t *testing.T) { - list1 := New() - - if actualValue := list1.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - - list2 := New(1, "b") - - if actualValue := list2.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - - if actualValue, ok := list2.Get(0); actualValue != 1 || !ok { - t.Errorf("Got %v expected %v", actualValue, 1) - } - - if actualValue, ok := list2.Get(1); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } - - if actualValue, ok := list2.Get(2); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } -} - -func TestListAdd(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue := list.Empty(); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, ok := list.Get(2); actualValue != "c" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } -} - -func TestListIndexOf(t *testing.T) { - list := New() - - expectedIndex := -1 - if index := list.IndexOf("a"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } - - list.Add("a") - list.Add("b", "c") - - expectedIndex = 0 - if index := list.IndexOf("a"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } - - expectedIndex = 1 - if index := list.IndexOf("b"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } - - expectedIndex = 2 - if index := list.IndexOf("c"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } -} - -func TestListRemove(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - list.Remove(2) - if actualValue, ok := list.Get(2); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - list.Remove(1) - list.Remove(0) - list.Remove(0) // no effect - if actualValue := list.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } -} - -func TestListGet(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue, ok := list.Get(0); actualValue != "a" || !ok { - t.Errorf("Got %v expected %v", actualValue, "a") - } - if actualValue, ok := list.Get(1); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } - if actualValue, ok := list.Get(2); actualValue != "c" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } - if actualValue, ok := list.Get(3); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - list.Remove(0) - if actualValue, ok := list.Get(0); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } -} - -func TestListSwap(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - list.Swap(0, 1) - if actualValue, ok := list.Get(0); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } -} - -func TestListSort(t *testing.T) { - list := New() - list.Sort(utils.StringComparator) - list.Add("e", "f", "g", "a", "b", "c", "d") - list.Sort(utils.StringComparator) - for i := 1; i < list.Size(); i++ { - a, _ := list.Get(i - 1) - b, _ := list.Get(i) - if a.(string) > b.(string) { - t.Errorf("Not sorted! %s > %s", a, b) - } - } -} - -func TestListClear(t *testing.T) { - list := New() - list.Add("e", "f", "g", "a", "b", "c", "d") - list.Clear() - if actualValue := list.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } -} - -func TestListContains(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue := list.Contains("a"); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Contains("a", "b", "c"); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Contains("a", "b", "c", "d"); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - list.Clear() - if actualValue := list.Contains("a"); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := list.Contains("a", "b", "c"); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } -} - -func TestListValues(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListInsert(t *testing.T) { - list := New() - list.Insert(0, "b", "c") - list.Insert(0, "a") - list.Insert(10, "x") // ignore - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - list.Insert(3, "d") // append - if actualValue := list.Size(); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, 4) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", list.Values()...), "abcd"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListSet(t *testing.T) { - list := New() - list.Set(0, "a") - list.Set(1, "b") - if actualValue := list.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - list.Set(2, "c") // append - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - list.Set(4, "d") // ignore - list.Set(1, "bb") // update - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abbc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListEach(t *testing.T) { - list := New() - list.Add("a", "b", "c") - list.Each(func(index int, value interface{}) { - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - }) -} - -func TestListMap(t *testing.T) { - list := New() - list.Add("a", "b", "c") - mappedList := list.Map(func(index int, value interface{}) interface{} { - return "mapped: " + value.(string) - }) - if actualValue, _ := mappedList.Get(0); actualValue != "mapped: a" { - t.Errorf("Got %v expected %v", actualValue, "mapped: a") - } - if actualValue, _ := mappedList.Get(1); actualValue != "mapped: b" { - t.Errorf("Got %v expected %v", actualValue, "mapped: b") - } - if actualValue, _ := mappedList.Get(2); actualValue != "mapped: c" { - t.Errorf("Got %v expected %v", actualValue, "mapped: c") - } - if mappedList.Size() != 3 { - t.Errorf("Got %v expected %v", mappedList.Size(), 3) - } -} - -func TestListSelect(t *testing.T) { - list := New() - list.Add("a", "b", "c") - selectedList := list.Select(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "b" - }) - if actualValue, _ := selectedList.Get(0); actualValue != "a" { - t.Errorf("Got %v expected %v", actualValue, "value: a") - } - if actualValue, _ := selectedList.Get(1); actualValue != "b" { - t.Errorf("Got %v expected %v", actualValue, "value: b") - } - if selectedList.Size() != 2 { - t.Errorf("Got %v expected %v", selectedList.Size(), 3) - } -} - -func TestListAny(t *testing.T) { - list := New() - list.Add("a", "b", "c") - any := list.Any(func(index int, value interface{}) bool { - return value.(string) == "c" - }) - if any != true { - t.Errorf("Got %v expected %v", any, true) - } - any = list.Any(func(index int, value interface{}) bool { - return value.(string) == "x" - }) - if any != false { - t.Errorf("Got %v expected %v", any, false) - } -} -func TestListAll(t *testing.T) { - list := New() - list.Add("a", "b", "c") - all := list.All(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "c" - }) - if all != true { - t.Errorf("Got %v expected %v", all, true) - } - all = list.All(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "b" - }) - if all != false { - t.Errorf("Got %v expected %v", all, false) - } -} -func TestListFind(t *testing.T) { - list := New() - list.Add("a", "b", "c") - foundIndex, foundValue := list.Find(func(index int, value interface{}) bool { - return value.(string) == "c" - }) - if foundValue != "c" || foundIndex != 2 { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 2) - } - foundIndex, foundValue = list.Find(func(index int, value interface{}) bool { - return value.(string) == "x" - }) - if foundValue != nil || foundIndex != -1 { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, nil, nil) - } -} -func TestListChaining(t *testing.T) { - list := New() - list.Add("a", "b", "c") - chainedList := list.Select(func(index int, value interface{}) bool { - return value.(string) > "a" - }).Map(func(index int, value interface{}) interface{} { - return value.(string) + value.(string) - }) - if chainedList.Size() != 2 { - t.Errorf("Got %v expected %v", chainedList.Size(), 2) - } - if actualValue, ok := chainedList.Get(0); actualValue != "bb" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } - if actualValue, ok := chainedList.Get(1); actualValue != "cc" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } -} - -func TestListIteratorNextOnEmpty(t *testing.T) { - list := New() - it := list.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty list") - } -} - -func TestListIteratorNext(t *testing.T) { - list := New() - list.Add("a", "b", "c") - it := list.Iterator() - count := 0 - for it.Next() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListIteratorPrevOnEmpty(t *testing.T) { - list := New() - it := list.Iterator() - for it.Prev() { - t.Errorf("Shouldn't iterate on empty list") - } -} - -func TestListIteratorPrev(t *testing.T) { - list := New() - list.Add("a", "b", "c") - it := list.Iterator() - for it.Next() { - } - count := 0 - for it.Prev() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListIteratorBegin(t *testing.T) { - list := New() - it := list.Iterator() - it.Begin() - list.Add("a", "b", "c") - for it.Next() { - } - it.Begin() - it.Next() - if index, value := it.Index(), it.Value(); index != 0 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") - } -} - -func TestListIteratorEnd(t *testing.T) { - list := New() - it := list.Iterator() - - if index := it.Index(); index != -1 { - t.Errorf("Got %v expected %v", index, -1) - } - - it.End() - if index := it.Index(); index != 0 { - t.Errorf("Got %v expected %v", index, 0) - } - - list.Add("a", "b", "c") - it.End() - if index := it.Index(); index != list.Size() { - t.Errorf("Got %v expected %v", index, list.Size()) - } - - it.Prev() - if index, value := it.Index(), it.Value(); index != list.Size()-1 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, list.Size()-1, "c") - } -} - -func TestListIteratorFirst(t *testing.T) { - list := New() - it := list.Iterator() - if actualValue, expectedValue := it.First(), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - list.Add("a", "b", "c") - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 0 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") - } -} - -func TestListIteratorLast(t *testing.T) { - list := New() - it := list.Iterator() - if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - list.Add("a", "b", "c") - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 2 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "c") - } -} - -func TestListSerialization(t *testing.T) { - list := New() - list.Add("a", "b", "c") - - var err error - assert := func() { - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := list.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := list.ToJSON() - assert() - - err = list.FromJSON(json) - assert() -} - -func benchmarkGet(b *testing.B, list *List, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - list.Get(n) - } - } -} - -func benchmarkAdd(b *testing.B, list *List, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - list.Add(n) - } - } -} - -func benchmarkRemove(b *testing.B, list *List, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - list.Remove(n) - } - } -} - -func BenchmarkArrayListGet100(b *testing.B) { - b.StopTimer() - size := 100 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkArrayListGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkArrayListGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkArrayListGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkArrayListAdd100(b *testing.B) { - b.StopTimer() - size := 100 - list := New() - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkArrayListAdd1000(b *testing.B) { - b.StopTimer() - size := 1000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkArrayListAdd10000(b *testing.B) { - b.StopTimer() - size := 10000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkArrayListAdd100000(b *testing.B) { - b.StopTimer() - size := 100000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkArrayListRemove100(b *testing.B) { - b.StopTimer() - size := 100 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} - -func BenchmarkArrayListRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} - -func BenchmarkArrayListRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} - -func BenchmarkArrayListRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} diff --git a/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/doublylinkedlist.go b/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/doublylinkedlist.go deleted file mode 100644 index 9035e38e2..000000000 --- a/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/doublylinkedlist.go +++ /dev/null @@ -1,345 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package doublylinkedlist implements the doubly-linked list. -// -// Structure is not thread safe. -// -// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29 -package doublylinkedlist - -import ( - "fmt" - "strings" - - "github.com/emirpasic/gods/lists" - "github.com/emirpasic/gods/utils" -) - -func assertListImplementation() { - var _ lists.List = (*List)(nil) -} - -// List holds the elements, where each element points to the next and previous element -type List struct { - first *element - last *element - size int -} - -type element struct { - value interface{} - prev *element - next *element -} - -// New instantiates a new list and adds the passed values, if any, to the list -func New(values ...interface{}) *List { - list := &List{} - if len(values) > 0 { - list.Add(values...) - } - return list -} - -// Add appends a value (one or more) at the end of the list (same as Append()) -func (list *List) Add(values ...interface{}) { - for _, value := range values { - newElement := &element{value: value, prev: list.last} - if list.size == 0 { - list.first = newElement - list.last = newElement - } else { - list.last.next = newElement - list.last = newElement - } - list.size++ - } -} - -// Append appends a value (one or more) at the end of the list (same as Add()) -func (list *List) Append(values ...interface{}) { - list.Add(values...) -} - -// Prepend prepends a values (or more) -func (list *List) Prepend(values ...interface{}) { - // in reverse to keep passed order i.e. ["c","d"] -> Prepend(["a","b"]) -> ["a","b","c",d"] - for v := len(values) - 1; v >= 0; v-- { - newElement := &element{value: values[v], next: list.first} - if list.size == 0 { - list.first = newElement - list.last = newElement - } else { - list.first.prev = newElement - list.first = newElement - } - list.size++ - } -} - -// Get returns the element at index. -// Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false. -func (list *List) Get(index int) (interface{}, bool) { - - if !list.withinRange(index) { - return nil, false - } - - // determine traveral direction, last to first or first to last - if list.size-index < index { - element := list.last - for e := list.size - 1; e != index; e, element = e-1, element.prev { - } - return element.value, true - } - element := list.first - for e := 0; e != index; e, element = e+1, element.next { - } - return element.value, true -} - -// Remove removes the element at the given index from the list. -func (list *List) Remove(index int) { - - if !list.withinRange(index) { - return - } - - if list.size == 1 { - list.Clear() - return - } - - var element *element - // determine traversal direction, last to first or first to last - if list.size-index < index { - element = list.last - for e := list.size - 1; e != index; e, element = e-1, element.prev { - } - } else { - element = list.first - for e := 0; e != index; e, element = e+1, element.next { - } - } - - if element == list.first { - list.first = element.next - } - if element == list.last { - list.last = element.prev - } - if element.prev != nil { - element.prev.next = element.next - } - if element.next != nil { - element.next.prev = element.prev - } - - element = nil - - list.size-- -} - -// Contains check if values (one or more) are present in the set. -// All values have to be present in the set for the method to return true. -// Performance time complexity of n^2. -// Returns true if no arguments are passed at all, i.e. set is always super-set of empty set. -func (list *List) Contains(values ...interface{}) bool { - - if len(values) == 0 { - return true - } - if list.size == 0 { - return false - } - for _, value := range values { - found := false - for element := list.first; element != nil; element = element.next { - if element.value == value { - found = true - break - } - } - if !found { - return false - } - } - return true -} - -// Values returns all elements in the list. -func (list *List) Values() []interface{} { - values := make([]interface{}, list.size, list.size) - for e, element := 0, list.first; element != nil; e, element = e+1, element.next { - values[e] = element.value - } - return values -} - -//IndexOf returns index of provided element -func (list *List) IndexOf(value interface{}) int { - if list.size == 0 { - return -1 - } - for index, element := range list.Values() { - if element == value { - return index - } - } - return -1 -} - -// Empty returns true if list does not contain any elements. -func (list *List) Empty() bool { - return list.size == 0 -} - -// Size returns number of elements within the list. -func (list *List) Size() int { - return list.size -} - -// Clear removes all elements from the list. -func (list *List) Clear() { - list.size = 0 - list.first = nil - list.last = nil -} - -// Sort sorts values (in-place) using. -func (list *List) Sort(comparator utils.Comparator) { - - if list.size < 2 { - return - } - - values := list.Values() - utils.Sort(values, comparator) - - list.Clear() - - list.Add(values...) - -} - -// Swap swaps values of two elements at the given indices. -func (list *List) Swap(i, j int) { - if list.withinRange(i) && list.withinRange(j) && i != j { - var element1, element2 *element - for e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next { - switch e { - case i: - element1 = currentElement - case j: - element2 = currentElement - } - } - element1.value, element2.value = element2.value, element1.value - } -} - -// Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right. -// Does not do anything if position is negative or bigger than list's size -// Note: position equal to list's size is valid, i.e. append. -func (list *List) Insert(index int, values ...interface{}) { - - if !list.withinRange(index) { - // Append - if index == list.size { - list.Add(values...) - } - return - } - - list.size += len(values) - - var beforeElement *element - var foundElement *element - // determine traversal direction, last to first or first to last - if list.size-index < index { - foundElement = list.last - for e := list.size - 1; e != index; e, foundElement = e-1, foundElement.prev { - beforeElement = foundElement.prev - } - } else { - foundElement = list.first - for e := 0; e != index; e, foundElement = e+1, foundElement.next { - beforeElement = foundElement - } - } - - if foundElement == list.first { - oldNextElement := list.first - for i, value := range values { - newElement := &element{value: value} - if i == 0 { - list.first = newElement - } else { - newElement.prev = beforeElement - beforeElement.next = newElement - } - beforeElement = newElement - } - oldNextElement.prev = beforeElement - beforeElement.next = oldNextElement - } else { - oldNextElement := beforeElement.next - for _, value := range values { - newElement := &element{value: value} - newElement.prev = beforeElement - beforeElement.next = newElement - beforeElement = newElement - } - oldNextElement.prev = beforeElement - beforeElement.next = oldNextElement - } -} - -// Set value at specified index position -// Does not do anything if position is negative or bigger than list's size -// Note: position equal to list's size is valid, i.e. append. -func (list *List) Set(index int, value interface{}) { - - if !list.withinRange(index) { - // Append - if index == list.size { - list.Add(value) - } - return - } - - var foundElement *element - // determine traversal direction, last to first or first to last - if list.size-index < index { - foundElement = list.last - for e := list.size - 1; e != index; { - fmt.Println("Set last", index, value, foundElement, foundElement.prev) - e, foundElement = e-1, foundElement.prev - } - } else { - foundElement = list.first - for e := 0; e != index; { - e, foundElement = e+1, foundElement.next - } - } - - foundElement.value = value -} - -// String returns a string representation of container -func (list *List) String() string { - str := "DoublyLinkedList\n" - values := []string{} - for element := list.first; element != nil; element = element.next { - values = append(values, fmt.Sprintf("%v", element.value)) - } - str += strings.Join(values, ", ") - return str -} - -// Check that the index is within bounds of the list -func (list *List) withinRange(index int) bool { - return index >= 0 && index < list.size -} diff --git a/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/doublylinkedlist_test.go b/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/doublylinkedlist_test.go deleted file mode 100644 index 596bd2e46..000000000 --- a/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/doublylinkedlist_test.go +++ /dev/null @@ -1,686 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package doublylinkedlist - -import ( - "fmt" - "testing" - - "github.com/emirpasic/gods/utils" -) - -func TestListNew(t *testing.T) { - list1 := New() - - if actualValue := list1.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - - list2 := New(1, "b") - - if actualValue := list2.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - - if actualValue, ok := list2.Get(0); actualValue != 1 || !ok { - t.Errorf("Got %v expected %v", actualValue, 1) - } - - if actualValue, ok := list2.Get(1); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } - - if actualValue, ok := list2.Get(2); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } -} - -func TestListAdd(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue := list.Empty(); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, ok := list.Get(2); actualValue != "c" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } -} - -func TestListRemove(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - list.Remove(2) - if actualValue, ok := list.Get(2); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - list.Remove(1) - list.Remove(0) - list.Remove(0) // no effect - if actualValue := list.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } -} - -func TestListGet(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue, ok := list.Get(0); actualValue != "a" || !ok { - t.Errorf("Got %v expected %v", actualValue, "a") - } - if actualValue, ok := list.Get(1); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } - if actualValue, ok := list.Get(2); actualValue != "c" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } - if actualValue, ok := list.Get(3); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - list.Remove(0) - if actualValue, ok := list.Get(0); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } -} - -func TestListSwap(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - list.Swap(0, 1) - if actualValue, ok := list.Get(0); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } -} - -func TestListSort(t *testing.T) { - list := New() - list.Sort(utils.StringComparator) - list.Add("e", "f", "g", "a", "b", "c", "d") - list.Sort(utils.StringComparator) - for i := 1; i < list.Size(); i++ { - a, _ := list.Get(i - 1) - b, _ := list.Get(i) - if a.(string) > b.(string) { - t.Errorf("Not sorted! %s > %s", a, b) - } - } -} - -func TestListClear(t *testing.T) { - list := New() - list.Add("e", "f", "g", "a", "b", "c", "d") - list.Clear() - if actualValue := list.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } -} - -func TestListContains(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue := list.Contains("a"); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Contains("a", "b", "c"); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Contains("a", "b", "c", "d"); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - list.Clear() - if actualValue := list.Contains("a"); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := list.Contains("a", "b", "c"); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } -} - -func TestListValues(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListIndexOf(t *testing.T) { - list := New() - - expectedIndex := -1 - if index := list.IndexOf("a"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } - - list.Add("a") - list.Add("b", "c") - - expectedIndex = 0 - if index := list.IndexOf("a"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } - - expectedIndex = 1 - if index := list.IndexOf("b"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } - - expectedIndex = 2 - if index := list.IndexOf("c"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } -} - -func TestListInsert(t *testing.T) { - list := New() - list.Insert(0, "b", "c") - list.Insert(0, "a") - list.Insert(10, "x") // ignore - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - list.Insert(3, "d") // append - if actualValue := list.Size(); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, 4) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", list.Values()...), "abcd"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListSet(t *testing.T) { - list := New() - list.Set(0, "a") - list.Set(1, "b") - if actualValue := list.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - list.Set(2, "c") // append - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - list.Set(4, "d") // ignore - list.Set(1, "bb") // update - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abbc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - list.Set(2, "cc") // last to first traversal - list.Set(0, "aa") // first to last traversal - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "aabbcc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListEach(t *testing.T) { - list := New() - list.Add("a", "b", "c") - list.Each(func(index int, value interface{}) { - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - }) -} - -func TestListMap(t *testing.T) { - list := New() - list.Add("a", "b", "c") - mappedList := list.Map(func(index int, value interface{}) interface{} { - return "mapped: " + value.(string) - }) - if actualValue, _ := mappedList.Get(0); actualValue != "mapped: a" { - t.Errorf("Got %v expected %v", actualValue, "mapped: a") - } - if actualValue, _ := mappedList.Get(1); actualValue != "mapped: b" { - t.Errorf("Got %v expected %v", actualValue, "mapped: b") - } - if actualValue, _ := mappedList.Get(2); actualValue != "mapped: c" { - t.Errorf("Got %v expected %v", actualValue, "mapped: c") - } - if mappedList.Size() != 3 { - t.Errorf("Got %v expected %v", mappedList.Size(), 3) - } -} - -func TestListSelect(t *testing.T) { - list := New() - list.Add("a", "b", "c") - selectedList := list.Select(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "b" - }) - if actualValue, _ := selectedList.Get(0); actualValue != "a" { - t.Errorf("Got %v expected %v", actualValue, "value: a") - } - if actualValue, _ := selectedList.Get(1); actualValue != "b" { - t.Errorf("Got %v expected %v", actualValue, "value: b") - } - if selectedList.Size() != 2 { - t.Errorf("Got %v expected %v", selectedList.Size(), 3) - } -} - -func TestListAny(t *testing.T) { - list := New() - list.Add("a", "b", "c") - any := list.Any(func(index int, value interface{}) bool { - return value.(string) == "c" - }) - if any != true { - t.Errorf("Got %v expected %v", any, true) - } - any = list.Any(func(index int, value interface{}) bool { - return value.(string) == "x" - }) - if any != false { - t.Errorf("Got %v expected %v", any, false) - } -} -func TestListAll(t *testing.T) { - list := New() - list.Add("a", "b", "c") - all := list.All(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "c" - }) - if all != true { - t.Errorf("Got %v expected %v", all, true) - } - all = list.All(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "b" - }) - if all != false { - t.Errorf("Got %v expected %v", all, false) - } -} -func TestListFind(t *testing.T) { - list := New() - list.Add("a", "b", "c") - foundIndex, foundValue := list.Find(func(index int, value interface{}) bool { - return value.(string) == "c" - }) - if foundValue != "c" || foundIndex != 2 { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 2) - } - foundIndex, foundValue = list.Find(func(index int, value interface{}) bool { - return value.(string) == "x" - }) - if foundValue != nil || foundIndex != -1 { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, nil, nil) - } -} -func TestListChaining(t *testing.T) { - list := New() - list.Add("a", "b", "c") - chainedList := list.Select(func(index int, value interface{}) bool { - return value.(string) > "a" - }).Map(func(index int, value interface{}) interface{} { - return value.(string) + value.(string) - }) - if chainedList.Size() != 2 { - t.Errorf("Got %v expected %v", chainedList.Size(), 2) - } - if actualValue, ok := chainedList.Get(0); actualValue != "bb" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } - if actualValue, ok := chainedList.Get(1); actualValue != "cc" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } -} - -func TestListIteratorNextOnEmpty(t *testing.T) { - list := New() - it := list.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty list") - } -} - -func TestListIteratorNext(t *testing.T) { - list := New() - list.Add("a", "b", "c") - it := list.Iterator() - count := 0 - for it.Next() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListIteratorPrevOnEmpty(t *testing.T) { - list := New() - it := list.Iterator() - for it.Prev() { - t.Errorf("Shouldn't iterate on empty list") - } -} - -func TestListIteratorPrev(t *testing.T) { - list := New() - list.Add("a", "b", "c") - it := list.Iterator() - for it.Next() { - } - count := 0 - for it.Prev() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListIteratorBegin(t *testing.T) { - list := New() - it := list.Iterator() - it.Begin() - list.Add("a", "b", "c") - for it.Next() { - } - it.Begin() - it.Next() - if index, value := it.Index(), it.Value(); index != 0 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") - } -} - -func TestListIteratorEnd(t *testing.T) { - list := New() - it := list.Iterator() - - if index := it.Index(); index != -1 { - t.Errorf("Got %v expected %v", index, -1) - } - - it.End() - if index := it.Index(); index != 0 { - t.Errorf("Got %v expected %v", index, 0) - } - - list.Add("a", "b", "c") - it.End() - if index := it.Index(); index != list.Size() { - t.Errorf("Got %v expected %v", index, list.Size()) - } - - it.Prev() - if index, value := it.Index(), it.Value(); index != list.Size()-1 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, list.Size()-1, "c") - } -} - -func TestListIteratorFirst(t *testing.T) { - list := New() - it := list.Iterator() - if actualValue, expectedValue := it.First(), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - list.Add("a", "b", "c") - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 0 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") - } -} - -func TestListIteratorLast(t *testing.T) { - list := New() - it := list.Iterator() - if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - list.Add("a", "b", "c") - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 2 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "c") - } -} - -func TestListSerialization(t *testing.T) { - list := New() - list.Add("a", "b", "c") - - var err error - assert := func() { - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := list.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := list.ToJSON() - assert() - - err = list.FromJSON(json) - assert() -} - -func benchmarkGet(b *testing.B, list *List, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - list.Get(n) - } - } -} - -func benchmarkAdd(b *testing.B, list *List, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - list.Add(n) - } - } -} - -func benchmarkRemove(b *testing.B, list *List, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - list.Remove(n) - } - } -} - -func BenchmarkDoublyLinkedListGet100(b *testing.B) { - b.StopTimer() - size := 100 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkDoublyLinkedListGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkDoublyLinkedListGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkDoublyLinkedListGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkDoublyLinkedListAdd100(b *testing.B) { - b.StopTimer() - size := 100 - list := New() - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkDoublyLinkedListAdd1000(b *testing.B) { - b.StopTimer() - size := 1000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkDoublyLinkedListAdd10000(b *testing.B) { - b.StopTimer() - size := 10000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkDoublyLinkedListAdd100000(b *testing.B) { - b.StopTimer() - size := 100000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkDoublyLinkedListRemove100(b *testing.B) { - b.StopTimer() - size := 100 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} - -func BenchmarkDoublyLinkedListRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} - -func BenchmarkDoublyLinkedListRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} - -func BenchmarkDoublyLinkedListRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} diff --git a/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/enumerable.go b/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/enumerable.go deleted file mode 100644 index e6cf60fbc..000000000 --- a/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/enumerable.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package doublylinkedlist - -import "github.com/emirpasic/gods/containers" - -func assertEnumerableImplementation() { - var _ containers.EnumerableWithIndex = (*List)(nil) -} - -// Each calls the given function once for each element, passing that element's index and value. -func (list *List) Each(f func(index int, value interface{})) { - iterator := list.Iterator() - for iterator.Next() { - f(iterator.Index(), iterator.Value()) - } -} - -// Map invokes the given function once for each element and returns a -// container containing the values returned by the given function. -func (list *List) Map(f func(index int, value interface{}) interface{}) *List { - newList := &List{} - iterator := list.Iterator() - for iterator.Next() { - newList.Add(f(iterator.Index(), iterator.Value())) - } - return newList -} - -// Select returns a new container containing all elements for which the given function returns a true value. -func (list *List) Select(f func(index int, value interface{}) bool) *List { - newList := &List{} - iterator := list.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - newList.Add(iterator.Value()) - } - } - return newList -} - -// Any passes each element of the container to the given function and -// returns true if the function ever returns true for any element. -func (list *List) Any(f func(index int, value interface{}) bool) bool { - iterator := list.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - return true - } - } - return false -} - -// All passes each element of the container to the given function and -// returns true if the function returns true for all elements. -func (list *List) All(f func(index int, value interface{}) bool) bool { - iterator := list.Iterator() - for iterator.Next() { - if !f(iterator.Index(), iterator.Value()) { - return false - } - } - return true -} - -// Find passes each element of the container to the given function and returns -// the first (index,value) for which the function is true or -1,nil otherwise -// if no element matches the criteria. -func (list *List) Find(f func(index int, value interface{}) bool) (index int, value interface{}) { - iterator := list.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - return iterator.Index(), iterator.Value() - } - } - return -1, nil -} diff --git a/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/iterator.go b/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/iterator.go deleted file mode 100644 index 040921d03..000000000 --- a/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/iterator.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package doublylinkedlist - -import "github.com/emirpasic/gods/containers" - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil) -} - -// Iterator holding the iterator's state -type Iterator struct { - list *List - index int - element *element -} - -// Iterator returns a stateful iterator whose values can be fetched by an index. -func (list *List) Iterator() Iterator { - return Iterator{list: list, index: -1, element: nil} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - if iterator.index < iterator.list.size { - iterator.index++ - } - if !iterator.list.withinRange(iterator.index) { - iterator.element = nil - return false - } - if iterator.index != 0 { - iterator.element = iterator.element.next - } else { - iterator.element = iterator.list.first - } - return true -} - -// Prev moves the iterator to the previous element and returns true if there was a previous element in the container. -// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - if iterator.index >= 0 { - iterator.index-- - } - if !iterator.list.withinRange(iterator.index) { - iterator.element = nil - return false - } - if iterator.index == iterator.list.size-1 { - iterator.element = iterator.list.last - } else { - iterator.element = iterator.element.prev - } - return iterator.list.withinRange(iterator.index) -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - return iterator.element.value -} - -// Index returns the current element's index. -// Does not modify the state of the iterator. -func (iterator *Iterator) Index() int { - return iterator.index -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.index = -1 - iterator.element = nil -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.index = iterator.list.size - iterator.element = iterator.list.last -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) First() bool { - iterator.Begin() - return iterator.Next() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - iterator.End() - return iterator.Prev() -} diff --git a/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/serialization.go b/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/serialization.go deleted file mode 100644 index 6018d80f2..000000000 --- a/vendor/github.com/emirpasic/gods/lists/doublylinkedlist/serialization.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package doublylinkedlist - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*List)(nil) - var _ containers.JSONDeserializer = (*List)(nil) -} - -// ToJSON outputs the JSON representation of list's elements. -func (list *List) ToJSON() ([]byte, error) { - return json.Marshal(list.Values()) -} - -// FromJSON populates list's elements from the input JSON representation. -func (list *List) FromJSON(data []byte) error { - elements := []interface{}{} - err := json.Unmarshal(data, &elements) - if err == nil { - list.Clear() - list.Add(elements...) - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/enumerable.go b/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/enumerable.go deleted file mode 100644 index 61ac289af..000000000 --- a/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/enumerable.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package singlylinkedlist - -import "github.com/emirpasic/gods/containers" - -func assertEnumerableImplementation() { - var _ containers.EnumerableWithIndex = (*List)(nil) -} - -// Each calls the given function once for each element, passing that element's index and value. -func (list *List) Each(f func(index int, value interface{})) { - iterator := list.Iterator() - for iterator.Next() { - f(iterator.Index(), iterator.Value()) - } -} - -// Map invokes the given function once for each element and returns a -// container containing the values returned by the given function. -func (list *List) Map(f func(index int, value interface{}) interface{}) *List { - newList := &List{} - iterator := list.Iterator() - for iterator.Next() { - newList.Add(f(iterator.Index(), iterator.Value())) - } - return newList -} - -// Select returns a new container containing all elements for which the given function returns a true value. -func (list *List) Select(f func(index int, value interface{}) bool) *List { - newList := &List{} - iterator := list.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - newList.Add(iterator.Value()) - } - } - return newList -} - -// Any passes each element of the container to the given function and -// returns true if the function ever returns true for any element. -func (list *List) Any(f func(index int, value interface{}) bool) bool { - iterator := list.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - return true - } - } - return false -} - -// All passes each element of the container to the given function and -// returns true if the function returns true for all elements. -func (list *List) All(f func(index int, value interface{}) bool) bool { - iterator := list.Iterator() - for iterator.Next() { - if !f(iterator.Index(), iterator.Value()) { - return false - } - } - return true -} - -// Find passes each element of the container to the given function and returns -// the first (index,value) for which the function is true or -1,nil otherwise -// if no element matches the criteria. -func (list *List) Find(f func(index int, value interface{}) bool) (index int, value interface{}) { - iterator := list.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - return iterator.Index(), iterator.Value() - } - } - return -1, nil -} diff --git a/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/iterator.go b/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/iterator.go deleted file mode 100644 index 48605c266..000000000 --- a/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/iterator.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package singlylinkedlist - -import "github.com/emirpasic/gods/containers" - -func assertIteratorImplementation() { - var _ containers.IteratorWithIndex = (*Iterator)(nil) -} - -// Iterator holding the iterator's state -type Iterator struct { - list *List - index int - element *element -} - -// Iterator returns a stateful iterator whose values can be fetched by an index. -func (list *List) Iterator() Iterator { - return Iterator{list: list, index: -1, element: nil} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - if iterator.index < iterator.list.size { - iterator.index++ - } - if !iterator.list.withinRange(iterator.index) { - iterator.element = nil - return false - } - if iterator.index == 0 { - iterator.element = iterator.list.first - } else { - iterator.element = iterator.element.next - } - return true -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - return iterator.element.value -} - -// Index returns the current element's index. -// Does not modify the state of the iterator. -func (iterator *Iterator) Index() int { - return iterator.index -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.index = -1 - iterator.element = nil -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) First() bool { - iterator.Begin() - return iterator.Next() -} diff --git a/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/serialization.go b/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/serialization.go deleted file mode 100644 index 324f1d9a3..000000000 --- a/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/serialization.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package singlylinkedlist - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*List)(nil) - var _ containers.JSONDeserializer = (*List)(nil) -} - -// ToJSON outputs the JSON representation of list's elements. -func (list *List) ToJSON() ([]byte, error) { - return json.Marshal(list.Values()) -} - -// FromJSON populates list's elements from the input JSON representation. -func (list *List) FromJSON(data []byte) error { - elements := []interface{}{} - err := json.Unmarshal(data, &elements) - if err == nil { - list.Clear() - list.Add(elements...) - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/singlylinkedlist.go b/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/singlylinkedlist.go deleted file mode 100644 index b61df78ff..000000000 --- a/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/singlylinkedlist.go +++ /dev/null @@ -1,302 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package singlylinkedlist implements the singly-linked list. -// -// Structure is not thread safe. -// -// Reference: https://en.wikipedia.org/wiki/List_%28abstract_data_type%29 -package singlylinkedlist - -import ( - "fmt" - "strings" - - "github.com/emirpasic/gods/lists" - "github.com/emirpasic/gods/utils" -) - -func assertListImplementation() { - var _ lists.List = (*List)(nil) -} - -// List holds the elements, where each element points to the next element -type List struct { - first *element - last *element - size int -} - -type element struct { - value interface{} - next *element -} - -// New instantiates a new list and adds the passed values, if any, to the list -func New(values ...interface{}) *List { - list := &List{} - if len(values) > 0 { - list.Add(values...) - } - return list -} - -// Add appends a value (one or more) at the end of the list (same as Append()) -func (list *List) Add(values ...interface{}) { - for _, value := range values { - newElement := &element{value: value} - if list.size == 0 { - list.first = newElement - list.last = newElement - } else { - list.last.next = newElement - list.last = newElement - } - list.size++ - } -} - -// Append appends a value (one or more) at the end of the list (same as Add()) -func (list *List) Append(values ...interface{}) { - list.Add(values...) -} - -// Prepend prepends a values (or more) -func (list *List) Prepend(values ...interface{}) { - // in reverse to keep passed order i.e. ["c","d"] -> Prepend(["a","b"]) -> ["a","b","c",d"] - for v := len(values) - 1; v >= 0; v-- { - newElement := &element{value: values[v], next: list.first} - list.first = newElement - if list.size == 0 { - list.last = newElement - } - list.size++ - } -} - -// Get returns the element at index. -// Second return parameter is true if index is within bounds of the array and array is not empty, otherwise false. -func (list *List) Get(index int) (interface{}, bool) { - - if !list.withinRange(index) { - return nil, false - } - - element := list.first - for e := 0; e != index; e, element = e+1, element.next { - } - - return element.value, true -} - -// Remove removes the element at the given index from the list. -func (list *List) Remove(index int) { - - if !list.withinRange(index) { - return - } - - if list.size == 1 { - list.Clear() - return - } - - var beforeElement *element - element := list.first - for e := 0; e != index; e, element = e+1, element.next { - beforeElement = element - } - - if element == list.first { - list.first = element.next - } - if element == list.last { - list.last = beforeElement - } - if beforeElement != nil { - beforeElement.next = element.next - } - - element = nil - - list.size-- -} - -// Contains checks if values (one or more) are present in the set. -// All values have to be present in the set for the method to return true. -// Performance time complexity of n^2. -// Returns true if no arguments are passed at all, i.e. set is always super-set of empty set. -func (list *List) Contains(values ...interface{}) bool { - - if len(values) == 0 { - return true - } - if list.size == 0 { - return false - } - for _, value := range values { - found := false - for element := list.first; element != nil; element = element.next { - if element.value == value { - found = true - break - } - } - if !found { - return false - } - } - return true -} - -// Values returns all elements in the list. -func (list *List) Values() []interface{} { - values := make([]interface{}, list.size, list.size) - for e, element := 0, list.first; element != nil; e, element = e+1, element.next { - values[e] = element.value - } - return values -} - -//IndexOf returns index of provided element -func (list *List) IndexOf(value interface{}) int { - if list.size == 0 { - return -1 - } - for index, element := range list.Values() { - if element == value { - return index - } - } - return -1 -} - -// Empty returns true if list does not contain any elements. -func (list *List) Empty() bool { - return list.size == 0 -} - -// Size returns number of elements within the list. -func (list *List) Size() int { - return list.size -} - -// Clear removes all elements from the list. -func (list *List) Clear() { - list.size = 0 - list.first = nil - list.last = nil -} - -// Sort sort values (in-place) using. -func (list *List) Sort(comparator utils.Comparator) { - - if list.size < 2 { - return - } - - values := list.Values() - utils.Sort(values, comparator) - - list.Clear() - - list.Add(values...) - -} - -// Swap swaps values of two elements at the given indices. -func (list *List) Swap(i, j int) { - if list.withinRange(i) && list.withinRange(j) && i != j { - var element1, element2 *element - for e, currentElement := 0, list.first; element1 == nil || element2 == nil; e, currentElement = e+1, currentElement.next { - switch e { - case i: - element1 = currentElement - case j: - element2 = currentElement - } - } - element1.value, element2.value = element2.value, element1.value - } -} - -// Insert inserts values at specified index position shifting the value at that position (if any) and any subsequent elements to the right. -// Does not do anything if position is negative or bigger than list's size -// Note: position equal to list's size is valid, i.e. append. -func (list *List) Insert(index int, values ...interface{}) { - - if !list.withinRange(index) { - // Append - if index == list.size { - list.Add(values...) - } - return - } - - list.size += len(values) - - var beforeElement *element - foundElement := list.first - for e := 0; e != index; e, foundElement = e+1, foundElement.next { - beforeElement = foundElement - } - - if foundElement == list.first { - oldNextElement := list.first - for i, value := range values { - newElement := &element{value: value} - if i == 0 { - list.first = newElement - } else { - beforeElement.next = newElement - } - beforeElement = newElement - } - beforeElement.next = oldNextElement - } else { - oldNextElement := beforeElement.next - for _, value := range values { - newElement := &element{value: value} - beforeElement.next = newElement - beforeElement = newElement - } - beforeElement.next = oldNextElement - } -} - -// Set value at specified index -// Does not do anything if position is negative or bigger than list's size -// Note: position equal to list's size is valid, i.e. append. -func (list *List) Set(index int, value interface{}) { - - if !list.withinRange(index) { - // Append - if index == list.size { - list.Add(value) - } - return - } - - foundElement := list.first - for e := 0; e != index; { - e, foundElement = e+1, foundElement.next - } - foundElement.value = value -} - -// String returns a string representation of container -func (list *List) String() string { - str := "SinglyLinkedList\n" - values := []string{} - for element := list.first; element != nil; element = element.next { - values = append(values, fmt.Sprintf("%v", element.value)) - } - str += strings.Join(values, ", ") - return str -} - -// Check that the index is within bounds of the list -func (list *List) withinRange(index int) bool { - return index >= 0 && index < list.size -} diff --git a/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/singlylinkedlist_test.go b/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/singlylinkedlist_test.go deleted file mode 100644 index 9b6fe59c2..000000000 --- a/vendor/github.com/emirpasic/gods/lists/singlylinkedlist/singlylinkedlist_test.go +++ /dev/null @@ -1,600 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package singlylinkedlist - -import ( - "fmt" - "testing" - - "github.com/emirpasic/gods/utils" -) - -func TestListNew(t *testing.T) { - list1 := New() - - if actualValue := list1.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - - list2 := New(1, "b") - - if actualValue := list2.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - - if actualValue, ok := list2.Get(0); actualValue != 1 || !ok { - t.Errorf("Got %v expected %v", actualValue, 1) - } - - if actualValue, ok := list2.Get(1); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } - - if actualValue, ok := list2.Get(2); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } -} - -func TestListAdd(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue := list.Empty(); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, ok := list.Get(2); actualValue != "c" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } -} - -func TestListRemove(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - list.Remove(2) - if actualValue, ok := list.Get(2); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - list.Remove(1) - list.Remove(0) - list.Remove(0) // no effect - if actualValue := list.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } -} - -func TestListGet(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue, ok := list.Get(0); actualValue != "a" || !ok { - t.Errorf("Got %v expected %v", actualValue, "a") - } - if actualValue, ok := list.Get(1); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } - if actualValue, ok := list.Get(2); actualValue != "c" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } - if actualValue, ok := list.Get(3); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - list.Remove(0) - if actualValue, ok := list.Get(0); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } -} - -func TestListSwap(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - list.Swap(0, 1) - if actualValue, ok := list.Get(0); actualValue != "b" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } -} - -func TestListSort(t *testing.T) { - list := New() - list.Sort(utils.StringComparator) - list.Add("e", "f", "g", "a", "b", "c", "d") - list.Sort(utils.StringComparator) - for i := 1; i < list.Size(); i++ { - a, _ := list.Get(i - 1) - b, _ := list.Get(i) - if a.(string) > b.(string) { - t.Errorf("Not sorted! %s > %s", a, b) - } - } -} - -func TestListClear(t *testing.T) { - list := New() - list.Add("e", "f", "g", "a", "b", "c", "d") - list.Clear() - if actualValue := list.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } -} - -func TestListContains(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue := list.Contains("a"); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Contains("a", "b", "c"); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := list.Contains("a", "b", "c", "d"); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - list.Clear() - if actualValue := list.Contains("a"); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := list.Contains("a", "b", "c"); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } -} - -func TestListValues(t *testing.T) { - list := New() - list.Add("a") - list.Add("b", "c") - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListIndexOf(t *testing.T) { - list := New() - - expectedIndex := -1 - if index := list.IndexOf("a"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } - - list.Add("a") - list.Add("b", "c") - - expectedIndex = 0 - if index := list.IndexOf("a"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } - - expectedIndex = 1 - if index := list.IndexOf("b"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } - - expectedIndex = 2 - if index := list.IndexOf("c"); index != expectedIndex { - t.Errorf("Got %v expected %v", index, expectedIndex) - } -} - -func TestListInsert(t *testing.T) { - list := New() - list.Insert(0, "b", "c") - list.Insert(0, "a") - list.Insert(10, "x") // ignore - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - list.Insert(3, "d") // append - if actualValue := list.Size(); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, 4) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", list.Values()...), "abcd"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListSet(t *testing.T) { - list := New() - list.Set(0, "a") - list.Set(1, "b") - if actualValue := list.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - list.Set(2, "c") // append - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - list.Set(4, "d") // ignore - list.Set(1, "bb") // update - if actualValue := list.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abbc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListEach(t *testing.T) { - list := New() - list.Add("a", "b", "c") - list.Each(func(index int, value interface{}) { - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - }) -} - -func TestListMap(t *testing.T) { - list := New() - list.Add("a", "b", "c") - mappedList := list.Map(func(index int, value interface{}) interface{} { - return "mapped: " + value.(string) - }) - if actualValue, _ := mappedList.Get(0); actualValue != "mapped: a" { - t.Errorf("Got %v expected %v", actualValue, "mapped: a") - } - if actualValue, _ := mappedList.Get(1); actualValue != "mapped: b" { - t.Errorf("Got %v expected %v", actualValue, "mapped: b") - } - if actualValue, _ := mappedList.Get(2); actualValue != "mapped: c" { - t.Errorf("Got %v expected %v", actualValue, "mapped: c") - } - if mappedList.Size() != 3 { - t.Errorf("Got %v expected %v", mappedList.Size(), 3) - } -} - -func TestListSelect(t *testing.T) { - list := New() - list.Add("a", "b", "c") - selectedList := list.Select(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "b" - }) - if actualValue, _ := selectedList.Get(0); actualValue != "a" { - t.Errorf("Got %v expected %v", actualValue, "value: a") - } - if actualValue, _ := selectedList.Get(1); actualValue != "b" { - t.Errorf("Got %v expected %v", actualValue, "value: b") - } - if selectedList.Size() != 2 { - t.Errorf("Got %v expected %v", selectedList.Size(), 3) - } -} - -func TestListAny(t *testing.T) { - list := New() - list.Add("a", "b", "c") - any := list.Any(func(index int, value interface{}) bool { - return value.(string) == "c" - }) - if any != true { - t.Errorf("Got %v expected %v", any, true) - } - any = list.Any(func(index int, value interface{}) bool { - return value.(string) == "x" - }) - if any != false { - t.Errorf("Got %v expected %v", any, false) - } -} -func TestListAll(t *testing.T) { - list := New() - list.Add("a", "b", "c") - all := list.All(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "c" - }) - if all != true { - t.Errorf("Got %v expected %v", all, true) - } - all = list.All(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "b" - }) - if all != false { - t.Errorf("Got %v expected %v", all, false) - } -} -func TestListFind(t *testing.T) { - list := New() - list.Add("a", "b", "c") - foundIndex, foundValue := list.Find(func(index int, value interface{}) bool { - return value.(string) == "c" - }) - if foundValue != "c" || foundIndex != 2 { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 2) - } - foundIndex, foundValue = list.Find(func(index int, value interface{}) bool { - return value.(string) == "x" - }) - if foundValue != nil || foundIndex != -1 { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, nil, nil) - } -} -func TestListChaining(t *testing.T) { - list := New() - list.Add("a", "b", "c") - chainedList := list.Select(func(index int, value interface{}) bool { - return value.(string) > "a" - }).Map(func(index int, value interface{}) interface{} { - return value.(string) + value.(string) - }) - if chainedList.Size() != 2 { - t.Errorf("Got %v expected %v", chainedList.Size(), 2) - } - if actualValue, ok := chainedList.Get(0); actualValue != "bb" || !ok { - t.Errorf("Got %v expected %v", actualValue, "b") - } - if actualValue, ok := chainedList.Get(1); actualValue != "cc" || !ok { - t.Errorf("Got %v expected %v", actualValue, "c") - } -} - -func TestListIteratorNextOnEmpty(t *testing.T) { - list := New() - it := list.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty list") - } -} - -func TestListIteratorNext(t *testing.T) { - list := New() - list.Add("a", "b", "c") - it := list.Iterator() - count := 0 - for it.Next() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestListIteratorBegin(t *testing.T) { - list := New() - it := list.Iterator() - it.Begin() - list.Add("a", "b", "c") - for it.Next() { - } - it.Begin() - it.Next() - if index, value := it.Index(), it.Value(); index != 0 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") - } -} - -func TestListIteratorFirst(t *testing.T) { - list := New() - it := list.Iterator() - if actualValue, expectedValue := it.First(), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - list.Add("a", "b", "c") - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 0 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") - } -} - -func TestListSerialization(t *testing.T) { - list := New() - list.Add("a", "b", "c") - - var err error - assert := func() { - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", list.Values()...), "abc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := list.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := list.ToJSON() - assert() - - err = list.FromJSON(json) - assert() -} - -func benchmarkGet(b *testing.B, list *List, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - list.Get(n) - } - } -} - -func benchmarkAdd(b *testing.B, list *List, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - list.Add(n) - } - } -} - -func benchmarkRemove(b *testing.B, list *List, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - list.Remove(n) - } - } -} - -func BenchmarkSinglyLinkedListGet100(b *testing.B) { - b.StopTimer() - size := 100 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkSinglyLinkedListGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkSinglyLinkedListGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkSinglyLinkedListGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkGet(b, list, size) -} - -func BenchmarkSinglyLinkedListAdd100(b *testing.B) { - b.StopTimer() - size := 100 - list := New() - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkSinglyLinkedListAdd1000(b *testing.B) { - b.StopTimer() - size := 1000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkSinglyLinkedListAdd10000(b *testing.B) { - b.StopTimer() - size := 10000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkSinglyLinkedListAdd100000(b *testing.B) { - b.StopTimer() - size := 100000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkAdd(b, list, size) -} - -func BenchmarkSinglyLinkedListRemove100(b *testing.B) { - b.StopTimer() - size := 100 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} - -func BenchmarkSinglyLinkedListRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} - -func BenchmarkSinglyLinkedListRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} - -func BenchmarkSinglyLinkedListRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - list := New() - for n := 0; n < size; n++ { - list.Add(n) - } - b.StartTimer() - benchmarkRemove(b, list, size) -} diff --git a/vendor/github.com/emirpasic/gods/maps/hashbidimap/hashbidimap.go b/vendor/github.com/emirpasic/gods/maps/hashbidimap/hashbidimap.go deleted file mode 100644 index 32985ab20..000000000 --- a/vendor/github.com/emirpasic/gods/maps/hashbidimap/hashbidimap.go +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package hashbidimap implements a bidirectional map backed by two hashmaps. -// -// A bidirectional map, or hash bag, is an associative data structure in which the (key,value) pairs form a one-to-one correspondence. -// Thus the binary relation is functional in each direction: value can also act as a key to key. -// A pair (a,b) thus provides a unique coupling between 'a' and 'b' so that 'b' can be found when 'a' is used as a key and 'a' can be found when 'b' is used as a key. -// -// Elements are unordered in the map. -// -// Structure is not thread safe. -// -// Reference: https://en.wikipedia.org/wiki/Bidirectional_map -package hashbidimap - -import ( - "fmt" - "github.com/emirpasic/gods/maps" - "github.com/emirpasic/gods/maps/hashmap" -) - -func assertMapImplementation() { - var _ maps.BidiMap = (*Map)(nil) -} - -// Map holds the elements in two hashmaps. -type Map struct { - forwardMap hashmap.Map - inverseMap hashmap.Map -} - -// New instantiates a bidirectional map. -func New() *Map { - return &Map{*hashmap.New(), *hashmap.New()} -} - -// Put inserts element into the map. -func (m *Map) Put(key interface{}, value interface{}) { - if valueByKey, ok := m.forwardMap.Get(key); ok { - m.inverseMap.Remove(valueByKey) - } - if keyByValue, ok := m.inverseMap.Get(value); ok { - m.forwardMap.Remove(keyByValue) - } - m.forwardMap.Put(key, value) - m.inverseMap.Put(value, key) -} - -// Get searches the element in the map by key and returns its value or nil if key is not found in map. -// Second return parameter is true if key was found, otherwise false. -func (m *Map) Get(key interface{}) (value interface{}, found bool) { - return m.forwardMap.Get(key) -} - -// GetKey searches the element in the map by value and returns its key or nil if value is not found in map. -// Second return parameter is true if value was found, otherwise false. -func (m *Map) GetKey(value interface{}) (key interface{}, found bool) { - return m.inverseMap.Get(value) -} - -// Remove removes the element from the map by key. -func (m *Map) Remove(key interface{}) { - if value, found := m.forwardMap.Get(key); found { - m.forwardMap.Remove(key) - m.inverseMap.Remove(value) - } -} - -// Empty returns true if map does not contain any elements -func (m *Map) Empty() bool { - return m.Size() == 0 -} - -// Size returns number of elements in the map. -func (m *Map) Size() int { - return m.forwardMap.Size() -} - -// Keys returns all keys (random order). -func (m *Map) Keys() []interface{} { - return m.forwardMap.Keys() -} - -// Values returns all values (random order). -func (m *Map) Values() []interface{} { - return m.inverseMap.Keys() -} - -// Clear removes all elements from the map. -func (m *Map) Clear() { - m.forwardMap.Clear() - m.inverseMap.Clear() -} - -// String returns a string representation of container -func (m *Map) String() string { - str := "HashBidiMap\n" - str += fmt.Sprintf("%v", m.forwardMap) - return str -} diff --git a/vendor/github.com/emirpasic/gods/maps/hashbidimap/hashbidimap_test.go b/vendor/github.com/emirpasic/gods/maps/hashbidimap/hashbidimap_test.go deleted file mode 100644 index 96e468894..000000000 --- a/vendor/github.com/emirpasic/gods/maps/hashbidimap/hashbidimap_test.go +++ /dev/null @@ -1,354 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package hashbidimap - -import ( - "fmt" - "testing" -) - -func TestMapPut(t *testing.T) { - m := New() - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - if actualValue := m.Size(); actualValue != 7 { - t.Errorf("Got %v expected %v", actualValue, 7) - } - if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - // key,expectedValue,expectedFound - tests1 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {8, nil, false}, - } - - for _, test := range tests1 { - // retrievals - actualValue, actualFound := m.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } -} - -func TestMapRemove(t *testing.T) { - m := New() - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - m.Remove(5) - m.Remove(6) - m.Remove(7) - m.Remove(8) - m.Remove(5) - - if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := m.Size(); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, 4) - } - - tests2 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, nil, false}, - {6, nil, false}, - {7, nil, false}, - {8, nil, false}, - } - - for _, test := range tests2 { - actualValue, actualFound := m.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } - - m.Remove(1) - m.Remove(4) - m.Remove(2) - m.Remove(3) - m.Remove(2) - m.Remove(2) - - if actualValue, expectedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := m.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } - if actualValue := m.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } -} - -func TestMapGetKey(t *testing.T) { - m := New() - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - // key,expectedValue,expectedFound - tests1 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {nil, "x", false}, - } - - for _, test := range tests1 { - // retrievals - actualValue, actualFound := m.GetKey(test[1]) - if actualValue != test[0] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[0]) - } - } -} - -func TestMapSerialization(t *testing.T) { - m := New() - m.Put("a", 1.0) - m.Put("b", 2.0) - m.Put("c", 3.0) - - var err error - assert := func() { - if actualValue, expectedValue := m.Keys(), []interface{}{"a", "b", "c"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := m.Values(), []interface{}{1.0, 2.0, 3.0}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := m.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := m.ToJSON() - assert() - - err = m.FromJSON(json) - assert() -} - -func sameElements(a []interface{}, b []interface{}) bool { - if len(a) != len(b) { - return false - } - for _, av := range a { - found := false - for _, bv := range b { - if av == bv { - found = true - break - } - } - if !found { - return false - } - } - return true -} - -func benchmarkGet(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Get(n) - } - } -} - -func benchmarkPut(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Put(n, n) - } - } -} - -func benchmarkRemove(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Remove(n) - } - } -} - -func BenchmarkHashBidiMapGet100(b *testing.B) { - b.StopTimer() - size := 100 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkHashBidiMapGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkHashBidiMapGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkHashBidiMapGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkHashBidiMapPut100(b *testing.B) { - b.StopTimer() - size := 100 - m := New() - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkHashBidiMapPut1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkHashBidiMapPut10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkHashBidiMapPut100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkHashBidiMapRemove100(b *testing.B) { - b.StopTimer() - size := 100 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkHashBidiMapRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkHashBidiMapRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkHashBidiMapRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} diff --git a/vendor/github.com/emirpasic/gods/maps/hashbidimap/serialization.go b/vendor/github.com/emirpasic/gods/maps/hashbidimap/serialization.go deleted file mode 100644 index 3db41d421..000000000 --- a/vendor/github.com/emirpasic/gods/maps/hashbidimap/serialization.go +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package hashbidimap - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Map)(nil) - var _ containers.JSONDeserializer = (*Map)(nil) -} - -// ToJSON outputs the JSON representation of the map. -func (m *Map) ToJSON() ([]byte, error) { - return m.forwardMap.ToJSON() -} - -// FromJSON populates the map from the input JSON representation. -func (m *Map) FromJSON(data []byte) error { - elements := make(map[string]interface{}) - err := json.Unmarshal(data, &elements) - if err == nil { - m.Clear() - for key, value := range elements { - m.Put(key, value) - } - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/maps/hashmap/hashmap.go b/vendor/github.com/emirpasic/gods/maps/hashmap/hashmap.go deleted file mode 100644 index 3f42ffc10..000000000 --- a/vendor/github.com/emirpasic/gods/maps/hashmap/hashmap.go +++ /dev/null @@ -1,92 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package hashmap implements a map backed by a hash table. -// -// Elements are unordered in the map. -// -// Structure is not thread safe. -// -// Reference: http://en.wikipedia.org/wiki/Associative_array -package hashmap - -import ( - "fmt" - "github.com/emirpasic/gods/maps" -) - -func assertMapImplementation() { - var _ maps.Map = (*Map)(nil) -} - -// Map holds the elements in go's native map -type Map struct { - m map[interface{}]interface{} -} - -// New instantiates a hash map. -func New() *Map { - return &Map{m: make(map[interface{}]interface{})} -} - -// Put inserts element into the map. -func (m *Map) Put(key interface{}, value interface{}) { - m.m[key] = value -} - -// Get searches the element in the map by key and returns its value or nil if key is not found in map. -// Second return parameter is true if key was found, otherwise false. -func (m *Map) Get(key interface{}) (value interface{}, found bool) { - value, found = m.m[key] - return -} - -// Remove removes the element from the map by key. -func (m *Map) Remove(key interface{}) { - delete(m.m, key) -} - -// Empty returns true if map does not contain any elements -func (m *Map) Empty() bool { - return m.Size() == 0 -} - -// Size returns number of elements in the map. -func (m *Map) Size() int { - return len(m.m) -} - -// Keys returns all keys (random order). -func (m *Map) Keys() []interface{} { - keys := make([]interface{}, m.Size()) - count := 0 - for key := range m.m { - keys[count] = key - count++ - } - return keys -} - -// Values returns all values (random order). -func (m *Map) Values() []interface{} { - values := make([]interface{}, m.Size()) - count := 0 - for _, value := range m.m { - values[count] = value - count++ - } - return values -} - -// Clear removes all elements from the map. -func (m *Map) Clear() { - m.m = make(map[interface{}]interface{}) -} - -// String returns a string representation of container -func (m *Map) String() string { - str := "HashMap\n" - str += fmt.Sprintf("%v", m.m) - return str -} diff --git a/vendor/github.com/emirpasic/gods/maps/hashmap/hashmap_test.go b/vendor/github.com/emirpasic/gods/maps/hashmap/hashmap_test.go deleted file mode 100644 index 7122574df..000000000 --- a/vendor/github.com/emirpasic/gods/maps/hashmap/hashmap_test.go +++ /dev/null @@ -1,322 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package hashmap - -import ( - "fmt" - "testing" -) - -func TestMapPut(t *testing.T) { - m := New() - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - if actualValue := m.Size(); actualValue != 7 { - t.Errorf("Got %v expected %v", actualValue, 7) - } - if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - // key,expectedValue,expectedFound - tests1 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {8, nil, false}, - } - - for _, test := range tests1 { - // retrievals - actualValue, actualFound := m.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } -} - -func TestMapRemove(t *testing.T) { - m := New() - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - m.Remove(5) - m.Remove(6) - m.Remove(7) - m.Remove(8) - m.Remove(5) - - if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := m.Size(); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, 4) - } - - tests2 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, nil, false}, - {6, nil, false}, - {7, nil, false}, - {8, nil, false}, - } - - for _, test := range tests2 { - actualValue, actualFound := m.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } - - m.Remove(1) - m.Remove(4) - m.Remove(2) - m.Remove(3) - m.Remove(2) - m.Remove(2) - - if actualValue, expectedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := m.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } - if actualValue := m.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } -} - -func TestMapSerialization(t *testing.T) { - m := New() - m.Put("a", 1.0) - m.Put("b", 2.0) - m.Put("c", 3.0) - - var err error - assert := func() { - if actualValue, expectedValue := m.Keys(), []interface{}{"a", "b", "c"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := m.Values(), []interface{}{1.0, 2.0, 3.0}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := m.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := m.ToJSON() - assert() - - err = m.FromJSON(json) - assert() -} - -func sameElements(a []interface{}, b []interface{}) bool { - if len(a) != len(b) { - return false - } - for _, av := range a { - found := false - for _, bv := range b { - if av == bv { - found = true - break - } - } - if !found { - return false - } - } - return true -} - -func benchmarkGet(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Get(n) - } - } -} - -func benchmarkPut(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - } -} - -func benchmarkRemove(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Remove(n) - } - } -} - -func BenchmarkHashMapGet100(b *testing.B) { - b.StopTimer() - size := 100 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkHashMapGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkHashMapGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkHashMapGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkHashMapPut100(b *testing.B) { - b.StopTimer() - size := 100 - m := New() - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkHashMapPut1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkHashMapPut10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkHashMapPut100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkHashMapRemove100(b *testing.B) { - b.StopTimer() - size := 100 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkHashMapRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkHashMapRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkHashMapRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} diff --git a/vendor/github.com/emirpasic/gods/maps/hashmap/serialization.go b/vendor/github.com/emirpasic/gods/maps/hashmap/serialization.go deleted file mode 100644 index b06eb7efa..000000000 --- a/vendor/github.com/emirpasic/gods/maps/hashmap/serialization.go +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package hashmap - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" - "github.com/emirpasic/gods/utils" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Map)(nil) - var _ containers.JSONDeserializer = (*Map)(nil) -} - -// ToJSON outputs the JSON representation of the map. -func (m *Map) ToJSON() ([]byte, error) { - elements := make(map[string]interface{}) - for key, value := range m.m { - elements[utils.ToString(key)] = value - } - return json.Marshal(&elements) -} - -// FromJSON populates the map from the input JSON representation. -func (m *Map) FromJSON(data []byte) error { - elements := make(map[string]interface{}) - err := json.Unmarshal(data, &elements) - if err == nil { - m.Clear() - for key, value := range elements { - m.m[key] = value - } - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/maps/linkedhashmap/enumerable.go b/vendor/github.com/emirpasic/gods/maps/linkedhashmap/enumerable.go deleted file mode 100644 index 644b00fdc..000000000 --- a/vendor/github.com/emirpasic/gods/maps/linkedhashmap/enumerable.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedhashmap - -import "github.com/emirpasic/gods/containers" - -func assertEnumerableImplementation() { - var _ containers.EnumerableWithKey = (*Map)(nil) -} - -// Each calls the given function once for each element, passing that element's key and value. -func (m *Map) Each(f func(key interface{}, value interface{})) { - iterator := m.Iterator() - for iterator.Next() { - f(iterator.Key(), iterator.Value()) - } -} - -// Map invokes the given function once for each element and returns a container -// containing the values returned by the given function as key/value pairs. -func (m *Map) Map(f func(key1 interface{}, value1 interface{}) (interface{}, interface{})) *Map { - newMap := New() - iterator := m.Iterator() - for iterator.Next() { - key2, value2 := f(iterator.Key(), iterator.Value()) - newMap.Put(key2, value2) - } - return newMap -} - -// Select returns a new container containing all elements for which the given function returns a true value. -func (m *Map) Select(f func(key interface{}, value interface{}) bool) *Map { - newMap := New() - iterator := m.Iterator() - for iterator.Next() { - if f(iterator.Key(), iterator.Value()) { - newMap.Put(iterator.Key(), iterator.Value()) - } - } - return newMap -} - -// Any passes each element of the container to the given function and -// returns true if the function ever returns true for any element. -func (m *Map) Any(f func(key interface{}, value interface{}) bool) bool { - iterator := m.Iterator() - for iterator.Next() { - if f(iterator.Key(), iterator.Value()) { - return true - } - } - return false -} - -// All passes each element of the container to the given function and -// returns true if the function returns true for all elements. -func (m *Map) All(f func(key interface{}, value interface{}) bool) bool { - iterator := m.Iterator() - for iterator.Next() { - if !f(iterator.Key(), iterator.Value()) { - return false - } - } - return true -} - -// Find passes each element of the container to the given function and returns -// the first (key,value) for which the function is true or nil,nil otherwise if no element -// matches the criteria. -func (m *Map) Find(f func(key interface{}, value interface{}) bool) (interface{}, interface{}) { - iterator := m.Iterator() - for iterator.Next() { - if f(iterator.Key(), iterator.Value()) { - return iterator.Key(), iterator.Value() - } - } - return nil, nil -} diff --git a/vendor/github.com/emirpasic/gods/maps/linkedhashmap/iterator.go b/vendor/github.com/emirpasic/gods/maps/linkedhashmap/iterator.go deleted file mode 100644 index d846efce7..000000000 --- a/vendor/github.com/emirpasic/gods/maps/linkedhashmap/iterator.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedhashmap - -import ( - "github.com/emirpasic/gods/containers" - "github.com/emirpasic/gods/lists/doublylinkedlist" -) - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithKey = (*Iterator)(nil) -} - -// Iterator holding the iterator's state -type Iterator struct { - iterator doublylinkedlist.Iterator - table map[interface{}]interface{} -} - -// Iterator returns a stateful iterator whose elements are key/value pairs. -func (m *Map) Iterator() Iterator { - return Iterator{ - iterator: m.ordering.Iterator(), - table: m.table} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's key and value can be retrieved by Key() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - return iterator.iterator.Next() -} - -// Prev moves the iterator to the previous element and returns true if there was a previous element in the container. -// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - return iterator.iterator.Prev() -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - key := iterator.iterator.Value() - return iterator.table[key] -} - -// Key returns the current element's key. -// Does not modify the state of the iterator. -func (iterator *Iterator) Key() interface{} { - return iterator.iterator.Value() -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.iterator.Begin() -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.iterator.End() -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator -func (iterator *Iterator) First() bool { - return iterator.iterator.First() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - return iterator.iterator.Last() -} diff --git a/vendor/github.com/emirpasic/gods/maps/linkedhashmap/linkedhashmap.go b/vendor/github.com/emirpasic/gods/maps/linkedhashmap/linkedhashmap.go deleted file mode 100644 index 45c4e35e8..000000000 --- a/vendor/github.com/emirpasic/gods/maps/linkedhashmap/linkedhashmap.go +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package linkedhashmap is a map that preserves insertion-order. -// -// It is backed by a hash table to store values and doubly-linked list to store ordering. -// -// Structure is not thread safe. -// -// Reference: http://en.wikipedia.org/wiki/Associative_array -package linkedhashmap - -import ( - "fmt" - "github.com/emirpasic/gods/lists/doublylinkedlist" - "github.com/emirpasic/gods/maps" - "strings" -) - -func assertMapImplementation() { - var _ maps.Map = (*Map)(nil) -} - -// Map holds the elements in a regular hash table, and uses doubly-linked list to store key ordering. -type Map struct { - table map[interface{}]interface{} - ordering *doublylinkedlist.List -} - -// New instantiates a linked-hash-map. -func New() *Map { - return &Map{ - table: make(map[interface{}]interface{}), - ordering: doublylinkedlist.New(), - } -} - -// Put inserts key-value pair into the map. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Put(key interface{}, value interface{}) { - if _, contains := m.table[key]; !contains { - m.ordering.Append(key) - } - m.table[key] = value -} - -// Get searches the element in the map by key and returns its value or nil if key is not found in tree. -// Second return parameter is true if key was found, otherwise false. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Get(key interface{}) (value interface{}, found bool) { - value = m.table[key] - found = value != nil - return -} - -// Remove removes the element from the map by key. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Remove(key interface{}) { - if _, contains := m.table[key]; contains { - delete(m.table, key) - index := m.ordering.IndexOf(key) - m.ordering.Remove(index) - } -} - -// Empty returns true if map does not contain any elements -func (m *Map) Empty() bool { - return m.Size() == 0 -} - -// Size returns number of elements in the map. -func (m *Map) Size() int { - return m.ordering.Size() -} - -// Keys returns all keys in-order -func (m *Map) Keys() []interface{} { - return m.ordering.Values() -} - -// Values returns all values in-order based on the key. -func (m *Map) Values() []interface{} { - values := make([]interface{}, m.Size()) - count := 0 - it := m.Iterator() - for it.Next() { - values[count] = it.Value() - count++ - } - return values -} - -// Clear removes all elements from the map. -func (m *Map) Clear() { - m.table = make(map[interface{}]interface{}) - m.ordering.Clear() -} - -// String returns a string representation of container -func (m *Map) String() string { - str := "LinkedHashMap\nmap[" - it := m.Iterator() - for it.Next() { - str += fmt.Sprintf("%v:%v ", it.Key(), it.Value()) - } - return strings.TrimRight(str, " ") + "]" - -} diff --git a/vendor/github.com/emirpasic/gods/maps/linkedhashmap/linkedhashmap_test.go b/vendor/github.com/emirpasic/gods/maps/linkedhashmap/linkedhashmap_test.go deleted file mode 100644 index 78437f146..000000000 --- a/vendor/github.com/emirpasic/gods/maps/linkedhashmap/linkedhashmap_test.go +++ /dev/null @@ -1,643 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedhashmap - -import ( - "fmt" - "testing" -) - -func TestMapPut(t *testing.T) { - m := New() - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - if actualValue := m.Size(); actualValue != 7 { - t.Errorf("Got %v expected %v", actualValue, 7) - } - if actualValue, expectedValue := m.Keys(), []interface{}{5, 6, 7, 3, 4, 1, 2}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := m.Values(), []interface{}{"e", "f", "g", "c", "d", "a", "b"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - // key,expectedValue,expectedFound - tests1 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {8, nil, false}, - } - - for _, test := range tests1 { - // retrievals - actualValue, actualFound := m.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } -} - -func TestMapRemove(t *testing.T) { - m := New() - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - m.Remove(5) - m.Remove(6) - m.Remove(7) - m.Remove(8) - m.Remove(5) - - if actualValue, expectedValue := m.Keys(), []interface{}{3, 4, 1, 2}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - if actualValue, expectedValue := m.Values(), []interface{}{"c", "d", "a", "b"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := m.Size(); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, 4) - } - - tests2 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, nil, false}, - {6, nil, false}, - {7, nil, false}, - {8, nil, false}, - } - - for _, test := range tests2 { - actualValue, actualFound := m.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } - - m.Remove(1) - m.Remove(4) - m.Remove(2) - m.Remove(3) - m.Remove(2) - m.Remove(2) - - if actualValue, expectedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := m.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } - if actualValue := m.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } -} - -func sameElements(a []interface{}, b []interface{}) bool { - // If one is nil, the other must also be nil. - if (a == nil) != (b == nil) { - return false - } - - if len(a) != len(b) { - return false - } - - for i := range a { - if a[i] != b[i] { - return false - } - } - - return true -} - -func TestMapEach(t *testing.T) { - m := New() - m.Put("c", 1) - m.Put("a", 2) - m.Put("b", 3) - count := 0 - m.Each(func(key interface{}, value interface{}) { - count++ - if actualValue, expectedValue := count, value; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - switch value { - case 1: - if actualValue, expectedValue := key, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := key, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 3: - if actualValue, expectedValue := key, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - }) -} - -func TestMapMap(t *testing.T) { - m := New() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - mappedMap := m.Map(func(key1 interface{}, value1 interface{}) (key2 interface{}, value2 interface{}) { - return key1, value1.(int) * value1.(int) - }) - if actualValue, _ := mappedMap.Get("c"); actualValue != 9 { - t.Errorf("Got %v expected %v", actualValue, "mapped: c") - } - if actualValue, _ := mappedMap.Get("a"); actualValue != 1 { - t.Errorf("Got %v expected %v", actualValue, "mapped: a") - } - if actualValue, _ := mappedMap.Get("b"); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, "mapped: b") - } - if mappedMap.Size() != 3 { - t.Errorf("Got %v expected %v", mappedMap.Size(), 3) - } -} - -func TestMapSelect(t *testing.T) { - m := New() - m.Put("c", 3) - m.Put("b", 1) - m.Put("a", 2) - selectedMap := m.Select(func(key interface{}, value interface{}) bool { - return key.(string) >= "a" && key.(string) <= "b" - }) - if actualValue, _ := selectedMap.Get("b"); actualValue != 1 { - t.Errorf("Got %v expected %v", actualValue, "value: a") - } - if actualValue, _ := selectedMap.Get("a"); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, "value: b") - } - if selectedMap.Size() != 2 { - t.Errorf("Got %v expected %v", selectedMap.Size(), 2) - } -} - -func TestMapAny(t *testing.T) { - m := New() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - any := m.Any(func(key interface{}, value interface{}) bool { - return value.(int) == 3 - }) - if any != true { - t.Errorf("Got %v expected %v", any, true) - } - any = m.Any(func(key interface{}, value interface{}) bool { - return value.(int) == 4 - }) - if any != false { - t.Errorf("Got %v expected %v", any, false) - } -} - -func TestMapAll(t *testing.T) { - m := New() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - all := m.All(func(key interface{}, value interface{}) bool { - return key.(string) >= "a" && key.(string) <= "c" - }) - if all != true { - t.Errorf("Got %v expected %v", all, true) - } - all = m.All(func(key interface{}, value interface{}) bool { - return key.(string) >= "a" && key.(string) <= "b" - }) - if all != false { - t.Errorf("Got %v expected %v", all, false) - } -} - -func TestMapFind(t *testing.T) { - m := New() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - foundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool { - return key.(string) == "c" - }) - if foundKey != "c" || foundValue != 3 { - t.Errorf("Got %v -> %v expected %v -> %v", foundKey, foundValue, "c", 3) - } - foundKey, foundValue = m.Find(func(key interface{}, value interface{}) bool { - return key.(string) == "x" - }) - if foundKey != nil || foundValue != nil { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundKey, nil, nil) - } -} - -func TestMapChaining(t *testing.T) { - m := New() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - chainedMap := m.Select(func(key interface{}, value interface{}) bool { - return value.(int) > 1 - }).Map(func(key interface{}, value interface{}) (interface{}, interface{}) { - return key.(string) + key.(string), value.(int) * value.(int) - }) - if actualValue := chainedMap.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue, found := chainedMap.Get("aa"); actualValue != nil || found { - t.Errorf("Got %v expected %v", actualValue, nil) - } - if actualValue, found := chainedMap.Get("bb"); actualValue != 4 || !found { - t.Errorf("Got %v expected %v", actualValue, 4) - } - if actualValue, found := chainedMap.Get("cc"); actualValue != 9 || !found { - t.Errorf("Got %v expected %v", actualValue, 9) - } -} - -func TestMapIteratorNextOnEmpty(t *testing.T) { - m := New() - it := m.Iterator() - it = m.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty map") - } -} - -func TestMapIteratorPrevOnEmpty(t *testing.T) { - m := New() - it := m.Iterator() - it = m.Iterator() - for it.Prev() { - t.Errorf("Shouldn't iterate on empty map") - } -} - -func TestMapIteratorNext(t *testing.T) { - m := New() - m.Put("c", 1) - m.Put("a", 2) - m.Put("b", 3) - - it := m.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - value := it.Value() - switch key { - case "c": - if actualValue, expectedValue := value, 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "a": - if actualValue, expectedValue := value, 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "b": - if actualValue, expectedValue := value, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestMapIteratorPrev(t *testing.T) { - m := New() - m.Put("c", 1) - m.Put("a", 2) - m.Put("b", 3) - - it := m.Iterator() - for it.Next() { - } - countDown := m.Size() - for it.Prev() { - key := it.Key() - value := it.Value() - switch key { - case "c": - if actualValue, expectedValue := value, 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "a": - if actualValue, expectedValue := value, 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "b": - if actualValue, expectedValue := value, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := value, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestMapIteratorBegin(t *testing.T) { - m := New() - it := m.Iterator() - it.Begin() - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - for it.Next() { - } - it.Begin() - it.Next() - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestMapTreeIteratorEnd(t *testing.T) { - m := New() - it := m.Iterator() - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - it.End() - it.Prev() - if key, value := it.Key(), it.Value(); key != 2 || value != "b" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 2, "b") - } -} - -func TestMapIteratorFirst(t *testing.T) { - m := New() - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - it := m.Iterator() - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestMapIteratorLast(t *testing.T) { - m := New() - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - it := m.Iterator() - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 2 || value != "b" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 2, "b") - } -} - -func TestMapSerialization(t *testing.T) { - for i := 0; i < 10; i++ { - original := New() - original.Put("d", "4") - original.Put("e", "5") - original.Put("c", "3") - original.Put("b", "2") - original.Put("a", "1") - - assertSerialization(original, "A", t) - - serialized, err := original.ToJSON() - if err != nil { - t.Errorf("Got error %v", err) - } - assertSerialization(original, "B", t) - - deserialized := New() - err = deserialized.FromJSON(serialized) - if err != nil { - t.Errorf("Got error %v", err) - } - assertSerialization(deserialized, "C", t) - } -} - -//noinspection GoBoolExpressions -func assertSerialization(m *Map, txt string, t *testing.T) { - if actualValue := m.Keys(); false || - actualValue[0].(string) != "d" || - actualValue[1].(string) != "e" || - actualValue[2].(string) != "c" || - actualValue[3].(string) != "b" || - actualValue[4].(string) != "a" { - t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[d,e,c,b,a]") - } - if actualValue := m.Values(); false || - actualValue[0].(string) != "4" || - actualValue[1].(string) != "5" || - actualValue[2].(string) != "3" || - actualValue[3].(string) != "2" || - actualValue[4].(string) != "1" { - t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[4,5,3,2,1]") - } - if actualValue, expectedValue := m.Size(), 5; actualValue != expectedValue { - t.Errorf("[%s] Got %v expected %v", txt, actualValue, expectedValue) - } -} - -func benchmarkGet(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Get(n) - } - } -} - -func benchmarkPut(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - } -} - -func benchmarkRemove(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Remove(n) - } - } -} - -func BenchmarkTreeMapGet100(b *testing.B) { - b.StopTimer() - size := 100 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeMapGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeMapGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeMapGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeMapPut100(b *testing.B) { - b.StopTimer() - size := 100 - m := New() - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeMapPut1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeMapPut10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeMapPut100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeMapRemove100(b *testing.B) { - b.StopTimer() - size := 100 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkTreeMapRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkTreeMapRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkTreeMapRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := New() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} diff --git a/vendor/github.com/emirpasic/gods/maps/linkedhashmap/serialization.go b/vendor/github.com/emirpasic/gods/maps/linkedhashmap/serialization.go deleted file mode 100644 index 4f723cf67..000000000 --- a/vendor/github.com/emirpasic/gods/maps/linkedhashmap/serialization.go +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedhashmap - -import ( - "bytes" - "encoding/json" - "github.com/emirpasic/gods/containers" - "github.com/emirpasic/gods/utils" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Map)(nil) - var _ containers.JSONDeserializer = (*Map)(nil) -} - -// ToJSON outputs the JSON representation of map. -func (m *Map) ToJSON() ([]byte, error) { - var b []byte - buf := bytes.NewBuffer(b) - - buf.WriteRune('{') - - it := m.Iterator() - lastIndex := m.Size() - 1 - index := 0 - - for it.Next() { - km, err := json.Marshal(it.Key()) - if err != nil { - return nil, err - } - buf.Write(km) - - buf.WriteRune(':') - - vm, err := json.Marshal(it.Value()) - if err != nil { - return nil, err - } - buf.Write(vm) - - if index != lastIndex { - buf.WriteRune(',') - } - - index++ - } - - buf.WriteRune('}') - - return buf.Bytes(), nil -} - -// FromJSON populates map from the input JSON representation. -//func (m *Map) FromJSON(data []byte) error { -// elements := make(map[string]interface{}) -// err := json.Unmarshal(data, &elements) -// if err == nil { -// m.Clear() -// for key, value := range elements { -// m.Put(key, value) -// } -// } -// return err -//} - -// FromJSON populates map from the input JSON representation. -func (m *Map) FromJSON(data []byte) error { - elements := make(map[string]interface{}) - err := json.Unmarshal(data, &elements) - if err != nil { - return err - } - - index := make(map[string]int) - var keys []interface{} - for key := range elements { - keys = append(keys, key) - esc, _ := json.Marshal(key) - index[key] = bytes.Index(data, esc) - } - - byIndex := func(a, b interface{}) int { - key1 := a.(string) - key2 := b.(string) - index1 := index[key1] - index2 := index[key2] - return index1 - index2 - } - - utils.Sort(keys, byIndex) - - m.Clear() - - for _, key := range keys { - m.Put(key, elements[key.(string)]) - } - - return nil -} diff --git a/vendor/github.com/emirpasic/gods/maps/maps.go b/vendor/github.com/emirpasic/gods/maps/maps.go deleted file mode 100644 index 93c64c925..000000000 --- a/vendor/github.com/emirpasic/gods/maps/maps.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package maps provides an abstract Map interface. -// -// In computer science, an associative array, map, symbol table, or dictionary is an abstract data type composed of a collection of (key, value) pairs, such that each possible key appears just once in the collection. -// -// Operations associated with this data type allow: -// - the addition of a pair to the collection -// - the removal of a pair from the collection -// - the modification of an existing pair -// - the lookup of a value associated with a particular key -// -// Reference: https://en.wikipedia.org/wiki/Associative_array -package maps - -import "github.com/emirpasic/gods/containers" - -// Map interface that all maps implement -type Map interface { - Put(key interface{}, value interface{}) - Get(key interface{}) (value interface{}, found bool) - Remove(key interface{}) - Keys() []interface{} - - containers.Container - // Empty() bool - // Size() int - // Clear() - // Values() []interface{} -} - -// BidiMap interface that all bidirectional maps implement (extends the Map interface) -type BidiMap interface { - GetKey(value interface{}) (key interface{}, found bool) - - Map -} diff --git a/vendor/github.com/emirpasic/gods/maps/treebidimap/enumerable.go b/vendor/github.com/emirpasic/gods/maps/treebidimap/enumerable.go deleted file mode 100644 index d5d829abe..000000000 --- a/vendor/github.com/emirpasic/gods/maps/treebidimap/enumerable.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treebidimap - -import "github.com/emirpasic/gods/containers" - -func assertEnumerableImplementation() { - var _ containers.EnumerableWithKey = (*Map)(nil) -} - -// Each calls the given function once for each element, passing that element's key and value. -func (m *Map) Each(f func(key interface{}, value interface{})) { - iterator := m.Iterator() - for iterator.Next() { - f(iterator.Key(), iterator.Value()) - } -} - -// Map invokes the given function once for each element and returns a container -// containing the values returned by the given function as key/value pairs. -func (m *Map) Map(f func(key1 interface{}, value1 interface{}) (interface{}, interface{})) *Map { - newMap := NewWith(m.keyComparator, m.valueComparator) - iterator := m.Iterator() - for iterator.Next() { - key2, value2 := f(iterator.Key(), iterator.Value()) - newMap.Put(key2, value2) - } - return newMap -} - -// Select returns a new container containing all elements for which the given function returns a true value. -func (m *Map) Select(f func(key interface{}, value interface{}) bool) *Map { - newMap := NewWith(m.keyComparator, m.valueComparator) - iterator := m.Iterator() - for iterator.Next() { - if f(iterator.Key(), iterator.Value()) { - newMap.Put(iterator.Key(), iterator.Value()) - } - } - return newMap -} - -// Any passes each element of the container to the given function and -// returns true if the function ever returns true for any element. -func (m *Map) Any(f func(key interface{}, value interface{}) bool) bool { - iterator := m.Iterator() - for iterator.Next() { - if f(iterator.Key(), iterator.Value()) { - return true - } - } - return false -} - -// All passes each element of the container to the given function and -// returns true if the function returns true for all elements. -func (m *Map) All(f func(key interface{}, value interface{}) bool) bool { - iterator := m.Iterator() - for iterator.Next() { - if !f(iterator.Key(), iterator.Value()) { - return false - } - } - return true -} - -// Find passes each element of the container to the given function and returns -// the first (key,value) for which the function is true or nil,nil otherwise if no element -// matches the criteria. -func (m *Map) Find(f func(key interface{}, value interface{}) bool) (interface{}, interface{}) { - iterator := m.Iterator() - for iterator.Next() { - if f(iterator.Key(), iterator.Value()) { - return iterator.Key(), iterator.Value() - } - } - return nil, nil -} diff --git a/vendor/github.com/emirpasic/gods/maps/treebidimap/iterator.go b/vendor/github.com/emirpasic/gods/maps/treebidimap/iterator.go deleted file mode 100644 index af9e27ae8..000000000 --- a/vendor/github.com/emirpasic/gods/maps/treebidimap/iterator.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treebidimap - -import ( - "github.com/emirpasic/gods/containers" - rbt "github.com/emirpasic/gods/trees/redblacktree" -) - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithKey = (*Iterator)(nil) -} - -// Iterator holding the iterator's state -type Iterator struct { - iterator rbt.Iterator -} - -// Iterator returns a stateful iterator whose elements are key/value pairs. -func (m *Map) Iterator() Iterator { - return Iterator{iterator: m.forwardMap.Iterator()} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's key and value can be retrieved by Key() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - return iterator.iterator.Next() -} - -// Prev moves the iterator to the previous element and returns true if there was a previous element in the container. -// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - return iterator.iterator.Prev() -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - return iterator.iterator.Value().(*data).value -} - -// Key returns the current element's key. -// Does not modify the state of the iterator. -func (iterator *Iterator) Key() interface{} { - return iterator.iterator.Key() -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.iterator.Begin() -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.iterator.End() -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator -func (iterator *Iterator) First() bool { - return iterator.iterator.First() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - return iterator.iterator.Last() -} diff --git a/vendor/github.com/emirpasic/gods/maps/treebidimap/serialization.go b/vendor/github.com/emirpasic/gods/maps/treebidimap/serialization.go deleted file mode 100644 index 17204f998..000000000 --- a/vendor/github.com/emirpasic/gods/maps/treebidimap/serialization.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treebidimap - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" - "github.com/emirpasic/gods/utils" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Map)(nil) - var _ containers.JSONDeserializer = (*Map)(nil) -} - -// ToJSON outputs the JSON representation of the map. -func (m *Map) ToJSON() ([]byte, error) { - elements := make(map[string]interface{}) - it := m.Iterator() - for it.Next() { - elements[utils.ToString(it.Key())] = it.Value() - } - return json.Marshal(&elements) -} - -// FromJSON populates the map from the input JSON representation. -func (m *Map) FromJSON(data []byte) error { - elements := make(map[string]interface{}) - err := json.Unmarshal(data, &elements) - if err == nil { - m.Clear() - for key, value := range elements { - m.Put(key, value) - } - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/maps/treebidimap/treebidimap.go b/vendor/github.com/emirpasic/gods/maps/treebidimap/treebidimap.go deleted file mode 100644 index 87eff9f7b..000000000 --- a/vendor/github.com/emirpasic/gods/maps/treebidimap/treebidimap.go +++ /dev/null @@ -1,138 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package treebidimap implements a bidirectional map backed by two red-black tree. -// -// This structure guarantees that the map will be in both ascending key and value order. -// -// Other than key and value ordering, the goal with this structure is to avoid duplication of elements, which can be significant if contained elements are large. -// -// A bidirectional map, or hash bag, is an associative data structure in which the (key,value) pairs form a one-to-one correspondence. -// Thus the binary relation is functional in each direction: value can also act as a key to key. -// A pair (a,b) thus provides a unique coupling between 'a' and 'b' so that 'b' can be found when 'a' is used as a key and 'a' can be found when 'b' is used as a key. -// -// Structure is not thread safe. -// -// Reference: https://en.wikipedia.org/wiki/Bidirectional_map -package treebidimap - -import ( - "fmt" - "github.com/emirpasic/gods/maps" - "github.com/emirpasic/gods/trees/redblacktree" - "github.com/emirpasic/gods/utils" - "strings" -) - -func assertMapImplementation() { - var _ maps.BidiMap = (*Map)(nil) -} - -// Map holds the elements in two red-black trees. -type Map struct { - forwardMap redblacktree.Tree - inverseMap redblacktree.Tree - keyComparator utils.Comparator - valueComparator utils.Comparator -} - -type data struct { - key interface{} - value interface{} -} - -// NewWith instantiates a bidirectional map. -func NewWith(keyComparator utils.Comparator, valueComparator utils.Comparator) *Map { - return &Map{ - forwardMap: *redblacktree.NewWith(keyComparator), - inverseMap: *redblacktree.NewWith(valueComparator), - keyComparator: keyComparator, - valueComparator: valueComparator, - } -} - -// NewWithIntComparators instantiates a bidirectional map with the IntComparator for key and value, i.e. keys and values are of type int. -func NewWithIntComparators() *Map { - return NewWith(utils.IntComparator, utils.IntComparator) -} - -// NewWithStringComparators instantiates a bidirectional map with the StringComparator for key and value, i.e. keys and values are of type string. -func NewWithStringComparators() *Map { - return NewWith(utils.StringComparator, utils.StringComparator) -} - -// Put inserts element into the map. -func (m *Map) Put(key interface{}, value interface{}) { - if d, ok := m.forwardMap.Get(key); ok { - m.inverseMap.Remove(d.(*data).value) - } - if d, ok := m.inverseMap.Get(value); ok { - m.forwardMap.Remove(d.(*data).key) - } - d := &data{key: key, value: value} - m.forwardMap.Put(key, d) - m.inverseMap.Put(value, d) -} - -// Get searches the element in the map by key and returns its value or nil if key is not found in map. -// Second return parameter is true if key was found, otherwise false. -func (m *Map) Get(key interface{}) (value interface{}, found bool) { - if d, ok := m.forwardMap.Get(key); ok { - return d.(*data).value, true - } - return nil, false -} - -// GetKey searches the element in the map by value and returns its key or nil if value is not found in map. -// Second return parameter is true if value was found, otherwise false. -func (m *Map) GetKey(value interface{}) (key interface{}, found bool) { - if d, ok := m.inverseMap.Get(value); ok { - return d.(*data).key, true - } - return nil, false -} - -// Remove removes the element from the map by key. -func (m *Map) Remove(key interface{}) { - if d, found := m.forwardMap.Get(key); found { - m.forwardMap.Remove(key) - m.inverseMap.Remove(d.(*data).value) - } -} - -// Empty returns true if map does not contain any elements -func (m *Map) Empty() bool { - return m.Size() == 0 -} - -// Size returns number of elements in the map. -func (m *Map) Size() int { - return m.forwardMap.Size() -} - -// Keys returns all keys (ordered). -func (m *Map) Keys() []interface{} { - return m.forwardMap.Keys() -} - -// Values returns all values (ordered). -func (m *Map) Values() []interface{} { - return m.inverseMap.Keys() -} - -// Clear removes all elements from the map. -func (m *Map) Clear() { - m.forwardMap.Clear() - m.inverseMap.Clear() -} - -// String returns a string representation of container -func (m *Map) String() string { - str := "TreeBidiMap\nmap[" - it := m.Iterator() - for it.Next() { - str += fmt.Sprintf("%v:%v ", it.Key(), it.Value()) - } - return strings.TrimRight(str, " ") + "]" -} diff --git a/vendor/github.com/emirpasic/gods/maps/treebidimap/treebidimap_test.go b/vendor/github.com/emirpasic/gods/maps/treebidimap/treebidimap_test.go deleted file mode 100644 index 686b57823..000000000 --- a/vendor/github.com/emirpasic/gods/maps/treebidimap/treebidimap_test.go +++ /dev/null @@ -1,676 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treebidimap - -import ( - "fmt" - "github.com/emirpasic/gods/utils" - "testing" -) - -func TestMapPut(t *testing.T) { - m := NewWith(utils.IntComparator, utils.StringComparator) - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - if actualValue := m.Size(); actualValue != 7 { - t.Errorf("Got %v expected %v", actualValue, 7) - } - if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - // key,expectedValue,expectedFound - tests1 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {8, nil, false}, - } - - for _, test := range tests1 { - // retrievals - actualValue, actualFound := m.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } -} - -func TestMapRemove(t *testing.T) { - m := NewWith(utils.IntComparator, utils.StringComparator) - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - m.Remove(5) - m.Remove(6) - m.Remove(7) - m.Remove(8) - m.Remove(5) - - if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := m.Size(); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, 4) - } - - tests2 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, nil, false}, - {6, nil, false}, - {7, nil, false}, - {8, nil, false}, - } - - for _, test := range tests2 { - actualValue, actualFound := m.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } - - m.Remove(1) - m.Remove(4) - m.Remove(2) - m.Remove(3) - m.Remove(2) - m.Remove(2) - - if actualValue, expectedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := m.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } - if actualValue := m.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } -} - -func TestMapGetKey(t *testing.T) { - m := NewWith(utils.IntComparator, utils.StringComparator) - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - // key,expectedValue,expectedFound - tests1 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {nil, "x", false}, - } - - for _, test := range tests1 { - // retrievals - actualValue, actualFound := m.GetKey(test[1]) - if actualValue != test[0] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[0]) - } - } -} - -func sameElements(a []interface{}, b []interface{}) bool { - if len(a) != len(b) { - return false - } - for _, av := range a { - found := false - for _, bv := range b { - if av == bv { - found = true - break - } - } - if !found { - return false - } - } - return true -} - -func TestMapEach(t *testing.T) { - m := NewWith(utils.StringComparator, utils.IntComparator) - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - count := 0 - m.Each(func(key interface{}, value interface{}) { - count++ - if actualValue, expectedValue := count, value; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - switch value { - case 1: - if actualValue, expectedValue := key, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := key, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 3: - if actualValue, expectedValue := key, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - }) -} - -func TestMapMap(t *testing.T) { - m := NewWith(utils.StringComparator, utils.IntComparator) - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - mappedMap := m.Map(func(key1 interface{}, value1 interface{}) (key2 interface{}, value2 interface{}) { - return key1, value1.(int) * value1.(int) - }) - if actualValue, _ := mappedMap.Get("a"); actualValue != 1 { - t.Errorf("Got %v expected %v", actualValue, "mapped: a") - } - if actualValue, _ := mappedMap.Get("b"); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, "mapped: b") - } - if actualValue, _ := mappedMap.Get("c"); actualValue != 9 { - t.Errorf("Got %v expected %v", actualValue, "mapped: c") - } - if mappedMap.Size() != 3 { - t.Errorf("Got %v expected %v", mappedMap.Size(), 3) - } -} - -func TestMapSelect(t *testing.T) { - m := NewWith(utils.StringComparator, utils.IntComparator) - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - selectedMap := m.Select(func(key interface{}, value interface{}) bool { - return key.(string) >= "a" && key.(string) <= "b" - }) - if actualValue, _ := selectedMap.Get("a"); actualValue != 1 { - t.Errorf("Got %v expected %v", actualValue, "value: a") - } - if actualValue, _ := selectedMap.Get("b"); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, "value: b") - } - if selectedMap.Size() != 2 { - t.Errorf("Got %v expected %v", selectedMap.Size(), 2) - } -} - -func TestMapAny(t *testing.T) { - m := NewWith(utils.StringComparator, utils.IntComparator) - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - any := m.Any(func(key interface{}, value interface{}) bool { - return value.(int) == 3 - }) - if any != true { - t.Errorf("Got %v expected %v", any, true) - } - any = m.Any(func(key interface{}, value interface{}) bool { - return value.(int) == 4 - }) - if any != false { - t.Errorf("Got %v expected %v", any, false) - } -} - -func TestMapAll(t *testing.T) { - m := NewWith(utils.StringComparator, utils.IntComparator) - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - all := m.All(func(key interface{}, value interface{}) bool { - return key.(string) >= "a" && key.(string) <= "c" - }) - if all != true { - t.Errorf("Got %v expected %v", all, true) - } - all = m.All(func(key interface{}, value interface{}) bool { - return key.(string) >= "a" && key.(string) <= "b" - }) - if all != false { - t.Errorf("Got %v expected %v", all, false) - } -} - -func TestMapFind(t *testing.T) { - m := NewWith(utils.StringComparator, utils.IntComparator) - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - foundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool { - return key.(string) == "c" - }) - if foundKey != "c" || foundValue != 3 { - t.Errorf("Got %v -> %v expected %v -> %v", foundKey, foundValue, "c", 3) - } - foundKey, foundValue = m.Find(func(key interface{}, value interface{}) bool { - return key.(string) == "x" - }) - if foundKey != nil || foundValue != nil { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundKey, nil, nil) - } -} - -func TestMapChaining(t *testing.T) { - m := NewWith(utils.StringComparator, utils.IntComparator) - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - chainedMap := m.Select(func(key interface{}, value interface{}) bool { - return value.(int) > 1 - }).Map(func(key interface{}, value interface{}) (interface{}, interface{}) { - return key.(string) + key.(string), value.(int) * value.(int) - }) - if actualValue := chainedMap.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue, found := chainedMap.Get("aa"); actualValue != nil || found { - t.Errorf("Got %v expected %v", actualValue, nil) - } - if actualValue, found := chainedMap.Get("bb"); actualValue != 4 || !found { - t.Errorf("Got %v expected %v", actualValue, 4) - } - if actualValue, found := chainedMap.Get("cc"); actualValue != 9 || !found { - t.Errorf("Got %v expected %v", actualValue, 9) - } -} - -func TestMapIteratorNextOnEmpty(t *testing.T) { - m := NewWithStringComparators() - it := m.Iterator() - it = m.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty map") - } -} - -func TestMapIteratorPrevOnEmpty(t *testing.T) { - m := NewWithStringComparators() - it := m.Iterator() - it = m.Iterator() - for it.Prev() { - t.Errorf("Shouldn't iterate on empty map") - } -} - -func TestMapIteratorNext(t *testing.T) { - m := NewWith(utils.StringComparator, utils.IntComparator) - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - - it := m.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - value := it.Value() - switch key { - case "a": - if actualValue, expectedValue := value, 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "b": - if actualValue, expectedValue := value, 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "c": - if actualValue, expectedValue := value, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestMapIteratorPrev(t *testing.T) { - m := NewWith(utils.StringComparator, utils.IntComparator) - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - - it := m.Iterator() - for it.Next() { - } - countDown := m.Size() - for it.Prev() { - key := it.Key() - value := it.Value() - switch key { - case "a": - if actualValue, expectedValue := value, 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "b": - if actualValue, expectedValue := value, 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "c": - if actualValue, expectedValue := value, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := value, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestMapIteratorBegin(t *testing.T) { - m := NewWith(utils.IntComparator, utils.StringComparator) - it := m.Iterator() - it.Begin() - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - for it.Next() { - } - it.Begin() - it.Next() - if key, value := it.Key(), it.Value(); key != 1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a") - } -} - -func TestMapTreeIteratorEnd(t *testing.T) { - m := NewWith(utils.IntComparator, utils.StringComparator) - it := m.Iterator() - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - it.End() - it.Prev() - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestMapIteratorFirst(t *testing.T) { - m := NewWith(utils.IntComparator, utils.StringComparator) - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - it := m.Iterator() - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a") - } -} - -func TestMapIteratorLast(t *testing.T) { - m := NewWith(utils.IntComparator, utils.StringComparator) - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - it := m.Iterator() - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestMapSerialization(t *testing.T) { - for i := 0; i < 10; i++ { - original := NewWith(utils.StringComparator, utils.StringComparator) - original.Put("d", "4") - original.Put("e", "5") - original.Put("c", "3") - original.Put("b", "2") - original.Put("a", "1") - - assertSerialization(original, "A", t) - - serialized, err := original.ToJSON() - if err != nil { - t.Errorf("Got error %v", err) - } - assertSerialization(original, "B", t) - - deserialized := NewWith(utils.StringComparator, utils.StringComparator) - err = deserialized.FromJSON(serialized) - if err != nil { - t.Errorf("Got error %v", err) - } - assertSerialization(deserialized, "C", t) - } -} - -//noinspection GoBoolExpressions -func assertSerialization(m *Map, txt string, t *testing.T) { - if actualValue := m.Keys(); false || - actualValue[0].(string) != "a" || - actualValue[1].(string) != "b" || - actualValue[2].(string) != "c" || - actualValue[3].(string) != "d" || - actualValue[4].(string) != "e" { - t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[a,b,c,d,e]") - } - if actualValue := m.Values(); false || - actualValue[0].(string) != "1" || - actualValue[1].(string) != "2" || - actualValue[2].(string) != "3" || - actualValue[3].(string) != "4" || - actualValue[4].(string) != "5" { - t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[1,2,3,4,5]") - } - if actualValue, expectedValue := m.Size(), 5; actualValue != expectedValue { - t.Errorf("[%s] Got %v expected %v", txt, actualValue, expectedValue) - } -} - -func benchmarkGet(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Get(n) - } - } -} - -func benchmarkPut(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Put(n, n) - } - } -} - -func benchmarkRemove(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Remove(n) - } - } -} - -func BenchmarkTreeBidiMapGet100(b *testing.B) { - b.StopTimer() - size := 100 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeBidiMapGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeBidiMapGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeBidiMapGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeBidiMapPut100(b *testing.B) { - b.StopTimer() - size := 100 - m := NewWithIntComparators() - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeBidiMapPut1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeBidiMapPut10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeBidiMapPut100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeBidiMapRemove100(b *testing.B) { - b.StopTimer() - size := 100 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkTreeBidiMapRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkTreeBidiMapRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkTreeBidiMapRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := NewWithIntComparators() - for n := 0; n < size; n++ { - m.Put(n, n) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} diff --git a/vendor/github.com/emirpasic/gods/maps/treemap/enumerable.go b/vendor/github.com/emirpasic/gods/maps/treemap/enumerable.go deleted file mode 100644 index 8cea6d00b..000000000 --- a/vendor/github.com/emirpasic/gods/maps/treemap/enumerable.go +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treemap - -import ( - "github.com/emirpasic/gods/containers" - rbt "github.com/emirpasic/gods/trees/redblacktree" -) - -func assertEnumerableImplementation() { - var _ containers.EnumerableWithKey = (*Map)(nil) -} - -// Each calls the given function once for each element, passing that element's key and value. -func (m *Map) Each(f func(key interface{}, value interface{})) { - iterator := m.Iterator() - for iterator.Next() { - f(iterator.Key(), iterator.Value()) - } -} - -// Map invokes the given function once for each element and returns a container -// containing the values returned by the given function as key/value pairs. -func (m *Map) Map(f func(key1 interface{}, value1 interface{}) (interface{}, interface{})) *Map { - newMap := &Map{tree: rbt.NewWith(m.tree.Comparator)} - iterator := m.Iterator() - for iterator.Next() { - key2, value2 := f(iterator.Key(), iterator.Value()) - newMap.Put(key2, value2) - } - return newMap -} - -// Select returns a new container containing all elements for which the given function returns a true value. -func (m *Map) Select(f func(key interface{}, value interface{}) bool) *Map { - newMap := &Map{tree: rbt.NewWith(m.tree.Comparator)} - iterator := m.Iterator() - for iterator.Next() { - if f(iterator.Key(), iterator.Value()) { - newMap.Put(iterator.Key(), iterator.Value()) - } - } - return newMap -} - -// Any passes each element of the container to the given function and -// returns true if the function ever returns true for any element. -func (m *Map) Any(f func(key interface{}, value interface{}) bool) bool { - iterator := m.Iterator() - for iterator.Next() { - if f(iterator.Key(), iterator.Value()) { - return true - } - } - return false -} - -// All passes each element of the container to the given function and -// returns true if the function returns true for all elements. -func (m *Map) All(f func(key interface{}, value interface{}) bool) bool { - iterator := m.Iterator() - for iterator.Next() { - if !f(iterator.Key(), iterator.Value()) { - return false - } - } - return true -} - -// Find passes each element of the container to the given function and returns -// the first (key,value) for which the function is true or nil,nil otherwise if no element -// matches the criteria. -func (m *Map) Find(f func(key interface{}, value interface{}) bool) (interface{}, interface{}) { - iterator := m.Iterator() - for iterator.Next() { - if f(iterator.Key(), iterator.Value()) { - return iterator.Key(), iterator.Value() - } - } - return nil, nil -} diff --git a/vendor/github.com/emirpasic/gods/maps/treemap/iterator.go b/vendor/github.com/emirpasic/gods/maps/treemap/iterator.go deleted file mode 100644 index 02b5c753e..000000000 --- a/vendor/github.com/emirpasic/gods/maps/treemap/iterator.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treemap - -import ( - "github.com/emirpasic/gods/containers" - rbt "github.com/emirpasic/gods/trees/redblacktree" -) - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithKey = (*Iterator)(nil) -} - -// Iterator holding the iterator's state -type Iterator struct { - iterator rbt.Iterator -} - -// Iterator returns a stateful iterator whose elements are key/value pairs. -func (m *Map) Iterator() Iterator { - return Iterator{iterator: m.tree.Iterator()} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's key and value can be retrieved by Key() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - return iterator.iterator.Next() -} - -// Prev moves the iterator to the previous element and returns true if there was a previous element in the container. -// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - return iterator.iterator.Prev() -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - return iterator.iterator.Value() -} - -// Key returns the current element's key. -// Does not modify the state of the iterator. -func (iterator *Iterator) Key() interface{} { - return iterator.iterator.Key() -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.iterator.Begin() -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.iterator.End() -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator -func (iterator *Iterator) First() bool { - return iterator.iterator.First() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - return iterator.iterator.Last() -} diff --git a/vendor/github.com/emirpasic/gods/maps/treemap/serialization.go b/vendor/github.com/emirpasic/gods/maps/treemap/serialization.go deleted file mode 100644 index d856300d3..000000000 --- a/vendor/github.com/emirpasic/gods/maps/treemap/serialization.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treemap - -import "github.com/emirpasic/gods/containers" - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Map)(nil) - var _ containers.JSONDeserializer = (*Map)(nil) -} - -// ToJSON outputs the JSON representation of the map. -func (m *Map) ToJSON() ([]byte, error) { - return m.tree.ToJSON() -} - -// FromJSON populates the map from the input JSON representation. -func (m *Map) FromJSON(data []byte) error { - return m.tree.FromJSON(data) -} diff --git a/vendor/github.com/emirpasic/gods/maps/treemap/treemap.go b/vendor/github.com/emirpasic/gods/maps/treemap/treemap.go deleted file mode 100644 index a8e1dc5c5..000000000 --- a/vendor/github.com/emirpasic/gods/maps/treemap/treemap.go +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package treemap implements a map backed by red-black tree. -// -// Elements are ordered by key in the map. -// -// Structure is not thread safe. -// -// Reference: http://en.wikipedia.org/wiki/Associative_array -package treemap - -import ( - "fmt" - "github.com/emirpasic/gods/maps" - rbt "github.com/emirpasic/gods/trees/redblacktree" - "github.com/emirpasic/gods/utils" - "strings" -) - -func assertMapImplementation() { - var _ maps.Map = (*Map)(nil) -} - -// Map holds the elements in a red-black tree -type Map struct { - tree *rbt.Tree -} - -// NewWith instantiates a tree map with the custom comparator. -func NewWith(comparator utils.Comparator) *Map { - return &Map{tree: rbt.NewWith(comparator)} -} - -// NewWithIntComparator instantiates a tree map with the IntComparator, i.e. keys are of type int. -func NewWithIntComparator() *Map { - return &Map{tree: rbt.NewWithIntComparator()} -} - -// NewWithStringComparator instantiates a tree map with the StringComparator, i.e. keys are of type string. -func NewWithStringComparator() *Map { - return &Map{tree: rbt.NewWithStringComparator()} -} - -// Put inserts key-value pair into the map. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Put(key interface{}, value interface{}) { - m.tree.Put(key, value) -} - -// Get searches the element in the map by key and returns its value or nil if key is not found in tree. -// Second return parameter is true if key was found, otherwise false. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Get(key interface{}) (value interface{}, found bool) { - return m.tree.Get(key) -} - -// Remove removes the element from the map by key. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Remove(key interface{}) { - m.tree.Remove(key) -} - -// Empty returns true if map does not contain any elements -func (m *Map) Empty() bool { - return m.tree.Empty() -} - -// Size returns number of elements in the map. -func (m *Map) Size() int { - return m.tree.Size() -} - -// Keys returns all keys in-order -func (m *Map) Keys() []interface{} { - return m.tree.Keys() -} - -// Values returns all values in-order based on the key. -func (m *Map) Values() []interface{} { - return m.tree.Values() -} - -// Clear removes all elements from the map. -func (m *Map) Clear() { - m.tree.Clear() -} - -// Min returns the minimum key and its value from the tree map. -// Returns nil, nil if map is empty. -func (m *Map) Min() (key interface{}, value interface{}) { - if node := m.tree.Left(); node != nil { - return node.Key, node.Value - } - return nil, nil -} - -// Max returns the maximum key and its value from the tree map. -// Returns nil, nil if map is empty. -func (m *Map) Max() (key interface{}, value interface{}) { - if node := m.tree.Right(); node != nil { - return node.Key, node.Value - } - return nil, nil -} - -// Floor finds the floor key-value pair for the input key. -// In case that no floor is found, then both returned values will be nil. -// It's generally enough to check the first value (key) for nil, which determines if floor was found. -// -// Floor key is defined as the largest key that is smaller than or equal to the given key. -// A floor key may not be found, either because the map is empty, or because -// all keys in the map are larger than the given key. -// -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Floor(key interface{}) (foundKey interface{}, foundValue interface{}) { - node, found := m.tree.Floor(key) - if found { - return node.Key, node.Value - } - return nil, nil -} - -// Ceiling finds the ceiling key-value pair for the input key. -// In case that no ceiling is found, then both returned values will be nil. -// It's generally enough to check the first value (key) for nil, which determines if ceiling was found. -// -// Ceiling key is defined as the smallest key that is larger than or equal to the given key. -// A ceiling key may not be found, either because the map is empty, or because -// all keys in the map are smaller than the given key. -// -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (m *Map) Ceiling(key interface{}) (foundKey interface{}, foundValue interface{}) { - node, found := m.tree.Ceiling(key) - if found { - return node.Key, node.Value - } - return nil, nil -} - -// String returns a string representation of container -func (m *Map) String() string { - str := "TreeMap\nmap[" - it := m.Iterator() - for it.Next() { - str += fmt.Sprintf("%v:%v ", it.Key(), it.Value()) - } - return strings.TrimRight(str, " ") + "]" - -} diff --git a/vendor/github.com/emirpasic/gods/maps/treemap/treemap_test.go b/vendor/github.com/emirpasic/gods/maps/treemap/treemap_test.go deleted file mode 100644 index 0ee162ecd..000000000 --- a/vendor/github.com/emirpasic/gods/maps/treemap/treemap_test.go +++ /dev/null @@ -1,699 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treemap - -import ( - "fmt" - "testing" -) - -func TestMapPut(t *testing.T) { - m := NewWithIntComparator() - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - if actualValue := m.Size(); actualValue != 7 { - t.Errorf("Got %v expected %v", actualValue, 7) - } - if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4, 5, 6, 7}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d", "e", "f", "g"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - // key,expectedValue,expectedFound - tests1 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {8, nil, false}, - } - - for _, test := range tests1 { - // retrievals - actualValue, actualFound := m.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } -} - -func TestMapRemove(t *testing.T) { - m := NewWithIntComparator() - m.Put(5, "e") - m.Put(6, "f") - m.Put(7, "g") - m.Put(3, "c") - m.Put(4, "d") - m.Put(1, "x") - m.Put(2, "b") - m.Put(1, "a") //overwrite - - m.Remove(5) - m.Remove(6) - m.Remove(7) - m.Remove(8) - m.Remove(5) - - if actualValue, expectedValue := m.Keys(), []interface{}{1, 2, 3, 4}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - if actualValue, expectedValue := m.Values(), []interface{}{"a", "b", "c", "d"}; !sameElements(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := m.Size(); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, 4) - } - - tests2 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, nil, false}, - {6, nil, false}, - {7, nil, false}, - {8, nil, false}, - } - - for _, test := range tests2 { - actualValue, actualFound := m.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } - - m.Remove(1) - m.Remove(4) - m.Remove(2) - m.Remove(3) - m.Remove(2) - m.Remove(2) - - if actualValue, expectedValue := fmt.Sprintf("%s", m.Keys()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", m.Values()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := m.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } - if actualValue := m.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } -} - -func TestMapFloor(t *testing.T) { - m := NewWithIntComparator() - m.Put(7, "g") - m.Put(3, "c") - m.Put(1, "a") - - // key,expectedKey,expectedValue,expectedFound - tests1 := [][]interface{}{ - {-1, nil, nil, false}, - {0, nil, nil, false}, - {1, 1, "a", true}, - {2, 1, "a", true}, - {3, 3, "c", true}, - {4, 3, "c", true}, - {7, 7, "g", true}, - {8, 7, "g", true}, - } - - for _, test := range tests1 { - // retrievals - actualKey, actualValue := m.Floor(test[0]) - actualFound := actualKey != nil && actualValue != nil - if actualKey != test[1] || actualValue != test[2] || actualFound != test[3] { - t.Errorf("Got %v, %v, %v, expected %v, %v, %v", actualKey, actualValue, actualFound, test[1], test[2], test[3]) - } - } -} - -func TestMapCeiling(t *testing.T) { - m := NewWithIntComparator() - m.Put(7, "g") - m.Put(3, "c") - m.Put(1, "a") - - // key,expectedKey,expectedValue,expectedFound - tests1 := [][]interface{}{ - {-1, 1, "a", true}, - {0, 1, "a", true}, - {1, 1, "a", true}, - {2, 3, "c", true}, - {3, 3, "c", true}, - {4, 7, "g", true}, - {7, 7, "g", true}, - {8, nil, nil, false}, - } - - for _, test := range tests1 { - // retrievals - actualKey, actualValue := m.Ceiling(test[0]) - actualFound := actualKey != nil && actualValue != nil - if actualKey != test[1] || actualValue != test[2] || actualFound != test[3] { - t.Errorf("Got %v, %v, %v, expected %v, %v, %v", actualKey, actualValue, actualFound, test[1], test[2], test[3]) - } - } -} - -func sameElements(a []interface{}, b []interface{}) bool { - if len(a) != len(b) { - return false - } - for _, av := range a { - found := false - for _, bv := range b { - if av == bv { - found = true - break - } - } - if !found { - return false - } - } - return true -} - -func TestMapEach(t *testing.T) { - m := NewWithStringComparator() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - count := 0 - m.Each(func(key interface{}, value interface{}) { - count++ - if actualValue, expectedValue := count, value; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - switch value { - case 1: - if actualValue, expectedValue := key, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := key, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 3: - if actualValue, expectedValue := key, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - }) -} - -func TestMapMap(t *testing.T) { - m := NewWithStringComparator() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - mappedMap := m.Map(func(key1 interface{}, value1 interface{}) (key2 interface{}, value2 interface{}) { - return key1, value1.(int) * value1.(int) - }) - if actualValue, _ := mappedMap.Get("a"); actualValue != 1 { - t.Errorf("Got %v expected %v", actualValue, "mapped: a") - } - if actualValue, _ := mappedMap.Get("b"); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, "mapped: b") - } - if actualValue, _ := mappedMap.Get("c"); actualValue != 9 { - t.Errorf("Got %v expected %v", actualValue, "mapped: c") - } - if mappedMap.Size() != 3 { - t.Errorf("Got %v expected %v", mappedMap.Size(), 3) - } -} - -func TestMapSelect(t *testing.T) { - m := NewWithStringComparator() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - selectedMap := m.Select(func(key interface{}, value interface{}) bool { - return key.(string) >= "a" && key.(string) <= "b" - }) - if actualValue, _ := selectedMap.Get("a"); actualValue != 1 { - t.Errorf("Got %v expected %v", actualValue, "value: a") - } - if actualValue, _ := selectedMap.Get("b"); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, "value: b") - } - if selectedMap.Size() != 2 { - t.Errorf("Got %v expected %v", selectedMap.Size(), 2) - } -} - -func TestMapAny(t *testing.T) { - m := NewWithStringComparator() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - any := m.Any(func(key interface{}, value interface{}) bool { - return value.(int) == 3 - }) - if any != true { - t.Errorf("Got %v expected %v", any, true) - } - any = m.Any(func(key interface{}, value interface{}) bool { - return value.(int) == 4 - }) - if any != false { - t.Errorf("Got %v expected %v", any, false) - } -} - -func TestMapAll(t *testing.T) { - m := NewWithStringComparator() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - all := m.All(func(key interface{}, value interface{}) bool { - return key.(string) >= "a" && key.(string) <= "c" - }) - if all != true { - t.Errorf("Got %v expected %v", all, true) - } - all = m.All(func(key interface{}, value interface{}) bool { - return key.(string) >= "a" && key.(string) <= "b" - }) - if all != false { - t.Errorf("Got %v expected %v", all, false) - } -} - -func TestMapFind(t *testing.T) { - m := NewWithStringComparator() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - foundKey, foundValue := m.Find(func(key interface{}, value interface{}) bool { - return key.(string) == "c" - }) - if foundKey != "c" || foundValue != 3 { - t.Errorf("Got %v -> %v expected %v -> %v", foundKey, foundValue, "c", 3) - } - foundKey, foundValue = m.Find(func(key interface{}, value interface{}) bool { - return key.(string) == "x" - }) - if foundKey != nil || foundValue != nil { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundKey, nil, nil) - } -} - -func TestMapChaining(t *testing.T) { - m := NewWithStringComparator() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - chainedMap := m.Select(func(key interface{}, value interface{}) bool { - return value.(int) > 1 - }).Map(func(key interface{}, value interface{}) (interface{}, interface{}) { - return key.(string) + key.(string), value.(int) * value.(int) - }) - if actualValue := chainedMap.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue, found := chainedMap.Get("aa"); actualValue != nil || found { - t.Errorf("Got %v expected %v", actualValue, nil) - } - if actualValue, found := chainedMap.Get("bb"); actualValue != 4 || !found { - t.Errorf("Got %v expected %v", actualValue, 4) - } - if actualValue, found := chainedMap.Get("cc"); actualValue != 9 || !found { - t.Errorf("Got %v expected %v", actualValue, 9) - } -} - -func TestMapIteratorNextOnEmpty(t *testing.T) { - m := NewWithStringComparator() - it := m.Iterator() - it = m.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty map") - } -} - -func TestMapIteratorPrevOnEmpty(t *testing.T) { - m := NewWithStringComparator() - it := m.Iterator() - it = m.Iterator() - for it.Prev() { - t.Errorf("Shouldn't iterate on empty map") - } -} - -func TestMapIteratorNext(t *testing.T) { - m := NewWithStringComparator() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - - it := m.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - value := it.Value() - switch key { - case "a": - if actualValue, expectedValue := value, 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "b": - if actualValue, expectedValue := value, 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "c": - if actualValue, expectedValue := value, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestMapIteratorPrev(t *testing.T) { - m := NewWithStringComparator() - m.Put("c", 3) - m.Put("a", 1) - m.Put("b", 2) - - it := m.Iterator() - for it.Next() { - } - countDown := m.Size() - for it.Prev() { - key := it.Key() - value := it.Value() - switch key { - case "a": - if actualValue, expectedValue := value, 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "b": - if actualValue, expectedValue := value, 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case "c": - if actualValue, expectedValue := value, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := value, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestMapIteratorBegin(t *testing.T) { - m := NewWithIntComparator() - it := m.Iterator() - it.Begin() - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - for it.Next() { - } - it.Begin() - it.Next() - if key, value := it.Key(), it.Value(); key != 1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a") - } -} - -func TestMapTreeIteratorEnd(t *testing.T) { - m := NewWithIntComparator() - it := m.Iterator() - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - it.End() - it.Prev() - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestMapIteratorFirst(t *testing.T) { - m := NewWithIntComparator() - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - it := m.Iterator() - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a") - } -} - -func TestMapIteratorLast(t *testing.T) { - m := NewWithIntComparator() - m.Put(3, "c") - m.Put(1, "a") - m.Put(2, "b") - it := m.Iterator() - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestMapSerialization(t *testing.T) { - for i := 0; i < 10; i++ { - original := NewWithStringComparator() - original.Put("d", "4") - original.Put("e", "5") - original.Put("c", "3") - original.Put("b", "2") - original.Put("a", "1") - - assertSerialization(original, "A", t) - - serialized, err := original.ToJSON() - if err != nil { - t.Errorf("Got error %v", err) - } - assertSerialization(original, "B", t) - - deserialized := NewWithStringComparator() - err = deserialized.FromJSON(serialized) - if err != nil { - t.Errorf("Got error %v", err) - } - assertSerialization(deserialized, "C", t) - } -} - -//noinspection GoBoolExpressions -func assertSerialization(m *Map, txt string, t *testing.T) { - if actualValue := m.Keys(); false || - actualValue[0].(string) != "a" || - actualValue[1].(string) != "b" || - actualValue[2].(string) != "c" || - actualValue[3].(string) != "d" || - actualValue[4].(string) != "e" { - t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[a,b,c,d,e]") - } - if actualValue := m.Values(); false || - actualValue[0].(string) != "1" || - actualValue[1].(string) != "2" || - actualValue[2].(string) != "3" || - actualValue[3].(string) != "4" || - actualValue[4].(string) != "5" { - t.Errorf("[%s] Got %v expected %v", txt, actualValue, "[1,2,3,4,5]") - } - if actualValue, expectedValue := m.Size(), 5; actualValue != expectedValue { - t.Errorf("[%s] Got %v expected %v", txt, actualValue, expectedValue) - } -} - -func benchmarkGet(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Get(n) - } - } -} - -func benchmarkPut(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - } -} - -func benchmarkRemove(b *testing.B, m *Map, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - m.Remove(n) - } - } -} - -func BenchmarkTreeMapGet100(b *testing.B) { - b.StopTimer() - size := 100 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeMapGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeMapGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeMapGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, m, size) -} - -func BenchmarkTreeMapPut100(b *testing.B) { - b.StopTimer() - size := 100 - m := NewWithIntComparator() - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeMapPut1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeMapPut10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeMapPut100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, m, size) -} - -func BenchmarkTreeMapRemove100(b *testing.B) { - b.StopTimer() - size := 100 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkTreeMapRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkTreeMapRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} - -func BenchmarkTreeMapRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - m := NewWithIntComparator() - for n := 0; n < size; n++ { - m.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, m, size) -} diff --git a/vendor/github.com/emirpasic/gods/sets/hashset/hashset.go b/vendor/github.com/emirpasic/gods/sets/hashset/hashset.go deleted file mode 100644 index 815d04901..000000000 --- a/vendor/github.com/emirpasic/gods/sets/hashset/hashset.go +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package hashset implements a set backed by a hash table. -// -// Structure is not thread safe. -// -// References: http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29 -package hashset - -import ( - "fmt" - "github.com/emirpasic/gods/sets" - "strings" -) - -func assertSetImplementation() { - var _ sets.Set = (*Set)(nil) -} - -// Set holds elements in go's native map -type Set struct { - items map[interface{}]struct{} -} - -var itemExists = struct{}{} - -// New instantiates a new empty set and adds the passed values, if any, to the set -func New(values ...interface{}) *Set { - set := &Set{items: make(map[interface{}]struct{})} - if len(values) > 0 { - set.Add(values...) - } - return set -} - -// Add adds the items (one or more) to the set. -func (set *Set) Add(items ...interface{}) { - for _, item := range items { - set.items[item] = itemExists - } -} - -// Remove removes the items (one or more) from the set. -func (set *Set) Remove(items ...interface{}) { - for _, item := range items { - delete(set.items, item) - } -} - -// Contains check if items (one or more) are present in the set. -// All items have to be present in the set for the method to return true. -// Returns true if no arguments are passed at all, i.e. set is always superset of empty set. -func (set *Set) Contains(items ...interface{}) bool { - for _, item := range items { - if _, contains := set.items[item]; !contains { - return false - } - } - return true -} - -// Empty returns true if set does not contain any elements. -func (set *Set) Empty() bool { - return set.Size() == 0 -} - -// Size returns number of elements within the set. -func (set *Set) Size() int { - return len(set.items) -} - -// Clear clears all values in the set. -func (set *Set) Clear() { - set.items = make(map[interface{}]struct{}) -} - -// Values returns all items in the set. -func (set *Set) Values() []interface{} { - values := make([]interface{}, set.Size()) - count := 0 - for item := range set.items { - values[count] = item - count++ - } - return values -} - -// String returns a string representation of container -func (set *Set) String() string { - str := "HashSet\n" - items := []string{} - for k := range set.items { - items = append(items, fmt.Sprintf("%v", k)) - } - str += strings.Join(items, ", ") - return str -} diff --git a/vendor/github.com/emirpasic/gods/sets/hashset/hashset_test.go b/vendor/github.com/emirpasic/gods/sets/hashset/hashset_test.go deleted file mode 100644 index cf63c8999..000000000 --- a/vendor/github.com/emirpasic/gods/sets/hashset/hashset_test.go +++ /dev/null @@ -1,259 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package hashset - -import ( - "testing" -) - -func TestSetNew(t *testing.T) { - set := New(2, 1) - - if actualValue := set.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue := set.Contains(1); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(2); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(3); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, true) - } -} - -func TestSetAdd(t *testing.T) { - set := New() - set.Add() - set.Add(1) - set.Add(2) - set.Add(2, 3) - set.Add() - if actualValue := set.Empty(); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := set.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } -} - -func TestSetContains(t *testing.T) { - set := New() - set.Add(3, 1, 2) - set.Add(2, 3) - set.Add() - if actualValue := set.Contains(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(1); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(1, 2, 3); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(1, 2, 3, 4); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } -} - -func TestSetRemove(t *testing.T) { - set := New() - set.Add(3, 1, 2) - set.Remove() - if actualValue := set.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - set.Remove(1) - if actualValue := set.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - set.Remove(3) - set.Remove(3) - set.Remove() - set.Remove(2) - if actualValue := set.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } -} - -func TestSetSerialization(t *testing.T) { - set := New() - set.Add("a", "b", "c") - - var err error - assert := func() { - if actualValue, expectedValue := set.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := set.Contains("a", "b", "c"); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := set.ToJSON() - assert() - - err = set.FromJSON(json) - assert() -} - -func benchmarkContains(b *testing.B, set *Set, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - set.Contains(n) - } - } -} - -func benchmarkAdd(b *testing.B, set *Set, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - set.Add(n) - } - } -} - -func benchmarkRemove(b *testing.B, set *Set, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - set.Remove(n) - } - } -} - -func BenchmarkHashSetContains100(b *testing.B) { - b.StopTimer() - size := 100 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkHashSetContains1000(b *testing.B) { - b.StopTimer() - size := 1000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkHashSetContains10000(b *testing.B) { - b.StopTimer() - size := 10000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkHashSetContains100000(b *testing.B) { - b.StopTimer() - size := 100000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkHashSetAdd100(b *testing.B) { - b.StopTimer() - size := 100 - set := New() - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkHashSetAdd1000(b *testing.B) { - b.StopTimer() - size := 1000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkHashSetAdd10000(b *testing.B) { - b.StopTimer() - size := 10000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkHashSetAdd100000(b *testing.B) { - b.StopTimer() - size := 100000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkHashSetRemove100(b *testing.B) { - b.StopTimer() - size := 100 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} - -func BenchmarkHashSetRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} - -func BenchmarkHashSetRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} - -func BenchmarkHashSetRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} diff --git a/vendor/github.com/emirpasic/gods/sets/hashset/serialization.go b/vendor/github.com/emirpasic/gods/sets/hashset/serialization.go deleted file mode 100644 index 7b8506df8..000000000 --- a/vendor/github.com/emirpasic/gods/sets/hashset/serialization.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package hashset - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Set)(nil) - var _ containers.JSONDeserializer = (*Set)(nil) -} - -// ToJSON outputs the JSON representation of the set. -func (set *Set) ToJSON() ([]byte, error) { - return json.Marshal(set.Values()) -} - -// FromJSON populates the set from the input JSON representation. -func (set *Set) FromJSON(data []byte) error { - elements := []interface{}{} - err := json.Unmarshal(data, &elements) - if err == nil { - set.Clear() - set.Add(elements...) - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/sets/linkedhashset/enumerable.go b/vendor/github.com/emirpasic/gods/sets/linkedhashset/enumerable.go deleted file mode 100644 index ad6ac967d..000000000 --- a/vendor/github.com/emirpasic/gods/sets/linkedhashset/enumerable.go +++ /dev/null @@ -1,79 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedhashset - -import "github.com/emirpasic/gods/containers" - -func assertEnumerableImplementation() { - var _ containers.EnumerableWithIndex = (*Set)(nil) -} - -// Each calls the given function once for each element, passing that element's index and value. -func (set *Set) Each(f func(index int, value interface{})) { - iterator := set.Iterator() - for iterator.Next() { - f(iterator.Index(), iterator.Value()) - } -} - -// Map invokes the given function once for each element and returns a -// container containing the values returned by the given function. -func (set *Set) Map(f func(index int, value interface{}) interface{}) *Set { - newSet := New() - iterator := set.Iterator() - for iterator.Next() { - newSet.Add(f(iterator.Index(), iterator.Value())) - } - return newSet -} - -// Select returns a new container containing all elements for which the given function returns a true value. -func (set *Set) Select(f func(index int, value interface{}) bool) *Set { - newSet := New() - iterator := set.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - newSet.Add(iterator.Value()) - } - } - return newSet -} - -// Any passes each element of the container to the given function and -// returns true if the function ever returns true for any element. -func (set *Set) Any(f func(index int, value interface{}) bool) bool { - iterator := set.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - return true - } - } - return false -} - -// All passes each element of the container to the given function and -// returns true if the function returns true for all elements. -func (set *Set) All(f func(index int, value interface{}) bool) bool { - iterator := set.Iterator() - for iterator.Next() { - if !f(iterator.Index(), iterator.Value()) { - return false - } - } - return true -} - -// Find passes each element of the container to the given function and returns -// the first (index,value) for which the function is true or -1,nil otherwise -// if no element matches the criteria. -func (set *Set) Find(f func(index int, value interface{}) bool) (int, interface{}) { - iterator := set.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - return iterator.Index(), iterator.Value() - } - } - return -1, nil -} diff --git a/vendor/github.com/emirpasic/gods/sets/linkedhashset/iterator.go b/vendor/github.com/emirpasic/gods/sets/linkedhashset/iterator.go deleted file mode 100644 index 3d190d913..000000000 --- a/vendor/github.com/emirpasic/gods/sets/linkedhashset/iterator.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedhashset - -import ( - "github.com/emirpasic/gods/containers" - "github.com/emirpasic/gods/lists/doublylinkedlist" -) - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil) -} - -// Iterator holding the iterator's state -type Iterator struct { - iterator doublylinkedlist.Iterator -} - -// Iterator returns a stateful iterator whose values can be fetched by an index. -func (set *Set) Iterator() Iterator { - return Iterator{iterator: set.ordering.Iterator()} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - return iterator.iterator.Next() -} - -// Prev moves the iterator to the previous element and returns true if there was a previous element in the container. -// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - return iterator.iterator.Prev() -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - return iterator.iterator.Value() -} - -// Index returns the current element's index. -// Does not modify the state of the iterator. -func (iterator *Iterator) Index() int { - return iterator.iterator.Index() -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.iterator.Begin() -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.iterator.End() -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) First() bool { - return iterator.iterator.First() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - return iterator.iterator.Last() -} diff --git a/vendor/github.com/emirpasic/gods/sets/linkedhashset/linkedhashset.go b/vendor/github.com/emirpasic/gods/sets/linkedhashset/linkedhashset.go deleted file mode 100644 index e589a127c..000000000 --- a/vendor/github.com/emirpasic/gods/sets/linkedhashset/linkedhashset.go +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package linkedhashset is a set that preserves insertion-order. -// -// It is backed by a hash table to store values and doubly-linked list to store ordering. -// -// Note that insertion-order is not affected if an element is re-inserted into the set. -// -// Structure is not thread safe. -// -// References: http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29 -package linkedhashset - -import ( - "fmt" - "github.com/emirpasic/gods/lists/doublylinkedlist" - "github.com/emirpasic/gods/sets" - "strings" -) - -func assertSetImplementation() { - var _ sets.Set = (*Set)(nil) -} - -// Set holds elements in go's native map -type Set struct { - table map[interface{}]struct{} - ordering *doublylinkedlist.List -} - -var itemExists = struct{}{} - -// New instantiates a new empty set and adds the passed values, if any, to the set -func New(values ...interface{}) *Set { - set := &Set{ - table: make(map[interface{}]struct{}), - ordering: doublylinkedlist.New(), - } - if len(values) > 0 { - set.Add(values...) - } - return set -} - -// Add adds the items (one or more) to the set. -// Note that insertion-order is not affected if an element is re-inserted into the set. -func (set *Set) Add(items ...interface{}) { - for _, item := range items { - if _, contains := set.table[item]; !contains { - set.table[item] = itemExists - set.ordering.Append(item) - } - } -} - -// Remove removes the items (one or more) from the set. -// Slow operation, worst-case O(n^2). -func (set *Set) Remove(items ...interface{}) { - for _, item := range items { - if _, contains := set.table[item]; contains { - delete(set.table, item) - index := set.ordering.IndexOf(item) - set.ordering.Remove(index) - } - } -} - -// Contains check if items (one or more) are present in the set. -// All items have to be present in the set for the method to return true. -// Returns true if no arguments are passed at all, i.e. set is always superset of empty set. -func (set *Set) Contains(items ...interface{}) bool { - for _, item := range items { - if _, contains := set.table[item]; !contains { - return false - } - } - return true -} - -// Empty returns true if set does not contain any elements. -func (set *Set) Empty() bool { - return set.Size() == 0 -} - -// Size returns number of elements within the set. -func (set *Set) Size() int { - return set.ordering.Size() -} - -// Clear clears all values in the set. -func (set *Set) Clear() { - set.table = make(map[interface{}]struct{}) - set.ordering.Clear() -} - -// Values returns all items in the set. -func (set *Set) Values() []interface{} { - values := make([]interface{}, set.Size()) - it := set.Iterator() - for it.Next() { - values[it.Index()] = it.Value() - } - return values -} - -// String returns a string representation of container -func (set *Set) String() string { - str := "LinkedHashSet\n" - items := []string{} - it := set.Iterator() - for it.Next() { - items = append(items, fmt.Sprintf("%v", it.Value())) - } - str += strings.Join(items, ", ") - return str -} diff --git a/vendor/github.com/emirpasic/gods/sets/linkedhashset/linkedhashset_test.go b/vendor/github.com/emirpasic/gods/sets/linkedhashset/linkedhashset_test.go deleted file mode 100644 index 10b6da2d9..000000000 --- a/vendor/github.com/emirpasic/gods/sets/linkedhashset/linkedhashset_test.go +++ /dev/null @@ -1,512 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedhashset - -import ( - "fmt" - "testing" -) - -func TestSetNew(t *testing.T) { - set := New(2, 1) - if actualValue := set.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - values := set.Values() - if actualValue := values[0]; actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue := values[1]; actualValue != 1 { - t.Errorf("Got %v expected %v", actualValue, 1) - } -} - -func TestSetAdd(t *testing.T) { - set := New() - set.Add() - set.Add(1) - set.Add(2) - set.Add(2, 3) - set.Add() - if actualValue := set.Empty(); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := set.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } -} - -func TestSetContains(t *testing.T) { - set := New() - set.Add(3, 1, 2) - set.Add(2, 3) - set.Add() - if actualValue := set.Contains(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(1); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(1, 2, 3); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(1, 2, 3, 4); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } -} - -func TestSetRemove(t *testing.T) { - set := New() - set.Add(3, 1, 2) - set.Remove() - if actualValue := set.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - set.Remove(1) - if actualValue := set.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - set.Remove(3) - set.Remove(3) - set.Remove() - set.Remove(2) - if actualValue := set.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } -} - -func TestSetEach(t *testing.T) { - set := New() - set.Add("c", "a", "b") - set.Each(func(index int, value interface{}) { - switch index { - case 0: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - }) -} - -func TestSetMap(t *testing.T) { - set := New() - set.Add("c", "a", "b") - mappedSet := set.Map(func(index int, value interface{}) interface{} { - return "mapped: " + value.(string) - }) - if actualValue, expectedValue := mappedSet.Contains("mapped: c", "mapped: b", "mapped: a"), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := mappedSet.Contains("mapped: c", "mapped: b", "mapped: x"), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if mappedSet.Size() != 3 { - t.Errorf("Got %v expected %v", mappedSet.Size(), 3) - } -} - -func TestSetSelect(t *testing.T) { - set := New() - set.Add("c", "a", "b") - selectedSet := set.Select(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "b" - }) - if actualValue, expectedValue := selectedSet.Contains("a", "b"), true; actualValue != expectedValue { - fmt.Println("A: ", selectedSet.Contains("b")) - t.Errorf("Got %v (%v) expected %v (%v)", actualValue, selectedSet.Values(), expectedValue, "[a b]") - } - if actualValue, expectedValue := selectedSet.Contains("a", "b", "c"), false; actualValue != expectedValue { - t.Errorf("Got %v (%v) expected %v (%v)", actualValue, selectedSet.Values(), expectedValue, "[a b]") - } - if selectedSet.Size() != 2 { - t.Errorf("Got %v expected %v", selectedSet.Size(), 3) - } -} - -func TestSetAny(t *testing.T) { - set := New() - set.Add("c", "a", "b") - any := set.Any(func(index int, value interface{}) bool { - return value.(string) == "c" - }) - if any != true { - t.Errorf("Got %v expected %v", any, true) - } - any = set.Any(func(index int, value interface{}) bool { - return value.(string) == "x" - }) - if any != false { - t.Errorf("Got %v expected %v", any, false) - } -} - -func TestSetAll(t *testing.T) { - set := New() - set.Add("c", "a", "b") - all := set.All(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "c" - }) - if all != true { - t.Errorf("Got %v expected %v", all, true) - } - all = set.All(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "b" - }) - if all != false { - t.Errorf("Got %v expected %v", all, false) - } -} - -func TestSetFind(t *testing.T) { - set := New() - set.Add("c", "a", "b") - foundIndex, foundValue := set.Find(func(index int, value interface{}) bool { - return value.(string) == "c" - }) - if foundValue != "c" || foundIndex != 0 { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 0) - } - foundIndex, foundValue = set.Find(func(index int, value interface{}) bool { - return value.(string) == "x" - }) - if foundValue != nil || foundIndex != -1 { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, nil, nil) - } -} - -func TestSetChaining(t *testing.T) { - set := New() - set.Add("c", "a", "b") -} - -func TestSetIteratorPrevOnEmpty(t *testing.T) { - set := New() - it := set.Iterator() - for it.Prev() { - t.Errorf("Shouldn't iterate on empty set") - } -} - -func TestSetIteratorNext(t *testing.T) { - set := New() - set.Add("c", "a", "b") - it := set.Iterator() - count := 0 - for it.Next() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := index, count-1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestSetIteratorPrev(t *testing.T) { - set := New() - set.Add("c", "a", "b") - it := set.Iterator() - for it.Prev() { - } - count := 0 - for it.Next() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := index, count-1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestSetIteratorBegin(t *testing.T) { - set := New() - it := set.Iterator() - it.Begin() - set.Add("a", "b", "c") - for it.Next() { - } - it.Begin() - it.Next() - if index, value := it.Index(), it.Value(); index != 0 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") - } -} - -func TestSetIteratorEnd(t *testing.T) { - set := New() - it := set.Iterator() - - if index := it.Index(); index != -1 { - t.Errorf("Got %v expected %v", index, -1) - } - - it.End() - if index := it.Index(); index != 0 { - t.Errorf("Got %v expected %v", index, 0) - } - - set.Add("a", "b", "c") - it.End() - if index := it.Index(); index != set.Size() { - t.Errorf("Got %v expected %v", index, set.Size()) - } - - it.Prev() - if index, value := it.Index(), it.Value(); index != set.Size()-1 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, set.Size()-1, "c") - } -} - -func TestSetIteratorFirst(t *testing.T) { - set := New() - set.Add("a", "b", "c") - it := set.Iterator() - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 0 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") - } -} - -func TestSetIteratorLast(t *testing.T) { - set := New() - set.Add("a", "b", "c") - it := set.Iterator() - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 2 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 3, "c") - } -} - -func TestSetSerialization(t *testing.T) { - set := New() - set.Add("a", "b", "c") - - var err error - assert := func() { - if actualValue, expectedValue := set.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := set.Contains("a", "b", "c"); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := set.ToJSON() - assert() - - err = set.FromJSON(json) - assert() -} - -func benchmarkContains(b *testing.B, set *Set, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - set.Contains(n) - } - } -} - -func benchmarkAdd(b *testing.B, set *Set, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - set.Add(n) - } - } -} - -func benchmarkRemove(b *testing.B, set *Set, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - set.Remove(n) - } - } -} - -func BenchmarkHashSetContains100(b *testing.B) { - b.StopTimer() - size := 100 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkHashSetContains1000(b *testing.B) { - b.StopTimer() - size := 1000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkHashSetContains10000(b *testing.B) { - b.StopTimer() - size := 10000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkHashSetContains100000(b *testing.B) { - b.StopTimer() - size := 100000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkHashSetAdd100(b *testing.B) { - b.StopTimer() - size := 100 - set := New() - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkHashSetAdd1000(b *testing.B) { - b.StopTimer() - size := 1000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkHashSetAdd10000(b *testing.B) { - b.StopTimer() - size := 10000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkHashSetAdd100000(b *testing.B) { - b.StopTimer() - size := 100000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkHashSetRemove100(b *testing.B) { - b.StopTimer() - size := 100 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} - -func BenchmarkHashSetRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} - -func BenchmarkHashSetRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} - -func BenchmarkHashSetRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - set := New() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} diff --git a/vendor/github.com/emirpasic/gods/sets/linkedhashset/serialization.go b/vendor/github.com/emirpasic/gods/sets/linkedhashset/serialization.go deleted file mode 100644 index 7e7d2911c..000000000 --- a/vendor/github.com/emirpasic/gods/sets/linkedhashset/serialization.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedhashset - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Set)(nil) - var _ containers.JSONDeserializer = (*Set)(nil) -} - -// ToJSON outputs the JSON representation of the set. -func (set *Set) ToJSON() ([]byte, error) { - return json.Marshal(set.Values()) -} - -// FromJSON populates the set from the input JSON representation. -func (set *Set) FromJSON(data []byte) error { - elements := []interface{}{} - err := json.Unmarshal(data, &elements) - if err == nil { - set.Clear() - set.Add(elements...) - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/sets/sets.go b/vendor/github.com/emirpasic/gods/sets/sets.go deleted file mode 100644 index 257329713..000000000 --- a/vendor/github.com/emirpasic/gods/sets/sets.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package sets provides an abstract Set interface. -// -// In computer science, a set is an abstract data type that can store certain values and no repeated values. It is a computer implementation of the mathematical concept of a finite set. Unlike most other collection types, rather than retrieving a specific element from a set, one typically tests a value for membership in a set. -// -// Reference: https://en.wikipedia.org/wiki/Set_%28abstract_data_type%29 -package sets - -import "github.com/emirpasic/gods/containers" - -// Set interface that all sets implement -type Set interface { - Add(elements ...interface{}) - Remove(elements ...interface{}) - Contains(elements ...interface{}) bool - - containers.Container - // Empty() bool - // Size() int - // Clear() - // Values() []interface{} -} diff --git a/vendor/github.com/emirpasic/gods/sets/treeset/enumerable.go b/vendor/github.com/emirpasic/gods/sets/treeset/enumerable.go deleted file mode 100644 index 59a0913a9..000000000 --- a/vendor/github.com/emirpasic/gods/sets/treeset/enumerable.go +++ /dev/null @@ -1,82 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treeset - -import ( - "github.com/emirpasic/gods/containers" - rbt "github.com/emirpasic/gods/trees/redblacktree" -) - -func assertEnumerableImplementation() { - var _ containers.EnumerableWithIndex = (*Set)(nil) -} - -// Each calls the given function once for each element, passing that element's index and value. -func (set *Set) Each(f func(index int, value interface{})) { - iterator := set.Iterator() - for iterator.Next() { - f(iterator.Index(), iterator.Value()) - } -} - -// Map invokes the given function once for each element and returns a -// container containing the values returned by the given function. -func (set *Set) Map(f func(index int, value interface{}) interface{}) *Set { - newSet := &Set{tree: rbt.NewWith(set.tree.Comparator)} - iterator := set.Iterator() - for iterator.Next() { - newSet.Add(f(iterator.Index(), iterator.Value())) - } - return newSet -} - -// Select returns a new container containing all elements for which the given function returns a true value. -func (set *Set) Select(f func(index int, value interface{}) bool) *Set { - newSet := &Set{tree: rbt.NewWith(set.tree.Comparator)} - iterator := set.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - newSet.Add(iterator.Value()) - } - } - return newSet -} - -// Any passes each element of the container to the given function and -// returns true if the function ever returns true for any element. -func (set *Set) Any(f func(index int, value interface{}) bool) bool { - iterator := set.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - return true - } - } - return false -} - -// All passes each element of the container to the given function and -// returns true if the function returns true for all elements. -func (set *Set) All(f func(index int, value interface{}) bool) bool { - iterator := set.Iterator() - for iterator.Next() { - if !f(iterator.Index(), iterator.Value()) { - return false - } - } - return true -} - -// Find passes each element of the container to the given function and returns -// the first (index,value) for which the function is true or -1,nil otherwise -// if no element matches the criteria. -func (set *Set) Find(f func(index int, value interface{}) bool) (int, interface{}) { - iterator := set.Iterator() - for iterator.Next() { - if f(iterator.Index(), iterator.Value()) { - return iterator.Index(), iterator.Value() - } - } - return -1, nil -} diff --git a/vendor/github.com/emirpasic/gods/sets/treeset/iterator.go b/vendor/github.com/emirpasic/gods/sets/treeset/iterator.go deleted file mode 100644 index 9dd62893a..000000000 --- a/vendor/github.com/emirpasic/gods/sets/treeset/iterator.go +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treeset - -import ( - "github.com/emirpasic/gods/containers" - rbt "github.com/emirpasic/gods/trees/redblacktree" -) - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil) -} - -// Iterator returns a stateful iterator whose values can be fetched by an index. -type Iterator struct { - index int - iterator rbt.Iterator - tree *rbt.Tree -} - -// Iterator holding the iterator's state -func (set *Set) Iterator() Iterator { - return Iterator{index: -1, iterator: set.tree.Iterator(), tree: set.tree} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - if iterator.index < iterator.tree.Size() { - iterator.index++ - } - return iterator.iterator.Next() -} - -// Prev moves the iterator to the previous element and returns true if there was a previous element in the container. -// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - if iterator.index >= 0 { - iterator.index-- - } - return iterator.iterator.Prev() -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - return iterator.iterator.Key() -} - -// Index returns the current element's index. -// Does not modify the state of the iterator. -func (iterator *Iterator) Index() int { - return iterator.index -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.index = -1 - iterator.iterator.Begin() -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.index = iterator.tree.Size() - iterator.iterator.End() -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) First() bool { - iterator.Begin() - return iterator.Next() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - iterator.End() - return iterator.Prev() -} diff --git a/vendor/github.com/emirpasic/gods/sets/treeset/serialization.go b/vendor/github.com/emirpasic/gods/sets/treeset/serialization.go deleted file mode 100644 index a53bfccf0..000000000 --- a/vendor/github.com/emirpasic/gods/sets/treeset/serialization.go +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treeset - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Set)(nil) - var _ containers.JSONDeserializer = (*Set)(nil) -} - -// ToJSON outputs the JSON representation of the set. -func (set *Set) ToJSON() ([]byte, error) { - return json.Marshal(set.Values()) -} - -// FromJSON populates the set from the input JSON representation. -func (set *Set) FromJSON(data []byte) error { - elements := []interface{}{} - err := json.Unmarshal(data, &elements) - if err == nil { - set.Clear() - set.Add(elements...) - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/sets/treeset/treeset.go b/vendor/github.com/emirpasic/gods/sets/treeset/treeset.go deleted file mode 100644 index 7efbf2dc6..000000000 --- a/vendor/github.com/emirpasic/gods/sets/treeset/treeset.go +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package treeset implements a tree backed by a red-black tree. -// -// Structure is not thread safe. -// -// Reference: http://en.wikipedia.org/wiki/Set_%28abstract_data_type%29 -package treeset - -import ( - "fmt" - "github.com/emirpasic/gods/sets" - rbt "github.com/emirpasic/gods/trees/redblacktree" - "github.com/emirpasic/gods/utils" - "strings" -) - -func assertSetImplementation() { - var _ sets.Set = (*Set)(nil) -} - -// Set holds elements in a red-black tree -type Set struct { - tree *rbt.Tree -} - -var itemExists = struct{}{} - -// NewWith instantiates a new empty set with the custom comparator. -func NewWith(comparator utils.Comparator, values ...interface{}) *Set { - set := &Set{tree: rbt.NewWith(comparator)} - if len(values) > 0 { - set.Add(values...) - } - return set -} - -// NewWithIntComparator instantiates a new empty set with the IntComparator, i.e. keys are of type int. -func NewWithIntComparator(values ...interface{}) *Set { - set := &Set{tree: rbt.NewWithIntComparator()} - if len(values) > 0 { - set.Add(values...) - } - return set -} - -// NewWithStringComparator instantiates a new empty set with the StringComparator, i.e. keys are of type string. -func NewWithStringComparator(values ...interface{}) *Set { - set := &Set{tree: rbt.NewWithStringComparator()} - if len(values) > 0 { - set.Add(values...) - } - return set -} - -// Add adds the items (one or more) to the set. -func (set *Set) Add(items ...interface{}) { - for _, item := range items { - set.tree.Put(item, itemExists) - } -} - -// Remove removes the items (one or more) from the set. -func (set *Set) Remove(items ...interface{}) { - for _, item := range items { - set.tree.Remove(item) - } -} - -// Contains checks weather items (one or more) are present in the set. -// All items have to be present in the set for the method to return true. -// Returns true if no arguments are passed at all, i.e. set is always superset of empty set. -func (set *Set) Contains(items ...interface{}) bool { - for _, item := range items { - if _, contains := set.tree.Get(item); !contains { - return false - } - } - return true -} - -// Empty returns true if set does not contain any elements. -func (set *Set) Empty() bool { - return set.tree.Size() == 0 -} - -// Size returns number of elements within the set. -func (set *Set) Size() int { - return set.tree.Size() -} - -// Clear clears all values in the set. -func (set *Set) Clear() { - set.tree.Clear() -} - -// Values returns all items in the set. -func (set *Set) Values() []interface{} { - return set.tree.Keys() -} - -// String returns a string representation of container -func (set *Set) String() string { - str := "TreeSet\n" - items := []string{} - for _, v := range set.tree.Keys() { - items = append(items, fmt.Sprintf("%v", v)) - } - str += strings.Join(items, ", ") - return str -} diff --git a/vendor/github.com/emirpasic/gods/sets/treeset/treeset_test.go b/vendor/github.com/emirpasic/gods/sets/treeset/treeset_test.go deleted file mode 100644 index b3cfca9d2..000000000 --- a/vendor/github.com/emirpasic/gods/sets/treeset/treeset_test.go +++ /dev/null @@ -1,521 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package treeset - -import ( - "fmt" - "testing" -) - -func TestSetNew(t *testing.T) { - set := NewWithIntComparator(2, 1) - if actualValue := set.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - values := set.Values() - if actualValue := values[0]; actualValue != 1 { - t.Errorf("Got %v expected %v", actualValue, 1) - } - if actualValue := values[1]; actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } -} - -func TestSetAdd(t *testing.T) { - set := NewWithIntComparator() - set.Add() - set.Add(1) - set.Add(2) - set.Add(2, 3) - set.Add() - if actualValue := set.Empty(); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := set.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, expectedValue := fmt.Sprintf("%d%d%d", set.Values()...), "123"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestSetContains(t *testing.T) { - set := NewWithIntComparator() - set.Add(3, 1, 2) - if actualValue := set.Contains(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(1); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(1, 2, 3); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := set.Contains(1, 2, 3, 4); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } -} - -func TestSetRemove(t *testing.T) { - set := NewWithIntComparator() - set.Add(3, 1, 2) - set.Remove() - if actualValue := set.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - set.Remove(1) - if actualValue := set.Size(); actualValue != 2 { - t.Errorf("Got %v expected %v", actualValue, 2) - } - set.Remove(3) - set.Remove(3) - set.Remove() - set.Remove(2) - if actualValue := set.Size(); actualValue != 0 { - t.Errorf("Got %v expected %v", actualValue, 0) - } -} - -func TestSetEach(t *testing.T) { - set := NewWithStringComparator() - set.Add("c", "a", "b") - set.Each(func(index int, value interface{}) { - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - }) -} - -func TestSetMap(t *testing.T) { - set := NewWithStringComparator() - set.Add("c", "a", "b") - mappedSet := set.Map(func(index int, value interface{}) interface{} { - return "mapped: " + value.(string) - }) - if actualValue, expectedValue := mappedSet.Contains("mapped: a", "mapped: b", "mapped: c"), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := mappedSet.Contains("mapped: a", "mapped: b", "mapped: x"), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if mappedSet.Size() != 3 { - t.Errorf("Got %v expected %v", mappedSet.Size(), 3) - } -} - -func TestSetSelect(t *testing.T) { - set := NewWithStringComparator() - set.Add("c", "a", "b") - selectedSet := set.Select(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "b" - }) - if actualValue, expectedValue := selectedSet.Contains("a", "b"), true; actualValue != expectedValue { - fmt.Println("A: ", selectedSet.Contains("b")) - t.Errorf("Got %v (%v) expected %v (%v)", actualValue, selectedSet.Values(), expectedValue, "[a b]") - } - if actualValue, expectedValue := selectedSet.Contains("a", "b", "c"), false; actualValue != expectedValue { - t.Errorf("Got %v (%v) expected %v (%v)", actualValue, selectedSet.Values(), expectedValue, "[a b]") - } - if selectedSet.Size() != 2 { - t.Errorf("Got %v expected %v", selectedSet.Size(), 3) - } -} - -func TestSetAny(t *testing.T) { - set := NewWithStringComparator() - set.Add("c", "a", "b") - any := set.Any(func(index int, value interface{}) bool { - return value.(string) == "c" - }) - if any != true { - t.Errorf("Got %v expected %v", any, true) - } - any = set.Any(func(index int, value interface{}) bool { - return value.(string) == "x" - }) - if any != false { - t.Errorf("Got %v expected %v", any, false) - } -} - -func TestSetAll(t *testing.T) { - set := NewWithStringComparator() - set.Add("c", "a", "b") - all := set.All(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "c" - }) - if all != true { - t.Errorf("Got %v expected %v", all, true) - } - all = set.All(func(index int, value interface{}) bool { - return value.(string) >= "a" && value.(string) <= "b" - }) - if all != false { - t.Errorf("Got %v expected %v", all, false) - } -} - -func TestSetFind(t *testing.T) { - set := NewWithStringComparator() - set.Add("c", "a", "b") - foundIndex, foundValue := set.Find(func(index int, value interface{}) bool { - return value.(string) == "c" - }) - if foundValue != "c" || foundIndex != 2 { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, "c", 2) - } - foundIndex, foundValue = set.Find(func(index int, value interface{}) bool { - return value.(string) == "x" - }) - if foundValue != nil || foundIndex != -1 { - t.Errorf("Got %v at %v expected %v at %v", foundValue, foundIndex, nil, nil) - } -} - -func TestSetChaining(t *testing.T) { - set := NewWithStringComparator() - set.Add("c", "a", "b") -} - -func TestSetIteratorNextOnEmpty(t *testing.T) { - set := NewWithStringComparator() - it := set.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty set") - } -} - -func TestSetIteratorPrevOnEmpty(t *testing.T) { - set := NewWithStringComparator() - it := set.Iterator() - for it.Prev() { - t.Errorf("Shouldn't iterate on empty set") - } -} - -func TestSetIteratorNext(t *testing.T) { - set := NewWithStringComparator() - set.Add("c", "a", "b") - it := set.Iterator() - count := 0 - for it.Next() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := index, count-1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestSetIteratorPrev(t *testing.T) { - set := NewWithStringComparator() - set.Add("c", "a", "b") - it := set.Iterator() - for it.Prev() { - } - count := 0 - for it.Next() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := index, count-1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestSetIteratorBegin(t *testing.T) { - set := NewWithStringComparator() - it := set.Iterator() - it.Begin() - set.Add("a", "b", "c") - for it.Next() { - } - it.Begin() - it.Next() - if index, value := it.Index(), it.Value(); index != 0 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") - } -} - -func TestSetIteratorEnd(t *testing.T) { - set := NewWithStringComparator() - it := set.Iterator() - - if index := it.Index(); index != -1 { - t.Errorf("Got %v expected %v", index, -1) - } - - it.End() - if index := it.Index(); index != 0 { - t.Errorf("Got %v expected %v", index, 0) - } - - set.Add("a", "b", "c") - it.End() - if index := it.Index(); index != set.Size() { - t.Errorf("Got %v expected %v", index, set.Size()) - } - - it.Prev() - if index, value := it.Index(), it.Value(); index != set.Size()-1 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, set.Size()-1, "c") - } -} - -func TestSetIteratorFirst(t *testing.T) { - set := NewWithStringComparator() - set.Add("a", "b", "c") - it := set.Iterator() - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 0 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "a") - } -} - -func TestSetIteratorLast(t *testing.T) { - set := NewWithStringComparator() - set.Add("a", "b", "c") - it := set.Iterator() - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 2 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "c") - } -} - -func TestSetSerialization(t *testing.T) { - set := NewWithStringComparator() - set.Add("a", "b", "c") - - var err error - assert := func() { - if actualValue, expectedValue := set.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := set.Contains("a", "b", "c"); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := set.ToJSON() - assert() - - err = set.FromJSON(json) - assert() -} - -func benchmarkContains(b *testing.B, set *Set, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - set.Contains(n) - } - } -} - -func benchmarkAdd(b *testing.B, set *Set, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - set.Add(n) - } - } -} - -func benchmarkRemove(b *testing.B, set *Set, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - set.Remove(n) - } - } -} - -func BenchmarkTreeSetContains100(b *testing.B) { - b.StopTimer() - size := 100 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkTreeSetContains1000(b *testing.B) { - b.StopTimer() - size := 1000 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkTreeSetContains10000(b *testing.B) { - b.StopTimer() - size := 10000 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkTreeSetContains100000(b *testing.B) { - b.StopTimer() - size := 100000 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkContains(b, set, size) -} - -func BenchmarkTreeSetAdd100(b *testing.B) { - b.StopTimer() - size := 100 - set := NewWithIntComparator() - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkTreeSetAdd1000(b *testing.B) { - b.StopTimer() - size := 1000 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkTreeSetAdd10000(b *testing.B) { - b.StopTimer() - size := 10000 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkTreeSetAdd100000(b *testing.B) { - b.StopTimer() - size := 100000 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkAdd(b, set, size) -} - -func BenchmarkTreeSetRemove100(b *testing.B) { - b.StopTimer() - size := 100 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} - -func BenchmarkTreeSetRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} - -func BenchmarkTreeSetRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} - -func BenchmarkTreeSetRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - set := NewWithIntComparator() - for n := 0; n < size; n++ { - set.Add(n) - } - b.StartTimer() - benchmarkRemove(b, set, size) -} diff --git a/vendor/github.com/emirpasic/gods/stacks/arraystack/arraystack.go b/vendor/github.com/emirpasic/gods/stacks/arraystack/arraystack.go deleted file mode 100644 index 9a971e98c..000000000 --- a/vendor/github.com/emirpasic/gods/stacks/arraystack/arraystack.go +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package arraystack implements a stack backed by array list. -// -// Structure is not thread safe. -// -// Reference: https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29#Array -package arraystack - -import ( - "fmt" - "github.com/emirpasic/gods/lists/arraylist" - "github.com/emirpasic/gods/stacks" - "strings" -) - -func assertStackImplementation() { - var _ stacks.Stack = (*Stack)(nil) -} - -// Stack holds elements in an array-list -type Stack struct { - list *arraylist.List -} - -// New instantiates a new empty stack -func New() *Stack { - return &Stack{list: arraylist.New()} -} - -// Push adds a value onto the top of the stack -func (stack *Stack) Push(value interface{}) { - stack.list.Add(value) -} - -// Pop removes top element on stack and returns it, or nil if stack is empty. -// Second return parameter is true, unless the stack was empty and there was nothing to pop. -func (stack *Stack) Pop() (value interface{}, ok bool) { - value, ok = stack.list.Get(stack.list.Size() - 1) - stack.list.Remove(stack.list.Size() - 1) - return -} - -// Peek returns top element on the stack without removing it, or nil if stack is empty. -// Second return parameter is true, unless the stack was empty and there was nothing to peek. -func (stack *Stack) Peek() (value interface{}, ok bool) { - return stack.list.Get(stack.list.Size() - 1) -} - -// Empty returns true if stack does not contain any elements. -func (stack *Stack) Empty() bool { - return stack.list.Empty() -} - -// Size returns number of elements within the stack. -func (stack *Stack) Size() int { - return stack.list.Size() -} - -// Clear removes all elements from the stack. -func (stack *Stack) Clear() { - stack.list.Clear() -} - -// Values returns all elements in the stack (LIFO order). -func (stack *Stack) Values() []interface{} { - size := stack.list.Size() - elements := make([]interface{}, size, size) - for i := 1; i <= size; i++ { - elements[size-i], _ = stack.list.Get(i - 1) // in reverse (LIFO) - } - return elements -} - -// String returns a string representation of container -func (stack *Stack) String() string { - str := "ArrayStack\n" - values := []string{} - for _, value := range stack.list.Values() { - values = append(values, fmt.Sprintf("%v", value)) - } - str += strings.Join(values, ", ") - return str -} - -// Check that the index is within bounds of the list -func (stack *Stack) withinRange(index int) bool { - return index >= 0 && index < stack.list.Size() -} diff --git a/vendor/github.com/emirpasic/gods/stacks/arraystack/arraystack_test.go b/vendor/github.com/emirpasic/gods/stacks/arraystack/arraystack_test.go deleted file mode 100644 index 62ba7fdbe..000000000 --- a/vendor/github.com/emirpasic/gods/stacks/arraystack/arraystack_test.go +++ /dev/null @@ -1,362 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package arraystack - -import ( - "fmt" - "testing" -) - -func TestStackPush(t *testing.T) { - stack := New() - if actualValue := stack.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - stack.Push(1) - stack.Push(2) - stack.Push(3) - - if actualValue := stack.Values(); actualValue[0].(int) != 3 || actualValue[1].(int) != 2 || actualValue[2].(int) != 1 { - t.Errorf("Got %v expected %v", actualValue, "[3,2,1]") - } - if actualValue := stack.Empty(); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := stack.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, ok := stack.Peek(); actualValue != 3 || !ok { - t.Errorf("Got %v expected %v", actualValue, 3) - } -} - -func TestStackPeek(t *testing.T) { - stack := New() - if actualValue, ok := stack.Peek(); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - stack.Push(1) - stack.Push(2) - stack.Push(3) - if actualValue, ok := stack.Peek(); actualValue != 3 || !ok { - t.Errorf("Got %v expected %v", actualValue, 3) - } -} - -func TestStackPop(t *testing.T) { - stack := New() - stack.Push(1) - stack.Push(2) - stack.Push(3) - stack.Pop() - if actualValue, ok := stack.Peek(); actualValue != 2 || !ok { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue, ok := stack.Pop(); actualValue != 2 || !ok { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue, ok := stack.Pop(); actualValue != 1 || !ok { - t.Errorf("Got %v expected %v", actualValue, 1) - } - if actualValue, ok := stack.Pop(); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - if actualValue := stack.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := stack.Values(); len(actualValue) != 0 { - t.Errorf("Got %v expected %v", actualValue, "[]") - } -} - -func TestStackIteratorOnEmpty(t *testing.T) { - stack := New() - it := stack.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty stack") - } -} - -func TestStackIteratorNext(t *testing.T) { - stack := New() - stack.Push("a") - stack.Push("b") - stack.Push("c") - - it := stack.Iterator() - count := 0 - for it.Next() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := index, count-1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestStackIteratorPrev(t *testing.T) { - stack := New() - stack.Push("a") - stack.Push("b") - stack.Push("c") - - it := stack.Iterator() - for it.Next() { - } - count := 0 - for it.Prev() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := index, 3-count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestStackIteratorBegin(t *testing.T) { - stack := New() - it := stack.Iterator() - it.Begin() - stack.Push("a") - stack.Push("b") - stack.Push("c") - for it.Next() { - } - it.Begin() - it.Next() - if index, value := it.Index(), it.Value(); index != 0 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c") - } -} - -func TestStackIteratorEnd(t *testing.T) { - stack := New() - it := stack.Iterator() - - if index := it.Index(); index != -1 { - t.Errorf("Got %v expected %v", index, -1) - } - - it.End() - if index := it.Index(); index != 0 { - t.Errorf("Got %v expected %v", index, 0) - } - - stack.Push("a") - stack.Push("b") - stack.Push("c") - it.End() - if index := it.Index(); index != stack.Size() { - t.Errorf("Got %v expected %v", index, stack.Size()) - } - - it.Prev() - if index, value := it.Index(), it.Value(); index != stack.Size()-1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, stack.Size()-1, "a") - } -} - -func TestStackIteratorFirst(t *testing.T) { - stack := New() - it := stack.Iterator() - if actualValue, expectedValue := it.First(), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - stack.Push("a") - stack.Push("b") - stack.Push("c") - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 0 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c") - } -} - -func TestStackIteratorLast(t *testing.T) { - stack := New() - it := stack.Iterator() - if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - stack.Push("a") - stack.Push("b") - stack.Push("c") - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 2 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 2, "a") - } -} - -func TestStackSerialization(t *testing.T) { - stack := New() - stack.Push("a") - stack.Push("b") - stack.Push("c") - - var err error - assert := func() { - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", stack.Values()...), "cba"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := stack.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := stack.ToJSON() - assert() - - err = stack.FromJSON(json) - assert() -} - -func benchmarkPush(b *testing.B, stack *Stack, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - stack.Push(n) - } - } -} - -func benchmarkPop(b *testing.B, stack *Stack, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - stack.Pop() - } - } -} - -func BenchmarkArrayStackPop100(b *testing.B) { - b.StopTimer() - size := 100 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPop(b, stack, size) -} - -func BenchmarkArrayStackPop1000(b *testing.B) { - b.StopTimer() - size := 1000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPop(b, stack, size) -} - -func BenchmarkArrayStackPop10000(b *testing.B) { - b.StopTimer() - size := 10000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPop(b, stack, size) -} - -func BenchmarkArrayStackPop100000(b *testing.B) { - b.StopTimer() - size := 100000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPop(b, stack, size) -} - -func BenchmarkArrayStackPush100(b *testing.B) { - b.StopTimer() - size := 100 - stack := New() - b.StartTimer() - benchmarkPush(b, stack, size) -} - -func BenchmarkArrayStackPush1000(b *testing.B) { - b.StopTimer() - size := 1000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPush(b, stack, size) -} - -func BenchmarkArrayStackPush10000(b *testing.B) { - b.StopTimer() - size := 10000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPush(b, stack, size) -} - -func BenchmarkArrayStackPush100000(b *testing.B) { - b.StopTimer() - size := 100000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPush(b, stack, size) -} diff --git a/vendor/github.com/emirpasic/gods/stacks/arraystack/iterator.go b/vendor/github.com/emirpasic/gods/stacks/arraystack/iterator.go deleted file mode 100644 index 48f9bf886..000000000 --- a/vendor/github.com/emirpasic/gods/stacks/arraystack/iterator.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package arraystack - -import "github.com/emirpasic/gods/containers" - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil) -} - -// Iterator returns a stateful iterator whose values can be fetched by an index. -type Iterator struct { - stack *Stack - index int -} - -// Iterator returns a stateful iterator whose values can be fetched by an index. -func (stack *Stack) Iterator() Iterator { - return Iterator{stack: stack, index: -1} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - if iterator.index < iterator.stack.Size() { - iterator.index++ - } - return iterator.stack.withinRange(iterator.index) -} - -// Prev moves the iterator to the previous element and returns true if there was a previous element in the container. -// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - if iterator.index >= 0 { - iterator.index-- - } - return iterator.stack.withinRange(iterator.index) -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - value, _ := iterator.stack.list.Get(iterator.stack.list.Size() - iterator.index - 1) // in reverse (LIFO) - return value -} - -// Index returns the current element's index. -// Does not modify the state of the iterator. -func (iterator *Iterator) Index() int { - return iterator.index -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.index = -1 -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.index = iterator.stack.Size() -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) First() bool { - iterator.Begin() - return iterator.Next() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - iterator.End() - return iterator.Prev() -} diff --git a/vendor/github.com/emirpasic/gods/stacks/arraystack/serialization.go b/vendor/github.com/emirpasic/gods/stacks/arraystack/serialization.go deleted file mode 100644 index c4ff54974..000000000 --- a/vendor/github.com/emirpasic/gods/stacks/arraystack/serialization.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package arraystack - -import "github.com/emirpasic/gods/containers" - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Stack)(nil) - var _ containers.JSONDeserializer = (*Stack)(nil) -} - -// ToJSON outputs the JSON representation of the stack. -func (stack *Stack) ToJSON() ([]byte, error) { - return stack.list.ToJSON() -} - -// FromJSON populates the stack from the input JSON representation. -func (stack *Stack) FromJSON(data []byte) error { - return stack.list.FromJSON(data) -} diff --git a/vendor/github.com/emirpasic/gods/stacks/linkedliststack/iterator.go b/vendor/github.com/emirpasic/gods/stacks/linkedliststack/iterator.go deleted file mode 100644 index 4c7eafaf3..000000000 --- a/vendor/github.com/emirpasic/gods/stacks/linkedliststack/iterator.go +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedliststack - -import "github.com/emirpasic/gods/containers" - -func assertIteratorImplementation() { - var _ containers.IteratorWithIndex = (*Iterator)(nil) -} - -// Iterator returns a stateful iterator whose values can be fetched by an index. -type Iterator struct { - stack *Stack - index int -} - -// Iterator returns a stateful iterator whose values can be fetched by an index. -func (stack *Stack) Iterator() Iterator { - return Iterator{stack: stack, index: -1} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - if iterator.index < iterator.stack.Size() { - iterator.index++ - } - return iterator.stack.withinRange(iterator.index) -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - value, _ := iterator.stack.list.Get(iterator.index) // in reverse (LIFO) - return value -} - -// Index returns the current element's index. -// Does not modify the state of the iterator. -func (iterator *Iterator) Index() int { - return iterator.index -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.index = -1 -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) First() bool { - iterator.Begin() - return iterator.Next() -} diff --git a/vendor/github.com/emirpasic/gods/stacks/linkedliststack/linkedliststack.go b/vendor/github.com/emirpasic/gods/stacks/linkedliststack/linkedliststack.go deleted file mode 100644 index da5bf2f74..000000000 --- a/vendor/github.com/emirpasic/gods/stacks/linkedliststack/linkedliststack.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package linkedliststack implements a stack backed by a singly-linked list. -// -// Structure is not thread safe. -// -// Reference:https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29#Linked_list -package linkedliststack - -import ( - "fmt" - "github.com/emirpasic/gods/lists/singlylinkedlist" - "github.com/emirpasic/gods/stacks" - "strings" -) - -func assertStackImplementation() { - var _ stacks.Stack = (*Stack)(nil) -} - -// Stack holds elements in a singly-linked-list -type Stack struct { - list *singlylinkedlist.List -} - -// New nnstantiates a new empty stack -func New() *Stack { - return &Stack{list: &singlylinkedlist.List{}} -} - -// Push adds a value onto the top of the stack -func (stack *Stack) Push(value interface{}) { - stack.list.Prepend(value) -} - -// Pop removes top element on stack and returns it, or nil if stack is empty. -// Second return parameter is true, unless the stack was empty and there was nothing to pop. -func (stack *Stack) Pop() (value interface{}, ok bool) { - value, ok = stack.list.Get(0) - stack.list.Remove(0) - return -} - -// Peek returns top element on the stack without removing it, or nil if stack is empty. -// Second return parameter is true, unless the stack was empty and there was nothing to peek. -func (stack *Stack) Peek() (value interface{}, ok bool) { - return stack.list.Get(0) -} - -// Empty returns true if stack does not contain any elements. -func (stack *Stack) Empty() bool { - return stack.list.Empty() -} - -// Size returns number of elements within the stack. -func (stack *Stack) Size() int { - return stack.list.Size() -} - -// Clear removes all elements from the stack. -func (stack *Stack) Clear() { - stack.list.Clear() -} - -// Values returns all elements in the stack (LIFO order). -func (stack *Stack) Values() []interface{} { - return stack.list.Values() -} - -// String returns a string representation of container -func (stack *Stack) String() string { - str := "LinkedListStack\n" - values := []string{} - for _, value := range stack.list.Values() { - values = append(values, fmt.Sprintf("%v", value)) - } - str += strings.Join(values, ", ") - return str -} - -// Check that the index is within bounds of the list -func (stack *Stack) withinRange(index int) bool { - return index >= 0 && index < stack.list.Size() -} diff --git a/vendor/github.com/emirpasic/gods/stacks/linkedliststack/linkedliststack_test.go b/vendor/github.com/emirpasic/gods/stacks/linkedliststack/linkedliststack_test.go deleted file mode 100644 index f7b6f956d..000000000 --- a/vendor/github.com/emirpasic/gods/stacks/linkedliststack/linkedliststack_test.go +++ /dev/null @@ -1,278 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedliststack - -import ( - "fmt" - "testing" -) - -func TestStackPush(t *testing.T) { - stack := New() - if actualValue := stack.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - stack.Push(1) - stack.Push(2) - stack.Push(3) - - if actualValue := stack.Values(); actualValue[0].(int) != 3 || actualValue[1].(int) != 2 || actualValue[2].(int) != 1 { - t.Errorf("Got %v expected %v", actualValue, "[3,2,1]") - } - if actualValue := stack.Empty(); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := stack.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, ok := stack.Peek(); actualValue != 3 || !ok { - t.Errorf("Got %v expected %v", actualValue, 3) - } -} - -func TestStackPeek(t *testing.T) { - stack := New() - if actualValue, ok := stack.Peek(); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - stack.Push(1) - stack.Push(2) - stack.Push(3) - if actualValue, ok := stack.Peek(); actualValue != 3 || !ok { - t.Errorf("Got %v expected %v", actualValue, 3) - } -} - -func TestStackPop(t *testing.T) { - stack := New() - stack.Push(1) - stack.Push(2) - stack.Push(3) - stack.Pop() - if actualValue, ok := stack.Peek(); actualValue != 2 || !ok { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue, ok := stack.Pop(); actualValue != 2 || !ok { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue, ok := stack.Pop(); actualValue != 1 || !ok { - t.Errorf("Got %v expected %v", actualValue, 1) - } - if actualValue, ok := stack.Pop(); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - if actualValue := stack.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := stack.Values(); len(actualValue) != 0 { - t.Errorf("Got %v expected %v", actualValue, "[]") - } -} - -func TestStackIterator(t *testing.T) { - stack := New() - stack.Push("a") - stack.Push("b") - stack.Push("c") - - // Iterator - it := stack.Iterator() - count := 0 - for it.Next() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, "c"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, "b"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, "a"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := index, count-1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - stack.Clear() - it = stack.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty stack") - } -} - -func TestStackIteratorBegin(t *testing.T) { - stack := New() - it := stack.Iterator() - it.Begin() - stack.Push("a") - stack.Push("b") - stack.Push("c") - for it.Next() { - } - it.Begin() - it.Next() - if index, value := it.Index(), it.Value(); index != 0 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c") - } -} - -func TestStackIteratorFirst(t *testing.T) { - stack := New() - it := stack.Iterator() - if actualValue, expectedValue := it.First(), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - stack.Push("a") - stack.Push("b") - stack.Push("c") - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 0 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, "c") - } -} - -func TestStackSerialization(t *testing.T) { - stack := New() - stack.Push("a") - stack.Push("b") - stack.Push("c") - - var err error - assert := func() { - if actualValue, expectedValue := fmt.Sprintf("%s%s%s", stack.Values()...), "cba"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := stack.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := stack.ToJSON() - assert() - - err = stack.FromJSON(json) - assert() -} - -func benchmarkPush(b *testing.B, stack *Stack, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - stack.Push(n) - } - } -} - -func benchmarkPop(b *testing.B, stack *Stack, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - stack.Pop() - } - } -} - -func BenchmarkLinkedListStackPop100(b *testing.B) { - b.StopTimer() - size := 100 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPop(b, stack, size) -} - -func BenchmarkLinkedListStackPop1000(b *testing.B) { - b.StopTimer() - size := 1000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPop(b, stack, size) -} - -func BenchmarkLinkedListStackPop10000(b *testing.B) { - b.StopTimer() - size := 10000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPop(b, stack, size) -} - -func BenchmarkLinkedListStackPop100000(b *testing.B) { - b.StopTimer() - size := 100000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPop(b, stack, size) -} - -func BenchmarkLinkedListStackPush100(b *testing.B) { - b.StopTimer() - size := 100 - stack := New() - b.StartTimer() - benchmarkPush(b, stack, size) -} - -func BenchmarkLinkedListStackPush1000(b *testing.B) { - b.StopTimer() - size := 1000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPush(b, stack, size) -} - -func BenchmarkLinkedListStackPush10000(b *testing.B) { - b.StopTimer() - size := 10000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPush(b, stack, size) -} - -func BenchmarkLinkedListStackPush100000(b *testing.B) { - b.StopTimer() - size := 100000 - stack := New() - for n := 0; n < size; n++ { - stack.Push(n) - } - b.StartTimer() - benchmarkPush(b, stack, size) -} diff --git a/vendor/github.com/emirpasic/gods/stacks/linkedliststack/serialization.go b/vendor/github.com/emirpasic/gods/stacks/linkedliststack/serialization.go deleted file mode 100644 index 63337a1ff..000000000 --- a/vendor/github.com/emirpasic/gods/stacks/linkedliststack/serialization.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package linkedliststack - -import "github.com/emirpasic/gods/containers" - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Stack)(nil) - var _ containers.JSONDeserializer = (*Stack)(nil) -} - -// ToJSON outputs the JSON representation of the stack. -func (stack *Stack) ToJSON() ([]byte, error) { - return stack.list.ToJSON() -} - -// FromJSON populates the stack from the input JSON representation. -func (stack *Stack) FromJSON(data []byte) error { - return stack.list.FromJSON(data) -} diff --git a/vendor/github.com/emirpasic/gods/stacks/stacks.go b/vendor/github.com/emirpasic/gods/stacks/stacks.go deleted file mode 100644 index b959e19fd..000000000 --- a/vendor/github.com/emirpasic/gods/stacks/stacks.go +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package stacks provides an abstract Stack interface. -// -// In computer science, a stack is an abstract data type that serves as a collection of elements, with two principal operations: push, which adds an element to the collection, and pop, which removes the most recently added element that was not yet removed. The order in which elements come off a stack gives rise to its alternative name, LIFO (for last in, first out). Additionally, a peek operation may give access to the top without modifying the stack. -// -// Reference: https://en.wikipedia.org/wiki/Stack_%28abstract_data_type%29 -package stacks - -import "github.com/emirpasic/gods/containers" - -// Stack interface that all stacks implement -type Stack interface { - Push(value interface{}) - Pop() (value interface{}, ok bool) - Peek() (value interface{}, ok bool) - - containers.Container - // Empty() bool - // Size() int - // Clear() - // Values() []interface{} -} diff --git a/vendor/github.com/emirpasic/gods/trees/avltree/avltree.go b/vendor/github.com/emirpasic/gods/trees/avltree/avltree.go deleted file mode 100644 index 1efdae4c3..000000000 --- a/vendor/github.com/emirpasic/gods/trees/avltree/avltree.go +++ /dev/null @@ -1,449 +0,0 @@ -// Copyright (c) 2017, Benjamin Scher Purcell. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package avltree implements an AVL balanced binary tree. -// -// Structure is not thread safe. -// -// References: https://en.wikipedia.org/wiki/AVL_tree -package avltree - -import ( - "fmt" - "github.com/emirpasic/gods/trees" - "github.com/emirpasic/gods/utils" -) - -func assertTreeImplementation() { - var _ trees.Tree = new(Tree) -} - -// Tree holds elements of the AVL tree. -type Tree struct { - Root *Node // Root node - Comparator utils.Comparator // Key comparator - size int // Total number of keys in the tree -} - -// Node is a single element within the tree -type Node struct { - Key interface{} - Value interface{} - Parent *Node // Parent node - Children [2]*Node // Children nodes - b int8 -} - -// NewWith instantiates an AVL tree with the custom comparator. -func NewWith(comparator utils.Comparator) *Tree { - return &Tree{Comparator: comparator} -} - -// NewWithIntComparator instantiates an AVL tree with the IntComparator, i.e. keys are of type int. -func NewWithIntComparator() *Tree { - return &Tree{Comparator: utils.IntComparator} -} - -// NewWithStringComparator instantiates an AVL tree with the StringComparator, i.e. keys are of type string. -func NewWithStringComparator() *Tree { - return &Tree{Comparator: utils.StringComparator} -} - -// Put inserts node into the tree. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (t *Tree) Put(key interface{}, value interface{}) { - t.put(key, value, nil, &t.Root) -} - -// Get searches the node in the tree by key and returns its value or nil if key is not found in tree. -// Second return parameter is true if key was found, otherwise false. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (t *Tree) Get(key interface{}) (value interface{}, found bool) { - n := t.Root - for n != nil { - cmp := t.Comparator(key, n.Key) - switch { - case cmp == 0: - return n.Value, true - case cmp < 0: - n = n.Children[0] - case cmp > 0: - n = n.Children[1] - } - } - return nil, false -} - -// Remove remove the node from the tree by key. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (t *Tree) Remove(key interface{}) { - t.remove(key, &t.Root) -} - -// Empty returns true if tree does not contain any nodes. -func (t *Tree) Empty() bool { - return t.size == 0 -} - -// Size returns the number of elements stored in the tree. -func (t *Tree) Size() int { - return t.size -} - -// Keys returns all keys in-order -func (t *Tree) Keys() []interface{} { - keys := make([]interface{}, t.size) - it := t.Iterator() - for i := 0; it.Next(); i++ { - keys[i] = it.Key() - } - return keys -} - -// Values returns all values in-order based on the key. -func (t *Tree) Values() []interface{} { - values := make([]interface{}, t.size) - it := t.Iterator() - for i := 0; it.Next(); i++ { - values[i] = it.Value() - } - return values -} - -// Left returns the minimum element of the AVL tree -// or nil if the tree is empty. -func (t *Tree) Left() *Node { - return t.bottom(0) -} - -// Right returns the maximum element of the AVL tree -// or nil if the tree is empty. -func (t *Tree) Right() *Node { - return t.bottom(1) -} - -// Floor Finds floor node of the input key, return the floor node or nil if no ceiling is found. -// Second return parameter is true if floor was found, otherwise false. -// -// Floor node is defined as the largest node that is smaller than or equal to the given node. -// A floor node may not be found, either because the tree is empty, or because -// all nodes in the tree is larger than the given node. -// -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (t *Tree) Floor(key interface{}) (floor *Node, found bool) { - found = false - n := t.Root - for n != nil { - c := t.Comparator(key, n.Key) - switch { - case c == 0: - return n, true - case c < 0: - n = n.Children[0] - case c > 0: - floor, found = n, true - n = n.Children[1] - } - } - if found { - return - } - return nil, false -} - -// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling is found. -// Second return parameter is true if ceiling was found, otherwise false. -// -// Ceiling node is defined as the smallest node that is larger than or equal to the given node. -// A ceiling node may not be found, either because the tree is empty, or because -// all nodes in the tree is smaller than the given node. -// -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (t *Tree) Ceiling(key interface{}) (floor *Node, found bool) { - found = false - n := t.Root - for n != nil { - c := t.Comparator(key, n.Key) - switch { - case c == 0: - return n, true - case c < 0: - floor, found = n, true - n = n.Children[0] - case c > 0: - n = n.Children[1] - } - } - if found { - return - } - return nil, false -} - -// Clear removes all nodes from the tree. -func (t *Tree) Clear() { - t.Root = nil - t.size = 0 -} - -// String returns a string representation of container -func (t *Tree) String() string { - str := "AVLTree\n" - if !t.Empty() { - output(t.Root, "", true, &str) - } - return str -} - -func (n *Node) String() string { - return fmt.Sprintf("%v", n.Key) -} - -func (t *Tree) put(key interface{}, value interface{}, p *Node, qp **Node) bool { - q := *qp - if q == nil { - t.size++ - *qp = &Node{Key: key, Value: value, Parent: p} - return true - } - - c := t.Comparator(key, q.Key) - if c == 0 { - q.Key = key - q.Value = value - return false - } - - if c < 0 { - c = -1 - } else { - c = 1 - } - a := (c + 1) / 2 - var fix bool - fix = t.put(key, value, q, &q.Children[a]) - if fix { - return putFix(int8(c), qp) - } - return false -} - -func (t *Tree) remove(key interface{}, qp **Node) bool { - q := *qp - if q == nil { - return false - } - - c := t.Comparator(key, q.Key) - if c == 0 { - t.size-- - if q.Children[1] == nil { - if q.Children[0] != nil { - q.Children[0].Parent = q.Parent - } - *qp = q.Children[0] - return true - } - fix := removeMin(&q.Children[1], &q.Key, &q.Value) - if fix { - return removeFix(-1, qp) - } - return false - } - - if c < 0 { - c = -1 - } else { - c = 1 - } - a := (c + 1) / 2 - fix := t.remove(key, &q.Children[a]) - if fix { - return removeFix(int8(-c), qp) - } - return false -} - -func removeMin(qp **Node, minKey *interface{}, minVal *interface{}) bool { - q := *qp - if q.Children[0] == nil { - *minKey = q.Key - *minVal = q.Value - if q.Children[1] != nil { - q.Children[1].Parent = q.Parent - } - *qp = q.Children[1] - return true - } - fix := removeMin(&q.Children[0], minKey, minVal) - if fix { - return removeFix(1, qp) - } - return false -} - -func putFix(c int8, t **Node) bool { - s := *t - if s.b == 0 { - s.b = c - return true - } - - if s.b == -c { - s.b = 0 - return false - } - - if s.Children[(c+1)/2].b == c { - s = singlerot(c, s) - } else { - s = doublerot(c, s) - } - *t = s - return false -} - -func removeFix(c int8, t **Node) bool { - s := *t - if s.b == 0 { - s.b = c - return false - } - - if s.b == -c { - s.b = 0 - return true - } - - a := (c + 1) / 2 - if s.Children[a].b == 0 { - s = rotate(c, s) - s.b = -c - *t = s - return false - } - - if s.Children[a].b == c { - s = singlerot(c, s) - } else { - s = doublerot(c, s) - } - *t = s - return true -} - -func singlerot(c int8, s *Node) *Node { - s.b = 0 - s = rotate(c, s) - s.b = 0 - return s -} - -func doublerot(c int8, s *Node) *Node { - a := (c + 1) / 2 - r := s.Children[a] - s.Children[a] = rotate(-c, s.Children[a]) - p := rotate(c, s) - - switch { - default: - s.b = 0 - r.b = 0 - case p.b == c: - s.b = -c - r.b = 0 - case p.b == -c: - s.b = 0 - r.b = c - } - - p.b = 0 - return p -} - -func rotate(c int8, s *Node) *Node { - a := (c + 1) / 2 - r := s.Children[a] - s.Children[a] = r.Children[a^1] - if s.Children[a] != nil { - s.Children[a].Parent = s - } - r.Children[a^1] = s - r.Parent = s.Parent - s.Parent = r - return r -} - -func (t *Tree) bottom(d int) *Node { - n := t.Root - if n == nil { - return nil - } - - for c := n.Children[d]; c != nil; c = n.Children[d] { - n = c - } - return n -} - -// Prev returns the previous element in an inorder -// walk of the AVL tree. -func (n *Node) Prev() *Node { - return n.walk1(0) -} - -// Next returns the next element in an inorder -// walk of the AVL tree. -func (n *Node) Next() *Node { - return n.walk1(1) -} - -func (n *Node) walk1(a int) *Node { - if n == nil { - return nil - } - - if n.Children[a] != nil { - n = n.Children[a] - for n.Children[a^1] != nil { - n = n.Children[a^1] - } - return n - } - - p := n.Parent - for p != nil && p.Children[a] == n { - n = p - p = p.Parent - } - return p -} - -func output(node *Node, prefix string, isTail bool, str *string) { - if node.Children[1] != nil { - newPrefix := prefix - if isTail { - newPrefix += "│ " - } else { - newPrefix += " " - } - output(node.Children[1], newPrefix, false, str) - } - *str += prefix - if isTail { - *str += "└── " - } else { - *str += "┌── " - } - *str += node.String() + "\n" - if node.Children[0] != nil { - newPrefix := prefix - if isTail { - newPrefix += " " - } else { - newPrefix += "│ " - } - output(node.Children[0], newPrefix, true, str) - } -} diff --git a/vendor/github.com/emirpasic/gods/trees/avltree/avltree_test.go b/vendor/github.com/emirpasic/gods/trees/avltree/avltree_test.go deleted file mode 100644 index 99c2adf6a..000000000 --- a/vendor/github.com/emirpasic/gods/trees/avltree/avltree_test.go +++ /dev/null @@ -1,741 +0,0 @@ -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package avltree - -import ( - "fmt" - "testing" -) - -func TestAVLTreePut(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - tree.Put(1, "a") //overwrite - - if actualValue := tree.Size(); actualValue != 7 { - t.Errorf("Got %v expected %v", actualValue, 7) - } - if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d%d%d%d", tree.Keys()...), "1234567"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s%s%s%s", tree.Values()...), "abcdefg"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - tests1 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {8, nil, false}, - } - - for _, test := range tests1 { - // retrievals - actualValue, actualFound := tree.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } -} - -func TestAVLTreeRemove(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - tree.Put(1, "a") //overwrite - - tree.Remove(5) - tree.Remove(6) - tree.Remove(7) - tree.Remove(8) - tree.Remove(5) - - if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d", tree.Keys()...), "1234"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := tree.Size(); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, 7) - } - - tests2 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, nil, false}, - {6, nil, false}, - {7, nil, false}, - {8, nil, false}, - } - - for _, test := range tests2 { - actualValue, actualFound := tree.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } - - tree.Remove(1) - tree.Remove(4) - tree.Remove(2) - tree.Remove(3) - tree.Remove(2) - tree.Remove(2) - - if actualValue, expectedValue := fmt.Sprintf("%s", tree.Keys()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", tree.Values()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if empty, size := tree.Empty(), tree.Size(); empty != true || size != -0 { - t.Errorf("Got %v expected %v", empty, true) - } - -} - -func TestAVLTreeLeftAndRight(t *testing.T) { - tree := NewWithIntComparator() - - if actualValue := tree.Left(); actualValue != nil { - t.Errorf("Got %v expected %v", actualValue, nil) - } - if actualValue := tree.Right(); actualValue != nil { - t.Errorf("Got %v expected %v", actualValue, nil) - } - - tree.Put(1, "a") - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") // overwrite - tree.Put(2, "b") - - if actualValue, expectedValue := fmt.Sprintf("%d", tree.Left().Key), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", tree.Left().Value), "x"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - if actualValue, expectedValue := fmt.Sprintf("%d", tree.Right().Key), "7"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", tree.Right().Value), "g"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestAVLTreeCeilingAndFloor(t *testing.T) { - tree := NewWithIntComparator() - - if node, found := tree.Floor(0); node != nil || found { - t.Errorf("Got %v expected %v", node, "") - } - if node, found := tree.Ceiling(0); node != nil || found { - t.Errorf("Got %v expected %v", node, "") - } - - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - - if node, found := tree.Floor(4); node.Key != 4 || !found { - t.Errorf("Got %v expected %v", node.Key, 4) - } - if node, found := tree.Floor(0); node != nil || found { - t.Errorf("Got %v expected %v", node, "") - } - - if node, found := tree.Ceiling(4); node.Key != 4 || !found { - t.Errorf("Got %v expected %v", node.Key, 4) - } - if node, found := tree.Ceiling(8); node != nil || found { - t.Errorf("Got %v expected %v", node, "") - } -} - -func TestAVLTreeIteratorNextOnEmpty(t *testing.T) { - tree := NewWithIntComparator() - it := tree.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty tree") - } -} - -func TestAVLTreeIteratorPrevOnEmpty(t *testing.T) { - tree := NewWithIntComparator() - it := tree.Iterator() - for it.Prev() { - t.Errorf("Shouldn't iterate on empty tree") - } -} - -func TestAVLTreeIterator1Next(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - tree.Put(1, "a") //overwrite - // │ ┌── 7 - // └── 6 - // │ ┌── 5 - // └── 4 - // │ ┌── 3 - // └── 2 - // └── 1 - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - switch key { - case count: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestAVLTreeIterator1Prev(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - tree.Put(1, "a") //overwrite - // │ ┌── 7 - // └── 6 - // │ ┌── 5 - // └── 4 - // │ ┌── 3 - // └── 2 - // └── 1 - it := tree.Iterator() - for it.Next() { - } - countDown := tree.size - for it.Prev() { - key := it.Key() - switch key { - case countDown: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestAVLTreeIterator2Next(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - switch key { - case count: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestAVLTreeIterator2Prev(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - for it.Next() { - } - countDown := tree.size - for it.Prev() { - key := it.Key() - switch key { - case countDown: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestAVLTreeIterator3Next(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(1, "a") - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - switch key { - case count: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestAVLTreeIterator3Prev(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(1, "a") - it := tree.Iterator() - for it.Next() { - } - countDown := tree.size - for it.Prev() { - key := it.Key() - switch key { - case countDown: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestAVLTreeIterator4Next(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(13, 5) - tree.Put(8, 3) - tree.Put(17, 7) - tree.Put(1, 1) - tree.Put(11, 4) - tree.Put(15, 6) - tree.Put(25, 9) - tree.Put(6, 2) - tree.Put(22, 8) - tree.Put(27, 10) - // │ ┌── 27 - // │ ┌── 25 - // │ │ └── 22 - // │ ┌── 17 - // │ │ └── 15 - // └── 13 - // │ ┌── 11 - // └── 8 - // │ ┌── 6 - // └── 1 - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - value := it.Value() - switch value { - case count: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestAVLTreeIterator4Prev(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(13, 5) - tree.Put(8, 3) - tree.Put(17, 7) - tree.Put(1, 1) - tree.Put(11, 4) - tree.Put(15, 6) - tree.Put(25, 9) - tree.Put(6, 2) - tree.Put(22, 8) - tree.Put(27, 10) - // │ ┌── 27 - // │ ┌── 25 - // │ │ └── 22 - // │ ┌── 17 - // │ │ └── 15 - // └── 13 - // │ ┌── 11 - // └── 8 - // │ ┌── 6 - // └── 1 - it := tree.Iterator() - count := tree.Size() - for it.Next() { - } - for it.Prev() { - value := it.Value() - switch value { - case count: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - count-- - } - if actualValue, expectedValue := count, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestAVLTreeIteratorBegin(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - - if it.Key() != nil { - t.Errorf("Got %v expected %v", it.Key(), nil) - } - - it.Begin() - - if it.Key() != nil { - t.Errorf("Got %v expected %v", it.Key(), nil) - } - - for it.Next() { - } - - it.Begin() - - if it.Key() != nil { - t.Errorf("Got %v expected %v", it.Key(), nil) - } - - it.Next() - if key, value := it.Key(), it.Value(); key != 1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a") - } -} - -func TestAVLTreeIteratorEnd(t *testing.T) { - tree := NewWithIntComparator() - it := tree.Iterator() - - if it.Key() != nil { - t.Errorf("Got %v expected %v", it.Key(), nil) - } - - it.End() - if it.Key() != nil { - t.Errorf("Got %v expected %v", it.Key(), nil) - } - - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it.End() - if it.Key() != nil { - t.Errorf("Got %v expected %v", it.Key(), nil) - } - - it.Prev() - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestAVLTreeIteratorFirst(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a") - } -} - -func TestAVLTreeIteratorLast(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestAVLTreeSerialization(t *testing.T) { - tree := NewWithStringComparator() - tree.Put("c", "3") - tree.Put("b", "2") - tree.Put("a", "1") - - var err error - assert := func() { - if actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := tree.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" { - t.Errorf("Got %v expected %v", actualValue, "[a,b,c]") - } - if actualValue := tree.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" { - t.Errorf("Got %v expected %v", actualValue, "[1,2,3]") - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := tree.ToJSON() - assert() - - err = tree.FromJSON(json) - assert() -} - -func benchmarkGet(b *testing.B, tree *Tree, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - tree.Get(n) - } - } -} - -func benchmarkPut(b *testing.B, tree *Tree, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - } -} - -func benchmarkRemove(b *testing.B, tree *Tree, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - tree.Remove(n) - } - } -} - -func BenchmarkAVLTreeGet100(b *testing.B) { - b.StopTimer() - size := 100 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkAVLTreeGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkAVLTreeGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkAVLTreeGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkAVLTreePut100(b *testing.B) { - b.StopTimer() - size := 100 - tree := NewWithIntComparator() - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkAVLTreePut1000(b *testing.B) { - b.StopTimer() - size := 1000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkAVLTreePut10000(b *testing.B) { - b.StopTimer() - size := 10000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkAVLTreePut100000(b *testing.B) { - b.StopTimer() - size := 100000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkAVLTreeRemove100(b *testing.B) { - b.StopTimer() - size := 100 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} - -func BenchmarkAVLTreeRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} - -func BenchmarkAVLTreeRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} - -func BenchmarkAVLTreeRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} diff --git a/vendor/github.com/emirpasic/gods/trees/avltree/iterator.go b/vendor/github.com/emirpasic/gods/trees/avltree/iterator.go deleted file mode 100644 index bf2ff1490..000000000 --- a/vendor/github.com/emirpasic/gods/trees/avltree/iterator.go +++ /dev/null @@ -1,117 +0,0 @@ -// Copyright (c) 2017, Benjamin Scher Purcell. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package avltree - -import "github.com/emirpasic/gods/containers" - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithKey = (*Iterator)(nil) -} - -// Iterator holding the iterator's state -type Iterator struct { - tree *Tree - node *Node - position position -} - -type position byte - -const ( - begin, between, end position = 0, 1, 2 -) - -// Iterator returns a stateful iterator whose elements are key/value pairs. -func (tree *Tree) Iterator() containers.ReverseIteratorWithKey { - return &Iterator{tree: tree, node: nil, position: begin} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's key and value can be retrieved by Key() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - switch iterator.position { - case begin: - iterator.position = between - iterator.node = iterator.tree.Left() - case between: - iterator.node = iterator.node.Next() - } - - if iterator.node == nil { - iterator.position = end - return false - } - return true -} - -// Prev moves the iterator to the next element and returns true if there was a previous element in the container. -// If Prev() returns true, then next element's key and value can be retrieved by Key() and Value(). -// If Prev() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - switch iterator.position { - case end: - iterator.position = between - iterator.node = iterator.tree.Right() - case between: - iterator.node = iterator.node.Prev() - } - - if iterator.node == nil { - iterator.position = begin - return false - } - return true -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - if iterator.node == nil { - return nil - } - return iterator.node.Value -} - -// Key returns the current element's key. -// Does not modify the state of the iterator. -func (iterator *Iterator) Key() interface{} { - if iterator.node == nil { - return nil - } - return iterator.node.Key -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.node = nil - iterator.position = begin -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.node = nil - iterator.position = end -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator -func (iterator *Iterator) First() bool { - iterator.Begin() - return iterator.Next() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - iterator.End() - return iterator.Prev() -} diff --git a/vendor/github.com/emirpasic/gods/trees/avltree/serialization.go b/vendor/github.com/emirpasic/gods/trees/avltree/serialization.go deleted file mode 100644 index 363de7f49..000000000 --- a/vendor/github.com/emirpasic/gods/trees/avltree/serialization.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package avltree - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" - "github.com/emirpasic/gods/utils" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Tree)(nil) - var _ containers.JSONDeserializer = (*Tree)(nil) -} - -// ToJSON outputs the JSON representation of the tree. -func (tree *Tree) ToJSON() ([]byte, error) { - elements := make(map[string]interface{}) - it := tree.Iterator() - for it.Next() { - elements[utils.ToString(it.Key())] = it.Value() - } - return json.Marshal(&elements) -} - -// FromJSON populates the tree from the input JSON representation. -func (tree *Tree) FromJSON(data []byte) error { - elements := make(map[string]interface{}) - err := json.Unmarshal(data, &elements) - if err == nil { - tree.Clear() - for key, value := range elements { - tree.Put(key, value) - } - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/trees/binaryheap/binaryheap.go b/vendor/github.com/emirpasic/gods/trees/binaryheap/binaryheap.go deleted file mode 100644 index 70b28cf52..000000000 --- a/vendor/github.com/emirpasic/gods/trees/binaryheap/binaryheap.go +++ /dev/null @@ -1,163 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package binaryheap implements a binary heap backed by array list. -// -// Comparator defines this heap as either min or max heap. -// -// Structure is not thread safe. -// -// References: http://en.wikipedia.org/wiki/Binary_heap -package binaryheap - -import ( - "fmt" - "github.com/emirpasic/gods/lists/arraylist" - "github.com/emirpasic/gods/trees" - "github.com/emirpasic/gods/utils" - "strings" -) - -func assertTreeImplementation() { - var _ trees.Tree = (*Heap)(nil) -} - -// Heap holds elements in an array-list -type Heap struct { - list *arraylist.List - Comparator utils.Comparator -} - -// NewWith instantiates a new empty heap tree with the custom comparator. -func NewWith(comparator utils.Comparator) *Heap { - return &Heap{list: arraylist.New(), Comparator: comparator} -} - -// NewWithIntComparator instantiates a new empty heap with the IntComparator, i.e. elements are of type int. -func NewWithIntComparator() *Heap { - return &Heap{list: arraylist.New(), Comparator: utils.IntComparator} -} - -// NewWithStringComparator instantiates a new empty heap with the StringComparator, i.e. elements are of type string. -func NewWithStringComparator() *Heap { - return &Heap{list: arraylist.New(), Comparator: utils.StringComparator} -} - -// Push adds a value onto the heap and bubbles it up accordingly. -func (heap *Heap) Push(values ...interface{}) { - if len(values) == 1 { - heap.list.Add(values[0]) - heap.bubbleUp() - } else { - // Reference: https://en.wikipedia.org/wiki/Binary_heap#Building_a_heap - for _, value := range values { - heap.list.Add(value) - } - size := heap.list.Size()/2 + 1 - for i := size; i >= 0; i-- { - heap.bubbleDownIndex(i) - } - } -} - -// Pop removes top element on heap and returns it, or nil if heap is empty. -// Second return parameter is true, unless the heap was empty and there was nothing to pop. -func (heap *Heap) Pop() (value interface{}, ok bool) { - value, ok = heap.list.Get(0) - if !ok { - return - } - lastIndex := heap.list.Size() - 1 - heap.list.Swap(0, lastIndex) - heap.list.Remove(lastIndex) - heap.bubbleDown() - return -} - -// Peek returns top element on the heap without removing it, or nil if heap is empty. -// Second return parameter is true, unless the heap was empty and there was nothing to peek. -func (heap *Heap) Peek() (value interface{}, ok bool) { - return heap.list.Get(0) -} - -// Empty returns true if heap does not contain any elements. -func (heap *Heap) Empty() bool { - return heap.list.Empty() -} - -// Size returns number of elements within the heap. -func (heap *Heap) Size() int { - return heap.list.Size() -} - -// Clear removes all elements from the heap. -func (heap *Heap) Clear() { - heap.list.Clear() -} - -// Values returns all elements in the heap. -func (heap *Heap) Values() []interface{} { - return heap.list.Values() -} - -// String returns a string representation of container -func (heap *Heap) String() string { - str := "BinaryHeap\n" - values := []string{} - for _, value := range heap.list.Values() { - values = append(values, fmt.Sprintf("%v", value)) - } - str += strings.Join(values, ", ") - return str -} - -// Performs the "bubble down" operation. This is to place the element that is at the root -// of the heap in its correct place so that the heap maintains the min/max-heap order property. -func (heap *Heap) bubbleDown() { - heap.bubbleDownIndex(0) -} - -// Performs the "bubble down" operation. This is to place the element that is at the index -// of the heap in its correct place so that the heap maintains the min/max-heap order property. -func (heap *Heap) bubbleDownIndex(index int) { - size := heap.list.Size() - for leftIndex := index<<1 + 1; leftIndex < size; leftIndex = index<<1 + 1 { - rightIndex := index<<1 + 2 - smallerIndex := leftIndex - leftValue, _ := heap.list.Get(leftIndex) - rightValue, _ := heap.list.Get(rightIndex) - if rightIndex < size && heap.Comparator(leftValue, rightValue) > 0 { - smallerIndex = rightIndex - } - indexValue, _ := heap.list.Get(index) - smallerValue, _ := heap.list.Get(smallerIndex) - if heap.Comparator(indexValue, smallerValue) > 0 { - heap.list.Swap(index, smallerIndex) - } else { - break - } - index = smallerIndex - } -} - -// Performs the "bubble up" operation. This is to place a newly inserted -// element (i.e. last element in the list) in its correct place so that -// the heap maintains the min/max-heap order property. -func (heap *Heap) bubbleUp() { - index := heap.list.Size() - 1 - for parentIndex := (index - 1) >> 1; index > 0; parentIndex = (index - 1) >> 1 { - indexValue, _ := heap.list.Get(index) - parentValue, _ := heap.list.Get(parentIndex) - if heap.Comparator(parentValue, indexValue) <= 0 { - break - } - heap.list.Swap(index, parentIndex) - index = parentIndex - } -} - -// Check that the index is within bounds of the list -func (heap *Heap) withinRange(index int) bool { - return index >= 0 && index < heap.list.Size() -} diff --git a/vendor/github.com/emirpasic/gods/trees/binaryheap/binaryheap_test.go b/vendor/github.com/emirpasic/gods/trees/binaryheap/binaryheap_test.go deleted file mode 100644 index cf9781376..000000000 --- a/vendor/github.com/emirpasic/gods/trees/binaryheap/binaryheap_test.go +++ /dev/null @@ -1,393 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package binaryheap - -import ( - "math/rand" - "testing" -) - -func TestBinaryHeapPush(t *testing.T) { - heap := NewWithIntComparator() - - if actualValue := heap.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - - heap.Push(3) // [3] - heap.Push(2) // [2,3] - heap.Push(1) // [1,3,2](2 swapped with 1, hence last) - - if actualValue := heap.Values(); actualValue[0].(int) != 1 || actualValue[1].(int) != 3 || actualValue[2].(int) != 2 { - t.Errorf("Got %v expected %v", actualValue, "[1,2,3]") - } - if actualValue := heap.Empty(); actualValue != false { - t.Errorf("Got %v expected %v", actualValue, false) - } - if actualValue := heap.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, ok := heap.Peek(); actualValue != 1 || !ok { - t.Errorf("Got %v expected %v", actualValue, 1) - } -} - -func TestBinaryHeapPushBulk(t *testing.T) { - heap := NewWithIntComparator() - - heap.Push(15, 20, 3, 1, 2) - - if actualValue := heap.Values(); actualValue[0].(int) != 1 || actualValue[1].(int) != 2 || actualValue[2].(int) != 3 { - t.Errorf("Got %v expected %v", actualValue, "[1,2,3]") - } - if actualValue, ok := heap.Pop(); actualValue != 1 || !ok { - t.Errorf("Got %v expected %v", actualValue, 1) - } -} - -func TestBinaryHeapPop(t *testing.T) { - heap := NewWithIntComparator() - - if actualValue := heap.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - - heap.Push(3) // [3] - heap.Push(2) // [2,3] - heap.Push(1) // [1,3,2](2 swapped with 1, hence last) - heap.Pop() // [3,2] - - if actualValue, ok := heap.Peek(); actualValue != 2 || !ok { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue, ok := heap.Pop(); actualValue != 2 || !ok { - t.Errorf("Got %v expected %v", actualValue, 2) - } - if actualValue, ok := heap.Pop(); actualValue != 3 || !ok { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, ok := heap.Pop(); actualValue != nil || ok { - t.Errorf("Got %v expected %v", actualValue, nil) - } - if actualValue := heap.Empty(); actualValue != true { - t.Errorf("Got %v expected %v", actualValue, true) - } - if actualValue := heap.Values(); len(actualValue) != 0 { - t.Errorf("Got %v expected %v", actualValue, "[]") - } -} - -func TestBinaryHeapRandom(t *testing.T) { - heap := NewWithIntComparator() - - rand.Seed(3) - for i := 0; i < 10000; i++ { - r := int(rand.Int31n(30)) - heap.Push(r) - } - - prev, _ := heap.Pop() - for !heap.Empty() { - curr, _ := heap.Pop() - if prev.(int) > curr.(int) { - t.Errorf("Heap property invalidated. prev: %v current: %v", prev, curr) - } - prev = curr - } -} - -func TestBinaryHeapIteratorOnEmpty(t *testing.T) { - heap := NewWithIntComparator() - it := heap.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty heap") - } -} - -func TestBinaryHeapIteratorNext(t *testing.T) { - heap := NewWithIntComparator() - heap.Push(3) // [3] - heap.Push(2) // [2,3] - heap.Push(1) // [1,3,2](2 swapped with 1, hence last) - - it := heap.Iterator() - count := 0 - for it.Next() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := index, count-1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBinaryHeapIteratorPrev(t *testing.T) { - heap := NewWithIntComparator() - heap.Push(3) // [3] - heap.Push(2) // [2,3] - heap.Push(1) // [1,3,2](2 swapped with 1, hence last) - - it := heap.Iterator() - for it.Next() { - } - count := 0 - for it.Prev() { - count++ - index := it.Index() - value := it.Value() - switch index { - case 0: - if actualValue, expectedValue := value, 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 1: - if actualValue, expectedValue := value, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - case 2: - if actualValue, expectedValue := value, 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - t.Errorf("Too many") - } - if actualValue, expectedValue := index, 3-count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - if actualValue, expectedValue := count, 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBinaryHeapIteratorBegin(t *testing.T) { - heap := NewWithIntComparator() - it := heap.Iterator() - it.Begin() - heap.Push(2) - heap.Push(3) - heap.Push(1) - for it.Next() { - } - it.Begin() - it.Next() - if index, value := it.Index(), it.Value(); index != 0 || value != 1 { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, 1) - } -} - -func TestListIteratorEnd(t *testing.T) { - heap := NewWithIntComparator() - it := heap.Iterator() - - if index := it.Index(); index != -1 { - t.Errorf("Got %v expected %v", index, -1) - } - - it.End() - if index := it.Index(); index != 0 { - t.Errorf("Got %v expected %v", index, 0) - } - - heap.Push(3) // [3] - heap.Push(2) // [2,3] - heap.Push(1) // [1,3,2](2 swapped with 1, hence last) - it.End() - if index := it.Index(); index != heap.Size() { - t.Errorf("Got %v expected %v", index, heap.Size()) - } - - it.Prev() - if index, value := it.Index(), it.Value(); index != heap.Size()-1 || value != 2 { - t.Errorf("Got %v,%v expected %v,%v", index, value, heap.Size()-1, 2) - } -} - -func TestStackIteratorFirst(t *testing.T) { - heap := NewWithIntComparator() - it := heap.Iterator() - if actualValue, expectedValue := it.First(), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - heap.Push(3) // [3] - heap.Push(2) // [2,3] - heap.Push(1) // [1,3,2](2 swapped with 1, hence last) - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 0 || value != 1 { - t.Errorf("Got %v,%v expected %v,%v", index, value, 0, 1) - } -} - -func TestBinaryHeapIteratorLast(t *testing.T) { - tree := NewWithIntComparator() - it := tree.Iterator() - if actualValue, expectedValue := it.Last(), false; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - tree.Push(2) - tree.Push(3) - tree.Push(1) // [1,3,2](2 swapped with 1, hence last) - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if index, value := it.Index(), it.Value(); index != 2 || value != 2 { - t.Errorf("Got %v,%v expected %v,%v", index, value, 2, 2) - } -} - -func TestBinaryHeapSerialization(t *testing.T) { - heap := NewWithStringComparator() - - heap.Push("c") // ["c"] - heap.Push("b") // ["b","c"] - heap.Push("a") // ["a","c","b"]("b" swapped with "a", hence last) - - var err error - assert := func() { - if actualValue := heap.Values(); actualValue[0].(string) != "a" || actualValue[1].(string) != "c" || actualValue[2].(string) != "b" { - t.Errorf("Got %v expected %v", actualValue, "[1,3,2]") - } - if actualValue := heap.Size(); actualValue != 3 { - t.Errorf("Got %v expected %v", actualValue, 3) - } - if actualValue, ok := heap.Peek(); actualValue != "a" || !ok { - t.Errorf("Got %v expected %v", actualValue, "a") - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := heap.ToJSON() - assert() - - err = heap.FromJSON(json) - assert() -} - -func benchmarkPush(b *testing.B, heap *Heap, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - heap.Push(n) - } - } -} - -func benchmarkPop(b *testing.B, heap *Heap, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - heap.Pop() - } - } -} - -func BenchmarkBinaryHeapPop100(b *testing.B) { - b.StopTimer() - size := 100 - heap := NewWithIntComparator() - for n := 0; n < size; n++ { - heap.Push(n) - } - b.StartTimer() - benchmarkPop(b, heap, size) -} - -func BenchmarkBinaryHeapPop1000(b *testing.B) { - b.StopTimer() - size := 1000 - heap := NewWithIntComparator() - for n := 0; n < size; n++ { - heap.Push(n) - } - b.StartTimer() - benchmarkPop(b, heap, size) -} - -func BenchmarkBinaryHeapPop10000(b *testing.B) { - b.StopTimer() - size := 10000 - heap := NewWithIntComparator() - for n := 0; n < size; n++ { - heap.Push(n) - } - b.StartTimer() - benchmarkPop(b, heap, size) -} - -func BenchmarkBinaryHeapPop100000(b *testing.B) { - b.StopTimer() - size := 100000 - heap := NewWithIntComparator() - for n := 0; n < size; n++ { - heap.Push(n) - } - b.StartTimer() - benchmarkPop(b, heap, size) -} - -func BenchmarkBinaryHeapPush100(b *testing.B) { - b.StopTimer() - size := 100 - heap := NewWithIntComparator() - b.StartTimer() - benchmarkPush(b, heap, size) -} - -func BenchmarkBinaryHeapPush1000(b *testing.B) { - b.StopTimer() - size := 1000 - heap := NewWithIntComparator() - for n := 0; n < size; n++ { - heap.Push(n) - } - b.StartTimer() - benchmarkPush(b, heap, size) -} - -func BenchmarkBinaryHeapPush10000(b *testing.B) { - b.StopTimer() - size := 10000 - heap := NewWithIntComparator() - for n := 0; n < size; n++ { - heap.Push(n) - } - b.StartTimer() - benchmarkPush(b, heap, size) -} - -func BenchmarkBinaryHeapPush100000(b *testing.B) { - b.StopTimer() - size := 100000 - heap := NewWithIntComparator() - for n := 0; n < size; n++ { - heap.Push(n) - } - b.StartTimer() - benchmarkPush(b, heap, size) -} diff --git a/vendor/github.com/emirpasic/gods/trees/binaryheap/iterator.go b/vendor/github.com/emirpasic/gods/trees/binaryheap/iterator.go deleted file mode 100644 index beeb8d701..000000000 --- a/vendor/github.com/emirpasic/gods/trees/binaryheap/iterator.go +++ /dev/null @@ -1,84 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package binaryheap - -import "github.com/emirpasic/gods/containers" - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithIndex = (*Iterator)(nil) -} - -// Iterator returns a stateful iterator whose values can be fetched by an index. -type Iterator struct { - heap *Heap - index int -} - -// Iterator returns a stateful iterator whose values can be fetched by an index. -func (heap *Heap) Iterator() Iterator { - return Iterator{heap: heap, index: -1} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's index and value can be retrieved by Index() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - if iterator.index < iterator.heap.Size() { - iterator.index++ - } - return iterator.heap.withinRange(iterator.index) -} - -// Prev moves the iterator to the previous element and returns true if there was a previous element in the container. -// If Prev() returns true, then previous element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - if iterator.index >= 0 { - iterator.index-- - } - return iterator.heap.withinRange(iterator.index) -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - value, _ := iterator.heap.list.Get(iterator.index) - return value -} - -// Index returns the current element's index. -// Does not modify the state of the iterator. -func (iterator *Iterator) Index() int { - return iterator.index -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.index = -1 -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.index = iterator.heap.Size() -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) First() bool { - iterator.Begin() - return iterator.Next() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's index and value can be retrieved by Index() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - iterator.End() - return iterator.Prev() -} diff --git a/vendor/github.com/emirpasic/gods/trees/binaryheap/serialization.go b/vendor/github.com/emirpasic/gods/trees/binaryheap/serialization.go deleted file mode 100644 index 00d0c7719..000000000 --- a/vendor/github.com/emirpasic/gods/trees/binaryheap/serialization.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package binaryheap - -import "github.com/emirpasic/gods/containers" - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Heap)(nil) - var _ containers.JSONDeserializer = (*Heap)(nil) -} - -// ToJSON outputs the JSON representation of the heap. -func (heap *Heap) ToJSON() ([]byte, error) { - return heap.list.ToJSON() -} - -// FromJSON populates the heap from the input JSON representation. -func (heap *Heap) FromJSON(data []byte) error { - return heap.list.FromJSON(data) -} diff --git a/vendor/github.com/emirpasic/gods/trees/btree/btree.go b/vendor/github.com/emirpasic/gods/trees/btree/btree.go deleted file mode 100644 index 5f866997c..000000000 --- a/vendor/github.com/emirpasic/gods/trees/btree/btree.go +++ /dev/null @@ -1,577 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package btree implements a B tree. -// -// According to Knuth's definition, a B-tree of order m is a tree which satisfies the following properties: -// - Every node has at most m children. -// - Every non-leaf node (except root) has at least ⌈m/2⌉ children. -// - The root has at least two children if it is not a leaf node. -// - A non-leaf node with k children contains k−1 keys. -// - All leaves appear in the same level -// -// Structure is not thread safe. -// -// References: https://en.wikipedia.org/wiki/B-tree -package btree - -import ( - "bytes" - "fmt" - "github.com/emirpasic/gods/trees" - "github.com/emirpasic/gods/utils" - "strings" -) - -func assertTreeImplementation() { - var _ trees.Tree = (*Tree)(nil) -} - -// Tree holds elements of the B-tree -type Tree struct { - Root *Node // Root node - Comparator utils.Comparator // Key comparator - size int // Total number of keys in the tree - m int // order (maximum number of children) -} - -// Node is a single element within the tree -type Node struct { - Parent *Node - Entries []*Entry // Contained keys in node - Children []*Node // Children nodes -} - -// Entry represents the key-value pair contained within nodes -type Entry struct { - Key interface{} - Value interface{} -} - -// NewWith instantiates a B-tree with the order (maximum number of children) and a custom key comparator. -func NewWith(order int, comparator utils.Comparator) *Tree { - if order < 3 { - panic("Invalid order, should be at least 3") - } - return &Tree{m: order, Comparator: comparator} -} - -// NewWithIntComparator instantiates a B-tree with the order (maximum number of children) and the IntComparator, i.e. keys are of type int. -func NewWithIntComparator(order int) *Tree { - return NewWith(order, utils.IntComparator) -} - -// NewWithStringComparator instantiates a B-tree with the order (maximum number of children) and the StringComparator, i.e. keys are of type string. -func NewWithStringComparator(order int) *Tree { - return NewWith(order, utils.StringComparator) -} - -// Put inserts key-value pair node into the tree. -// If key already exists, then its value is updated with the new value. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (tree *Tree) Put(key interface{}, value interface{}) { - entry := &Entry{Key: key, Value: value} - - if tree.Root == nil { - tree.Root = &Node{Entries: []*Entry{entry}, Children: []*Node{}} - tree.size++ - return - } - - if tree.insert(tree.Root, entry) { - tree.size++ - } -} - -// Get searches the node in the tree by key and returns its value or nil if key is not found in tree. -// Second return parameter is true if key was found, otherwise false. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (tree *Tree) Get(key interface{}) (value interface{}, found bool) { - node, index, found := tree.searchRecursively(tree.Root, key) - if found { - return node.Entries[index].Value, true - } - return nil, false -} - -// Remove remove the node from the tree by key. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (tree *Tree) Remove(key interface{}) { - node, index, found := tree.searchRecursively(tree.Root, key) - if found { - tree.delete(node, index) - tree.size-- - } -} - -// Empty returns true if tree does not contain any nodes -func (tree *Tree) Empty() bool { - return tree.size == 0 -} - -// Size returns number of nodes in the tree. -func (tree *Tree) Size() int { - return tree.size -} - -// Keys returns all keys in-order -func (tree *Tree) Keys() []interface{} { - keys := make([]interface{}, tree.size) - it := tree.Iterator() - for i := 0; it.Next(); i++ { - keys[i] = it.Key() - } - return keys -} - -// Values returns all values in-order based on the key. -func (tree *Tree) Values() []interface{} { - values := make([]interface{}, tree.size) - it := tree.Iterator() - for i := 0; it.Next(); i++ { - values[i] = it.Value() - } - return values -} - -// Clear removes all nodes from the tree. -func (tree *Tree) Clear() { - tree.Root = nil - tree.size = 0 -} - -// Height returns the height of the tree. -func (tree *Tree) Height() int { - return tree.Root.height() -} - -// Left returns the left-most (min) node or nil if tree is empty. -func (tree *Tree) Left() *Node { - return tree.left(tree.Root) -} - -// LeftKey returns the left-most (min) key or nil if tree is empty. -func (tree *Tree) LeftKey() interface{} { - if left := tree.Left(); left != nil { - return left.Entries[0].Key - } - return nil -} - -// LeftValue returns the left-most value or nil if tree is empty. -func (tree *Tree) LeftValue() interface{} { - if left := tree.Left(); left != nil { - return left.Entries[0].Value - } - return nil -} - -// Right returns the right-most (max) node or nil if tree is empty. -func (tree *Tree) Right() *Node { - return tree.right(tree.Root) -} - -// RightKey returns the right-most (max) key or nil if tree is empty. -func (tree *Tree) RightKey() interface{} { - if right := tree.Right(); right != nil { - return right.Entries[len(right.Entries)-1].Key - } - return nil -} - -// RightValue returns the right-most value or nil if tree is empty. -func (tree *Tree) RightValue() interface{} { - if right := tree.Right(); right != nil { - return right.Entries[len(right.Entries)-1].Value - } - return nil -} - -// String returns a string representation of container (for debugging purposes) -func (tree *Tree) String() string { - var buffer bytes.Buffer - if _, err := buffer.WriteString("BTree\n"); err != nil { - } - if !tree.Empty() { - tree.output(&buffer, tree.Root, 0, true) - } - return buffer.String() -} - -func (entry *Entry) String() string { - return fmt.Sprintf("%v", entry.Key) -} - -func (tree *Tree) output(buffer *bytes.Buffer, node *Node, level int, isTail bool) { - for e := 0; e < len(node.Entries)+1; e++ { - if e < len(node.Children) { - tree.output(buffer, node.Children[e], level+1, true) - } - if e < len(node.Entries) { - if _, err := buffer.WriteString(strings.Repeat(" ", level)); err != nil { - } - if _, err := buffer.WriteString(fmt.Sprintf("%v", node.Entries[e].Key) + "\n"); err != nil { - } - } - } -} - -func (node *Node) height() int { - height := 0 - for ; node != nil; node = node.Children[0] { - height++ - if len(node.Children) == 0 { - break - } - } - return height -} - -func (tree *Tree) isLeaf(node *Node) bool { - return len(node.Children) == 0 -} - -func (tree *Tree) isFull(node *Node) bool { - return len(node.Entries) == tree.maxEntries() -} - -func (tree *Tree) shouldSplit(node *Node) bool { - return len(node.Entries) > tree.maxEntries() -} - -func (tree *Tree) maxChildren() int { - return tree.m -} - -func (tree *Tree) minChildren() int { - return (tree.m + 1) / 2 // ceil(m/2) -} - -func (tree *Tree) maxEntries() int { - return tree.maxChildren() - 1 -} - -func (tree *Tree) minEntries() int { - return tree.minChildren() - 1 -} - -func (tree *Tree) middle() int { - return (tree.m - 1) / 2 // "-1" to favor right nodes to have more keys when splitting -} - -// search searches only within the single node among its entries -func (tree *Tree) search(node *Node, key interface{}) (index int, found bool) { - low, high := 0, len(node.Entries)-1 - var mid int - for low <= high { - mid = (high + low) / 2 - compare := tree.Comparator(key, node.Entries[mid].Key) - switch { - case compare > 0: - low = mid + 1 - case compare < 0: - high = mid - 1 - case compare == 0: - return mid, true - } - } - return low, false -} - -// searchRecursively searches recursively down the tree starting at the startNode -func (tree *Tree) searchRecursively(startNode *Node, key interface{}) (node *Node, index int, found bool) { - if tree.Empty() { - return nil, -1, false - } - node = startNode - for { - index, found = tree.search(node, key) - if found { - return node, index, true - } - if tree.isLeaf(node) { - return nil, -1, false - } - node = node.Children[index] - } -} - -func (tree *Tree) insert(node *Node, entry *Entry) (inserted bool) { - if tree.isLeaf(node) { - return tree.insertIntoLeaf(node, entry) - } - return tree.insertIntoInternal(node, entry) -} - -func (tree *Tree) insertIntoLeaf(node *Node, entry *Entry) (inserted bool) { - insertPosition, found := tree.search(node, entry.Key) - if found { - node.Entries[insertPosition] = entry - return false - } - // Insert entry's key in the middle of the node - node.Entries = append(node.Entries, nil) - copy(node.Entries[insertPosition+1:], node.Entries[insertPosition:]) - node.Entries[insertPosition] = entry - tree.split(node) - return true -} - -func (tree *Tree) insertIntoInternal(node *Node, entry *Entry) (inserted bool) { - insertPosition, found := tree.search(node, entry.Key) - if found { - node.Entries[insertPosition] = entry - return false - } - return tree.insert(node.Children[insertPosition], entry) -} - -func (tree *Tree) split(node *Node) { - if !tree.shouldSplit(node) { - return - } - - if node == tree.Root { - tree.splitRoot() - return - } - - tree.splitNonRoot(node) -} - -func (tree *Tree) splitNonRoot(node *Node) { - middle := tree.middle() - parent := node.Parent - - left := &Node{Entries: append([]*Entry(nil), node.Entries[:middle]...), Parent: parent} - right := &Node{Entries: append([]*Entry(nil), node.Entries[middle+1:]...), Parent: parent} - - // Move children from the node to be split into left and right nodes - if !tree.isLeaf(node) { - left.Children = append([]*Node(nil), node.Children[:middle+1]...) - right.Children = append([]*Node(nil), node.Children[middle+1:]...) - setParent(left.Children, left) - setParent(right.Children, right) - } - - insertPosition, _ := tree.search(parent, node.Entries[middle].Key) - - // Insert middle key into parent - parent.Entries = append(parent.Entries, nil) - copy(parent.Entries[insertPosition+1:], parent.Entries[insertPosition:]) - parent.Entries[insertPosition] = node.Entries[middle] - - // Set child left of inserted key in parent to the created left node - parent.Children[insertPosition] = left - - // Set child right of inserted key in parent to the created right node - parent.Children = append(parent.Children, nil) - copy(parent.Children[insertPosition+2:], parent.Children[insertPosition+1:]) - parent.Children[insertPosition+1] = right - - tree.split(parent) -} - -func (tree *Tree) splitRoot() { - middle := tree.middle() - - left := &Node{Entries: append([]*Entry(nil), tree.Root.Entries[:middle]...)} - right := &Node{Entries: append([]*Entry(nil), tree.Root.Entries[middle+1:]...)} - - // Move children from the node to be split into left and right nodes - if !tree.isLeaf(tree.Root) { - left.Children = append([]*Node(nil), tree.Root.Children[:middle+1]...) - right.Children = append([]*Node(nil), tree.Root.Children[middle+1:]...) - setParent(left.Children, left) - setParent(right.Children, right) - } - - // Root is a node with one entry and two children (left and right) - newRoot := &Node{ - Entries: []*Entry{tree.Root.Entries[middle]}, - Children: []*Node{left, right}, - } - - left.Parent = newRoot - right.Parent = newRoot - tree.Root = newRoot -} - -func setParent(nodes []*Node, parent *Node) { - for _, node := range nodes { - node.Parent = parent - } -} - -func (tree *Tree) left(node *Node) *Node { - if tree.Empty() { - return nil - } - current := node - for { - if tree.isLeaf(current) { - return current - } - current = current.Children[0] - } -} - -func (tree *Tree) right(node *Node) *Node { - if tree.Empty() { - return nil - } - current := node - for { - if tree.isLeaf(current) { - return current - } - current = current.Children[len(current.Children)-1] - } -} - -// leftSibling returns the node's left sibling and child index (in parent) if it exists, otherwise (nil,-1) -// key is any of keys in node (could even be deleted). -func (tree *Tree) leftSibling(node *Node, key interface{}) (*Node, int) { - if node.Parent != nil { - index, _ := tree.search(node.Parent, key) - index-- - if index >= 0 && index < len(node.Parent.Children) { - return node.Parent.Children[index], index - } - } - return nil, -1 -} - -// rightSibling returns the node's right sibling and child index (in parent) if it exists, otherwise (nil,-1) -// key is any of keys in node (could even be deleted). -func (tree *Tree) rightSibling(node *Node, key interface{}) (*Node, int) { - if node.Parent != nil { - index, _ := tree.search(node.Parent, key) - index++ - if index < len(node.Parent.Children) { - return node.Parent.Children[index], index - } - } - return nil, -1 -} - -// delete deletes an entry in node at entries' index -// ref.: https://en.wikipedia.org/wiki/B-tree#Deletion -func (tree *Tree) delete(node *Node, index int) { - // deleting from a leaf node - if tree.isLeaf(node) { - deletedKey := node.Entries[index].Key - tree.deleteEntry(node, index) - tree.rebalance(node, deletedKey) - if len(tree.Root.Entries) == 0 { - tree.Root = nil - } - return - } - - // deleting from an internal node - leftLargestNode := tree.right(node.Children[index]) // largest node in the left sub-tree (assumed to exist) - leftLargestEntryIndex := len(leftLargestNode.Entries) - 1 - node.Entries[index] = leftLargestNode.Entries[leftLargestEntryIndex] - deletedKey := leftLargestNode.Entries[leftLargestEntryIndex].Key - tree.deleteEntry(leftLargestNode, leftLargestEntryIndex) - tree.rebalance(leftLargestNode, deletedKey) -} - -// rebalance rebalances the tree after deletion if necessary and returns true, otherwise false. -// Note that we first delete the entry and then call rebalance, thus the passed deleted key as reference. -func (tree *Tree) rebalance(node *Node, deletedKey interface{}) { - // check if rebalancing is needed - if node == nil || len(node.Entries) >= tree.minEntries() { - return - } - - // try to borrow from left sibling - leftSibling, leftSiblingIndex := tree.leftSibling(node, deletedKey) - if leftSibling != nil && len(leftSibling.Entries) > tree.minEntries() { - // rotate right - node.Entries = append([]*Entry{node.Parent.Entries[leftSiblingIndex]}, node.Entries...) // prepend parent's separator entry to node's entries - node.Parent.Entries[leftSiblingIndex] = leftSibling.Entries[len(leftSibling.Entries)-1] - tree.deleteEntry(leftSibling, len(leftSibling.Entries)-1) - if !tree.isLeaf(leftSibling) { - leftSiblingRightMostChild := leftSibling.Children[len(leftSibling.Children)-1] - leftSiblingRightMostChild.Parent = node - node.Children = append([]*Node{leftSiblingRightMostChild}, node.Children...) - tree.deleteChild(leftSibling, len(leftSibling.Children)-1) - } - return - } - - // try to borrow from right sibling - rightSibling, rightSiblingIndex := tree.rightSibling(node, deletedKey) - if rightSibling != nil && len(rightSibling.Entries) > tree.minEntries() { - // rotate left - node.Entries = append(node.Entries, node.Parent.Entries[rightSiblingIndex-1]) // append parent's separator entry to node's entries - node.Parent.Entries[rightSiblingIndex-1] = rightSibling.Entries[0] - tree.deleteEntry(rightSibling, 0) - if !tree.isLeaf(rightSibling) { - rightSiblingLeftMostChild := rightSibling.Children[0] - rightSiblingLeftMostChild.Parent = node - node.Children = append(node.Children, rightSiblingLeftMostChild) - tree.deleteChild(rightSibling, 0) - } - return - } - - // merge with siblings - if rightSibling != nil { - // merge with right sibling - node.Entries = append(node.Entries, node.Parent.Entries[rightSiblingIndex-1]) - node.Entries = append(node.Entries, rightSibling.Entries...) - deletedKey = node.Parent.Entries[rightSiblingIndex-1].Key - tree.deleteEntry(node.Parent, rightSiblingIndex-1) - tree.appendChildren(node.Parent.Children[rightSiblingIndex], node) - tree.deleteChild(node.Parent, rightSiblingIndex) - } else if leftSibling != nil { - // merge with left sibling - entries := append([]*Entry(nil), leftSibling.Entries...) - entries = append(entries, node.Parent.Entries[leftSiblingIndex]) - node.Entries = append(entries, node.Entries...) - deletedKey = node.Parent.Entries[leftSiblingIndex].Key - tree.deleteEntry(node.Parent, leftSiblingIndex) - tree.prependChildren(node.Parent.Children[leftSiblingIndex], node) - tree.deleteChild(node.Parent, leftSiblingIndex) - } - - // make the merged node the root if its parent was the root and the root is empty - if node.Parent == tree.Root && len(tree.Root.Entries) == 0 { - tree.Root = node - node.Parent = nil - return - } - - // parent might underflow, so try to rebalance if necessary - tree.rebalance(node.Parent, deletedKey) -} - -func (tree *Tree) prependChildren(fromNode *Node, toNode *Node) { - children := append([]*Node(nil), fromNode.Children...) - toNode.Children = append(children, toNode.Children...) - setParent(fromNode.Children, toNode) -} - -func (tree *Tree) appendChildren(fromNode *Node, toNode *Node) { - toNode.Children = append(toNode.Children, fromNode.Children...) - setParent(fromNode.Children, toNode) -} - -func (tree *Tree) deleteEntry(node *Node, index int) { - copy(node.Entries[index:], node.Entries[index+1:]) - node.Entries[len(node.Entries)-1] = nil - node.Entries = node.Entries[:len(node.Entries)-1] -} - -func (tree *Tree) deleteChild(node *Node, index int) { - if index >= len(node.Children) { - return - } - copy(node.Children[index:], node.Children[index+1:]) - node.Children[len(node.Children)-1] = nil - node.Children = node.Children[:len(node.Children)-1] -} diff --git a/vendor/github.com/emirpasic/gods/trees/btree/btree_test.go b/vendor/github.com/emirpasic/gods/trees/btree/btree_test.go deleted file mode 100644 index 4d69665b2..000000000 --- a/vendor/github.com/emirpasic/gods/trees/btree/btree_test.go +++ /dev/null @@ -1,1259 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package btree - -import ( - "fmt" - "testing" -) - -func TestBTreeGet1(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(1, "a") - tree.Put(2, "b") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - - tests := [][]interface{}{ - {0, nil, false}, - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {8, nil, false}, - } - - for _, test := range tests { - if value, found := tree.Get(test[0]); value != test[1] || found != test[2] { - t.Errorf("Got %v,%v expected %v,%v", value, found, test[1], test[2]) - } - } -} - -func TestBTreeGet2(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(7, "g") - tree.Put(9, "i") - tree.Put(10, "j") - tree.Put(6, "f") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(5, "e") - tree.Put(8, "h") - tree.Put(2, "b") - tree.Put(1, "a") - - tests := [][]interface{}{ - {0, nil, false}, - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {8, "h", true}, - {9, "i", true}, - {10, "j", true}, - {11, nil, false}, - } - - for _, test := range tests { - if value, found := tree.Get(test[0]); value != test[1] || found != test[2] { - t.Errorf("Got %v,%v expected %v,%v", value, found, test[1], test[2]) - } - } -} - -func TestBTreePut1(t *testing.T) { - // https://upload.wikimedia.org/wikipedia/commons/3/33/B_tree_insertion_example.png - tree := NewWithIntComparator(3) - assertValidTree(t, tree, 0) - - tree.Put(1, 0) - assertValidTree(t, tree, 1) - assertValidTreeNode(t, tree.Root, 1, 0, []int{1}, false) - - tree.Put(2, 1) - assertValidTree(t, tree, 2) - assertValidTreeNode(t, tree.Root, 2, 0, []int{1, 2}, false) - - tree.Put(3, 2) - assertValidTree(t, tree, 3) - assertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true) - - tree.Put(4, 2) - assertValidTree(t, tree, 4) - assertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{3, 4}, true) - - tree.Put(5, 2) - assertValidTree(t, tree, 5) - assertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true) - assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{5}, true) - - tree.Put(6, 2) - assertValidTree(t, tree, 6) - assertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true) - assertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{5, 6}, true) - - tree.Put(7, 2) - assertValidTree(t, tree, 7) - assertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true) -} - -func TestBTreePut2(t *testing.T) { - tree := NewWithIntComparator(4) - assertValidTree(t, tree, 0) - - tree.Put(0, 0) - assertValidTree(t, tree, 1) - assertValidTreeNode(t, tree.Root, 1, 0, []int{0}, false) - - tree.Put(2, 2) - assertValidTree(t, tree, 2) - assertValidTreeNode(t, tree.Root, 2, 0, []int{0, 2}, false) - - tree.Put(1, 1) - assertValidTree(t, tree, 3) - assertValidTreeNode(t, tree.Root, 3, 0, []int{0, 1, 2}, false) - - tree.Put(1, 1) - assertValidTree(t, tree, 3) - assertValidTreeNode(t, tree.Root, 3, 0, []int{0, 1, 2}, false) - - tree.Put(3, 3) - assertValidTree(t, tree, 4) - assertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true) - assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{2, 3}, true) - - tree.Put(4, 4) - assertValidTree(t, tree, 5) - assertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true) - assertValidTreeNode(t, tree.Root.Children[1], 3, 0, []int{2, 3, 4}, true) - - tree.Put(5, 5) - assertValidTree(t, tree, 6) - assertValidTreeNode(t, tree.Root, 2, 3, []int{1, 3}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{4, 5}, true) -} - -func TestBTreePut3(t *testing.T) { - // http://www.geeksforgeeks.org/b-tree-set-1-insert-2/ - tree := NewWithIntComparator(6) - assertValidTree(t, tree, 0) - - tree.Put(10, 0) - assertValidTree(t, tree, 1) - assertValidTreeNode(t, tree.Root, 1, 0, []int{10}, false) - - tree.Put(20, 1) - assertValidTree(t, tree, 2) - assertValidTreeNode(t, tree.Root, 2, 0, []int{10, 20}, false) - - tree.Put(30, 2) - assertValidTree(t, tree, 3) - assertValidTreeNode(t, tree.Root, 3, 0, []int{10, 20, 30}, false) - - tree.Put(40, 3) - assertValidTree(t, tree, 4) - assertValidTreeNode(t, tree.Root, 4, 0, []int{10, 20, 30, 40}, false) - - tree.Put(50, 4) - assertValidTree(t, tree, 5) - assertValidTreeNode(t, tree.Root, 5, 0, []int{10, 20, 30, 40, 50}, false) - - tree.Put(60, 5) - assertValidTree(t, tree, 6) - assertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true) - assertValidTreeNode(t, tree.Root.Children[1], 3, 0, []int{40, 50, 60}, true) - - tree.Put(70, 6) - assertValidTree(t, tree, 7) - assertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true) - assertValidTreeNode(t, tree.Root.Children[1], 4, 0, []int{40, 50, 60, 70}, true) - - tree.Put(80, 7) - assertValidTree(t, tree, 8) - assertValidTreeNode(t, tree.Root, 1, 2, []int{30}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true) - assertValidTreeNode(t, tree.Root.Children[1], 5, 0, []int{40, 50, 60, 70, 80}, true) - - tree.Put(90, 8) - assertValidTree(t, tree, 9) - assertValidTreeNode(t, tree.Root, 2, 3, []int{30, 60}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{10, 20}, true) - assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{40, 50}, true) - assertValidTreeNode(t, tree.Root.Children[2], 3, 0, []int{70, 80, 90}, true) -} - -func TestBTreePut4(t *testing.T) { - tree := NewWithIntComparator(3) - assertValidTree(t, tree, 0) - - tree.Put(6, nil) - assertValidTree(t, tree, 1) - assertValidTreeNode(t, tree.Root, 1, 0, []int{6}, false) - - tree.Put(5, nil) - assertValidTree(t, tree, 2) - assertValidTreeNode(t, tree.Root, 2, 0, []int{5, 6}, false) - - tree.Put(4, nil) - assertValidTree(t, tree, 3) - assertValidTreeNode(t, tree.Root, 1, 2, []int{5}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{4}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{6}, true) - - tree.Put(3, nil) - assertValidTree(t, tree, 4) - assertValidTreeNode(t, tree.Root, 1, 2, []int{5}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{3, 4}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{6}, true) - - tree.Put(2, nil) - assertValidTree(t, tree, 5) - assertValidTreeNode(t, tree.Root, 2, 3, []int{3, 5}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true) - assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{6}, true) - - tree.Put(1, nil) - assertValidTree(t, tree, 6) - assertValidTreeNode(t, tree.Root, 2, 3, []int{3, 5}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{1, 2}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true) - assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{6}, true) - - tree.Put(0, nil) - assertValidTree(t, tree, 7) - assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{0}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true) - - tree.Put(-1, nil) - assertValidTree(t, tree, 8) - assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[0], 2, 0, []int{-1, 0}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true) - - tree.Put(-2, nil) - assertValidTree(t, tree, 9) - assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 3, []int{-1, 1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{-2}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{0}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[2], 1, 0, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true) - - tree.Put(-3, nil) - assertValidTree(t, tree, 10) - assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 3, []int{-1, 1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[0], 2, 0, []int{-3, -2}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{0}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[2], 1, 0, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{4}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{6}, true) - - tree.Put(-4, nil) - assertValidTree(t, tree, 11) - assertValidTreeNode(t, tree.Root, 2, 3, []int{-1, 3}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{-3}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[2], 1, 2, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{-4}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{-2}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{0}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[2].Children[0], 1, 0, []int{4}, true) - assertValidTreeNode(t, tree.Root.Children[2].Children[1], 1, 0, []int{6}, true) -} - -func TestBTreeRemove1(t *testing.T) { - // empty - tree := NewWithIntComparator(3) - tree.Remove(1) - assertValidTree(t, tree, 0) -} - -func TestBTreeRemove2(t *testing.T) { - // leaf node (no underflow) - tree := NewWithIntComparator(3) - tree.Put(1, nil) - tree.Put(2, nil) - - tree.Remove(1) - assertValidTree(t, tree, 1) - assertValidTreeNode(t, tree.Root, 1, 0, []int{2}, false) - - tree.Remove(2) - assertValidTree(t, tree, 0) -} - -func TestBTreeRemove3(t *testing.T) { - // merge with right (underflow) - { - tree := NewWithIntComparator(3) - tree.Put(1, nil) - tree.Put(2, nil) - tree.Put(3, nil) - - tree.Remove(1) - assertValidTree(t, tree, 2) - assertValidTreeNode(t, tree.Root, 2, 0, []int{2, 3}, false) - } - // merge with left (underflow) - { - tree := NewWithIntComparator(3) - tree.Put(1, nil) - tree.Put(2, nil) - tree.Put(3, nil) - - tree.Remove(3) - assertValidTree(t, tree, 2) - assertValidTreeNode(t, tree.Root, 2, 0, []int{1, 2}, false) - } -} - -func TestBTreeRemove4(t *testing.T) { - // rotate left (underflow) - tree := NewWithIntComparator(3) - tree.Put(1, nil) - tree.Put(2, nil) - tree.Put(3, nil) - tree.Put(4, nil) - - assertValidTree(t, tree, 4) - assertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 2, 0, []int{3, 4}, true) - - tree.Remove(1) - assertValidTree(t, tree, 3) - assertValidTreeNode(t, tree.Root, 1, 2, []int{3}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{4}, true) -} - -func TestBTreeRemove5(t *testing.T) { - // rotate right (underflow) - tree := NewWithIntComparator(3) - tree.Put(1, nil) - tree.Put(2, nil) - tree.Put(3, nil) - tree.Put(0, nil) - - assertValidTree(t, tree, 4) - assertValidTreeNode(t, tree.Root, 1, 2, []int{2}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{0, 1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true) - - tree.Remove(3) - assertValidTree(t, tree, 3) - assertValidTreeNode(t, tree.Root, 1, 2, []int{1}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{0}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{2}, true) -} - -func TestBTreeRemove6(t *testing.T) { - // root height reduction after a series of underflows on right side - // use simulator: https://www.cs.usfca.edu/~galles/visualization/BTree.html - tree := NewWithIntComparator(3) - tree.Put(1, nil) - tree.Put(2, nil) - tree.Put(3, nil) - tree.Put(4, nil) - tree.Put(5, nil) - tree.Put(6, nil) - tree.Put(7, nil) - - assertValidTree(t, tree, 7) - assertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true) - - tree.Remove(7) - assertValidTree(t, tree, 6) - assertValidTreeNode(t, tree.Root, 2, 3, []int{2, 4}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{3}, true) - assertValidTreeNode(t, tree.Root.Children[2], 2, 0, []int{5, 6}, true) -} - -func TestBTreeRemove7(t *testing.T) { - // root height reduction after a series of underflows on left side - // use simulator: https://www.cs.usfca.edu/~galles/visualization/BTree.html - tree := NewWithIntComparator(3) - tree.Put(1, nil) - tree.Put(2, nil) - tree.Put(3, nil) - tree.Put(4, nil) - tree.Put(5, nil) - tree.Put(6, nil) - tree.Put(7, nil) - - assertValidTree(t, tree, 7) - assertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{6}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true) - - tree.Remove(1) // series of underflows - assertValidTree(t, tree, 6) - assertValidTreeNode(t, tree.Root, 2, 3, []int{4, 6}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{2, 3}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{7}, true) - - // clear all remaining - tree.Remove(2) - assertValidTree(t, tree, 5) - assertValidTreeNode(t, tree.Root, 2, 3, []int{4, 6}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{3}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[2], 1, 0, []int{7}, true) - - tree.Remove(3) - assertValidTree(t, tree, 4) - assertValidTreeNode(t, tree.Root, 1, 2, []int{6}, false) - assertValidTreeNode(t, tree.Root.Children[0], 2, 0, []int{4, 5}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{7}, true) - - tree.Remove(4) - assertValidTree(t, tree, 3) - assertValidTreeNode(t, tree.Root, 1, 2, []int{6}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 0, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 0, []int{7}, true) - - tree.Remove(5) - assertValidTree(t, tree, 2) - assertValidTreeNode(t, tree.Root, 2, 0, []int{6, 7}, false) - - tree.Remove(6) - assertValidTree(t, tree, 1) - assertValidTreeNode(t, tree.Root, 1, 0, []int{7}, false) - - tree.Remove(7) - assertValidTree(t, tree, 0) -} - -func TestBTreeRemove8(t *testing.T) { - // use simulator: https://www.cs.usfca.edu/~galles/visualization/BTree.html - tree := NewWithIntComparator(3) - tree.Put(1, nil) - tree.Put(2, nil) - tree.Put(3, nil) - tree.Put(4, nil) - tree.Put(5, nil) - tree.Put(6, nil) - tree.Put(7, nil) - tree.Put(8, nil) - tree.Put(9, nil) - - assertValidTree(t, tree, 9) - assertValidTreeNode(t, tree.Root, 1, 2, []int{4}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{2}, true) - assertValidTreeNode(t, tree.Root.Children[1], 2, 3, []int{6, 8}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[0], 1, 0, []int{1}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{3}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{7}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[2], 1, 0, []int{9}, true) - - tree.Remove(1) - assertValidTree(t, tree, 8) - assertValidTreeNode(t, tree.Root, 1, 2, []int{6}, false) - assertValidTreeNode(t, tree.Root.Children[0], 1, 2, []int{4}, true) - assertValidTreeNode(t, tree.Root.Children[1], 1, 2, []int{8}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[0], 2, 0, []int{2, 3}, true) - assertValidTreeNode(t, tree.Root.Children[0].Children[1], 1, 0, []int{5}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[0], 1, 0, []int{7}, true) - assertValidTreeNode(t, tree.Root.Children[1].Children[1], 1, 0, []int{9}, true) -} - -func TestBTreeRemove9(t *testing.T) { - const max = 1000 - orders := []int{3, 4, 5, 6, 7, 8, 9, 10, 20, 100, 500, 1000, 5000, 10000} - for _, order := range orders { - - tree := NewWithIntComparator(order) - - { - for i := 1; i <= max; i++ { - tree.Put(i, i) - } - assertValidTree(t, tree, max) - - for i := 1; i <= max; i++ { - if _, found := tree.Get(i); !found { - t.Errorf("Not found %v", i) - } - } - - for i := 1; i <= max; i++ { - tree.Remove(i) - } - assertValidTree(t, tree, 0) - } - - { - for i := max; i > 0; i-- { - tree.Put(i, i) - } - assertValidTree(t, tree, max) - - for i := max; i > 0; i-- { - if _, found := tree.Get(i); !found { - t.Errorf("Not found %v", i) - } - } - - for i := max; i > 0; i-- { - tree.Remove(i) - } - assertValidTree(t, tree, 0) - } - } -} - -func TestBTreeHeight(t *testing.T) { - tree := NewWithIntComparator(3) - if actualValue, expectedValue := tree.Height(), 0; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - tree.Put(1, 0) - if actualValue, expectedValue := tree.Height(), 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - tree.Put(2, 1) - if actualValue, expectedValue := tree.Height(), 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - tree.Put(3, 2) - if actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - tree.Put(4, 2) - if actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - tree.Put(5, 2) - if actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - tree.Put(6, 2) - if actualValue, expectedValue := tree.Height(), 2; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - tree.Put(7, 2) - if actualValue, expectedValue := tree.Height(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - tree.Remove(1) - tree.Remove(2) - tree.Remove(3) - tree.Remove(4) - tree.Remove(5) - tree.Remove(6) - tree.Remove(7) - if actualValue, expectedValue := tree.Height(), 0; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBTreeLeftAndRight(t *testing.T) { - tree := NewWithIntComparator(3) - - if actualValue := tree.Left(); actualValue != nil { - t.Errorf("Got %v expected %v", actualValue, nil) - } - if actualValue := tree.Right(); actualValue != nil { - t.Errorf("Got %v expected %v", actualValue, nil) - } - - tree.Put(1, "a") - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") // overwrite - tree.Put(2, "b") - - if actualValue, expectedValue := tree.LeftKey(), 1; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := tree.LeftValue(), "x"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - if actualValue, expectedValue := tree.RightKey(), 7; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := tree.RightValue(), "g"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBTreeIteratorValuesAndKeys(t *testing.T) { - tree := NewWithIntComparator(4) - tree.Put(4, "d") - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(7, "g") - tree.Put(2, "b") - tree.Put(1, "x") // override - if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d%d%d%d", tree.Keys()...), "1234567"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s%s%s%s", tree.Values()...), "xbcdefg"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := tree.Size(); actualValue != 7 { - t.Errorf("Got %v expected %v", actualValue, 7) - } -} - -func TestBTreeIteratorNextOnEmpty(t *testing.T) { - tree := NewWithIntComparator(3) - it := tree.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty tree") - } -} - -func TestBTreeIteratorPrevOnEmpty(t *testing.T) { - tree := NewWithIntComparator(3) - it := tree.Iterator() - for it.Prev() { - t.Errorf("Shouldn't iterate on empty tree") - } -} - -func TestBTreeIterator1Next(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - tree.Put(1, "a") //overwrite - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - switch key { - case count: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBTreeIterator1Prev(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - tree.Put(1, "a") //overwrite - it := tree.Iterator() - for it.Next() { - } - countDown := tree.size - for it.Prev() { - key := it.Key() - switch key { - case countDown: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBTreeIterator2Next(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - switch key { - case count: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBTreeIterator2Prev(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - for it.Next() { - } - countDown := tree.size - for it.Prev() { - key := it.Key() - switch key { - case countDown: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBTreeIterator3Next(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(1, "a") - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - switch key { - case count: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBTreeIterator3Prev(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(1, "a") - it := tree.Iterator() - for it.Next() { - } - countDown := tree.size - for it.Prev() { - key := it.Key() - switch key { - case countDown: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBTreeIterator4Next(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(13, 5) - tree.Put(8, 3) - tree.Put(17, 7) - tree.Put(1, 1) - tree.Put(11, 4) - tree.Put(15, 6) - tree.Put(25, 9) - tree.Put(6, 2) - tree.Put(22, 8) - tree.Put(27, 10) - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - value := it.Value() - switch value { - case count: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBTreeIterator4Prev(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(13, 5) - tree.Put(8, 3) - tree.Put(17, 7) - tree.Put(1, 1) - tree.Put(11, 4) - tree.Put(15, 6) - tree.Put(25, 9) - tree.Put(6, 2) - tree.Put(22, 8) - tree.Put(27, 10) - it := tree.Iterator() - count := tree.Size() - for it.Next() { - } - for it.Prev() { - value := it.Value() - switch value { - case count: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - count-- - } - if actualValue, expectedValue := count, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestBTreeIteratorBegin(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - it.Begin() - - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - for it.Next() { - } - - it.Begin() - - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - it.Next() - if key, value := it.Key(), it.Value(); key != 1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a") - } -} - -func TestBTreeIteratorEnd(t *testing.T) { - tree := NewWithIntComparator(3) - it := tree.Iterator() - - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - it.End() - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it.End() - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - it.Prev() - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestBTreeIteratorFirst(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a") - } -} - -func TestBTreeIteratorLast(t *testing.T) { - tree := NewWithIntComparator(3) - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestBTree_search(t *testing.T) { - { - tree := NewWithIntComparator(3) - tree.Root = &Node{Entries: []*Entry{}, Children: make([]*Node, 0)} - tests := [][]interface{}{ - {0, 0, false}, - } - for _, test := range tests { - index, found := tree.search(tree.Root, test[0]) - if actualValue, expectedValue := index, test[1]; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := found, test[2]; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - { - tree := NewWithIntComparator(3) - tree.Root = &Node{Entries: []*Entry{{2, 0}, {4, 1}, {6, 2}}, Children: []*Node{}} - tests := [][]interface{}{ - {0, 0, false}, - {1, 0, false}, - {2, 0, true}, - {3, 1, false}, - {4, 1, true}, - {5, 2, false}, - {6, 2, true}, - {7, 3, false}, - } - for _, test := range tests { - index, found := tree.search(tree.Root, test[0]) - if actualValue, expectedValue := index, test[1]; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := found, test[2]; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } -} - -func assertValidTree(t *testing.T, tree *Tree, expectedSize int) { - if actualValue, expectedValue := tree.size, expectedSize; actualValue != expectedValue { - t.Errorf("Got %v expected %v for tree size", actualValue, expectedValue) - } -} - -func assertValidTreeNode(t *testing.T, node *Node, expectedEntries int, expectedChildren int, keys []int, hasParent bool) { - if actualValue, expectedValue := node.Parent != nil, hasParent; actualValue != expectedValue { - t.Errorf("Got %v expected %v for hasParent", actualValue, expectedValue) - } - if actualValue, expectedValue := len(node.Entries), expectedEntries; actualValue != expectedValue { - t.Errorf("Got %v expected %v for entries size", actualValue, expectedValue) - } - if actualValue, expectedValue := len(node.Children), expectedChildren; actualValue != expectedValue { - t.Errorf("Got %v expected %v for children size", actualValue, expectedValue) - } - for i, key := range keys { - if actualValue, expectedValue := node.Entries[i].Key, key; actualValue != expectedValue { - t.Errorf("Got %v expected %v for key", actualValue, expectedValue) - } - } -} - -func TestBTreeSerialization(t *testing.T) { - tree := NewWithStringComparator(3) - tree.Put("c", "3") - tree.Put("b", "2") - tree.Put("a", "1") - - var err error - assert := func() { - if actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := tree.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" { - t.Errorf("Got %v expected %v", actualValue, "[a,b,c]") - } - if actualValue := tree.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" { - t.Errorf("Got %v expected %v", actualValue, "[1,2,3]") - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := tree.ToJSON() - assert() - - err = tree.FromJSON(json) - assert() -} - -func benchmarkGet(b *testing.B, tree *Tree, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - tree.Get(n) - } - } -} - -func benchmarkPut(b *testing.B, tree *Tree, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - } -} - -func benchmarkRemove(b *testing.B, tree *Tree, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - tree.Remove(n) - } - } -} - -func BenchmarkBTreeGet100(b *testing.B) { - b.StopTimer() - size := 100 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkBTreeGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkBTreeGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkBTreeGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkBTreePut100(b *testing.B) { - b.StopTimer() - size := 100 - tree := NewWithIntComparator(128) - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkBTreePut1000(b *testing.B) { - b.StopTimer() - size := 1000 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkBTreePut10000(b *testing.B) { - b.StopTimer() - size := 10000 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkBTreePut100000(b *testing.B) { - b.StopTimer() - size := 100000 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkBTreeRemove100(b *testing.B) { - b.StopTimer() - size := 100 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} - -func BenchmarkBTreeRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} - -func BenchmarkBTreeRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} - -func BenchmarkBTreeRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - tree := NewWithIntComparator(128) - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} diff --git a/vendor/github.com/emirpasic/gods/trees/btree/iterator.go b/vendor/github.com/emirpasic/gods/trees/btree/iterator.go deleted file mode 100644 index 840db6871..000000000 --- a/vendor/github.com/emirpasic/gods/trees/btree/iterator.go +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package btree - -import "github.com/emirpasic/gods/containers" - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithKey = (*Iterator)(nil) -} - -// Iterator holding the iterator's state -type Iterator struct { - tree *Tree - node *Node - entry *Entry - position position -} - -type position byte - -const ( - begin, between, end position = 0, 1, 2 -) - -// Iterator returns a stateful iterator whose elements are key/value pairs. -func (tree *Tree) Iterator() Iterator { - return Iterator{tree: tree, node: nil, position: begin} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's key and value can be retrieved by Key() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - // If already at end, go to end - if iterator.position == end { - goto end - } - // If at beginning, get the left-most entry in the tree - if iterator.position == begin { - left := iterator.tree.Left() - if left == nil { - goto end - } - iterator.node = left - iterator.entry = left.Entries[0] - goto between - } - { - // Find current entry position in current node - e, _ := iterator.tree.search(iterator.node, iterator.entry.Key) - // Try to go down to the child right of the current entry - if e+1 < len(iterator.node.Children) { - iterator.node = iterator.node.Children[e+1] - // Try to go down to the child left of the current node - for len(iterator.node.Children) > 0 { - iterator.node = iterator.node.Children[0] - } - // Return the left-most entry - iterator.entry = iterator.node.Entries[0] - goto between - } - // Above assures that we have reached a leaf node, so return the next entry in current node (if any) - if e+1 < len(iterator.node.Entries) { - iterator.entry = iterator.node.Entries[e+1] - goto between - } - } - // Reached leaf node and there are no entries to the right of the current entry, so go up to the parent - for iterator.node.Parent != nil { - iterator.node = iterator.node.Parent - // Find next entry position in current node (note: search returns the first equal or bigger than entry) - e, _ := iterator.tree.search(iterator.node, iterator.entry.Key) - // Check that there is a next entry position in current node - if e < len(iterator.node.Entries) { - iterator.entry = iterator.node.Entries[e] - goto between - } - } - -end: - iterator.End() - return false - -between: - iterator.position = between - return true -} - -// Prev moves the iterator to the previous element and returns true if there was a previous element in the container. -// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - // If already at beginning, go to begin - if iterator.position == begin { - goto begin - } - // If at end, get the right-most entry in the tree - if iterator.position == end { - right := iterator.tree.Right() - if right == nil { - goto begin - } - iterator.node = right - iterator.entry = right.Entries[len(right.Entries)-1] - goto between - } - { - // Find current entry position in current node - e, _ := iterator.tree.search(iterator.node, iterator.entry.Key) - // Try to go down to the child left of the current entry - if e < len(iterator.node.Children) { - iterator.node = iterator.node.Children[e] - // Try to go down to the child right of the current node - for len(iterator.node.Children) > 0 { - iterator.node = iterator.node.Children[len(iterator.node.Children)-1] - } - // Return the right-most entry - iterator.entry = iterator.node.Entries[len(iterator.node.Entries)-1] - goto between - } - // Above assures that we have reached a leaf node, so return the previous entry in current node (if any) - if e-1 >= 0 { - iterator.entry = iterator.node.Entries[e-1] - goto between - } - } - // Reached leaf node and there are no entries to the left of the current entry, so go up to the parent - for iterator.node.Parent != nil { - iterator.node = iterator.node.Parent - // Find previous entry position in current node (note: search returns the first equal or bigger than entry) - e, _ := iterator.tree.search(iterator.node, iterator.entry.Key) - // Check that there is a previous entry position in current node - if e-1 >= 0 { - iterator.entry = iterator.node.Entries[e-1] - goto between - } - } - -begin: - iterator.Begin() - return false - -between: - iterator.position = between - return true -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - return iterator.entry.Value -} - -// Key returns the current element's key. -// Does not modify the state of the iterator. -func (iterator *Iterator) Key() interface{} { - return iterator.entry.Key -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.node = nil - iterator.position = begin - iterator.entry = nil -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.node = nil - iterator.position = end - iterator.entry = nil -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator -func (iterator *Iterator) First() bool { - iterator.Begin() - return iterator.Next() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - iterator.End() - return iterator.Prev() -} diff --git a/vendor/github.com/emirpasic/gods/trees/btree/serialization.go b/vendor/github.com/emirpasic/gods/trees/btree/serialization.go deleted file mode 100644 index 43851676d..000000000 --- a/vendor/github.com/emirpasic/gods/trees/btree/serialization.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package btree - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" - "github.com/emirpasic/gods/utils" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Tree)(nil) - var _ containers.JSONDeserializer = (*Tree)(nil) -} - -// ToJSON outputs the JSON representation of the tree. -func (tree *Tree) ToJSON() ([]byte, error) { - elements := make(map[string]interface{}) - it := tree.Iterator() - for it.Next() { - elements[utils.ToString(it.Key())] = it.Value() - } - return json.Marshal(&elements) -} - -// FromJSON populates the tree from the input JSON representation. -func (tree *Tree) FromJSON(data []byte) error { - elements := make(map[string]interface{}) - err := json.Unmarshal(data, &elements) - if err == nil { - tree.Clear() - for key, value := range elements { - tree.Put(key, value) - } - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/trees/redblacktree/iterator.go b/vendor/github.com/emirpasic/gods/trees/redblacktree/iterator.go deleted file mode 100644 index 9cde5e430..000000000 --- a/vendor/github.com/emirpasic/gods/trees/redblacktree/iterator.go +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package redblacktree - -import "github.com/emirpasic/gods/containers" - -func assertIteratorImplementation() { - var _ containers.ReverseIteratorWithKey = (*Iterator)(nil) -} - -// Iterator holding the iterator's state -type Iterator struct { - tree *Tree - node *Node - position position -} - -type position byte - -const ( - begin, between, end position = 0, 1, 2 -) - -// Iterator returns a stateful iterator whose elements are key/value pairs. -func (tree *Tree) Iterator() Iterator { - return Iterator{tree: tree, node: nil, position: begin} -} - -// IteratorAt returns a stateful iterator whose elements are key/value pairs that is initialised at a particular node. -func (tree *Tree) IteratorAt(node *Node) Iterator { - return Iterator{tree: tree, node: node, position: between} -} - -// Next moves the iterator to the next element and returns true if there was a next element in the container. -// If Next() returns true, then next element's key and value can be retrieved by Key() and Value(). -// If Next() was called for the first time, then it will point the iterator to the first element if it exists. -// Modifies the state of the iterator. -func (iterator *Iterator) Next() bool { - if iterator.position == end { - goto end - } - if iterator.position == begin { - left := iterator.tree.Left() - if left == nil { - goto end - } - iterator.node = left - goto between - } - if iterator.node.Right != nil { - iterator.node = iterator.node.Right - for iterator.node.Left != nil { - iterator.node = iterator.node.Left - } - goto between - } - if iterator.node.Parent != nil { - node := iterator.node - for iterator.node.Parent != nil { - iterator.node = iterator.node.Parent - if iterator.tree.Comparator(node.Key, iterator.node.Key) <= 0 { - goto between - } - } - } - -end: - iterator.node = nil - iterator.position = end - return false - -between: - iterator.position = between - return true -} - -// Prev moves the iterator to the previous element and returns true if there was a previous element in the container. -// If Prev() returns true, then previous element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Prev() bool { - if iterator.position == begin { - goto begin - } - if iterator.position == end { - right := iterator.tree.Right() - if right == nil { - goto begin - } - iterator.node = right - goto between - } - if iterator.node.Left != nil { - iterator.node = iterator.node.Left - for iterator.node.Right != nil { - iterator.node = iterator.node.Right - } - goto between - } - if iterator.node.Parent != nil { - node := iterator.node - for iterator.node.Parent != nil { - iterator.node = iterator.node.Parent - if iterator.tree.Comparator(node.Key, iterator.node.Key) >= 0 { - goto between - } - } - } - -begin: - iterator.node = nil - iterator.position = begin - return false - -between: - iterator.position = between - return true -} - -// Value returns the current element's value. -// Does not modify the state of the iterator. -func (iterator *Iterator) Value() interface{} { - return iterator.node.Value -} - -// Key returns the current element's key. -// Does not modify the state of the iterator. -func (iterator *Iterator) Key() interface{} { - return iterator.node.Key -} - -// Begin resets the iterator to its initial state (one-before-first) -// Call Next() to fetch the first element if any. -func (iterator *Iterator) Begin() { - iterator.node = nil - iterator.position = begin -} - -// End moves the iterator past the last element (one-past-the-end). -// Call Prev() to fetch the last element if any. -func (iterator *Iterator) End() { - iterator.node = nil - iterator.position = end -} - -// First moves the iterator to the first element and returns true if there was a first element in the container. -// If First() returns true, then first element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator -func (iterator *Iterator) First() bool { - iterator.Begin() - return iterator.Next() -} - -// Last moves the iterator to the last element and returns true if there was a last element in the container. -// If Last() returns true, then last element's key and value can be retrieved by Key() and Value(). -// Modifies the state of the iterator. -func (iterator *Iterator) Last() bool { - iterator.End() - return iterator.Prev() -} diff --git a/vendor/github.com/emirpasic/gods/trees/redblacktree/redblacktree.go b/vendor/github.com/emirpasic/gods/trees/redblacktree/redblacktree.go deleted file mode 100644 index 8301ffd7b..000000000 --- a/vendor/github.com/emirpasic/gods/trees/redblacktree/redblacktree.go +++ /dev/null @@ -1,527 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package redblacktree implements a red-black tree. -// -// Used by TreeSet and TreeMap. -// -// Structure is not thread safe. -// -// References: http://en.wikipedia.org/wiki/Red%E2%80%93black_tree -package redblacktree - -import ( - "fmt" - "github.com/emirpasic/gods/trees" - "github.com/emirpasic/gods/utils" -) - -func assertTreeImplementation() { - var _ trees.Tree = (*Tree)(nil) -} - -type color bool - -const ( - black, red color = true, false -) - -// Tree holds elements of the red-black tree -type Tree struct { - Root *Node - size int - Comparator utils.Comparator -} - -// Node is a single element within the tree -type Node struct { - Key interface{} - Value interface{} - color color - Left *Node - Right *Node - Parent *Node -} - -// NewWith instantiates a red-black tree with the custom comparator. -func NewWith(comparator utils.Comparator) *Tree { - return &Tree{Comparator: comparator} -} - -// NewWithIntComparator instantiates a red-black tree with the IntComparator, i.e. keys are of type int. -func NewWithIntComparator() *Tree { - return &Tree{Comparator: utils.IntComparator} -} - -// NewWithStringComparator instantiates a red-black tree with the StringComparator, i.e. keys are of type string. -func NewWithStringComparator() *Tree { - return &Tree{Comparator: utils.StringComparator} -} - -// Put inserts node into the tree. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (tree *Tree) Put(key interface{}, value interface{}) { - var insertedNode *Node - if tree.Root == nil { - // Assert key is of comparator's type for initial tree - tree.Comparator(key, key) - tree.Root = &Node{Key: key, Value: value, color: red} - insertedNode = tree.Root - } else { - node := tree.Root - loop := true - for loop { - compare := tree.Comparator(key, node.Key) - switch { - case compare == 0: - node.Key = key - node.Value = value - return - case compare < 0: - if node.Left == nil { - node.Left = &Node{Key: key, Value: value, color: red} - insertedNode = node.Left - loop = false - } else { - node = node.Left - } - case compare > 0: - if node.Right == nil { - node.Right = &Node{Key: key, Value: value, color: red} - insertedNode = node.Right - loop = false - } else { - node = node.Right - } - } - } - insertedNode.Parent = node - } - tree.insertCase1(insertedNode) - tree.size++ -} - -// Get searches the node in the tree by key and returns its value or nil if key is not found in tree. -// Second return parameter is true if key was found, otherwise false. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (tree *Tree) Get(key interface{}) (value interface{}, found bool) { - node := tree.lookup(key) - if node != nil { - return node.Value, true - } - return nil, false -} - -// Remove remove the node from the tree by key. -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (tree *Tree) Remove(key interface{}) { - var child *Node - node := tree.lookup(key) - if node == nil { - return - } - if node.Left != nil && node.Right != nil { - pred := node.Left.maximumNode() - node.Key = pred.Key - node.Value = pred.Value - node = pred - } - if node.Left == nil || node.Right == nil { - if node.Right == nil { - child = node.Left - } else { - child = node.Right - } - if node.color == black { - node.color = nodeColor(child) - tree.deleteCase1(node) - } - tree.replaceNode(node, child) - if node.Parent == nil && child != nil { - child.color = black - } - } - tree.size-- -} - -// Empty returns true if tree does not contain any nodes -func (tree *Tree) Empty() bool { - return tree.size == 0 -} - -// Size returns number of nodes in the tree. -func (tree *Tree) Size() int { - return tree.size -} - -// Keys returns all keys in-order -func (tree *Tree) Keys() []interface{} { - keys := make([]interface{}, tree.size) - it := tree.Iterator() - for i := 0; it.Next(); i++ { - keys[i] = it.Key() - } - return keys -} - -// Values returns all values in-order based on the key. -func (tree *Tree) Values() []interface{} { - values := make([]interface{}, tree.size) - it := tree.Iterator() - for i := 0; it.Next(); i++ { - values[i] = it.Value() - } - return values -} - -// Left returns the left-most (min) node or nil if tree is empty. -func (tree *Tree) Left() *Node { - var parent *Node - current := tree.Root - for current != nil { - parent = current - current = current.Left - } - return parent -} - -// Right returns the right-most (max) node or nil if tree is empty. -func (tree *Tree) Right() *Node { - var parent *Node - current := tree.Root - for current != nil { - parent = current - current = current.Right - } - return parent -} - -// Floor Finds floor node of the input key, return the floor node or nil if no floor is found. -// Second return parameter is true if floor was found, otherwise false. -// -// Floor node is defined as the largest node that is smaller than or equal to the given node. -// A floor node may not be found, either because the tree is empty, or because -// all nodes in the tree are larger than the given node. -// -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (tree *Tree) Floor(key interface{}) (floor *Node, found bool) { - found = false - node := tree.Root - for node != nil { - compare := tree.Comparator(key, node.Key) - switch { - case compare == 0: - return node, true - case compare < 0: - node = node.Left - case compare > 0: - floor, found = node, true - node = node.Right - } - } - if found { - return floor, true - } - return nil, false -} - -// Ceiling finds ceiling node of the input key, return the ceiling node or nil if no ceiling is found. -// Second return parameter is true if ceiling was found, otherwise false. -// -// Ceiling node is defined as the smallest node that is larger than or equal to the given node. -// A ceiling node may not be found, either because the tree is empty, or because -// all nodes in the tree are smaller than the given node. -// -// Key should adhere to the comparator's type assertion, otherwise method panics. -func (tree *Tree) Ceiling(key interface{}) (ceiling *Node, found bool) { - found = false - node := tree.Root - for node != nil { - compare := tree.Comparator(key, node.Key) - switch { - case compare == 0: - return node, true - case compare < 0: - ceiling, found = node, true - node = node.Left - case compare > 0: - node = node.Right - } - } - if found { - return ceiling, true - } - return nil, false -} - -// Clear removes all nodes from the tree. -func (tree *Tree) Clear() { - tree.Root = nil - tree.size = 0 -} - -// String returns a string representation of container -func (tree *Tree) String() string { - str := "RedBlackTree\n" - if !tree.Empty() { - output(tree.Root, "", true, &str) - } - return str -} - -func (node *Node) String() string { - return fmt.Sprintf("%v", node.Key) -} - -func output(node *Node, prefix string, isTail bool, str *string) { - if node.Right != nil { - newPrefix := prefix - if isTail { - newPrefix += "│ " - } else { - newPrefix += " " - } - output(node.Right, newPrefix, false, str) - } - *str += prefix - if isTail { - *str += "└── " - } else { - *str += "┌── " - } - *str += node.String() + "\n" - if node.Left != nil { - newPrefix := prefix - if isTail { - newPrefix += " " - } else { - newPrefix += "│ " - } - output(node.Left, newPrefix, true, str) - } -} - -func (tree *Tree) lookup(key interface{}) *Node { - node := tree.Root - for node != nil { - compare := tree.Comparator(key, node.Key) - switch { - case compare == 0: - return node - case compare < 0: - node = node.Left - case compare > 0: - node = node.Right - } - } - return nil -} - -func (node *Node) grandparent() *Node { - if node != nil && node.Parent != nil { - return node.Parent.Parent - } - return nil -} - -func (node *Node) uncle() *Node { - if node == nil || node.Parent == nil || node.Parent.Parent == nil { - return nil - } - return node.Parent.sibling() -} - -func (node *Node) sibling() *Node { - if node == nil || node.Parent == nil { - return nil - } - if node == node.Parent.Left { - return node.Parent.Right - } - return node.Parent.Left -} - -func (tree *Tree) rotateLeft(node *Node) { - right := node.Right - tree.replaceNode(node, right) - node.Right = right.Left - if right.Left != nil { - right.Left.Parent = node - } - right.Left = node - node.Parent = right -} - -func (tree *Tree) rotateRight(node *Node) { - left := node.Left - tree.replaceNode(node, left) - node.Left = left.Right - if left.Right != nil { - left.Right.Parent = node - } - left.Right = node - node.Parent = left -} - -func (tree *Tree) replaceNode(old *Node, new *Node) { - if old.Parent == nil { - tree.Root = new - } else { - if old == old.Parent.Left { - old.Parent.Left = new - } else { - old.Parent.Right = new - } - } - if new != nil { - new.Parent = old.Parent - } -} - -func (tree *Tree) insertCase1(node *Node) { - if node.Parent == nil { - node.color = black - } else { - tree.insertCase2(node) - } -} - -func (tree *Tree) insertCase2(node *Node) { - if nodeColor(node.Parent) == black { - return - } - tree.insertCase3(node) -} - -func (tree *Tree) insertCase3(node *Node) { - uncle := node.uncle() - if nodeColor(uncle) == red { - node.Parent.color = black - uncle.color = black - node.grandparent().color = red - tree.insertCase1(node.grandparent()) - } else { - tree.insertCase4(node) - } -} - -func (tree *Tree) insertCase4(node *Node) { - grandparent := node.grandparent() - if node == node.Parent.Right && node.Parent == grandparent.Left { - tree.rotateLeft(node.Parent) - node = node.Left - } else if node == node.Parent.Left && node.Parent == grandparent.Right { - tree.rotateRight(node.Parent) - node = node.Right - } - tree.insertCase5(node) -} - -func (tree *Tree) insertCase5(node *Node) { - node.Parent.color = black - grandparent := node.grandparent() - grandparent.color = red - if node == node.Parent.Left && node.Parent == grandparent.Left { - tree.rotateRight(grandparent) - } else if node == node.Parent.Right && node.Parent == grandparent.Right { - tree.rotateLeft(grandparent) - } -} - -func (node *Node) maximumNode() *Node { - if node == nil { - return nil - } - for node.Right != nil { - node = node.Right - } - return node -} - -func (tree *Tree) deleteCase1(node *Node) { - if node.Parent == nil { - return - } - tree.deleteCase2(node) -} - -func (tree *Tree) deleteCase2(node *Node) { - sibling := node.sibling() - if nodeColor(sibling) == red { - node.Parent.color = red - sibling.color = black - if node == node.Parent.Left { - tree.rotateLeft(node.Parent) - } else { - tree.rotateRight(node.Parent) - } - } - tree.deleteCase3(node) -} - -func (tree *Tree) deleteCase3(node *Node) { - sibling := node.sibling() - if nodeColor(node.Parent) == black && - nodeColor(sibling) == black && - nodeColor(sibling.Left) == black && - nodeColor(sibling.Right) == black { - sibling.color = red - tree.deleteCase1(node.Parent) - } else { - tree.deleteCase4(node) - } -} - -func (tree *Tree) deleteCase4(node *Node) { - sibling := node.sibling() - if nodeColor(node.Parent) == red && - nodeColor(sibling) == black && - nodeColor(sibling.Left) == black && - nodeColor(sibling.Right) == black { - sibling.color = red - node.Parent.color = black - } else { - tree.deleteCase5(node) - } -} - -func (tree *Tree) deleteCase5(node *Node) { - sibling := node.sibling() - if node == node.Parent.Left && - nodeColor(sibling) == black && - nodeColor(sibling.Left) == red && - nodeColor(sibling.Right) == black { - sibling.color = red - sibling.Left.color = black - tree.rotateRight(sibling) - } else if node == node.Parent.Right && - nodeColor(sibling) == black && - nodeColor(sibling.Right) == red && - nodeColor(sibling.Left) == black { - sibling.color = red - sibling.Right.color = black - tree.rotateLeft(sibling) - } - tree.deleteCase6(node) -} - -func (tree *Tree) deleteCase6(node *Node) { - sibling := node.sibling() - sibling.color = nodeColor(node.Parent) - node.Parent.color = black - if node == node.Parent.Left && nodeColor(sibling.Right) == red { - sibling.Right.color = black - tree.rotateLeft(node.Parent) - } else if nodeColor(sibling.Left) == red { - sibling.Left.color = black - tree.rotateRight(node.Parent) - } -} - -func nodeColor(node *Node) color { - if node == nil { - return black - } - return node.color -} diff --git a/vendor/github.com/emirpasic/gods/trees/redblacktree/redblacktree_test.go b/vendor/github.com/emirpasic/gods/trees/redblacktree/redblacktree_test.go deleted file mode 100644 index 74c3d8a0d..000000000 --- a/vendor/github.com/emirpasic/gods/trees/redblacktree/redblacktree_test.go +++ /dev/null @@ -1,742 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package redblacktree - -import ( - "fmt" - "testing" -) - -func TestRedBlackTreePut(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - tree.Put(1, "a") //overwrite - - if actualValue := tree.Size(); actualValue != 7 { - t.Errorf("Got %v expected %v", actualValue, 7) - } - if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d%d%d%d", tree.Keys()...), "1234567"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s%s%s%s", tree.Values()...), "abcdefg"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - tests1 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, "e", true}, - {6, "f", true}, - {7, "g", true}, - {8, nil, false}, - } - - for _, test := range tests1 { - // retrievals - actualValue, actualFound := tree.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } -} - -func TestRedBlackTreeRemove(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - tree.Put(1, "a") //overwrite - - tree.Remove(5) - tree.Remove(6) - tree.Remove(7) - tree.Remove(8) - tree.Remove(5) - - if actualValue, expectedValue := fmt.Sprintf("%d%d%d%d", tree.Keys()...), "1234"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s%s%s%s", tree.Values()...), "abcd"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := tree.Size(); actualValue != 4 { - t.Errorf("Got %v expected %v", actualValue, 7) - } - - tests2 := [][]interface{}{ - {1, "a", true}, - {2, "b", true}, - {3, "c", true}, - {4, "d", true}, - {5, nil, false}, - {6, nil, false}, - {7, nil, false}, - {8, nil, false}, - } - - for _, test := range tests2 { - actualValue, actualFound := tree.Get(test[0]) - if actualValue != test[1] || actualFound != test[2] { - t.Errorf("Got %v expected %v", actualValue, test[1]) - } - } - - tree.Remove(1) - tree.Remove(4) - tree.Remove(2) - tree.Remove(3) - tree.Remove(2) - tree.Remove(2) - - if actualValue, expectedValue := fmt.Sprintf("%s", tree.Keys()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", tree.Values()), "[]"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if empty, size := tree.Empty(), tree.Size(); empty != true || size != -0 { - t.Errorf("Got %v expected %v", empty, true) - } - -} - -func TestRedBlackTreeLeftAndRight(t *testing.T) { - tree := NewWithIntComparator() - - if actualValue := tree.Left(); actualValue != nil { - t.Errorf("Got %v expected %v", actualValue, nil) - } - if actualValue := tree.Right(); actualValue != nil { - t.Errorf("Got %v expected %v", actualValue, nil) - } - - tree.Put(1, "a") - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") // overwrite - tree.Put(2, "b") - - if actualValue, expectedValue := fmt.Sprintf("%d", tree.Left().Key), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", tree.Left().Value), "x"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - if actualValue, expectedValue := fmt.Sprintf("%d", tree.Right().Key), "7"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue, expectedValue := fmt.Sprintf("%s", tree.Right().Value), "g"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestRedBlackTreeCeilingAndFloor(t *testing.T) { - tree := NewWithIntComparator() - - if node, found := tree.Floor(0); node != nil || found { - t.Errorf("Got %v expected %v", node, "") - } - if node, found := tree.Ceiling(0); node != nil || found { - t.Errorf("Got %v expected %v", node, "") - } - - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - - if node, found := tree.Floor(4); node.Key != 4 || !found { - t.Errorf("Got %v expected %v", node.Key, 4) - } - if node, found := tree.Floor(0); node != nil || found { - t.Errorf("Got %v expected %v", node, "") - } - - if node, found := tree.Ceiling(4); node.Key != 4 || !found { - t.Errorf("Got %v expected %v", node.Key, 4) - } - if node, found := tree.Ceiling(8); node != nil || found { - t.Errorf("Got %v expected %v", node, "") - } -} - -func TestRedBlackTreeIteratorNextOnEmpty(t *testing.T) { - tree := NewWithIntComparator() - it := tree.Iterator() - for it.Next() { - t.Errorf("Shouldn't iterate on empty tree") - } -} - -func TestRedBlackTreeIteratorPrevOnEmpty(t *testing.T) { - tree := NewWithIntComparator() - it := tree.Iterator() - for it.Prev() { - t.Errorf("Shouldn't iterate on empty tree") - } -} - -func TestRedBlackTreeIterator1Next(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - tree.Put(1, "a") //overwrite - // │ ┌── 7 - // └── 6 - // │ ┌── 5 - // └── 4 - // │ ┌── 3 - // └── 2 - // └── 1 - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - switch key { - case count: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestRedBlackTreeIterator1Prev(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(5, "e") - tree.Put(6, "f") - tree.Put(7, "g") - tree.Put(3, "c") - tree.Put(4, "d") - tree.Put(1, "x") - tree.Put(2, "b") - tree.Put(1, "a") //overwrite - // │ ┌── 7 - // └── 6 - // │ ┌── 5 - // └── 4 - // │ ┌── 3 - // └── 2 - // └── 1 - it := tree.Iterator() - for it.Next() { - } - countDown := tree.size - for it.Prev() { - key := it.Key() - switch key { - case countDown: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestRedBlackTreeIterator2Next(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - switch key { - case count: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestRedBlackTreeIterator2Prev(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - for it.Next() { - } - countDown := tree.size - for it.Prev() { - key := it.Key() - switch key { - case countDown: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestRedBlackTreeIterator3Next(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(1, "a") - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - key := it.Key() - switch key { - case count: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestRedBlackTreeIterator3Prev(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(1, "a") - it := tree.Iterator() - for it.Next() { - } - countDown := tree.size - for it.Prev() { - key := it.Key() - switch key { - case countDown: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := key, countDown; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - countDown-- - } - if actualValue, expectedValue := countDown, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestRedBlackTreeIterator4Next(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(13, 5) - tree.Put(8, 3) - tree.Put(17, 7) - tree.Put(1, 1) - tree.Put(11, 4) - tree.Put(15, 6) - tree.Put(25, 9) - tree.Put(6, 2) - tree.Put(22, 8) - tree.Put(27, 10) - // │ ┌── 27 - // │ ┌── 25 - // │ │ └── 22 - // │ ┌── 17 - // │ │ └── 15 - // └── 13 - // │ ┌── 11 - // └── 8 - // │ ┌── 6 - // └── 1 - it := tree.Iterator() - count := 0 - for it.Next() { - count++ - value := it.Value() - switch value { - case count: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - } - if actualValue, expectedValue := count, tree.Size(); actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestRedBlackTreeIterator4Prev(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(13, 5) - tree.Put(8, 3) - tree.Put(17, 7) - tree.Put(1, 1) - tree.Put(11, 4) - tree.Put(15, 6) - tree.Put(25, 9) - tree.Put(6, 2) - tree.Put(22, 8) - tree.Put(27, 10) - // │ ┌── 27 - // │ ┌── 25 - // │ │ └── 22 - // │ ┌── 17 - // │ │ └── 15 - // └── 13 - // │ ┌── 11 - // └── 8 - // │ ┌── 6 - // └── 1 - it := tree.Iterator() - count := tree.Size() - for it.Next() { - } - for it.Prev() { - value := it.Value() - switch value { - case count: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - default: - if actualValue, expectedValue := value, count; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - } - count-- - } - if actualValue, expectedValue := count, 0; actualValue != expectedValue { - t.Errorf("Size different. Got %v expected %v", actualValue, expectedValue) - } -} - -func TestRedBlackTreeIteratorBegin(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - it.Begin() - - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - for it.Next() { - } - - it.Begin() - - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - it.Next() - if key, value := it.Key(), it.Value(); key != 1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a") - } -} - -func TestRedBlackTreeIteratorEnd(t *testing.T) { - tree := NewWithIntComparator() - it := tree.Iterator() - - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - it.End() - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it.End() - if it.node != nil { - t.Errorf("Got %v expected %v", it.node, nil) - } - - it.Prev() - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestRedBlackTreeIteratorFirst(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - if actualValue, expectedValue := it.First(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 1 || value != "a" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 1, "a") - } -} - -func TestRedBlackTreeIteratorLast(t *testing.T) { - tree := NewWithIntComparator() - tree.Put(3, "c") - tree.Put(1, "a") - tree.Put(2, "b") - it := tree.Iterator() - if actualValue, expectedValue := it.Last(), true; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if key, value := it.Key(), it.Value(); key != 3 || value != "c" { - t.Errorf("Got %v,%v expected %v,%v", key, value, 3, "c") - } -} - -func TestRedBlackTreeSerialization(t *testing.T) { - tree := NewWithStringComparator() - tree.Put("c", "3") - tree.Put("b", "2") - tree.Put("a", "1") - - var err error - assert := func() { - if actualValue, expectedValue := tree.Size(), 3; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - if actualValue := tree.Keys(); actualValue[0].(string) != "a" || actualValue[1].(string) != "b" || actualValue[2].(string) != "c" { - t.Errorf("Got %v expected %v", actualValue, "[a,b,c]") - } - if actualValue := tree.Values(); actualValue[0].(string) != "1" || actualValue[1].(string) != "2" || actualValue[2].(string) != "3" { - t.Errorf("Got %v expected %v", actualValue, "[1,2,3]") - } - if err != nil { - t.Errorf("Got error %v", err) - } - } - - assert() - - json, err := tree.ToJSON() - assert() - - err = tree.FromJSON(json) - assert() -} - -func benchmarkGet(b *testing.B, tree *Tree, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - tree.Get(n) - } - } -} - -func benchmarkPut(b *testing.B, tree *Tree, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - } -} - -func benchmarkRemove(b *testing.B, tree *Tree, size int) { - for i := 0; i < b.N; i++ { - for n := 0; n < size; n++ { - tree.Remove(n) - } - } -} - -func BenchmarkRedBlackTreeGet100(b *testing.B) { - b.StopTimer() - size := 100 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkRedBlackTreeGet1000(b *testing.B) { - b.StopTimer() - size := 1000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkRedBlackTreeGet10000(b *testing.B) { - b.StopTimer() - size := 10000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkRedBlackTreeGet100000(b *testing.B) { - b.StopTimer() - size := 100000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkGet(b, tree, size) -} - -func BenchmarkRedBlackTreePut100(b *testing.B) { - b.StopTimer() - size := 100 - tree := NewWithIntComparator() - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkRedBlackTreePut1000(b *testing.B) { - b.StopTimer() - size := 1000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkRedBlackTreePut10000(b *testing.B) { - b.StopTimer() - size := 10000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkRedBlackTreePut100000(b *testing.B) { - b.StopTimer() - size := 100000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkPut(b, tree, size) -} - -func BenchmarkRedBlackTreeRemove100(b *testing.B) { - b.StopTimer() - size := 100 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} - -func BenchmarkRedBlackTreeRemove1000(b *testing.B) { - b.StopTimer() - size := 1000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} - -func BenchmarkRedBlackTreeRemove10000(b *testing.B) { - b.StopTimer() - size := 10000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} - -func BenchmarkRedBlackTreeRemove100000(b *testing.B) { - b.StopTimer() - size := 100000 - tree := NewWithIntComparator() - for n := 0; n < size; n++ { - tree.Put(n, struct{}{}) - } - b.StartTimer() - benchmarkRemove(b, tree, size) -} diff --git a/vendor/github.com/emirpasic/gods/trees/redblacktree/serialization.go b/vendor/github.com/emirpasic/gods/trees/redblacktree/serialization.go deleted file mode 100644 index a1b8a7796..000000000 --- a/vendor/github.com/emirpasic/gods/trees/redblacktree/serialization.go +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package redblacktree - -import ( - "encoding/json" - "github.com/emirpasic/gods/containers" - "github.com/emirpasic/gods/utils" -) - -func assertSerializationImplementation() { - var _ containers.JSONSerializer = (*Tree)(nil) - var _ containers.JSONDeserializer = (*Tree)(nil) -} - -// ToJSON outputs the JSON representation of the tree. -func (tree *Tree) ToJSON() ([]byte, error) { - elements := make(map[string]interface{}) - it := tree.Iterator() - for it.Next() { - elements[utils.ToString(it.Key())] = it.Value() - } - return json.Marshal(&elements) -} - -// FromJSON populates the tree from the input JSON representation. -func (tree *Tree) FromJSON(data []byte) error { - elements := make(map[string]interface{}) - err := json.Unmarshal(data, &elements) - if err == nil { - tree.Clear() - for key, value := range elements { - tree.Put(key, value) - } - } - return err -} diff --git a/vendor/github.com/emirpasic/gods/trees/trees.go b/vendor/github.com/emirpasic/gods/trees/trees.go deleted file mode 100644 index a5a7427d3..000000000 --- a/vendor/github.com/emirpasic/gods/trees/trees.go +++ /dev/null @@ -1,21 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// Package trees provides an abstract Tree interface. -// -// In computer science, a tree is a widely used abstract data type (ADT) or data structure implementing this ADT that simulates a hierarchical tree structure, with a root value and subtrees of children with a parent node, represented as a set of linked nodes. -// -// Reference: https://en.wikipedia.org/wiki/Tree_%28data_structure%29 -package trees - -import "github.com/emirpasic/gods/containers" - -// Tree interface that all trees implement -type Tree interface { - containers.Container - // Empty() bool - // Size() int - // Clear() - // Values() []interface{} -} diff --git a/vendor/github.com/emirpasic/gods/utils/comparator_test.go b/vendor/github.com/emirpasic/gods/utils/comparator_test.go deleted file mode 100644 index 40efbd375..000000000 --- a/vendor/github.com/emirpasic/gods/utils/comparator_test.go +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package utils - -import ( - "testing" - "time" -) - -func TestIntComparator(t *testing.T) { - - // i1,i2,expected - tests := [][]interface{}{ - {1, 1, 0}, - {1, 2, -1}, - {2, 1, 1}, - {11, 22, -1}, - {0, 0, 0}, - {1, 0, 1}, - {0, 1, -1}, - } - - for _, test := range tests { - actual := IntComparator(test[0], test[1]) - expected := test[2] - if actual != expected { - t.Errorf("Got %v expected %v", actual, expected) - } - } -} - -func TestStringComparator(t *testing.T) { - - // s1,s2,expected - tests := [][]interface{}{ - {"a", "a", 0}, - {"a", "b", -1}, - {"b", "a", 1}, - {"aa", "aab", -1}, - {"", "", 0}, - {"a", "", 1}, - {"", "a", -1}, - {"", "aaaaaaa", -1}, - } - - for _, test := range tests { - actual := StringComparator(test[0], test[1]) - expected := test[2] - if actual != expected { - t.Errorf("Got %v expected %v", actual, expected) - } - } -} - -func TestTimeComparator(t *testing.T) { - - now := time.Now() - - // i1,i2,expected - tests := [][]interface{}{ - {now, now, 0}, - {now.Add(24 * 7 * 2 * time.Hour), now, 1}, - {now, now.Add(24 * 7 * 2 * time.Hour), -1}, - } - - for _, test := range tests { - actual := TimeComparator(test[0], test[1]) - expected := test[2] - if actual != expected { - t.Errorf("Got %v expected %v", actual, expected) - } - } -} - -func TestCustomComparator(t *testing.T) { - - type Custom struct { - id int - name string - } - - byID := func(a, b interface{}) int { - c1 := a.(Custom) - c2 := b.(Custom) - switch { - case c1.id > c2.id: - return 1 - case c1.id < c2.id: - return -1 - default: - return 0 - } - } - - // o1,o2,expected - tests := [][]interface{}{ - {Custom{1, "a"}, Custom{1, "a"}, 0}, - {Custom{1, "a"}, Custom{2, "b"}, -1}, - {Custom{2, "b"}, Custom{1, "a"}, 1}, - {Custom{1, "a"}, Custom{1, "b"}, 0}, - } - - for _, test := range tests { - actual := byID(test[0], test[1]) - expected := test[2] - if actual != expected { - t.Errorf("Got %v expected %v", actual, expected) - } - } -} diff --git a/vendor/github.com/emirpasic/gods/utils/sort_test.go b/vendor/github.com/emirpasic/gods/utils/sort_test.go deleted file mode 100644 index 7831fc9bf..000000000 --- a/vendor/github.com/emirpasic/gods/utils/sort_test.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package utils - -import ( - "math/rand" - "testing" -) - -func TestSortInts(t *testing.T) { - ints := []interface{}{} - ints = append(ints, 4) - ints = append(ints, 1) - ints = append(ints, 2) - ints = append(ints, 3) - - Sort(ints, IntComparator) - - for i := 1; i < len(ints); i++ { - if ints[i-1].(int) > ints[i].(int) { - t.Errorf("Not sorted!") - } - } - -} - -func TestSortStrings(t *testing.T) { - - strings := []interface{}{} - strings = append(strings, "d") - strings = append(strings, "a") - strings = append(strings, "b") - strings = append(strings, "c") - - Sort(strings, StringComparator) - - for i := 1; i < len(strings); i++ { - if strings[i-1].(string) > strings[i].(string) { - t.Errorf("Not sorted!") - } - } -} - -func TestSortStructs(t *testing.T) { - type User struct { - id int - name string - } - - byID := func(a, b interface{}) int { - c1 := a.(User) - c2 := b.(User) - switch { - case c1.id > c2.id: - return 1 - case c1.id < c2.id: - return -1 - default: - return 0 - } - } - - // o1,o2,expected - users := []interface{}{ - User{4, "d"}, - User{1, "a"}, - User{3, "c"}, - User{2, "b"}, - } - - Sort(users, byID) - - for i := 1; i < len(users); i++ { - if users[i-1].(User).id > users[i].(User).id { - t.Errorf("Not sorted!") - } - } -} - -func TestSortRandom(t *testing.T) { - ints := []interface{}{} - for i := 0; i < 10000; i++ { - ints = append(ints, rand.Int()) - } - Sort(ints, IntComparator) - for i := 1; i < len(ints); i++ { - if ints[i-1].(int) > ints[i].(int) { - t.Errorf("Not sorted!") - } - } -} - -func BenchmarkGoSortRandom(b *testing.B) { - b.StopTimer() - ints := []interface{}{} - for i := 0; i < 100000; i++ { - ints = append(ints, rand.Int()) - } - b.StartTimer() - Sort(ints, IntComparator) - b.StopTimer() -} diff --git a/vendor/github.com/emirpasic/gods/utils/utils.go b/vendor/github.com/emirpasic/gods/utils/utils.go index d305a7c8d..1ad49cbc0 100644 --- a/vendor/github.com/emirpasic/gods/utils/utils.go +++ b/vendor/github.com/emirpasic/gods/utils/utils.go @@ -16,31 +16,31 @@ import ( // ToString converts a value to string. func ToString(value interface{}) string { - switch value := value.(type) { + switch value.(type) { case string: - return value + return value.(string) case int8: - return strconv.FormatInt(int64(value), 10) + return strconv.FormatInt(int64(value.(int8)), 10) case int16: - return strconv.FormatInt(int64(value), 10) + return strconv.FormatInt(int64(value.(int16)), 10) case int32: - return strconv.FormatInt(int64(value), 10) + return strconv.FormatInt(int64(value.(int32)), 10) case int64: - return strconv.FormatInt(int64(value), 10) + return strconv.FormatInt(int64(value.(int64)), 10) case uint8: - return strconv.FormatUint(uint64(value), 10) + return strconv.FormatUint(uint64(value.(uint8)), 10) case uint16: - return strconv.FormatUint(uint64(value), 10) + return strconv.FormatUint(uint64(value.(uint16)), 10) case uint32: - return strconv.FormatUint(uint64(value), 10) + return strconv.FormatUint(uint64(value.(uint32)), 10) case uint64: - return strconv.FormatUint(uint64(value), 10) + return strconv.FormatUint(uint64(value.(uint64)), 10) case float32: - return strconv.FormatFloat(float64(value), 'g', -1, 64) + return strconv.FormatFloat(float64(value.(float32)), 'g', -1, 64) case float64: - return strconv.FormatFloat(float64(value), 'g', -1, 64) + return strconv.FormatFloat(float64(value.(float64)), 'g', -1, 64) case bool: - return strconv.FormatBool(value) + return strconv.FormatBool(value.(bool)) default: return fmt.Sprintf("%+v", value) } diff --git a/vendor/github.com/emirpasic/gods/utils/utils_test.go b/vendor/github.com/emirpasic/gods/utils/utils_test.go deleted file mode 100644 index afbca1b91..000000000 --- a/vendor/github.com/emirpasic/gods/utils/utils_test.go +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright (c) 2015, Emir Pasic. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package utils - -import ( - "strings" - "testing" -) - -func TestToStringInts(t *testing.T) { - var value interface{} - - value = int8(1) - if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - value = int16(1) - if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - value = int32(1) - if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - value = int64(1) - if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - value = rune(1) - if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestToStringUInts(t *testing.T) { - var value interface{} - - value = uint8(1) - if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - value = uint16(1) - if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - value = uint32(1) - if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - value = uint64(1) - if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - value = byte(1) - if actualValue, expectedValue := ToString(value), "1"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestToStringFloats(t *testing.T) { - var value interface{} - - value = float32(1.123456) - if actualValue, expectedValue := ToString(value), "1.123456"; !strings.HasPrefix(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - value = float64(1.123456) - if actualValue, expectedValue := ToString(value), "1.123456"; !strings.HasPrefix(actualValue, expectedValue) { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} - -func TestToStringOther(t *testing.T) { - var value interface{} - - value = "abc" - if actualValue, expectedValue := ToString(value), "abc"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - value = true - if actualValue, expectedValue := ToString(value), "true"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } - - type T struct { - id int - name string - } - - if actualValue, expectedValue := ToString(T{1, "abc"}), "{id:1 name:abc}"; actualValue != expectedValue { - t.Errorf("Got %v expected %v", actualValue, expectedValue) - } -} diff --git a/vendor/github.com/golang/protobuf/jsonpb/decode.go b/vendor/github.com/golang/protobuf/jsonpb/decode.go new file mode 100644 index 000000000..7c6c5a524 --- /dev/null +++ b/vendor/github.com/golang/protobuf/jsonpb/decode.go @@ -0,0 +1,514 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jsonpb + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "math" + "reflect" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/encoding/protojson" + protoV2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" +) + +const wrapJSONUnmarshalV2 = false + +// UnmarshalNext unmarshals the next JSON object from d into m. +func UnmarshalNext(d *json.Decoder, m proto.Message) error { + return new(Unmarshaler).UnmarshalNext(d, m) +} + +// Unmarshal unmarshals a JSON object from r into m. +func Unmarshal(r io.Reader, m proto.Message) error { + return new(Unmarshaler).Unmarshal(r, m) +} + +// UnmarshalString unmarshals a JSON object from s into m. +func UnmarshalString(s string, m proto.Message) error { + return new(Unmarshaler).Unmarshal(strings.NewReader(s), m) +} + +// Unmarshaler is a configurable object for converting from a JSON +// representation to a protocol buffer object. +type Unmarshaler struct { + // AllowUnknownFields specifies whether to allow messages to contain + // unknown JSON fields, as opposed to failing to unmarshal. + AllowUnknownFields bool + + // AnyResolver is used to resolve the google.protobuf.Any well-known type. + // If unset, the global registry is used by default. + AnyResolver AnyResolver +} + +// JSONPBUnmarshaler is implemented by protobuf messages that customize the way +// they are unmarshaled from JSON. Messages that implement this should also +// implement JSONPBMarshaler so that the custom format can be produced. +// +// The JSON unmarshaling must follow the JSON to proto specification: +// https://developers.google.com/protocol-buffers/docs/proto3#json +// +// Deprecated: Custom types should implement protobuf reflection instead. +type JSONPBUnmarshaler interface { + UnmarshalJSONPB(*Unmarshaler, []byte) error +} + +// Unmarshal unmarshals a JSON object from r into m. +func (u *Unmarshaler) Unmarshal(r io.Reader, m proto.Message) error { + return u.UnmarshalNext(json.NewDecoder(r), m) +} + +// UnmarshalNext unmarshals the next JSON object from d into m. +func (u *Unmarshaler) UnmarshalNext(d *json.Decoder, m proto.Message) error { + if m == nil { + return errors.New("invalid nil message") + } + + // Parse the next JSON object from the stream. + raw := json.RawMessage{} + if err := d.Decode(&raw); err != nil { + return err + } + + // Check for custom unmarshalers first since they may not properly + // implement protobuf reflection that the logic below relies on. + if jsu, ok := m.(JSONPBUnmarshaler); ok { + return jsu.UnmarshalJSONPB(u, raw) + } + + mr := proto.MessageReflect(m) + + // NOTE: For historical reasons, a top-level null is treated as a noop. + // This is incorrect, but kept for compatibility. + if string(raw) == "null" && mr.Descriptor().FullName() != "google.protobuf.Value" { + return nil + } + + if wrapJSONUnmarshalV2 { + // NOTE: If input message is non-empty, we need to preserve merge semantics + // of the old jsonpb implementation. These semantics are not supported by + // the protobuf JSON specification. + isEmpty := true + mr.Range(func(protoreflect.FieldDescriptor, protoreflect.Value) bool { + isEmpty = false // at least one iteration implies non-empty + return false + }) + if !isEmpty { + // Perform unmarshaling into a newly allocated, empty message. + mr = mr.New() + + // Use a defer to copy all unmarshaled fields into the original message. + dst := proto.MessageReflect(m) + defer mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + dst.Set(fd, v) + return true + }) + } + + // Unmarshal using the v2 JSON unmarshaler. + opts := protojson.UnmarshalOptions{ + DiscardUnknown: u.AllowUnknownFields, + } + if u.AnyResolver != nil { + opts.Resolver = anyResolver{u.AnyResolver} + } + return opts.Unmarshal(raw, mr.Interface()) + } else { + if err := u.unmarshalMessage(mr, raw); err != nil { + return err + } + return protoV2.CheckInitialized(mr.Interface()) + } +} + +func (u *Unmarshaler) unmarshalMessage(m protoreflect.Message, in []byte) error { + md := m.Descriptor() + fds := md.Fields() + + if string(in) == "null" && md.FullName() != "google.protobuf.Value" { + return nil + } + + if jsu, ok := proto.MessageV1(m.Interface()).(JSONPBUnmarshaler); ok { + return jsu.UnmarshalJSONPB(u, in) + } + + switch wellKnownType(md.FullName()) { + case "Any": + var jsonObject map[string]json.RawMessage + if err := json.Unmarshal(in, &jsonObject); err != nil { + return err + } + + rawTypeURL, ok := jsonObject["@type"] + if !ok { + return errors.New("Any JSON doesn't have '@type'") + } + typeURL, err := unquoteString(string(rawTypeURL)) + if err != nil { + return fmt.Errorf("can't unmarshal Any's '@type': %q", rawTypeURL) + } + m.Set(fds.ByNumber(1), protoreflect.ValueOfString(typeURL)) + + var m2 protoreflect.Message + if u.AnyResolver != nil { + mi, err := u.AnyResolver.Resolve(typeURL) + if err != nil { + return err + } + m2 = proto.MessageReflect(mi) + } else { + mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL) + if err != nil { + if err == protoregistry.NotFound { + return fmt.Errorf("could not resolve Any message type: %v", typeURL) + } + return err + } + m2 = mt.New() + } + + if wellKnownType(m2.Descriptor().FullName()) != "" { + rawValue, ok := jsonObject["value"] + if !ok { + return errors.New("Any JSON doesn't have 'value'") + } + if err := u.unmarshalMessage(m2, rawValue); err != nil { + return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err) + } + } else { + delete(jsonObject, "@type") + rawJSON, err := json.Marshal(jsonObject) + if err != nil { + return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err) + } + if err = u.unmarshalMessage(m2, rawJSON); err != nil { + return fmt.Errorf("can't unmarshal Any nested proto %v: %v", typeURL, err) + } + } + + rawWire, err := protoV2.Marshal(m2.Interface()) + if err != nil { + return fmt.Errorf("can't marshal proto %v into Any.Value: %v", typeURL, err) + } + m.Set(fds.ByNumber(2), protoreflect.ValueOfBytes(rawWire)) + return nil + case "BoolValue", "BytesValue", "StringValue", + "Int32Value", "UInt32Value", "FloatValue", + "Int64Value", "UInt64Value", "DoubleValue": + fd := fds.ByNumber(1) + v, err := u.unmarshalValue(m.NewField(fd), in, fd) + if err != nil { + return err + } + m.Set(fd, v) + return nil + case "Duration": + v, err := unquoteString(string(in)) + if err != nil { + return err + } + d, err := time.ParseDuration(v) + if err != nil { + return fmt.Errorf("bad Duration: %v", err) + } + + sec := d.Nanoseconds() / 1e9 + nsec := d.Nanoseconds() % 1e9 + m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec))) + m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec))) + return nil + case "Timestamp": + v, err := unquoteString(string(in)) + if err != nil { + return err + } + t, err := time.Parse(time.RFC3339Nano, v) + if err != nil { + return fmt.Errorf("bad Timestamp: %v", err) + } + + sec := t.Unix() + nsec := t.Nanosecond() + m.Set(fds.ByNumber(1), protoreflect.ValueOfInt64(int64(sec))) + m.Set(fds.ByNumber(2), protoreflect.ValueOfInt32(int32(nsec))) + return nil + case "Value": + switch { + case string(in) == "null": + m.Set(fds.ByNumber(1), protoreflect.ValueOfEnum(0)) + case string(in) == "true": + m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(true)) + case string(in) == "false": + m.Set(fds.ByNumber(4), protoreflect.ValueOfBool(false)) + case hasPrefixAndSuffix('"', in, '"'): + s, err := unquoteString(string(in)) + if err != nil { + return fmt.Errorf("unrecognized type for Value %q", in) + } + m.Set(fds.ByNumber(3), protoreflect.ValueOfString(s)) + case hasPrefixAndSuffix('[', in, ']'): + v := m.Mutable(fds.ByNumber(6)) + return u.unmarshalMessage(v.Message(), in) + case hasPrefixAndSuffix('{', in, '}'): + v := m.Mutable(fds.ByNumber(5)) + return u.unmarshalMessage(v.Message(), in) + default: + f, err := strconv.ParseFloat(string(in), 0) + if err != nil { + return fmt.Errorf("unrecognized type for Value %q", in) + } + m.Set(fds.ByNumber(2), protoreflect.ValueOfFloat64(f)) + } + return nil + case "ListValue": + var jsonArray []json.RawMessage + if err := json.Unmarshal(in, &jsonArray); err != nil { + return fmt.Errorf("bad ListValue: %v", err) + } + + lv := m.Mutable(fds.ByNumber(1)).List() + for _, raw := range jsonArray { + ve := lv.NewElement() + if err := u.unmarshalMessage(ve.Message(), raw); err != nil { + return err + } + lv.Append(ve) + } + return nil + case "Struct": + var jsonObject map[string]json.RawMessage + if err := json.Unmarshal(in, &jsonObject); err != nil { + return fmt.Errorf("bad StructValue: %v", err) + } + + mv := m.Mutable(fds.ByNumber(1)).Map() + for key, raw := range jsonObject { + kv := protoreflect.ValueOf(key).MapKey() + vv := mv.NewValue() + if err := u.unmarshalMessage(vv.Message(), raw); err != nil { + return fmt.Errorf("bad value in StructValue for key %q: %v", key, err) + } + mv.Set(kv, vv) + } + return nil + } + + var jsonObject map[string]json.RawMessage + if err := json.Unmarshal(in, &jsonObject); err != nil { + return err + } + + // Handle known fields. + for i := 0; i < fds.Len(); i++ { + fd := fds.Get(i) + if fd.IsWeak() && fd.Message().IsPlaceholder() { + continue // weak reference is not linked in + } + + // Search for any raw JSON value associated with this field. + var raw json.RawMessage + name := string(fd.Name()) + if fd.Kind() == protoreflect.GroupKind { + name = string(fd.Message().Name()) + } + if v, ok := jsonObject[name]; ok { + delete(jsonObject, name) + raw = v + } + name = string(fd.JSONName()) + if v, ok := jsonObject[name]; ok { + delete(jsonObject, name) + raw = v + } + + // Unmarshal the field value. + if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd)) { + continue + } + v, err := u.unmarshalValue(m.NewField(fd), raw, fd) + if err != nil { + return err + } + m.Set(fd, v) + } + + // Handle extension fields. + for name, raw := range jsonObject { + if !strings.HasPrefix(name, "[") || !strings.HasSuffix(name, "]") { + continue + } + + // Resolve the extension field by name. + xname := protoreflect.FullName(name[len("[") : len(name)-len("]")]) + xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname) + if xt == nil && isMessageSet(md) { + xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension")) + } + if xt == nil { + continue + } + delete(jsonObject, name) + fd := xt.TypeDescriptor() + if fd.ContainingMessage().FullName() != m.Descriptor().FullName() { + return fmt.Errorf("extension field %q does not extend message %q", xname, m.Descriptor().FullName()) + } + + // Unmarshal the field value. + if raw == nil || (string(raw) == "null" && !isSingularWellKnownValue(fd)) { + continue + } + v, err := u.unmarshalValue(m.NewField(fd), raw, fd) + if err != nil { + return err + } + m.Set(fd, v) + } + + if !u.AllowUnknownFields && len(jsonObject) > 0 { + for name := range jsonObject { + return fmt.Errorf("unknown field %q in %v", name, md.FullName()) + } + } + return nil +} + +func isSingularWellKnownValue(fd protoreflect.FieldDescriptor) bool { + if md := fd.Message(); md != nil { + return md.FullName() == "google.protobuf.Value" && fd.Cardinality() != protoreflect.Repeated + } + return false +} + +func (u *Unmarshaler) unmarshalValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { + switch { + case fd.IsList(): + var jsonArray []json.RawMessage + if err := json.Unmarshal(in, &jsonArray); err != nil { + return v, err + } + lv := v.List() + for _, raw := range jsonArray { + ve, err := u.unmarshalSingularValue(lv.NewElement(), raw, fd) + if err != nil { + return v, err + } + lv.Append(ve) + } + return v, nil + case fd.IsMap(): + var jsonObject map[string]json.RawMessage + if err := json.Unmarshal(in, &jsonObject); err != nil { + return v, err + } + kfd := fd.MapKey() + vfd := fd.MapValue() + mv := v.Map() + for key, raw := range jsonObject { + var kv protoreflect.MapKey + if kfd.Kind() == protoreflect.StringKind { + kv = protoreflect.ValueOf(key).MapKey() + } else { + v, err := u.unmarshalSingularValue(kfd.Default(), []byte(key), kfd) + if err != nil { + return v, err + } + kv = v.MapKey() + } + + vv, err := u.unmarshalSingularValue(mv.NewValue(), raw, vfd) + if err != nil { + return v, err + } + mv.Set(kv, vv) + } + return v, nil + default: + return u.unmarshalSingularValue(v, in, fd) + } +} + +var nonFinite = map[string]float64{ + `"NaN"`: math.NaN(), + `"Infinity"`: math.Inf(+1), + `"-Infinity"`: math.Inf(-1), +} + +func (u *Unmarshaler) unmarshalSingularValue(v protoreflect.Value, in []byte, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { + switch fd.Kind() { + case protoreflect.BoolKind: + return unmarshalValue(in, new(bool)) + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: + return unmarshalValue(trimQuote(in), new(int32)) + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + return unmarshalValue(trimQuote(in), new(int64)) + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: + return unmarshalValue(trimQuote(in), new(uint32)) + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + return unmarshalValue(trimQuote(in), new(uint64)) + case protoreflect.FloatKind: + if f, ok := nonFinite[string(in)]; ok { + return protoreflect.ValueOfFloat32(float32(f)), nil + } + return unmarshalValue(trimQuote(in), new(float32)) + case protoreflect.DoubleKind: + if f, ok := nonFinite[string(in)]; ok { + return protoreflect.ValueOfFloat64(float64(f)), nil + } + return unmarshalValue(trimQuote(in), new(float64)) + case protoreflect.StringKind: + return unmarshalValue(in, new(string)) + case protoreflect.BytesKind: + return unmarshalValue(in, new([]byte)) + case protoreflect.EnumKind: + if hasPrefixAndSuffix('"', in, '"') { + vd := fd.Enum().Values().ByName(protoreflect.Name(trimQuote(in))) + if vd == nil { + return v, fmt.Errorf("unknown value %q for enum %s", in, fd.Enum().FullName()) + } + return protoreflect.ValueOfEnum(vd.Number()), nil + } + return unmarshalValue(in, new(protoreflect.EnumNumber)) + case protoreflect.MessageKind, protoreflect.GroupKind: + err := u.unmarshalMessage(v.Message(), in) + return v, err + default: + panic(fmt.Sprintf("invalid kind %v", fd.Kind())) + } +} + +func unmarshalValue(in []byte, v interface{}) (protoreflect.Value, error) { + err := json.Unmarshal(in, v) + return protoreflect.ValueOf(reflect.ValueOf(v).Elem().Interface()), err +} + +func unquoteString(in string) (out string, err error) { + err = json.Unmarshal([]byte(in), &out) + return out, err +} + +func hasPrefixAndSuffix(prefix byte, in []byte, suffix byte) bool { + if len(in) >= 2 && in[0] == prefix && in[len(in)-1] == suffix { + return true + } + return false +} + +// trimQuote is like unquoteString but simply strips surrounding quotes. +// This is incorrect, but is behavior done by the legacy implementation. +func trimQuote(in []byte) []byte { + if len(in) >= 2 && in[0] == '"' && in[len(in)-1] == '"' { + in = in[1 : len(in)-1] + } + return in +} diff --git a/vendor/github.com/golang/protobuf/jsonpb/encode.go b/vendor/github.com/golang/protobuf/jsonpb/encode.go new file mode 100644 index 000000000..685c80a62 --- /dev/null +++ b/vendor/github.com/golang/protobuf/jsonpb/encode.go @@ -0,0 +1,559 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package jsonpb + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "math" + "reflect" + "sort" + "strconv" + "strings" + "time" + + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/encoding/protojson" + protoV2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" +) + +const wrapJSONMarshalV2 = false + +// Marshaler is a configurable object for marshaling protocol buffer messages +// to the specified JSON representation. +type Marshaler struct { + // OrigName specifies whether to use the original protobuf name for fields. + OrigName bool + + // EnumsAsInts specifies whether to render enum values as integers, + // as opposed to string values. + EnumsAsInts bool + + // EmitDefaults specifies whether to render fields with zero values. + EmitDefaults bool + + // Indent controls whether the output is compact or not. + // If empty, the output is compact JSON. Otherwise, every JSON object + // entry and JSON array value will be on its own line. + // Each line will be preceded by repeated copies of Indent, where the + // number of copies is the current indentation depth. + Indent string + + // AnyResolver is used to resolve the google.protobuf.Any well-known type. + // If unset, the global registry is used by default. + AnyResolver AnyResolver +} + +// JSONPBMarshaler is implemented by protobuf messages that customize the +// way they are marshaled to JSON. Messages that implement this should also +// implement JSONPBUnmarshaler so that the custom format can be parsed. +// +// The JSON marshaling must follow the proto to JSON specification: +// https://developers.google.com/protocol-buffers/docs/proto3#json +// +// Deprecated: Custom types should implement protobuf reflection instead. +type JSONPBMarshaler interface { + MarshalJSONPB(*Marshaler) ([]byte, error) +} + +// Marshal serializes a protobuf message as JSON into w. +func (jm *Marshaler) Marshal(w io.Writer, m proto.Message) error { + b, err := jm.marshal(m) + if len(b) > 0 { + if _, err := w.Write(b); err != nil { + return err + } + } + return err +} + +// MarshalToString serializes a protobuf message as JSON in string form. +func (jm *Marshaler) MarshalToString(m proto.Message) (string, error) { + b, err := jm.marshal(m) + if err != nil { + return "", err + } + return string(b), nil +} + +func (jm *Marshaler) marshal(m proto.Message) ([]byte, error) { + v := reflect.ValueOf(m) + if m == nil || (v.Kind() == reflect.Ptr && v.IsNil()) { + return nil, errors.New("Marshal called with nil") + } + + // Check for custom marshalers first since they may not properly + // implement protobuf reflection that the logic below relies on. + if jsm, ok := m.(JSONPBMarshaler); ok { + return jsm.MarshalJSONPB(jm) + } + + if wrapJSONMarshalV2 { + opts := protojson.MarshalOptions{ + UseProtoNames: jm.OrigName, + UseEnumNumbers: jm.EnumsAsInts, + EmitUnpopulated: jm.EmitDefaults, + Indent: jm.Indent, + } + if jm.AnyResolver != nil { + opts.Resolver = anyResolver{jm.AnyResolver} + } + return opts.Marshal(proto.MessageReflect(m).Interface()) + } else { + // Check for unpopulated required fields first. + m2 := proto.MessageReflect(m) + if err := protoV2.CheckInitialized(m2.Interface()); err != nil { + return nil, err + } + + w := jsonWriter{Marshaler: jm} + err := w.marshalMessage(m2, "", "") + return w.buf, err + } +} + +type jsonWriter struct { + *Marshaler + buf []byte +} + +func (w *jsonWriter) write(s string) { + w.buf = append(w.buf, s...) +} + +func (w *jsonWriter) marshalMessage(m protoreflect.Message, indent, typeURL string) error { + if jsm, ok := proto.MessageV1(m.Interface()).(JSONPBMarshaler); ok { + b, err := jsm.MarshalJSONPB(w.Marshaler) + if err != nil { + return err + } + if typeURL != "" { + // we are marshaling this object to an Any type + var js map[string]*json.RawMessage + if err = json.Unmarshal(b, &js); err != nil { + return fmt.Errorf("type %T produced invalid JSON: %v", m.Interface(), err) + } + turl, err := json.Marshal(typeURL) + if err != nil { + return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err) + } + js["@type"] = (*json.RawMessage)(&turl) + if b, err = json.Marshal(js); err != nil { + return err + } + } + w.write(string(b)) + return nil + } + + md := m.Descriptor() + fds := md.Fields() + + // Handle well-known types. + const secondInNanos = int64(time.Second / time.Nanosecond) + switch wellKnownType(md.FullName()) { + case "Any": + return w.marshalAny(m, indent) + case "BoolValue", "BytesValue", "StringValue", + "Int32Value", "UInt32Value", "FloatValue", + "Int64Value", "UInt64Value", "DoubleValue": + fd := fds.ByNumber(1) + return w.marshalValue(fd, m.Get(fd), indent) + case "Duration": + const maxSecondsInDuration = 315576000000 + // "Generated output always contains 0, 3, 6, or 9 fractional digits, + // depending on required precision." + s := m.Get(fds.ByNumber(1)).Int() + ns := m.Get(fds.ByNumber(2)).Int() + if s < -maxSecondsInDuration || s > maxSecondsInDuration { + return fmt.Errorf("seconds out of range %v", s) + } + if ns <= -secondInNanos || ns >= secondInNanos { + return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos) + } + if (s > 0 && ns < 0) || (s < 0 && ns > 0) { + return errors.New("signs of seconds and nanos do not match") + } + var sign string + if s < 0 || ns < 0 { + sign, s, ns = "-", -1*s, -1*ns + } + x := fmt.Sprintf("%s%d.%09d", sign, s, ns) + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, ".000") + w.write(fmt.Sprintf(`"%vs"`, x)) + return nil + case "Timestamp": + // "RFC 3339, where generated output will always be Z-normalized + // and uses 0, 3, 6 or 9 fractional digits." + s := m.Get(fds.ByNumber(1)).Int() + ns := m.Get(fds.ByNumber(2)).Int() + if ns < 0 || ns >= secondInNanos { + return fmt.Errorf("ns out of range [0, %v)", secondInNanos) + } + t := time.Unix(s, ns).UTC() + // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits). + x := t.Format("2006-01-02T15:04:05.000000000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, "000") + x = strings.TrimSuffix(x, ".000") + w.write(fmt.Sprintf(`"%vZ"`, x)) + return nil + case "Value": + // JSON value; which is a null, number, string, bool, object, or array. + od := md.Oneofs().Get(0) + fd := m.WhichOneof(od) + if fd == nil { + return errors.New("nil Value") + } + return w.marshalValue(fd, m.Get(fd), indent) + case "Struct", "ListValue": + // JSON object or array. + fd := fds.ByNumber(1) + return w.marshalValue(fd, m.Get(fd), indent) + } + + w.write("{") + if w.Indent != "" { + w.write("\n") + } + + firstField := true + if typeURL != "" { + if err := w.marshalTypeURL(indent, typeURL); err != nil { + return err + } + firstField = false + } + + for i := 0; i < fds.Len(); { + fd := fds.Get(i) + if od := fd.ContainingOneof(); od != nil { + fd = m.WhichOneof(od) + i += od.Fields().Len() + if fd == nil { + continue + } + } else { + i++ + } + + v := m.Get(fd) + + if !m.Has(fd) { + if !w.EmitDefaults || fd.ContainingOneof() != nil { + continue + } + if fd.Cardinality() != protoreflect.Repeated && (fd.Message() != nil || fd.Syntax() == protoreflect.Proto2) { + v = protoreflect.Value{} // use "null" for singular messages or proto2 scalars + } + } + + if !firstField { + w.writeComma() + } + if err := w.marshalField(fd, v, indent); err != nil { + return err + } + firstField = false + } + + // Handle proto2 extensions. + if md.ExtensionRanges().Len() > 0 { + // Collect a sorted list of all extension descriptor and values. + type ext struct { + desc protoreflect.FieldDescriptor + val protoreflect.Value + } + var exts []ext + m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + if fd.IsExtension() { + exts = append(exts, ext{fd, v}) + } + return true + }) + sort.Slice(exts, func(i, j int) bool { + return exts[i].desc.Number() < exts[j].desc.Number() + }) + + for _, ext := range exts { + if !firstField { + w.writeComma() + } + if err := w.marshalField(ext.desc, ext.val, indent); err != nil { + return err + } + firstField = false + } + } + + if w.Indent != "" { + w.write("\n") + w.write(indent) + } + w.write("}") + return nil +} + +func (w *jsonWriter) writeComma() { + if w.Indent != "" { + w.write(",\n") + } else { + w.write(",") + } +} + +func (w *jsonWriter) marshalAny(m protoreflect.Message, indent string) error { + // "If the Any contains a value that has a special JSON mapping, + // it will be converted as follows: {"@type": xxx, "value": yyy}. + // Otherwise, the value will be converted into a JSON object, + // and the "@type" field will be inserted to indicate the actual data type." + md := m.Descriptor() + typeURL := m.Get(md.Fields().ByNumber(1)).String() + rawVal := m.Get(md.Fields().ByNumber(2)).Bytes() + + var m2 protoreflect.Message + if w.AnyResolver != nil { + mi, err := w.AnyResolver.Resolve(typeURL) + if err != nil { + return err + } + m2 = proto.MessageReflect(mi) + } else { + mt, err := protoregistry.GlobalTypes.FindMessageByURL(typeURL) + if err != nil { + return err + } + m2 = mt.New() + } + + if err := protoV2.Unmarshal(rawVal, m2.Interface()); err != nil { + return err + } + + if wellKnownType(m2.Descriptor().FullName()) == "" { + return w.marshalMessage(m2, indent, typeURL) + } + + w.write("{") + if w.Indent != "" { + w.write("\n") + } + if err := w.marshalTypeURL(indent, typeURL); err != nil { + return err + } + w.writeComma() + if w.Indent != "" { + w.write(indent) + w.write(w.Indent) + w.write(`"value": `) + } else { + w.write(`"value":`) + } + if err := w.marshalMessage(m2, indent+w.Indent, ""); err != nil { + return err + } + if w.Indent != "" { + w.write("\n") + w.write(indent) + } + w.write("}") + return nil +} + +func (w *jsonWriter) marshalTypeURL(indent, typeURL string) error { + if w.Indent != "" { + w.write(indent) + w.write(w.Indent) + } + w.write(`"@type":`) + if w.Indent != "" { + w.write(" ") + } + b, err := json.Marshal(typeURL) + if err != nil { + return err + } + w.write(string(b)) + return nil +} + +// marshalField writes field description and value to the Writer. +func (w *jsonWriter) marshalField(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { + if w.Indent != "" { + w.write(indent) + w.write(w.Indent) + } + w.write(`"`) + switch { + case fd.IsExtension(): + // For message set, use the fname of the message as the extension name. + name := string(fd.FullName()) + if isMessageSet(fd.ContainingMessage()) { + name = strings.TrimSuffix(name, ".message_set_extension") + } + + w.write("[" + name + "]") + case w.OrigName: + name := string(fd.Name()) + if fd.Kind() == protoreflect.GroupKind { + name = string(fd.Message().Name()) + } + w.write(name) + default: + w.write(string(fd.JSONName())) + } + w.write(`":`) + if w.Indent != "" { + w.write(" ") + } + return w.marshalValue(fd, v, indent) +} + +func (w *jsonWriter) marshalValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { + switch { + case fd.IsList(): + w.write("[") + comma := "" + lv := v.List() + for i := 0; i < lv.Len(); i++ { + w.write(comma) + if w.Indent != "" { + w.write("\n") + w.write(indent) + w.write(w.Indent) + w.write(w.Indent) + } + if err := w.marshalSingularValue(fd, lv.Get(i), indent+w.Indent); err != nil { + return err + } + comma = "," + } + if w.Indent != "" { + w.write("\n") + w.write(indent) + w.write(w.Indent) + } + w.write("]") + return nil + case fd.IsMap(): + kfd := fd.MapKey() + vfd := fd.MapValue() + mv := v.Map() + + // Collect a sorted list of all map keys and values. + type entry struct{ key, val protoreflect.Value } + var entries []entry + mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { + entries = append(entries, entry{k.Value(), v}) + return true + }) + sort.Slice(entries, func(i, j int) bool { + switch kfd.Kind() { + case protoreflect.BoolKind: + return !entries[i].key.Bool() && entries[j].key.Bool() + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + return entries[i].key.Int() < entries[j].key.Int() + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + return entries[i].key.Uint() < entries[j].key.Uint() + case protoreflect.StringKind: + return entries[i].key.String() < entries[j].key.String() + default: + panic("invalid kind") + } + }) + + w.write(`{`) + comma := "" + for _, entry := range entries { + w.write(comma) + if w.Indent != "" { + w.write("\n") + w.write(indent) + w.write(w.Indent) + w.write(w.Indent) + } + + s := fmt.Sprint(entry.key.Interface()) + b, err := json.Marshal(s) + if err != nil { + return err + } + w.write(string(b)) + + w.write(`:`) + if w.Indent != "" { + w.write(` `) + } + + if err := w.marshalSingularValue(vfd, entry.val, indent+w.Indent); err != nil { + return err + } + comma = "," + } + if w.Indent != "" { + w.write("\n") + w.write(indent) + w.write(w.Indent) + } + w.write(`}`) + return nil + default: + return w.marshalSingularValue(fd, v, indent) + } +} + +func (w *jsonWriter) marshalSingularValue(fd protoreflect.FieldDescriptor, v protoreflect.Value, indent string) error { + switch { + case !v.IsValid(): + w.write("null") + return nil + case fd.Message() != nil: + return w.marshalMessage(v.Message(), indent+w.Indent, "") + case fd.Enum() != nil: + if fd.Enum().FullName() == "google.protobuf.NullValue" { + w.write("null") + return nil + } + + vd := fd.Enum().Values().ByNumber(v.Enum()) + if vd == nil || w.EnumsAsInts { + w.write(strconv.Itoa(int(v.Enum()))) + } else { + w.write(`"` + string(vd.Name()) + `"`) + } + return nil + default: + switch v.Interface().(type) { + case float32, float64: + switch { + case math.IsInf(v.Float(), +1): + w.write(`"Infinity"`) + return nil + case math.IsInf(v.Float(), -1): + w.write(`"-Infinity"`) + return nil + case math.IsNaN(v.Float()): + w.write(`"NaN"`) + return nil + } + case int64, uint64: + w.write(fmt.Sprintf(`"%d"`, v.Interface())) + return nil + } + + b, err := json.Marshal(v.Interface()) + if err != nil { + return err + } + w.write(string(b)) + return nil + } +} diff --git a/vendor/github.com/golang/protobuf/jsonpb/json.go b/vendor/github.com/golang/protobuf/jsonpb/json.go new file mode 100644 index 000000000..480e2448d --- /dev/null +++ b/vendor/github.com/golang/protobuf/jsonpb/json.go @@ -0,0 +1,69 @@ +// Copyright 2015 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package jsonpb provides functionality to marshal and unmarshal between a +// protocol buffer message and JSON. It follows the specification at +// https://developers.google.com/protocol-buffers/docs/proto3#json. +// +// Do not rely on the default behavior of the standard encoding/json package +// when called on generated message types as it does not operate correctly. +// +// Deprecated: Use the "google.golang.org/protobuf/encoding/protojson" +// package instead. +package jsonpb + +import ( + "github.com/golang/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/runtime/protoimpl" +) + +// AnyResolver takes a type URL, present in an Any message, +// and resolves it into an instance of the associated message. +type AnyResolver interface { + Resolve(typeURL string) (proto.Message, error) +} + +type anyResolver struct{ AnyResolver } + +func (r anyResolver) FindMessageByName(message protoreflect.FullName) (protoreflect.MessageType, error) { + return r.FindMessageByURL(string(message)) +} + +func (r anyResolver) FindMessageByURL(url string) (protoreflect.MessageType, error) { + m, err := r.Resolve(url) + if err != nil { + return nil, err + } + return protoimpl.X.MessageTypeOf(m), nil +} + +func (r anyResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { + return protoregistry.GlobalTypes.FindExtensionByName(field) +} + +func (r anyResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { + return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) +} + +func wellKnownType(s protoreflect.FullName) string { + if s.Parent() == "google.protobuf" { + switch s.Name() { + case "Empty", "Any", + "BoolValue", "BytesValue", "StringValue", + "Int32Value", "UInt32Value", "FloatValue", + "Int64Value", "UInt64Value", "DoubleValue", + "Duration", "Timestamp", + "NullValue", "Struct", "Value", "ListValue": + return string(s.Name()) + } + } + return "" +} + +func isMessageSet(md protoreflect.MessageDescriptor) bool { + ms, ok := md.(interface{ IsMessageSet() bool }) + return ok && ms.IsMessageSet() +} diff --git a/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go b/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go deleted file mode 100644 index f0d66befb..000000000 --- a/vendor/github.com/golang/protobuf/jsonpb/jsonpb.go +++ /dev/null @@ -1,1290 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2015 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/* -Package jsonpb provides marshaling and unmarshaling between protocol buffers and JSON. -It follows the specification at https://developers.google.com/protocol-buffers/docs/proto3#json. - -This package produces a different output than the standard "encoding/json" package, -which does not operate correctly on protocol buffers. -*/ -package jsonpb - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "io" - "math" - "reflect" - "sort" - "strconv" - "strings" - "time" - - "github.com/golang/protobuf/proto" - - stpb "github.com/golang/protobuf/ptypes/struct" -) - -const secondInNanos = int64(time.Second / time.Nanosecond) -const maxSecondsInDuration = 315576000000 - -// Marshaler is a configurable object for converting between -// protocol buffer objects and a JSON representation for them. -type Marshaler struct { - // Whether to render enum values as integers, as opposed to string values. - EnumsAsInts bool - - // Whether to render fields with zero values. - EmitDefaults bool - - // A string to indent each level by. The presence of this field will - // also cause a space to appear between the field separator and - // value, and for newlines to be appear between fields and array - // elements. - Indent string - - // Whether to use the original (.proto) name for fields. - OrigName bool - - // A custom URL resolver to use when marshaling Any messages to JSON. - // If unset, the default resolution strategy is to extract the - // fully-qualified type name from the type URL and pass that to - // proto.MessageType(string). - AnyResolver AnyResolver -} - -// AnyResolver takes a type URL, present in an Any message, and resolves it into -// an instance of the associated message. -type AnyResolver interface { - Resolve(typeUrl string) (proto.Message, error) -} - -func defaultResolveAny(typeUrl string) (proto.Message, error) { - // Only the part of typeUrl after the last slash is relevant. - mname := typeUrl - if slash := strings.LastIndex(mname, "/"); slash >= 0 { - mname = mname[slash+1:] - } - mt := proto.MessageType(mname) - if mt == nil { - return nil, fmt.Errorf("unknown message type %q", mname) - } - return reflect.New(mt.Elem()).Interface().(proto.Message), nil -} - -// JSONPBMarshaler is implemented by protobuf messages that customize the -// way they are marshaled to JSON. Messages that implement this should -// also implement JSONPBUnmarshaler so that the custom format can be -// parsed. -// -// The JSON marshaling must follow the proto to JSON specification: -// https://developers.google.com/protocol-buffers/docs/proto3#json -type JSONPBMarshaler interface { - MarshalJSONPB(*Marshaler) ([]byte, error) -} - -// JSONPBUnmarshaler is implemented by protobuf messages that customize -// the way they are unmarshaled from JSON. Messages that implement this -// should also implement JSONPBMarshaler so that the custom format can be -// produced. -// -// The JSON unmarshaling must follow the JSON to proto specification: -// https://developers.google.com/protocol-buffers/docs/proto3#json -type JSONPBUnmarshaler interface { - UnmarshalJSONPB(*Unmarshaler, []byte) error -} - -// Marshal marshals a protocol buffer into JSON. -func (m *Marshaler) Marshal(out io.Writer, pb proto.Message) error { - v := reflect.ValueOf(pb) - if pb == nil || (v.Kind() == reflect.Ptr && v.IsNil()) { - return errors.New("Marshal called with nil") - } - // Check for unset required fields first. - if err := checkRequiredFields(pb); err != nil { - return err - } - writer := &errWriter{writer: out} - return m.marshalObject(writer, pb, "", "") -} - -// MarshalToString converts a protocol buffer object to JSON string. -func (m *Marshaler) MarshalToString(pb proto.Message) (string, error) { - var buf bytes.Buffer - if err := m.Marshal(&buf, pb); err != nil { - return "", err - } - return buf.String(), nil -} - -type int32Slice []int32 - -var nonFinite = map[string]float64{ - `"NaN"`: math.NaN(), - `"Infinity"`: math.Inf(1), - `"-Infinity"`: math.Inf(-1), -} - -// For sorting extensions ids to ensure stable output. -func (s int32Slice) Len() int { return len(s) } -func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } -func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -type wkt interface { - XXX_WellKnownType() string -} - -var ( - wktType = reflect.TypeOf((*wkt)(nil)).Elem() - messageType = reflect.TypeOf((*proto.Message)(nil)).Elem() -) - -// marshalObject writes a struct to the Writer. -func (m *Marshaler) marshalObject(out *errWriter, v proto.Message, indent, typeURL string) error { - if jsm, ok := v.(JSONPBMarshaler); ok { - b, err := jsm.MarshalJSONPB(m) - if err != nil { - return err - } - if typeURL != "" { - // we are marshaling this object to an Any type - var js map[string]*json.RawMessage - if err = json.Unmarshal(b, &js); err != nil { - return fmt.Errorf("type %T produced invalid JSON: %v", v, err) - } - turl, err := json.Marshal(typeURL) - if err != nil { - return fmt.Errorf("failed to marshal type URL %q to JSON: %v", typeURL, err) - } - js["@type"] = (*json.RawMessage)(&turl) - if m.Indent != "" { - b, err = json.MarshalIndent(js, indent, m.Indent) - } else { - b, err = json.Marshal(js) - } - if err != nil { - return err - } - } - - out.write(string(b)) - return out.err - } - - s := reflect.ValueOf(v).Elem() - - // Handle well-known types. - if wkt, ok := v.(wkt); ok { - switch wkt.XXX_WellKnownType() { - case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", - "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": - // "Wrappers use the same representation in JSON - // as the wrapped primitive type, ..." - sprop := proto.GetProperties(s.Type()) - return m.marshalValue(out, sprop.Prop[0], s.Field(0), indent) - case "Any": - // Any is a bit more involved. - return m.marshalAny(out, v, indent) - case "Duration": - s, ns := s.Field(0).Int(), s.Field(1).Int() - if s < -maxSecondsInDuration || s > maxSecondsInDuration { - return fmt.Errorf("seconds out of range %v", s) - } - if ns <= -secondInNanos || ns >= secondInNanos { - return fmt.Errorf("ns out of range (%v, %v)", -secondInNanos, secondInNanos) - } - if (s > 0 && ns < 0) || (s < 0 && ns > 0) { - return errors.New("signs of seconds and nanos do not match") - } - // Generated output always contains 0, 3, 6, or 9 fractional digits, - // depending on required precision, followed by the suffix "s". - f := "%d.%09d" - if ns < 0 { - ns = -ns - if s == 0 { - f = "-%d.%09d" - } - } - x := fmt.Sprintf(f, s, ns) - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, ".000") - out.write(`"`) - out.write(x) - out.write(`s"`) - return out.err - case "Struct", "ListValue": - // Let marshalValue handle the `Struct.fields` map or the `ListValue.values` slice. - // TODO: pass the correct Properties if needed. - return m.marshalValue(out, &proto.Properties{}, s.Field(0), indent) - case "Timestamp": - // "RFC 3339, where generated output will always be Z-normalized - // and uses 0, 3, 6 or 9 fractional digits." - s, ns := s.Field(0).Int(), s.Field(1).Int() - if ns < 0 || ns >= secondInNanos { - return fmt.Errorf("ns out of range [0, %v)", secondInNanos) - } - t := time.Unix(s, ns).UTC() - // time.RFC3339Nano isn't exactly right (we need to get 3/6/9 fractional digits). - x := t.Format("2006-01-02T15:04:05.000000000") - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, "000") - x = strings.TrimSuffix(x, ".000") - out.write(`"`) - out.write(x) - out.write(`Z"`) - return out.err - case "Value": - // Value has a single oneof. - kind := s.Field(0) - if kind.IsNil() { - // "absence of any variant indicates an error" - return errors.New("nil Value") - } - // oneof -> *T -> T -> T.F - x := kind.Elem().Elem().Field(0) - // TODO: pass the correct Properties if needed. - return m.marshalValue(out, &proto.Properties{}, x, indent) - } - } - - out.write("{") - if m.Indent != "" { - out.write("\n") - } - - firstField := true - - if typeURL != "" { - if err := m.marshalTypeURL(out, indent, typeURL); err != nil { - return err - } - firstField = false - } - - for i := 0; i < s.NumField(); i++ { - value := s.Field(i) - valueField := s.Type().Field(i) - if strings.HasPrefix(valueField.Name, "XXX_") { - continue - } - - // IsNil will panic on most value kinds. - switch value.Kind() { - case reflect.Chan, reflect.Func, reflect.Interface: - if value.IsNil() { - continue - } - } - - if !m.EmitDefaults { - switch value.Kind() { - case reflect.Bool: - if !value.Bool() { - continue - } - case reflect.Int32, reflect.Int64: - if value.Int() == 0 { - continue - } - case reflect.Uint32, reflect.Uint64: - if value.Uint() == 0 { - continue - } - case reflect.Float32, reflect.Float64: - if value.Float() == 0 { - continue - } - case reflect.String: - if value.Len() == 0 { - continue - } - case reflect.Map, reflect.Ptr, reflect.Slice: - if value.IsNil() { - continue - } - } - } - - // Oneof fields need special handling. - if valueField.Tag.Get("protobuf_oneof") != "" { - // value is an interface containing &T{real_value}. - sv := value.Elem().Elem() // interface -> *T -> T - value = sv.Field(0) - valueField = sv.Type().Field(0) - } - prop := jsonProperties(valueField, m.OrigName) - if !firstField { - m.writeSep(out) - } - if err := m.marshalField(out, prop, value, indent); err != nil { - return err - } - firstField = false - } - - // Handle proto2 extensions. - if ep, ok := v.(proto.Message); ok { - extensions := proto.RegisteredExtensions(v) - // Sort extensions for stable output. - ids := make([]int32, 0, len(extensions)) - for id, desc := range extensions { - if !proto.HasExtension(ep, desc) { - continue - } - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) - for _, id := range ids { - desc := extensions[id] - if desc == nil { - // unknown extension - continue - } - ext, extErr := proto.GetExtension(ep, desc) - if extErr != nil { - return extErr - } - value := reflect.ValueOf(ext) - var prop proto.Properties - prop.Parse(desc.Tag) - prop.JSONName = fmt.Sprintf("[%s]", desc.Name) - if !firstField { - m.writeSep(out) - } - if err := m.marshalField(out, &prop, value, indent); err != nil { - return err - } - firstField = false - } - - } - - if m.Indent != "" { - out.write("\n") - out.write(indent) - } - out.write("}") - return out.err -} - -func (m *Marshaler) writeSep(out *errWriter) { - if m.Indent != "" { - out.write(",\n") - } else { - out.write(",") - } -} - -func (m *Marshaler) marshalAny(out *errWriter, any proto.Message, indent string) error { - // "If the Any contains a value that has a special JSON mapping, - // it will be converted as follows: {"@type": xxx, "value": yyy}. - // Otherwise, the value will be converted into a JSON object, - // and the "@type" field will be inserted to indicate the actual data type." - v := reflect.ValueOf(any).Elem() - turl := v.Field(0).String() - val := v.Field(1).Bytes() - - var msg proto.Message - var err error - if m.AnyResolver != nil { - msg, err = m.AnyResolver.Resolve(turl) - } else { - msg, err = defaultResolveAny(turl) - } - if err != nil { - return err - } - - if err := proto.Unmarshal(val, msg); err != nil { - return err - } - - if _, ok := msg.(wkt); ok { - out.write("{") - if m.Indent != "" { - out.write("\n") - } - if err := m.marshalTypeURL(out, indent, turl); err != nil { - return err - } - m.writeSep(out) - if m.Indent != "" { - out.write(indent) - out.write(m.Indent) - out.write(`"value": `) - } else { - out.write(`"value":`) - } - if err := m.marshalObject(out, msg, indent+m.Indent, ""); err != nil { - return err - } - if m.Indent != "" { - out.write("\n") - out.write(indent) - } - out.write("}") - return out.err - } - - return m.marshalObject(out, msg, indent, turl) -} - -func (m *Marshaler) marshalTypeURL(out *errWriter, indent, typeURL string) error { - if m.Indent != "" { - out.write(indent) - out.write(m.Indent) - } - out.write(`"@type":`) - if m.Indent != "" { - out.write(" ") - } - b, err := json.Marshal(typeURL) - if err != nil { - return err - } - out.write(string(b)) - return out.err -} - -// marshalField writes field description and value to the Writer. -func (m *Marshaler) marshalField(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { - if m.Indent != "" { - out.write(indent) - out.write(m.Indent) - } - out.write(`"`) - out.write(prop.JSONName) - out.write(`":`) - if m.Indent != "" { - out.write(" ") - } - if err := m.marshalValue(out, prop, v, indent); err != nil { - return err - } - return nil -} - -// marshalValue writes the value to the Writer. -func (m *Marshaler) marshalValue(out *errWriter, prop *proto.Properties, v reflect.Value, indent string) error { - var err error - v = reflect.Indirect(v) - - // Handle nil pointer - if v.Kind() == reflect.Invalid { - out.write("null") - return out.err - } - - // Handle repeated elements. - if v.Kind() == reflect.Slice && v.Type().Elem().Kind() != reflect.Uint8 { - out.write("[") - comma := "" - for i := 0; i < v.Len(); i++ { - sliceVal := v.Index(i) - out.write(comma) - if m.Indent != "" { - out.write("\n") - out.write(indent) - out.write(m.Indent) - out.write(m.Indent) - } - if err := m.marshalValue(out, prop, sliceVal, indent+m.Indent); err != nil { - return err - } - comma = "," - } - if m.Indent != "" { - out.write("\n") - out.write(indent) - out.write(m.Indent) - } - out.write("]") - return out.err - } - - // Handle well-known types. - // Most are handled up in marshalObject (because 99% are messages). - if v.Type().Implements(wktType) { - wkt := v.Interface().(wkt) - switch wkt.XXX_WellKnownType() { - case "NullValue": - out.write("null") - return out.err - } - } - - // Handle enumerations. - if !m.EnumsAsInts && prop.Enum != "" { - // Unknown enum values will are stringified by the proto library as their - // value. Such values should _not_ be quoted or they will be interpreted - // as an enum string instead of their value. - enumStr := v.Interface().(fmt.Stringer).String() - var valStr string - if v.Kind() == reflect.Ptr { - valStr = strconv.Itoa(int(v.Elem().Int())) - } else { - valStr = strconv.Itoa(int(v.Int())) - } - isKnownEnum := enumStr != valStr - if isKnownEnum { - out.write(`"`) - } - out.write(enumStr) - if isKnownEnum { - out.write(`"`) - } - return out.err - } - - // Handle nested messages. - if v.Kind() == reflect.Struct { - return m.marshalObject(out, v.Addr().Interface().(proto.Message), indent+m.Indent, "") - } - - // Handle maps. - // Since Go randomizes map iteration, we sort keys for stable output. - if v.Kind() == reflect.Map { - out.write(`{`) - keys := v.MapKeys() - sort.Sort(mapKeys(keys)) - for i, k := range keys { - if i > 0 { - out.write(`,`) - } - if m.Indent != "" { - out.write("\n") - out.write(indent) - out.write(m.Indent) - out.write(m.Indent) - } - - // TODO handle map key prop properly - b, err := json.Marshal(k.Interface()) - if err != nil { - return err - } - s := string(b) - - // If the JSON is not a string value, encode it again to make it one. - if !strings.HasPrefix(s, `"`) { - b, err := json.Marshal(s) - if err != nil { - return err - } - s = string(b) - } - - out.write(s) - out.write(`:`) - if m.Indent != "" { - out.write(` `) - } - - vprop := prop - if prop != nil && prop.MapValProp != nil { - vprop = prop.MapValProp - } - if err := m.marshalValue(out, vprop, v.MapIndex(k), indent+m.Indent); err != nil { - return err - } - } - if m.Indent != "" { - out.write("\n") - out.write(indent) - out.write(m.Indent) - } - out.write(`}`) - return out.err - } - - // Handle non-finite floats, e.g. NaN, Infinity and -Infinity. - if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { - f := v.Float() - var sval string - switch { - case math.IsInf(f, 1): - sval = `"Infinity"` - case math.IsInf(f, -1): - sval = `"-Infinity"` - case math.IsNaN(f): - sval = `"NaN"` - } - if sval != "" { - out.write(sval) - return out.err - } - } - - // Default handling defers to the encoding/json library. - b, err := json.Marshal(v.Interface()) - if err != nil { - return err - } - needToQuote := string(b[0]) != `"` && (v.Kind() == reflect.Int64 || v.Kind() == reflect.Uint64) - if needToQuote { - out.write(`"`) - } - out.write(string(b)) - if needToQuote { - out.write(`"`) - } - return out.err -} - -// Unmarshaler is a configurable object for converting from a JSON -// representation to a protocol buffer object. -type Unmarshaler struct { - // Whether to allow messages to contain unknown fields, as opposed to - // failing to unmarshal. - AllowUnknownFields bool - - // A custom URL resolver to use when unmarshaling Any messages from JSON. - // If unset, the default resolution strategy is to extract the - // fully-qualified type name from the type URL and pass that to - // proto.MessageType(string). - AnyResolver AnyResolver -} - -// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream. -// This function is lenient and will decode any options permutations of the -// related Marshaler. -func (u *Unmarshaler) UnmarshalNext(dec *json.Decoder, pb proto.Message) error { - inputValue := json.RawMessage{} - if err := dec.Decode(&inputValue); err != nil { - return err - } - if err := u.unmarshalValue(reflect.ValueOf(pb).Elem(), inputValue, nil); err != nil { - return err - } - return checkRequiredFields(pb) -} - -// Unmarshal unmarshals a JSON object stream into a protocol -// buffer. This function is lenient and will decode any options -// permutations of the related Marshaler. -func (u *Unmarshaler) Unmarshal(r io.Reader, pb proto.Message) error { - dec := json.NewDecoder(r) - return u.UnmarshalNext(dec, pb) -} - -// UnmarshalNext unmarshals the next protocol buffer from a JSON object stream. -// This function is lenient and will decode any options permutations of the -// related Marshaler. -func UnmarshalNext(dec *json.Decoder, pb proto.Message) error { - return new(Unmarshaler).UnmarshalNext(dec, pb) -} - -// Unmarshal unmarshals a JSON object stream into a protocol -// buffer. This function is lenient and will decode any options -// permutations of the related Marshaler. -func Unmarshal(r io.Reader, pb proto.Message) error { - return new(Unmarshaler).Unmarshal(r, pb) -} - -// UnmarshalString will populate the fields of a protocol buffer based -// on a JSON string. This function is lenient and will decode any options -// permutations of the related Marshaler. -func UnmarshalString(str string, pb proto.Message) error { - return new(Unmarshaler).Unmarshal(strings.NewReader(str), pb) -} - -// unmarshalValue converts/copies a value into the target. -// prop may be nil. -func (u *Unmarshaler) unmarshalValue(target reflect.Value, inputValue json.RawMessage, prop *proto.Properties) error { - targetType := target.Type() - - // Allocate memory for pointer fields. - if targetType.Kind() == reflect.Ptr { - // If input value is "null" and target is a pointer type, then the field should be treated as not set - // UNLESS the target is structpb.Value, in which case it should be set to structpb.NullValue. - _, isJSONPBUnmarshaler := target.Interface().(JSONPBUnmarshaler) - if string(inputValue) == "null" && targetType != reflect.TypeOf(&stpb.Value{}) && !isJSONPBUnmarshaler { - return nil - } - target.Set(reflect.New(targetType.Elem())) - - return u.unmarshalValue(target.Elem(), inputValue, prop) - } - - if jsu, ok := target.Addr().Interface().(JSONPBUnmarshaler); ok { - return jsu.UnmarshalJSONPB(u, []byte(inputValue)) - } - - // Handle well-known types that are not pointers. - if w, ok := target.Addr().Interface().(wkt); ok { - switch w.XXX_WellKnownType() { - case "DoubleValue", "FloatValue", "Int64Value", "UInt64Value", - "Int32Value", "UInt32Value", "BoolValue", "StringValue", "BytesValue": - return u.unmarshalValue(target.Field(0), inputValue, prop) - case "Any": - // Use json.RawMessage pointer type instead of value to support pre-1.8 version. - // 1.8 changed RawMessage.MarshalJSON from pointer type to value type, see - // https://github.com/golang/go/issues/14493 - var jsonFields map[string]*json.RawMessage - if err := json.Unmarshal(inputValue, &jsonFields); err != nil { - return err - } - - val, ok := jsonFields["@type"] - if !ok || val == nil { - return errors.New("Any JSON doesn't have '@type'") - } - - var turl string - if err := json.Unmarshal([]byte(*val), &turl); err != nil { - return fmt.Errorf("can't unmarshal Any's '@type': %q", *val) - } - target.Field(0).SetString(turl) - - var m proto.Message - var err error - if u.AnyResolver != nil { - m, err = u.AnyResolver.Resolve(turl) - } else { - m, err = defaultResolveAny(turl) - } - if err != nil { - return err - } - - if _, ok := m.(wkt); ok { - val, ok := jsonFields["value"] - if !ok { - return errors.New("Any JSON doesn't have 'value'") - } - - if err := u.unmarshalValue(reflect.ValueOf(m).Elem(), *val, nil); err != nil { - return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err) - } - } else { - delete(jsonFields, "@type") - nestedProto, err := json.Marshal(jsonFields) - if err != nil { - return fmt.Errorf("can't generate JSON for Any's nested proto to be unmarshaled: %v", err) - } - - if err = u.unmarshalValue(reflect.ValueOf(m).Elem(), nestedProto, nil); err != nil { - return fmt.Errorf("can't unmarshal Any nested proto %T: %v", m, err) - } - } - - b, err := proto.Marshal(m) - if err != nil { - return fmt.Errorf("can't marshal proto %T into Any.Value: %v", m, err) - } - target.Field(1).SetBytes(b) - - return nil - case "Duration": - unq, err := unquote(string(inputValue)) - if err != nil { - return err - } - - d, err := time.ParseDuration(unq) - if err != nil { - return fmt.Errorf("bad Duration: %v", err) - } - - ns := d.Nanoseconds() - s := ns / 1e9 - ns %= 1e9 - target.Field(0).SetInt(s) - target.Field(1).SetInt(ns) - return nil - case "Timestamp": - unq, err := unquote(string(inputValue)) - if err != nil { - return err - } - - t, err := time.Parse(time.RFC3339Nano, unq) - if err != nil { - return fmt.Errorf("bad Timestamp: %v", err) - } - - target.Field(0).SetInt(t.Unix()) - target.Field(1).SetInt(int64(t.Nanosecond())) - return nil - case "Struct": - var m map[string]json.RawMessage - if err := json.Unmarshal(inputValue, &m); err != nil { - return fmt.Errorf("bad StructValue: %v", err) - } - - target.Field(0).Set(reflect.ValueOf(map[string]*stpb.Value{})) - for k, jv := range m { - pv := &stpb.Value{} - if err := u.unmarshalValue(reflect.ValueOf(pv).Elem(), jv, prop); err != nil { - return fmt.Errorf("bad value in StructValue for key %q: %v", k, err) - } - target.Field(0).SetMapIndex(reflect.ValueOf(k), reflect.ValueOf(pv)) - } - return nil - case "ListValue": - var s []json.RawMessage - if err := json.Unmarshal(inputValue, &s); err != nil { - return fmt.Errorf("bad ListValue: %v", err) - } - - target.Field(0).Set(reflect.ValueOf(make([]*stpb.Value, len(s)))) - for i, sv := range s { - if err := u.unmarshalValue(target.Field(0).Index(i), sv, prop); err != nil { - return err - } - } - return nil - case "Value": - ivStr := string(inputValue) - if ivStr == "null" { - target.Field(0).Set(reflect.ValueOf(&stpb.Value_NullValue{})) - } else if v, err := strconv.ParseFloat(ivStr, 0); err == nil { - target.Field(0).Set(reflect.ValueOf(&stpb.Value_NumberValue{v})) - } else if v, err := unquote(ivStr); err == nil { - target.Field(0).Set(reflect.ValueOf(&stpb.Value_StringValue{v})) - } else if v, err := strconv.ParseBool(ivStr); err == nil { - target.Field(0).Set(reflect.ValueOf(&stpb.Value_BoolValue{v})) - } else if err := json.Unmarshal(inputValue, &[]json.RawMessage{}); err == nil { - lv := &stpb.ListValue{} - target.Field(0).Set(reflect.ValueOf(&stpb.Value_ListValue{lv})) - return u.unmarshalValue(reflect.ValueOf(lv).Elem(), inputValue, prop) - } else if err := json.Unmarshal(inputValue, &map[string]json.RawMessage{}); err == nil { - sv := &stpb.Struct{} - target.Field(0).Set(reflect.ValueOf(&stpb.Value_StructValue{sv})) - return u.unmarshalValue(reflect.ValueOf(sv).Elem(), inputValue, prop) - } else { - return fmt.Errorf("unrecognized type for Value %q", ivStr) - } - return nil - } - } - - // Handle enums, which have an underlying type of int32, - // and may appear as strings. - // The case of an enum appearing as a number is handled - // at the bottom of this function. - if inputValue[0] == '"' && prop != nil && prop.Enum != "" { - vmap := proto.EnumValueMap(prop.Enum) - // Don't need to do unquoting; valid enum names - // are from a limited character set. - s := inputValue[1 : len(inputValue)-1] - n, ok := vmap[string(s)] - if !ok { - return fmt.Errorf("unknown value %q for enum %s", s, prop.Enum) - } - if target.Kind() == reflect.Ptr { // proto2 - target.Set(reflect.New(targetType.Elem())) - target = target.Elem() - } - if targetType.Kind() != reflect.Int32 { - return fmt.Errorf("invalid target %q for enum %s", targetType.Kind(), prop.Enum) - } - target.SetInt(int64(n)) - return nil - } - - // Handle nested messages. - if targetType.Kind() == reflect.Struct { - var jsonFields map[string]json.RawMessage - if err := json.Unmarshal(inputValue, &jsonFields); err != nil { - return err - } - - consumeField := func(prop *proto.Properties) (json.RawMessage, bool) { - // Be liberal in what names we accept; both orig_name and camelName are okay. - fieldNames := acceptedJSONFieldNames(prop) - - vOrig, okOrig := jsonFields[fieldNames.orig] - vCamel, okCamel := jsonFields[fieldNames.camel] - if !okOrig && !okCamel { - return nil, false - } - // If, for some reason, both are present in the data, favour the camelName. - var raw json.RawMessage - if okOrig { - raw = vOrig - delete(jsonFields, fieldNames.orig) - } - if okCamel { - raw = vCamel - delete(jsonFields, fieldNames.camel) - } - return raw, true - } - - sprops := proto.GetProperties(targetType) - for i := 0; i < target.NumField(); i++ { - ft := target.Type().Field(i) - if strings.HasPrefix(ft.Name, "XXX_") { - continue - } - - valueForField, ok := consumeField(sprops.Prop[i]) - if !ok { - continue - } - - if err := u.unmarshalValue(target.Field(i), valueForField, sprops.Prop[i]); err != nil { - return err - } - } - // Check for any oneof fields. - if len(jsonFields) > 0 { - for _, oop := range sprops.OneofTypes { - raw, ok := consumeField(oop.Prop) - if !ok { - continue - } - nv := reflect.New(oop.Type.Elem()) - target.Field(oop.Field).Set(nv) - if err := u.unmarshalValue(nv.Elem().Field(0), raw, oop.Prop); err != nil { - return err - } - } - } - // Handle proto2 extensions. - if len(jsonFields) > 0 { - if ep, ok := target.Addr().Interface().(proto.Message); ok { - for _, ext := range proto.RegisteredExtensions(ep) { - name := fmt.Sprintf("[%s]", ext.Name) - raw, ok := jsonFields[name] - if !ok { - continue - } - delete(jsonFields, name) - nv := reflect.New(reflect.TypeOf(ext.ExtensionType).Elem()) - if err := u.unmarshalValue(nv.Elem(), raw, nil); err != nil { - return err - } - if err := proto.SetExtension(ep, ext, nv.Interface()); err != nil { - return err - } - } - } - } - if !u.AllowUnknownFields && len(jsonFields) > 0 { - // Pick any field to be the scapegoat. - var f string - for fname := range jsonFields { - f = fname - break - } - return fmt.Errorf("unknown field %q in %v", f, targetType) - } - return nil - } - - // Handle arrays (which aren't encoded bytes) - if targetType.Kind() == reflect.Slice && targetType.Elem().Kind() != reflect.Uint8 { - var slc []json.RawMessage - if err := json.Unmarshal(inputValue, &slc); err != nil { - return err - } - if slc != nil { - l := len(slc) - target.Set(reflect.MakeSlice(targetType, l, l)) - for i := 0; i < l; i++ { - if err := u.unmarshalValue(target.Index(i), slc[i], prop); err != nil { - return err - } - } - } - return nil - } - - // Handle maps (whose keys are always strings) - if targetType.Kind() == reflect.Map { - var mp map[string]json.RawMessage - if err := json.Unmarshal(inputValue, &mp); err != nil { - return err - } - if mp != nil { - target.Set(reflect.MakeMap(targetType)) - for ks, raw := range mp { - // Unmarshal map key. The core json library already decoded the key into a - // string, so we handle that specially. Other types were quoted post-serialization. - var k reflect.Value - if targetType.Key().Kind() == reflect.String { - k = reflect.ValueOf(ks) - } else { - k = reflect.New(targetType.Key()).Elem() - var kprop *proto.Properties - if prop != nil && prop.MapKeyProp != nil { - kprop = prop.MapKeyProp - } - if err := u.unmarshalValue(k, json.RawMessage(ks), kprop); err != nil { - return err - } - } - - // Unmarshal map value. - v := reflect.New(targetType.Elem()).Elem() - var vprop *proto.Properties - if prop != nil && prop.MapValProp != nil { - vprop = prop.MapValProp - } - if err := u.unmarshalValue(v, raw, vprop); err != nil { - return err - } - target.SetMapIndex(k, v) - } - } - return nil - } - - // Non-finite numbers can be encoded as strings. - isFloat := targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64 - if isFloat { - if num, ok := nonFinite[string(inputValue)]; ok { - target.SetFloat(num) - return nil - } - } - - // integers & floats can be encoded as strings. In this case we drop - // the quotes and proceed as normal. - isNum := targetType.Kind() == reflect.Int64 || targetType.Kind() == reflect.Uint64 || - targetType.Kind() == reflect.Int32 || targetType.Kind() == reflect.Uint32 || - targetType.Kind() == reflect.Float32 || targetType.Kind() == reflect.Float64 - if isNum && strings.HasPrefix(string(inputValue), `"`) { - inputValue = inputValue[1 : len(inputValue)-1] - } - - // Use the encoding/json for parsing other value types. - return json.Unmarshal(inputValue, target.Addr().Interface()) -} - -func unquote(s string) (string, error) { - var ret string - err := json.Unmarshal([]byte(s), &ret) - return ret, err -} - -// jsonProperties returns parsed proto.Properties for the field and corrects JSONName attribute. -func jsonProperties(f reflect.StructField, origName bool) *proto.Properties { - var prop proto.Properties - prop.Init(f.Type, f.Name, f.Tag.Get("protobuf"), &f) - if origName || prop.JSONName == "" { - prop.JSONName = prop.OrigName - } - return &prop -} - -type fieldNames struct { - orig, camel string -} - -func acceptedJSONFieldNames(prop *proto.Properties) fieldNames { - opts := fieldNames{orig: prop.OrigName, camel: prop.OrigName} - if prop.JSONName != "" { - opts.camel = prop.JSONName - } - return opts -} - -// Writer wrapper inspired by https://blog.golang.org/errors-are-values -type errWriter struct { - writer io.Writer - err error -} - -func (w *errWriter) write(str string) { - if w.err != nil { - return - } - _, w.err = w.writer.Write([]byte(str)) -} - -// Map fields may have key types of non-float scalars, strings and enums. -// The easiest way to sort them in some deterministic order is to use fmt. -// If this turns out to be inefficient we can always consider other options, -// such as doing a Schwartzian transform. -// -// Numeric keys are sorted in numeric order per -// https://developers.google.com/protocol-buffers/docs/proto#maps. -type mapKeys []reflect.Value - -func (s mapKeys) Len() int { return len(s) } -func (s mapKeys) Swap(i, j int) { s[i], s[j] = s[j], s[i] } -func (s mapKeys) Less(i, j int) bool { - if k := s[i].Kind(); k == s[j].Kind() { - switch k { - case reflect.String: - return s[i].String() < s[j].String() - case reflect.Int32, reflect.Int64: - return s[i].Int() < s[j].Int() - case reflect.Uint32, reflect.Uint64: - return s[i].Uint() < s[j].Uint() - } - } - return fmt.Sprint(s[i].Interface()) < fmt.Sprint(s[j].Interface()) -} - -// checkRequiredFields returns an error if any required field in the given proto message is not set. -// This function is used by both Marshal and Unmarshal. While required fields only exist in a -// proto2 message, a proto3 message can contain proto2 message(s). -func checkRequiredFields(pb proto.Message) error { - // Most well-known type messages do not contain required fields. The "Any" type may contain - // a message that has required fields. - // - // When an Any message is being marshaled, the code will invoked proto.Unmarshal on Any.Value - // field in order to transform that into JSON, and that should have returned an error if a - // required field is not set in the embedded message. - // - // When an Any message is being unmarshaled, the code will have invoked proto.Marshal on the - // embedded message to store the serialized message in Any.Value field, and that should have - // returned an error if a required field is not set. - if _, ok := pb.(wkt); ok { - return nil - } - - v := reflect.ValueOf(pb) - // Skip message if it is not a struct pointer. - if v.Kind() != reflect.Ptr { - return nil - } - v = v.Elem() - if v.Kind() != reflect.Struct { - return nil - } - - for i := 0; i < v.NumField(); i++ { - field := v.Field(i) - sfield := v.Type().Field(i) - - if sfield.PkgPath != "" { - // blank PkgPath means the field is exported; skip if not exported - continue - } - - if strings.HasPrefix(sfield.Name, "XXX_") { - continue - } - - // Oneof field is an interface implemented by wrapper structs containing the actual oneof - // field, i.e. an interface containing &T{real_value}. - if sfield.Tag.Get("protobuf_oneof") != "" { - if field.Kind() != reflect.Interface { - continue - } - v := field.Elem() - if v.Kind() != reflect.Ptr || v.IsNil() { - continue - } - v = v.Elem() - if v.Kind() != reflect.Struct || v.NumField() < 1 { - continue - } - field = v.Field(0) - sfield = v.Type().Field(0) - } - - protoTag := sfield.Tag.Get("protobuf") - if protoTag == "" { - continue - } - var prop proto.Properties - prop.Init(sfield.Type, sfield.Name, protoTag, &sfield) - - switch field.Kind() { - case reflect.Map: - if field.IsNil() { - continue - } - // Check each map value. - keys := field.MapKeys() - for _, k := range keys { - v := field.MapIndex(k) - if err := checkRequiredFieldsInValue(v); err != nil { - return err - } - } - case reflect.Slice: - // Handle non-repeated type, e.g. bytes. - if !prop.Repeated { - if prop.Required && field.IsNil() { - return fmt.Errorf("required field %q is not set", prop.Name) - } - continue - } - - // Handle repeated type. - if field.IsNil() { - continue - } - // Check each slice item. - for i := 0; i < field.Len(); i++ { - v := field.Index(i) - if err := checkRequiredFieldsInValue(v); err != nil { - return err - } - } - case reflect.Ptr: - if field.IsNil() { - if prop.Required { - return fmt.Errorf("required field %q is not set", prop.Name) - } - continue - } - if err := checkRequiredFieldsInValue(field); err != nil { - return err - } - } - } - - // Handle proto2 extensions. - for _, ext := range proto.RegisteredExtensions(pb) { - if !proto.HasExtension(pb, ext) { - continue - } - ep, err := proto.GetExtension(pb, ext) - if err != nil { - return err - } - err = checkRequiredFieldsInValue(reflect.ValueOf(ep)) - if err != nil { - return err - } - } - - return nil -} - -func checkRequiredFieldsInValue(v reflect.Value) error { - if v.Type().Implements(messageType) { - return checkRequiredFields(v.Interface().(proto.Message)) - } - return nil -} diff --git a/vendor/github.com/golang/protobuf/proto/buffer.go b/vendor/github.com/golang/protobuf/proto/buffer.go new file mode 100644 index 000000000..e810e6fea --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/buffer.go @@ -0,0 +1,324 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "errors" + "fmt" + + "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + WireVarint = 0 + WireFixed32 = 5 + WireFixed64 = 1 + WireBytes = 2 + WireStartGroup = 3 + WireEndGroup = 4 +) + +// EncodeVarint returns the varint encoded bytes of v. +func EncodeVarint(v uint64) []byte { + return protowire.AppendVarint(nil, v) +} + +// SizeVarint returns the length of the varint encoded bytes of v. +// This is equal to len(EncodeVarint(v)). +func SizeVarint(v uint64) int { + return protowire.SizeVarint(v) +} + +// DecodeVarint parses a varint encoded integer from b, +// returning the integer value and the length of the varint. +// It returns (0, 0) if there is a parse error. +func DecodeVarint(b []byte) (uint64, int) { + v, n := protowire.ConsumeVarint(b) + if n < 0 { + return 0, 0 + } + return v, n +} + +// Buffer is a buffer for encoding and decoding the protobuf wire format. +// It may be reused between invocations to reduce memory usage. +type Buffer struct { + buf []byte + idx int + deterministic bool +} + +// NewBuffer allocates a new Buffer initialized with buf, +// where the contents of buf are considered the unread portion of the buffer. +func NewBuffer(buf []byte) *Buffer { + return &Buffer{buf: buf} +} + +// SetDeterministic specifies whether to use deterministic serialization. +// +// Deterministic serialization guarantees that for a given binary, equal +// messages will always be serialized to the same bytes. This implies: +// +// - Repeated serialization of a message will return the same bytes. +// - Different processes of the same binary (which may be executing on +// different machines) will serialize equal messages to the same bytes. +// +// Note that the deterministic serialization is NOT canonical across +// languages. It is not guaranteed to remain stable over time. It is unstable +// across different builds with schema changes due to unknown fields. +// Users who need canonical serialization (e.g., persistent storage in a +// canonical form, fingerprinting, etc.) should define their own +// canonicalization specification and implement their own serializer rather +// than relying on this API. +// +// If deterministic serialization is requested, map entries will be sorted +// by keys in lexographical order. This is an implementation detail and +// subject to change. +func (b *Buffer) SetDeterministic(deterministic bool) { + b.deterministic = deterministic +} + +// SetBuf sets buf as the internal buffer, +// where the contents of buf are considered the unread portion of the buffer. +func (b *Buffer) SetBuf(buf []byte) { + b.buf = buf + b.idx = 0 +} + +// Reset clears the internal buffer of all written and unread data. +func (b *Buffer) Reset() { + b.buf = b.buf[:0] + b.idx = 0 +} + +// Bytes returns the internal buffer. +func (b *Buffer) Bytes() []byte { + return b.buf +} + +// Unread returns the unread portion of the buffer. +func (b *Buffer) Unread() []byte { + return b.buf[b.idx:] +} + +// Marshal appends the wire-format encoding of m to the buffer. +func (b *Buffer) Marshal(m Message) error { + var err error + b.buf, err = marshalAppend(b.buf, m, b.deterministic) + return err +} + +// Unmarshal parses the wire-format message in the buffer and +// places the decoded results in m. +// It does not reset m before unmarshaling. +func (b *Buffer) Unmarshal(m Message) error { + err := UnmarshalMerge(b.Unread(), m) + b.idx = len(b.buf) + return err +} + +type unknownFields struct{ XXX_unrecognized protoimpl.UnknownFields } + +func (m *unknownFields) String() string { panic("not implemented") } +func (m *unknownFields) Reset() { panic("not implemented") } +func (m *unknownFields) ProtoMessage() { panic("not implemented") } + +// DebugPrint dumps the encoded bytes of b with a header and footer including s +// to stdout. This is only intended for debugging. +func (*Buffer) DebugPrint(s string, b []byte) { + m := MessageReflect(new(unknownFields)) + m.SetUnknown(b) + b, _ = prototext.MarshalOptions{AllowPartial: true, Indent: "\t"}.Marshal(m.Interface()) + fmt.Printf("==== %s ====\n%s==== %s ====\n", s, b, s) +} + +// EncodeVarint appends an unsigned varint encoding to the buffer. +func (b *Buffer) EncodeVarint(v uint64) error { + b.buf = protowire.AppendVarint(b.buf, v) + return nil +} + +// EncodeZigzag32 appends a 32-bit zig-zag varint encoding to the buffer. +func (b *Buffer) EncodeZigzag32(v uint64) error { + return b.EncodeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) +} + +// EncodeZigzag64 appends a 64-bit zig-zag varint encoding to the buffer. +func (b *Buffer) EncodeZigzag64(v uint64) error { + return b.EncodeVarint(uint64((uint64(v) << 1) ^ uint64((int64(v) >> 63)))) +} + +// EncodeFixed32 appends a 32-bit little-endian integer to the buffer. +func (b *Buffer) EncodeFixed32(v uint64) error { + b.buf = protowire.AppendFixed32(b.buf, uint32(v)) + return nil +} + +// EncodeFixed64 appends a 64-bit little-endian integer to the buffer. +func (b *Buffer) EncodeFixed64(v uint64) error { + b.buf = protowire.AppendFixed64(b.buf, uint64(v)) + return nil +} + +// EncodeRawBytes appends a length-prefixed raw bytes to the buffer. +func (b *Buffer) EncodeRawBytes(v []byte) error { + b.buf = protowire.AppendBytes(b.buf, v) + return nil +} + +// EncodeStringBytes appends a length-prefixed raw bytes to the buffer. +// It does not validate whether v contains valid UTF-8. +func (b *Buffer) EncodeStringBytes(v string) error { + b.buf = protowire.AppendString(b.buf, v) + return nil +} + +// EncodeMessage appends a length-prefixed encoded message to the buffer. +func (b *Buffer) EncodeMessage(m Message) error { + var err error + b.buf = protowire.AppendVarint(b.buf, uint64(Size(m))) + b.buf, err = marshalAppend(b.buf, m, b.deterministic) + return err +} + +// DecodeVarint consumes an encoded unsigned varint from the buffer. +func (b *Buffer) DecodeVarint() (uint64, error) { + v, n := protowire.ConsumeVarint(b.buf[b.idx:]) + if n < 0 { + return 0, protowire.ParseError(n) + } + b.idx += n + return uint64(v), nil +} + +// DecodeZigzag32 consumes an encoded 32-bit zig-zag varint from the buffer. +func (b *Buffer) DecodeZigzag32() (uint64, error) { + v, err := b.DecodeVarint() + if err != nil { + return 0, err + } + return uint64((uint32(v) >> 1) ^ uint32((int32(v&1)<<31)>>31)), nil +} + +// DecodeZigzag64 consumes an encoded 64-bit zig-zag varint from the buffer. +func (b *Buffer) DecodeZigzag64() (uint64, error) { + v, err := b.DecodeVarint() + if err != nil { + return 0, err + } + return uint64((uint64(v) >> 1) ^ uint64((int64(v&1)<<63)>>63)), nil +} + +// DecodeFixed32 consumes a 32-bit little-endian integer from the buffer. +func (b *Buffer) DecodeFixed32() (uint64, error) { + v, n := protowire.ConsumeFixed32(b.buf[b.idx:]) + if n < 0 { + return 0, protowire.ParseError(n) + } + b.idx += n + return uint64(v), nil +} + +// DecodeFixed64 consumes a 64-bit little-endian integer from the buffer. +func (b *Buffer) DecodeFixed64() (uint64, error) { + v, n := protowire.ConsumeFixed64(b.buf[b.idx:]) + if n < 0 { + return 0, protowire.ParseError(n) + } + b.idx += n + return uint64(v), nil +} + +// DecodeRawBytes consumes a length-prefixed raw bytes from the buffer. +// If alloc is specified, it returns a copy the raw bytes +// rather than a sub-slice of the buffer. +func (b *Buffer) DecodeRawBytes(alloc bool) ([]byte, error) { + v, n := protowire.ConsumeBytes(b.buf[b.idx:]) + if n < 0 { + return nil, protowire.ParseError(n) + } + b.idx += n + if alloc { + v = append([]byte(nil), v...) + } + return v, nil +} + +// DecodeStringBytes consumes a length-prefixed raw bytes from the buffer. +// It does not validate whether the raw bytes contain valid UTF-8. +func (b *Buffer) DecodeStringBytes() (string, error) { + v, n := protowire.ConsumeString(b.buf[b.idx:]) + if n < 0 { + return "", protowire.ParseError(n) + } + b.idx += n + return v, nil +} + +// DecodeMessage consumes a length-prefixed message from the buffer. +// It does not reset m before unmarshaling. +func (b *Buffer) DecodeMessage(m Message) error { + v, err := b.DecodeRawBytes(false) + if err != nil { + return err + } + return UnmarshalMerge(v, m) +} + +// DecodeGroup consumes a message group from the buffer. +// It assumes that the start group marker has already been consumed and +// consumes all bytes until (and including the end group marker). +// It does not reset m before unmarshaling. +func (b *Buffer) DecodeGroup(m Message) error { + v, n, err := consumeGroup(b.buf[b.idx:]) + if err != nil { + return err + } + b.idx += n + return UnmarshalMerge(v, m) +} + +// consumeGroup parses b until it finds an end group marker, returning +// the raw bytes of the message (excluding the end group marker) and the +// the total length of the message (including the end group marker). +func consumeGroup(b []byte) ([]byte, int, error) { + b0 := b + depth := 1 // assume this follows a start group marker + for { + _, wtyp, tagLen := protowire.ConsumeTag(b) + if tagLen < 0 { + return nil, 0, protowire.ParseError(tagLen) + } + b = b[tagLen:] + + var valLen int + switch wtyp { + case protowire.VarintType: + _, valLen = protowire.ConsumeVarint(b) + case protowire.Fixed32Type: + _, valLen = protowire.ConsumeFixed32(b) + case protowire.Fixed64Type: + _, valLen = protowire.ConsumeFixed64(b) + case protowire.BytesType: + _, valLen = protowire.ConsumeBytes(b) + case protowire.StartGroupType: + depth++ + case protowire.EndGroupType: + depth-- + default: + return nil, 0, errors.New("proto: cannot parse reserved wire type") + } + if valLen < 0 { + return nil, 0, protowire.ParseError(valLen) + } + b = b[valLen:] + + if depth == 0 { + return b0[:len(b0)-len(b)-tagLen], len(b0) - len(b), nil + } + } +} diff --git a/vendor/github.com/golang/protobuf/proto/clone.go b/vendor/github.com/golang/protobuf/proto/clone.go deleted file mode 100644 index 3cd3249f7..000000000 --- a/vendor/github.com/golang/protobuf/proto/clone.go +++ /dev/null @@ -1,253 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2011 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Protocol buffer deep copy and merge. -// TODO: RawMessage. - -package proto - -import ( - "fmt" - "log" - "reflect" - "strings" -) - -// Clone returns a deep copy of a protocol buffer. -func Clone(src Message) Message { - in := reflect.ValueOf(src) - if in.IsNil() { - return src - } - out := reflect.New(in.Type().Elem()) - dst := out.Interface().(Message) - Merge(dst, src) - return dst -} - -// Merger is the interface representing objects that can merge messages of the same type. -type Merger interface { - // Merge merges src into this message. - // Required and optional fields that are set in src will be set to that value in dst. - // Elements of repeated fields will be appended. - // - // Merge may panic if called with a different argument type than the receiver. - Merge(src Message) -} - -// generatedMerger is the custom merge method that generated protos will have. -// We must add this method since a generate Merge method will conflict with -// many existing protos that have a Merge data field already defined. -type generatedMerger interface { - XXX_Merge(src Message) -} - -// Merge merges src into dst. -// Required and optional fields that are set in src will be set to that value in dst. -// Elements of repeated fields will be appended. -// Merge panics if src and dst are not the same type, or if dst is nil. -func Merge(dst, src Message) { - if m, ok := dst.(Merger); ok { - m.Merge(src) - return - } - - in := reflect.ValueOf(src) - out := reflect.ValueOf(dst) - if out.IsNil() { - panic("proto: nil destination") - } - if in.Type() != out.Type() { - panic(fmt.Sprintf("proto.Merge(%T, %T) type mismatch", dst, src)) - } - if in.IsNil() { - return // Merge from nil src is a noop - } - if m, ok := dst.(generatedMerger); ok { - m.XXX_Merge(src) - return - } - mergeStruct(out.Elem(), in.Elem()) -} - -func mergeStruct(out, in reflect.Value) { - sprop := GetProperties(in.Type()) - for i := 0; i < in.NumField(); i++ { - f := in.Type().Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - mergeAny(out.Field(i), in.Field(i), false, sprop.Prop[i]) - } - - if emIn, err := extendable(in.Addr().Interface()); err == nil { - emOut, _ := extendable(out.Addr().Interface()) - mIn, muIn := emIn.extensionsRead() - if mIn != nil { - mOut := emOut.extensionsWrite() - muIn.Lock() - mergeExtension(mOut, mIn) - muIn.Unlock() - } - } - - uf := in.FieldByName("XXX_unrecognized") - if !uf.IsValid() { - return - } - uin := uf.Bytes() - if len(uin) > 0 { - out.FieldByName("XXX_unrecognized").SetBytes(append([]byte(nil), uin...)) - } -} - -// mergeAny performs a merge between two values of the same type. -// viaPtr indicates whether the values were indirected through a pointer (implying proto2). -// prop is set if this is a struct field (it may be nil). -func mergeAny(out, in reflect.Value, viaPtr bool, prop *Properties) { - if in.Type() == protoMessageType { - if !in.IsNil() { - if out.IsNil() { - out.Set(reflect.ValueOf(Clone(in.Interface().(Message)))) - } else { - Merge(out.Interface().(Message), in.Interface().(Message)) - } - } - return - } - switch in.Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64: - if !viaPtr && isProto3Zero(in) { - return - } - out.Set(in) - case reflect.Interface: - // Probably a oneof field; copy non-nil values. - if in.IsNil() { - return - } - // Allocate destination if it is not set, or set to a different type. - // Otherwise we will merge as normal. - if out.IsNil() || out.Elem().Type() != in.Elem().Type() { - out.Set(reflect.New(in.Elem().Elem().Type())) // interface -> *T -> T -> new(T) - } - mergeAny(out.Elem(), in.Elem(), false, nil) - case reflect.Map: - if in.Len() == 0 { - return - } - if out.IsNil() { - out.Set(reflect.MakeMap(in.Type())) - } - // For maps with value types of *T or []byte we need to deep copy each value. - elemKind := in.Type().Elem().Kind() - for _, key := range in.MapKeys() { - var val reflect.Value - switch elemKind { - case reflect.Ptr: - val = reflect.New(in.Type().Elem().Elem()) - mergeAny(val, in.MapIndex(key), false, nil) - case reflect.Slice: - val = in.MapIndex(key) - val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) - default: - val = in.MapIndex(key) - } - out.SetMapIndex(key, val) - } - case reflect.Ptr: - if in.IsNil() { - return - } - if out.IsNil() { - out.Set(reflect.New(in.Elem().Type())) - } - mergeAny(out.Elem(), in.Elem(), true, nil) - case reflect.Slice: - if in.IsNil() { - return - } - if in.Type().Elem().Kind() == reflect.Uint8 { - // []byte is a scalar bytes field, not a repeated field. - - // Edge case: if this is in a proto3 message, a zero length - // bytes field is considered the zero value, and should not - // be merged. - if prop != nil && prop.proto3 && in.Len() == 0 { - return - } - - // Make a deep copy. - // Append to []byte{} instead of []byte(nil) so that we never end up - // with a nil result. - out.SetBytes(append([]byte{}, in.Bytes()...)) - return - } - n := in.Len() - if out.IsNil() { - out.Set(reflect.MakeSlice(in.Type(), 0, n)) - } - switch in.Type().Elem().Kind() { - case reflect.Bool, reflect.Float32, reflect.Float64, reflect.Int32, reflect.Int64, - reflect.String, reflect.Uint32, reflect.Uint64: - out.Set(reflect.AppendSlice(out, in)) - default: - for i := 0; i < n; i++ { - x := reflect.Indirect(reflect.New(in.Type().Elem())) - mergeAny(x, in.Index(i), false, nil) - out.Set(reflect.Append(out, x)) - } - } - case reflect.Struct: - mergeStruct(out, in) - default: - // unknown type, so not a protocol buffer - log.Printf("proto: don't know how to copy %v", in) - } -} - -func mergeExtension(out, in map[int32]Extension) { - for extNum, eIn := range in { - eOut := Extension{desc: eIn.desc} - if eIn.value != nil { - v := reflect.New(reflect.TypeOf(eIn.value)).Elem() - mergeAny(v, reflect.ValueOf(eIn.value), false, nil) - eOut.value = v.Interface() - } - if eIn.enc != nil { - eOut.enc = make([]byte, len(eIn.enc)) - copy(eOut.enc, eIn.enc) - } - - out[extNum] = eOut - } -} diff --git a/vendor/github.com/golang/protobuf/proto/decode.go b/vendor/github.com/golang/protobuf/proto/decode.go deleted file mode 100644 index 63b0f08be..000000000 --- a/vendor/github.com/golang/protobuf/proto/decode.go +++ /dev/null @@ -1,427 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for decoding protocol buffer data to construct in-memory representations. - */ - -import ( - "errors" - "fmt" - "io" -) - -// errOverflow is returned when an integer is too large to be represented. -var errOverflow = errors.New("proto: integer overflow") - -// ErrInternalBadWireType is returned by generated code when an incorrect -// wire type is encountered. It does not get returned to user code. -var ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") - -// DecodeVarint reads a varint-encoded integer from the slice. -// It returns the integer and the number of bytes consumed, or -// zero if there is not enough. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func DecodeVarint(buf []byte) (x uint64, n int) { - for shift := uint(0); shift < 64; shift += 7 { - if n >= len(buf) { - return 0, 0 - } - b := uint64(buf[n]) - n++ - x |= (b & 0x7F) << shift - if (b & 0x80) == 0 { - return x, n - } - } - - // The number is too large to represent in a 64-bit value. - return 0, 0 -} - -func (p *Buffer) decodeVarintSlow() (x uint64, err error) { - i := p.index - l := len(p.buf) - - for shift := uint(0); shift < 64; shift += 7 { - if i >= l { - err = io.ErrUnexpectedEOF - return - } - b := p.buf[i] - i++ - x |= (uint64(b) & 0x7F) << shift - if b < 0x80 { - p.index = i - return - } - } - - // The number is too large to represent in a 64-bit value. - err = errOverflow - return -} - -// DecodeVarint reads a varint-encoded integer from the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) DecodeVarint() (x uint64, err error) { - i := p.index - buf := p.buf - - if i >= len(buf) { - return 0, io.ErrUnexpectedEOF - } else if buf[i] < 0x80 { - p.index++ - return uint64(buf[i]), nil - } else if len(buf)-i < 10 { - return p.decodeVarintSlow() - } - - var b uint64 - // we already checked the first byte - x = uint64(buf[i]) - 0x80 - i++ - - b = uint64(buf[i]) - i++ - x += b << 7 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 7 - - b = uint64(buf[i]) - i++ - x += b << 14 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 14 - - b = uint64(buf[i]) - i++ - x += b << 21 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 21 - - b = uint64(buf[i]) - i++ - x += b << 28 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 28 - - b = uint64(buf[i]) - i++ - x += b << 35 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 35 - - b = uint64(buf[i]) - i++ - x += b << 42 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 42 - - b = uint64(buf[i]) - i++ - x += b << 49 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 49 - - b = uint64(buf[i]) - i++ - x += b << 56 - if b&0x80 == 0 { - goto done - } - x -= 0x80 << 56 - - b = uint64(buf[i]) - i++ - x += b << 63 - if b&0x80 == 0 { - goto done - } - - return 0, errOverflow - -done: - p.index = i - return x, nil -} - -// DecodeFixed64 reads a 64-bit integer from the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (p *Buffer) DecodeFixed64() (x uint64, err error) { - // x, err already 0 - i := p.index + 8 - if i < 0 || i > len(p.buf) { - err = io.ErrUnexpectedEOF - return - } - p.index = i - - x = uint64(p.buf[i-8]) - x |= uint64(p.buf[i-7]) << 8 - x |= uint64(p.buf[i-6]) << 16 - x |= uint64(p.buf[i-5]) << 24 - x |= uint64(p.buf[i-4]) << 32 - x |= uint64(p.buf[i-3]) << 40 - x |= uint64(p.buf[i-2]) << 48 - x |= uint64(p.buf[i-1]) << 56 - return -} - -// DecodeFixed32 reads a 32-bit integer from the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (p *Buffer) DecodeFixed32() (x uint64, err error) { - // x, err already 0 - i := p.index + 4 - if i < 0 || i > len(p.buf) { - err = io.ErrUnexpectedEOF - return - } - p.index = i - - x = uint64(p.buf[i-4]) - x |= uint64(p.buf[i-3]) << 8 - x |= uint64(p.buf[i-2]) << 16 - x |= uint64(p.buf[i-1]) << 24 - return -} - -// DecodeZigzag64 reads a zigzag-encoded 64-bit integer -// from the Buffer. -// This is the format used for the sint64 protocol buffer type. -func (p *Buffer) DecodeZigzag64() (x uint64, err error) { - x, err = p.DecodeVarint() - if err != nil { - return - } - x = (x >> 1) ^ uint64((int64(x&1)<<63)>>63) - return -} - -// DecodeZigzag32 reads a zigzag-encoded 32-bit integer -// from the Buffer. -// This is the format used for the sint32 protocol buffer type. -func (p *Buffer) DecodeZigzag32() (x uint64, err error) { - x, err = p.DecodeVarint() - if err != nil { - return - } - x = uint64((uint32(x) >> 1) ^ uint32((int32(x&1)<<31)>>31)) - return -} - -// DecodeRawBytes reads a count-delimited byte buffer from the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (p *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { - n, err := p.DecodeVarint() - if err != nil { - return nil, err - } - - nb := int(n) - if nb < 0 { - return nil, fmt.Errorf("proto: bad byte length %d", nb) - } - end := p.index + nb - if end < p.index || end > len(p.buf) { - return nil, io.ErrUnexpectedEOF - } - - if !alloc { - // todo: check if can get more uses of alloc=false - buf = p.buf[p.index:end] - p.index += nb - return - } - - buf = make([]byte, nb) - copy(buf, p.buf[p.index:]) - p.index += nb - return -} - -// DecodeStringBytes reads an encoded string from the Buffer. -// This is the format used for the proto2 string type. -func (p *Buffer) DecodeStringBytes() (s string, err error) { - buf, err := p.DecodeRawBytes(false) - if err != nil { - return - } - return string(buf), nil -} - -// Unmarshaler is the interface representing objects that can -// unmarshal themselves. The argument points to data that may be -// overwritten, so implementations should not keep references to the -// buffer. -// Unmarshal implementations should not clear the receiver. -// Any unmarshaled data should be merged into the receiver. -// Callers of Unmarshal that do not want to retain existing data -// should Reset the receiver before calling Unmarshal. -type Unmarshaler interface { - Unmarshal([]byte) error -} - -// newUnmarshaler is the interface representing objects that can -// unmarshal themselves. The semantics are identical to Unmarshaler. -// -// This exists to support protoc-gen-go generated messages. -// The proto package will stop type-asserting to this interface in the future. -// -// DO NOT DEPEND ON THIS. -type newUnmarshaler interface { - XXX_Unmarshal([]byte) error -} - -// Unmarshal parses the protocol buffer representation in buf and places the -// decoded result in pb. If the struct underlying pb does not match -// the data in buf, the results can be unpredictable. -// -// Unmarshal resets pb before starting to unmarshal, so any -// existing data in pb is always removed. Use UnmarshalMerge -// to preserve and append to existing data. -func Unmarshal(buf []byte, pb Message) error { - pb.Reset() - if u, ok := pb.(newUnmarshaler); ok { - return u.XXX_Unmarshal(buf) - } - if u, ok := pb.(Unmarshaler); ok { - return u.Unmarshal(buf) - } - return NewBuffer(buf).Unmarshal(pb) -} - -// UnmarshalMerge parses the protocol buffer representation in buf and -// writes the decoded result to pb. If the struct underlying pb does not match -// the data in buf, the results can be unpredictable. -// -// UnmarshalMerge merges into existing data in pb. -// Most code should use Unmarshal instead. -func UnmarshalMerge(buf []byte, pb Message) error { - if u, ok := pb.(newUnmarshaler); ok { - return u.XXX_Unmarshal(buf) - } - if u, ok := pb.(Unmarshaler); ok { - // NOTE: The history of proto have unfortunately been inconsistent - // whether Unmarshaler should or should not implicitly clear itself. - // Some implementations do, most do not. - // Thus, calling this here may or may not do what people want. - // - // See https://github.com/golang/protobuf/issues/424 - return u.Unmarshal(buf) - } - return NewBuffer(buf).Unmarshal(pb) -} - -// DecodeMessage reads a count-delimited message from the Buffer. -func (p *Buffer) DecodeMessage(pb Message) error { - enc, err := p.DecodeRawBytes(false) - if err != nil { - return err - } - return NewBuffer(enc).Unmarshal(pb) -} - -// DecodeGroup reads a tag-delimited group from the Buffer. -// StartGroup tag is already consumed. This function consumes -// EndGroup tag. -func (p *Buffer) DecodeGroup(pb Message) error { - b := p.buf[p.index:] - x, y := findEndGroup(b) - if x < 0 { - return io.ErrUnexpectedEOF - } - err := Unmarshal(b[:x], pb) - p.index += y - return err -} - -// Unmarshal parses the protocol buffer representation in the -// Buffer and places the decoded result in pb. If the struct -// underlying pb does not match the data in the buffer, the results can be -// unpredictable. -// -// Unlike proto.Unmarshal, this does not reset pb before starting to unmarshal. -func (p *Buffer) Unmarshal(pb Message) error { - // If the object can unmarshal itself, let it. - if u, ok := pb.(newUnmarshaler); ok { - err := u.XXX_Unmarshal(p.buf[p.index:]) - p.index = len(p.buf) - return err - } - if u, ok := pb.(Unmarshaler); ok { - // NOTE: The history of proto have unfortunately been inconsistent - // whether Unmarshaler should or should not implicitly clear itself. - // Some implementations do, most do not. - // Thus, calling this here may or may not do what people want. - // - // See https://github.com/golang/protobuf/issues/424 - err := u.Unmarshal(p.buf[p.index:]) - p.index = len(p.buf) - return err - } - - // Slow workaround for messages that aren't Unmarshalers. - // This includes some hand-coded .pb.go files and - // bootstrap protos. - // TODO: fix all of those and then add Unmarshal to - // the Message interface. Then: - // The cast above and code below can be deleted. - // The old unmarshaler can be deleted. - // Clients can call Unmarshal directly (can already do that, actually). - var info InternalMessageInfo - err := info.Unmarshal(pb, p.buf[p.index:]) - p.index = len(p.buf) - return err -} diff --git a/vendor/github.com/golang/protobuf/proto/defaults.go b/vendor/github.com/golang/protobuf/proto/defaults.go new file mode 100644 index 000000000..d399bf069 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/defaults.go @@ -0,0 +1,63 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "google.golang.org/protobuf/reflect/protoreflect" +) + +// SetDefaults sets unpopulated scalar fields to their default values. +// Fields within a oneof are not set even if they have a default value. +// SetDefaults is recursively called upon any populated message fields. +func SetDefaults(m Message) { + if m != nil { + setDefaults(MessageReflect(m)) + } +} + +func setDefaults(m protoreflect.Message) { + fds := m.Descriptor().Fields() + for i := 0; i < fds.Len(); i++ { + fd := fds.Get(i) + if !m.Has(fd) { + if fd.HasDefault() && fd.ContainingOneof() == nil { + v := fd.Default() + if fd.Kind() == protoreflect.BytesKind { + v = protoreflect.ValueOf(append([]byte(nil), v.Bytes()...)) // copy the default bytes + } + m.Set(fd, v) + } + continue + } + } + + m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + switch { + // Handle singular message. + case fd.Cardinality() != protoreflect.Repeated: + if fd.Message() != nil { + setDefaults(m.Get(fd).Message()) + } + // Handle list of messages. + case fd.IsList(): + if fd.Message() != nil { + ls := m.Get(fd).List() + for i := 0; i < ls.Len(); i++ { + setDefaults(ls.Get(i).Message()) + } + } + // Handle map of messages. + case fd.IsMap(): + if fd.MapValue().Message() != nil { + ms := m.Get(fd).Map() + ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool { + setDefaults(v.Message()) + return true + }) + } + } + return true + }) +} diff --git a/vendor/github.com/golang/protobuf/proto/deprecated.go b/vendor/github.com/golang/protobuf/proto/deprecated.go index 35b882c09..e8db57e09 100644 --- a/vendor/github.com/golang/protobuf/proto/deprecated.go +++ b/vendor/github.com/golang/protobuf/proto/deprecated.go @@ -1,63 +1,113 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2018 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. package proto -import "errors" +import ( + "encoding/json" + "errors" + "fmt" + "strconv" -// Deprecated: do not use. + protoV2 "google.golang.org/protobuf/proto" +) + +var ( + // Deprecated: No longer returned. + ErrNil = errors.New("proto: Marshal called with nil") + + // Deprecated: No longer returned. + ErrTooLarge = errors.New("proto: message encodes to over 2 GB") + + // Deprecated: No longer returned. + ErrInternalBadWireType = errors.New("proto: internal error: bad wiretype for oneof") +) + +// Deprecated: Do not use. type Stats struct{ Emalloc, Dmalloc, Encode, Decode, Chit, Cmiss, Size uint64 } -// Deprecated: do not use. +// Deprecated: Do not use. func GetStats() Stats { return Stats{} } -// Deprecated: do not use. +// Deprecated: Do not use. func MarshalMessageSet(interface{}) ([]byte, error) { return nil, errors.New("proto: not implemented") } -// Deprecated: do not use. +// Deprecated: Do not use. func UnmarshalMessageSet([]byte, interface{}) error { return errors.New("proto: not implemented") } -// Deprecated: do not use. +// Deprecated: Do not use. func MarshalMessageSetJSON(interface{}) ([]byte, error) { return nil, errors.New("proto: not implemented") } -// Deprecated: do not use. +// Deprecated: Do not use. func UnmarshalMessageSetJSON([]byte, interface{}) error { return errors.New("proto: not implemented") } -// Deprecated: do not use. +// Deprecated: Do not use. func RegisterMessageSetType(Message, int32, string) {} + +// Deprecated: Do not use. +func EnumName(m map[int32]string, v int32) string { + s, ok := m[v] + if ok { + return s + } + return strconv.Itoa(int(v)) +} + +// Deprecated: Do not use. +func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { + if data[0] == '"' { + // New style: enums are strings. + var repr string + if err := json.Unmarshal(data, &repr); err != nil { + return -1, err + } + val, ok := m[repr] + if !ok { + return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) + } + return val, nil + } + // Old style: enums are ints. + var val int32 + if err := json.Unmarshal(data, &val); err != nil { + return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) + } + return val, nil +} + +// Deprecated: Do not use; this type existed for intenal-use only. +type InternalMessageInfo struct{} + +// Deprecated: Do not use; this method existed for intenal-use only. +func (*InternalMessageInfo) DiscardUnknown(m Message) { + DiscardUnknown(m) +} + +// Deprecated: Do not use; this method existed for intenal-use only. +func (*InternalMessageInfo) Marshal(b []byte, m Message, deterministic bool) ([]byte, error) { + return protoV2.MarshalOptions{Deterministic: deterministic}.MarshalAppend(b, MessageV2(m)) +} + +// Deprecated: Do not use; this method existed for intenal-use only. +func (*InternalMessageInfo) Merge(dst, src Message) { + protoV2.Merge(MessageV2(dst), MessageV2(src)) +} + +// Deprecated: Do not use; this method existed for intenal-use only. +func (*InternalMessageInfo) Size(m Message) int { + return protoV2.Size(MessageV2(m)) +} + +// Deprecated: Do not use; this method existed for intenal-use only. +func (*InternalMessageInfo) Unmarshal(m Message, b []byte) error { + return protoV2.UnmarshalOptions{Merge: true}.Unmarshal(b, MessageV2(m)) +} diff --git a/vendor/github.com/golang/protobuf/proto/discard.go b/vendor/github.com/golang/protobuf/proto/discard.go index dea2617ce..2187e877f 100644 --- a/vendor/github.com/golang/protobuf/proto/discard.go +++ b/vendor/github.com/golang/protobuf/proto/discard.go @@ -1,48 +1,13 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2017 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. package proto import ( - "fmt" - "reflect" - "strings" - "sync" - "sync/atomic" + "google.golang.org/protobuf/reflect/protoreflect" ) -type generatedDiscarder interface { - XXX_DiscardUnknown() -} - // DiscardUnknown recursively discards all unknown fields from this message // and all embedded messages. // @@ -51,300 +16,43 @@ type generatedDiscarder interface { // marshal to be able to produce a message that continues to have those // unrecognized fields. To avoid this, DiscardUnknown is used to // explicitly clear the unknown fields after unmarshaling. -// -// For proto2 messages, the unknown fields of message extensions are only -// discarded from messages that have been accessed via GetExtension. func DiscardUnknown(m Message) { - if m, ok := m.(generatedDiscarder); ok { - m.XXX_DiscardUnknown() - return - } - // TODO: Dynamically populate a InternalMessageInfo for legacy messages, - // but the master branch has no implementation for InternalMessageInfo, - // so it would be more work to replicate that approach. - discardLegacy(m) -} - -// DiscardUnknown recursively discards all unknown fields. -func (a *InternalMessageInfo) DiscardUnknown(m Message) { - di := atomicLoadDiscardInfo(&a.discard) - if di == nil { - di = getDiscardInfo(reflect.TypeOf(m).Elem()) - atomicStoreDiscardInfo(&a.discard, di) - } - di.discard(toPointer(&m)) -} - -type discardInfo struct { - typ reflect.Type - - initialized int32 // 0: only typ is valid, 1: everything is valid - lock sync.Mutex - - fields []discardFieldInfo - unrecognized field -} - -type discardFieldInfo struct { - field field // Offset of field, guaranteed to be valid - discard func(src pointer) -} - -var ( - discardInfoMap = map[reflect.Type]*discardInfo{} - discardInfoLock sync.Mutex -) - -func getDiscardInfo(t reflect.Type) *discardInfo { - discardInfoLock.Lock() - defer discardInfoLock.Unlock() - di := discardInfoMap[t] - if di == nil { - di = &discardInfo{typ: t} - discardInfoMap[t] = di + if m != nil { + discardUnknown(MessageReflect(m)) } - return di } -func (di *discardInfo) discard(src pointer) { - if src.isNil() { - return // Nothing to do. - } - - if atomic.LoadInt32(&di.initialized) == 0 { - di.computeDiscardInfo() - } - - for _, fi := range di.fields { - sfp := src.offset(fi.field) - fi.discard(sfp) - } - - // For proto2 messages, only discard unknown fields in message extensions - // that have been accessed via GetExtension. - if em, err := extendable(src.asPointerTo(di.typ).Interface()); err == nil { - // Ignore lock since DiscardUnknown is not concurrency safe. - emm, _ := em.extensionsRead() - for _, mx := range emm { - if m, ok := mx.value.(Message); ok { - DiscardUnknown(m) +func discardUnknown(m protoreflect.Message) { + m.Range(func(fd protoreflect.FieldDescriptor, val protoreflect.Value) bool { + switch { + // Handle singular message. + case fd.Cardinality() != protoreflect.Repeated: + if fd.Message() != nil { + discardUnknown(m.Get(fd).Message()) } - } - } - - if di.unrecognized.IsValid() { - *src.offset(di.unrecognized).toBytes() = nil - } -} - -func (di *discardInfo) computeDiscardInfo() { - di.lock.Lock() - defer di.lock.Unlock() - if di.initialized != 0 { - return - } - t := di.typ - n := t.NumField() - - for i := 0; i < n; i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - - dfi := discardFieldInfo{field: toField(&f)} - tf := f.Type - - // Unwrap tf to get its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic(fmt.Sprintf("%v.%s cannot be a slice of pointers to primitive types", t, f.Name)) - } - - switch tf.Kind() { - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("%v.%s cannot be a direct struct value", t, f.Name)) - case isSlice: // E.g., []*pb.T - di := getDiscardInfo(tf) - dfi.discard = func(src pointer) { - sps := src.getPointerSlice() - for _, sp := range sps { - if !sp.isNil() { - di.discard(sp) - } - } - } - default: // E.g., *pb.T - di := getDiscardInfo(tf) - dfi.discard = func(src pointer) { - sp := src.getPointer() - if !sp.isNil() { - di.discard(sp) - } + // Handle list of messages. + case fd.IsList(): + if fd.Message() != nil { + ls := m.Get(fd).List() + for i := 0; i < ls.Len(); i++ { + discardUnknown(ls.Get(i).Message()) } } - case reflect.Map: - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%v.%s cannot be a pointer to a map or a slice of map values", t, f.Name)) - default: // E.g., map[K]V - if tf.Elem().Kind() == reflect.Ptr { // Proto struct (e.g., *T) - dfi.discard = func(src pointer) { - sm := src.asPointerTo(tf).Elem() - if sm.Len() == 0 { - return - } - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - DiscardUnknown(val.Interface().(Message)) - } - } - } else { - dfi.discard = func(pointer) {} // Noop - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%v.%s cannot be a pointer to a interface or a slice of interface values", t, f.Name)) - default: // E.g., interface{} - // TODO: Make this faster? - dfi.discard = func(src pointer) { - su := src.asPointerTo(tf).Elem() - if !su.IsNil() { - sv := su.Elem().Elem().Field(0) - if sv.Kind() == reflect.Ptr && sv.IsNil() { - return - } - switch sv.Type().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - DiscardUnknown(sv.Interface().(Message)) - } - } - } + // Handle map of messages. + case fd.IsMap(): + if fd.MapValue().Message() != nil { + ms := m.Get(fd).Map() + ms.Range(func(_ protoreflect.MapKey, v protoreflect.Value) bool { + discardUnknown(v.Message()) + return true + }) } - default: - continue - } - di.fields = append(di.fields, dfi) - } - - di.unrecognized = invalidField - if f, ok := t.FieldByName("XXX_unrecognized"); ok { - if f.Type != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - di.unrecognized = toField(&f) - } - - atomic.StoreInt32(&di.initialized, 1) -} - -func discardLegacy(m Message) { - v := reflect.ValueOf(m) - if v.Kind() != reflect.Ptr || v.IsNil() { - return - } - v = v.Elem() - if v.Kind() != reflect.Struct { - return - } - t := v.Type() - - for i := 0; i < v.NumField(); i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue } - vf := v.Field(i) - tf := f.Type + return true + }) - // Unwrap tf to get its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic(fmt.Sprintf("%T.%s cannot be a slice of pointers to primitive types", m, f.Name)) - } - - switch tf.Kind() { - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("%T.%s cannot be a direct struct value", m, f.Name)) - case isSlice: // E.g., []*pb.T - for j := 0; j < vf.Len(); j++ { - discardLegacy(vf.Index(j).Interface().(Message)) - } - default: // E.g., *pb.T - discardLegacy(vf.Interface().(Message)) - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%T.%s cannot be a pointer to a map or a slice of map values", m, f.Name)) - default: // E.g., map[K]V - tv := vf.Type().Elem() - if tv.Kind() == reflect.Ptr && tv.Implements(protoMessageType) { // Proto struct (e.g., *T) - for _, key := range vf.MapKeys() { - val := vf.MapIndex(key) - discardLegacy(val.Interface().(Message)) - } - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic(fmt.Sprintf("%T.%s cannot be a pointer to a interface or a slice of interface values", m, f.Name)) - default: // E.g., test_proto.isCommunique_Union interface - if !vf.IsNil() && f.Tag.Get("protobuf_oneof") != "" { - vf = vf.Elem() // E.g., *test_proto.Communique_Msg - if !vf.IsNil() { - vf = vf.Elem() // E.g., test_proto.Communique_Msg - vf = vf.Field(0) // E.g., Proto struct (e.g., *T) or primitive value - if vf.Kind() == reflect.Ptr { - discardLegacy(vf.Interface().(Message)) - } - } - } - } - } - } - - if vf := v.FieldByName("XXX_unrecognized"); vf.IsValid() { - if vf.Type() != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - vf.Set(reflect.ValueOf([]byte(nil))) - } - - // For proto2 messages, only discard unknown fields in message extensions - // that have been accessed via GetExtension. - if em, err := extendable(m); err == nil { - // Ignore lock since discardLegacy is not concurrency safe. - emm, _ := em.extensionsRead() - for _, mx := range emm { - if m, ok := mx.value.(Message); ok { - discardLegacy(m) - } - } + // Discard unknown fields. + if len(m.GetUnknown()) > 0 { + m.SetUnknown(nil) } } diff --git a/vendor/github.com/golang/protobuf/proto/encode.go b/vendor/github.com/golang/protobuf/proto/encode.go deleted file mode 100644 index 3abfed2cf..000000000 --- a/vendor/github.com/golang/protobuf/proto/encode.go +++ /dev/null @@ -1,203 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Routines for encoding data into the wire format for protocol buffers. - */ - -import ( - "errors" - "reflect" -) - -var ( - // errRepeatedHasNil is the error returned if Marshal is called with - // a struct with a repeated field containing a nil element. - errRepeatedHasNil = errors.New("proto: repeated field has nil element") - - // errOneofHasNil is the error returned if Marshal is called with - // a struct with a oneof field containing a nil element. - errOneofHasNil = errors.New("proto: oneof field has nil value") - - // ErrNil is the error returned if Marshal is called with nil. - ErrNil = errors.New("proto: Marshal called with nil") - - // ErrTooLarge is the error returned if Marshal is called with a - // message that encodes to >2GB. - ErrTooLarge = errors.New("proto: message encodes to over 2 GB") -) - -// The fundamental encoders that put bytes on the wire. -// Those that take integer types all accept uint64 and are -// therefore of type valueEncoder. - -const maxVarintBytes = 10 // maximum length of a varint - -// EncodeVarint returns the varint encoding of x. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -// Not used by the package itself, but helpful to clients -// wishing to use the same encoding. -func EncodeVarint(x uint64) []byte { - var buf [maxVarintBytes]byte - var n int - for n = 0; x > 127; n++ { - buf[n] = 0x80 | uint8(x&0x7F) - x >>= 7 - } - buf[n] = uint8(x) - n++ - return buf[0:n] -} - -// EncodeVarint writes a varint-encoded integer to the Buffer. -// This is the format for the -// int32, int64, uint32, uint64, bool, and enum -// protocol buffer types. -func (p *Buffer) EncodeVarint(x uint64) error { - for x >= 1<<7 { - p.buf = append(p.buf, uint8(x&0x7f|0x80)) - x >>= 7 - } - p.buf = append(p.buf, uint8(x)) - return nil -} - -// SizeVarint returns the varint encoding size of an integer. -func SizeVarint(x uint64) int { - switch { - case x < 1<<7: - return 1 - case x < 1<<14: - return 2 - case x < 1<<21: - return 3 - case x < 1<<28: - return 4 - case x < 1<<35: - return 5 - case x < 1<<42: - return 6 - case x < 1<<49: - return 7 - case x < 1<<56: - return 8 - case x < 1<<63: - return 9 - } - return 10 -} - -// EncodeFixed64 writes a 64-bit integer to the Buffer. -// This is the format for the -// fixed64, sfixed64, and double protocol buffer types. -func (p *Buffer) EncodeFixed64(x uint64) error { - p.buf = append(p.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24), - uint8(x>>32), - uint8(x>>40), - uint8(x>>48), - uint8(x>>56)) - return nil -} - -// EncodeFixed32 writes a 32-bit integer to the Buffer. -// This is the format for the -// fixed32, sfixed32, and float protocol buffer types. -func (p *Buffer) EncodeFixed32(x uint64) error { - p.buf = append(p.buf, - uint8(x), - uint8(x>>8), - uint8(x>>16), - uint8(x>>24)) - return nil -} - -// EncodeZigzag64 writes a zigzag-encoded 64-bit integer -// to the Buffer. -// This is the format used for the sint64 protocol buffer type. -func (p *Buffer) EncodeZigzag64(x uint64) error { - // use signed number to get arithmetic right shift. - return p.EncodeVarint(uint64((x << 1) ^ uint64((int64(x) >> 63)))) -} - -// EncodeZigzag32 writes a zigzag-encoded 32-bit integer -// to the Buffer. -// This is the format used for the sint32 protocol buffer type. -func (p *Buffer) EncodeZigzag32(x uint64) error { - // use signed number to get arithmetic right shift. - return p.EncodeVarint(uint64((uint32(x) << 1) ^ uint32((int32(x) >> 31)))) -} - -// EncodeRawBytes writes a count-delimited byte buffer to the Buffer. -// This is the format used for the bytes protocol buffer -// type and for embedded messages. -func (p *Buffer) EncodeRawBytes(b []byte) error { - p.EncodeVarint(uint64(len(b))) - p.buf = append(p.buf, b...) - return nil -} - -// EncodeStringBytes writes an encoded string to the Buffer. -// This is the format used for the proto2 string type. -func (p *Buffer) EncodeStringBytes(s string) error { - p.EncodeVarint(uint64(len(s))) - p.buf = append(p.buf, s...) - return nil -} - -// Marshaler is the interface representing objects that can marshal themselves. -type Marshaler interface { - Marshal() ([]byte, error) -} - -// EncodeMessage writes the protocol buffer to the Buffer, -// prefixed by a varint-encoded length. -func (p *Buffer) EncodeMessage(pb Message) error { - siz := Size(pb) - p.EncodeVarint(uint64(siz)) - return p.Marshal(pb) -} - -// All protocol buffer fields are nillable, but be careful. -func isNil(v reflect.Value) bool { - switch v.Kind() { - case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice: - return v.IsNil() - } - return false -} diff --git a/vendor/github.com/golang/protobuf/proto/equal.go b/vendor/github.com/golang/protobuf/proto/equal.go deleted file mode 100644 index f9b6e41b3..000000000 --- a/vendor/github.com/golang/protobuf/proto/equal.go +++ /dev/null @@ -1,301 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2011 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// Protocol buffer comparison. - -package proto - -import ( - "bytes" - "log" - "reflect" - "strings" -) - -/* -Equal returns true iff protocol buffers a and b are equal. -The arguments must both be pointers to protocol buffer structs. - -Equality is defined in this way: - - Two messages are equal iff they are the same type, - corresponding fields are equal, unknown field sets - are equal, and extensions sets are equal. - - Two set scalar fields are equal iff their values are equal. - If the fields are of a floating-point type, remember that - NaN != x for all x, including NaN. If the message is defined - in a proto3 .proto file, fields are not "set"; specifically, - zero length proto3 "bytes" fields are equal (nil == {}). - - Two repeated fields are equal iff their lengths are the same, - and their corresponding elements are equal. Note a "bytes" field, - although represented by []byte, is not a repeated field and the - rule for the scalar fields described above applies. - - Two unset fields are equal. - - Two unknown field sets are equal if their current - encoded state is equal. - - Two extension sets are equal iff they have corresponding - elements that are pairwise equal. - - Two map fields are equal iff their lengths are the same, - and they contain the same set of elements. Zero-length map - fields are equal. - - Every other combination of things are not equal. - -The return value is undefined if a and b are not protocol buffers. -*/ -func Equal(a, b Message) bool { - if a == nil || b == nil { - return a == b - } - v1, v2 := reflect.ValueOf(a), reflect.ValueOf(b) - if v1.Type() != v2.Type() { - return false - } - if v1.Kind() == reflect.Ptr { - if v1.IsNil() { - return v2.IsNil() - } - if v2.IsNil() { - return false - } - v1, v2 = v1.Elem(), v2.Elem() - } - if v1.Kind() != reflect.Struct { - return false - } - return equalStruct(v1, v2) -} - -// v1 and v2 are known to have the same type. -func equalStruct(v1, v2 reflect.Value) bool { - sprop := GetProperties(v1.Type()) - for i := 0; i < v1.NumField(); i++ { - f := v1.Type().Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - f1, f2 := v1.Field(i), v2.Field(i) - if f.Type.Kind() == reflect.Ptr { - if n1, n2 := f1.IsNil(), f2.IsNil(); n1 && n2 { - // both unset - continue - } else if n1 != n2 { - // set/unset mismatch - return false - } - f1, f2 = f1.Elem(), f2.Elem() - } - if !equalAny(f1, f2, sprop.Prop[i]) { - return false - } - } - - if em1 := v1.FieldByName("XXX_InternalExtensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_InternalExtensions") - if !equalExtensions(v1.Type(), em1.Interface().(XXX_InternalExtensions), em2.Interface().(XXX_InternalExtensions)) { - return false - } - } - - if em1 := v1.FieldByName("XXX_extensions"); em1.IsValid() { - em2 := v2.FieldByName("XXX_extensions") - if !equalExtMap(v1.Type(), em1.Interface().(map[int32]Extension), em2.Interface().(map[int32]Extension)) { - return false - } - } - - uf := v1.FieldByName("XXX_unrecognized") - if !uf.IsValid() { - return true - } - - u1 := uf.Bytes() - u2 := v2.FieldByName("XXX_unrecognized").Bytes() - return bytes.Equal(u1, u2) -} - -// v1 and v2 are known to have the same type. -// prop may be nil. -func equalAny(v1, v2 reflect.Value, prop *Properties) bool { - if v1.Type() == protoMessageType { - m1, _ := v1.Interface().(Message) - m2, _ := v2.Interface().(Message) - return Equal(m1, m2) - } - switch v1.Kind() { - case reflect.Bool: - return v1.Bool() == v2.Bool() - case reflect.Float32, reflect.Float64: - return v1.Float() == v2.Float() - case reflect.Int32, reflect.Int64: - return v1.Int() == v2.Int() - case reflect.Interface: - // Probably a oneof field; compare the inner values. - n1, n2 := v1.IsNil(), v2.IsNil() - if n1 || n2 { - return n1 == n2 - } - e1, e2 := v1.Elem(), v2.Elem() - if e1.Type() != e2.Type() { - return false - } - return equalAny(e1, e2, nil) - case reflect.Map: - if v1.Len() != v2.Len() { - return false - } - for _, key := range v1.MapKeys() { - val2 := v2.MapIndex(key) - if !val2.IsValid() { - // This key was not found in the second map. - return false - } - if !equalAny(v1.MapIndex(key), val2, nil) { - return false - } - } - return true - case reflect.Ptr: - // Maps may have nil values in them, so check for nil. - if v1.IsNil() && v2.IsNil() { - return true - } - if v1.IsNil() != v2.IsNil() { - return false - } - return equalAny(v1.Elem(), v2.Elem(), prop) - case reflect.Slice: - if v1.Type().Elem().Kind() == reflect.Uint8 { - // short circuit: []byte - - // Edge case: if this is in a proto3 message, a zero length - // bytes field is considered the zero value. - if prop != nil && prop.proto3 && v1.Len() == 0 && v2.Len() == 0 { - return true - } - if v1.IsNil() != v2.IsNil() { - return false - } - return bytes.Equal(v1.Interface().([]byte), v2.Interface().([]byte)) - } - - if v1.Len() != v2.Len() { - return false - } - for i := 0; i < v1.Len(); i++ { - if !equalAny(v1.Index(i), v2.Index(i), prop) { - return false - } - } - return true - case reflect.String: - return v1.Interface().(string) == v2.Interface().(string) - case reflect.Struct: - return equalStruct(v1, v2) - case reflect.Uint32, reflect.Uint64: - return v1.Uint() == v2.Uint() - } - - // unknown type, so not a protocol buffer - log.Printf("proto: don't know how to compare %v", v1) - return false -} - -// base is the struct type that the extensions are based on. -// x1 and x2 are InternalExtensions. -func equalExtensions(base reflect.Type, x1, x2 XXX_InternalExtensions) bool { - em1, _ := x1.extensionsRead() - em2, _ := x2.extensionsRead() - return equalExtMap(base, em1, em2) -} - -func equalExtMap(base reflect.Type, em1, em2 map[int32]Extension) bool { - if len(em1) != len(em2) { - return false - } - - for extNum, e1 := range em1 { - e2, ok := em2[extNum] - if !ok { - return false - } - - m1 := extensionAsLegacyType(e1.value) - m2 := extensionAsLegacyType(e2.value) - - if m1 == nil && m2 == nil { - // Both have only encoded form. - if bytes.Equal(e1.enc, e2.enc) { - continue - } - // The bytes are different, but the extensions might still be - // equal. We need to decode them to compare. - } - - if m1 != nil && m2 != nil { - // Both are unencoded. - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { - return false - } - continue - } - - // At least one is encoded. To do a semantically correct comparison - // we need to unmarshal them first. - var desc *ExtensionDesc - if m := extensionMaps[base]; m != nil { - desc = m[extNum] - } - if desc == nil { - // If both have only encoded form and the bytes are the same, - // it is handled above. We get here when the bytes are different. - // We don't know how to decode it, so just compare them as byte - // slices. - log.Printf("proto: don't know how to compare extension %d of %v", extNum, base) - return false - } - var err error - if m1 == nil { - m1, err = decodeExtension(e1.enc, desc) - } - if m2 == nil && err == nil { - m2, err = decodeExtension(e2.enc, desc) - } - if err != nil { - // The encoded form is invalid. - log.Printf("proto: badly encoded extension %d of %v: %v", extNum, base, err) - return false - } - if !equalAny(reflect.ValueOf(m1), reflect.ValueOf(m2), nil) { - return false - } - } - - return true -} diff --git a/vendor/github.com/golang/protobuf/proto/extensions.go b/vendor/github.com/golang/protobuf/proto/extensions.go index fa88add30..42fc120c9 100644 --- a/vendor/github.com/golang/protobuf/proto/extensions.go +++ b/vendor/github.com/golang/protobuf/proto/extensions.go @@ -1,607 +1,356 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. package proto -/* - * Types and routines for supporting protocol buffer extensions. - */ - import ( "errors" "fmt" - "io" "reflect" - "strconv" - "sync" -) - -// ErrMissingExtension is the error returned by GetExtension if the named extension is not in the message. -var ErrMissingExtension = errors.New("proto: missing extension") - -// ExtensionRange represents a range of message extensions for a protocol buffer. -// Used in code generated by the protocol compiler. -type ExtensionRange struct { - Start, End int32 // both inclusive -} - -// extendableProto is an interface implemented by any protocol buffer generated by the current -// proto compiler that may be extended. -type extendableProto interface { - Message - ExtensionRangeArray() []ExtensionRange - extensionsWrite() map[int32]Extension - extensionsRead() (map[int32]Extension, sync.Locker) -} - -// extendableProtoV1 is an interface implemented by a protocol buffer generated by the previous -// version of the proto compiler that may be extended. -type extendableProtoV1 interface { - Message - ExtensionRangeArray() []ExtensionRange - ExtensionMap() map[int32]Extension -} -// extensionAdapter is a wrapper around extendableProtoV1 that implements extendableProto. -type extensionAdapter struct { - extendableProtoV1 -} + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/runtime/protoimpl" +) -func (e extensionAdapter) extensionsWrite() map[int32]Extension { - return e.ExtensionMap() -} +type ( + // ExtensionDesc represents an extension descriptor and + // is used to interact with an extension field in a message. + // + // Variables of this type are generated in code by protoc-gen-go. + ExtensionDesc = protoimpl.ExtensionInfo -func (e extensionAdapter) extensionsRead() (map[int32]Extension, sync.Locker) { - return e.ExtensionMap(), notLocker{} -} + // ExtensionRange represents a range of message extensions. + // Used in code generated by protoc-gen-go. + ExtensionRange = protoiface.ExtensionRangeV1 -// notLocker is a sync.Locker whose Lock and Unlock methods are nops. -type notLocker struct{} + // Deprecated: Do not use; this is an internal type. + Extension = protoimpl.ExtensionFieldV1 -func (n notLocker) Lock() {} -func (n notLocker) Unlock() {} + // Deprecated: Do not use; this is an internal type. + XXX_InternalExtensions = protoimpl.ExtensionFields +) -// extendable returns the extendableProto interface for the given generated proto message. -// If the proto message has the old extension format, it returns a wrapper that implements -// the extendableProto interface. -func extendable(p interface{}) (extendableProto, error) { - switch p := p.(type) { - case extendableProto: - if isNilPtr(p) { - return nil, fmt.Errorf("proto: nil %T is not extendable", p) - } - return p, nil - case extendableProtoV1: - if isNilPtr(p) { - return nil, fmt.Errorf("proto: nil %T is not extendable", p) - } - return extensionAdapter{p}, nil - } - // Don't allocate a specific error containing %T: - // this is the hot path for Clone and MarshalText. - return nil, errNotExtendable -} +// ErrMissingExtension reports whether the extension was not present. +var ErrMissingExtension = errors.New("proto: missing extension") var errNotExtendable = errors.New("proto: not an extendable proto.Message") -func isNilPtr(x interface{}) bool { - v := reflect.ValueOf(x) - return v.Kind() == reflect.Ptr && v.IsNil() -} - -// XXX_InternalExtensions is an internal representation of proto extensions. -// -// Each generated message struct type embeds an anonymous XXX_InternalExtensions field, -// thus gaining the unexported 'extensions' method, which can be called only from the proto package. -// -// The methods of XXX_InternalExtensions are not concurrency safe in general, -// but calls to logically read-only methods such as has and get may be executed concurrently. -type XXX_InternalExtensions struct { - // The struct must be indirect so that if a user inadvertently copies a - // generated message and its embedded XXX_InternalExtensions, they - // avoid the mayhem of a copied mutex. - // - // The mutex serializes all logically read-only operations to p.extensionMap. - // It is up to the client to ensure that write operations to p.extensionMap are - // mutually exclusive with other accesses. - p *struct { - mu sync.Mutex - extensionMap map[int32]Extension +// HasExtension reports whether the extension field is present in m +// either as an explicitly populated field or as an unknown field. +func HasExtension(m Message, xt *ExtensionDesc) (has bool) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { + return false } -} -// extensionsWrite returns the extension map, creating it on first use. -func (e *XXX_InternalExtensions) extensionsWrite() map[int32]Extension { - if e.p == nil { - e.p = new(struct { - mu sync.Mutex - extensionMap map[int32]Extension + // Check whether any populated known field matches the field number. + xtd := xt.TypeDescriptor() + if isValidExtension(mr.Descriptor(), xtd) { + has = mr.Has(xtd) + } else { + mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { + has = int32(fd.Number()) == xt.Field + return !has }) - e.p.extensionMap = make(map[int32]Extension) } - return e.p.extensionMap -} -// extensionsRead returns the extensions map for read-only use. It may be nil. -// The caller must hold the returned mutex's lock when accessing Elements within the map. -func (e *XXX_InternalExtensions) extensionsRead() (map[int32]Extension, sync.Locker) { - if e.p == nil { - return nil, nil + // Check whether any unknown field matches the field number. + for b := mr.GetUnknown(); !has && len(b) > 0; { + num, _, n := protowire.ConsumeField(b) + has = int32(num) == xt.Field + b = b[n:] } - return e.p.extensionMap, &e.p.mu -} - -// ExtensionDesc represents an extension specification. -// Used in generated code from the protocol compiler. -type ExtensionDesc struct { - ExtendedType Message // nil pointer to the type that is being extended - ExtensionType interface{} // nil pointer to the extension type - Field int32 // field number - Name string // fully-qualified name of extension, for text formatting - Tag string // protobuf tag style - Filename string // name of the file in which the extension is defined -} - -func (ed *ExtensionDesc) repeated() bool { - t := reflect.TypeOf(ed.ExtensionType) - return t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 -} - -// Extension represents an extension in a message. -type Extension struct { - // When an extension is stored in a message using SetExtension - // only desc and value are set. When the message is marshaled - // enc will be set to the encoded form of the message. - // - // When a message is unmarshaled and contains extensions, each - // extension will have only enc set. When such an extension is - // accessed using GetExtension (or GetExtensions) desc and value - // will be set. - desc *ExtensionDesc - - // value is a concrete value for the extension field. Let the type of - // desc.ExtensionType be the "API type" and the type of Extension.value - // be the "storage type". The API type and storage type are the same except: - // * For scalars (except []byte), the API type uses *T, - // while the storage type uses T. - // * For repeated fields, the API type uses []T, while the storage type - // uses *[]T. - // - // The reason for the divergence is so that the storage type more naturally - // matches what is expected of when retrieving the values through the - // protobuf reflection APIs. - // - // The value may only be populated if desc is also populated. - value interface{} - - // enc is the raw bytes for the extension field. - enc []byte + return has } -// SetRawExtension is for testing only. -func SetRawExtension(base Message, id int32, b []byte) { - epb, err := extendable(base) - if err != nil { +// ClearExtension removes the extension field from m +// either as an explicitly populated field or as an unknown field. +func ClearExtension(m Message, xt *ExtensionDesc) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { return } - extmap := epb.extensionsWrite() - extmap[id] = Extension{enc: b} -} -// isExtensionField returns true iff the given field number is in an extension range. -func isExtensionField(pb extendableProto, field int32) bool { - for _, er := range pb.ExtensionRangeArray() { - if er.Start <= field && field <= er.End { + xtd := xt.TypeDescriptor() + if isValidExtension(mr.Descriptor(), xtd) { + mr.Clear(xtd) + } else { + mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { + if int32(fd.Number()) == xt.Field { + mr.Clear(fd) + return false + } return true - } - } - return false -} - -// checkExtensionTypes checks that the given extension is valid for pb. -func checkExtensionTypes(pb extendableProto, extension *ExtensionDesc) error { - var pbi interface{} = pb - // Check the extended type. - if ea, ok := pbi.(extensionAdapter); ok { - pbi = ea.extendableProtoV1 - } - if a, b := reflect.TypeOf(pbi), reflect.TypeOf(extension.ExtendedType); a != b { - return fmt.Errorf("proto: bad extended type; %v does not extend %v", b, a) - } - // Check the range. - if !isExtensionField(pb, extension.Field) { - return errors.New("proto: bad extension number; not in declared ranges") - } - return nil -} - -// extPropKey is sufficient to uniquely identify an extension. -type extPropKey struct { - base reflect.Type - field int32 -} - -var extProp = struct { - sync.RWMutex - m map[extPropKey]*Properties -}{ - m: make(map[extPropKey]*Properties), -} - -func extensionProperties(ed *ExtensionDesc) *Properties { - key := extPropKey{base: reflect.TypeOf(ed.ExtendedType), field: ed.Field} - - extProp.RLock() - if prop, ok := extProp.m[key]; ok { - extProp.RUnlock() - return prop - } - extProp.RUnlock() - - extProp.Lock() - defer extProp.Unlock() - // Check again. - if prop, ok := extProp.m[key]; ok { - return prop - } - - prop := new(Properties) - prop.Init(reflect.TypeOf(ed.ExtensionType), "unknown_name", ed.Tag, nil) - extProp.m[key] = prop - return prop -} - -// HasExtension returns whether the given extension is present in pb. -func HasExtension(pb Message, extension *ExtensionDesc) bool { - // TODO: Check types, field numbers, etc.? - epb, err := extendable(pb) - if err != nil { - return false - } - extmap, mu := epb.extensionsRead() - if extmap == nil { - return false + }) } - mu.Lock() - _, ok := extmap[extension.Field] - mu.Unlock() - return ok + clearUnknown(mr, fieldNum(xt.Field)) } -// ClearExtension removes the given extension from pb. -func ClearExtension(pb Message, extension *ExtensionDesc) { - epb, err := extendable(pb) - if err != nil { +// ClearAllExtensions clears all extensions from m. +// This includes populated fields and unknown fields in the extension range. +func ClearAllExtensions(m Message) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { return } - // TODO: Check types, field numbers, etc.? - extmap := epb.extensionsWrite() - delete(extmap, extension.Field) + + mr.Range(func(fd protoreflect.FieldDescriptor, _ protoreflect.Value) bool { + if fd.IsExtension() { + mr.Clear(fd) + } + return true + }) + clearUnknown(mr, mr.Descriptor().ExtensionRanges()) } -// GetExtension retrieves a proto2 extended field from pb. +// GetExtension retrieves a proto2 extended field from m. // // If the descriptor is type complete (i.e., ExtensionDesc.ExtensionType is non-nil), // then GetExtension parses the encoded field and returns a Go value of the specified type. // If the field is not present, then the default value is returned (if one is specified), // otherwise ErrMissingExtension is reported. // -// If the descriptor is not type complete (i.e., ExtensionDesc.ExtensionType is nil), -// then GetExtension returns the raw encoded bytes of the field extension. -func GetExtension(pb Message, extension *ExtensionDesc) (interface{}, error) { - epb, err := extendable(pb) - if err != nil { - return nil, err - } - - if extension.ExtendedType != nil { - // can only check type if this is a complete descriptor - if err := checkExtensionTypes(epb, extension); err != nil { - return nil, err +// If the descriptor is type incomplete (i.e., ExtensionDesc.ExtensionType is nil), +// then GetExtension returns the raw encoded bytes for the extension field. +func GetExtension(m Message, xt *ExtensionDesc) (interface{}, error) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { + return nil, errNotExtendable + } + + // Retrieve the unknown fields for this extension field. + var bo protoreflect.RawFields + for bi := mr.GetUnknown(); len(bi) > 0; { + num, _, n := protowire.ConsumeField(bi) + if int32(num) == xt.Field { + bo = append(bo, bi[:n]...) } + bi = bi[n:] } - emap, mu := epb.extensionsRead() - if emap == nil { - return defaultExtensionValue(extension) - } - mu.Lock() - defer mu.Unlock() - e, ok := emap[extension.Field] - if !ok { - // defaultExtensionValue returns the default value or - // ErrMissingExtension if there is no default. - return defaultExtensionValue(extension) - } - - if e.value != nil { - // Already decoded. Check the descriptor, though. - if e.desc != extension { - // This shouldn't happen. If it does, it means that - // GetExtension was called twice with two different - // descriptors with the same field number. - return nil, errors.New("proto: descriptor conflict") - } - return extensionAsLegacyType(e.value), nil + // For type incomplete descriptors, only retrieve the unknown fields. + if xt.ExtensionType == nil { + return []byte(bo), nil } - if extension.ExtensionType == nil { - // incomplete descriptor - return e.enc, nil + // If the extension field only exists as unknown fields, unmarshal it. + // This is rarely done since proto.Unmarshal eagerly unmarshals extensions. + xtd := xt.TypeDescriptor() + if !isValidExtension(mr.Descriptor(), xtd) { + return nil, fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) } - - v, err := decodeExtension(e.enc, extension) - if err != nil { - return nil, err + if !mr.Has(xtd) && len(bo) > 0 { + m2 := mr.New() + if err := (proto.UnmarshalOptions{ + Resolver: extensionResolver{xt}, + }.Unmarshal(bo, m2.Interface())); err != nil { + return nil, err + } + if m2.Has(xtd) { + mr.Set(xtd, m2.Get(xtd)) + clearUnknown(mr, fieldNum(xt.Field)) + } } - // Remember the decoded version and drop the encoded version. - // That way it is safe to mutate what we return. - e.value = extensionAsStorageType(v) - e.desc = extension - e.enc = nil - emap[extension.Field] = e - return extensionAsLegacyType(e.value), nil -} - -// defaultExtensionValue returns the default value for extension. -// If no default for an extension is defined ErrMissingExtension is returned. -func defaultExtensionValue(extension *ExtensionDesc) (interface{}, error) { - if extension.ExtensionType == nil { - // incomplete descriptor, so no default + // Check whether the message has the extension field set or a default. + var pv protoreflect.Value + switch { + case mr.Has(xtd): + pv = mr.Get(xtd) + case xtd.HasDefault(): + pv = xtd.Default() + default: return nil, ErrMissingExtension } - t := reflect.TypeOf(extension.ExtensionType) - props := extensionProperties(extension) - - sf, _, err := fieldDefault(t, props) - if err != nil { - return nil, err - } - - if sf == nil || sf.value == nil { - // There is no default value. - return nil, ErrMissingExtension + v := xt.InterfaceOf(pv) + rv := reflect.ValueOf(v) + if isScalarKind(rv.Kind()) { + rv2 := reflect.New(rv.Type()) + rv2.Elem().Set(rv) + v = rv2.Interface() } + return v, nil +} - if t.Kind() != reflect.Ptr { - // We do not need to return a Ptr, we can directly return sf.value. - return sf.value, nil - } +// extensionResolver is a custom extension resolver that stores a single +// extension type that takes precedence over the global registry. +type extensionResolver struct{ xt protoreflect.ExtensionType } - // We need to return an interface{} that is a pointer to sf.value. - value := reflect.New(t).Elem() - value.Set(reflect.New(value.Type().Elem())) - if sf.kind == reflect.Int32 { - // We may have an int32 or an enum, but the underlying data is int32. - // Since we can't set an int32 into a non int32 reflect.value directly - // set it as a int32. - value.Elem().SetInt(int64(sf.value.(int32))) - } else { - value.Elem().Set(reflect.ValueOf(sf.value)) +func (r extensionResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { + if xtd := r.xt.TypeDescriptor(); xtd.FullName() == field { + return r.xt, nil } - return value.Interface(), nil + return protoregistry.GlobalTypes.FindExtensionByName(field) } -// decodeExtension decodes an extension encoded in b. -func decodeExtension(b []byte, extension *ExtensionDesc) (interface{}, error) { - t := reflect.TypeOf(extension.ExtensionType) - unmarshal := typeUnmarshaler(t, extension.Tag) - - // t is a pointer to a struct, pointer to basic type or a slice. - // Allocate space to store the pointer/slice. - value := reflect.New(t).Elem() - - var err error - for { - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - wire := int(x) & 7 - - b, err = unmarshal(b, valToPointer(value.Addr()), wire) - if err != nil { - return nil, err - } - - if len(b) == 0 { - break - } +func (r extensionResolver) FindExtensionByNumber(message protoreflect.FullName, field protoreflect.FieldNumber) (protoreflect.ExtensionType, error) { + if xtd := r.xt.TypeDescriptor(); xtd.ContainingMessage().FullName() == message && xtd.Number() == field { + return r.xt, nil } - return value.Interface(), nil + return protoregistry.GlobalTypes.FindExtensionByNumber(message, field) } -// GetExtensions returns a slice of the extensions present in pb that are also listed in es. -// The returned slice has the same length as es; missing extensions will appear as nil elements. -func GetExtensions(pb Message, es []*ExtensionDesc) (extensions []interface{}, err error) { - epb, err := extendable(pb) - if err != nil { - return nil, err +// GetExtensions returns a list of the extensions values present in m, +// corresponding with the provided list of extension descriptors, xts. +// If an extension is missing in m, the corresponding value is nil. +func GetExtensions(m Message, xts []*ExtensionDesc) ([]interface{}, error) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { + return nil, errNotExtendable } - extensions = make([]interface{}, len(es)) - for i, e := range es { - extensions[i], err = GetExtension(epb, e) - if err == ErrMissingExtension { - err = nil - } + + vs := make([]interface{}, len(xts)) + for i, xt := range xts { + v, err := GetExtension(m, xt) if err != nil { - return + if err == ErrMissingExtension { + continue + } + return vs, err } + vs[i] = v } - return + return vs, nil } -// ExtensionDescs returns a new slice containing pb's extension descriptors, in undefined order. -// For non-registered extensions, ExtensionDescs returns an incomplete descriptor containing -// just the Field field, which defines the extension's field number. -func ExtensionDescs(pb Message) ([]*ExtensionDesc, error) { - epb, err := extendable(pb) - if err != nil { - return nil, err +// SetExtension sets an extension field in m to the provided value. +func SetExtension(m Message, xt *ExtensionDesc, v interface{}) error { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { + return errNotExtendable } - registeredExtensions := RegisteredExtensions(pb) - emap, mu := epb.extensionsRead() - if emap == nil { - return nil, nil + rv := reflect.ValueOf(v) + if reflect.TypeOf(v) != reflect.TypeOf(xt.ExtensionType) { + return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", v, xt.ExtensionType) } - mu.Lock() - defer mu.Unlock() - extensions := make([]*ExtensionDesc, 0, len(emap)) - for extid, e := range emap { - desc := e.desc - if desc == nil { - desc = registeredExtensions[extid] - if desc == nil { - desc = &ExtensionDesc{Field: extid} - } + if rv.Kind() == reflect.Ptr { + if rv.IsNil() { + return fmt.Errorf("proto: SetExtension called with nil value of type %T", v) + } + if isScalarKind(rv.Elem().Kind()) { + v = rv.Elem().Interface() } - - extensions = append(extensions, desc) } - return extensions, nil -} -// SetExtension sets the specified extension of pb to the specified value. -func SetExtension(pb Message, extension *ExtensionDesc, value interface{}) error { - epb, err := extendable(pb) - if err != nil { - return err - } - if err := checkExtensionTypes(epb, extension); err != nil { - return err - } - typ := reflect.TypeOf(extension.ExtensionType) - if typ != reflect.TypeOf(value) { - return fmt.Errorf("proto: bad extension value type. got: %T, want: %T", value, extension.ExtensionType) + xtd := xt.TypeDescriptor() + if !isValidExtension(mr.Descriptor(), xtd) { + return fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) } - // nil extension values need to be caught early, because the - // encoder can't distinguish an ErrNil due to a nil extension - // from an ErrNil due to a missing field. Extensions are - // always optional, so the encoder would just swallow the error - // and drop all the extensions from the encoded message. - if reflect.ValueOf(value).IsNil() { - return fmt.Errorf("proto: SetExtension called with nil value of type %T", value) - } - - extmap := epb.extensionsWrite() - extmap[extension.Field] = Extension{desc: extension, value: extensionAsStorageType(value)} + mr.Set(xtd, xt.ValueOf(v)) + clearUnknown(mr, fieldNum(xt.Field)) return nil } -// ClearAllExtensions clears all extensions from pb. -func ClearAllExtensions(pb Message) { - epb, err := extendable(pb) - if err != nil { +// SetRawExtension inserts b into the unknown fields of m. +// +// Deprecated: Use Message.ProtoReflect.SetUnknown instead. +func SetRawExtension(m Message, fnum int32, b []byte) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { return } - m := epb.extensionsWrite() - for k := range m { - delete(m, k) + + // Verify that the raw field is valid. + for b0 := b; len(b0) > 0; { + num, _, n := protowire.ConsumeField(b0) + if int32(num) != fnum { + panic(fmt.Sprintf("mismatching field number: got %d, want %d", num, fnum)) + } + b0 = b0[n:] } -} -// A global registry of extensions. -// The generated code will register the generated descriptors by calling RegisterExtension. + ClearExtension(m, &ExtensionDesc{Field: fnum}) + mr.SetUnknown(append(mr.GetUnknown(), b...)) +} -var extensionMaps = make(map[reflect.Type]map[int32]*ExtensionDesc) +// ExtensionDescs returns a list of extension descriptors found in m, +// containing descriptors for both populated extension fields in m and +// also unknown fields of m that are in the extension range. +// For the later case, an type incomplete descriptor is provided where only +// the ExtensionDesc.Field field is populated. +// The order of the extension descriptors is undefined. +func ExtensionDescs(m Message) ([]*ExtensionDesc, error) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() || mr.Descriptor().ExtensionRanges().Len() == 0 { + return nil, errNotExtendable + } -// RegisterExtension is called from the generated code. -func RegisterExtension(desc *ExtensionDesc) { - st := reflect.TypeOf(desc.ExtendedType).Elem() - m := extensionMaps[st] - if m == nil { - m = make(map[int32]*ExtensionDesc) - extensionMaps[st] = m + // Collect a set of known extension descriptors. + extDescs := make(map[protoreflect.FieldNumber]*ExtensionDesc) + mr.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + if fd.IsExtension() { + xt := fd.(protoreflect.ExtensionTypeDescriptor) + if xd, ok := xt.Type().(*ExtensionDesc); ok { + extDescs[fd.Number()] = xd + } + } + return true + }) + + // Collect a set of unknown extension descriptors. + extRanges := mr.Descriptor().ExtensionRanges() + for b := mr.GetUnknown(); len(b) > 0; { + num, _, n := protowire.ConsumeField(b) + if extRanges.Has(num) && extDescs[num] == nil { + extDescs[num] = nil + } + b = b[n:] } - if _, ok := m[desc.Field]; ok { - panic("proto: duplicate extension registered: " + st.String() + " " + strconv.Itoa(int(desc.Field))) + + // Transpose the set of descriptors into a list. + var xts []*ExtensionDesc + for num, xt := range extDescs { + if xt == nil { + xt = &ExtensionDesc{Field: int32(num)} + } + xts = append(xts, xt) } - m[desc.Field] = desc + return xts, nil } -// RegisteredExtensions returns a map of the registered extensions of a -// protocol buffer struct, indexed by the extension number. -// The argument pb should be a nil pointer to the struct type. -func RegisteredExtensions(pb Message) map[int32]*ExtensionDesc { - return extensionMaps[reflect.TypeOf(pb).Elem()] +// isValidExtension reports whether xtd is a valid extension descriptor for md. +func isValidExtension(md protoreflect.MessageDescriptor, xtd protoreflect.ExtensionTypeDescriptor) bool { + return xtd.ContainingMessage() == md && md.ExtensionRanges().Has(xtd.Number()) } -// extensionAsLegacyType converts an value in the storage type as the API type. -// See Extension.value. -func extensionAsLegacyType(v interface{}) interface{} { - switch rv := reflect.ValueOf(v); rv.Kind() { +// isScalarKind reports whether k is a protobuf scalar kind (except bytes). +// This function exists for historical reasons since the representation of +// scalars differs between v1 and v2, where v1 uses *T and v2 uses T. +func isScalarKind(k reflect.Kind) bool { + switch k { case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: - // Represent primitive types as a pointer to the value. - rv2 := reflect.New(rv.Type()) - rv2.Elem().Set(rv) - v = rv2.Interface() - case reflect.Ptr: - // Represent slice types as the value itself. - switch rv.Type().Elem().Kind() { - case reflect.Slice: - if rv.IsNil() { - v = reflect.Zero(rv.Type().Elem()).Interface() - } else { - v = rv.Elem().Interface() - } - } + return true + default: + return false } - return v } -// extensionAsStorageType converts an value in the API type as the storage type. -// See Extension.value. -func extensionAsStorageType(v interface{}) interface{} { - switch rv := reflect.ValueOf(v); rv.Kind() { - case reflect.Ptr: - // Represent slice types as the value itself. - switch rv.Type().Elem().Kind() { - case reflect.Bool, reflect.Int32, reflect.Int64, reflect.Uint32, reflect.Uint64, reflect.Float32, reflect.Float64, reflect.String: - if rv.IsNil() { - v = reflect.Zero(rv.Type().Elem()).Interface() - } else { - v = rv.Elem().Interface() - } - } - case reflect.Slice: - // Represent slice types as a pointer to the value. - if rv.Type().Elem().Kind() != reflect.Uint8 { - rv2 := reflect.New(rv.Type()) - rv2.Elem().Set(rv) - v = rv2.Interface() +// clearUnknown removes unknown fields from m where remover.Has reports true. +func clearUnknown(m protoreflect.Message, remover interface { + Has(protoreflect.FieldNumber) bool +}) { + var bo protoreflect.RawFields + for bi := m.GetUnknown(); len(bi) > 0; { + num, _, n := protowire.ConsumeField(bi) + if !remover.Has(num) { + bo = append(bo, bi[:n]...) } + bi = bi[n:] } - return v + if bi := m.GetUnknown(); len(bi) != len(bo) { + m.SetUnknown(bo) + } +} + +type fieldNum protoreflect.FieldNumber + +func (n1 fieldNum) Has(n2 protoreflect.FieldNumber) bool { + return protoreflect.FieldNumber(n1) == n2 } diff --git a/vendor/github.com/golang/protobuf/proto/lib.go b/vendor/github.com/golang/protobuf/proto/lib.go deleted file mode 100644 index 70fbda532..000000000 --- a/vendor/github.com/golang/protobuf/proto/lib.go +++ /dev/null @@ -1,965 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -/* -Package proto converts data structures to and from the wire format of -protocol buffers. It works in concert with the Go source code generated -for .proto files by the protocol compiler. - -A summary of the properties of the protocol buffer interface -for a protocol buffer variable v: - - - Names are turned from camel_case to CamelCase for export. - - There are no methods on v to set fields; just treat - them as structure fields. - - There are getters that return a field's value if set, - and return the field's default value if unset. - The getters work even if the receiver is a nil message. - - The zero value for a struct is its correct initialization state. - All desired fields must be set before marshaling. - - A Reset() method will restore a protobuf struct to its zero state. - - Non-repeated fields are pointers to the values; nil means unset. - That is, optional or required field int32 f becomes F *int32. - - Repeated fields are slices. - - Helper functions are available to aid the setting of fields. - msg.Foo = proto.String("hello") // set field - - Constants are defined to hold the default values of all fields that - have them. They have the form Default_StructName_FieldName. - Because the getter methods handle defaulted values, - direct use of these constants should be rare. - - Enums are given type names and maps from names to values. - Enum values are prefixed by the enclosing message's name, or by the - enum's type name if it is a top-level enum. Enum types have a String - method, and a Enum method to assist in message construction. - - Nested messages, groups and enums have type names prefixed with the name of - the surrounding message type. - - Extensions are given descriptor names that start with E_, - followed by an underscore-delimited list of the nested messages - that contain it (if any) followed by the CamelCased name of the - extension field itself. HasExtension, ClearExtension, GetExtension - and SetExtension are functions for manipulating extensions. - - Oneof field sets are given a single field in their message, - with distinguished wrapper types for each possible field value. - - Marshal and Unmarshal are functions to encode and decode the wire format. - -When the .proto file specifies `syntax="proto3"`, there are some differences: - - - Non-repeated fields of non-message type are values instead of pointers. - - Enum types do not get an Enum method. - -The simplest way to describe this is to see an example. -Given file test.proto, containing - - package example; - - enum FOO { X = 17; } - - message Test { - required string label = 1; - optional int32 type = 2 [default=77]; - repeated int64 reps = 3; - optional group OptionalGroup = 4 { - required string RequiredField = 5; - } - oneof union { - int32 number = 6; - string name = 7; - } - } - -The resulting file, test.pb.go, is: - - package example - - import proto "github.com/golang/protobuf/proto" - import math "math" - - type FOO int32 - const ( - FOO_X FOO = 17 - ) - var FOO_name = map[int32]string{ - 17: "X", - } - var FOO_value = map[string]int32{ - "X": 17, - } - - func (x FOO) Enum() *FOO { - p := new(FOO) - *p = x - return p - } - func (x FOO) String() string { - return proto.EnumName(FOO_name, int32(x)) - } - func (x *FOO) UnmarshalJSON(data []byte) error { - value, err := proto.UnmarshalJSONEnum(FOO_value, data) - if err != nil { - return err - } - *x = FOO(value) - return nil - } - - type Test struct { - Label *string `protobuf:"bytes,1,req,name=label" json:"label,omitempty"` - Type *int32 `protobuf:"varint,2,opt,name=type,def=77" json:"type,omitempty"` - Reps []int64 `protobuf:"varint,3,rep,name=reps" json:"reps,omitempty"` - Optionalgroup *Test_OptionalGroup `protobuf:"group,4,opt,name=OptionalGroup" json:"optionalgroup,omitempty"` - // Types that are valid to be assigned to Union: - // *Test_Number - // *Test_Name - Union isTest_Union `protobuf_oneof:"union"` - XXX_unrecognized []byte `json:"-"` - } - func (m *Test) Reset() { *m = Test{} } - func (m *Test) String() string { return proto.CompactTextString(m) } - func (*Test) ProtoMessage() {} - - type isTest_Union interface { - isTest_Union() - } - - type Test_Number struct { - Number int32 `protobuf:"varint,6,opt,name=number"` - } - type Test_Name struct { - Name string `protobuf:"bytes,7,opt,name=name"` - } - - func (*Test_Number) isTest_Union() {} - func (*Test_Name) isTest_Union() {} - - func (m *Test) GetUnion() isTest_Union { - if m != nil { - return m.Union - } - return nil - } - const Default_Test_Type int32 = 77 - - func (m *Test) GetLabel() string { - if m != nil && m.Label != nil { - return *m.Label - } - return "" - } - - func (m *Test) GetType() int32 { - if m != nil && m.Type != nil { - return *m.Type - } - return Default_Test_Type - } - - func (m *Test) GetOptionalgroup() *Test_OptionalGroup { - if m != nil { - return m.Optionalgroup - } - return nil - } - - type Test_OptionalGroup struct { - RequiredField *string `protobuf:"bytes,5,req" json:"RequiredField,omitempty"` - } - func (m *Test_OptionalGroup) Reset() { *m = Test_OptionalGroup{} } - func (m *Test_OptionalGroup) String() string { return proto.CompactTextString(m) } - - func (m *Test_OptionalGroup) GetRequiredField() string { - if m != nil && m.RequiredField != nil { - return *m.RequiredField - } - return "" - } - - func (m *Test) GetNumber() int32 { - if x, ok := m.GetUnion().(*Test_Number); ok { - return x.Number - } - return 0 - } - - func (m *Test) GetName() string { - if x, ok := m.GetUnion().(*Test_Name); ok { - return x.Name - } - return "" - } - - func init() { - proto.RegisterEnum("example.FOO", FOO_name, FOO_value) - } - -To create and play with a Test object: - - package main - - import ( - "log" - - "github.com/golang/protobuf/proto" - pb "./example.pb" - ) - - func main() { - test := &pb.Test{ - Label: proto.String("hello"), - Type: proto.Int32(17), - Reps: []int64{1, 2, 3}, - Optionalgroup: &pb.Test_OptionalGroup{ - RequiredField: proto.String("good bye"), - }, - Union: &pb.Test_Name{"fred"}, - } - data, err := proto.Marshal(test) - if err != nil { - log.Fatal("marshaling error: ", err) - } - newTest := &pb.Test{} - err = proto.Unmarshal(data, newTest) - if err != nil { - log.Fatal("unmarshaling error: ", err) - } - // Now test and newTest contain the same data. - if test.GetLabel() != newTest.GetLabel() { - log.Fatalf("data mismatch %q != %q", test.GetLabel(), newTest.GetLabel()) - } - // Use a type switch to determine which oneof was set. - switch u := test.Union.(type) { - case *pb.Test_Number: // u.Number contains the number. - case *pb.Test_Name: // u.Name contains the string. - } - // etc. - } -*/ -package proto - -import ( - "encoding/json" - "fmt" - "log" - "reflect" - "sort" - "strconv" - "sync" -) - -// RequiredNotSetError is an error type returned by either Marshal or Unmarshal. -// Marshal reports this when a required field is not initialized. -// Unmarshal reports this when a required field is missing from the wire data. -type RequiredNotSetError struct{ field string } - -func (e *RequiredNotSetError) Error() string { - if e.field == "" { - return fmt.Sprintf("proto: required field not set") - } - return fmt.Sprintf("proto: required field %q not set", e.field) -} -func (e *RequiredNotSetError) RequiredNotSet() bool { - return true -} - -type invalidUTF8Error struct{ field string } - -func (e *invalidUTF8Error) Error() string { - if e.field == "" { - return "proto: invalid UTF-8 detected" - } - return fmt.Sprintf("proto: field %q contains invalid UTF-8", e.field) -} -func (e *invalidUTF8Error) InvalidUTF8() bool { - return true -} - -// errInvalidUTF8 is a sentinel error to identify fields with invalid UTF-8. -// This error should not be exposed to the external API as such errors should -// be recreated with the field information. -var errInvalidUTF8 = &invalidUTF8Error{} - -// isNonFatal reports whether the error is either a RequiredNotSet error -// or a InvalidUTF8 error. -func isNonFatal(err error) bool { - if re, ok := err.(interface{ RequiredNotSet() bool }); ok && re.RequiredNotSet() { - return true - } - if re, ok := err.(interface{ InvalidUTF8() bool }); ok && re.InvalidUTF8() { - return true - } - return false -} - -type nonFatal struct{ E error } - -// Merge merges err into nf and reports whether it was successful. -// Otherwise it returns false for any fatal non-nil errors. -func (nf *nonFatal) Merge(err error) (ok bool) { - if err == nil { - return true // not an error - } - if !isNonFatal(err) { - return false // fatal error - } - if nf.E == nil { - nf.E = err // store first instance of non-fatal error - } - return true -} - -// Message is implemented by generated protocol buffer messages. -type Message interface { - Reset() - String() string - ProtoMessage() -} - -// A Buffer is a buffer manager for marshaling and unmarshaling -// protocol buffers. It may be reused between invocations to -// reduce memory usage. It is not necessary to use a Buffer; -// the global functions Marshal and Unmarshal create a -// temporary Buffer and are fine for most applications. -type Buffer struct { - buf []byte // encode/decode byte stream - index int // read point - - deterministic bool -} - -// NewBuffer allocates a new Buffer and initializes its internal data to -// the contents of the argument slice. -func NewBuffer(e []byte) *Buffer { - return &Buffer{buf: e} -} - -// Reset resets the Buffer, ready for marshaling a new protocol buffer. -func (p *Buffer) Reset() { - p.buf = p.buf[0:0] // for reading/writing - p.index = 0 // for reading -} - -// SetBuf replaces the internal buffer with the slice, -// ready for unmarshaling the contents of the slice. -func (p *Buffer) SetBuf(s []byte) { - p.buf = s - p.index = 0 -} - -// Bytes returns the contents of the Buffer. -func (p *Buffer) Bytes() []byte { return p.buf } - -// SetDeterministic sets whether to use deterministic serialization. -// -// Deterministic serialization guarantees that for a given binary, equal -// messages will always be serialized to the same bytes. This implies: -// -// - Repeated serialization of a message will return the same bytes. -// - Different processes of the same binary (which may be executing on -// different machines) will serialize equal messages to the same bytes. -// -// Note that the deterministic serialization is NOT canonical across -// languages. It is not guaranteed to remain stable over time. It is unstable -// across different builds with schema changes due to unknown fields. -// Users who need canonical serialization (e.g., persistent storage in a -// canonical form, fingerprinting, etc.) should define their own -// canonicalization specification and implement their own serializer rather -// than relying on this API. -// -// If deterministic serialization is requested, map entries will be sorted -// by keys in lexicographical order. This is an implementation detail and -// subject to change. -func (p *Buffer) SetDeterministic(deterministic bool) { - p.deterministic = deterministic -} - -/* - * Helper routines for simplifying the creation of optional fields of basic type. - */ - -// Bool is a helper routine that allocates a new bool value -// to store v and returns a pointer to it. -func Bool(v bool) *bool { - return &v -} - -// Int32 is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it. -func Int32(v int32) *int32 { - return &v -} - -// Int is a helper routine that allocates a new int32 value -// to store v and returns a pointer to it, but unlike Int32 -// its argument value is an int. -func Int(v int) *int32 { - p := new(int32) - *p = int32(v) - return p -} - -// Int64 is a helper routine that allocates a new int64 value -// to store v and returns a pointer to it. -func Int64(v int64) *int64 { - return &v -} - -// Float32 is a helper routine that allocates a new float32 value -// to store v and returns a pointer to it. -func Float32(v float32) *float32 { - return &v -} - -// Float64 is a helper routine that allocates a new float64 value -// to store v and returns a pointer to it. -func Float64(v float64) *float64 { - return &v -} - -// Uint32 is a helper routine that allocates a new uint32 value -// to store v and returns a pointer to it. -func Uint32(v uint32) *uint32 { - return &v -} - -// Uint64 is a helper routine that allocates a new uint64 value -// to store v and returns a pointer to it. -func Uint64(v uint64) *uint64 { - return &v -} - -// String is a helper routine that allocates a new string value -// to store v and returns a pointer to it. -func String(v string) *string { - return &v -} - -// EnumName is a helper function to simplify printing protocol buffer enums -// by name. Given an enum map and a value, it returns a useful string. -func EnumName(m map[int32]string, v int32) string { - s, ok := m[v] - if ok { - return s - } - return strconv.Itoa(int(v)) -} - -// UnmarshalJSONEnum is a helper function to simplify recovering enum int values -// from their JSON-encoded representation. Given a map from the enum's symbolic -// names to its int values, and a byte buffer containing the JSON-encoded -// value, it returns an int32 that can be cast to the enum type by the caller. -// -// The function can deal with both JSON representations, numeric and symbolic. -func UnmarshalJSONEnum(m map[string]int32, data []byte, enumName string) (int32, error) { - if data[0] == '"' { - // New style: enums are strings. - var repr string - if err := json.Unmarshal(data, &repr); err != nil { - return -1, err - } - val, ok := m[repr] - if !ok { - return 0, fmt.Errorf("unrecognized enum %s value %q", enumName, repr) - } - return val, nil - } - // Old style: enums are ints. - var val int32 - if err := json.Unmarshal(data, &val); err != nil { - return 0, fmt.Errorf("cannot unmarshal %#q into enum %s", data, enumName) - } - return val, nil -} - -// DebugPrint dumps the encoded data in b in a debugging format with a header -// including the string s. Used in testing but made available for general debugging. -func (p *Buffer) DebugPrint(s string, b []byte) { - var u uint64 - - obuf := p.buf - index := p.index - p.buf = b - p.index = 0 - depth := 0 - - fmt.Printf("\n--- %s ---\n", s) - -out: - for { - for i := 0; i < depth; i++ { - fmt.Print(" ") - } - - index := p.index - if index == len(p.buf) { - break - } - - op, err := p.DecodeVarint() - if err != nil { - fmt.Printf("%3d: fetching op err %v\n", index, err) - break out - } - tag := op >> 3 - wire := op & 7 - - switch wire { - default: - fmt.Printf("%3d: t=%3d unknown wire=%d\n", - index, tag, wire) - break out - - case WireBytes: - var r []byte - - r, err = p.DecodeRawBytes(false) - if err != nil { - break out - } - fmt.Printf("%3d: t=%3d bytes [%d]", index, tag, len(r)) - if len(r) <= 6 { - for i := 0; i < len(r); i++ { - fmt.Printf(" %.2x", r[i]) - } - } else { - for i := 0; i < 3; i++ { - fmt.Printf(" %.2x", r[i]) - } - fmt.Printf(" ..") - for i := len(r) - 3; i < len(r); i++ { - fmt.Printf(" %.2x", r[i]) - } - } - fmt.Printf("\n") - - case WireFixed32: - u, err = p.DecodeFixed32() - if err != nil { - fmt.Printf("%3d: t=%3d fix32 err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d fix32 %d\n", index, tag, u) - - case WireFixed64: - u, err = p.DecodeFixed64() - if err != nil { - fmt.Printf("%3d: t=%3d fix64 err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d fix64 %d\n", index, tag, u) - - case WireVarint: - u, err = p.DecodeVarint() - if err != nil { - fmt.Printf("%3d: t=%3d varint err %v\n", index, tag, err) - break out - } - fmt.Printf("%3d: t=%3d varint %d\n", index, tag, u) - - case WireStartGroup: - fmt.Printf("%3d: t=%3d start\n", index, tag) - depth++ - - case WireEndGroup: - depth-- - fmt.Printf("%3d: t=%3d end\n", index, tag) - } - } - - if depth != 0 { - fmt.Printf("%3d: start-end not balanced %d\n", p.index, depth) - } - fmt.Printf("\n") - - p.buf = obuf - p.index = index -} - -// SetDefaults sets unset protocol buffer fields to their default values. -// It only modifies fields that are both unset and have defined defaults. -// It recursively sets default values in any non-nil sub-messages. -func SetDefaults(pb Message) { - setDefaults(reflect.ValueOf(pb), true, false) -} - -// v is a pointer to a struct. -func setDefaults(v reflect.Value, recur, zeros bool) { - v = v.Elem() - - defaultMu.RLock() - dm, ok := defaults[v.Type()] - defaultMu.RUnlock() - if !ok { - dm = buildDefaultMessage(v.Type()) - defaultMu.Lock() - defaults[v.Type()] = dm - defaultMu.Unlock() - } - - for _, sf := range dm.scalars { - f := v.Field(sf.index) - if !f.IsNil() { - // field already set - continue - } - dv := sf.value - if dv == nil && !zeros { - // no explicit default, and don't want to set zeros - continue - } - fptr := f.Addr().Interface() // **T - // TODO: Consider batching the allocations we do here. - switch sf.kind { - case reflect.Bool: - b := new(bool) - if dv != nil { - *b = dv.(bool) - } - *(fptr.(**bool)) = b - case reflect.Float32: - f := new(float32) - if dv != nil { - *f = dv.(float32) - } - *(fptr.(**float32)) = f - case reflect.Float64: - f := new(float64) - if dv != nil { - *f = dv.(float64) - } - *(fptr.(**float64)) = f - case reflect.Int32: - // might be an enum - if ft := f.Type(); ft != int32PtrType { - // enum - f.Set(reflect.New(ft.Elem())) - if dv != nil { - f.Elem().SetInt(int64(dv.(int32))) - } - } else { - // int32 field - i := new(int32) - if dv != nil { - *i = dv.(int32) - } - *(fptr.(**int32)) = i - } - case reflect.Int64: - i := new(int64) - if dv != nil { - *i = dv.(int64) - } - *(fptr.(**int64)) = i - case reflect.String: - s := new(string) - if dv != nil { - *s = dv.(string) - } - *(fptr.(**string)) = s - case reflect.Uint8: - // exceptional case: []byte - var b []byte - if dv != nil { - db := dv.([]byte) - b = make([]byte, len(db)) - copy(b, db) - } else { - b = []byte{} - } - *(fptr.(*[]byte)) = b - case reflect.Uint32: - u := new(uint32) - if dv != nil { - *u = dv.(uint32) - } - *(fptr.(**uint32)) = u - case reflect.Uint64: - u := new(uint64) - if dv != nil { - *u = dv.(uint64) - } - *(fptr.(**uint64)) = u - default: - log.Printf("proto: can't set default for field %v (sf.kind=%v)", f, sf.kind) - } - } - - for _, ni := range dm.nested { - f := v.Field(ni) - // f is *T or []*T or map[T]*T - switch f.Kind() { - case reflect.Ptr: - if f.IsNil() { - continue - } - setDefaults(f, recur, zeros) - - case reflect.Slice: - for i := 0; i < f.Len(); i++ { - e := f.Index(i) - if e.IsNil() { - continue - } - setDefaults(e, recur, zeros) - } - - case reflect.Map: - for _, k := range f.MapKeys() { - e := f.MapIndex(k) - if e.IsNil() { - continue - } - setDefaults(e, recur, zeros) - } - } - } -} - -var ( - // defaults maps a protocol buffer struct type to a slice of the fields, - // with its scalar fields set to their proto-declared non-zero default values. - defaultMu sync.RWMutex - defaults = make(map[reflect.Type]defaultMessage) - - int32PtrType = reflect.TypeOf((*int32)(nil)) -) - -// defaultMessage represents information about the default values of a message. -type defaultMessage struct { - scalars []scalarField - nested []int // struct field index of nested messages -} - -type scalarField struct { - index int // struct field index - kind reflect.Kind // element type (the T in *T or []T) - value interface{} // the proto-declared default value, or nil -} - -// t is a struct type. -func buildDefaultMessage(t reflect.Type) (dm defaultMessage) { - sprop := GetProperties(t) - for _, prop := range sprop.Prop { - fi, ok := sprop.decoderTags.get(prop.Tag) - if !ok { - // XXX_unrecognized - continue - } - ft := t.Field(fi).Type - - sf, nested, err := fieldDefault(ft, prop) - switch { - case err != nil: - log.Print(err) - case nested: - dm.nested = append(dm.nested, fi) - case sf != nil: - sf.index = fi - dm.scalars = append(dm.scalars, *sf) - } - } - - return dm -} - -// fieldDefault returns the scalarField for field type ft. -// sf will be nil if the field can not have a default. -// nestedMessage will be true if this is a nested message. -// Note that sf.index is not set on return. -func fieldDefault(ft reflect.Type, prop *Properties) (sf *scalarField, nestedMessage bool, err error) { - var canHaveDefault bool - switch ft.Kind() { - case reflect.Ptr: - if ft.Elem().Kind() == reflect.Struct { - nestedMessage = true - } else { - canHaveDefault = true // proto2 scalar field - } - - case reflect.Slice: - switch ft.Elem().Kind() { - case reflect.Ptr: - nestedMessage = true // repeated message - case reflect.Uint8: - canHaveDefault = true // bytes field - } - - case reflect.Map: - if ft.Elem().Kind() == reflect.Ptr { - nestedMessage = true // map with message values - } - } - - if !canHaveDefault { - if nestedMessage { - return nil, true, nil - } - return nil, false, nil - } - - // We now know that ft is a pointer or slice. - sf = &scalarField{kind: ft.Elem().Kind()} - - // scalar fields without defaults - if !prop.HasDefault { - return sf, false, nil - } - - // a scalar field: either *T or []byte - switch ft.Elem().Kind() { - case reflect.Bool: - x, err := strconv.ParseBool(prop.Default) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default bool %q: %v", prop.Default, err) - } - sf.value = x - case reflect.Float32: - x, err := strconv.ParseFloat(prop.Default, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default float32 %q: %v", prop.Default, err) - } - sf.value = float32(x) - case reflect.Float64: - x, err := strconv.ParseFloat(prop.Default, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default float64 %q: %v", prop.Default, err) - } - sf.value = x - case reflect.Int32: - x, err := strconv.ParseInt(prop.Default, 10, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default int32 %q: %v", prop.Default, err) - } - sf.value = int32(x) - case reflect.Int64: - x, err := strconv.ParseInt(prop.Default, 10, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default int64 %q: %v", prop.Default, err) - } - sf.value = x - case reflect.String: - sf.value = prop.Default - case reflect.Uint8: - // []byte (not *uint8) - sf.value = []byte(prop.Default) - case reflect.Uint32: - x, err := strconv.ParseUint(prop.Default, 10, 32) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default uint32 %q: %v", prop.Default, err) - } - sf.value = uint32(x) - case reflect.Uint64: - x, err := strconv.ParseUint(prop.Default, 10, 64) - if err != nil { - return nil, false, fmt.Errorf("proto: bad default uint64 %q: %v", prop.Default, err) - } - sf.value = x - default: - return nil, false, fmt.Errorf("proto: unhandled def kind %v", ft.Elem().Kind()) - } - - return sf, false, nil -} - -// mapKeys returns a sort.Interface to be used for sorting the map keys. -// Map fields may have key types of non-float scalars, strings and enums. -func mapKeys(vs []reflect.Value) sort.Interface { - s := mapKeySorter{vs: vs} - - // Type specialization per https://developers.google.com/protocol-buffers/docs/proto#maps. - if len(vs) == 0 { - return s - } - switch vs[0].Kind() { - case reflect.Int32, reflect.Int64: - s.less = func(a, b reflect.Value) bool { return a.Int() < b.Int() } - case reflect.Uint32, reflect.Uint64: - s.less = func(a, b reflect.Value) bool { return a.Uint() < b.Uint() } - case reflect.Bool: - s.less = func(a, b reflect.Value) bool { return !a.Bool() && b.Bool() } // false < true - case reflect.String: - s.less = func(a, b reflect.Value) bool { return a.String() < b.String() } - default: - panic(fmt.Sprintf("unsupported map key type: %v", vs[0].Kind())) - } - - return s -} - -type mapKeySorter struct { - vs []reflect.Value - less func(a, b reflect.Value) bool -} - -func (s mapKeySorter) Len() int { return len(s.vs) } -func (s mapKeySorter) Swap(i, j int) { s.vs[i], s.vs[j] = s.vs[j], s.vs[i] } -func (s mapKeySorter) Less(i, j int) bool { - return s.less(s.vs[i], s.vs[j]) -} - -// isProto3Zero reports whether v is a zero proto3 value. -func isProto3Zero(v reflect.Value) bool { - switch v.Kind() { - case reflect.Bool: - return !v.Bool() - case reflect.Int32, reflect.Int64: - return v.Int() == 0 - case reflect.Uint32, reflect.Uint64: - return v.Uint() == 0 - case reflect.Float32, reflect.Float64: - return v.Float() == 0 - case reflect.String: - return v.String() == "" - } - return false -} - -const ( - // ProtoPackageIsVersion3 is referenced from generated protocol buffer files - // to assert that that code is compatible with this version of the proto package. - ProtoPackageIsVersion3 = true - - // ProtoPackageIsVersion2 is referenced from generated protocol buffer files - // to assert that that code is compatible with this version of the proto package. - ProtoPackageIsVersion2 = true - - // ProtoPackageIsVersion1 is referenced from generated protocol buffer files - // to assert that that code is compatible with this version of the proto package. - ProtoPackageIsVersion1 = true -) - -// InternalMessageInfo is a type used internally by generated .pb.go files. -// This type is not intended to be used by non-generated code. -// This type is not subject to any compatibility guarantee. -type InternalMessageInfo struct { - marshal *marshalInfo - unmarshal *unmarshalInfo - merge *mergeInfo - discard *discardInfo -} diff --git a/vendor/github.com/golang/protobuf/proto/message_set.go b/vendor/github.com/golang/protobuf/proto/message_set.go deleted file mode 100644 index f48a75676..000000000 --- a/vendor/github.com/golang/protobuf/proto/message_set.go +++ /dev/null @@ -1,181 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -/* - * Support for message sets. - */ - -import ( - "errors" -) - -// errNoMessageTypeID occurs when a protocol buffer does not have a message type ID. -// A message type ID is required for storing a protocol buffer in a message set. -var errNoMessageTypeID = errors.New("proto does not have a message type ID") - -// The first two types (_MessageSet_Item and messageSet) -// model what the protocol compiler produces for the following protocol message: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// }; -// } -// That is the MessageSet wire format. We can't use a proto to generate these -// because that would introduce a circular dependency between it and this package. - -type _MessageSet_Item struct { - TypeId *int32 `protobuf:"varint,2,req,name=type_id"` - Message []byte `protobuf:"bytes,3,req,name=message"` -} - -type messageSet struct { - Item []*_MessageSet_Item `protobuf:"group,1,rep"` - XXX_unrecognized []byte - // TODO: caching? -} - -// Make sure messageSet is a Message. -var _ Message = (*messageSet)(nil) - -// messageTypeIder is an interface satisfied by a protocol buffer type -// that may be stored in a MessageSet. -type messageTypeIder interface { - MessageTypeId() int32 -} - -func (ms *messageSet) find(pb Message) *_MessageSet_Item { - mti, ok := pb.(messageTypeIder) - if !ok { - return nil - } - id := mti.MessageTypeId() - for _, item := range ms.Item { - if *item.TypeId == id { - return item - } - } - return nil -} - -func (ms *messageSet) Has(pb Message) bool { - return ms.find(pb) != nil -} - -func (ms *messageSet) Unmarshal(pb Message) error { - if item := ms.find(pb); item != nil { - return Unmarshal(item.Message, pb) - } - if _, ok := pb.(messageTypeIder); !ok { - return errNoMessageTypeID - } - return nil // TODO: return error instead? -} - -func (ms *messageSet) Marshal(pb Message) error { - msg, err := Marshal(pb) - if err != nil { - return err - } - if item := ms.find(pb); item != nil { - // reuse existing item - item.Message = msg - return nil - } - - mti, ok := pb.(messageTypeIder) - if !ok { - return errNoMessageTypeID - } - - mtid := mti.MessageTypeId() - ms.Item = append(ms.Item, &_MessageSet_Item{ - TypeId: &mtid, - Message: msg, - }) - return nil -} - -func (ms *messageSet) Reset() { *ms = messageSet{} } -func (ms *messageSet) String() string { return CompactTextString(ms) } -func (*messageSet) ProtoMessage() {} - -// Support for the message_set_wire_format message option. - -func skipVarint(buf []byte) []byte { - i := 0 - for ; buf[i]&0x80 != 0; i++ { - } - return buf[i+1:] -} - -// unmarshalMessageSet decodes the extension map encoded in buf in the message set wire format. -// It is called by Unmarshal methods on protocol buffer messages with the message_set_wire_format option. -func unmarshalMessageSet(buf []byte, exts interface{}) error { - var m map[int32]Extension - switch exts := exts.(type) { - case *XXX_InternalExtensions: - m = exts.extensionsWrite() - case map[int32]Extension: - m = exts - default: - return errors.New("proto: not an extension map") - } - - ms := new(messageSet) - if err := Unmarshal(buf, ms); err != nil { - return err - } - for _, item := range ms.Item { - id := *item.TypeId - msg := item.Message - - // Restore wire type and field number varint, plus length varint. - // Be careful to preserve duplicate items. - b := EncodeVarint(uint64(id)<<3 | WireBytes) - if ext, ok := m[id]; ok { - // Existing data; rip off the tag and length varint - // so we join the new data correctly. - // We can assume that ext.enc is set because we are unmarshaling. - o := ext.enc[len(b):] // skip wire type and field number - _, n := DecodeVarint(o) // calculate length of length varint - o = o[n:] // skip length varint - msg = append(o, msg...) // join old data and new data - } - b = append(b, EncodeVarint(uint64(len(msg)))...) - b = append(b, msg...) - - m[id] = Extension{enc: b} - } - return nil -} diff --git a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go b/vendor/github.com/golang/protobuf/proto/pointer_reflect.go deleted file mode 100644 index 94fa9194a..000000000 --- a/vendor/github.com/golang/protobuf/proto/pointer_reflect.go +++ /dev/null @@ -1,360 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build purego appengine js - -// This file contains an implementation of proto field accesses using package reflect. -// It is slower than the code in pointer_unsafe.go but it avoids package unsafe and can -// be used on App Engine. - -package proto - -import ( - "reflect" - "sync" -) - -const unsafeAllowed = false - -// A field identifies a field in a struct, accessible from a pointer. -// In this implementation, a field is identified by the sequence of field indices -// passed to reflect's FieldByIndex. -type field []int - -// toField returns a field equivalent to the given reflect field. -func toField(f *reflect.StructField) field { - return f.Index -} - -// invalidField is an invalid field identifier. -var invalidField = field(nil) - -// zeroField is a noop when calling pointer.offset. -var zeroField = field([]int{}) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { return f != nil } - -// The pointer type is for the table-driven decoder. -// The implementation here uses a reflect.Value of pointer type to -// create a generic pointer. In pointer_unsafe.go we use unsafe -// instead of reflect to implement the same (but faster) interface. -type pointer struct { - v reflect.Value -} - -// toPointer converts an interface of pointer type to a pointer -// that points to the same target. -func toPointer(i *Message) pointer { - return pointer{v: reflect.ValueOf(*i)} -} - -// toAddrPointer converts an interface to a pointer that points to -// the interface data. -func toAddrPointer(i *interface{}, isptr, deref bool) pointer { - v := reflect.ValueOf(*i) - u := reflect.New(v.Type()) - u.Elem().Set(v) - if deref { - u = u.Elem() - } - return pointer{v: u} -} - -// valToPointer converts v to a pointer. v must be of pointer type. -func valToPointer(v reflect.Value) pointer { - return pointer{v: v} -} - -// offset converts from a pointer to a structure to a pointer to -// one of its fields. -func (p pointer) offset(f field) pointer { - return pointer{v: p.v.Elem().FieldByIndex(f).Addr()} -} - -func (p pointer) isNil() bool { - return p.v.IsNil() -} - -// grow updates the slice s in place to make it one element longer. -// s must be addressable. -// Returns the (addressable) new element. -func grow(s reflect.Value) reflect.Value { - n, m := s.Len(), s.Cap() - if n < m { - s.SetLen(n + 1) - } else { - s.Set(reflect.Append(s, reflect.Zero(s.Type().Elem()))) - } - return s.Index(n) -} - -func (p pointer) toInt64() *int64 { - return p.v.Interface().(*int64) -} -func (p pointer) toInt64Ptr() **int64 { - return p.v.Interface().(**int64) -} -func (p pointer) toInt64Slice() *[]int64 { - return p.v.Interface().(*[]int64) -} - -var int32ptr = reflect.TypeOf((*int32)(nil)) - -func (p pointer) toInt32() *int32 { - return p.v.Convert(int32ptr).Interface().(*int32) -} - -// The toInt32Ptr/Slice methods don't work because of enums. -// Instead, we must use set/get methods for the int32ptr/slice case. -/* - func (p pointer) toInt32Ptr() **int32 { - return p.v.Interface().(**int32) -} - func (p pointer) toInt32Slice() *[]int32 { - return p.v.Interface().(*[]int32) -} -*/ -func (p pointer) getInt32Ptr() *int32 { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - return p.v.Elem().Interface().(*int32) - } - // an enum - return p.v.Elem().Convert(int32PtrType).Interface().(*int32) -} -func (p pointer) setInt32Ptr(v int32) { - // Allocate value in a *int32. Possibly convert that to a *enum. - // Then assign it to a **int32 or **enum. - // Note: we can convert *int32 to *enum, but we can't convert - // **int32 to **enum! - p.v.Elem().Set(reflect.ValueOf(&v).Convert(p.v.Type().Elem())) -} - -// getInt32Slice copies []int32 from p as a new slice. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) getInt32Slice() []int32 { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - return p.v.Elem().Interface().([]int32) - } - // an enum - // Allocate a []int32, then assign []enum's values into it. - // Note: we can't convert []enum to []int32. - slice := p.v.Elem() - s := make([]int32, slice.Len()) - for i := 0; i < slice.Len(); i++ { - s[i] = int32(slice.Index(i).Int()) - } - return s -} - -// setInt32Slice copies []int32 into p as a new slice. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) setInt32Slice(v []int32) { - if p.v.Type().Elem().Elem() == reflect.TypeOf(int32(0)) { - // raw int32 type - p.v.Elem().Set(reflect.ValueOf(v)) - return - } - // an enum - // Allocate a []enum, then assign []int32's values into it. - // Note: we can't convert []enum to []int32. - slice := reflect.MakeSlice(p.v.Type().Elem(), len(v), cap(v)) - for i, x := range v { - slice.Index(i).SetInt(int64(x)) - } - p.v.Elem().Set(slice) -} -func (p pointer) appendInt32Slice(v int32) { - grow(p.v.Elem()).SetInt(int64(v)) -} - -func (p pointer) toUint64() *uint64 { - return p.v.Interface().(*uint64) -} -func (p pointer) toUint64Ptr() **uint64 { - return p.v.Interface().(**uint64) -} -func (p pointer) toUint64Slice() *[]uint64 { - return p.v.Interface().(*[]uint64) -} -func (p pointer) toUint32() *uint32 { - return p.v.Interface().(*uint32) -} -func (p pointer) toUint32Ptr() **uint32 { - return p.v.Interface().(**uint32) -} -func (p pointer) toUint32Slice() *[]uint32 { - return p.v.Interface().(*[]uint32) -} -func (p pointer) toBool() *bool { - return p.v.Interface().(*bool) -} -func (p pointer) toBoolPtr() **bool { - return p.v.Interface().(**bool) -} -func (p pointer) toBoolSlice() *[]bool { - return p.v.Interface().(*[]bool) -} -func (p pointer) toFloat64() *float64 { - return p.v.Interface().(*float64) -} -func (p pointer) toFloat64Ptr() **float64 { - return p.v.Interface().(**float64) -} -func (p pointer) toFloat64Slice() *[]float64 { - return p.v.Interface().(*[]float64) -} -func (p pointer) toFloat32() *float32 { - return p.v.Interface().(*float32) -} -func (p pointer) toFloat32Ptr() **float32 { - return p.v.Interface().(**float32) -} -func (p pointer) toFloat32Slice() *[]float32 { - return p.v.Interface().(*[]float32) -} -func (p pointer) toString() *string { - return p.v.Interface().(*string) -} -func (p pointer) toStringPtr() **string { - return p.v.Interface().(**string) -} -func (p pointer) toStringSlice() *[]string { - return p.v.Interface().(*[]string) -} -func (p pointer) toBytes() *[]byte { - return p.v.Interface().(*[]byte) -} -func (p pointer) toBytesSlice() *[][]byte { - return p.v.Interface().(*[][]byte) -} -func (p pointer) toExtensions() *XXX_InternalExtensions { - return p.v.Interface().(*XXX_InternalExtensions) -} -func (p pointer) toOldExtensions() *map[int32]Extension { - return p.v.Interface().(*map[int32]Extension) -} -func (p pointer) getPointer() pointer { - return pointer{v: p.v.Elem()} -} -func (p pointer) setPointer(q pointer) { - p.v.Elem().Set(q.v) -} -func (p pointer) appendPointer(q pointer) { - grow(p.v.Elem()).Set(q.v) -} - -// getPointerSlice copies []*T from p as a new []pointer. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) getPointerSlice() []pointer { - if p.v.IsNil() { - return nil - } - n := p.v.Elem().Len() - s := make([]pointer, n) - for i := 0; i < n; i++ { - s[i] = pointer{v: p.v.Elem().Index(i)} - } - return s -} - -// setPointerSlice copies []pointer into p as a new []*T. -// This behavior differs from the implementation in pointer_unsafe.go. -func (p pointer) setPointerSlice(v []pointer) { - if v == nil { - p.v.Elem().Set(reflect.New(p.v.Elem().Type()).Elem()) - return - } - s := reflect.MakeSlice(p.v.Elem().Type(), 0, len(v)) - for _, p := range v { - s = reflect.Append(s, p.v) - } - p.v.Elem().Set(s) -} - -// getInterfacePointer returns a pointer that points to the -// interface data of the interface pointed by p. -func (p pointer) getInterfacePointer() pointer { - if p.v.Elem().IsNil() { - return pointer{v: p.v.Elem()} - } - return pointer{v: p.v.Elem().Elem().Elem().Field(0).Addr()} // *interface -> interface -> *struct -> struct -} - -func (p pointer) asPointerTo(t reflect.Type) reflect.Value { - // TODO: check that p.v.Type().Elem() == t? - return p.v -} - -func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} -func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { - atomicLock.Lock() - defer atomicLock.Unlock() - return *p -} -func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { - atomicLock.Lock() - defer atomicLock.Unlock() - *p = v -} - -var atomicLock sync.Mutex diff --git a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go b/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go deleted file mode 100644 index dbfffe071..000000000 --- a/vendor/github.com/golang/protobuf/proto/pointer_unsafe.go +++ /dev/null @@ -1,313 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2012 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// +build !purego,!appengine,!js - -// This file contains the implementation of the proto field accesses using package unsafe. - -package proto - -import ( - "reflect" - "sync/atomic" - "unsafe" -) - -const unsafeAllowed = true - -// A field identifies a field in a struct, accessible from a pointer. -// In this implementation, a field is identified by its byte offset from the start of the struct. -type field uintptr - -// toField returns a field equivalent to the given reflect field. -func toField(f *reflect.StructField) field { - return field(f.Offset) -} - -// invalidField is an invalid field identifier. -const invalidField = ^field(0) - -// zeroField is a noop when calling pointer.offset. -const zeroField = field(0) - -// IsValid reports whether the field identifier is valid. -func (f field) IsValid() bool { - return f != invalidField -} - -// The pointer type below is for the new table-driven encoder/decoder. -// The implementation here uses unsafe.Pointer to create a generic pointer. -// In pointer_reflect.go we use reflect instead of unsafe to implement -// the same (but slower) interface. -type pointer struct { - p unsafe.Pointer -} - -// size of pointer -var ptrSize = unsafe.Sizeof(uintptr(0)) - -// toPointer converts an interface of pointer type to a pointer -// that points to the same target. -func toPointer(i *Message) pointer { - // Super-tricky - read pointer out of data word of interface value. - // Saves ~25ns over the equivalent: - // return valToPointer(reflect.ValueOf(*i)) - return pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} -} - -// toAddrPointer converts an interface to a pointer that points to -// the interface data. -func toAddrPointer(i *interface{}, isptr, deref bool) (p pointer) { - // Super-tricky - read or get the address of data word of interface value. - if isptr { - // The interface is of pointer type, thus it is a direct interface. - // The data word is the pointer data itself. We take its address. - p = pointer{p: unsafe.Pointer(uintptr(unsafe.Pointer(i)) + ptrSize)} - } else { - // The interface is not of pointer type. The data word is the pointer - // to the data. - p = pointer{p: (*[2]unsafe.Pointer)(unsafe.Pointer(i))[1]} - } - if deref { - p.p = *(*unsafe.Pointer)(p.p) - } - return p -} - -// valToPointer converts v to a pointer. v must be of pointer type. -func valToPointer(v reflect.Value) pointer { - return pointer{p: unsafe.Pointer(v.Pointer())} -} - -// offset converts from a pointer to a structure to a pointer to -// one of its fields. -func (p pointer) offset(f field) pointer { - // For safety, we should panic if !f.IsValid, however calling panic causes - // this to no longer be inlineable, which is a serious performance cost. - /* - if !f.IsValid() { - panic("invalid field") - } - */ - return pointer{p: unsafe.Pointer(uintptr(p.p) + uintptr(f))} -} - -func (p pointer) isNil() bool { - return p.p == nil -} - -func (p pointer) toInt64() *int64 { - return (*int64)(p.p) -} -func (p pointer) toInt64Ptr() **int64 { - return (**int64)(p.p) -} -func (p pointer) toInt64Slice() *[]int64 { - return (*[]int64)(p.p) -} -func (p pointer) toInt32() *int32 { - return (*int32)(p.p) -} - -// See pointer_reflect.go for why toInt32Ptr/Slice doesn't exist. -/* - func (p pointer) toInt32Ptr() **int32 { - return (**int32)(p.p) - } - func (p pointer) toInt32Slice() *[]int32 { - return (*[]int32)(p.p) - } -*/ -func (p pointer) getInt32Ptr() *int32 { - return *(**int32)(p.p) -} -func (p pointer) setInt32Ptr(v int32) { - *(**int32)(p.p) = &v -} - -// getInt32Slice loads a []int32 from p. -// The value returned is aliased with the original slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) getInt32Slice() []int32 { - return *(*[]int32)(p.p) -} - -// setInt32Slice stores a []int32 to p. -// The value set is aliased with the input slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) setInt32Slice(v []int32) { - *(*[]int32)(p.p) = v -} - -// TODO: Can we get rid of appendInt32Slice and use setInt32Slice instead? -func (p pointer) appendInt32Slice(v int32) { - s := (*[]int32)(p.p) - *s = append(*s, v) -} - -func (p pointer) toUint64() *uint64 { - return (*uint64)(p.p) -} -func (p pointer) toUint64Ptr() **uint64 { - return (**uint64)(p.p) -} -func (p pointer) toUint64Slice() *[]uint64 { - return (*[]uint64)(p.p) -} -func (p pointer) toUint32() *uint32 { - return (*uint32)(p.p) -} -func (p pointer) toUint32Ptr() **uint32 { - return (**uint32)(p.p) -} -func (p pointer) toUint32Slice() *[]uint32 { - return (*[]uint32)(p.p) -} -func (p pointer) toBool() *bool { - return (*bool)(p.p) -} -func (p pointer) toBoolPtr() **bool { - return (**bool)(p.p) -} -func (p pointer) toBoolSlice() *[]bool { - return (*[]bool)(p.p) -} -func (p pointer) toFloat64() *float64 { - return (*float64)(p.p) -} -func (p pointer) toFloat64Ptr() **float64 { - return (**float64)(p.p) -} -func (p pointer) toFloat64Slice() *[]float64 { - return (*[]float64)(p.p) -} -func (p pointer) toFloat32() *float32 { - return (*float32)(p.p) -} -func (p pointer) toFloat32Ptr() **float32 { - return (**float32)(p.p) -} -func (p pointer) toFloat32Slice() *[]float32 { - return (*[]float32)(p.p) -} -func (p pointer) toString() *string { - return (*string)(p.p) -} -func (p pointer) toStringPtr() **string { - return (**string)(p.p) -} -func (p pointer) toStringSlice() *[]string { - return (*[]string)(p.p) -} -func (p pointer) toBytes() *[]byte { - return (*[]byte)(p.p) -} -func (p pointer) toBytesSlice() *[][]byte { - return (*[][]byte)(p.p) -} -func (p pointer) toExtensions() *XXX_InternalExtensions { - return (*XXX_InternalExtensions)(p.p) -} -func (p pointer) toOldExtensions() *map[int32]Extension { - return (*map[int32]Extension)(p.p) -} - -// getPointerSlice loads []*T from p as a []pointer. -// The value returned is aliased with the original slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) getPointerSlice() []pointer { - // Super-tricky - p should point to a []*T where T is a - // message type. We load it as []pointer. - return *(*[]pointer)(p.p) -} - -// setPointerSlice stores []pointer into p as a []*T. -// The value set is aliased with the input slice. -// This behavior differs from the implementation in pointer_reflect.go. -func (p pointer) setPointerSlice(v []pointer) { - // Super-tricky - p should point to a []*T where T is a - // message type. We store it as []pointer. - *(*[]pointer)(p.p) = v -} - -// getPointer loads the pointer at p and returns it. -func (p pointer) getPointer() pointer { - return pointer{p: *(*unsafe.Pointer)(p.p)} -} - -// setPointer stores the pointer q at p. -func (p pointer) setPointer(q pointer) { - *(*unsafe.Pointer)(p.p) = q.p -} - -// append q to the slice pointed to by p. -func (p pointer) appendPointer(q pointer) { - s := (*[]unsafe.Pointer)(p.p) - *s = append(*s, q.p) -} - -// getInterfacePointer returns a pointer that points to the -// interface data of the interface pointed by p. -func (p pointer) getInterfacePointer() pointer { - // Super-tricky - read pointer out of data word of interface value. - return pointer{p: (*(*[2]unsafe.Pointer)(p.p))[1]} -} - -// asPointerTo returns a reflect.Value that is a pointer to an -// object of type t stored at p. -func (p pointer) asPointerTo(t reflect.Type) reflect.Value { - return reflect.NewAt(t, p.p) -} - -func atomicLoadUnmarshalInfo(p **unmarshalInfo) *unmarshalInfo { - return (*unmarshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreUnmarshalInfo(p **unmarshalInfo, v *unmarshalInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadMarshalInfo(p **marshalInfo) *marshalInfo { - return (*marshalInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreMarshalInfo(p **marshalInfo, v *marshalInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadMergeInfo(p **mergeInfo) *mergeInfo { - return (*mergeInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreMergeInfo(p **mergeInfo, v *mergeInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} -func atomicLoadDiscardInfo(p **discardInfo) *discardInfo { - return (*discardInfo)(atomic.LoadPointer((*unsafe.Pointer)(unsafe.Pointer(p)))) -} -func atomicStoreDiscardInfo(p **discardInfo, v *discardInfo) { - atomic.StorePointer((*unsafe.Pointer)(unsafe.Pointer(p)), unsafe.Pointer(v)) -} diff --git a/vendor/github.com/golang/protobuf/proto/properties.go b/vendor/github.com/golang/protobuf/proto/properties.go index a4b8c0cd3..dcdc2202f 100644 --- a/vendor/github.com/golang/protobuf/proto/properties.go +++ b/vendor/github.com/golang/protobuf/proto/properties.go @@ -1,162 +1,104 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. package proto -/* - * Routines for encoding data into the wire format for protocol buffers. - */ - import ( "fmt" - "log" "reflect" - "sort" "strconv" "strings" "sync" -) - -const debug bool = false -// Constants that identify the encoding of a value on the wire. -const ( - WireVarint = 0 - WireFixed64 = 1 - WireBytes = 2 - WireStartGroup = 3 - WireEndGroup = 4 - WireFixed32 = 5 + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoimpl" ) -// tagMap is an optimization over map[int]int for typical protocol buffer -// use-cases. Encoded protocol buffers are often in tag order with small tag -// numbers. -type tagMap struct { - fastTags []int - slowTags map[int]int -} - -// tagMapFastLimit is the upper bound on the tag number that will be stored in -// the tagMap slice rather than its map. -const tagMapFastLimit = 1024 - -func (p *tagMap) get(t int) (int, bool) { - if t > 0 && t < tagMapFastLimit { - if t >= len(p.fastTags) { - return 0, false - } - fi := p.fastTags[t] - return fi, fi >= 0 - } - fi, ok := p.slowTags[t] - return fi, ok -} - -func (p *tagMap) put(t int, fi int) { - if t > 0 && t < tagMapFastLimit { - for len(p.fastTags) < t+1 { - p.fastTags = append(p.fastTags, -1) - } - p.fastTags[t] = fi - return - } - if p.slowTags == nil { - p.slowTags = make(map[int]int) - } - p.slowTags[t] = fi -} - -// StructProperties represents properties for all the fields of a struct. -// decoderTags and decoderOrigNames should only be used by the decoder. +// StructProperties represents protocol buffer type information for a +// generated protobuf message in the open-struct API. +// +// Deprecated: Do not use. type StructProperties struct { - Prop []*Properties // properties for each field - reqCount int // required count - decoderTags tagMap // map from proto tag to struct field number - decoderOrigNames map[string]int // map from original name to struct field number - order []int // list of struct field numbers in tag order + // Prop are the properties for each field. + // + // Fields belonging to a oneof are stored in OneofTypes instead, with a + // single Properties representing the parent oneof held here. + // + // The order of Prop matches the order of fields in the Go struct. + // Struct fields that are not related to protobufs have a "XXX_" prefix + // in the Properties.Name and must be ignored by the user. + Prop []*Properties // OneofTypes contains information about the oneof fields in this message. - // It is keyed by the original name of a field. + // It is keyed by the protobuf field name. OneofTypes map[string]*OneofProperties } -// OneofProperties represents information about a specific field in a oneof. -type OneofProperties struct { - Type reflect.Type // pointer to generated struct type for this oneof field - Field int // struct field number of the containing oneof in the message - Prop *Properties -} - -// Implement the sorting interface so we can sort the fields in tag order, as recommended by the spec. -// See encode.go, (*Buffer).enc_struct. - -func (sp *StructProperties) Len() int { return len(sp.order) } -func (sp *StructProperties) Less(i, j int) bool { - return sp.Prop[sp.order[i]].Tag < sp.Prop[sp.order[j]].Tag -} -func (sp *StructProperties) Swap(i, j int) { sp.order[i], sp.order[j] = sp.order[j], sp.order[i] } - -// Properties represents the protocol-specific behavior of a single struct field. +// Properties represents the type information for a protobuf message field. +// +// Deprecated: Do not use. type Properties struct { - Name string // name of the field, for error messages - OrigName string // original name before protocol compiler (always set) - JSONName string // name to use for JSON; determined by protoc - Wire string + // Name is a placeholder name with little meaningful semantic value. + // If the name has an "XXX_" prefix, the entire Properties must be ignored. + Name string + // OrigName is the protobuf field name or oneof name. + OrigName string + // JSONName is the JSON name for the protobuf field. + JSONName string + // Enum is a placeholder name for enums. + // For historical reasons, this is neither the Go name for the enum, + // nor the protobuf name for the enum. + Enum string // Deprecated: Do not use. + // Weak contains the full name of the weakly referenced message. + Weak string + // Wire is a string representation of the wire type. + Wire string + // WireType is the protobuf wire type for the field. WireType int - Tag int + // Tag is the protobuf field number. + Tag int + // Required reports whether this is a required field. Required bool + // Optional reports whether this is a optional field. Optional bool + // Repeated reports whether this is a repeated field. Repeated bool - Packed bool // relevant for repeated primitives only - Enum string // set for enum types only - proto3 bool // whether this is known to be a proto3 field - oneof bool // whether this is a oneof field - - Default string // default value - HasDefault bool // whether an explicit default was provided - - stype reflect.Type // set for struct types only - sprop *StructProperties // set for struct types only + // Packed reports whether this is a packed repeated field of scalars. + Packed bool + // Proto3 reports whether this field operates under the proto3 syntax. + Proto3 bool + // Oneof reports whether this field belongs within a oneof. + Oneof bool + + // Default is the default value in string form. + Default string + // HasDefault reports whether the field has a default value. + HasDefault bool + + // MapKeyProp is the properties for the key field for a map field. + MapKeyProp *Properties + // MapValProp is the properties for the value field for a map field. + MapValProp *Properties +} - mtype reflect.Type // set for map types only - MapKeyProp *Properties // set for map types only - MapValProp *Properties // set for map types only +// OneofProperties represents the type information for a protobuf oneof. +// +// Deprecated: Do not use. +type OneofProperties struct { + // Type is a pointer to the generated wrapper type for the field value. + // This is nil for messages that are not in the open-struct API. + Type reflect.Type + // Field is the index into StructProperties.Prop for the containing oneof. + Field int + // Prop is the properties for the field. + Prop *Properties } // String formats the properties in the protobuf struct field tag style. func (p *Properties) String() string { s := p.Wire - s += "," - s += strconv.Itoa(p.Tag) + s += "," + strconv.Itoa(p.Tag) if p.Required { s += ",req" } @@ -170,18 +112,21 @@ func (p *Properties) String() string { s += ",packed" } s += ",name=" + p.OrigName - if p.JSONName != p.OrigName { + if p.JSONName != "" { s += ",json=" + p.JSONName } - if p.proto3 { + if len(p.Enum) > 0 { + s += ",enum=" + p.Enum + } + if len(p.Weak) > 0 { + s += ",weak=" + p.Weak + } + if p.Proto3 { s += ",proto3" } - if p.oneof { + if p.Oneof { s += ",oneof" } - if len(p.Enum) > 0 { - s += ",enum=" + p.Enum - } if p.HasDefault { s += ",def=" + p.Default } @@ -189,356 +134,173 @@ func (p *Properties) String() string { } // Parse populates p by parsing a string in the protobuf struct field tag style. -func (p *Properties) Parse(s string) { - // "bytes,49,opt,name=foo,def=hello!" - fields := strings.Split(s, ",") // breaks def=, but handled below. - if len(fields) < 2 { - log.Printf("proto: tag has too few fields: %q", s) - return - } - - p.Wire = fields[0] - switch p.Wire { - case "varint": - p.WireType = WireVarint - case "fixed32": - p.WireType = WireFixed32 - case "fixed64": - p.WireType = WireFixed64 - case "zigzag32": - p.WireType = WireVarint - case "zigzag64": - p.WireType = WireVarint - case "bytes", "group": - p.WireType = WireBytes - // no numeric converter for non-numeric types - default: - log.Printf("proto: tag has unknown wire type: %q", s) - return - } - - var err error - p.Tag, err = strconv.Atoi(fields[1]) - if err != nil { - return - } - -outer: - for i := 2; i < len(fields); i++ { - f := fields[i] - switch { - case f == "req": - p.Required = true - case f == "opt": +func (p *Properties) Parse(tag string) { + // For example: "bytes,49,opt,name=foo,def=hello!" + for len(tag) > 0 { + i := strings.IndexByte(tag, ',') + if i < 0 { + i = len(tag) + } + switch s := tag[:i]; { + case strings.HasPrefix(s, "name="): + p.OrigName = s[len("name="):] + case strings.HasPrefix(s, "json="): + p.JSONName = s[len("json="):] + case strings.HasPrefix(s, "enum="): + p.Enum = s[len("enum="):] + case strings.HasPrefix(s, "weak="): + p.Weak = s[len("weak="):] + case strings.Trim(s, "0123456789") == "": + n, _ := strconv.ParseUint(s, 10, 32) + p.Tag = int(n) + case s == "opt": p.Optional = true - case f == "rep": + case s == "req": + p.Required = true + case s == "rep": p.Repeated = true - case f == "packed": + case s == "varint" || s == "zigzag32" || s == "zigzag64": + p.Wire = s + p.WireType = WireVarint + case s == "fixed32": + p.Wire = s + p.WireType = WireFixed32 + case s == "fixed64": + p.Wire = s + p.WireType = WireFixed64 + case s == "bytes": + p.Wire = s + p.WireType = WireBytes + case s == "group": + p.Wire = s + p.WireType = WireStartGroup + case s == "packed": p.Packed = true - case strings.HasPrefix(f, "name="): - p.OrigName = f[5:] - case strings.HasPrefix(f, "json="): - p.JSONName = f[5:] - case strings.HasPrefix(f, "enum="): - p.Enum = f[5:] - case f == "proto3": - p.proto3 = true - case f == "oneof": - p.oneof = true - case strings.HasPrefix(f, "def="): + case s == "proto3": + p.Proto3 = true + case s == "oneof": + p.Oneof = true + case strings.HasPrefix(s, "def="): + // The default tag is special in that everything afterwards is the + // default regardless of the presence of commas. p.HasDefault = true - p.Default = f[4:] // rest of string - if i+1 < len(fields) { - // Commas aren't escaped, and def is always last. - p.Default += "," + strings.Join(fields[i+1:], ",") - break outer - } - } - } -} - -var protoMessageType = reflect.TypeOf((*Message)(nil)).Elem() - -// setFieldProps initializes the field properties for submessages and maps. -func (p *Properties) setFieldProps(typ reflect.Type, f *reflect.StructField, lockGetProp bool) { - switch t1 := typ; t1.Kind() { - case reflect.Ptr: - if t1.Elem().Kind() == reflect.Struct { - p.stype = t1.Elem() - } - - case reflect.Slice: - if t2 := t1.Elem(); t2.Kind() == reflect.Ptr && t2.Elem().Kind() == reflect.Struct { - p.stype = t2.Elem() - } - - case reflect.Map: - p.mtype = t1 - p.MapKeyProp = &Properties{} - p.MapKeyProp.init(reflect.PtrTo(p.mtype.Key()), "Key", f.Tag.Get("protobuf_key"), nil, lockGetProp) - p.MapValProp = &Properties{} - vtype := p.mtype.Elem() - if vtype.Kind() != reflect.Ptr && vtype.Kind() != reflect.Slice { - // The value type is not a message (*T) or bytes ([]byte), - // so we need encoders for the pointer to this type. - vtype = reflect.PtrTo(vtype) - } - p.MapValProp.init(vtype, "Value", f.Tag.Get("protobuf_val"), nil, lockGetProp) - } - - if p.stype != nil { - if lockGetProp { - p.sprop = GetProperties(p.stype) - } else { - p.sprop = getPropertiesLocked(p.stype) + p.Default, i = tag[len("def="):], len(tag) } + tag = strings.TrimPrefix(tag[i:], ",") } } -var ( - marshalerType = reflect.TypeOf((*Marshaler)(nil)).Elem() -) - // Init populates the properties from a protocol buffer struct tag. +// +// Deprecated: Do not use. func (p *Properties) Init(typ reflect.Type, name, tag string, f *reflect.StructField) { - p.init(typ, name, tag, f, true) -} - -func (p *Properties) init(typ reflect.Type, name, tag string, f *reflect.StructField, lockGetProp bool) { - // "bytes,49,opt,def=hello!" p.Name = name p.OrigName = name if tag == "" { return } p.Parse(tag) - p.setFieldProps(typ, f, lockGetProp) + + if typ != nil && typ.Kind() == reflect.Map { + p.MapKeyProp = new(Properties) + p.MapKeyProp.Init(nil, "Key", f.Tag.Get("protobuf_key"), nil) + p.MapValProp = new(Properties) + p.MapValProp.Init(nil, "Value", f.Tag.Get("protobuf_val"), nil) + } } -var ( - propertiesMu sync.RWMutex - propertiesMap = make(map[reflect.Type]*StructProperties) -) +var propertiesCache sync.Map // map[reflect.Type]*StructProperties -// GetProperties returns the list of properties for the type represented by t. -// t must represent a generated struct type of a protocol message. +// GetProperties returns the list of properties for the type represented by t, +// which must be a generated protocol buffer message in the open-struct API, +// where protobuf message fields are represented by exported Go struct fields. +// +// Deprecated: Use protobuf reflection instead. func GetProperties(t reflect.Type) *StructProperties { - if t.Kind() != reflect.Struct { - panic("proto: type must have kind struct") - } - - // Most calls to GetProperties in a long-running program will be - // retrieving details for types we have seen before. - propertiesMu.RLock() - sprop, ok := propertiesMap[t] - propertiesMu.RUnlock() - if ok { - return sprop + if p, ok := propertiesCache.Load(t); ok { + return p.(*StructProperties) } - - propertiesMu.Lock() - sprop = getPropertiesLocked(t) - propertiesMu.Unlock() - return sprop + p, _ := propertiesCache.LoadOrStore(t, newProperties(t)) + return p.(*StructProperties) } -type ( - oneofFuncsIface interface { - XXX_OneofFuncs() (func(Message, *Buffer) error, func(Message, int, int, *Buffer) (bool, error), func(Message) int, []interface{}) - } - oneofWrappersIface interface { - XXX_OneofWrappers() []interface{} - } -) - -// getPropertiesLocked requires that propertiesMu is held. -func getPropertiesLocked(t reflect.Type) *StructProperties { - if prop, ok := propertiesMap[t]; ok { - return prop +func newProperties(t reflect.Type) *StructProperties { + if t.Kind() != reflect.Struct { + panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) } + var hasOneof bool prop := new(StructProperties) - // in case of recursive protos, fill this in now. - propertiesMap[t] = prop - - // build properties - prop.Prop = make([]*Properties, t.NumField()) - prop.order = make([]int, t.NumField()) + // Construct a list of properties for each field in the struct. for i := 0; i < t.NumField(); i++ { - f := t.Field(i) p := new(Properties) - name := f.Name - p.init(f.Type, name, f.Tag.Get("protobuf"), &f, false) + f := t.Field(i) + tagField := f.Tag.Get("protobuf") + p.Init(f.Type, f.Name, tagField, &f) - oneof := f.Tag.Get("protobuf_oneof") // special case - if oneof != "" { - // Oneof fields don't use the traditional protobuf tag. - p.OrigName = oneof + tagOneof := f.Tag.Get("protobuf_oneof") + if tagOneof != "" { + hasOneof = true + p.OrigName = tagOneof } - prop.Prop[i] = p - prop.order[i] = i - if debug { - print(i, " ", f.Name, " ", t.String(), " ") - if p.Tag > 0 { - print(p.String()) - } - print("\n") + + // Rename unrelated struct fields with the "XXX_" prefix since so much + // user code simply checks for this to exclude special fields. + if tagField == "" && tagOneof == "" && !strings.HasPrefix(p.Name, "XXX_") { + p.Name = "XXX_" + p.Name + p.OrigName = "XXX_" + p.OrigName + } else if p.Weak != "" { + p.Name = p.OrigName // avoid possible "XXX_" prefix on weak field } + + prop.Prop = append(prop.Prop, p) } - // Re-order prop.order. - sort.Sort(prop) + // Construct a mapping of oneof field names to properties. + if hasOneof { + var oneofWrappers []interface{} + if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofFuncs"); ok { + oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[3].Interface().([]interface{}) + } + if fn, ok := reflect.PtrTo(t).MethodByName("XXX_OneofWrappers"); ok { + oneofWrappers = fn.Func.Call([]reflect.Value{reflect.Zero(fn.Type.In(0))})[0].Interface().([]interface{}) + } + if m, ok := reflect.Zero(reflect.PtrTo(t)).Interface().(protoreflect.ProtoMessage); ok { + if m, ok := m.ProtoReflect().(interface{ ProtoMessageInfo() *protoimpl.MessageInfo }); ok { + oneofWrappers = m.ProtoMessageInfo().OneofWrappers + } + } - var oots []interface{} - switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { - case oneofFuncsIface: - _, _, _, oots = m.XXX_OneofFuncs() - case oneofWrappersIface: - oots = m.XXX_OneofWrappers() - } - if len(oots) > 0 { - // Interpret oneof metadata. prop.OneofTypes = make(map[string]*OneofProperties) - for _, oot := range oots { - oop := &OneofProperties{ - Type: reflect.ValueOf(oot).Type(), // *T + for _, wrapper := range oneofWrappers { + p := &OneofProperties{ + Type: reflect.ValueOf(wrapper).Type(), // *T Prop: new(Properties), } - sft := oop.Type.Elem().Field(0) - oop.Prop.Name = sft.Name - oop.Prop.Parse(sft.Tag.Get("protobuf")) - // There will be exactly one interface field that - // this new value is assignable to. - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if f.Type.Kind() != reflect.Interface { - continue + f := p.Type.Elem().Field(0) + p.Prop.Name = f.Name + p.Prop.Parse(f.Tag.Get("protobuf")) + + // Determine the struct field that contains this oneof. + // Each wrapper is assignable to exactly one parent field. + var foundOneof bool + for i := 0; i < t.NumField() && !foundOneof; i++ { + if p.Type.AssignableTo(t.Field(i).Type) { + p.Field = i + foundOneof = true } - if !oop.Type.AssignableTo(f.Type) { - continue - } - oop.Field = i - break } - prop.OneofTypes[oop.Prop.OrigName] = oop - } - } - - // build required counts - // build tags - reqCount := 0 - prop.decoderOrigNames = make(map[string]int) - for i, p := range prop.Prop { - if strings.HasPrefix(p.Name, "XXX_") { - // Internal fields should not appear in tags/origNames maps. - // They are handled specially when encoding and decoding. - continue - } - if p.Required { - reqCount++ + if !foundOneof { + panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) + } + prop.OneofTypes[p.Prop.OrigName] = p } - prop.decoderTags.put(p.Tag, i) - prop.decoderOrigNames[p.OrigName] = i } - prop.reqCount = reqCount return prop } -// A global registry of enum types. -// The generated code will register the generated maps by calling RegisterEnum. - -var enumValueMaps = make(map[string]map[string]int32) - -// RegisterEnum is called from the generated code to install the enum descriptor -// maps into the global table to aid parsing text format protocol buffers. -func RegisterEnum(typeName string, unusedNameMap map[int32]string, valueMap map[string]int32) { - if _, ok := enumValueMaps[typeName]; ok { - panic("proto: duplicate enum registered: " + typeName) - } - enumValueMaps[typeName] = valueMap -} - -// EnumValueMap returns the mapping from names to integers of the -// enum type enumType, or a nil if not found. -func EnumValueMap(enumType string) map[string]int32 { - return enumValueMaps[enumType] -} - -// A registry of all linked message types. -// The string is a fully-qualified proto name ("pkg.Message"). -var ( - protoTypedNils = make(map[string]Message) // a map from proto names to typed nil pointers - protoMapTypes = make(map[string]reflect.Type) // a map from proto names to map types - revProtoTypes = make(map[reflect.Type]string) -) - -// RegisterType is called from generated code and maps from the fully qualified -// proto name to the type (pointer to struct) of the protocol buffer. -func RegisterType(x Message, name string) { - if _, ok := protoTypedNils[name]; ok { - // TODO: Some day, make this a panic. - log.Printf("proto: duplicate proto type registered: %s", name) - return - } - t := reflect.TypeOf(x) - if v := reflect.ValueOf(x); v.Kind() == reflect.Ptr && v.Pointer() == 0 { - // Generated code always calls RegisterType with nil x. - // This check is just for extra safety. - protoTypedNils[name] = x - } else { - protoTypedNils[name] = reflect.Zero(t).Interface().(Message) - } - revProtoTypes[t] = name -} - -// RegisterMapType is called from generated code and maps from the fully qualified -// proto name to the native map type of the proto map definition. -func RegisterMapType(x interface{}, name string) { - if reflect.TypeOf(x).Kind() != reflect.Map { - panic(fmt.Sprintf("RegisterMapType(%T, %q); want map", x, name)) - } - if _, ok := protoMapTypes[name]; ok { - log.Printf("proto: duplicate proto type registered: %s", name) - return - } - t := reflect.TypeOf(x) - protoMapTypes[name] = t - revProtoTypes[t] = name -} - -// MessageName returns the fully-qualified proto name for the given message type. -func MessageName(x Message) string { - type xname interface { - XXX_MessageName() string - } - if m, ok := x.(xname); ok { - return m.XXX_MessageName() - } - return revProtoTypes[reflect.TypeOf(x)] -} - -// MessageType returns the message type (pointer to struct) for a named message. -// The type is not guaranteed to implement proto.Message if the name refers to a -// map entry. -func MessageType(name string) reflect.Type { - if t, ok := protoTypedNils[name]; ok { - return reflect.TypeOf(t) - } - return protoMapTypes[name] -} - -// A registry of all linked proto files. -var ( - protoFiles = make(map[string][]byte) // file name => fileDescriptor -) - -// RegisterFile is called from generated code and maps from the -// full file name of a .proto file to its compressed FileDescriptorProto. -func RegisterFile(filename string, fileDescriptor []byte) { - protoFiles[filename] = fileDescriptor -} - -// FileDescriptor returns the compressed FileDescriptorProto for a .proto file. -func FileDescriptor(filename string) []byte { return protoFiles[filename] } +func (sp *StructProperties) Len() int { return len(sp.Prop) } +func (sp *StructProperties) Less(i, j int) bool { return false } +func (sp *StructProperties) Swap(i, j int) { return } diff --git a/vendor/github.com/golang/protobuf/proto/proto.go b/vendor/github.com/golang/protobuf/proto/proto.go new file mode 100644 index 000000000..5aee89c32 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/proto.go @@ -0,0 +1,167 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package proto provides functionality for handling protocol buffer messages. +// In particular, it provides marshaling and unmarshaling between a protobuf +// message and the binary wire format. +// +// See https://developers.google.com/protocol-buffers/docs/gotutorial for +// more information. +// +// Deprecated: Use the "google.golang.org/protobuf/proto" package instead. +package proto + +import ( + protoV2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/runtime/protoiface" + "google.golang.org/protobuf/runtime/protoimpl" +) + +const ( + ProtoPackageIsVersion1 = true + ProtoPackageIsVersion2 = true + ProtoPackageIsVersion3 = true + ProtoPackageIsVersion4 = true +) + +// GeneratedEnum is any enum type generated by protoc-gen-go +// which is a named int32 kind. +// This type exists for documentation purposes. +type GeneratedEnum interface{} + +// GeneratedMessage is any message type generated by protoc-gen-go +// which is a pointer to a named struct kind. +// This type exists for documentation purposes. +type GeneratedMessage interface{} + +// Message is a protocol buffer message. +// +// This is the v1 version of the message interface and is marginally better +// than an empty interface as it lacks any method to programatically interact +// with the contents of the message. +// +// A v2 message is declared in "google.golang.org/protobuf/proto".Message and +// exposes protobuf reflection as a first-class feature of the interface. +// +// To convert a v1 message to a v2 message, use the MessageV2 function. +// To convert a v2 message to a v1 message, use the MessageV1 function. +type Message = protoiface.MessageV1 + +// MessageV1 converts either a v1 or v2 message to a v1 message. +// It returns nil if m is nil. +func MessageV1(m GeneratedMessage) protoiface.MessageV1 { + return protoimpl.X.ProtoMessageV1Of(m) +} + +// MessageV2 converts either a v1 or v2 message to a v2 message. +// It returns nil if m is nil. +func MessageV2(m GeneratedMessage) protoV2.Message { + return protoimpl.X.ProtoMessageV2Of(m) +} + +// MessageReflect returns a reflective view for a message. +// It returns nil if m is nil. +func MessageReflect(m Message) protoreflect.Message { + return protoimpl.X.MessageOf(m) +} + +// Marshaler is implemented by messages that can marshal themselves. +// This interface is used by the following functions: Size, Marshal, +// Buffer.Marshal, and Buffer.EncodeMessage. +// +// Deprecated: Do not implement. +type Marshaler interface { + // Marshal formats the encoded bytes of the message. + // It should be deterministic and emit valid protobuf wire data. + // The caller takes ownership of the returned buffer. + Marshal() ([]byte, error) +} + +// Unmarshaler is implemented by messages that can unmarshal themselves. +// This interface is used by the following functions: Unmarshal, UnmarshalMerge, +// Buffer.Unmarshal, Buffer.DecodeMessage, and Buffer.DecodeGroup. +// +// Deprecated: Do not implement. +type Unmarshaler interface { + // Unmarshal parses the encoded bytes of the protobuf wire input. + // The provided buffer is only valid for during method call. + // It should not reset the receiver message. + Unmarshal([]byte) error +} + +// Merger is implemented by messages that can merge themselves. +// This interface is used by the following functions: Clone and Merge. +// +// Deprecated: Do not implement. +type Merger interface { + // Merge merges the contents of src into the receiver message. + // It clones all data structures in src such that it aliases no mutable + // memory referenced by src. + Merge(src Message) +} + +// RequiredNotSetError is an error type returned when +// marshaling or unmarshaling a message with missing required fields. +type RequiredNotSetError struct { + err error +} + +func (e *RequiredNotSetError) Error() string { + if e.err != nil { + return e.err.Error() + } + return "proto: required field not set" +} +func (e *RequiredNotSetError) RequiredNotSet() bool { + return true +} + +func checkRequiredNotSet(m protoV2.Message) error { + if err := protoV2.CheckInitialized(m); err != nil { + return &RequiredNotSetError{err: err} + } + return nil +} + +// Clone returns a deep copy of src. +func Clone(src Message) Message { + return MessageV1(protoV2.Clone(MessageV2(src))) +} + +// Merge merges src into dst, which must be messages of the same type. +// +// Populated scalar fields in src are copied to dst, while populated +// singular messages in src are merged into dst by recursively calling Merge. +// The elements of every list field in src is appended to the corresponded +// list fields in dst. The entries of every map field in src is copied into +// the corresponding map field in dst, possibly replacing existing entries. +// The unknown fields of src are appended to the unknown fields of dst. +func Merge(dst, src Message) { + protoV2.Merge(MessageV2(dst), MessageV2(src)) +} + +// Equal reports whether two messages are equal. +// If two messages marshal to the same bytes under deterministic serialization, +// then Equal is guaranteed to report true. +// +// Two messages are equal if they are the same protobuf message type, +// have the same set of populated known and extension field values, +// and the same set of unknown fields values. +// +// Scalar values are compared with the equivalent of the == operator in Go, +// except bytes values which are compared using bytes.Equal and +// floating point values which specially treat NaNs as equal. +// Message values are compared by recursively calling Equal. +// Lists are equal if each element value is also equal. +// Maps are equal if they have the same set of keys, where the pair of values +// for each key is also equal. +func Equal(x, y Message) bool { + return protoV2.Equal(MessageV2(x), MessageV2(y)) +} + +func isMessageSet(md protoreflect.MessageDescriptor) bool { + ms, ok := md.(interface{ IsMessageSet() bool }) + return ok && ms.IsMessageSet() +} diff --git a/vendor/github.com/golang/protobuf/proto/registry.go b/vendor/github.com/golang/protobuf/proto/registry.go new file mode 100644 index 000000000..066b4323b --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/registry.go @@ -0,0 +1,317 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "bytes" + "compress/gzip" + "fmt" + "io/ioutil" + "reflect" + "strings" + "sync" + + "google.golang.org/protobuf/reflect/protodesc" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + "google.golang.org/protobuf/runtime/protoimpl" +) + +// filePath is the path to the proto source file. +type filePath = string // e.g., "google/protobuf/descriptor.proto" + +// fileDescGZIP is the compressed contents of the encoded FileDescriptorProto. +type fileDescGZIP = []byte + +var fileCache sync.Map // map[filePath]fileDescGZIP + +// RegisterFile is called from generated code to register the compressed +// FileDescriptorProto with the file path for a proto source file. +// +// Deprecated: Use protoregistry.GlobalFiles.RegisterFile instead. +func RegisterFile(s filePath, d fileDescGZIP) { + // Decompress the descriptor. + zr, err := gzip.NewReader(bytes.NewReader(d)) + if err != nil { + panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err)) + } + b, err := ioutil.ReadAll(zr) + if err != nil { + panic(fmt.Sprintf("proto: invalid compressed file descriptor: %v", err)) + } + + // Construct a protoreflect.FileDescriptor from the raw descriptor. + // Note that DescBuilder.Build automatically registers the constructed + // file descriptor with the v2 registry. + protoimpl.DescBuilder{RawDescriptor: b}.Build() + + // Locally cache the raw descriptor form for the file. + fileCache.Store(s, d) +} + +// FileDescriptor returns the compressed FileDescriptorProto given the file path +// for a proto source file. It returns nil if not found. +// +// Deprecated: Use protoregistry.GlobalFiles.FindFileByPath instead. +func FileDescriptor(s filePath) fileDescGZIP { + if v, ok := fileCache.Load(s); ok { + return v.(fileDescGZIP) + } + + // Find the descriptor in the v2 registry. + var b []byte + if fd, _ := protoregistry.GlobalFiles.FindFileByPath(s); fd != nil { + b, _ = Marshal(protodesc.ToFileDescriptorProto(fd)) + } + + // Locally cache the raw descriptor form for the file. + if len(b) > 0 { + v, _ := fileCache.LoadOrStore(s, protoimpl.X.CompressGZIP(b)) + return v.(fileDescGZIP) + } + return nil +} + +// enumName is the name of an enum. For historical reasons, the enum name is +// neither the full Go name nor the full protobuf name of the enum. +// The name is the dot-separated combination of just the proto package that the +// enum is declared within followed by the Go type name of the generated enum. +type enumName = string // e.g., "my.proto.package.GoMessage_GoEnum" + +// enumsByName maps enum values by name to their numeric counterpart. +type enumsByName = map[string]int32 + +// enumsByNumber maps enum values by number to their name counterpart. +type enumsByNumber = map[int32]string + +var enumCache sync.Map // map[enumName]enumsByName +var numFilesCache sync.Map // map[protoreflect.FullName]int + +// RegisterEnum is called from the generated code to register the mapping of +// enum value names to enum numbers for the enum identified by s. +// +// Deprecated: Use protoregistry.GlobalTypes.RegisterEnum instead. +func RegisterEnum(s enumName, _ enumsByNumber, m enumsByName) { + if _, ok := enumCache.Load(s); ok { + panic("proto: duplicate enum registered: " + s) + } + enumCache.Store(s, m) + + // This does not forward registration to the v2 registry since this API + // lacks sufficient information to construct a complete v2 enum descriptor. +} + +// EnumValueMap returns the mapping from enum value names to enum numbers for +// the enum of the given name. It returns nil if not found. +// +// Deprecated: Use protoregistry.GlobalTypes.FindEnumByName instead. +func EnumValueMap(s enumName) enumsByName { + if v, ok := enumCache.Load(s); ok { + return v.(enumsByName) + } + + // Check whether the cache is stale. If the number of files in the current + // package differs, then it means that some enums may have been recently + // registered upstream that we do not know about. + var protoPkg protoreflect.FullName + if i := strings.LastIndexByte(s, '.'); i >= 0 { + protoPkg = protoreflect.FullName(s[:i]) + } + v, _ := numFilesCache.Load(protoPkg) + numFiles, _ := v.(int) + if protoregistry.GlobalFiles.NumFilesByPackage(protoPkg) == numFiles { + return nil // cache is up-to-date; was not found earlier + } + + // Update the enum cache for all enums declared in the given proto package. + numFiles = 0 + protoregistry.GlobalFiles.RangeFilesByPackage(protoPkg, func(fd protoreflect.FileDescriptor) bool { + walkEnums(fd, func(ed protoreflect.EnumDescriptor) { + name := protoimpl.X.LegacyEnumName(ed) + if _, ok := enumCache.Load(name); !ok { + m := make(enumsByName) + evs := ed.Values() + for i := evs.Len() - 1; i >= 0; i-- { + ev := evs.Get(i) + m[string(ev.Name())] = int32(ev.Number()) + } + enumCache.LoadOrStore(name, m) + } + }) + numFiles++ + return true + }) + numFilesCache.Store(protoPkg, numFiles) + + // Check cache again for enum map. + if v, ok := enumCache.Load(s); ok { + return v.(enumsByName) + } + return nil +} + +// walkEnums recursively walks all enums declared in d. +func walkEnums(d interface { + Enums() protoreflect.EnumDescriptors + Messages() protoreflect.MessageDescriptors +}, f func(protoreflect.EnumDescriptor)) { + eds := d.Enums() + for i := eds.Len() - 1; i >= 0; i-- { + f(eds.Get(i)) + } + mds := d.Messages() + for i := mds.Len() - 1; i >= 0; i-- { + walkEnums(mds.Get(i), f) + } +} + +// messageName is the full name of protobuf message. +type messageName = string + +var messageTypeCache sync.Map // map[messageName]reflect.Type + +// RegisterType is called from generated code to register the message Go type +// for a message of the given name. +// +// Deprecated: Use protoregistry.GlobalTypes.RegisterMessage instead. +func RegisterType(m Message, s messageName) { + mt := protoimpl.X.LegacyMessageTypeOf(m, protoreflect.FullName(s)) + if err := protoregistry.GlobalTypes.RegisterMessage(mt); err != nil { + panic(err) + } + messageTypeCache.Store(s, reflect.TypeOf(m)) +} + +// RegisterMapType is called from generated code to register the Go map type +// for a protobuf message representing a map entry. +// +// Deprecated: Do not use. +func RegisterMapType(m interface{}, s messageName) { + t := reflect.TypeOf(m) + if t.Kind() != reflect.Map { + panic(fmt.Sprintf("invalid map kind: %v", t)) + } + if _, ok := messageTypeCache.Load(s); ok { + panic(fmt.Errorf("proto: duplicate proto message registered: %s", s)) + } + messageTypeCache.Store(s, t) +} + +// MessageType returns the message type for a named message. +// It returns nil if not found. +// +// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead. +func MessageType(s messageName) reflect.Type { + if v, ok := messageTypeCache.Load(s); ok { + return v.(reflect.Type) + } + + // Derive the message type from the v2 registry. + var t reflect.Type + if mt, _ := protoregistry.GlobalTypes.FindMessageByName(protoreflect.FullName(s)); mt != nil { + t = messageGoType(mt) + } + + // If we could not get a concrete type, it is possible that it is a + // pseudo-message for a map entry. + if t == nil { + d, _ := protoregistry.GlobalFiles.FindDescriptorByName(protoreflect.FullName(s)) + if md, _ := d.(protoreflect.MessageDescriptor); md != nil && md.IsMapEntry() { + kt := goTypeForField(md.Fields().ByNumber(1)) + vt := goTypeForField(md.Fields().ByNumber(2)) + t = reflect.MapOf(kt, vt) + } + } + + // Locally cache the message type for the given name. + if t != nil { + v, _ := messageTypeCache.LoadOrStore(s, t) + return v.(reflect.Type) + } + return nil +} + +func goTypeForField(fd protoreflect.FieldDescriptor) reflect.Type { + switch k := fd.Kind(); k { + case protoreflect.EnumKind: + if et, _ := protoregistry.GlobalTypes.FindEnumByName(fd.Enum().FullName()); et != nil { + return enumGoType(et) + } + return reflect.TypeOf(protoreflect.EnumNumber(0)) + case protoreflect.MessageKind, protoreflect.GroupKind: + if mt, _ := protoregistry.GlobalTypes.FindMessageByName(fd.Message().FullName()); mt != nil { + return messageGoType(mt) + } + return reflect.TypeOf((*protoreflect.Message)(nil)).Elem() + default: + return reflect.TypeOf(fd.Default().Interface()) + } +} + +func enumGoType(et protoreflect.EnumType) reflect.Type { + return reflect.TypeOf(et.New(0)) +} + +func messageGoType(mt protoreflect.MessageType) reflect.Type { + return reflect.TypeOf(MessageV1(mt.Zero().Interface())) +} + +// MessageName returns the full protobuf name for the given message type. +// +// Deprecated: Use protoreflect.MessageDescriptor.FullName instead. +func MessageName(m Message) messageName { + if m == nil { + return "" + } + if m, ok := m.(interface{ XXX_MessageName() messageName }); ok { + return m.XXX_MessageName() + } + return messageName(protoimpl.X.MessageDescriptorOf(m).FullName()) +} + +// RegisterExtension is called from the generated code to register +// the extension descriptor. +// +// Deprecated: Use protoregistry.GlobalTypes.RegisterExtension instead. +func RegisterExtension(d *ExtensionDesc) { + if err := protoregistry.GlobalTypes.RegisterExtension(d); err != nil { + panic(err) + } +} + +type extensionsByNumber = map[int32]*ExtensionDesc + +var extensionCache sync.Map // map[messageName]extensionsByNumber + +// RegisteredExtensions returns a map of the registered extensions for the +// provided protobuf message, indexed by the extension field number. +// +// Deprecated: Use protoregistry.GlobalTypes.RangeExtensionsByMessage instead. +func RegisteredExtensions(m Message) extensionsByNumber { + // Check whether the cache is stale. If the number of extensions for + // the given message differs, then it means that some extensions were + // recently registered upstream that we do not know about. + s := MessageName(m) + v, _ := extensionCache.Load(s) + xs, _ := v.(extensionsByNumber) + if protoregistry.GlobalTypes.NumExtensionsByMessage(protoreflect.FullName(s)) == len(xs) { + return xs // cache is up-to-date + } + + // Cache is stale, re-compute the extensions map. + xs = make(extensionsByNumber) + protoregistry.GlobalTypes.RangeExtensionsByMessage(protoreflect.FullName(s), func(xt protoreflect.ExtensionType) bool { + if xd, ok := xt.(*ExtensionDesc); ok { + xs[int32(xt.TypeDescriptor().Number())] = xd + } else { + // TODO: This implies that the protoreflect.ExtensionType is a + // custom type not generated by protoc-gen-go. We could try and + // convert the type to an ExtensionDesc. + } + return true + }) + extensionCache.Store(s, xs) + return xs +} diff --git a/vendor/github.com/golang/protobuf/proto/table_marshal.go b/vendor/github.com/golang/protobuf/proto/table_marshal.go deleted file mode 100644 index 5cb11fa95..000000000 --- a/vendor/github.com/golang/protobuf/proto/table_marshal.go +++ /dev/null @@ -1,2776 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "errors" - "fmt" - "math" - "reflect" - "sort" - "strconv" - "strings" - "sync" - "sync/atomic" - "unicode/utf8" -) - -// a sizer takes a pointer to a field and the size of its tag, computes the size of -// the encoded data. -type sizer func(pointer, int) int - -// a marshaler takes a byte slice, a pointer to a field, and its tag (in wire format), -// marshals the field to the end of the slice, returns the slice and error (if any). -type marshaler func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) - -// marshalInfo is the information used for marshaling a message. -type marshalInfo struct { - typ reflect.Type - fields []*marshalFieldInfo - unrecognized field // offset of XXX_unrecognized - extensions field // offset of XXX_InternalExtensions - v1extensions field // offset of XXX_extensions - sizecache field // offset of XXX_sizecache - initialized int32 // 0 -- only typ is set, 1 -- fully initialized - messageset bool // uses message set wire format - hasmarshaler bool // has custom marshaler - sync.RWMutex // protect extElems map, also for initialization - extElems map[int32]*marshalElemInfo // info of extension elements -} - -// marshalFieldInfo is the information used for marshaling a field of a message. -type marshalFieldInfo struct { - field field - wiretag uint64 // tag in wire format - tagsize int // size of tag in wire format - sizer sizer - marshaler marshaler - isPointer bool - required bool // field is required - name string // name of the field, for error reporting - oneofElems map[reflect.Type]*marshalElemInfo // info of oneof elements -} - -// marshalElemInfo is the information used for marshaling an extension or oneof element. -type marshalElemInfo struct { - wiretag uint64 // tag in wire format - tagsize int // size of tag in wire format - sizer sizer - marshaler marshaler - isptr bool // elem is pointer typed, thus interface of this type is a direct interface (extension only) - deref bool // dereference the pointer before operating on it; implies isptr -} - -var ( - marshalInfoMap = map[reflect.Type]*marshalInfo{} - marshalInfoLock sync.Mutex -) - -// getMarshalInfo returns the information to marshal a given type of message. -// The info it returns may not necessarily initialized. -// t is the type of the message (NOT the pointer to it). -func getMarshalInfo(t reflect.Type) *marshalInfo { - marshalInfoLock.Lock() - u, ok := marshalInfoMap[t] - if !ok { - u = &marshalInfo{typ: t} - marshalInfoMap[t] = u - } - marshalInfoLock.Unlock() - return u -} - -// Size is the entry point from generated code, -// and should be ONLY called by generated code. -// It computes the size of encoded data of msg. -// a is a pointer to a place to store cached marshal info. -func (a *InternalMessageInfo) Size(msg Message) int { - u := getMessageMarshalInfo(msg, a) - ptr := toPointer(&msg) - if ptr.isNil() { - // We get here if msg is a typed nil ((*SomeMessage)(nil)), - // so it satisfies the interface, and msg == nil wouldn't - // catch it. We don't want crash in this case. - return 0 - } - return u.size(ptr) -} - -// Marshal is the entry point from generated code, -// and should be ONLY called by generated code. -// It marshals msg to the end of b. -// a is a pointer to a place to store cached marshal info. -func (a *InternalMessageInfo) Marshal(b []byte, msg Message, deterministic bool) ([]byte, error) { - u := getMessageMarshalInfo(msg, a) - ptr := toPointer(&msg) - if ptr.isNil() { - // We get here if msg is a typed nil ((*SomeMessage)(nil)), - // so it satisfies the interface, and msg == nil wouldn't - // catch it. We don't want crash in this case. - return b, ErrNil - } - return u.marshal(b, ptr, deterministic) -} - -func getMessageMarshalInfo(msg interface{}, a *InternalMessageInfo) *marshalInfo { - // u := a.marshal, but atomically. - // We use an atomic here to ensure memory consistency. - u := atomicLoadMarshalInfo(&a.marshal) - if u == nil { - // Get marshal information from type of message. - t := reflect.ValueOf(msg).Type() - if t.Kind() != reflect.Ptr { - panic(fmt.Sprintf("cannot handle non-pointer message type %v", t)) - } - u = getMarshalInfo(t.Elem()) - // Store it in the cache for later users. - // a.marshal = u, but atomically. - atomicStoreMarshalInfo(&a.marshal, u) - } - return u -} - -// size is the main function to compute the size of the encoded data of a message. -// ptr is the pointer to the message. -func (u *marshalInfo) size(ptr pointer) int { - if atomic.LoadInt32(&u.initialized) == 0 { - u.computeMarshalInfo() - } - - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if u.hasmarshaler { - m := ptr.asPointerTo(u.typ).Interface().(Marshaler) - b, _ := m.Marshal() - return len(b) - } - - n := 0 - for _, f := range u.fields { - if f.isPointer && ptr.offset(f.field).getPointer().isNil() { - // nil pointer always marshals to nothing - continue - } - n += f.sizer(ptr.offset(f.field), f.tagsize) - } - if u.extensions.IsValid() { - e := ptr.offset(u.extensions).toExtensions() - if u.messageset { - n += u.sizeMessageSet(e) - } else { - n += u.sizeExtensions(e) - } - } - if u.v1extensions.IsValid() { - m := *ptr.offset(u.v1extensions).toOldExtensions() - n += u.sizeV1Extensions(m) - } - if u.unrecognized.IsValid() { - s := *ptr.offset(u.unrecognized).toBytes() - n += len(s) - } - // cache the result for use in marshal - if u.sizecache.IsValid() { - atomic.StoreInt32(ptr.offset(u.sizecache).toInt32(), int32(n)) - } - return n -} - -// cachedsize gets the size from cache. If there is no cache (i.e. message is not generated), -// fall back to compute the size. -func (u *marshalInfo) cachedsize(ptr pointer) int { - if u.sizecache.IsValid() { - return int(atomic.LoadInt32(ptr.offset(u.sizecache).toInt32())) - } - return u.size(ptr) -} - -// marshal is the main function to marshal a message. It takes a byte slice and appends -// the encoded data to the end of the slice, returns the slice and error (if any). -// ptr is the pointer to the message. -// If deterministic is true, map is marshaled in deterministic order. -func (u *marshalInfo) marshal(b []byte, ptr pointer, deterministic bool) ([]byte, error) { - if atomic.LoadInt32(&u.initialized) == 0 { - u.computeMarshalInfo() - } - - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if u.hasmarshaler { - m := ptr.asPointerTo(u.typ).Interface().(Marshaler) - b1, err := m.Marshal() - b = append(b, b1...) - return b, err - } - - var err, errLater error - // The old marshaler encodes extensions at beginning. - if u.extensions.IsValid() { - e := ptr.offset(u.extensions).toExtensions() - if u.messageset { - b, err = u.appendMessageSet(b, e, deterministic) - } else { - b, err = u.appendExtensions(b, e, deterministic) - } - if err != nil { - return b, err - } - } - if u.v1extensions.IsValid() { - m := *ptr.offset(u.v1extensions).toOldExtensions() - b, err = u.appendV1Extensions(b, m, deterministic) - if err != nil { - return b, err - } - } - for _, f := range u.fields { - if f.required { - if ptr.offset(f.field).getPointer().isNil() { - // Required field is not set. - // We record the error but keep going, to give a complete marshaling. - if errLater == nil { - errLater = &RequiredNotSetError{f.name} - } - continue - } - } - if f.isPointer && ptr.offset(f.field).getPointer().isNil() { - // nil pointer always marshals to nothing - continue - } - b, err = f.marshaler(b, ptr.offset(f.field), f.wiretag, deterministic) - if err != nil { - if err1, ok := err.(*RequiredNotSetError); ok { - // Required field in submessage is not set. - // We record the error but keep going, to give a complete marshaling. - if errLater == nil { - errLater = &RequiredNotSetError{f.name + "." + err1.field} - } - continue - } - if err == errRepeatedHasNil { - err = errors.New("proto: repeated field " + f.name + " has nil element") - } - if err == errInvalidUTF8 { - if errLater == nil { - fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name - errLater = &invalidUTF8Error{fullName} - } - continue - } - return b, err - } - } - if u.unrecognized.IsValid() { - s := *ptr.offset(u.unrecognized).toBytes() - b = append(b, s...) - } - return b, errLater -} - -// computeMarshalInfo initializes the marshal info. -func (u *marshalInfo) computeMarshalInfo() { - u.Lock() - defer u.Unlock() - if u.initialized != 0 { // non-atomic read is ok as it is protected by the lock - return - } - - t := u.typ - u.unrecognized = invalidField - u.extensions = invalidField - u.v1extensions = invalidField - u.sizecache = invalidField - - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - if reflect.PtrTo(t).Implements(marshalerType) { - u.hasmarshaler = true - atomic.StoreInt32(&u.initialized, 1) - return - } - - // get oneof implementers - var oneofImplementers []interface{} - switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { - case oneofFuncsIface: - _, _, _, oneofImplementers = m.XXX_OneofFuncs() - case oneofWrappersIface: - oneofImplementers = m.XXX_OneofWrappers() - } - - n := t.NumField() - - // deal with XXX fields first - for i := 0; i < t.NumField(); i++ { - f := t.Field(i) - if !strings.HasPrefix(f.Name, "XXX_") { - continue - } - switch f.Name { - case "XXX_sizecache": - u.sizecache = toField(&f) - case "XXX_unrecognized": - u.unrecognized = toField(&f) - case "XXX_InternalExtensions": - u.extensions = toField(&f) - u.messageset = f.Tag.Get("protobuf_messageset") == "1" - case "XXX_extensions": - u.v1extensions = toField(&f) - case "XXX_NoUnkeyedLiteral": - // nothing to do - default: - panic("unknown XXX field: " + f.Name) - } - n-- - } - - // normal fields - fields := make([]marshalFieldInfo, n) // batch allocation - u.fields = make([]*marshalFieldInfo, 0, n) - for i, j := 0, 0; i < t.NumField(); i++ { - f := t.Field(i) - - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - field := &fields[j] - j++ - field.name = f.Name - u.fields = append(u.fields, field) - if f.Tag.Get("protobuf_oneof") != "" { - field.computeOneofFieldInfo(&f, oneofImplementers) - continue - } - if f.Tag.Get("protobuf") == "" { - // field has no tag (not in generated message), ignore it - u.fields = u.fields[:len(u.fields)-1] - j-- - continue - } - field.computeMarshalFieldInfo(&f) - } - - // fields are marshaled in tag order on the wire. - sort.Sort(byTag(u.fields)) - - atomic.StoreInt32(&u.initialized, 1) -} - -// helper for sorting fields by tag -type byTag []*marshalFieldInfo - -func (a byTag) Len() int { return len(a) } -func (a byTag) Swap(i, j int) { a[i], a[j] = a[j], a[i] } -func (a byTag) Less(i, j int) bool { return a[i].wiretag < a[j].wiretag } - -// getExtElemInfo returns the information to marshal an extension element. -// The info it returns is initialized. -func (u *marshalInfo) getExtElemInfo(desc *ExtensionDesc) *marshalElemInfo { - // get from cache first - u.RLock() - e, ok := u.extElems[desc.Field] - u.RUnlock() - if ok { - return e - } - - t := reflect.TypeOf(desc.ExtensionType) // pointer or slice to basic type or struct - tags := strings.Split(desc.Tag, ",") - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - if t.Kind() == reflect.Ptr && t.Elem().Kind() != reflect.Struct { - t = t.Elem() - } - sizer, marshaler := typeMarshaler(t, tags, false, false) - var deref bool - if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { - t = reflect.PtrTo(t) - deref = true - } - e = &marshalElemInfo{ - wiretag: uint64(tag)<<3 | wt, - tagsize: SizeVarint(uint64(tag) << 3), - sizer: sizer, - marshaler: marshaler, - isptr: t.Kind() == reflect.Ptr, - deref: deref, - } - - // update cache - u.Lock() - if u.extElems == nil { - u.extElems = make(map[int32]*marshalElemInfo) - } - u.extElems[desc.Field] = e - u.Unlock() - return e -} - -// computeMarshalFieldInfo fills up the information to marshal a field. -func (fi *marshalFieldInfo) computeMarshalFieldInfo(f *reflect.StructField) { - // parse protobuf tag of the field. - // tag has format of "bytes,49,opt,name=foo,def=hello!" - tags := strings.Split(f.Tag.Get("protobuf"), ",") - if tags[0] == "" { - return - } - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - if tags[2] == "req" { - fi.required = true - } - fi.setTag(f, tag, wt) - fi.setMarshaler(f, tags) -} - -func (fi *marshalFieldInfo) computeOneofFieldInfo(f *reflect.StructField, oneofImplementers []interface{}) { - fi.field = toField(f) - fi.wiretag = math.MaxInt32 // Use a large tag number, make oneofs sorted at the end. This tag will not appear on the wire. - fi.isPointer = true - fi.sizer, fi.marshaler = makeOneOfMarshaler(fi, f) - fi.oneofElems = make(map[reflect.Type]*marshalElemInfo) - - ityp := f.Type // interface type - for _, o := range oneofImplementers { - t := reflect.TypeOf(o) - if !t.Implements(ityp) { - continue - } - sf := t.Elem().Field(0) // oneof implementer is a struct with a single field - tags := strings.Split(sf.Tag.Get("protobuf"), ",") - tag, err := strconv.Atoi(tags[1]) - if err != nil { - panic("tag is not an integer") - } - wt := wiretype(tags[0]) - sizer, marshaler := typeMarshaler(sf.Type, tags, false, true) // oneof should not omit any zero value - fi.oneofElems[t.Elem()] = &marshalElemInfo{ - wiretag: uint64(tag)<<3 | wt, - tagsize: SizeVarint(uint64(tag) << 3), - sizer: sizer, - marshaler: marshaler, - } - } -} - -// wiretype returns the wire encoding of the type. -func wiretype(encoding string) uint64 { - switch encoding { - case "fixed32": - return WireFixed32 - case "fixed64": - return WireFixed64 - case "varint", "zigzag32", "zigzag64": - return WireVarint - case "bytes": - return WireBytes - case "group": - return WireStartGroup - } - panic("unknown wire type " + encoding) -} - -// setTag fills up the tag (in wire format) and its size in the info of a field. -func (fi *marshalFieldInfo) setTag(f *reflect.StructField, tag int, wt uint64) { - fi.field = toField(f) - fi.wiretag = uint64(tag)<<3 | wt - fi.tagsize = SizeVarint(uint64(tag) << 3) -} - -// setMarshaler fills up the sizer and marshaler in the info of a field. -func (fi *marshalFieldInfo) setMarshaler(f *reflect.StructField, tags []string) { - switch f.Type.Kind() { - case reflect.Map: - // map field - fi.isPointer = true - fi.sizer, fi.marshaler = makeMapMarshaler(f) - return - case reflect.Ptr, reflect.Slice: - fi.isPointer = true - } - fi.sizer, fi.marshaler = typeMarshaler(f.Type, tags, true, false) -} - -// typeMarshaler returns the sizer and marshaler of a given field. -// t is the type of the field. -// tags is the generated "protobuf" tag of the field. -// If nozero is true, zero value is not marshaled to the wire. -// If oneof is true, it is a oneof field. -func typeMarshaler(t reflect.Type, tags []string, nozero, oneof bool) (sizer, marshaler) { - encoding := tags[0] - - pointer := false - slice := false - if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { - slice = true - t = t.Elem() - } - if t.Kind() == reflect.Ptr { - pointer = true - t = t.Elem() - } - - packed := false - proto3 := false - validateUTF8 := true - for i := 2; i < len(tags); i++ { - if tags[i] == "packed" { - packed = true - } - if tags[i] == "proto3" { - proto3 = true - } - } - validateUTF8 = validateUTF8 && proto3 - - switch t.Kind() { - case reflect.Bool: - if pointer { - return sizeBoolPtr, appendBoolPtr - } - if slice { - if packed { - return sizeBoolPackedSlice, appendBoolPackedSlice - } - return sizeBoolSlice, appendBoolSlice - } - if nozero { - return sizeBoolValueNoZero, appendBoolValueNoZero - } - return sizeBoolValue, appendBoolValue - case reflect.Uint32: - switch encoding { - case "fixed32": - if pointer { - return sizeFixed32Ptr, appendFixed32Ptr - } - if slice { - if packed { - return sizeFixed32PackedSlice, appendFixed32PackedSlice - } - return sizeFixed32Slice, appendFixed32Slice - } - if nozero { - return sizeFixed32ValueNoZero, appendFixed32ValueNoZero - } - return sizeFixed32Value, appendFixed32Value - case "varint": - if pointer { - return sizeVarint32Ptr, appendVarint32Ptr - } - if slice { - if packed { - return sizeVarint32PackedSlice, appendVarint32PackedSlice - } - return sizeVarint32Slice, appendVarint32Slice - } - if nozero { - return sizeVarint32ValueNoZero, appendVarint32ValueNoZero - } - return sizeVarint32Value, appendVarint32Value - } - case reflect.Int32: - switch encoding { - case "fixed32": - if pointer { - return sizeFixedS32Ptr, appendFixedS32Ptr - } - if slice { - if packed { - return sizeFixedS32PackedSlice, appendFixedS32PackedSlice - } - return sizeFixedS32Slice, appendFixedS32Slice - } - if nozero { - return sizeFixedS32ValueNoZero, appendFixedS32ValueNoZero - } - return sizeFixedS32Value, appendFixedS32Value - case "varint": - if pointer { - return sizeVarintS32Ptr, appendVarintS32Ptr - } - if slice { - if packed { - return sizeVarintS32PackedSlice, appendVarintS32PackedSlice - } - return sizeVarintS32Slice, appendVarintS32Slice - } - if nozero { - return sizeVarintS32ValueNoZero, appendVarintS32ValueNoZero - } - return sizeVarintS32Value, appendVarintS32Value - case "zigzag32": - if pointer { - return sizeZigzag32Ptr, appendZigzag32Ptr - } - if slice { - if packed { - return sizeZigzag32PackedSlice, appendZigzag32PackedSlice - } - return sizeZigzag32Slice, appendZigzag32Slice - } - if nozero { - return sizeZigzag32ValueNoZero, appendZigzag32ValueNoZero - } - return sizeZigzag32Value, appendZigzag32Value - } - case reflect.Uint64: - switch encoding { - case "fixed64": - if pointer { - return sizeFixed64Ptr, appendFixed64Ptr - } - if slice { - if packed { - return sizeFixed64PackedSlice, appendFixed64PackedSlice - } - return sizeFixed64Slice, appendFixed64Slice - } - if nozero { - return sizeFixed64ValueNoZero, appendFixed64ValueNoZero - } - return sizeFixed64Value, appendFixed64Value - case "varint": - if pointer { - return sizeVarint64Ptr, appendVarint64Ptr - } - if slice { - if packed { - return sizeVarint64PackedSlice, appendVarint64PackedSlice - } - return sizeVarint64Slice, appendVarint64Slice - } - if nozero { - return sizeVarint64ValueNoZero, appendVarint64ValueNoZero - } - return sizeVarint64Value, appendVarint64Value - } - case reflect.Int64: - switch encoding { - case "fixed64": - if pointer { - return sizeFixedS64Ptr, appendFixedS64Ptr - } - if slice { - if packed { - return sizeFixedS64PackedSlice, appendFixedS64PackedSlice - } - return sizeFixedS64Slice, appendFixedS64Slice - } - if nozero { - return sizeFixedS64ValueNoZero, appendFixedS64ValueNoZero - } - return sizeFixedS64Value, appendFixedS64Value - case "varint": - if pointer { - return sizeVarintS64Ptr, appendVarintS64Ptr - } - if slice { - if packed { - return sizeVarintS64PackedSlice, appendVarintS64PackedSlice - } - return sizeVarintS64Slice, appendVarintS64Slice - } - if nozero { - return sizeVarintS64ValueNoZero, appendVarintS64ValueNoZero - } - return sizeVarintS64Value, appendVarintS64Value - case "zigzag64": - if pointer { - return sizeZigzag64Ptr, appendZigzag64Ptr - } - if slice { - if packed { - return sizeZigzag64PackedSlice, appendZigzag64PackedSlice - } - return sizeZigzag64Slice, appendZigzag64Slice - } - if nozero { - return sizeZigzag64ValueNoZero, appendZigzag64ValueNoZero - } - return sizeZigzag64Value, appendZigzag64Value - } - case reflect.Float32: - if pointer { - return sizeFloat32Ptr, appendFloat32Ptr - } - if slice { - if packed { - return sizeFloat32PackedSlice, appendFloat32PackedSlice - } - return sizeFloat32Slice, appendFloat32Slice - } - if nozero { - return sizeFloat32ValueNoZero, appendFloat32ValueNoZero - } - return sizeFloat32Value, appendFloat32Value - case reflect.Float64: - if pointer { - return sizeFloat64Ptr, appendFloat64Ptr - } - if slice { - if packed { - return sizeFloat64PackedSlice, appendFloat64PackedSlice - } - return sizeFloat64Slice, appendFloat64Slice - } - if nozero { - return sizeFloat64ValueNoZero, appendFloat64ValueNoZero - } - return sizeFloat64Value, appendFloat64Value - case reflect.String: - if validateUTF8 { - if pointer { - return sizeStringPtr, appendUTF8StringPtr - } - if slice { - return sizeStringSlice, appendUTF8StringSlice - } - if nozero { - return sizeStringValueNoZero, appendUTF8StringValueNoZero - } - return sizeStringValue, appendUTF8StringValue - } - if pointer { - return sizeStringPtr, appendStringPtr - } - if slice { - return sizeStringSlice, appendStringSlice - } - if nozero { - return sizeStringValueNoZero, appendStringValueNoZero - } - return sizeStringValue, appendStringValue - case reflect.Slice: - if slice { - return sizeBytesSlice, appendBytesSlice - } - if oneof { - // Oneof bytes field may also have "proto3" tag. - // We want to marshal it as a oneof field. Do this - // check before the proto3 check. - return sizeBytesOneof, appendBytesOneof - } - if proto3 { - return sizeBytes3, appendBytes3 - } - return sizeBytes, appendBytes - case reflect.Struct: - switch encoding { - case "group": - if slice { - return makeGroupSliceMarshaler(getMarshalInfo(t)) - } - return makeGroupMarshaler(getMarshalInfo(t)) - case "bytes": - if slice { - return makeMessageSliceMarshaler(getMarshalInfo(t)) - } - return makeMessageMarshaler(getMarshalInfo(t)) - } - } - panic(fmt.Sprintf("unknown or mismatched type: type: %v, wire type: %v", t, encoding)) -} - -// Below are functions to size/marshal a specific type of a field. -// They are stored in the field's info, and called by function pointers. -// They have type sizer or marshaler. - -func sizeFixed32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFixed32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFixed32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFixed32Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - return (4 + tagsize) * len(s) -} -func sizeFixed32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFixedS32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFixedS32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFixedS32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFixedS32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - return (4 + tagsize) * len(s) -} -func sizeFixedS32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFloat32Value(_ pointer, tagsize int) int { - return 4 + tagsize -} -func sizeFloat32ValueNoZero(ptr pointer, tagsize int) int { - v := math.Float32bits(*ptr.toFloat32()) - if v == 0 { - return 0 - } - return 4 + tagsize -} -func sizeFloat32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toFloat32Ptr() - if p == nil { - return 0 - } - return 4 + tagsize -} -func sizeFloat32Slice(ptr pointer, tagsize int) int { - s := *ptr.toFloat32Slice() - return (4 + tagsize) * len(s) -} -func sizeFloat32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toFloat32Slice() - if len(s) == 0 { - return 0 - } - return 4*len(s) + SizeVarint(uint64(4*len(s))) + tagsize -} -func sizeFixed64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFixed64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFixed64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFixed64Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - return (8 + tagsize) * len(s) -} -func sizeFixed64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeFixedS64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFixedS64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFixedS64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFixedS64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - return (8 + tagsize) * len(s) -} -func sizeFixedS64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeFloat64Value(_ pointer, tagsize int) int { - return 8 + tagsize -} -func sizeFloat64ValueNoZero(ptr pointer, tagsize int) int { - v := math.Float64bits(*ptr.toFloat64()) - if v == 0 { - return 0 - } - return 8 + tagsize -} -func sizeFloat64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toFloat64Ptr() - if p == nil { - return 0 - } - return 8 + tagsize -} -func sizeFloat64Slice(ptr pointer, tagsize int) int { - s := *ptr.toFloat64Slice() - return (8 + tagsize) * len(s) -} -func sizeFloat64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toFloat64Slice() - if len(s) == 0 { - return 0 - } - return 8*len(s) + SizeVarint(uint64(8*len(s))) + tagsize -} -func sizeVarint32Value(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarint32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint32() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarint32Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint32Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarint32Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarint32PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarintS32Value(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarintS32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarintS32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarint64Value(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - return SizeVarint(v) + tagsize -} -func sizeVarint64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toUint64() - if v == 0 { - return 0 - } - return SizeVarint(v) + tagsize -} -func sizeVarint64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toUint64Ptr() - if p == nil { - return 0 - } - return SizeVarint(*p) + tagsize -} -func sizeVarint64Slice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(v) + tagsize - } - return n -} -func sizeVarint64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(v) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeVarintS64Value(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v)) + tagsize -} -func sizeVarintS64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - return SizeVarint(uint64(*p)) + tagsize -} -func sizeVarintS64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) + tagsize - } - return n -} -func sizeVarintS64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeZigzag32Value(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt32() - if v == 0 { - return 0 - } - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32Ptr(ptr pointer, tagsize int) int { - p := ptr.getInt32Ptr() - if p == nil { - return 0 - } - v := *p - return SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize -} -func sizeZigzag32Slice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) + tagsize - } - return n -} -func sizeZigzag32PackedSlice(ptr pointer, tagsize int) int { - s := ptr.getInt32Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeZigzag64Value(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64ValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toInt64() - if v == 0 { - return 0 - } - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64Ptr(ptr pointer, tagsize int) int { - p := *ptr.toInt64Ptr() - if p == nil { - return 0 - } - v := *p - return SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize -} -func sizeZigzag64Slice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1)^uint64((int64(v)>>63))) + tagsize - } - return n -} -func sizeZigzag64PackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return 0 - } - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) - } - return n + SizeVarint(uint64(n)) + tagsize -} -func sizeBoolValue(_ pointer, tagsize int) int { - return 1 + tagsize -} -func sizeBoolValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toBool() - if !v { - return 0 - } - return 1 + tagsize -} -func sizeBoolPtr(ptr pointer, tagsize int) int { - p := *ptr.toBoolPtr() - if p == nil { - return 0 - } - return 1 + tagsize -} -func sizeBoolSlice(ptr pointer, tagsize int) int { - s := *ptr.toBoolSlice() - return (1 + tagsize) * len(s) -} -func sizeBoolPackedSlice(ptr pointer, tagsize int) int { - s := *ptr.toBoolSlice() - if len(s) == 0 { - return 0 - } - return len(s) + SizeVarint(uint64(len(s))) + tagsize -} -func sizeStringValue(ptr pointer, tagsize int) int { - v := *ptr.toString() - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringValueNoZero(ptr pointer, tagsize int) int { - v := *ptr.toString() - if v == "" { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringPtr(ptr pointer, tagsize int) int { - p := *ptr.toStringPtr() - if p == nil { - return 0 - } - v := *p - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeStringSlice(ptr pointer, tagsize int) int { - s := *ptr.toStringSlice() - n := 0 - for _, v := range s { - n += len(v) + SizeVarint(uint64(len(v))) + tagsize - } - return n -} -func sizeBytes(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - if v == nil { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytes3(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - if len(v) == 0 { - return 0 - } - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytesOneof(ptr pointer, tagsize int) int { - v := *ptr.toBytes() - return len(v) + SizeVarint(uint64(len(v))) + tagsize -} -func sizeBytesSlice(ptr pointer, tagsize int) int { - s := *ptr.toBytesSlice() - n := 0 - for _, v := range s { - n += len(v) + SizeVarint(uint64(len(v))) + tagsize - } - return n -} - -// appendFixed32 appends an encoded fixed32 to b. -func appendFixed32(b []byte, v uint32) []byte { - b = append(b, - byte(v), - byte(v>>8), - byte(v>>16), - byte(v>>24)) - return b -} - -// appendFixed64 appends an encoded fixed64 to b. -func appendFixed64(b []byte, v uint64) []byte { - b = append(b, - byte(v), - byte(v>>8), - byte(v>>16), - byte(v>>24), - byte(v>>32), - byte(v>>40), - byte(v>>48), - byte(v>>56)) - return b -} - -// appendVarint appends an encoded varint to b. -func appendVarint(b []byte, v uint64) []byte { - // TODO: make 1-byte (maybe 2-byte) case inline-able, once we - // have non-leaf inliner. - switch { - case v < 1<<7: - b = append(b, byte(v)) - case v < 1<<14: - b = append(b, - byte(v&0x7f|0x80), - byte(v>>7)) - case v < 1<<21: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte(v>>14)) - case v < 1<<28: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte(v>>21)) - case v < 1<<35: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte(v>>28)) - case v < 1<<42: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte(v>>35)) - case v < 1<<49: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte(v>>42)) - case v < 1<<56: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte(v>>49)) - case v < 1<<63: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte((v>>49)&0x7f|0x80), - byte(v>>56)) - default: - b = append(b, - byte(v&0x7f|0x80), - byte((v>>7)&0x7f|0x80), - byte((v>>14)&0x7f|0x80), - byte((v>>21)&0x7f|0x80), - byte((v>>28)&0x7f|0x80), - byte((v>>35)&0x7f|0x80), - byte((v>>42)&0x7f|0x80), - byte((v>>49)&0x7f|0x80), - byte((v>>56)&0x7f|0x80), - 1) - } - return b -} - -func appendFixed32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFixed32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFixed32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, *p) - return b, nil -} -func appendFixed32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - } - return b, nil -} -func appendFixed32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, v) - } - return b, nil -} -func appendFixedS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - return b, nil -} -func appendFixedS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - return b, nil -} -func appendFixedS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(*p)) - return b, nil -} -func appendFixedS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, uint32(v)) - } - return b, nil -} -func appendFixedS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, uint32(v)) - } - return b, nil -} -func appendFloat32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float32bits(*ptr.toFloat32()) - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFloat32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float32bits(*ptr.toFloat32()) - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, v) - return b, nil -} -func appendFloat32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toFloat32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed32(b, math.Float32bits(*p)) - return b, nil -} -func appendFloat32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed32(b, math.Float32bits(v)) - } - return b, nil -} -func appendFloat32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(4*len(s))) - for _, v := range s { - b = appendFixed32(b, math.Float32bits(v)) - } - return b, nil -} -func appendFixed64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFixed64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFixed64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, *p) - return b, nil -} -func appendFixed64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - } - return b, nil -} -func appendFixed64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, v) - } - return b, nil -} -func appendFixedS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - return b, nil -} -func appendFixedS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - return b, nil -} -func appendFixedS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(*p)) - return b, nil -} -func appendFixedS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, uint64(v)) - } - return b, nil -} -func appendFixedS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, uint64(v)) - } - return b, nil -} -func appendFloat64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float64bits(*ptr.toFloat64()) - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFloat64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := math.Float64bits(*ptr.toFloat64()) - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, v) - return b, nil -} -func appendFloat64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toFloat64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendFixed64(b, math.Float64bits(*p)) - return b, nil -} -func appendFloat64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendFixed64(b, math.Float64bits(v)) - } - return b, nil -} -func appendFloat64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toFloat64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(8*len(s))) - for _, v := range s { - b = appendFixed64(b, math.Float64bits(v)) - } - return b, nil -} -func appendVarint32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarint32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarint32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarint32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarint32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarintS32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarint64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - return b, nil -} -func appendVarint64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toUint64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - return b, nil -} -func appendVarint64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toUint64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, *p) - return b, nil -} -func appendVarint64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, v) - } - return b, nil -} -func appendVarint64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toUint64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(v) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, v) - } - return b, nil -} -func appendVarintS64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - return b, nil -} -func appendVarintS64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(*p)) - return b, nil -} -func appendVarintS64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendVarintS64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v)) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v)) - } - return b, nil -} -func appendZigzag32Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt32() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := ptr.getInt32Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - v := *p - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - return b, nil -} -func appendZigzag32Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - } - return b, nil -} -func appendZigzag32PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := ptr.getInt32Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64((uint32(v) << 1) ^ uint32((int32(v) >> 31)))) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64((uint32(v)<<1)^uint32((int32(v)>>31)))) - } - return b, nil -} -func appendZigzag64Value(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64ValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toInt64() - if v == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64Ptr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toInt64Ptr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - v := *p - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - return b, nil -} -func appendZigzag64Slice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - } - return b, nil -} -func appendZigzag64PackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toInt64Slice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - // compute size - n := 0 - for _, v := range s { - n += SizeVarint(uint64(v<<1) ^ uint64((int64(v) >> 63))) - } - b = appendVarint(b, uint64(n)) - for _, v := range s { - b = appendVarint(b, uint64(v<<1)^uint64((int64(v)>>63))) - } - return b, nil -} -func appendBoolValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBool() - b = appendVarint(b, wiretag) - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - return b, nil -} -func appendBoolValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBool() - if !v { - return b, nil - } - b = appendVarint(b, wiretag) - b = append(b, 1) - return b, nil -} - -func appendBoolPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toBoolPtr() - if p == nil { - return b, nil - } - b = appendVarint(b, wiretag) - if *p { - b = append(b, 1) - } else { - b = append(b, 0) - } - return b, nil -} -func appendBoolSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBoolSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - } - return b, nil -} -func appendBoolPackedSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBoolSlice() - if len(s) == 0 { - return b, nil - } - b = appendVarint(b, wiretag&^7|WireBytes) - b = appendVarint(b, uint64(len(s))) - for _, v := range s { - if v { - b = append(b, 1) - } else { - b = append(b, 0) - } - } - return b, nil -} -func appendStringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toString() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toString() - if v == "" { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - p := *ptr.toStringPtr() - if p == nil { - return b, nil - } - v := *p - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendStringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toStringSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - return b, nil -} -func appendUTF8StringValue(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - v := *ptr.toString() - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendUTF8StringValueNoZero(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - v := *ptr.toString() - if v == "" { - return b, nil - } - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendUTF8StringPtr(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - p := *ptr.toStringPtr() - if p == nil { - return b, nil - } - v := *p - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendUTF8StringSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - var invalidUTF8 bool - s := *ptr.toStringSlice() - for _, v := range s { - if !utf8.ValidString(v) { - invalidUTF8 = true - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - if invalidUTF8 { - return b, errInvalidUTF8 - } - return b, nil -} -func appendBytes(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - if v == nil { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytes3(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - if len(v) == 0 { - return b, nil - } - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytesOneof(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - v := *ptr.toBytes() - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - return b, nil -} -func appendBytesSlice(b []byte, ptr pointer, wiretag uint64, _ bool) ([]byte, error) { - s := *ptr.toBytesSlice() - for _, v := range s { - b = appendVarint(b, wiretag) - b = appendVarint(b, uint64(len(v))) - b = append(b, v...) - } - return b, nil -} - -// makeGroupMarshaler returns the sizer and marshaler for a group. -// u is the marshal info of the underlying message. -func makeGroupMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - p := ptr.getPointer() - if p.isNil() { - return 0 - } - return u.size(p) + 2*tagsize - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - p := ptr.getPointer() - if p.isNil() { - return b, nil - } - var err error - b = appendVarint(b, wiretag) // start group - b, err = u.marshal(b, p, deterministic) - b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group - return b, err - } -} - -// makeGroupSliceMarshaler returns the sizer and marshaler for a group slice. -// u is the marshal info of the underlying message. -func makeGroupSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getPointerSlice() - n := 0 - for _, v := range s { - if v.isNil() { - continue - } - n += u.size(v) + 2*tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getPointerSlice() - var err error - var nerr nonFatal - for _, v := range s { - if v.isNil() { - return b, errRepeatedHasNil - } - b = appendVarint(b, wiretag) // start group - b, err = u.marshal(b, v, deterministic) - b = appendVarint(b, wiretag+(WireEndGroup-WireStartGroup)) // end group - if !nerr.Merge(err) { - if err == ErrNil { - err = errRepeatedHasNil - } - return b, err - } - } - return b, nerr.E - } -} - -// makeMessageMarshaler returns the sizer and marshaler for a message field. -// u is the marshal info of the message. -func makeMessageMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - p := ptr.getPointer() - if p.isNil() { - return 0 - } - siz := u.size(p) - return siz + SizeVarint(uint64(siz)) + tagsize - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - p := ptr.getPointer() - if p.isNil() { - return b, nil - } - b = appendVarint(b, wiretag) - siz := u.cachedsize(p) - b = appendVarint(b, uint64(siz)) - return u.marshal(b, p, deterministic) - } -} - -// makeMessageSliceMarshaler returns the sizer and marshaler for a message slice. -// u is the marshal info of the message. -func makeMessageSliceMarshaler(u *marshalInfo) (sizer, marshaler) { - return func(ptr pointer, tagsize int) int { - s := ptr.getPointerSlice() - n := 0 - for _, v := range s { - if v.isNil() { - continue - } - siz := u.size(v) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, wiretag uint64, deterministic bool) ([]byte, error) { - s := ptr.getPointerSlice() - var err error - var nerr nonFatal - for _, v := range s { - if v.isNil() { - return b, errRepeatedHasNil - } - b = appendVarint(b, wiretag) - siz := u.cachedsize(v) - b = appendVarint(b, uint64(siz)) - b, err = u.marshal(b, v, deterministic) - - if !nerr.Merge(err) { - if err == ErrNil { - err = errRepeatedHasNil - } - return b, err - } - } - return b, nerr.E - } -} - -// makeMapMarshaler returns the sizer and marshaler for a map field. -// f is the pointer to the reflect data structure of the field. -func makeMapMarshaler(f *reflect.StructField) (sizer, marshaler) { - // figure out key and value type - t := f.Type - keyType := t.Key() - valType := t.Elem() - keyTags := strings.Split(f.Tag.Get("protobuf_key"), ",") - valTags := strings.Split(f.Tag.Get("protobuf_val"), ",") - keySizer, keyMarshaler := typeMarshaler(keyType, keyTags, false, false) // don't omit zero value in map - valSizer, valMarshaler := typeMarshaler(valType, valTags, false, false) // don't omit zero value in map - keyWireTag := 1<<3 | wiretype(keyTags[0]) - valWireTag := 2<<3 | wiretype(valTags[0]) - - // We create an interface to get the addresses of the map key and value. - // If value is pointer-typed, the interface is a direct interface, the - // idata itself is the value. Otherwise, the idata is the pointer to the - // value. - // Key cannot be pointer-typed. - valIsPtr := valType.Kind() == reflect.Ptr - - // If value is a message with nested maps, calling - // valSizer in marshal may be quadratic. We should use - // cached version in marshal (but not in size). - // If value is not message type, we don't have size cache, - // but it cannot be nested either. Just use valSizer. - valCachedSizer := valSizer - if valIsPtr && valType.Elem().Kind() == reflect.Struct { - u := getMarshalInfo(valType.Elem()) - valCachedSizer = func(ptr pointer, tagsize int) int { - // Same as message sizer, but use cache. - p := ptr.getPointer() - if p.isNil() { - return 0 - } - siz := u.cachedsize(p) - return siz + SizeVarint(uint64(siz)) + tagsize - } - } - return func(ptr pointer, tagsize int) int { - m := ptr.asPointerTo(t).Elem() // the map - n := 0 - for _, k := range m.MapKeys() { - ki := k.Interface() - vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value - siz := keySizer(kaddr, 1) + valSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) - n += siz + SizeVarint(uint64(siz)) + tagsize - } - return n - }, - func(b []byte, ptr pointer, tag uint64, deterministic bool) ([]byte, error) { - m := ptr.asPointerTo(t).Elem() // the map - var err error - keys := m.MapKeys() - if len(keys) > 1 && deterministic { - sort.Sort(mapKeys(keys)) - } - - var nerr nonFatal - for _, k := range keys { - ki := k.Interface() - vi := m.MapIndex(k).Interface() - kaddr := toAddrPointer(&ki, false, false) // pointer to key - vaddr := toAddrPointer(&vi, valIsPtr, false) // pointer to value - b = appendVarint(b, tag) - siz := keySizer(kaddr, 1) + valCachedSizer(vaddr, 1) // tag of key = 1 (size=1), tag of val = 2 (size=1) - b = appendVarint(b, uint64(siz)) - b, err = keyMarshaler(b, kaddr, keyWireTag, deterministic) - if !nerr.Merge(err) { - return b, err - } - b, err = valMarshaler(b, vaddr, valWireTag, deterministic) - if err != ErrNil && !nerr.Merge(err) { // allow nil value in map - return b, err - } - } - return b, nerr.E - } -} - -// makeOneOfMarshaler returns the sizer and marshaler for a oneof field. -// fi is the marshal info of the field. -// f is the pointer to the reflect data structure of the field. -func makeOneOfMarshaler(fi *marshalFieldInfo, f *reflect.StructField) (sizer, marshaler) { - // Oneof field is an interface. We need to get the actual data type on the fly. - t := f.Type - return func(ptr pointer, _ int) int { - p := ptr.getInterfacePointer() - if p.isNil() { - return 0 - } - v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct - telem := v.Type() - e := fi.oneofElems[telem] - return e.sizer(p, e.tagsize) - }, - func(b []byte, ptr pointer, _ uint64, deterministic bool) ([]byte, error) { - p := ptr.getInterfacePointer() - if p.isNil() { - return b, nil - } - v := ptr.asPointerTo(t).Elem().Elem().Elem() // *interface -> interface -> *struct -> struct - telem := v.Type() - if telem.Field(0).Type.Kind() == reflect.Ptr && p.getPointer().isNil() { - return b, errOneofHasNil - } - e := fi.oneofElems[telem] - return e.marshaler(b, p, e.wiretag, deterministic) - } -} - -// sizeExtensions computes the size of encoded data for a XXX_InternalExtensions field. -func (u *marshalInfo) sizeExtensions(ext *XXX_InternalExtensions) int { - m, mu := ext.extensionsRead() - if m == nil { - return 0 - } - mu.Lock() - - n := 0 - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - n += len(e.enc) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr, ei.deref) - n += ei.sizer(p, ei.tagsize) - } - mu.Unlock() - return n -} - -// appendExtensions marshals a XXX_InternalExtensions field to the end of byte slice b. -func (u *marshalInfo) appendExtensions(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { - m, mu := ext.extensionsRead() - if m == nil { - return b, nil - } - mu.Lock() - defer mu.Unlock() - - var err error - var nerr nonFatal - - // Fast-path for common cases: zero or one extensions. - // Don't bother sorting the keys. - if len(m) <= 1 { - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr, ei.deref) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E - } - - // Sort the keys to provide a deterministic encoding. - // Not sure this is required, but the old code does it. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - for _, k := range keys { - e := m[int32(k)] - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr, ei.deref) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E -} - -// message set format is: -// message MessageSet { -// repeated group Item = 1 { -// required int32 type_id = 2; -// required string message = 3; -// }; -// } - -// sizeMessageSet computes the size of encoded data for a XXX_InternalExtensions field -// in message set format (above). -func (u *marshalInfo) sizeMessageSet(ext *XXX_InternalExtensions) int { - m, mu := ext.extensionsRead() - if m == nil { - return 0 - } - mu.Lock() - - n := 0 - for id, e := range m { - n += 2 // start group, end group. tag = 1 (size=1) - n += SizeVarint(uint64(id)) + 1 // type_id, tag = 2 (size=1) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - siz := len(msgWithLen) - n += siz + 1 // message, tag = 3 (size=1) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr, ei.deref) - n += ei.sizer(p, 1) // message, tag = 3 (size=1) - } - mu.Unlock() - return n -} - -// appendMessageSet marshals a XXX_InternalExtensions field in message set format (above) -// to the end of byte slice b. -func (u *marshalInfo) appendMessageSet(b []byte, ext *XXX_InternalExtensions, deterministic bool) ([]byte, error) { - m, mu := ext.extensionsRead() - if m == nil { - return b, nil - } - mu.Lock() - defer mu.Unlock() - - var err error - var nerr nonFatal - - // Fast-path for common cases: zero or one extensions. - // Don't bother sorting the keys. - if len(m) <= 1 { - for id, e := range m { - b = append(b, 1<<3|WireStartGroup) - b = append(b, 2<<3|WireVarint) - b = appendVarint(b, uint64(id)) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - b = append(b, 3<<3|WireBytes) - b = append(b, msgWithLen...) - b = append(b, 1<<3|WireEndGroup) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr, ei.deref) - b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) - if !nerr.Merge(err) { - return b, err - } - b = append(b, 1<<3|WireEndGroup) - } - return b, nerr.E - } - - // Sort the keys to provide a deterministic encoding. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - for _, id := range keys { - e := m[int32(id)] - b = append(b, 1<<3|WireStartGroup) - b = append(b, 2<<3|WireVarint) - b = appendVarint(b, uint64(id)) - - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - msgWithLen := skipVarint(e.enc) // skip old tag, but leave the length varint - b = append(b, 3<<3|WireBytes) - b = append(b, msgWithLen...) - b = append(b, 1<<3|WireEndGroup) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr, ei.deref) - b, err = ei.marshaler(b, p, 3<<3|WireBytes, deterministic) - b = append(b, 1<<3|WireEndGroup) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E -} - -// sizeV1Extensions computes the size of encoded data for a V1-API extension field. -func (u *marshalInfo) sizeV1Extensions(m map[int32]Extension) int { - if m == nil { - return 0 - } - - n := 0 - for _, e := range m { - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - n += len(e.enc) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr, ei.deref) - n += ei.sizer(p, ei.tagsize) - } - return n -} - -// appendV1Extensions marshals a V1-API extension field to the end of byte slice b. -func (u *marshalInfo) appendV1Extensions(b []byte, m map[int32]Extension, deterministic bool) ([]byte, error) { - if m == nil { - return b, nil - } - - // Sort the keys to provide a deterministic encoding. - keys := make([]int, 0, len(m)) - for k := range m { - keys = append(keys, int(k)) - } - sort.Ints(keys) - - var err error - var nerr nonFatal - for _, k := range keys { - e := m[int32(k)] - if e.value == nil || e.desc == nil { - // Extension is only in its encoded form. - b = append(b, e.enc...) - continue - } - - // We don't skip extensions that have an encoded form set, - // because the extension value may have been mutated after - // the last time this function was called. - - ei := u.getExtElemInfo(e.desc) - v := e.value - p := toAddrPointer(&v, ei.isptr, ei.deref) - b, err = ei.marshaler(b, p, ei.wiretag, deterministic) - if !nerr.Merge(err) { - return b, err - } - } - return b, nerr.E -} - -// newMarshaler is the interface representing objects that can marshal themselves. -// -// This exists to support protoc-gen-go generated messages. -// The proto package will stop type-asserting to this interface in the future. -// -// DO NOT DEPEND ON THIS. -type newMarshaler interface { - XXX_Size() int - XXX_Marshal(b []byte, deterministic bool) ([]byte, error) -} - -// Size returns the encoded size of a protocol buffer message. -// This is the main entry point. -func Size(pb Message) int { - if m, ok := pb.(newMarshaler); ok { - return m.XXX_Size() - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - b, _ := m.Marshal() - return len(b) - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return 0 - } - var info InternalMessageInfo - return info.Size(pb) -} - -// Marshal takes a protocol buffer message -// and encodes it into the wire format, returning the data. -// This is the main entry point. -func Marshal(pb Message) ([]byte, error) { - if m, ok := pb.(newMarshaler); ok { - siz := m.XXX_Size() - b := make([]byte, 0, siz) - return m.XXX_Marshal(b, false) - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - return m.Marshal() - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return nil, ErrNil - } - var info InternalMessageInfo - siz := info.Size(pb) - b := make([]byte, 0, siz) - return info.Marshal(b, pb, false) -} - -// Marshal takes a protocol buffer message -// and encodes it into the wire format, writing the result to the -// Buffer. -// This is an alternative entry point. It is not necessary to use -// a Buffer for most applications. -func (p *Buffer) Marshal(pb Message) error { - var err error - if m, ok := pb.(newMarshaler); ok { - siz := m.XXX_Size() - p.grow(siz) // make sure buf has enough capacity - p.buf, err = m.XXX_Marshal(p.buf, p.deterministic) - return err - } - if m, ok := pb.(Marshaler); ok { - // If the message can marshal itself, let it do it, for compatibility. - // NOTE: This is not efficient. - b, err := m.Marshal() - p.buf = append(p.buf, b...) - return err - } - // in case somehow we didn't generate the wrapper - if pb == nil { - return ErrNil - } - var info InternalMessageInfo - siz := info.Size(pb) - p.grow(siz) // make sure buf has enough capacity - p.buf, err = info.Marshal(p.buf, pb, p.deterministic) - return err -} - -// grow grows the buffer's capacity, if necessary, to guarantee space for -// another n bytes. After grow(n), at least n bytes can be written to the -// buffer without another allocation. -func (p *Buffer) grow(n int) { - need := len(p.buf) + n - if need <= cap(p.buf) { - return - } - newCap := len(p.buf) * 2 - if newCap < need { - newCap = need - } - p.buf = append(make([]byte, 0, newCap), p.buf...) -} diff --git a/vendor/github.com/golang/protobuf/proto/table_merge.go b/vendor/github.com/golang/protobuf/proto/table_merge.go deleted file mode 100644 index 5525def6a..000000000 --- a/vendor/github.com/golang/protobuf/proto/table_merge.go +++ /dev/null @@ -1,654 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "fmt" - "reflect" - "strings" - "sync" - "sync/atomic" -) - -// Merge merges the src message into dst. -// This assumes that dst and src of the same type and are non-nil. -func (a *InternalMessageInfo) Merge(dst, src Message) { - mi := atomicLoadMergeInfo(&a.merge) - if mi == nil { - mi = getMergeInfo(reflect.TypeOf(dst).Elem()) - atomicStoreMergeInfo(&a.merge, mi) - } - mi.merge(toPointer(&dst), toPointer(&src)) -} - -type mergeInfo struct { - typ reflect.Type - - initialized int32 // 0: only typ is valid, 1: everything is valid - lock sync.Mutex - - fields []mergeFieldInfo - unrecognized field // Offset of XXX_unrecognized -} - -type mergeFieldInfo struct { - field field // Offset of field, guaranteed to be valid - - // isPointer reports whether the value in the field is a pointer. - // This is true for the following situations: - // * Pointer to struct - // * Pointer to basic type (proto2 only) - // * Slice (first value in slice header is a pointer) - // * String (first value in string header is a pointer) - isPointer bool - - // basicWidth reports the width of the field assuming that it is directly - // embedded in the struct (as is the case for basic types in proto3). - // The possible values are: - // 0: invalid - // 1: bool - // 4: int32, uint32, float32 - // 8: int64, uint64, float64 - basicWidth int - - // Where dst and src are pointers to the types being merged. - merge func(dst, src pointer) -} - -var ( - mergeInfoMap = map[reflect.Type]*mergeInfo{} - mergeInfoLock sync.Mutex -) - -func getMergeInfo(t reflect.Type) *mergeInfo { - mergeInfoLock.Lock() - defer mergeInfoLock.Unlock() - mi := mergeInfoMap[t] - if mi == nil { - mi = &mergeInfo{typ: t} - mergeInfoMap[t] = mi - } - return mi -} - -// merge merges src into dst assuming they are both of type *mi.typ. -func (mi *mergeInfo) merge(dst, src pointer) { - if dst.isNil() { - panic("proto: nil destination") - } - if src.isNil() { - return // Nothing to do. - } - - if atomic.LoadInt32(&mi.initialized) == 0 { - mi.computeMergeInfo() - } - - for _, fi := range mi.fields { - sfp := src.offset(fi.field) - - // As an optimization, we can avoid the merge function call cost - // if we know for sure that the source will have no effect - // by checking if it is the zero value. - if unsafeAllowed { - if fi.isPointer && sfp.getPointer().isNil() { // Could be slice or string - continue - } - if fi.basicWidth > 0 { - switch { - case fi.basicWidth == 1 && !*sfp.toBool(): - continue - case fi.basicWidth == 4 && *sfp.toUint32() == 0: - continue - case fi.basicWidth == 8 && *sfp.toUint64() == 0: - continue - } - } - } - - dfp := dst.offset(fi.field) - fi.merge(dfp, sfp) - } - - // TODO: Make this faster? - out := dst.asPointerTo(mi.typ).Elem() - in := src.asPointerTo(mi.typ).Elem() - if emIn, err := extendable(in.Addr().Interface()); err == nil { - emOut, _ := extendable(out.Addr().Interface()) - mIn, muIn := emIn.extensionsRead() - if mIn != nil { - mOut := emOut.extensionsWrite() - muIn.Lock() - mergeExtension(mOut, mIn) - muIn.Unlock() - } - } - - if mi.unrecognized.IsValid() { - if b := *src.offset(mi.unrecognized).toBytes(); len(b) > 0 { - *dst.offset(mi.unrecognized).toBytes() = append([]byte(nil), b...) - } - } -} - -func (mi *mergeInfo) computeMergeInfo() { - mi.lock.Lock() - defer mi.lock.Unlock() - if mi.initialized != 0 { - return - } - t := mi.typ - n := t.NumField() - - props := GetProperties(t) - for i := 0; i < n; i++ { - f := t.Field(i) - if strings.HasPrefix(f.Name, "XXX_") { - continue - } - - mfi := mergeFieldInfo{field: toField(&f)} - tf := f.Type - - // As an optimization, we can avoid the merge function call cost - // if we know for sure that the source will have no effect - // by checking if it is the zero value. - if unsafeAllowed { - switch tf.Kind() { - case reflect.Ptr, reflect.Slice, reflect.String: - // As a special case, we assume slices and strings are pointers - // since we know that the first field in the SliceSlice or - // StringHeader is a data pointer. - mfi.isPointer = true - case reflect.Bool: - mfi.basicWidth = 1 - case reflect.Int32, reflect.Uint32, reflect.Float32: - mfi.basicWidth = 4 - case reflect.Int64, reflect.Uint64, reflect.Float64: - mfi.basicWidth = 8 - } - } - - // Unwrap tf to get at its most basic type. - var isPointer, isSlice bool - if tf.Kind() == reflect.Slice && tf.Elem().Kind() != reflect.Uint8 { - isSlice = true - tf = tf.Elem() - } - if tf.Kind() == reflect.Ptr { - isPointer = true - tf = tf.Elem() - } - if isPointer && isSlice && tf.Kind() != reflect.Struct { - panic("both pointer and slice for basic type in " + tf.Name()) - } - - switch tf.Kind() { - case reflect.Int32: - switch { - case isSlice: // E.g., []int32 - mfi.merge = func(dst, src pointer) { - // NOTE: toInt32Slice is not defined (see pointer_reflect.go). - /* - sfsp := src.toInt32Slice() - if *sfsp != nil { - dfsp := dst.toInt32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []int64{} - } - } - */ - sfs := src.getInt32Slice() - if sfs != nil { - dfs := dst.getInt32Slice() - dfs = append(dfs, sfs...) - if dfs == nil { - dfs = []int32{} - } - dst.setInt32Slice(dfs) - } - } - case isPointer: // E.g., *int32 - mfi.merge = func(dst, src pointer) { - // NOTE: toInt32Ptr is not defined (see pointer_reflect.go). - /* - sfpp := src.toInt32Ptr() - if *sfpp != nil { - dfpp := dst.toInt32Ptr() - if *dfpp == nil { - *dfpp = Int32(**sfpp) - } else { - **dfpp = **sfpp - } - } - */ - sfp := src.getInt32Ptr() - if sfp != nil { - dfp := dst.getInt32Ptr() - if dfp == nil { - dst.setInt32Ptr(*sfp) - } else { - *dfp = *sfp - } - } - } - default: // E.g., int32 - mfi.merge = func(dst, src pointer) { - if v := *src.toInt32(); v != 0 { - *dst.toInt32() = v - } - } - } - case reflect.Int64: - switch { - case isSlice: // E.g., []int64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toInt64Slice() - if *sfsp != nil { - dfsp := dst.toInt64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []int64{} - } - } - } - case isPointer: // E.g., *int64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toInt64Ptr() - if *sfpp != nil { - dfpp := dst.toInt64Ptr() - if *dfpp == nil { - *dfpp = Int64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., int64 - mfi.merge = func(dst, src pointer) { - if v := *src.toInt64(); v != 0 { - *dst.toInt64() = v - } - } - } - case reflect.Uint32: - switch { - case isSlice: // E.g., []uint32 - mfi.merge = func(dst, src pointer) { - sfsp := src.toUint32Slice() - if *sfsp != nil { - dfsp := dst.toUint32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []uint32{} - } - } - } - case isPointer: // E.g., *uint32 - mfi.merge = func(dst, src pointer) { - sfpp := src.toUint32Ptr() - if *sfpp != nil { - dfpp := dst.toUint32Ptr() - if *dfpp == nil { - *dfpp = Uint32(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., uint32 - mfi.merge = func(dst, src pointer) { - if v := *src.toUint32(); v != 0 { - *dst.toUint32() = v - } - } - } - case reflect.Uint64: - switch { - case isSlice: // E.g., []uint64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toUint64Slice() - if *sfsp != nil { - dfsp := dst.toUint64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []uint64{} - } - } - } - case isPointer: // E.g., *uint64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toUint64Ptr() - if *sfpp != nil { - dfpp := dst.toUint64Ptr() - if *dfpp == nil { - *dfpp = Uint64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., uint64 - mfi.merge = func(dst, src pointer) { - if v := *src.toUint64(); v != 0 { - *dst.toUint64() = v - } - } - } - case reflect.Float32: - switch { - case isSlice: // E.g., []float32 - mfi.merge = func(dst, src pointer) { - sfsp := src.toFloat32Slice() - if *sfsp != nil { - dfsp := dst.toFloat32Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []float32{} - } - } - } - case isPointer: // E.g., *float32 - mfi.merge = func(dst, src pointer) { - sfpp := src.toFloat32Ptr() - if *sfpp != nil { - dfpp := dst.toFloat32Ptr() - if *dfpp == nil { - *dfpp = Float32(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., float32 - mfi.merge = func(dst, src pointer) { - if v := *src.toFloat32(); v != 0 { - *dst.toFloat32() = v - } - } - } - case reflect.Float64: - switch { - case isSlice: // E.g., []float64 - mfi.merge = func(dst, src pointer) { - sfsp := src.toFloat64Slice() - if *sfsp != nil { - dfsp := dst.toFloat64Slice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []float64{} - } - } - } - case isPointer: // E.g., *float64 - mfi.merge = func(dst, src pointer) { - sfpp := src.toFloat64Ptr() - if *sfpp != nil { - dfpp := dst.toFloat64Ptr() - if *dfpp == nil { - *dfpp = Float64(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., float64 - mfi.merge = func(dst, src pointer) { - if v := *src.toFloat64(); v != 0 { - *dst.toFloat64() = v - } - } - } - case reflect.Bool: - switch { - case isSlice: // E.g., []bool - mfi.merge = func(dst, src pointer) { - sfsp := src.toBoolSlice() - if *sfsp != nil { - dfsp := dst.toBoolSlice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []bool{} - } - } - } - case isPointer: // E.g., *bool - mfi.merge = func(dst, src pointer) { - sfpp := src.toBoolPtr() - if *sfpp != nil { - dfpp := dst.toBoolPtr() - if *dfpp == nil { - *dfpp = Bool(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., bool - mfi.merge = func(dst, src pointer) { - if v := *src.toBool(); v { - *dst.toBool() = v - } - } - } - case reflect.String: - switch { - case isSlice: // E.g., []string - mfi.merge = func(dst, src pointer) { - sfsp := src.toStringSlice() - if *sfsp != nil { - dfsp := dst.toStringSlice() - *dfsp = append(*dfsp, *sfsp...) - if *dfsp == nil { - *dfsp = []string{} - } - } - } - case isPointer: // E.g., *string - mfi.merge = func(dst, src pointer) { - sfpp := src.toStringPtr() - if *sfpp != nil { - dfpp := dst.toStringPtr() - if *dfpp == nil { - *dfpp = String(**sfpp) - } else { - **dfpp = **sfpp - } - } - } - default: // E.g., string - mfi.merge = func(dst, src pointer) { - if v := *src.toString(); v != "" { - *dst.toString() = v - } - } - } - case reflect.Slice: - isProto3 := props.Prop[i].proto3 - switch { - case isPointer: - panic("bad pointer in byte slice case in " + tf.Name()) - case tf.Elem().Kind() != reflect.Uint8: - panic("bad element kind in byte slice case in " + tf.Name()) - case isSlice: // E.g., [][]byte - mfi.merge = func(dst, src pointer) { - sbsp := src.toBytesSlice() - if *sbsp != nil { - dbsp := dst.toBytesSlice() - for _, sb := range *sbsp { - if sb == nil { - *dbsp = append(*dbsp, nil) - } else { - *dbsp = append(*dbsp, append([]byte{}, sb...)) - } - } - if *dbsp == nil { - *dbsp = [][]byte{} - } - } - } - default: // E.g., []byte - mfi.merge = func(dst, src pointer) { - sbp := src.toBytes() - if *sbp != nil { - dbp := dst.toBytes() - if !isProto3 || len(*sbp) > 0 { - *dbp = append([]byte{}, *sbp...) - } - } - } - } - case reflect.Struct: - switch { - case !isPointer: - panic(fmt.Sprintf("message field %s without pointer", tf)) - case isSlice: // E.g., []*pb.T - mi := getMergeInfo(tf) - mfi.merge = func(dst, src pointer) { - sps := src.getPointerSlice() - if sps != nil { - dps := dst.getPointerSlice() - for _, sp := range sps { - var dp pointer - if !sp.isNil() { - dp = valToPointer(reflect.New(tf)) - mi.merge(dp, sp) - } - dps = append(dps, dp) - } - if dps == nil { - dps = []pointer{} - } - dst.setPointerSlice(dps) - } - } - default: // E.g., *pb.T - mi := getMergeInfo(tf) - mfi.merge = func(dst, src pointer) { - sp := src.getPointer() - if !sp.isNil() { - dp := dst.getPointer() - if dp.isNil() { - dp = valToPointer(reflect.New(tf)) - dst.setPointer(dp) - } - mi.merge(dp, sp) - } - } - } - case reflect.Map: - switch { - case isPointer || isSlice: - panic("bad pointer or slice in map case in " + tf.Name()) - default: // E.g., map[K]V - mfi.merge = func(dst, src pointer) { - sm := src.asPointerTo(tf).Elem() - if sm.Len() == 0 { - return - } - dm := dst.asPointerTo(tf).Elem() - if dm.IsNil() { - dm.Set(reflect.MakeMap(tf)) - } - - switch tf.Elem().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - val = reflect.ValueOf(Clone(val.Interface().(Message))) - dm.SetMapIndex(key, val) - } - case reflect.Slice: // E.g. Bytes type (e.g., []byte) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - val = reflect.ValueOf(append([]byte{}, val.Bytes()...)) - dm.SetMapIndex(key, val) - } - default: // Basic type (e.g., string) - for _, key := range sm.MapKeys() { - val := sm.MapIndex(key) - dm.SetMapIndex(key, val) - } - } - } - } - case reflect.Interface: - // Must be oneof field. - switch { - case isPointer || isSlice: - panic("bad pointer or slice in interface case in " + tf.Name()) - default: // E.g., interface{} - // TODO: Make this faster? - mfi.merge = func(dst, src pointer) { - su := src.asPointerTo(tf).Elem() - if !su.IsNil() { - du := dst.asPointerTo(tf).Elem() - typ := su.Elem().Type() - if du.IsNil() || du.Elem().Type() != typ { - du.Set(reflect.New(typ.Elem())) // Initialize interface if empty - } - sv := su.Elem().Elem().Field(0) - if sv.Kind() == reflect.Ptr && sv.IsNil() { - return - } - dv := du.Elem().Elem().Field(0) - if dv.Kind() == reflect.Ptr && dv.IsNil() { - dv.Set(reflect.New(sv.Type().Elem())) // Initialize proto message if empty - } - switch sv.Type().Kind() { - case reflect.Ptr: // Proto struct (e.g., *T) - Merge(dv.Interface().(Message), sv.Interface().(Message)) - case reflect.Slice: // E.g. Bytes type (e.g., []byte) - dv.Set(reflect.ValueOf(append([]byte{}, sv.Bytes()...))) - default: // Basic type (e.g., string) - dv.Set(sv) - } - } - } - } - default: - panic(fmt.Sprintf("merger not found for type:%s", tf)) - } - mi.fields = append(mi.fields, mfi) - } - - mi.unrecognized = invalidField - if f, ok := t.FieldByName("XXX_unrecognized"); ok { - if f.Type != reflect.TypeOf([]byte{}) { - panic("expected XXX_unrecognized to be of type []byte") - } - mi.unrecognized = toField(&f) - } - - atomic.StoreInt32(&mi.initialized, 1) -} diff --git a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go b/vendor/github.com/golang/protobuf/proto/table_unmarshal.go deleted file mode 100644 index acee2fc52..000000000 --- a/vendor/github.com/golang/protobuf/proto/table_unmarshal.go +++ /dev/null @@ -1,2053 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -import ( - "errors" - "fmt" - "io" - "math" - "reflect" - "strconv" - "strings" - "sync" - "sync/atomic" - "unicode/utf8" -) - -// Unmarshal is the entry point from the generated .pb.go files. -// This function is not intended to be used by non-generated code. -// This function is not subject to any compatibility guarantee. -// msg contains a pointer to a protocol buffer struct. -// b is the data to be unmarshaled into the protocol buffer. -// a is a pointer to a place to store cached unmarshal information. -func (a *InternalMessageInfo) Unmarshal(msg Message, b []byte) error { - // Load the unmarshal information for this message type. - // The atomic load ensures memory consistency. - u := atomicLoadUnmarshalInfo(&a.unmarshal) - if u == nil { - // Slow path: find unmarshal info for msg, update a with it. - u = getUnmarshalInfo(reflect.TypeOf(msg).Elem()) - atomicStoreUnmarshalInfo(&a.unmarshal, u) - } - // Then do the unmarshaling. - err := u.unmarshal(toPointer(&msg), b) - return err -} - -type unmarshalInfo struct { - typ reflect.Type // type of the protobuf struct - - // 0 = only typ field is initialized - // 1 = completely initialized - initialized int32 - lock sync.Mutex // prevents double initialization - dense []unmarshalFieldInfo // fields indexed by tag # - sparse map[uint64]unmarshalFieldInfo // fields indexed by tag # - reqFields []string // names of required fields - reqMask uint64 // 1< 0 { - // Read tag and wire type. - // Special case 1 and 2 byte varints. - var x uint64 - if b[0] < 128 { - x = uint64(b[0]) - b = b[1:] - } else if len(b) >= 2 && b[1] < 128 { - x = uint64(b[0]&0x7f) + uint64(b[1])<<7 - b = b[2:] - } else { - var n int - x, n = decodeVarint(b) - if n == 0 { - return io.ErrUnexpectedEOF - } - b = b[n:] - } - tag := x >> 3 - wire := int(x) & 7 - - // Dispatch on the tag to one of the unmarshal* functions below. - var f unmarshalFieldInfo - if tag < uint64(len(u.dense)) { - f = u.dense[tag] - } else { - f = u.sparse[tag] - } - if fn := f.unmarshal; fn != nil { - var err error - b, err = fn(b, m.offset(f.field), wire) - if err == nil { - reqMask |= f.reqMask - continue - } - if r, ok := err.(*RequiredNotSetError); ok { - // Remember this error, but keep parsing. We need to produce - // a full parse even if a required field is missing. - if errLater == nil { - errLater = r - } - reqMask |= f.reqMask - continue - } - if err != errInternalBadWireType { - if err == errInvalidUTF8 { - if errLater == nil { - fullName := revProtoTypes[reflect.PtrTo(u.typ)] + "." + f.name - errLater = &invalidUTF8Error{fullName} - } - continue - } - return err - } - // Fragments with bad wire type are treated as unknown fields. - } - - // Unknown tag. - if !u.unrecognized.IsValid() { - // Don't keep unrecognized data; just skip it. - var err error - b, err = skipField(b, wire) - if err != nil { - return err - } - continue - } - // Keep unrecognized data around. - // maybe in extensions, maybe in the unrecognized field. - z := m.offset(u.unrecognized).toBytes() - var emap map[int32]Extension - var e Extension - for _, r := range u.extensionRanges { - if uint64(r.Start) <= tag && tag <= uint64(r.End) { - if u.extensions.IsValid() { - mp := m.offset(u.extensions).toExtensions() - emap = mp.extensionsWrite() - e = emap[int32(tag)] - z = &e.enc - break - } - if u.oldExtensions.IsValid() { - p := m.offset(u.oldExtensions).toOldExtensions() - emap = *p - if emap == nil { - emap = map[int32]Extension{} - *p = emap - } - e = emap[int32(tag)] - z = &e.enc - break - } - panic("no extensions field available") - } - } - - // Use wire type to skip data. - var err error - b0 := b - b, err = skipField(b, wire) - if err != nil { - return err - } - *z = encodeVarint(*z, tag<<3|uint64(wire)) - *z = append(*z, b0[:len(b0)-len(b)]...) - - if emap != nil { - emap[int32(tag)] = e - } - } - if reqMask != u.reqMask && errLater == nil { - // A required field of this message is missing. - for _, n := range u.reqFields { - if reqMask&1 == 0 { - errLater = &RequiredNotSetError{n} - } - reqMask >>= 1 - } - } - return errLater -} - -// computeUnmarshalInfo fills in u with information for use -// in unmarshaling protocol buffers of type u.typ. -func (u *unmarshalInfo) computeUnmarshalInfo() { - u.lock.Lock() - defer u.lock.Unlock() - if u.initialized != 0 { - return - } - t := u.typ - n := t.NumField() - - // Set up the "not found" value for the unrecognized byte buffer. - // This is the default for proto3. - u.unrecognized = invalidField - u.extensions = invalidField - u.oldExtensions = invalidField - - // List of the generated type and offset for each oneof field. - type oneofField struct { - ityp reflect.Type // interface type of oneof field - field field // offset in containing message - } - var oneofFields []oneofField - - for i := 0; i < n; i++ { - f := t.Field(i) - if f.Name == "XXX_unrecognized" { - // The byte slice used to hold unrecognized input is special. - if f.Type != reflect.TypeOf(([]byte)(nil)) { - panic("bad type for XXX_unrecognized field: " + f.Type.Name()) - } - u.unrecognized = toField(&f) - continue - } - if f.Name == "XXX_InternalExtensions" { - // Ditto here. - if f.Type != reflect.TypeOf(XXX_InternalExtensions{}) { - panic("bad type for XXX_InternalExtensions field: " + f.Type.Name()) - } - u.extensions = toField(&f) - if f.Tag.Get("protobuf_messageset") == "1" { - u.isMessageSet = true - } - continue - } - if f.Name == "XXX_extensions" { - // An older form of the extensions field. - if f.Type != reflect.TypeOf((map[int32]Extension)(nil)) { - panic("bad type for XXX_extensions field: " + f.Type.Name()) - } - u.oldExtensions = toField(&f) - continue - } - if f.Name == "XXX_NoUnkeyedLiteral" || f.Name == "XXX_sizecache" { - continue - } - - oneof := f.Tag.Get("protobuf_oneof") - if oneof != "" { - oneofFields = append(oneofFields, oneofField{f.Type, toField(&f)}) - // The rest of oneof processing happens below. - continue - } - - tags := f.Tag.Get("protobuf") - tagArray := strings.Split(tags, ",") - if len(tagArray) < 2 { - panic("protobuf tag not enough fields in " + t.Name() + "." + f.Name + ": " + tags) - } - tag, err := strconv.Atoi(tagArray[1]) - if err != nil { - panic("protobuf tag field not an integer: " + tagArray[1]) - } - - name := "" - for _, tag := range tagArray[3:] { - if strings.HasPrefix(tag, "name=") { - name = tag[5:] - } - } - - // Extract unmarshaling function from the field (its type and tags). - unmarshal := fieldUnmarshaler(&f) - - // Required field? - var reqMask uint64 - if tagArray[2] == "req" { - bit := len(u.reqFields) - u.reqFields = append(u.reqFields, name) - reqMask = uint64(1) << uint(bit) - // TODO: if we have more than 64 required fields, we end up - // not verifying that all required fields are present. - // Fix this, perhaps using a count of required fields? - } - - // Store the info in the correct slot in the message. - u.setTag(tag, toField(&f), unmarshal, reqMask, name) - } - - // Find any types associated with oneof fields. - var oneofImplementers []interface{} - switch m := reflect.Zero(reflect.PtrTo(t)).Interface().(type) { - case oneofFuncsIface: - _, _, _, oneofImplementers = m.XXX_OneofFuncs() - case oneofWrappersIface: - oneofImplementers = m.XXX_OneofWrappers() - } - for _, v := range oneofImplementers { - tptr := reflect.TypeOf(v) // *Msg_X - typ := tptr.Elem() // Msg_X - - f := typ.Field(0) // oneof implementers have one field - baseUnmarshal := fieldUnmarshaler(&f) - tags := strings.Split(f.Tag.Get("protobuf"), ",") - fieldNum, err := strconv.Atoi(tags[1]) - if err != nil { - panic("protobuf tag field not an integer: " + tags[1]) - } - var name string - for _, tag := range tags { - if strings.HasPrefix(tag, "name=") { - name = strings.TrimPrefix(tag, "name=") - break - } - } - - // Find the oneof field that this struct implements. - // Might take O(n^2) to process all of the oneofs, but who cares. - for _, of := range oneofFields { - if tptr.Implements(of.ityp) { - // We have found the corresponding interface for this struct. - // That lets us know where this struct should be stored - // when we encounter it during unmarshaling. - unmarshal := makeUnmarshalOneof(typ, of.ityp, baseUnmarshal) - u.setTag(fieldNum, of.field, unmarshal, 0, name) - } - } - - } - - // Get extension ranges, if any. - fn := reflect.Zero(reflect.PtrTo(t)).MethodByName("ExtensionRangeArray") - if fn.IsValid() { - if !u.extensions.IsValid() && !u.oldExtensions.IsValid() { - panic("a message with extensions, but no extensions field in " + t.Name()) - } - u.extensionRanges = fn.Call(nil)[0].Interface().([]ExtensionRange) - } - - // Explicitly disallow tag 0. This will ensure we flag an error - // when decoding a buffer of all zeros. Without this code, we - // would decode and skip an all-zero buffer of even length. - // [0 0] is [tag=0/wiretype=varint varint-encoded-0]. - u.setTag(0, zeroField, func(b []byte, f pointer, w int) ([]byte, error) { - return nil, fmt.Errorf("proto: %s: illegal tag 0 (wire type %d)", t, w) - }, 0, "") - - // Set mask for required field check. - u.reqMask = uint64(1)<= 0 && (tag < 16 || tag < 2*n) { // TODO: what are the right numbers here? - for len(u.dense) <= tag { - u.dense = append(u.dense, unmarshalFieldInfo{}) - } - u.dense[tag] = i - return - } - if u.sparse == nil { - u.sparse = map[uint64]unmarshalFieldInfo{} - } - u.sparse[uint64(tag)] = i -} - -// fieldUnmarshaler returns an unmarshaler for the given field. -func fieldUnmarshaler(f *reflect.StructField) unmarshaler { - if f.Type.Kind() == reflect.Map { - return makeUnmarshalMap(f) - } - return typeUnmarshaler(f.Type, f.Tag.Get("protobuf")) -} - -// typeUnmarshaler returns an unmarshaler for the given field type / field tag pair. -func typeUnmarshaler(t reflect.Type, tags string) unmarshaler { - tagArray := strings.Split(tags, ",") - encoding := tagArray[0] - name := "unknown" - proto3 := false - validateUTF8 := true - for _, tag := range tagArray[3:] { - if strings.HasPrefix(tag, "name=") { - name = tag[5:] - } - if tag == "proto3" { - proto3 = true - } - } - validateUTF8 = validateUTF8 && proto3 - - // Figure out packaging (pointer, slice, or both) - slice := false - pointer := false - if t.Kind() == reflect.Slice && t.Elem().Kind() != reflect.Uint8 { - slice = true - t = t.Elem() - } - if t.Kind() == reflect.Ptr { - pointer = true - t = t.Elem() - } - - // We'll never have both pointer and slice for basic types. - if pointer && slice && t.Kind() != reflect.Struct { - panic("both pointer and slice for basic type in " + t.Name()) - } - - switch t.Kind() { - case reflect.Bool: - if pointer { - return unmarshalBoolPtr - } - if slice { - return unmarshalBoolSlice - } - return unmarshalBoolValue - case reflect.Int32: - switch encoding { - case "fixed32": - if pointer { - return unmarshalFixedS32Ptr - } - if slice { - return unmarshalFixedS32Slice - } - return unmarshalFixedS32Value - case "varint": - // this could be int32 or enum - if pointer { - return unmarshalInt32Ptr - } - if slice { - return unmarshalInt32Slice - } - return unmarshalInt32Value - case "zigzag32": - if pointer { - return unmarshalSint32Ptr - } - if slice { - return unmarshalSint32Slice - } - return unmarshalSint32Value - } - case reflect.Int64: - switch encoding { - case "fixed64": - if pointer { - return unmarshalFixedS64Ptr - } - if slice { - return unmarshalFixedS64Slice - } - return unmarshalFixedS64Value - case "varint": - if pointer { - return unmarshalInt64Ptr - } - if slice { - return unmarshalInt64Slice - } - return unmarshalInt64Value - case "zigzag64": - if pointer { - return unmarshalSint64Ptr - } - if slice { - return unmarshalSint64Slice - } - return unmarshalSint64Value - } - case reflect.Uint32: - switch encoding { - case "fixed32": - if pointer { - return unmarshalFixed32Ptr - } - if slice { - return unmarshalFixed32Slice - } - return unmarshalFixed32Value - case "varint": - if pointer { - return unmarshalUint32Ptr - } - if slice { - return unmarshalUint32Slice - } - return unmarshalUint32Value - } - case reflect.Uint64: - switch encoding { - case "fixed64": - if pointer { - return unmarshalFixed64Ptr - } - if slice { - return unmarshalFixed64Slice - } - return unmarshalFixed64Value - case "varint": - if pointer { - return unmarshalUint64Ptr - } - if slice { - return unmarshalUint64Slice - } - return unmarshalUint64Value - } - case reflect.Float32: - if pointer { - return unmarshalFloat32Ptr - } - if slice { - return unmarshalFloat32Slice - } - return unmarshalFloat32Value - case reflect.Float64: - if pointer { - return unmarshalFloat64Ptr - } - if slice { - return unmarshalFloat64Slice - } - return unmarshalFloat64Value - case reflect.Map: - panic("map type in typeUnmarshaler in " + t.Name()) - case reflect.Slice: - if pointer { - panic("bad pointer in slice case in " + t.Name()) - } - if slice { - return unmarshalBytesSlice - } - return unmarshalBytesValue - case reflect.String: - if validateUTF8 { - if pointer { - return unmarshalUTF8StringPtr - } - if slice { - return unmarshalUTF8StringSlice - } - return unmarshalUTF8StringValue - } - if pointer { - return unmarshalStringPtr - } - if slice { - return unmarshalStringSlice - } - return unmarshalStringValue - case reflect.Struct: - // message or group field - if !pointer { - panic(fmt.Sprintf("message/group field %s:%s without pointer", t, encoding)) - } - switch encoding { - case "bytes": - if slice { - return makeUnmarshalMessageSlicePtr(getUnmarshalInfo(t), name) - } - return makeUnmarshalMessagePtr(getUnmarshalInfo(t), name) - case "group": - if slice { - return makeUnmarshalGroupSlicePtr(getUnmarshalInfo(t), name) - } - return makeUnmarshalGroupPtr(getUnmarshalInfo(t), name) - } - } - panic(fmt.Sprintf("unmarshaler not found type:%s encoding:%s", t, encoding)) -} - -// Below are all the unmarshalers for individual fields of various types. - -func unmarshalInt64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - *f.toInt64() = v - return b, nil -} - -func unmarshalInt64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - *f.toInt64Ptr() = &v - return b, nil -} - -func unmarshalInt64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - s := f.toInt64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x) - s := f.toInt64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalSint64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - *f.toInt64() = v - return b, nil -} - -func unmarshalSint64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - *f.toInt64Ptr() = &v - return b, nil -} - -func unmarshalSint64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - s := f.toInt64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int64(x>>1) ^ int64(x)<<63>>63 - s := f.toInt64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalUint64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - *f.toUint64() = v - return b, nil -} - -func unmarshalUint64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - *f.toUint64Ptr() = &v - return b, nil -} - -func unmarshalUint64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - s := f.toUint64Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint64(x) - s := f.toUint64Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalInt32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - *f.toInt32() = v - return b, nil -} - -func unmarshalInt32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.setInt32Ptr(v) - return b, nil -} - -func unmarshalInt32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.appendInt32Slice(v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x) - f.appendInt32Slice(v) - return b, nil -} - -func unmarshalSint32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - *f.toInt32() = v - return b, nil -} - -func unmarshalSint32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.setInt32Ptr(v) - return b, nil -} - -func unmarshalSint32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.appendInt32Slice(v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := int32(x>>1) ^ int32(x)<<31>>31 - f.appendInt32Slice(v) - return b, nil -} - -func unmarshalUint32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - *f.toUint32() = v - return b, nil -} - -func unmarshalUint32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - *f.toUint32Ptr() = &v - return b, nil -} - -func unmarshalUint32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - s := f.toUint32Slice() - *s = append(*s, v) - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - v := uint32(x) - s := f.toUint32Slice() - *s = append(*s, v) - return b, nil -} - -func unmarshalFixed64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - *f.toUint64() = v - return b[8:], nil -} - -func unmarshalFixed64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - *f.toUint64Ptr() = &v - return b[8:], nil -} - -func unmarshalFixed64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - s := f.toUint64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 - s := f.toUint64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFixedS64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - *f.toInt64() = v - return b[8:], nil -} - -func unmarshalFixedS64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - *f.toInt64Ptr() = &v - return b[8:], nil -} - -func unmarshalFixedS64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - s := f.toInt64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := int64(b[0]) | int64(b[1])<<8 | int64(b[2])<<16 | int64(b[3])<<24 | int64(b[4])<<32 | int64(b[5])<<40 | int64(b[6])<<48 | int64(b[7])<<56 - s := f.toInt64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFixed32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - *f.toUint32() = v - return b[4:], nil -} - -func unmarshalFixed32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - *f.toUint32Ptr() = &v - return b[4:], nil -} - -func unmarshalFixed32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - s := f.toUint32Slice() - *s = append(*s, v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 - s := f.toUint32Slice() - *s = append(*s, v) - return b[4:], nil -} - -func unmarshalFixedS32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - *f.toInt32() = v - return b[4:], nil -} - -func unmarshalFixedS32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.setInt32Ptr(v) - return b[4:], nil -} - -func unmarshalFixedS32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.appendInt32Slice(v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := int32(b[0]) | int32(b[1])<<8 | int32(b[2])<<16 | int32(b[3])<<24 - f.appendInt32Slice(v) - return b[4:], nil -} - -func unmarshalBoolValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - // Note: any length varint is allowed, even though any sane - // encoder will use one byte. - // See https://github.com/golang/protobuf/issues/76 - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - // TODO: check if x>1? Tests seem to indicate no. - v := x != 0 - *f.toBool() = v - return b[n:], nil -} - -func unmarshalBoolPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - *f.toBoolPtr() = &v - return b[n:], nil -} - -func unmarshalBoolSlice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - x, n = decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - s := f.toBoolSlice() - *s = append(*s, v) - b = b[n:] - } - return res, nil - } - if w != WireVarint { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - v := x != 0 - s := f.toBoolSlice() - *s = append(*s, v) - return b[n:], nil -} - -func unmarshalFloat64Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - *f.toFloat64() = v - return b[8:], nil -} - -func unmarshalFloat64Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - *f.toFloat64Ptr() = &v - return b[8:], nil -} - -func unmarshalFloat64Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - s := f.toFloat64Slice() - *s = append(*s, v) - b = b[8:] - } - return res, nil - } - if w != WireFixed64 { - return b, errInternalBadWireType - } - if len(b) < 8 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float64frombits(uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56) - s := f.toFloat64Slice() - *s = append(*s, v) - return b[8:], nil -} - -func unmarshalFloat32Value(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - *f.toFloat32() = v - return b[4:], nil -} - -func unmarshalFloat32Ptr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - *f.toFloat32Ptr() = &v - return b[4:], nil -} - -func unmarshalFloat32Slice(b []byte, f pointer, w int) ([]byte, error) { - if w == WireBytes { // packed - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - res := b[x:] - b = b[:x] - for len(b) > 0 { - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - s := f.toFloat32Slice() - *s = append(*s, v) - b = b[4:] - } - return res, nil - } - if w != WireFixed32 { - return b, errInternalBadWireType - } - if len(b) < 4 { - return nil, io.ErrUnexpectedEOF - } - v := math.Float32frombits(uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24) - s := f.toFloat32Slice() - *s = append(*s, v) - return b[4:], nil -} - -func unmarshalStringValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toString() = v - return b[x:], nil -} - -func unmarshalStringPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toStringPtr() = &v - return b[x:], nil -} - -func unmarshalStringSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - s := f.toStringSlice() - *s = append(*s, v) - return b[x:], nil -} - -func unmarshalUTF8StringValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toString() = v - if !utf8.ValidString(v) { - return b[x:], errInvalidUTF8 - } - return b[x:], nil -} - -func unmarshalUTF8StringPtr(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - *f.toStringPtr() = &v - if !utf8.ValidString(v) { - return b[x:], errInvalidUTF8 - } - return b[x:], nil -} - -func unmarshalUTF8StringSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := string(b[:x]) - s := f.toStringSlice() - *s = append(*s, v) - if !utf8.ValidString(v) { - return b[x:], errInvalidUTF8 - } - return b[x:], nil -} - -var emptyBuf [0]byte - -func unmarshalBytesValue(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - // The use of append here is a trick which avoids the zeroing - // that would be required if we used a make/copy pair. - // We append to emptyBuf instead of nil because we want - // a non-nil result even when the length is 0. - v := append(emptyBuf[:], b[:x]...) - *f.toBytes() = v - return b[x:], nil -} - -func unmarshalBytesSlice(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := append(emptyBuf[:], b[:x]...) - s := f.toBytesSlice() - *s = append(*s, v) - return b[x:], nil -} - -func makeUnmarshalMessagePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - // First read the message field to see if something is there. - // The semantics of multiple submessages are weird. Instead of - // the last one winning (as it is for all other fields), multiple - // submessages are merged. - v := f.getPointer() - if v.isNil() { - v = valToPointer(reflect.New(sub.typ)) - f.setPointer(v) - } - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - return b[x:], err - } -} - -func makeUnmarshalMessageSlicePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireBytes { - return b, errInternalBadWireType - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - v := valToPointer(reflect.New(sub.typ)) - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - f.appendPointer(v) - return b[x:], err - } -} - -func makeUnmarshalGroupPtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireStartGroup { - return b, errInternalBadWireType - } - x, y := findEndGroup(b) - if x < 0 { - return nil, io.ErrUnexpectedEOF - } - v := f.getPointer() - if v.isNil() { - v = valToPointer(reflect.New(sub.typ)) - f.setPointer(v) - } - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - return b[y:], err - } -} - -func makeUnmarshalGroupSlicePtr(sub *unmarshalInfo, name string) unmarshaler { - return func(b []byte, f pointer, w int) ([]byte, error) { - if w != WireStartGroup { - return b, errInternalBadWireType - } - x, y := findEndGroup(b) - if x < 0 { - return nil, io.ErrUnexpectedEOF - } - v := valToPointer(reflect.New(sub.typ)) - err := sub.unmarshal(v, b[:x]) - if err != nil { - if r, ok := err.(*RequiredNotSetError); ok { - r.field = name + "." + r.field - } else { - return nil, err - } - } - f.appendPointer(v) - return b[y:], err - } -} - -func makeUnmarshalMap(f *reflect.StructField) unmarshaler { - t := f.Type - kt := t.Key() - vt := t.Elem() - unmarshalKey := typeUnmarshaler(kt, f.Tag.Get("protobuf_key")) - unmarshalVal := typeUnmarshaler(vt, f.Tag.Get("protobuf_val")) - return func(b []byte, f pointer, w int) ([]byte, error) { - // The map entry is a submessage. Figure out how big it is. - if w != WireBytes { - return nil, fmt.Errorf("proto: bad wiretype for map field: got %d want %d", w, WireBytes) - } - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - b = b[n:] - if x > uint64(len(b)) { - return nil, io.ErrUnexpectedEOF - } - r := b[x:] // unused data to return - b = b[:x] // data for map entry - - // Note: we could use #keys * #values ~= 200 functions - // to do map decoding without reflection. Probably not worth it. - // Maps will be somewhat slow. Oh well. - - // Read key and value from data. - var nerr nonFatal - k := reflect.New(kt) - v := reflect.New(vt) - for len(b) > 0 { - x, n := decodeVarint(b) - if n == 0 { - return nil, io.ErrUnexpectedEOF - } - wire := int(x) & 7 - b = b[n:] - - var err error - switch x >> 3 { - case 1: - b, err = unmarshalKey(b, valToPointer(k), wire) - case 2: - b, err = unmarshalVal(b, valToPointer(v), wire) - default: - err = errInternalBadWireType // skip unknown tag - } - - if nerr.Merge(err) { - continue - } - if err != errInternalBadWireType { - return nil, err - } - - // Skip past unknown fields. - b, err = skipField(b, wire) - if err != nil { - return nil, err - } - } - - // Get map, allocate if needed. - m := f.asPointerTo(t).Elem() // an addressable map[K]T - if m.IsNil() { - m.Set(reflect.MakeMap(t)) - } - - // Insert into map. - m.SetMapIndex(k.Elem(), v.Elem()) - - return r, nerr.E - } -} - -// makeUnmarshalOneof makes an unmarshaler for oneof fields. -// for: -// message Msg { -// oneof F { -// int64 X = 1; -// float64 Y = 2; -// } -// } -// typ is the type of the concrete entry for a oneof case (e.g. Msg_X). -// ityp is the interface type of the oneof field (e.g. isMsg_F). -// unmarshal is the unmarshaler for the base type of the oneof case (e.g. int64). -// Note that this function will be called once for each case in the oneof. -func makeUnmarshalOneof(typ, ityp reflect.Type, unmarshal unmarshaler) unmarshaler { - sf := typ.Field(0) - field0 := toField(&sf) - return func(b []byte, f pointer, w int) ([]byte, error) { - // Allocate holder for value. - v := reflect.New(typ) - - // Unmarshal data into holder. - // We unmarshal into the first field of the holder object. - var err error - var nerr nonFatal - b, err = unmarshal(b, valToPointer(v).offset(field0), w) - if !nerr.Merge(err) { - return nil, err - } - - // Write pointer to holder into target field. - f.asPointerTo(ityp).Elem().Set(v) - - return b, nerr.E - } -} - -// Error used by decode internally. -var errInternalBadWireType = errors.New("proto: internal error: bad wiretype") - -// skipField skips past a field of type wire and returns the remaining bytes. -func skipField(b []byte, wire int) ([]byte, error) { - switch wire { - case WireVarint: - _, k := decodeVarint(b) - if k == 0 { - return b, io.ErrUnexpectedEOF - } - b = b[k:] - case WireFixed32: - if len(b) < 4 { - return b, io.ErrUnexpectedEOF - } - b = b[4:] - case WireFixed64: - if len(b) < 8 { - return b, io.ErrUnexpectedEOF - } - b = b[8:] - case WireBytes: - m, k := decodeVarint(b) - if k == 0 || uint64(len(b)-k) < m { - return b, io.ErrUnexpectedEOF - } - b = b[uint64(k)+m:] - case WireStartGroup: - _, i := findEndGroup(b) - if i == -1 { - return b, io.ErrUnexpectedEOF - } - b = b[i:] - default: - return b, fmt.Errorf("proto: can't skip unknown wire type %d", wire) - } - return b, nil -} - -// findEndGroup finds the index of the next EndGroup tag. -// Groups may be nested, so the "next" EndGroup tag is the first -// unpaired EndGroup. -// findEndGroup returns the indexes of the start and end of the EndGroup tag. -// Returns (-1,-1) if it can't find one. -func findEndGroup(b []byte) (int, int) { - depth := 1 - i := 0 - for { - x, n := decodeVarint(b[i:]) - if n == 0 { - return -1, -1 - } - j := i - i += n - switch x & 7 { - case WireVarint: - _, k := decodeVarint(b[i:]) - if k == 0 { - return -1, -1 - } - i += k - case WireFixed32: - if len(b)-4 < i { - return -1, -1 - } - i += 4 - case WireFixed64: - if len(b)-8 < i { - return -1, -1 - } - i += 8 - case WireBytes: - m, k := decodeVarint(b[i:]) - if k == 0 { - return -1, -1 - } - i += k - if uint64(len(b)-i) < m { - return -1, -1 - } - i += int(m) - case WireStartGroup: - depth++ - case WireEndGroup: - depth-- - if depth == 0 { - return j, i - } - default: - return -1, -1 - } - } -} - -// encodeVarint appends a varint-encoded integer to b and returns the result. -func encodeVarint(b []byte, x uint64) []byte { - for x >= 1<<7 { - b = append(b, byte(x&0x7f|0x80)) - x >>= 7 - } - return append(b, byte(x)) -} - -// decodeVarint reads a varint-encoded integer from b. -// Returns the decoded integer and the number of bytes read. -// If there is an error, it returns 0,0. -func decodeVarint(b []byte) (uint64, int) { - var x, y uint64 - if len(b) == 0 { - goto bad - } - x = uint64(b[0]) - if x < 0x80 { - return x, 1 - } - x -= 0x80 - - if len(b) <= 1 { - goto bad - } - y = uint64(b[1]) - x += y << 7 - if y < 0x80 { - return x, 2 - } - x -= 0x80 << 7 - - if len(b) <= 2 { - goto bad - } - y = uint64(b[2]) - x += y << 14 - if y < 0x80 { - return x, 3 - } - x -= 0x80 << 14 - - if len(b) <= 3 { - goto bad - } - y = uint64(b[3]) - x += y << 21 - if y < 0x80 { - return x, 4 - } - x -= 0x80 << 21 - - if len(b) <= 4 { - goto bad - } - y = uint64(b[4]) - x += y << 28 - if y < 0x80 { - return x, 5 - } - x -= 0x80 << 28 - - if len(b) <= 5 { - goto bad - } - y = uint64(b[5]) - x += y << 35 - if y < 0x80 { - return x, 6 - } - x -= 0x80 << 35 - - if len(b) <= 6 { - goto bad - } - y = uint64(b[6]) - x += y << 42 - if y < 0x80 { - return x, 7 - } - x -= 0x80 << 42 - - if len(b) <= 7 { - goto bad - } - y = uint64(b[7]) - x += y << 49 - if y < 0x80 { - return x, 8 - } - x -= 0x80 << 49 - - if len(b) <= 8 { - goto bad - } - y = uint64(b[8]) - x += y << 56 - if y < 0x80 { - return x, 9 - } - x -= 0x80 << 56 - - if len(b) <= 9 { - goto bad - } - y = uint64(b[9]) - x += y << 63 - if y < 2 { - return x, 10 - } - -bad: - return 0, 0 -} diff --git a/vendor/github.com/golang/protobuf/proto/text.go b/vendor/github.com/golang/protobuf/proto/text.go deleted file mode 100644 index d97f9b356..000000000 --- a/vendor/github.com/golang/protobuf/proto/text.go +++ /dev/null @@ -1,845 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// Functions for writing the text protocol buffer format. - -import ( - "bufio" - "bytes" - "encoding" - "errors" - "fmt" - "io" - "log" - "math" - "reflect" - "sort" - "strings" -) - -var ( - newline = []byte("\n") - spaces = []byte(" ") - endBraceNewline = []byte("}\n") - backslashN = []byte{'\\', 'n'} - backslashR = []byte{'\\', 'r'} - backslashT = []byte{'\\', 't'} - backslashDQ = []byte{'\\', '"'} - backslashBS = []byte{'\\', '\\'} - posInf = []byte("inf") - negInf = []byte("-inf") - nan = []byte("nan") -) - -type writer interface { - io.Writer - WriteByte(byte) error -} - -// textWriter is an io.Writer that tracks its indentation level. -type textWriter struct { - ind int - complete bool // if the current position is a complete line - compact bool // whether to write out as a one-liner - w writer -} - -func (w *textWriter) WriteString(s string) (n int, err error) { - if !strings.Contains(s, "\n") { - if !w.compact && w.complete { - w.writeIndent() - } - w.complete = false - return io.WriteString(w.w, s) - } - // WriteString is typically called without newlines, so this - // codepath and its copy are rare. We copy to avoid - // duplicating all of Write's logic here. - return w.Write([]byte(s)) -} - -func (w *textWriter) Write(p []byte) (n int, err error) { - newlines := bytes.Count(p, newline) - if newlines == 0 { - if !w.compact && w.complete { - w.writeIndent() - } - n, err = w.w.Write(p) - w.complete = false - return n, err - } - - frags := bytes.SplitN(p, newline, newlines+1) - if w.compact { - for i, frag := range frags { - if i > 0 { - if err := w.w.WriteByte(' '); err != nil { - return n, err - } - n++ - } - nn, err := w.w.Write(frag) - n += nn - if err != nil { - return n, err - } - } - return n, nil - } - - for i, frag := range frags { - if w.complete { - w.writeIndent() - } - nn, err := w.w.Write(frag) - n += nn - if err != nil { - return n, err - } - if i+1 < len(frags) { - if err := w.w.WriteByte('\n'); err != nil { - return n, err - } - n++ - } - } - w.complete = len(frags[len(frags)-1]) == 0 - return n, nil -} - -func (w *textWriter) WriteByte(c byte) error { - if w.compact && c == '\n' { - c = ' ' - } - if !w.compact && w.complete { - w.writeIndent() - } - err := w.w.WriteByte(c) - w.complete = c == '\n' - return err -} - -func (w *textWriter) indent() { w.ind++ } - -func (w *textWriter) unindent() { - if w.ind == 0 { - log.Print("proto: textWriter unindented too far") - return - } - w.ind-- -} - -func writeName(w *textWriter, props *Properties) error { - if _, err := w.WriteString(props.OrigName); err != nil { - return err - } - if props.Wire != "group" { - return w.WriteByte(':') - } - return nil -} - -func requiresQuotes(u string) bool { - // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. - for _, ch := range u { - switch { - case ch == '.' || ch == '/' || ch == '_': - continue - case '0' <= ch && ch <= '9': - continue - case 'A' <= ch && ch <= 'Z': - continue - case 'a' <= ch && ch <= 'z': - continue - default: - return true - } - } - return false -} - -// isAny reports whether sv is a google.protobuf.Any message -func isAny(sv reflect.Value) bool { - type wkt interface { - XXX_WellKnownType() string - } - t, ok := sv.Addr().Interface().(wkt) - return ok && t.XXX_WellKnownType() == "Any" -} - -// writeProto3Any writes an expanded google.protobuf.Any message. -// -// It returns (false, nil) if sv value can't be unmarshaled (e.g. because -// required messages are not linked in). -// -// It returns (true, error) when sv was written in expanded format or an error -// was encountered. -func (tm *TextMarshaler) writeProto3Any(w *textWriter, sv reflect.Value) (bool, error) { - turl := sv.FieldByName("TypeUrl") - val := sv.FieldByName("Value") - if !turl.IsValid() || !val.IsValid() { - return true, errors.New("proto: invalid google.protobuf.Any message") - } - - b, ok := val.Interface().([]byte) - if !ok { - return true, errors.New("proto: invalid google.protobuf.Any message") - } - - parts := strings.Split(turl.String(), "/") - mt := MessageType(parts[len(parts)-1]) - if mt == nil { - return false, nil - } - m := reflect.New(mt.Elem()) - if err := Unmarshal(b, m.Interface().(Message)); err != nil { - return false, nil - } - w.Write([]byte("[")) - u := turl.String() - if requiresQuotes(u) { - writeString(w, u) - } else { - w.Write([]byte(u)) - } - if w.compact { - w.Write([]byte("]:<")) - } else { - w.Write([]byte("]: <\n")) - w.ind++ - } - if err := tm.writeStruct(w, m.Elem()); err != nil { - return true, err - } - if w.compact { - w.Write([]byte("> ")) - } else { - w.ind-- - w.Write([]byte(">\n")) - } - return true, nil -} - -func (tm *TextMarshaler) writeStruct(w *textWriter, sv reflect.Value) error { - if tm.ExpandAny && isAny(sv) { - if canExpand, err := tm.writeProto3Any(w, sv); canExpand { - return err - } - } - st := sv.Type() - sprops := GetProperties(st) - for i := 0; i < sv.NumField(); i++ { - fv := sv.Field(i) - props := sprops.Prop[i] - name := st.Field(i).Name - - if name == "XXX_NoUnkeyedLiteral" { - continue - } - - if strings.HasPrefix(name, "XXX_") { - // There are two XXX_ fields: - // XXX_unrecognized []byte - // XXX_extensions map[int32]proto.Extension - // The first is handled here; - // the second is handled at the bottom of this function. - if name == "XXX_unrecognized" && !fv.IsNil() { - if err := writeUnknownStruct(w, fv.Interface().([]byte)); err != nil { - return err - } - } - continue - } - if fv.Kind() == reflect.Ptr && fv.IsNil() { - // Field not filled in. This could be an optional field or - // a required field that wasn't filled in. Either way, there - // isn't anything we can show for it. - continue - } - if fv.Kind() == reflect.Slice && fv.IsNil() { - // Repeated field that is empty, or a bytes field that is unused. - continue - } - - if props.Repeated && fv.Kind() == reflect.Slice { - // Repeated field. - for j := 0; j < fv.Len(); j++ { - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - v := fv.Index(j) - if v.Kind() == reflect.Ptr && v.IsNil() { - // A nil message in a repeated field is not valid, - // but we can handle that more gracefully than panicking. - if _, err := w.Write([]byte("\n")); err != nil { - return err - } - continue - } - if err := tm.writeAny(w, v, props); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - continue - } - if fv.Kind() == reflect.Map { - // Map fields are rendered as a repeated struct with key/value fields. - keys := fv.MapKeys() - sort.Sort(mapKeys(keys)) - for _, key := range keys { - val := fv.MapIndex(key) - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - // open struct - if err := w.WriteByte('<'); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - // key - if _, err := w.WriteString("key:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, key, props.MapKeyProp); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - // nil values aren't legal, but we can avoid panicking because of them. - if val.Kind() != reflect.Ptr || !val.IsNil() { - // value - if _, err := w.WriteString("value:"); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, val, props.MapValProp); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - // close struct - w.unindent() - if err := w.WriteByte('>'); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - } - continue - } - if props.proto3 && fv.Kind() == reflect.Slice && fv.Len() == 0 { - // empty bytes field - continue - } - if fv.Kind() != reflect.Ptr && fv.Kind() != reflect.Slice { - // proto3 non-repeated scalar field; skip if zero value - if isProto3Zero(fv) { - continue - } - } - - if fv.Kind() == reflect.Interface { - // Check if it is a oneof. - if st.Field(i).Tag.Get("protobuf_oneof") != "" { - // fv is nil, or holds a pointer to generated struct. - // That generated struct has exactly one field, - // which has a protobuf struct tag. - if fv.IsNil() { - continue - } - inner := fv.Elem().Elem() // interface -> *T -> T - tag := inner.Type().Field(0).Tag.Get("protobuf") - props = new(Properties) // Overwrite the outer props var, but not its pointee. - props.Parse(tag) - // Write the value in the oneof, not the oneof itself. - fv = inner.Field(0) - - // Special case to cope with malformed messages gracefully: - // If the value in the oneof is a nil pointer, don't panic - // in writeAny. - if fv.Kind() == reflect.Ptr && fv.IsNil() { - // Use errors.New so writeAny won't render quotes. - msg := errors.New("/* nil */") - fv = reflect.ValueOf(&msg).Elem() - } - } - } - - if err := writeName(w, props); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - - // Enums have a String method, so writeAny will work fine. - if err := tm.writeAny(w, fv, props); err != nil { - return err - } - - if err := w.WriteByte('\n'); err != nil { - return err - } - } - - // Extensions (the XXX_extensions field). - pv := sv.Addr() - if _, err := extendable(pv.Interface()); err == nil { - if err := tm.writeExtensions(w, pv); err != nil { - return err - } - } - - return nil -} - -var textMarshalerType = reflect.TypeOf((*encoding.TextMarshaler)(nil)).Elem() - -// writeAny writes an arbitrary field. -func (tm *TextMarshaler) writeAny(w *textWriter, v reflect.Value, props *Properties) error { - v = reflect.Indirect(v) - - // Floats have special cases. - if v.Kind() == reflect.Float32 || v.Kind() == reflect.Float64 { - x := v.Float() - var b []byte - switch { - case math.IsInf(x, 1): - b = posInf - case math.IsInf(x, -1): - b = negInf - case math.IsNaN(x): - b = nan - } - if b != nil { - _, err := w.Write(b) - return err - } - // Other values are handled below. - } - - // We don't attempt to serialise every possible value type; only those - // that can occur in protocol buffers. - switch v.Kind() { - case reflect.Slice: - // Should only be a []byte; repeated fields are handled in writeStruct. - if err := writeString(w, string(v.Bytes())); err != nil { - return err - } - case reflect.String: - if err := writeString(w, v.String()); err != nil { - return err - } - case reflect.Struct: - // Required/optional group/message. - var bra, ket byte = '<', '>' - if props != nil && props.Wire == "group" { - bra, ket = '{', '}' - } - if err := w.WriteByte(bra); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte('\n'); err != nil { - return err - } - } - w.indent() - if v.CanAddr() { - // Calling v.Interface on a struct causes the reflect package to - // copy the entire struct. This is racy with the new Marshaler - // since we atomically update the XXX_sizecache. - // - // Thus, we retrieve a pointer to the struct if possible to avoid - // a race since v.Interface on the pointer doesn't copy the struct. - // - // If v is not addressable, then we are not worried about a race - // since it implies that the binary Marshaler cannot possibly be - // mutating this value. - v = v.Addr() - } - if v.Type().Implements(textMarshalerType) { - text, err := v.Interface().(encoding.TextMarshaler).MarshalText() - if err != nil { - return err - } - if _, err = w.Write(text); err != nil { - return err - } - } else { - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - if err := tm.writeStruct(w, v); err != nil { - return err - } - } - w.unindent() - if err := w.WriteByte(ket); err != nil { - return err - } - default: - _, err := fmt.Fprint(w, v.Interface()) - return err - } - return nil -} - -// equivalent to C's isprint. -func isprint(c byte) bool { - return c >= 0x20 && c < 0x7f -} - -// writeString writes a string in the protocol buffer text format. -// It is similar to strconv.Quote except we don't use Go escape sequences, -// we treat the string as a byte sequence, and we use octal escapes. -// These differences are to maintain interoperability with the other -// languages' implementations of the text format. -func writeString(w *textWriter, s string) error { - // use WriteByte here to get any needed indent - if err := w.WriteByte('"'); err != nil { - return err - } - // Loop over the bytes, not the runes. - for i := 0; i < len(s); i++ { - var err error - // Divergence from C++: we don't escape apostrophes. - // There's no need to escape them, and the C++ parser - // copes with a naked apostrophe. - switch c := s[i]; c { - case '\n': - _, err = w.w.Write(backslashN) - case '\r': - _, err = w.w.Write(backslashR) - case '\t': - _, err = w.w.Write(backslashT) - case '"': - _, err = w.w.Write(backslashDQ) - case '\\': - _, err = w.w.Write(backslashBS) - default: - if isprint(c) { - err = w.w.WriteByte(c) - } else { - _, err = fmt.Fprintf(w.w, "\\%03o", c) - } - } - if err != nil { - return err - } - } - return w.WriteByte('"') -} - -func writeUnknownStruct(w *textWriter, data []byte) (err error) { - if !w.compact { - if _, err := fmt.Fprintf(w, "/* %d unknown bytes */\n", len(data)); err != nil { - return err - } - } - b := NewBuffer(data) - for b.index < len(b.buf) { - x, err := b.DecodeVarint() - if err != nil { - _, err := fmt.Fprintf(w, "/* %v */\n", err) - return err - } - wire, tag := x&7, x>>3 - if wire == WireEndGroup { - w.unindent() - if _, err := w.Write(endBraceNewline); err != nil { - return err - } - continue - } - if _, err := fmt.Fprint(w, tag); err != nil { - return err - } - if wire != WireStartGroup { - if err := w.WriteByte(':'); err != nil { - return err - } - } - if !w.compact || wire == WireStartGroup { - if err := w.WriteByte(' '); err != nil { - return err - } - } - switch wire { - case WireBytes: - buf, e := b.DecodeRawBytes(false) - if e == nil { - _, err = fmt.Fprintf(w, "%q", buf) - } else { - _, err = fmt.Fprintf(w, "/* %v */", e) - } - case WireFixed32: - x, err = b.DecodeFixed32() - err = writeUnknownInt(w, x, err) - case WireFixed64: - x, err = b.DecodeFixed64() - err = writeUnknownInt(w, x, err) - case WireStartGroup: - err = w.WriteByte('{') - w.indent() - case WireVarint: - x, err = b.DecodeVarint() - err = writeUnknownInt(w, x, err) - default: - _, err = fmt.Fprintf(w, "/* unknown wire type %d */", wire) - } - if err != nil { - return err - } - if err = w.WriteByte('\n'); err != nil { - return err - } - } - return nil -} - -func writeUnknownInt(w *textWriter, x uint64, err error) error { - if err == nil { - _, err = fmt.Fprint(w, x) - } else { - _, err = fmt.Fprintf(w, "/* %v */", err) - } - return err -} - -type int32Slice []int32 - -func (s int32Slice) Len() int { return len(s) } -func (s int32Slice) Less(i, j int) bool { return s[i] < s[j] } -func (s int32Slice) Swap(i, j int) { s[i], s[j] = s[j], s[i] } - -// writeExtensions writes all the extensions in pv. -// pv is assumed to be a pointer to a protocol message struct that is extendable. -func (tm *TextMarshaler) writeExtensions(w *textWriter, pv reflect.Value) error { - emap := extensionMaps[pv.Type().Elem()] - ep, _ := extendable(pv.Interface()) - - // Order the extensions by ID. - // This isn't strictly necessary, but it will give us - // canonical output, which will also make testing easier. - m, mu := ep.extensionsRead() - if m == nil { - return nil - } - mu.Lock() - ids := make([]int32, 0, len(m)) - for id := range m { - ids = append(ids, id) - } - sort.Sort(int32Slice(ids)) - mu.Unlock() - - for _, extNum := range ids { - ext := m[extNum] - var desc *ExtensionDesc - if emap != nil { - desc = emap[extNum] - } - if desc == nil { - // Unknown extension. - if err := writeUnknownStruct(w, ext.enc); err != nil { - return err - } - continue - } - - pb, err := GetExtension(ep, desc) - if err != nil { - return fmt.Errorf("failed getting extension: %v", err) - } - - // Repeated extensions will appear as a slice. - if !desc.repeated() { - if err := tm.writeExtension(w, desc.Name, pb); err != nil { - return err - } - } else { - v := reflect.ValueOf(pb) - for i := 0; i < v.Len(); i++ { - if err := tm.writeExtension(w, desc.Name, v.Index(i).Interface()); err != nil { - return err - } - } - } - } - return nil -} - -func (tm *TextMarshaler) writeExtension(w *textWriter, name string, pb interface{}) error { - if _, err := fmt.Fprintf(w, "[%s]:", name); err != nil { - return err - } - if !w.compact { - if err := w.WriteByte(' '); err != nil { - return err - } - } - if err := tm.writeAny(w, reflect.ValueOf(pb), nil); err != nil { - return err - } - if err := w.WriteByte('\n'); err != nil { - return err - } - return nil -} - -func (w *textWriter) writeIndent() { - if !w.complete { - return - } - remain := w.ind * 2 - for remain > 0 { - n := remain - if n > len(spaces) { - n = len(spaces) - } - w.w.Write(spaces[:n]) - remain -= n - } - w.complete = false -} - -// TextMarshaler is a configurable text format marshaler. -type TextMarshaler struct { - Compact bool // use compact text format (one line). - ExpandAny bool // expand google.protobuf.Any messages of known types -} - -// Marshal writes a given protocol buffer in text format. -// The only errors returned are from w. -func (tm *TextMarshaler) Marshal(w io.Writer, pb Message) error { - val := reflect.ValueOf(pb) - if pb == nil || val.IsNil() { - w.Write([]byte("")) - return nil - } - var bw *bufio.Writer - ww, ok := w.(writer) - if !ok { - bw = bufio.NewWriter(w) - ww = bw - } - aw := &textWriter{ - w: ww, - complete: true, - compact: tm.Compact, - } - - if etm, ok := pb.(encoding.TextMarshaler); ok { - text, err := etm.MarshalText() - if err != nil { - return err - } - if _, err = aw.Write(text); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil - } - // Dereference the received pointer so we don't have outer < and >. - v := reflect.Indirect(val) - if err := tm.writeStruct(aw, v); err != nil { - return err - } - if bw != nil { - return bw.Flush() - } - return nil -} - -// Text is the same as Marshal, but returns the string directly. -func (tm *TextMarshaler) Text(pb Message) string { - var buf bytes.Buffer - tm.Marshal(&buf, pb) - return buf.String() -} - -var ( - defaultTextMarshaler = TextMarshaler{} - compactTextMarshaler = TextMarshaler{Compact: true} -) - -// TODO: consider removing some of the Marshal functions below. - -// MarshalText writes a given protocol buffer in text format. -// The only errors returned are from w. -func MarshalText(w io.Writer, pb Message) error { return defaultTextMarshaler.Marshal(w, pb) } - -// MarshalTextString is the same as MarshalText, but returns the string directly. -func MarshalTextString(pb Message) string { return defaultTextMarshaler.Text(pb) } - -// CompactText writes a given protocol buffer in compact text format (one line). -func CompactText(w io.Writer, pb Message) error { return compactTextMarshaler.Marshal(w, pb) } - -// CompactTextString is the same as CompactText, but returns the string directly. -func CompactTextString(pb Message) string { return compactTextMarshaler.Text(pb) } diff --git a/vendor/github.com/golang/protobuf/proto/text_decode.go b/vendor/github.com/golang/protobuf/proto/text_decode.go new file mode 100644 index 000000000..47eb3e445 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/text_decode.go @@ -0,0 +1,801 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "encoding" + "errors" + "fmt" + "reflect" + "strconv" + "strings" + "unicode/utf8" + + "google.golang.org/protobuf/encoding/prototext" + protoV2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" +) + +const wrapTextUnmarshalV2 = false + +// ParseError is returned by UnmarshalText. +type ParseError struct { + Message string + + // Deprecated: Do not use. + Line, Offset int +} + +func (e *ParseError) Error() string { + if wrapTextUnmarshalV2 { + return e.Message + } + if e.Line == 1 { + return fmt.Sprintf("line 1.%d: %v", e.Offset, e.Message) + } + return fmt.Sprintf("line %d: %v", e.Line, e.Message) +} + +// UnmarshalText parses a proto text formatted string into m. +func UnmarshalText(s string, m Message) error { + if u, ok := m.(encoding.TextUnmarshaler); ok { + return u.UnmarshalText([]byte(s)) + } + + m.Reset() + mi := MessageV2(m) + + if wrapTextUnmarshalV2 { + err := prototext.UnmarshalOptions{ + AllowPartial: true, + }.Unmarshal([]byte(s), mi) + if err != nil { + return &ParseError{Message: err.Error()} + } + return checkRequiredNotSet(mi) + } else { + if err := newTextParser(s).unmarshalMessage(mi.ProtoReflect(), ""); err != nil { + return err + } + return checkRequiredNotSet(mi) + } +} + +type textParser struct { + s string // remaining input + done bool // whether the parsing is finished (success or error) + backed bool // whether back() was called + offset, line int + cur token +} + +type token struct { + value string + err *ParseError + line int // line number + offset int // byte number from start of input, not start of line + unquoted string // the unquoted version of value, if it was a quoted string +} + +func newTextParser(s string) *textParser { + p := new(textParser) + p.s = s + p.line = 1 + p.cur.line = 1 + return p +} + +func (p *textParser) unmarshalMessage(m protoreflect.Message, terminator string) (err error) { + md := m.Descriptor() + fds := md.Fields() + + // A struct is a sequence of "name: value", terminated by one of + // '>' or '}', or the end of the input. A name may also be + // "[extension]" or "[type/url]". + // + // The whole struct can also be an expanded Any message, like: + // [type/url] < ... struct contents ... > + seen := make(map[protoreflect.FieldNumber]bool) + for { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value == terminator { + break + } + if tok.value == "[" { + if err := p.unmarshalExtensionOrAny(m, seen); err != nil { + return err + } + continue + } + + // This is a normal, non-extension field. + name := protoreflect.Name(tok.value) + fd := fds.ByName(name) + switch { + case fd == nil: + gd := fds.ByName(protoreflect.Name(strings.ToLower(string(name)))) + if gd != nil && gd.Kind() == protoreflect.GroupKind && gd.Message().Name() == name { + fd = gd + } + case fd.Kind() == protoreflect.GroupKind && fd.Message().Name() != name: + fd = nil + case fd.IsWeak() && fd.Message().IsPlaceholder(): + fd = nil + } + if fd == nil { + typeName := string(md.FullName()) + if m, ok := m.Interface().(Message); ok { + t := reflect.TypeOf(m) + if t.Kind() == reflect.Ptr { + typeName = t.Elem().String() + } + } + return p.errorf("unknown field name %q in %v", name, typeName) + } + if od := fd.ContainingOneof(); od != nil && m.WhichOneof(od) != nil { + return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, od.Name()) + } + if fd.Cardinality() != protoreflect.Repeated && seen[fd.Number()] { + return p.errorf("non-repeated field %q was repeated", fd.Name()) + } + seen[fd.Number()] = true + + // Consume any colon. + if err := p.checkForColon(fd); err != nil { + return err + } + + // Parse into the field. + v := m.Get(fd) + if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) { + v = m.Mutable(fd) + } + if v, err = p.unmarshalValue(v, fd); err != nil { + return err + } + m.Set(fd, v) + + if err := p.consumeOptionalSeparator(); err != nil { + return err + } + } + return nil +} + +func (p *textParser) unmarshalExtensionOrAny(m protoreflect.Message, seen map[protoreflect.FieldNumber]bool) error { + name, err := p.consumeExtensionOrAnyName() + if err != nil { + return err + } + + // If it contains a slash, it's an Any type URL. + if slashIdx := strings.LastIndex(name, "/"); slashIdx >= 0 { + tok := p.next() + if tok.err != nil { + return tok.err + } + // consume an optional colon + if tok.value == ":" { + tok = p.next() + if tok.err != nil { + return tok.err + } + } + + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return p.errorf("expected '{' or '<', found %q", tok.value) + } + + mt, err := protoregistry.GlobalTypes.FindMessageByURL(name) + if err != nil { + return p.errorf("unrecognized message %q in google.protobuf.Any", name[slashIdx+len("/"):]) + } + m2 := mt.New() + if err := p.unmarshalMessage(m2, terminator); err != nil { + return err + } + b, err := protoV2.Marshal(m2.Interface()) + if err != nil { + return p.errorf("failed to marshal message of type %q: %v", name[slashIdx+len("/"):], err) + } + + urlFD := m.Descriptor().Fields().ByName("type_url") + valFD := m.Descriptor().Fields().ByName("value") + if seen[urlFD.Number()] { + return p.errorf("Any message unpacked multiple times, or %q already set", urlFD.Name()) + } + if seen[valFD.Number()] { + return p.errorf("Any message unpacked multiple times, or %q already set", valFD.Name()) + } + m.Set(urlFD, protoreflect.ValueOfString(name)) + m.Set(valFD, protoreflect.ValueOfBytes(b)) + seen[urlFD.Number()] = true + seen[valFD.Number()] = true + return nil + } + + xname := protoreflect.FullName(name) + xt, _ := protoregistry.GlobalTypes.FindExtensionByName(xname) + if xt == nil && isMessageSet(m.Descriptor()) { + xt, _ = protoregistry.GlobalTypes.FindExtensionByName(xname.Append("message_set_extension")) + } + if xt == nil { + return p.errorf("unrecognized extension %q", name) + } + fd := xt.TypeDescriptor() + if fd.ContainingMessage().FullName() != m.Descriptor().FullName() { + return p.errorf("extension field %q does not extend message %q", name, m.Descriptor().FullName()) + } + + if err := p.checkForColon(fd); err != nil { + return err + } + + v := m.Get(fd) + if !m.Has(fd) && (fd.IsList() || fd.IsMap() || fd.Message() != nil) { + v = m.Mutable(fd) + } + v, err = p.unmarshalValue(v, fd) + if err != nil { + return err + } + m.Set(fd, v) + return p.consumeOptionalSeparator() +} + +func (p *textParser) unmarshalValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { + tok := p.next() + if tok.err != nil { + return v, tok.err + } + if tok.value == "" { + return v, p.errorf("unexpected EOF") + } + + switch { + case fd.IsList(): + lv := v.List() + var err error + if tok.value == "[" { + // Repeated field with list notation, like [1,2,3]. + for { + vv := lv.NewElement() + vv, err = p.unmarshalSingularValue(vv, fd) + if err != nil { + return v, err + } + lv.Append(vv) + + tok := p.next() + if tok.err != nil { + return v, tok.err + } + if tok.value == "]" { + break + } + if tok.value != "," { + return v, p.errorf("Expected ']' or ',' found %q", tok.value) + } + } + return v, nil + } + + // One value of the repeated field. + p.back() + vv := lv.NewElement() + vv, err = p.unmarshalSingularValue(vv, fd) + if err != nil { + return v, err + } + lv.Append(vv) + return v, nil + case fd.IsMap(): + // The map entry should be this sequence of tokens: + // < key : KEY value : VALUE > + // However, implementations may omit key or value, and technically + // we should support them in any order. + var terminator string + switch tok.value { + case "<": + terminator = ">" + case "{": + terminator = "}" + default: + return v, p.errorf("expected '{' or '<', found %q", tok.value) + } + + keyFD := fd.MapKey() + valFD := fd.MapValue() + + mv := v.Map() + kv := keyFD.Default() + vv := mv.NewValue() + for { + tok := p.next() + if tok.err != nil { + return v, tok.err + } + if tok.value == terminator { + break + } + var err error + switch tok.value { + case "key": + if err := p.consumeToken(":"); err != nil { + return v, err + } + if kv, err = p.unmarshalSingularValue(kv, keyFD); err != nil { + return v, err + } + if err := p.consumeOptionalSeparator(); err != nil { + return v, err + } + case "value": + if err := p.checkForColon(valFD); err != nil { + return v, err + } + if vv, err = p.unmarshalSingularValue(vv, valFD); err != nil { + return v, err + } + if err := p.consumeOptionalSeparator(); err != nil { + return v, err + } + default: + p.back() + return v, p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) + } + } + mv.Set(kv.MapKey(), vv) + return v, nil + default: + p.back() + return p.unmarshalSingularValue(v, fd) + } +} + +func (p *textParser) unmarshalSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) (protoreflect.Value, error) { + tok := p.next() + if tok.err != nil { + return v, tok.err + } + if tok.value == "" { + return v, p.errorf("unexpected EOF") + } + + switch fd.Kind() { + case protoreflect.BoolKind: + switch tok.value { + case "true", "1", "t", "True": + return protoreflect.ValueOfBool(true), nil + case "false", "0", "f", "False": + return protoreflect.ValueOfBool(false), nil + } + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind: + if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { + return protoreflect.ValueOfInt32(int32(x)), nil + } + + // The C++ parser accepts large positive hex numbers that uses + // two's complement arithmetic to represent negative numbers. + // This feature is here for backwards compatibility with C++. + if strings.HasPrefix(tok.value, "0x") { + if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { + return protoreflect.ValueOfInt32(int32(-(int64(^x) + 1))), nil + } + } + case protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { + return protoreflect.ValueOfInt64(int64(x)), nil + } + + // The C++ parser accepts large positive hex numbers that uses + // two's complement arithmetic to represent negative numbers. + // This feature is here for backwards compatibility with C++. + if strings.HasPrefix(tok.value, "0x") { + if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { + return protoreflect.ValueOfInt64(int64(-(int64(^x) + 1))), nil + } + } + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind: + if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { + return protoreflect.ValueOfUint32(uint32(x)), nil + } + case protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { + return protoreflect.ValueOfUint64(uint64(x)), nil + } + case protoreflect.FloatKind: + // Ignore 'f' for compatibility with output generated by C++, + // but don't remove 'f' when the value is "-inf" or "inf". + v := tok.value + if strings.HasSuffix(v, "f") && v != "-inf" && v != "inf" { + v = v[:len(v)-len("f")] + } + if x, err := strconv.ParseFloat(v, 32); err == nil { + return protoreflect.ValueOfFloat32(float32(x)), nil + } + case protoreflect.DoubleKind: + // Ignore 'f' for compatibility with output generated by C++, + // but don't remove 'f' when the value is "-inf" or "inf". + v := tok.value + if strings.HasSuffix(v, "f") && v != "-inf" && v != "inf" { + v = v[:len(v)-len("f")] + } + if x, err := strconv.ParseFloat(v, 64); err == nil { + return protoreflect.ValueOfFloat64(float64(x)), nil + } + case protoreflect.StringKind: + if isQuote(tok.value[0]) { + return protoreflect.ValueOfString(tok.unquoted), nil + } + case protoreflect.BytesKind: + if isQuote(tok.value[0]) { + return protoreflect.ValueOfBytes([]byte(tok.unquoted)), nil + } + case protoreflect.EnumKind: + if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { + return protoreflect.ValueOfEnum(protoreflect.EnumNumber(x)), nil + } + vd := fd.Enum().Values().ByName(protoreflect.Name(tok.value)) + if vd != nil { + return protoreflect.ValueOfEnum(vd.Number()), nil + } + case protoreflect.MessageKind, protoreflect.GroupKind: + var terminator string + switch tok.value { + case "{": + terminator = "}" + case "<": + terminator = ">" + default: + return v, p.errorf("expected '{' or '<', found %q", tok.value) + } + err := p.unmarshalMessage(v.Message(), terminator) + return v, err + default: + panic(fmt.Sprintf("invalid kind %v", fd.Kind())) + } + return v, p.errorf("invalid %v: %v", fd.Kind(), tok.value) +} + +// Consume a ':' from the input stream (if the next token is a colon), +// returning an error if a colon is needed but not present. +func (p *textParser) checkForColon(fd protoreflect.FieldDescriptor) *ParseError { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ":" { + if fd.Message() == nil { + return p.errorf("expected ':', found %q", tok.value) + } + p.back() + } + return nil +} + +// consumeExtensionOrAnyName consumes an extension name or an Any type URL and +// the following ']'. It returns the name or URL consumed. +func (p *textParser) consumeExtensionOrAnyName() (string, error) { + tok := p.next() + if tok.err != nil { + return "", tok.err + } + + // If extension name or type url is quoted, it's a single token. + if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { + name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) + if err != nil { + return "", err + } + return name, p.consumeToken("]") + } + + // Consume everything up to "]" + var parts []string + for tok.value != "]" { + parts = append(parts, tok.value) + tok = p.next() + if tok.err != nil { + return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) + } + if p.done && tok.value != "]" { + return "", p.errorf("unclosed type_url or extension name") + } + } + return strings.Join(parts, ""), nil +} + +// consumeOptionalSeparator consumes an optional semicolon or comma. +// It is used in unmarshalMessage to provide backward compatibility. +func (p *textParser) consumeOptionalSeparator() error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != ";" && tok.value != "," { + p.back() + } + return nil +} + +func (p *textParser) errorf(format string, a ...interface{}) *ParseError { + pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} + p.cur.err = pe + p.done = true + return pe +} + +func (p *textParser) skipWhitespace() { + i := 0 + for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { + if p.s[i] == '#' { + // comment; skip to end of line or input + for i < len(p.s) && p.s[i] != '\n' { + i++ + } + if i == len(p.s) { + break + } + } + if p.s[i] == '\n' { + p.line++ + } + i++ + } + p.offset += i + p.s = p.s[i:len(p.s)] + if len(p.s) == 0 { + p.done = true + } +} + +func (p *textParser) advance() { + // Skip whitespace + p.skipWhitespace() + if p.done { + return + } + + // Start of non-whitespace + p.cur.err = nil + p.cur.offset, p.cur.line = p.offset, p.line + p.cur.unquoted = "" + switch p.s[0] { + case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': + // Single symbol + p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] + case '"', '\'': + // Quoted string + i := 1 + for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { + if p.s[i] == '\\' && i+1 < len(p.s) { + // skip escaped char + i++ + } + i++ + } + if i >= len(p.s) || p.s[i] != p.s[0] { + p.errorf("unmatched quote") + return + } + unq, err := unquoteC(p.s[1:i], rune(p.s[0])) + if err != nil { + p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) + return + } + p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] + p.cur.unquoted = unq + default: + i := 0 + for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { + i++ + } + if i == 0 { + p.errorf("unexpected byte %#x", p.s[0]) + return + } + p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] + } + p.offset += len(p.cur.value) +} + +// Back off the parser by one token. Can only be done between calls to next(). +// It makes the next advance() a no-op. +func (p *textParser) back() { p.backed = true } + +// Advances the parser and returns the new current token. +func (p *textParser) next() *token { + if p.backed || p.done { + p.backed = false + return &p.cur + } + p.advance() + if p.done { + p.cur.value = "" + } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { + // Look for multiple quoted strings separated by whitespace, + // and concatenate them. + cat := p.cur + for { + p.skipWhitespace() + if p.done || !isQuote(p.s[0]) { + break + } + p.advance() + if p.cur.err != nil { + return &p.cur + } + cat.value += " " + p.cur.value + cat.unquoted += p.cur.unquoted + } + p.done = false // parser may have seen EOF, but we want to return cat + p.cur = cat + } + return &p.cur +} + +func (p *textParser) consumeToken(s string) error { + tok := p.next() + if tok.err != nil { + return tok.err + } + if tok.value != s { + p.back() + return p.errorf("expected %q, found %q", s, tok.value) + } + return nil +} + +var errBadUTF8 = errors.New("proto: bad UTF-8") + +func unquoteC(s string, quote rune) (string, error) { + // This is based on C++'s tokenizer.cc. + // Despite its name, this is *not* parsing C syntax. + // For instance, "\0" is an invalid quoted string. + + // Avoid allocation in trivial cases. + simple := true + for _, r := range s { + if r == '\\' || r == quote { + simple = false + break + } + } + if simple { + return s, nil + } + + buf := make([]byte, 0, 3*len(s)/2) + for len(s) > 0 { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", errBadUTF8 + } + s = s[n:] + if r != '\\' { + if r < utf8.RuneSelf { + buf = append(buf, byte(r)) + } else { + buf = append(buf, string(r)...) + } + continue + } + + ch, tail, err := unescape(s) + if err != nil { + return "", err + } + buf = append(buf, ch...) + s = tail + } + return string(buf), nil +} + +func unescape(s string) (ch string, tail string, err error) { + r, n := utf8.DecodeRuneInString(s) + if r == utf8.RuneError && n == 1 { + return "", "", errBadUTF8 + } + s = s[n:] + switch r { + case 'a': + return "\a", s, nil + case 'b': + return "\b", s, nil + case 'f': + return "\f", s, nil + case 'n': + return "\n", s, nil + case 'r': + return "\r", s, nil + case 't': + return "\t", s, nil + case 'v': + return "\v", s, nil + case '?': + return "?", s, nil // trigraph workaround + case '\'', '"', '\\': + return string(r), s, nil + case '0', '1', '2', '3', '4', '5', '6', '7': + if len(s) < 2 { + return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) + } + ss := string(r) + s[:2] + s = s[2:] + i, err := strconv.ParseUint(ss, 8, 8) + if err != nil { + return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) + } + return string([]byte{byte(i)}), s, nil + case 'x', 'X', 'u', 'U': + var n int + switch r { + case 'x', 'X': + n = 2 + case 'u': + n = 4 + case 'U': + n = 8 + } + if len(s) < n { + return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) + } + ss := s[:n] + s = s[n:] + i, err := strconv.ParseUint(ss, 16, 64) + if err != nil { + return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) + } + if r == 'x' || r == 'X' { + return string([]byte{byte(i)}), s, nil + } + if i > utf8.MaxRune { + return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) + } + return string(rune(i)), s, nil + } + return "", "", fmt.Errorf(`unknown escape \%c`, r) +} + +func isIdentOrNumberChar(c byte) bool { + switch { + case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': + return true + case '0' <= c && c <= '9': + return true + } + switch c { + case '-', '+', '.', '_': + return true + } + return false +} + +func isWhitespace(c byte) bool { + switch c { + case ' ', '\t', '\n', '\r': + return true + } + return false +} + +func isQuote(c byte) bool { + switch c { + case '"', '\'': + return true + } + return false +} diff --git a/vendor/github.com/golang/protobuf/proto/text_encode.go b/vendor/github.com/golang/protobuf/proto/text_encode.go new file mode 100644 index 000000000..a31134eeb --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/text_encode.go @@ -0,0 +1,560 @@ +// Copyright 2010 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + "bytes" + "encoding" + "fmt" + "io" + "math" + "sort" + "strings" + + "google.golang.org/protobuf/encoding/prototext" + "google.golang.org/protobuf/encoding/protowire" + "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" +) + +const wrapTextMarshalV2 = false + +// TextMarshaler is a configurable text format marshaler. +type TextMarshaler struct { + Compact bool // use compact text format (one line) + ExpandAny bool // expand google.protobuf.Any messages of known types +} + +// Marshal writes the proto text format of m to w. +func (tm *TextMarshaler) Marshal(w io.Writer, m Message) error { + b, err := tm.marshal(m) + if len(b) > 0 { + if _, err := w.Write(b); err != nil { + return err + } + } + return err +} + +// Text returns a proto text formatted string of m. +func (tm *TextMarshaler) Text(m Message) string { + b, _ := tm.marshal(m) + return string(b) +} + +func (tm *TextMarshaler) marshal(m Message) ([]byte, error) { + mr := MessageReflect(m) + if mr == nil || !mr.IsValid() { + return []byte(""), nil + } + + if wrapTextMarshalV2 { + if m, ok := m.(encoding.TextMarshaler); ok { + return m.MarshalText() + } + + opts := prototext.MarshalOptions{ + AllowPartial: true, + EmitUnknown: true, + } + if !tm.Compact { + opts.Indent = " " + } + if !tm.ExpandAny { + opts.Resolver = (*protoregistry.Types)(nil) + } + return opts.Marshal(mr.Interface()) + } else { + w := &textWriter{ + compact: tm.Compact, + expandAny: tm.ExpandAny, + complete: true, + } + + if m, ok := m.(encoding.TextMarshaler); ok { + b, err := m.MarshalText() + if err != nil { + return nil, err + } + w.Write(b) + return w.buf, nil + } + + err := w.writeMessage(mr) + return w.buf, err + } +} + +var ( + defaultTextMarshaler = TextMarshaler{} + compactTextMarshaler = TextMarshaler{Compact: true} +) + +// MarshalText writes the proto text format of m to w. +func MarshalText(w io.Writer, m Message) error { return defaultTextMarshaler.Marshal(w, m) } + +// MarshalTextString returns a proto text formatted string of m. +func MarshalTextString(m Message) string { return defaultTextMarshaler.Text(m) } + +// CompactText writes the compact proto text format of m to w. +func CompactText(w io.Writer, m Message) error { return compactTextMarshaler.Marshal(w, m) } + +// CompactTextString returns a compact proto text formatted string of m. +func CompactTextString(m Message) string { return compactTextMarshaler.Text(m) } + +var ( + newline = []byte("\n") + endBraceNewline = []byte("}\n") + posInf = []byte("inf") + negInf = []byte("-inf") + nan = []byte("nan") +) + +// textWriter is an io.Writer that tracks its indentation level. +type textWriter struct { + compact bool // same as TextMarshaler.Compact + expandAny bool // same as TextMarshaler.ExpandAny + complete bool // whether the current position is a complete line + indent int // indentation level; never negative + buf []byte +} + +func (w *textWriter) Write(p []byte) (n int, _ error) { + newlines := bytes.Count(p, newline) + if newlines == 0 { + if !w.compact && w.complete { + w.writeIndent() + } + w.buf = append(w.buf, p...) + w.complete = false + return len(p), nil + } + + frags := bytes.SplitN(p, newline, newlines+1) + if w.compact { + for i, frag := range frags { + if i > 0 { + w.buf = append(w.buf, ' ') + n++ + } + w.buf = append(w.buf, frag...) + n += len(frag) + } + return n, nil + } + + for i, frag := range frags { + if w.complete { + w.writeIndent() + } + w.buf = append(w.buf, frag...) + n += len(frag) + if i+1 < len(frags) { + w.buf = append(w.buf, '\n') + n++ + } + } + w.complete = len(frags[len(frags)-1]) == 0 + return n, nil +} + +func (w *textWriter) WriteByte(c byte) error { + if w.compact && c == '\n' { + c = ' ' + } + if !w.compact && w.complete { + w.writeIndent() + } + w.buf = append(w.buf, c) + w.complete = c == '\n' + return nil +} + +func (w *textWriter) writeName(fd protoreflect.FieldDescriptor) { + if !w.compact && w.complete { + w.writeIndent() + } + w.complete = false + + if fd.Kind() != protoreflect.GroupKind { + w.buf = append(w.buf, fd.Name()...) + w.WriteByte(':') + } else { + // Use message type name for group field name. + w.buf = append(w.buf, fd.Message().Name()...) + } + + if !w.compact { + w.WriteByte(' ') + } +} + +func requiresQuotes(u string) bool { + // When type URL contains any characters except [0-9A-Za-z./\-]*, it must be quoted. + for _, ch := range u { + switch { + case ch == '.' || ch == '/' || ch == '_': + continue + case '0' <= ch && ch <= '9': + continue + case 'A' <= ch && ch <= 'Z': + continue + case 'a' <= ch && ch <= 'z': + continue + default: + return true + } + } + return false +} + +// writeProto3Any writes an expanded google.protobuf.Any message. +// +// It returns (false, nil) if sv value can't be unmarshaled (e.g. because +// required messages are not linked in). +// +// It returns (true, error) when sv was written in expanded format or an error +// was encountered. +func (w *textWriter) writeProto3Any(m protoreflect.Message) (bool, error) { + md := m.Descriptor() + fdURL := md.Fields().ByName("type_url") + fdVal := md.Fields().ByName("value") + + url := m.Get(fdURL).String() + mt, err := protoregistry.GlobalTypes.FindMessageByURL(url) + if err != nil { + return false, nil + } + + b := m.Get(fdVal).Bytes() + m2 := mt.New() + if err := proto.Unmarshal(b, m2.Interface()); err != nil { + return false, nil + } + w.Write([]byte("[")) + if requiresQuotes(url) { + w.writeQuotedString(url) + } else { + w.Write([]byte(url)) + } + if w.compact { + w.Write([]byte("]:<")) + } else { + w.Write([]byte("]: <\n")) + w.indent++ + } + if err := w.writeMessage(m2); err != nil { + return true, err + } + if w.compact { + w.Write([]byte("> ")) + } else { + w.indent-- + w.Write([]byte(">\n")) + } + return true, nil +} + +func (w *textWriter) writeMessage(m protoreflect.Message) error { + md := m.Descriptor() + if w.expandAny && md.FullName() == "google.protobuf.Any" { + if canExpand, err := w.writeProto3Any(m); canExpand { + return err + } + } + + fds := md.Fields() + for i := 0; i < fds.Len(); { + fd := fds.Get(i) + if od := fd.ContainingOneof(); od != nil { + fd = m.WhichOneof(od) + i += od.Fields().Len() + } else { + i++ + } + if fd == nil || !m.Has(fd) { + continue + } + + switch { + case fd.IsList(): + lv := m.Get(fd).List() + for j := 0; j < lv.Len(); j++ { + w.writeName(fd) + v := lv.Get(j) + if err := w.writeSingularValue(v, fd); err != nil { + return err + } + w.WriteByte('\n') + } + case fd.IsMap(): + kfd := fd.MapKey() + vfd := fd.MapValue() + mv := m.Get(fd).Map() + + type entry struct{ key, val protoreflect.Value } + var entries []entry + mv.Range(func(k protoreflect.MapKey, v protoreflect.Value) bool { + entries = append(entries, entry{k.Value(), v}) + return true + }) + sort.Slice(entries, func(i, j int) bool { + switch kfd.Kind() { + case protoreflect.BoolKind: + return !entries[i].key.Bool() && entries[j].key.Bool() + case protoreflect.Int32Kind, protoreflect.Sint32Kind, protoreflect.Sfixed32Kind, protoreflect.Int64Kind, protoreflect.Sint64Kind, protoreflect.Sfixed64Kind: + return entries[i].key.Int() < entries[j].key.Int() + case protoreflect.Uint32Kind, protoreflect.Fixed32Kind, protoreflect.Uint64Kind, protoreflect.Fixed64Kind: + return entries[i].key.Uint() < entries[j].key.Uint() + case protoreflect.StringKind: + return entries[i].key.String() < entries[j].key.String() + default: + panic("invalid kind") + } + }) + for _, entry := range entries { + w.writeName(fd) + w.WriteByte('<') + if !w.compact { + w.WriteByte('\n') + } + w.indent++ + w.writeName(kfd) + if err := w.writeSingularValue(entry.key, kfd); err != nil { + return err + } + w.WriteByte('\n') + w.writeName(vfd) + if err := w.writeSingularValue(entry.val, vfd); err != nil { + return err + } + w.WriteByte('\n') + w.indent-- + w.WriteByte('>') + w.WriteByte('\n') + } + default: + w.writeName(fd) + if err := w.writeSingularValue(m.Get(fd), fd); err != nil { + return err + } + w.WriteByte('\n') + } + } + + if b := m.GetUnknown(); len(b) > 0 { + w.writeUnknownFields(b) + } + return w.writeExtensions(m) +} + +func (w *textWriter) writeSingularValue(v protoreflect.Value, fd protoreflect.FieldDescriptor) error { + switch fd.Kind() { + case protoreflect.FloatKind, protoreflect.DoubleKind: + switch vf := v.Float(); { + case math.IsInf(vf, +1): + w.Write(posInf) + case math.IsInf(vf, -1): + w.Write(negInf) + case math.IsNaN(vf): + w.Write(nan) + default: + fmt.Fprint(w, v.Interface()) + } + case protoreflect.StringKind: + // NOTE: This does not validate UTF-8 for historical reasons. + w.writeQuotedString(string(v.String())) + case protoreflect.BytesKind: + w.writeQuotedString(string(v.Bytes())) + case protoreflect.MessageKind, protoreflect.GroupKind: + var bra, ket byte = '<', '>' + if fd.Kind() == protoreflect.GroupKind { + bra, ket = '{', '}' + } + w.WriteByte(bra) + if !w.compact { + w.WriteByte('\n') + } + w.indent++ + m := v.Message() + if m2, ok := m.Interface().(encoding.TextMarshaler); ok { + b, err := m2.MarshalText() + if err != nil { + return err + } + w.Write(b) + } else { + w.writeMessage(m) + } + w.indent-- + w.WriteByte(ket) + case protoreflect.EnumKind: + if ev := fd.Enum().Values().ByNumber(v.Enum()); ev != nil { + fmt.Fprint(w, ev.Name()) + } else { + fmt.Fprint(w, v.Enum()) + } + default: + fmt.Fprint(w, v.Interface()) + } + return nil +} + +// writeQuotedString writes a quoted string in the protocol buffer text format. +func (w *textWriter) writeQuotedString(s string) { + w.WriteByte('"') + for i := 0; i < len(s); i++ { + switch c := s[i]; c { + case '\n': + w.buf = append(w.buf, `\n`...) + case '\r': + w.buf = append(w.buf, `\r`...) + case '\t': + w.buf = append(w.buf, `\t`...) + case '"': + w.buf = append(w.buf, `\"`...) + case '\\': + w.buf = append(w.buf, `\\`...) + default: + if isPrint := c >= 0x20 && c < 0x7f; isPrint { + w.buf = append(w.buf, c) + } else { + w.buf = append(w.buf, fmt.Sprintf(`\%03o`, c)...) + } + } + } + w.WriteByte('"') +} + +func (w *textWriter) writeUnknownFields(b []byte) { + if !w.compact { + fmt.Fprintf(w, "/* %d unknown bytes */\n", len(b)) + } + + for len(b) > 0 { + num, wtyp, n := protowire.ConsumeTag(b) + if n < 0 { + return + } + b = b[n:] + + if wtyp == protowire.EndGroupType { + w.indent-- + w.Write(endBraceNewline) + continue + } + fmt.Fprint(w, num) + if wtyp != protowire.StartGroupType { + w.WriteByte(':') + } + if !w.compact || wtyp == protowire.StartGroupType { + w.WriteByte(' ') + } + switch wtyp { + case protowire.VarintType: + v, n := protowire.ConsumeVarint(b) + if n < 0 { + return + } + b = b[n:] + fmt.Fprint(w, v) + case protowire.Fixed32Type: + v, n := protowire.ConsumeFixed32(b) + if n < 0 { + return + } + b = b[n:] + fmt.Fprint(w, v) + case protowire.Fixed64Type: + v, n := protowire.ConsumeFixed64(b) + if n < 0 { + return + } + b = b[n:] + fmt.Fprint(w, v) + case protowire.BytesType: + v, n := protowire.ConsumeBytes(b) + if n < 0 { + return + } + b = b[n:] + fmt.Fprintf(w, "%q", v) + case protowire.StartGroupType: + w.WriteByte('{') + w.indent++ + default: + fmt.Fprintf(w, "/* unknown wire type %d */", wtyp) + } + w.WriteByte('\n') + } +} + +// writeExtensions writes all the extensions in m. +func (w *textWriter) writeExtensions(m protoreflect.Message) error { + md := m.Descriptor() + if md.ExtensionRanges().Len() == 0 { + return nil + } + + type ext struct { + desc protoreflect.FieldDescriptor + val protoreflect.Value + } + var exts []ext + m.Range(func(fd protoreflect.FieldDescriptor, v protoreflect.Value) bool { + if fd.IsExtension() { + exts = append(exts, ext{fd, v}) + } + return true + }) + sort.Slice(exts, func(i, j int) bool { + return exts[i].desc.Number() < exts[j].desc.Number() + }) + + for _, ext := range exts { + // For message set, use the name of the message as the extension name. + name := string(ext.desc.FullName()) + if isMessageSet(ext.desc.ContainingMessage()) { + name = strings.TrimSuffix(name, ".message_set_extension") + } + + if !ext.desc.IsList() { + if err := w.writeSingularExtension(name, ext.val, ext.desc); err != nil { + return err + } + } else { + lv := ext.val.List() + for i := 0; i < lv.Len(); i++ { + if err := w.writeSingularExtension(name, lv.Get(i), ext.desc); err != nil { + return err + } + } + } + } + return nil +} + +func (w *textWriter) writeSingularExtension(name string, v protoreflect.Value, fd protoreflect.FieldDescriptor) error { + fmt.Fprintf(w, "[%s]:", name) + if !w.compact { + w.WriteByte(' ') + } + if err := w.writeSingularValue(v, fd); err != nil { + return err + } + w.WriteByte('\n') + return nil +} + +func (w *textWriter) writeIndent() { + if !w.complete { + return + } + for i := 0; i < w.indent*2; i++ { + w.buf = append(w.buf, ' ') + } + w.complete = false +} diff --git a/vendor/github.com/golang/protobuf/proto/text_parser.go b/vendor/github.com/golang/protobuf/proto/text_parser.go deleted file mode 100644 index bb55a3af2..000000000 --- a/vendor/github.com/golang/protobuf/proto/text_parser.go +++ /dev/null @@ -1,880 +0,0 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2010 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -package proto - -// Functions for parsing the Text protocol buffer format. -// TODO: message sets. - -import ( - "encoding" - "errors" - "fmt" - "reflect" - "strconv" - "strings" - "unicode/utf8" -) - -// Error string emitted when deserializing Any and fields are already set -const anyRepeatedlyUnpacked = "Any message unpacked multiple times, or %q already set" - -type ParseError struct { - Message string - Line int // 1-based line number - Offset int // 0-based byte offset from start of input -} - -func (p *ParseError) Error() string { - if p.Line == 1 { - // show offset only for first line - return fmt.Sprintf("line 1.%d: %v", p.Offset, p.Message) - } - return fmt.Sprintf("line %d: %v", p.Line, p.Message) -} - -type token struct { - value string - err *ParseError - line int // line number - offset int // byte number from start of input, not start of line - unquoted string // the unquoted version of value, if it was a quoted string -} - -func (t *token) String() string { - if t.err == nil { - return fmt.Sprintf("%q (line=%d, offset=%d)", t.value, t.line, t.offset) - } - return fmt.Sprintf("parse error: %v", t.err) -} - -type textParser struct { - s string // remaining input - done bool // whether the parsing is finished (success or error) - backed bool // whether back() was called - offset, line int - cur token -} - -func newTextParser(s string) *textParser { - p := new(textParser) - p.s = s - p.line = 1 - p.cur.line = 1 - return p -} - -func (p *textParser) errorf(format string, a ...interface{}) *ParseError { - pe := &ParseError{fmt.Sprintf(format, a...), p.cur.line, p.cur.offset} - p.cur.err = pe - p.done = true - return pe -} - -// Numbers and identifiers are matched by [-+._A-Za-z0-9] -func isIdentOrNumberChar(c byte) bool { - switch { - case 'A' <= c && c <= 'Z', 'a' <= c && c <= 'z': - return true - case '0' <= c && c <= '9': - return true - } - switch c { - case '-', '+', '.', '_': - return true - } - return false -} - -func isWhitespace(c byte) bool { - switch c { - case ' ', '\t', '\n', '\r': - return true - } - return false -} - -func isQuote(c byte) bool { - switch c { - case '"', '\'': - return true - } - return false -} - -func (p *textParser) skipWhitespace() { - i := 0 - for i < len(p.s) && (isWhitespace(p.s[i]) || p.s[i] == '#') { - if p.s[i] == '#' { - // comment; skip to end of line or input - for i < len(p.s) && p.s[i] != '\n' { - i++ - } - if i == len(p.s) { - break - } - } - if p.s[i] == '\n' { - p.line++ - } - i++ - } - p.offset += i - p.s = p.s[i:len(p.s)] - if len(p.s) == 0 { - p.done = true - } -} - -func (p *textParser) advance() { - // Skip whitespace - p.skipWhitespace() - if p.done { - return - } - - // Start of non-whitespace - p.cur.err = nil - p.cur.offset, p.cur.line = p.offset, p.line - p.cur.unquoted = "" - switch p.s[0] { - case '<', '>', '{', '}', ':', '[', ']', ';', ',', '/': - // Single symbol - p.cur.value, p.s = p.s[0:1], p.s[1:len(p.s)] - case '"', '\'': - // Quoted string - i := 1 - for i < len(p.s) && p.s[i] != p.s[0] && p.s[i] != '\n' { - if p.s[i] == '\\' && i+1 < len(p.s) { - // skip escaped char - i++ - } - i++ - } - if i >= len(p.s) || p.s[i] != p.s[0] { - p.errorf("unmatched quote") - return - } - unq, err := unquoteC(p.s[1:i], rune(p.s[0])) - if err != nil { - p.errorf("invalid quoted string %s: %v", p.s[0:i+1], err) - return - } - p.cur.value, p.s = p.s[0:i+1], p.s[i+1:len(p.s)] - p.cur.unquoted = unq - default: - i := 0 - for i < len(p.s) && isIdentOrNumberChar(p.s[i]) { - i++ - } - if i == 0 { - p.errorf("unexpected byte %#x", p.s[0]) - return - } - p.cur.value, p.s = p.s[0:i], p.s[i:len(p.s)] - } - p.offset += len(p.cur.value) -} - -var ( - errBadUTF8 = errors.New("proto: bad UTF-8") -) - -func unquoteC(s string, quote rune) (string, error) { - // This is based on C++'s tokenizer.cc. - // Despite its name, this is *not* parsing C syntax. - // For instance, "\0" is an invalid quoted string. - - // Avoid allocation in trivial cases. - simple := true - for _, r := range s { - if r == '\\' || r == quote { - simple = false - break - } - } - if simple { - return s, nil - } - - buf := make([]byte, 0, 3*len(s)/2) - for len(s) > 0 { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", errBadUTF8 - } - s = s[n:] - if r != '\\' { - if r < utf8.RuneSelf { - buf = append(buf, byte(r)) - } else { - buf = append(buf, string(r)...) - } - continue - } - - ch, tail, err := unescape(s) - if err != nil { - return "", err - } - buf = append(buf, ch...) - s = tail - } - return string(buf), nil -} - -func unescape(s string) (ch string, tail string, err error) { - r, n := utf8.DecodeRuneInString(s) - if r == utf8.RuneError && n == 1 { - return "", "", errBadUTF8 - } - s = s[n:] - switch r { - case 'a': - return "\a", s, nil - case 'b': - return "\b", s, nil - case 'f': - return "\f", s, nil - case 'n': - return "\n", s, nil - case 'r': - return "\r", s, nil - case 't': - return "\t", s, nil - case 'v': - return "\v", s, nil - case '?': - return "?", s, nil // trigraph workaround - case '\'', '"', '\\': - return string(r), s, nil - case '0', '1', '2', '3', '4', '5', '6', '7': - if len(s) < 2 { - return "", "", fmt.Errorf(`\%c requires 2 following digits`, r) - } - ss := string(r) + s[:2] - s = s[2:] - i, err := strconv.ParseUint(ss, 8, 8) - if err != nil { - return "", "", fmt.Errorf(`\%s contains non-octal digits`, ss) - } - return string([]byte{byte(i)}), s, nil - case 'x', 'X', 'u', 'U': - var n int - switch r { - case 'x', 'X': - n = 2 - case 'u': - n = 4 - case 'U': - n = 8 - } - if len(s) < n { - return "", "", fmt.Errorf(`\%c requires %d following digits`, r, n) - } - ss := s[:n] - s = s[n:] - i, err := strconv.ParseUint(ss, 16, 64) - if err != nil { - return "", "", fmt.Errorf(`\%c%s contains non-hexadecimal digits`, r, ss) - } - if r == 'x' || r == 'X' { - return string([]byte{byte(i)}), s, nil - } - if i > utf8.MaxRune { - return "", "", fmt.Errorf(`\%c%s is not a valid Unicode code point`, r, ss) - } - return string(i), s, nil - } - return "", "", fmt.Errorf(`unknown escape \%c`, r) -} - -// Back off the parser by one token. Can only be done between calls to next(). -// It makes the next advance() a no-op. -func (p *textParser) back() { p.backed = true } - -// Advances the parser and returns the new current token. -func (p *textParser) next() *token { - if p.backed || p.done { - p.backed = false - return &p.cur - } - p.advance() - if p.done { - p.cur.value = "" - } else if len(p.cur.value) > 0 && isQuote(p.cur.value[0]) { - // Look for multiple quoted strings separated by whitespace, - // and concatenate them. - cat := p.cur - for { - p.skipWhitespace() - if p.done || !isQuote(p.s[0]) { - break - } - p.advance() - if p.cur.err != nil { - return &p.cur - } - cat.value += " " + p.cur.value - cat.unquoted += p.cur.unquoted - } - p.done = false // parser may have seen EOF, but we want to return cat - p.cur = cat - } - return &p.cur -} - -func (p *textParser) consumeToken(s string) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != s { - p.back() - return p.errorf("expected %q, found %q", s, tok.value) - } - return nil -} - -// Return a RequiredNotSetError indicating which required field was not set. -func (p *textParser) missingRequiredFieldError(sv reflect.Value) *RequiredNotSetError { - st := sv.Type() - sprops := GetProperties(st) - for i := 0; i < st.NumField(); i++ { - if !isNil(sv.Field(i)) { - continue - } - - props := sprops.Prop[i] - if props.Required { - return &RequiredNotSetError{fmt.Sprintf("%v.%v", st, props.OrigName)} - } - } - return &RequiredNotSetError{fmt.Sprintf("%v.", st)} // should not happen -} - -// Returns the index in the struct for the named field, as well as the parsed tag properties. -func structFieldByName(sprops *StructProperties, name string) (int, *Properties, bool) { - i, ok := sprops.decoderOrigNames[name] - if ok { - return i, sprops.Prop[i], true - } - return -1, nil, false -} - -// Consume a ':' from the input stream (if the next token is a colon), -// returning an error if a colon is needed but not present. -func (p *textParser) checkForColon(props *Properties, typ reflect.Type) *ParseError { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ":" { - // Colon is optional when the field is a group or message. - needColon := true - switch props.Wire { - case "group": - needColon = false - case "bytes": - // A "bytes" field is either a message, a string, or a repeated field; - // those three become *T, *string and []T respectively, so we can check for - // this field being a pointer to a non-string. - if typ.Kind() == reflect.Ptr { - // *T or *string - if typ.Elem().Kind() == reflect.String { - break - } - } else if typ.Kind() == reflect.Slice { - // []T or []*T - if typ.Elem().Kind() != reflect.Ptr { - break - } - } else if typ.Kind() == reflect.String { - // The proto3 exception is for a string field, - // which requires a colon. - break - } - needColon = false - } - if needColon { - return p.errorf("expected ':', found %q", tok.value) - } - p.back() - } - return nil -} - -func (p *textParser) readStruct(sv reflect.Value, terminator string) error { - st := sv.Type() - sprops := GetProperties(st) - reqCount := sprops.reqCount - var reqFieldErr error - fieldSet := make(map[string]bool) - // A struct is a sequence of "name: value", terminated by one of - // '>' or '}', or the end of the input. A name may also be - // "[extension]" or "[type/url]". - // - // The whole struct can also be an expanded Any message, like: - // [type/url] < ... struct contents ... > - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - if tok.value == "[" { - // Looks like an extension or an Any. - // - // TODO: Check whether we need to handle - // namespace rooted names (e.g. ".something.Foo"). - extName, err := p.consumeExtName() - if err != nil { - return err - } - - if s := strings.LastIndex(extName, "/"); s >= 0 { - // If it contains a slash, it's an Any type URL. - messageName := extName[s+1:] - mt := MessageType(messageName) - if mt == nil { - return p.errorf("unrecognized message %q in google.protobuf.Any", messageName) - } - tok = p.next() - if tok.err != nil { - return tok.err - } - // consume an optional colon - if tok.value == ":" { - tok = p.next() - if tok.err != nil { - return tok.err - } - } - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - v := reflect.New(mt.Elem()) - if pe := p.readStruct(v.Elem(), terminator); pe != nil { - return pe - } - b, err := Marshal(v.Interface().(Message)) - if err != nil { - return p.errorf("failed to marshal message of type %q: %v", messageName, err) - } - if fieldSet["type_url"] { - return p.errorf(anyRepeatedlyUnpacked, "type_url") - } - if fieldSet["value"] { - return p.errorf(anyRepeatedlyUnpacked, "value") - } - sv.FieldByName("TypeUrl").SetString(extName) - sv.FieldByName("Value").SetBytes(b) - fieldSet["type_url"] = true - fieldSet["value"] = true - continue - } - - var desc *ExtensionDesc - // This could be faster, but it's functional. - // TODO: Do something smarter than a linear scan. - for _, d := range RegisteredExtensions(reflect.New(st).Interface().(Message)) { - if d.Name == extName { - desc = d - break - } - } - if desc == nil { - return p.errorf("unrecognized extension %q", extName) - } - - props := &Properties{} - props.Parse(desc.Tag) - - typ := reflect.TypeOf(desc.ExtensionType) - if err := p.checkForColon(props, typ); err != nil { - return err - } - - rep := desc.repeated() - - // Read the extension structure, and set it in - // the value we're constructing. - var ext reflect.Value - if !rep { - ext = reflect.New(typ).Elem() - } else { - ext = reflect.New(typ.Elem()).Elem() - } - if err := p.readAny(ext, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } - ep := sv.Addr().Interface().(Message) - if !rep { - SetExtension(ep, desc, ext.Interface()) - } else { - old, err := GetExtension(ep, desc) - var sl reflect.Value - if err == nil { - sl = reflect.ValueOf(old) // existing slice - } else { - sl = reflect.MakeSlice(typ, 0, 1) - } - sl = reflect.Append(sl, ext) - SetExtension(ep, desc, sl.Interface()) - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - continue - } - - // This is a normal, non-extension field. - name := tok.value - var dst reflect.Value - fi, props, ok := structFieldByName(sprops, name) - if ok { - dst = sv.Field(fi) - } else if oop, ok := sprops.OneofTypes[name]; ok { - // It is a oneof. - props = oop.Prop - nv := reflect.New(oop.Type.Elem()) - dst = nv.Elem().Field(0) - field := sv.Field(oop.Field) - if !field.IsNil() { - return p.errorf("field '%s' would overwrite already parsed oneof '%s'", name, sv.Type().Field(oop.Field).Name) - } - field.Set(nv) - } - if !dst.IsValid() { - return p.errorf("unknown field name %q in %v", name, st) - } - - if dst.Kind() == reflect.Map { - // Consume any colon. - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Construct the map if it doesn't already exist. - if dst.IsNil() { - dst.Set(reflect.MakeMap(dst.Type())) - } - key := reflect.New(dst.Type().Key()).Elem() - val := reflect.New(dst.Type().Elem()).Elem() - - // The map entry should be this sequence of tokens: - // < key : KEY value : VALUE > - // However, implementations may omit key or value, and technically - // we should support them in any order. See b/28924776 for a time - // this went wrong. - - tok := p.next() - var terminator string - switch tok.value { - case "<": - terminator = ">" - case "{": - terminator = "}" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - for { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == terminator { - break - } - switch tok.value { - case "key": - if err := p.consumeToken(":"); err != nil { - return err - } - if err := p.readAny(key, props.MapKeyProp); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - case "value": - if err := p.checkForColon(props.MapValProp, dst.Type().Elem()); err != nil { - return err - } - if err := p.readAny(val, props.MapValProp); err != nil { - return err - } - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - default: - p.back() - return p.errorf(`expected "key", "value", or %q, found %q`, terminator, tok.value) - } - } - - dst.SetMapIndex(key, val) - continue - } - - // Check that it's not already set if it's not a repeated field. - if !props.Repeated && fieldSet[name] { - return p.errorf("non-repeated field %q was repeated", name) - } - - if err := p.checkForColon(props, dst.Type()); err != nil { - return err - } - - // Parse into the field. - fieldSet[name] = true - if err := p.readAny(dst, props); err != nil { - if _, ok := err.(*RequiredNotSetError); !ok { - return err - } - reqFieldErr = err - } - if props.Required { - reqCount-- - } - - if err := p.consumeOptionalSeparator(); err != nil { - return err - } - - } - - if reqCount > 0 { - return p.missingRequiredFieldError(sv) - } - return reqFieldErr -} - -// consumeExtName consumes extension name or expanded Any type URL and the -// following ']'. It returns the name or URL consumed. -func (p *textParser) consumeExtName() (string, error) { - tok := p.next() - if tok.err != nil { - return "", tok.err - } - - // If extension name or type url is quoted, it's a single token. - if len(tok.value) > 2 && isQuote(tok.value[0]) && tok.value[len(tok.value)-1] == tok.value[0] { - name, err := unquoteC(tok.value[1:len(tok.value)-1], rune(tok.value[0])) - if err != nil { - return "", err - } - return name, p.consumeToken("]") - } - - // Consume everything up to "]" - var parts []string - for tok.value != "]" { - parts = append(parts, tok.value) - tok = p.next() - if tok.err != nil { - return "", p.errorf("unrecognized type_url or extension name: %s", tok.err) - } - if p.done && tok.value != "]" { - return "", p.errorf("unclosed type_url or extension name") - } - } - return strings.Join(parts, ""), nil -} - -// consumeOptionalSeparator consumes an optional semicolon or comma. -// It is used in readStruct to provide backward compatibility. -func (p *textParser) consumeOptionalSeparator() error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value != ";" && tok.value != "," { - p.back() - } - return nil -} - -func (p *textParser) readAny(v reflect.Value, props *Properties) error { - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == "" { - return p.errorf("unexpected EOF") - } - - switch fv := v; fv.Kind() { - case reflect.Slice: - at := v.Type() - if at.Elem().Kind() == reflect.Uint8 { - // Special case for []byte - if tok.value[0] != '"' && tok.value[0] != '\'' { - // Deliberately written out here, as the error after - // this switch statement would write "invalid []byte: ...", - // which is not as user-friendly. - return p.errorf("invalid string: %v", tok.value) - } - bytes := []byte(tok.unquoted) - fv.Set(reflect.ValueOf(bytes)) - return nil - } - // Repeated field. - if tok.value == "[" { - // Repeated field with list notation, like [1,2,3]. - for { - fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) - err := p.readAny(fv.Index(fv.Len()-1), props) - if err != nil { - return err - } - tok := p.next() - if tok.err != nil { - return tok.err - } - if tok.value == "]" { - break - } - if tok.value != "," { - return p.errorf("Expected ']' or ',' found %q", tok.value) - } - } - return nil - } - // One value of the repeated field. - p.back() - fv.Set(reflect.Append(fv, reflect.New(at.Elem()).Elem())) - return p.readAny(fv.Index(fv.Len()-1), props) - case reflect.Bool: - // true/1/t/True or false/f/0/False. - switch tok.value { - case "true", "1", "t", "True": - fv.SetBool(true) - return nil - case "false", "0", "f", "False": - fv.SetBool(false) - return nil - } - case reflect.Float32, reflect.Float64: - v := tok.value - // Ignore 'f' for compatibility with output generated by C++, but don't - // remove 'f' when the value is "-inf" or "inf". - if strings.HasSuffix(v, "f") && tok.value != "-inf" && tok.value != "inf" { - v = v[:len(v)-1] - } - if f, err := strconv.ParseFloat(v, fv.Type().Bits()); err == nil { - fv.SetFloat(f) - return nil - } - case reflect.Int32: - if x, err := strconv.ParseInt(tok.value, 0, 32); err == nil { - fv.SetInt(x) - return nil - } - - if len(props.Enum) == 0 { - break - } - m, ok := enumValueMaps[props.Enum] - if !ok { - break - } - x, ok := m[tok.value] - if !ok { - break - } - fv.SetInt(int64(x)) - return nil - case reflect.Int64: - if x, err := strconv.ParseInt(tok.value, 0, 64); err == nil { - fv.SetInt(x) - return nil - } - - case reflect.Ptr: - // A basic field (indirected through pointer), or a repeated message/group - p.back() - fv.Set(reflect.New(fv.Type().Elem())) - return p.readAny(fv.Elem(), props) - case reflect.String: - if tok.value[0] == '"' || tok.value[0] == '\'' { - fv.SetString(tok.unquoted) - return nil - } - case reflect.Struct: - var terminator string - switch tok.value { - case "{": - terminator = "}" - case "<": - terminator = ">" - default: - return p.errorf("expected '{' or '<', found %q", tok.value) - } - // TODO: Handle nested messages which implement encoding.TextUnmarshaler. - return p.readStruct(fv, terminator) - case reflect.Uint32: - if x, err := strconv.ParseUint(tok.value, 0, 32); err == nil { - fv.SetUint(uint64(x)) - return nil - } - case reflect.Uint64: - if x, err := strconv.ParseUint(tok.value, 0, 64); err == nil { - fv.SetUint(x) - return nil - } - } - return p.errorf("invalid %v: %v", v.Type(), tok.value) -} - -// UnmarshalText reads a protocol buffer in Text format. UnmarshalText resets pb -// before starting to unmarshal, so any existing data in pb is always removed. -// If a required field is not set and no other error occurs, -// UnmarshalText returns *RequiredNotSetError. -func UnmarshalText(s string, pb Message) error { - if um, ok := pb.(encoding.TextUnmarshaler); ok { - return um.UnmarshalText([]byte(s)) - } - pb.Reset() - v := reflect.ValueOf(pb) - return newTextParser(s).readStruct(v.Elem(), "") -} diff --git a/vendor/github.com/golang/protobuf/proto/wire.go b/vendor/github.com/golang/protobuf/proto/wire.go new file mode 100644 index 000000000..d7c28da5a --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/wire.go @@ -0,0 +1,78 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +import ( + protoV2 "google.golang.org/protobuf/proto" + "google.golang.org/protobuf/runtime/protoiface" +) + +// Size returns the size in bytes of the wire-format encoding of m. +func Size(m Message) int { + if m == nil { + return 0 + } + mi := MessageV2(m) + return protoV2.Size(mi) +} + +// Marshal returns the wire-format encoding of m. +func Marshal(m Message) ([]byte, error) { + b, err := marshalAppend(nil, m, false) + if b == nil { + b = zeroBytes + } + return b, err +} + +var zeroBytes = make([]byte, 0, 0) + +func marshalAppend(buf []byte, m Message, deterministic bool) ([]byte, error) { + if m == nil { + return nil, ErrNil + } + mi := MessageV2(m) + nbuf, err := protoV2.MarshalOptions{ + Deterministic: deterministic, + AllowPartial: true, + }.MarshalAppend(buf, mi) + if err != nil { + return buf, err + } + if len(buf) == len(nbuf) { + if !mi.ProtoReflect().IsValid() { + return buf, ErrNil + } + } + return nbuf, checkRequiredNotSet(mi) +} + +// Unmarshal parses a wire-format message in b and places the decoded results in m. +// +// Unmarshal resets m before starting to unmarshal, so any existing data in m is always +// removed. Use UnmarshalMerge to preserve and append to existing data. +func Unmarshal(b []byte, m Message) error { + m.Reset() + return UnmarshalMerge(b, m) +} + +// UnmarshalMerge parses a wire-format message in b and places the decoded results in m. +func UnmarshalMerge(b []byte, m Message) error { + mi := MessageV2(m) + out, err := protoV2.UnmarshalOptions{ + AllowPartial: true, + Merge: true, + }.UnmarshalState(protoiface.UnmarshalInput{ + Buf: b, + Message: mi.ProtoReflect(), + }) + if err != nil { + return err + } + if out.Flags&protoiface.UnmarshalInitialized > 0 { + return nil + } + return checkRequiredNotSet(mi) +} diff --git a/vendor/github.com/golang/protobuf/proto/wrappers.go b/vendor/github.com/golang/protobuf/proto/wrappers.go new file mode 100644 index 000000000..398e34859 --- /dev/null +++ b/vendor/github.com/golang/protobuf/proto/wrappers.go @@ -0,0 +1,34 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package proto + +// Bool stores v in a new bool value and returns a pointer to it. +func Bool(v bool) *bool { return &v } + +// Int stores v in a new int32 value and returns a pointer to it. +// +// Deprecated: Use Int32 instead. +func Int(v int) *int32 { return Int32(int32(v)) } + +// Int32 stores v in a new int32 value and returns a pointer to it. +func Int32(v int32) *int32 { return &v } + +// Int64 stores v in a new int64 value and returns a pointer to it. +func Int64(v int64) *int64 { return &v } + +// Uint32 stores v in a new uint32 value and returns a pointer to it. +func Uint32(v uint32) *uint32 { return &v } + +// Uint64 stores v in a new uint64 value and returns a pointer to it. +func Uint64(v uint64) *uint64 { return &v } + +// Float32 stores v in a new float32 value and returns a pointer to it. +func Float32(v float32) *float32 { return &v } + +// Float64 stores v in a new float64 value and returns a pointer to it. +func Float64(v float64) *float64 { return &v } + +// String stores v in a new string value and returns a pointer to it. +func String(v string) *string { return &v } diff --git a/vendor/github.com/golang/protobuf/ptypes/any.go b/vendor/github.com/golang/protobuf/ptypes/any.go index 70276e8f5..85f9f5736 100644 --- a/vendor/github.com/golang/protobuf/ptypes/any.go +++ b/vendor/github.com/golang/protobuf/ptypes/any.go @@ -1,141 +1,179 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. package ptypes -// This file implements functions to marshal proto.Message to/from -// google.protobuf.Any message. - import ( "fmt" - "reflect" "strings" "github.com/golang/protobuf/proto" - "github.com/golang/protobuf/ptypes/any" + "google.golang.org/protobuf/reflect/protoreflect" + "google.golang.org/protobuf/reflect/protoregistry" + + anypb "github.com/golang/protobuf/ptypes/any" ) -const googleApis = "type.googleapis.com/" +const urlPrefix = "type.googleapis.com/" -// AnyMessageName returns the name of the message contained in a google.protobuf.Any message. +// AnyMessageName returns the message name contained in an anypb.Any message. +// Most type assertions should use the Is function instead. // -// Note that regular type assertions should be done using the Is -// function. AnyMessageName is provided for less common use cases like filtering a -// sequence of Any messages based on a set of allowed message type names. -func AnyMessageName(any *any.Any) (string, error) { +// Deprecated: Call the any.MessageName method instead. +func AnyMessageName(any *anypb.Any) (string, error) { + name, err := anyMessageName(any) + return string(name), err +} +func anyMessageName(any *anypb.Any) (protoreflect.FullName, error) { if any == nil { return "", fmt.Errorf("message is nil") } - slash := strings.LastIndex(any.TypeUrl, "/") - if slash < 0 { + name := protoreflect.FullName(any.TypeUrl) + if i := strings.LastIndex(any.TypeUrl, "/"); i >= 0 { + name = name[i+len("/"):] + } + if !name.IsValid() { return "", fmt.Errorf("message type url %q is invalid", any.TypeUrl) } - return any.TypeUrl[slash+1:], nil + return name, nil } -// MarshalAny takes the protocol buffer and encodes it into google.protobuf.Any. -func MarshalAny(pb proto.Message) (*any.Any, error) { - value, err := proto.Marshal(pb) +// MarshalAny marshals the given message m into an anypb.Any message. +// +// Deprecated: Call the anypb.New function instead. +func MarshalAny(m proto.Message) (*anypb.Any, error) { + switch dm := m.(type) { + case DynamicAny: + m = dm.Message + case *DynamicAny: + if dm == nil { + return nil, proto.ErrNil + } + m = dm.Message + } + b, err := proto.Marshal(m) if err != nil { return nil, err } - return &any.Any{TypeUrl: googleApis + proto.MessageName(pb), Value: value}, nil + return &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil } -// DynamicAny is a value that can be passed to UnmarshalAny to automatically -// allocate a proto.Message for the type specified in a google.protobuf.Any -// message. The allocated message is stored in the embedded proto.Message. -// -// Example: +// Empty returns a new message of the type specified in an anypb.Any message. +// It returns protoregistry.NotFound if the corresponding message type could not +// be resolved in the global registry. // -// var x ptypes.DynamicAny -// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... } -// fmt.Printf("unmarshaled message: %v", x.Message) -type DynamicAny struct { - proto.Message -} - -// Empty returns a new proto.Message of the type specified in a -// google.protobuf.Any message. It returns an error if corresponding message -// type isn't linked in. -func Empty(any *any.Any) (proto.Message, error) { - aname, err := AnyMessageName(any) +// Deprecated: Use protoregistry.GlobalTypes.FindMessageByName instead +// to resolve the message name and create a new instance of it. +func Empty(any *anypb.Any) (proto.Message, error) { + name, err := anyMessageName(any) if err != nil { return nil, err } - - t := proto.MessageType(aname) - if t == nil { - return nil, fmt.Errorf("any: message type %q isn't linked in", aname) + mt, err := protoregistry.GlobalTypes.FindMessageByName(name) + if err != nil { + return nil, err } - return reflect.New(t.Elem()).Interface().(proto.Message), nil + return proto.MessageV1(mt.New().Interface()), nil } -// UnmarshalAny parses the protocol buffer representation in a google.protobuf.Any -// message and places the decoded result in pb. It returns an error if type of -// contents of Any message does not match type of pb message. +// UnmarshalAny unmarshals the encoded value contained in the anypb.Any message +// into the provided message m. It returns an error if the target message +// does not match the type in the Any message or if an unmarshal error occurs. +// +// The target message m may be a *DynamicAny message. If the underlying message +// type could not be resolved, then this returns protoregistry.NotFound. // -// pb can be a proto.Message, or a *DynamicAny. -func UnmarshalAny(any *any.Any, pb proto.Message) error { - if d, ok := pb.(*DynamicAny); ok { - if d.Message == nil { +// Deprecated: Call the any.UnmarshalTo method instead. +func UnmarshalAny(any *anypb.Any, m proto.Message) error { + if dm, ok := m.(*DynamicAny); ok { + if dm.Message == nil { var err error - d.Message, err = Empty(any) + dm.Message, err = Empty(any) if err != nil { return err } } - return UnmarshalAny(any, d.Message) + m = dm.Message } - aname, err := AnyMessageName(any) + anyName, err := AnyMessageName(any) if err != nil { return err } - - mname := proto.MessageName(pb) - if aname != mname { - return fmt.Errorf("mismatched message type: got %q want %q", aname, mname) + msgName := proto.MessageName(m) + if anyName != msgName { + return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName) } - return proto.Unmarshal(any.Value, pb) + return proto.Unmarshal(any.Value, m) } -// Is returns true if any value contains a given message type. -func Is(any *any.Any, pb proto.Message) bool { - // The following is equivalent to AnyMessageName(any) == proto.MessageName(pb), - // but it avoids scanning TypeUrl for the slash. - if any == nil { +// Is reports whether the Any message contains a message of the specified type. +// +// Deprecated: Call the any.MessageIs method instead. +func Is(any *anypb.Any, m proto.Message) bool { + if any == nil || m == nil { return false } - name := proto.MessageName(pb) - prefix := len(any.TypeUrl) - len(name) - return prefix >= 1 && any.TypeUrl[prefix-1] == '/' && any.TypeUrl[prefix:] == name + name := proto.MessageName(m) + if !strings.HasSuffix(any.TypeUrl, name) { + return false + } + return len(any.TypeUrl) == len(name) || any.TypeUrl[len(any.TypeUrl)-len(name)-1] == '/' +} + +// DynamicAny is a value that can be passed to UnmarshalAny to automatically +// allocate a proto.Message for the type specified in an anypb.Any message. +// The allocated message is stored in the embedded proto.Message. +// +// Example: +// var x ptypes.DynamicAny +// if err := ptypes.UnmarshalAny(a, &x); err != nil { ... } +// fmt.Printf("unmarshaled message: %v", x.Message) +// +// Deprecated: Use the any.UnmarshalNew method instead to unmarshal +// the any message contents into a new instance of the underlying message. +type DynamicAny struct{ proto.Message } + +func (m DynamicAny) String() string { + if m.Message == nil { + return "" + } + return m.Message.String() +} +func (m DynamicAny) Reset() { + if m.Message == nil { + return + } + m.Message.Reset() +} +func (m DynamicAny) ProtoMessage() { + return +} +func (m DynamicAny) ProtoReflect() protoreflect.Message { + if m.Message == nil { + return nil + } + return dynamicAny{proto.MessageReflect(m.Message)} +} + +type dynamicAny struct{ protoreflect.Message } + +func (m dynamicAny) Type() protoreflect.MessageType { + return dynamicAnyType{m.Message.Type()} +} +func (m dynamicAny) New() protoreflect.Message { + return dynamicAnyType{m.Message.Type()}.New() +} +func (m dynamicAny) Interface() protoreflect.ProtoMessage { + return DynamicAny{proto.MessageV1(m.Message.Interface())} +} + +type dynamicAnyType struct{ protoreflect.MessageType } + +func (t dynamicAnyType) New() protoreflect.Message { + return dynamicAny{t.MessageType.New()} +} +func (t dynamicAnyType) Zero() protoreflect.Message { + return dynamicAny{t.MessageType.Zero()} } diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go index 78ee52334..0ef27d33d 100644 --- a/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go +++ b/vendor/github.com/golang/protobuf/ptypes/any/any.pb.go @@ -1,200 +1,62 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: google/protobuf/any.proto +// source: github.com/golang/protobuf/ptypes/any/any.proto package any import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + anypb "google.golang.org/protobuf/types/known/anypb" + reflect "reflect" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +// Symbols defined in public import of google/protobuf/any.proto. -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +type Any = anypb.Any -// `Any` contains an arbitrary serialized protocol buffer message along with a -// URL that describes the type of the serialized message. -// -// Protobuf library provides support to pack/unpack Any values in the form -// of utility functions or additional generated methods of the Any type. -// -// Example 1: Pack and unpack a message in C++. -// -// Foo foo = ...; -// Any any; -// any.PackFrom(foo); -// ... -// if (any.UnpackTo(&foo)) { -// ... -// } -// -// Example 2: Pack and unpack a message in Java. -// -// Foo foo = ...; -// Any any = Any.pack(foo); -// ... -// if (any.is(Foo.class)) { -// foo = any.unpack(Foo.class); -// } -// -// Example 3: Pack and unpack a message in Python. -// -// foo = Foo(...) -// any = Any() -// any.Pack(foo) -// ... -// if any.Is(Foo.DESCRIPTOR): -// any.Unpack(foo) -// ... -// -// Example 4: Pack and unpack a message in Go -// -// foo := &pb.Foo{...} -// any, err := ptypes.MarshalAny(foo) -// ... -// foo := &pb.Foo{} -// if err := ptypes.UnmarshalAny(any, foo); err != nil { -// ... -// } -// -// The pack methods provided by protobuf library will by default use -// 'type.googleapis.com/full.type.name' as the type URL and the unpack -// methods only use the fully qualified type name after the last '/' -// in the type URL, for example "foo.bar.com/x/y.z" will yield type -// name "y.z". -// -// -// JSON -// ==== -// The JSON representation of an `Any` value uses the regular -// representation of the deserialized, embedded message, with an -// additional field `@type` which contains the type URL. Example: -// -// package google.profile; -// message Person { -// string first_name = 1; -// string last_name = 2; -// } -// -// { -// "@type": "type.googleapis.com/google.profile.Person", -// "firstName": , -// "lastName": -// } -// -// If the embedded message type is well-known and has a custom JSON -// representation, that representation will be embedded adding a field -// `value` which holds the custom JSON in addition to the `@type` -// field. Example (for message [google.protobuf.Duration][]): -// -// { -// "@type": "type.googleapis.com/google.protobuf.Duration", -// "value": "1.212s" -// } -// -type Any struct { - // A URL/resource name that uniquely identifies the type of the serialized - // protocol buffer message. 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). - // - // In practice, teams usually precompile into the binary all types that they - // expect it to use in the context of Any. However, for URLs which use the - // scheme `http`, `https`, or no scheme, one can optionally set up a type - // server that maps type URLs to message definitions as follows: - // - // * If no scheme is provided, `https` is assumed. - // * An HTTP GET on the URL must yield a [google.protobuf.Type][] - // value in binary format, or produce an error. - // * Applications are allowed to cache lookup results based on the - // URL, or have them precompiled into a binary to avoid any - // lookup. Therefore, binary compatibility needs to be preserved - // on changes to types. (Use versioned type names to manage - // breaking changes.) - // - // Note: this functionality is not currently available in the official - // protobuf release, and it is not used for type URLs beginning with - // type.googleapis.com. - // - // Schemes other than `http`, `https` (or the empty scheme) might be - // used with implementation specific semantics. - // - TypeUrl string `protobuf:"bytes,1,opt,name=type_url,json=typeUrl,proto3" json:"type_url,omitempty"` - // Must be a valid serialized protocol buffer of the above specified type. - Value []byte `protobuf:"bytes,2,opt,name=value,proto3" json:"value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} +var File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor -func (m *Any) Reset() { *m = Any{} } -func (m *Any) String() string { return proto.CompactTextString(m) } -func (*Any) ProtoMessage() {} -func (*Any) Descriptor() ([]byte, []int) { - return fileDescriptor_b53526c13ae22eb4, []int{0} +var file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = []byte{ + 0x0a, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x2b, 0x5a, 0x29, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, + 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2f, 0x61, 0x6e, 0x79, 0x3b, 0x61, 0x6e, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x33, } -func (*Any) XXX_WellKnownType() string { return "Any" } - -func (m *Any) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Any.Unmarshal(m, b) -} -func (m *Any) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Any.Marshal(b, m, deterministic) -} -func (m *Any) XXX_Merge(src proto.Message) { - xxx_messageInfo_Any.Merge(m, src) -} -func (m *Any) XXX_Size() int { - return xxx_messageInfo_Any.Size(m) -} -func (m *Any) XXX_DiscardUnknown() { - xxx_messageInfo_Any.DiscardUnknown(m) +var file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } -var xxx_messageInfo_Any proto.InternalMessageInfo - -func (m *Any) GetTypeUrl() string { - if m != nil { - return m.TypeUrl +func init() { file_github_com_golang_protobuf_ptypes_any_any_proto_init() } +func file_github_com_golang_protobuf_ptypes_any_any_proto_init() { + if File_github_com_golang_protobuf_ptypes_any_any_proto != nil { + return } - return "" -} - -func (m *Any) GetValue() []byte { - if m != nil { - return m.Value - } - return nil -} - -func init() { - proto.RegisterType((*Any)(nil), "google.protobuf.Any") -} - -func init() { proto.RegisterFile("google/protobuf/any.proto", fileDescriptor_b53526c13ae22eb4) } - -var fileDescriptor_b53526c13ae22eb4 = []byte{ - // 185 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4c, 0xcf, 0xcf, 0x4f, - 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcc, 0xab, 0xd4, - 0x03, 0x73, 0x84, 0xf8, 0x21, 0x52, 0x7a, 0x30, 0x29, 0x25, 0x33, 0x2e, 0x66, 0xc7, 0xbc, 0x4a, - 0x21, 0x49, 0x2e, 0x8e, 0x92, 0xca, 0x82, 0xd4, 0xf8, 0xd2, 0xa2, 0x1c, 0x09, 0x46, 0x05, 0x46, - 0x0d, 0xce, 0x20, 0x76, 0x10, 0x3f, 0xb4, 0x28, 0x47, 0x48, 0x84, 0x8b, 0xb5, 0x2c, 0x31, 0xa7, - 0x34, 0x55, 0x82, 0x49, 0x81, 0x51, 0x83, 0x27, 0x08, 0xc2, 0x71, 0xca, 0xe7, 0x12, 0x4e, 0xce, - 0xcf, 0xd5, 0x43, 0x33, 0xce, 0x89, 0xc3, 0x31, 0xaf, 0x32, 0x00, 0xc4, 0x09, 0x60, 0x8c, 0x52, - 0x4d, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, - 0x4b, 0x47, 0xb8, 0xa8, 0x00, 0x64, 0x7a, 0x31, 0xc8, 0x61, 0x8b, 0x98, 0x98, 0xdd, 0x03, 0x9c, - 0x56, 0x31, 0xc9, 0xb9, 0x43, 0x8c, 0x0a, 0x80, 0x2a, 0xd1, 0x0b, 0x4f, 0xcd, 0xc9, 0xf1, 0xce, - 0xcb, 0x2f, 0xcf, 0x0b, 0x01, 0x29, 0x4d, 0x62, 0x03, 0xeb, 0x35, 0x06, 0x04, 0x00, 0x00, 0xff, - 0xff, 0x13, 0xf8, 0xe8, 0x42, 0xdd, 0x00, 0x00, 0x00, + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_any_any_proto = out.File + file_github_com_golang_protobuf_ptypes_any_any_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_any_any_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_any_any_proto_depIdxs = nil } diff --git a/vendor/github.com/golang/protobuf/ptypes/any/any.proto b/vendor/github.com/golang/protobuf/ptypes/any/any.proto deleted file mode 100644 index 493294255..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/any/any.proto +++ /dev/null @@ -1,154 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package google.protobuf; - -option csharp_namespace = "Google.Protobuf.WellKnownTypes"; -option go_package = "github.com/golang/protobuf/ptypes/any"; -option java_package = "com.google.protobuf"; -option java_outer_classname = "AnyProto"; -option java_multiple_files = true; -option objc_class_prefix = "GPB"; - -// `Any` contains an arbitrary serialized protocol buffer message along with a -// URL that describes the type of the serialized message. -// -// Protobuf library provides support to pack/unpack Any values in the form -// of utility functions or additional generated methods of the Any type. -// -// Example 1: Pack and unpack a message in C++. -// -// Foo foo = ...; -// Any any; -// any.PackFrom(foo); -// ... -// if (any.UnpackTo(&foo)) { -// ... -// } -// -// Example 2: Pack and unpack a message in Java. -// -// Foo foo = ...; -// Any any = Any.pack(foo); -// ... -// if (any.is(Foo.class)) { -// foo = any.unpack(Foo.class); -// } -// -// Example 3: Pack and unpack a message in Python. -// -// foo = Foo(...) -// any = Any() -// any.Pack(foo) -// ... -// if any.Is(Foo.DESCRIPTOR): -// any.Unpack(foo) -// ... -// -// Example 4: Pack and unpack a message in Go -// -// foo := &pb.Foo{...} -// any, err := ptypes.MarshalAny(foo) -// ... -// foo := &pb.Foo{} -// if err := ptypes.UnmarshalAny(any, foo); err != nil { -// ... -// } -// -// The pack methods provided by protobuf library will by default use -// 'type.googleapis.com/full.type.name' as the type URL and the unpack -// methods only use the fully qualified type name after the last '/' -// in the type URL, for example "foo.bar.com/x/y.z" will yield type -// name "y.z". -// -// -// JSON -// ==== -// The JSON representation of an `Any` value uses the regular -// representation of the deserialized, embedded message, with an -// additional field `@type` which contains the type URL. Example: -// -// package google.profile; -// message Person { -// string first_name = 1; -// string last_name = 2; -// } -// -// { -// "@type": "type.googleapis.com/google.profile.Person", -// "firstName": , -// "lastName": -// } -// -// If the embedded message type is well-known and has a custom JSON -// representation, that representation will be embedded adding a field -// `value` which holds the custom JSON in addition to the `@type` -// field. Example (for message [google.protobuf.Duration][]): -// -// { -// "@type": "type.googleapis.com/google.protobuf.Duration", -// "value": "1.212s" -// } -// -message Any { - // A URL/resource name that uniquely identifies the type of the serialized - // protocol buffer message. 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). - // - // In practice, teams usually precompile into the binary all types that they - // expect it to use in the context of Any. However, for URLs which use the - // scheme `http`, `https`, or no scheme, one can optionally set up a type - // server that maps type URLs to message definitions as follows: - // - // * If no scheme is provided, `https` is assumed. - // * An HTTP GET on the URL must yield a [google.protobuf.Type][] - // value in binary format, or produce an error. - // * Applications are allowed to cache lookup results based on the - // URL, or have them precompiled into a binary to avoid any - // lookup. Therefore, binary compatibility needs to be preserved - // on changes to types. (Use versioned type names to manage - // breaking changes.) - // - // Note: this functionality is not currently available in the official - // protobuf release, and it is not used for type URLs beginning with - // type.googleapis.com. - // - // Schemes other than `http`, `https` (or the empty scheme) might be - // used with implementation specific semantics. - // - string type_url = 1; - - // Must be a valid serialized protocol buffer of the above specified type. - bytes value = 2; -} diff --git a/vendor/github.com/golang/protobuf/ptypes/doc.go b/vendor/github.com/golang/protobuf/ptypes/doc.go index c0d595da7..d3c33259d 100644 --- a/vendor/github.com/golang/protobuf/ptypes/doc.go +++ b/vendor/github.com/golang/protobuf/ptypes/doc.go @@ -1,35 +1,10 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. -/* -Package ptypes contains code for interacting with well-known types. -*/ +// Package ptypes provides functionality for interacting with well-known types. +// +// Deprecated: Well-known types have specialized functionality directly +// injected into the generated packages for each message type. +// See the deprecation notice for each function for the suggested alternative. package ptypes diff --git a/vendor/github.com/golang/protobuf/ptypes/duration.go b/vendor/github.com/golang/protobuf/ptypes/duration.go index 26d1ca2fb..b2b55dd85 100644 --- a/vendor/github.com/golang/protobuf/ptypes/duration.go +++ b/vendor/github.com/golang/protobuf/ptypes/duration.go @@ -1,102 +1,76 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. package ptypes -// This file implements conversions between google.protobuf.Duration -// and time.Duration. - import ( "errors" "fmt" "time" - durpb "github.com/golang/protobuf/ptypes/duration" + durationpb "github.com/golang/protobuf/ptypes/duration" ) +// Range of google.protobuf.Duration as specified in duration.proto. +// This is about 10,000 years in seconds. const ( - // Range of a durpb.Duration in seconds, as specified in - // google/protobuf/duration.proto. This is about 10,000 years in seconds. maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) minSeconds = -maxSeconds ) -// validateDuration determines whether the durpb.Duration is valid according to the -// definition in google/protobuf/duration.proto. A valid durpb.Duration -// may still be too large to fit into a time.Duration (the range of durpb.Duration -// is about 10,000 years, and the range of time.Duration is about 290). -func validateDuration(d *durpb.Duration) error { - if d == nil { - return errors.New("duration: nil Duration") - } - if d.Seconds < minSeconds || d.Seconds > maxSeconds { - return fmt.Errorf("duration: %v: seconds out of range", d) - } - if d.Nanos <= -1e9 || d.Nanos >= 1e9 { - return fmt.Errorf("duration: %v: nanos out of range", d) - } - // Seconds and Nanos must have the same sign, unless d.Nanos is zero. - if (d.Seconds < 0 && d.Nanos > 0) || (d.Seconds > 0 && d.Nanos < 0) { - return fmt.Errorf("duration: %v: seconds and nanos have different signs", d) - } - return nil -} - -// Duration converts a durpb.Duration to a time.Duration. Duration -// returns an error if the durpb.Duration is invalid or is too large to be -// represented in a time.Duration. -func Duration(p *durpb.Duration) (time.Duration, error) { - if err := validateDuration(p); err != nil { +// Duration converts a durationpb.Duration to a time.Duration. +// Duration returns an error if dur is invalid or overflows a time.Duration. +// +// Deprecated: Call the dur.AsDuration and dur.CheckValid methods instead. +func Duration(dur *durationpb.Duration) (time.Duration, error) { + if err := validateDuration(dur); err != nil { return 0, err } - d := time.Duration(p.Seconds) * time.Second - if int64(d/time.Second) != p.Seconds { - return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) + d := time.Duration(dur.Seconds) * time.Second + if int64(d/time.Second) != dur.Seconds { + return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) } - if p.Nanos != 0 { - d += time.Duration(p.Nanos) * time.Nanosecond - if (d < 0) != (p.Nanos < 0) { - return 0, fmt.Errorf("duration: %v is out of range for time.Duration", p) + if dur.Nanos != 0 { + d += time.Duration(dur.Nanos) * time.Nanosecond + if (d < 0) != (dur.Nanos < 0) { + return 0, fmt.Errorf("duration: %v is out of range for time.Duration", dur) } } return d, nil } -// DurationProto converts a time.Duration to a durpb.Duration. -func DurationProto(d time.Duration) *durpb.Duration { +// DurationProto converts a time.Duration to a durationpb.Duration. +// +// Deprecated: Call the durationpb.New function instead. +func DurationProto(d time.Duration) *durationpb.Duration { nanos := d.Nanoseconds() secs := nanos / 1e9 nanos -= secs * 1e9 - return &durpb.Duration{ - Seconds: secs, + return &durationpb.Duration{ + Seconds: int64(secs), Nanos: int32(nanos), } } + +// validateDuration determines whether the durationpb.Duration is valid +// according to the definition in google/protobuf/duration.proto. +// A valid durpb.Duration may still be too large to fit into a time.Duration +// Note that the range of durationpb.Duration is about 10,000 years, +// while the range of time.Duration is about 290 years. +func validateDuration(dur *durationpb.Duration) error { + if dur == nil { + return errors.New("duration: nil Duration") + } + if dur.Seconds < minSeconds || dur.Seconds > maxSeconds { + return fmt.Errorf("duration: %v: seconds out of range", dur) + } + if dur.Nanos <= -1e9 || dur.Nanos >= 1e9 { + return fmt.Errorf("duration: %v: nanos out of range", dur) + } + // Seconds and Nanos must have the same sign, unless d.Nanos is zero. + if (dur.Seconds < 0 && dur.Nanos > 0) || (dur.Seconds > 0 && dur.Nanos < 0) { + return fmt.Errorf("duration: %v: seconds and nanos have different signs", dur) + } + return nil +} diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go index 0d681ee21..d0079ee3e 100644 --- a/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go +++ b/vendor/github.com/golang/protobuf/ptypes/duration/duration.pb.go @@ -1,161 +1,63 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: google/protobuf/duration.proto +// source: github.com/golang/protobuf/ptypes/duration/duration.proto package duration import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + durationpb "google.golang.org/protobuf/types/known/durationpb" + reflect "reflect" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +// Symbols defined in public import of google/protobuf/duration.proto. -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +type Duration = durationpb.Duration -// A Duration represents a signed, fixed-length span of time represented -// as a count of seconds and fractions of seconds at nanosecond -// resolution. It is independent of any calendar and concepts like "day" -// or "month". It is related to Timestamp in that the difference between -// two Timestamp values is a Duration and it can be added or subtracted -// from a Timestamp. Range is approximately +-10,000 years. -// -// # Examples -// -// Example 1: Compute Duration from two Timestamps in pseudo code. -// -// Timestamp start = ...; -// Timestamp end = ...; -// Duration duration = ...; -// -// duration.seconds = end.seconds - start.seconds; -// duration.nanos = end.nanos - start.nanos; -// -// if (duration.seconds < 0 && duration.nanos > 0) { -// duration.seconds += 1; -// duration.nanos -= 1000000000; -// } else if (durations.seconds > 0 && duration.nanos < 0) { -// duration.seconds -= 1; -// duration.nanos += 1000000000; -// } -// -// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. -// -// Timestamp start = ...; -// Duration duration = ...; -// Timestamp end = ...; -// -// end.seconds = start.seconds + duration.seconds; -// end.nanos = start.nanos + duration.nanos; -// -// if (end.nanos < 0) { -// end.seconds -= 1; -// end.nanos += 1000000000; -// } else if (end.nanos >= 1000000000) { -// end.seconds += 1; -// end.nanos -= 1000000000; -// } -// -// Example 3: Compute Duration from datetime.timedelta in Python. -// -// td = datetime.timedelta(days=3, minutes=10) -// duration = Duration() -// duration.FromTimedelta(td) -// -// # JSON Mapping -// -// In JSON format, the Duration type is encoded as a string rather than an -// object, where the string ends in the suffix "s" (indicating seconds) and -// is preceded by the number of seconds, with nanoseconds expressed as -// fractional seconds. For example, 3 seconds with 0 nanoseconds should be -// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should -// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 -// microsecond should be expressed in JSON format as "3.000001s". -// -// -type Duration struct { - // Signed seconds of the span of time. Must be from -315,576,000,000 - // to +315,576,000,000 inclusive. Note: these bounds are computed from: - // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years - Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` - // Signed fractions of a second at nanosecond resolution of the span - // of time. Durations less than one second are represented with a 0 - // `seconds` field and a positive or negative `nanos` field. For durations - // of one second or more, a non-zero value for the `nanos` field must be - // of the same sign as the `seconds` field. Must be from -999,999,999 - // to +999,999,999 inclusive. - Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} +var File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor -func (m *Duration) Reset() { *m = Duration{} } -func (m *Duration) String() string { return proto.CompactTextString(m) } -func (*Duration) ProtoMessage() {} -func (*Duration) Descriptor() ([]byte, []int) { - return fileDescriptor_23597b2ebd7ac6c5, []int{0} +var file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = []byte{ + 0x0a, 0x39, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x35, 0x5a, 0x33, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, + 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x3b, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } -func (*Duration) XXX_WellKnownType() string { return "Duration" } - -func (m *Duration) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Duration.Unmarshal(m, b) -} -func (m *Duration) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Duration.Marshal(b, m, deterministic) -} -func (m *Duration) XXX_Merge(src proto.Message) { - xxx_messageInfo_Duration.Merge(m, src) -} -func (m *Duration) XXX_Size() int { - return xxx_messageInfo_Duration.Size(m) -} -func (m *Duration) XXX_DiscardUnknown() { - xxx_messageInfo_Duration.DiscardUnknown(m) +var file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } -var xxx_messageInfo_Duration proto.InternalMessageInfo - -func (m *Duration) GetSeconds() int64 { - if m != nil { - return m.Seconds +func init() { file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() } +func file_github_com_golang_protobuf_ptypes_duration_duration_proto_init() { + if File_github_com_golang_protobuf_ptypes_duration_duration_proto != nil { + return } - return 0 -} - -func (m *Duration) GetNanos() int32 { - if m != nil { - return m.Nanos - } - return 0 -} - -func init() { - proto.RegisterType((*Duration)(nil), "google.protobuf.Duration") -} - -func init() { proto.RegisterFile("google/protobuf/duration.proto", fileDescriptor_23597b2ebd7ac6c5) } - -var fileDescriptor_23597b2ebd7ac6c5 = []byte{ - // 190 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4b, 0xcf, 0xcf, 0x4f, - 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0x29, 0x2d, 0x4a, - 0x2c, 0xc9, 0xcc, 0xcf, 0xd3, 0x03, 0x8b, 0x08, 0xf1, 0x43, 0xe4, 0xf5, 0x60, 0xf2, 0x4a, 0x56, - 0x5c, 0x1c, 0x2e, 0x50, 0x25, 0x42, 0x12, 0x5c, 0xec, 0xc5, 0xa9, 0xc9, 0xf9, 0x79, 0x29, 0xc5, - 0x12, 0x8c, 0x0a, 0x8c, 0x1a, 0xcc, 0x41, 0x30, 0xae, 0x90, 0x08, 0x17, 0x6b, 0x5e, 0x62, 0x5e, - 0x7e, 0xb1, 0x04, 0x93, 0x02, 0xa3, 0x06, 0x6b, 0x10, 0x84, 0xe3, 0x54, 0xc3, 0x25, 0x9c, 0x9c, - 0x9f, 0xab, 0x87, 0x66, 0xa4, 0x13, 0x2f, 0xcc, 0xc0, 0x00, 0x90, 0x48, 0x00, 0x63, 0x94, 0x56, - 0x7a, 0x66, 0x49, 0x46, 0x69, 0x92, 0x5e, 0x72, 0x7e, 0xae, 0x7e, 0x7a, 0x7e, 0x4e, 0x62, 0x5e, - 0x3a, 0xc2, 0x7d, 0x05, 0x25, 0x95, 0x05, 0xa9, 0xc5, 0x70, 0x67, 0xfe, 0x60, 0x64, 0x5c, 0xc4, - 0xc4, 0xec, 0x1e, 0xe0, 0xb4, 0x8a, 0x49, 0xce, 0x1d, 0x62, 0x6e, 0x00, 0x54, 0xa9, 0x5e, 0x78, - 0x6a, 0x4e, 0x8e, 0x77, 0x5e, 0x7e, 0x79, 0x5e, 0x08, 0x48, 0x4b, 0x12, 0x1b, 0xd8, 0x0c, 0x63, - 0x40, 0x00, 0x00, 0x00, 0xff, 0xff, 0xdc, 0x84, 0x30, 0xff, 0xf3, 0x00, 0x00, 0x00, + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_duration_duration_proto = out.File + file_github_com_golang_protobuf_ptypes_duration_duration_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_duration_duration_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_duration_duration_proto_depIdxs = nil } diff --git a/vendor/github.com/golang/protobuf/ptypes/duration/duration.proto b/vendor/github.com/golang/protobuf/ptypes/duration/duration.proto deleted file mode 100644 index 975fce41a..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/duration/duration.proto +++ /dev/null @@ -1,117 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package google.protobuf; - -option csharp_namespace = "Google.Protobuf.WellKnownTypes"; -option cc_enable_arenas = true; -option go_package = "github.com/golang/protobuf/ptypes/duration"; -option java_package = "com.google.protobuf"; -option java_outer_classname = "DurationProto"; -option java_multiple_files = true; -option objc_class_prefix = "GPB"; - -// A Duration represents a signed, fixed-length span of time represented -// as a count of seconds and fractions of seconds at nanosecond -// resolution. It is independent of any calendar and concepts like "day" -// or "month". It is related to Timestamp in that the difference between -// two Timestamp values is a Duration and it can be added or subtracted -// from a Timestamp. Range is approximately +-10,000 years. -// -// # Examples -// -// Example 1: Compute Duration from two Timestamps in pseudo code. -// -// Timestamp start = ...; -// Timestamp end = ...; -// Duration duration = ...; -// -// duration.seconds = end.seconds - start.seconds; -// duration.nanos = end.nanos - start.nanos; -// -// if (duration.seconds < 0 && duration.nanos > 0) { -// duration.seconds += 1; -// duration.nanos -= 1000000000; -// } else if (durations.seconds > 0 && duration.nanos < 0) { -// duration.seconds -= 1; -// duration.nanos += 1000000000; -// } -// -// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code. -// -// Timestamp start = ...; -// Duration duration = ...; -// Timestamp end = ...; -// -// end.seconds = start.seconds + duration.seconds; -// end.nanos = start.nanos + duration.nanos; -// -// if (end.nanos < 0) { -// end.seconds -= 1; -// end.nanos += 1000000000; -// } else if (end.nanos >= 1000000000) { -// end.seconds += 1; -// end.nanos -= 1000000000; -// } -// -// Example 3: Compute Duration from datetime.timedelta in Python. -// -// td = datetime.timedelta(days=3, minutes=10) -// duration = Duration() -// duration.FromTimedelta(td) -// -// # JSON Mapping -// -// In JSON format, the Duration type is encoded as a string rather than an -// object, where the string ends in the suffix "s" (indicating seconds) and -// is preceded by the number of seconds, with nanoseconds expressed as -// fractional seconds. For example, 3 seconds with 0 nanoseconds should be -// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should -// be expressed in JSON format as "3.000000001s", and 3 seconds and 1 -// microsecond should be expressed in JSON format as "3.000001s". -// -// -message Duration { - - // Signed seconds of the span of time. Must be from -315,576,000,000 - // to +315,576,000,000 inclusive. Note: these bounds are computed from: - // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years - int64 seconds = 1; - - // Signed fractions of a second at nanosecond resolution of the span - // of time. Durations less than one second are represented with a 0 - // `seconds` field and a positive or negative `nanos` field. For durations - // of one second or more, a non-zero value for the `nanos` field must be - // of the same sign as the `seconds` field. Must be from -999,999,999 - // to +999,999,999 inclusive. - int32 nanos = 2; -} diff --git a/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go b/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go index b4eb03ecc..16686a655 100644 --- a/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go +++ b/vendor/github.com/golang/protobuf/ptypes/empty/empty.pb.go @@ -1,83 +1,62 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: google/protobuf/empty.proto +// source: github.com/golang/protobuf/ptypes/empty/empty.proto package empty import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + emptypb "google.golang.org/protobuf/types/known/emptypb" + reflect "reflect" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// A generic empty message that you can re-use to avoid defining duplicated -// empty messages in your APIs. A typical example is to use it as the request -// or the response type of an API method. For instance: -// -// service Foo { -// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); -// } -// -// The JSON representation for `Empty` is empty JSON object `{}`. -type Empty struct { - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Empty) Reset() { *m = Empty{} } -func (m *Empty) String() string { return proto.CompactTextString(m) } -func (*Empty) ProtoMessage() {} -func (*Empty) Descriptor() ([]byte, []int) { - return fileDescriptor_900544acb223d5b8, []int{0} -} - -func (*Empty) XXX_WellKnownType() string { return "Empty" } - -func (m *Empty) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Empty.Unmarshal(m, b) -} -func (m *Empty) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Empty.Marshal(b, m, deterministic) -} -func (m *Empty) XXX_Merge(src proto.Message) { - xxx_messageInfo_Empty.Merge(m, src) -} -func (m *Empty) XXX_Size() int { - return xxx_messageInfo_Empty.Size(m) -} -func (m *Empty) XXX_DiscardUnknown() { - xxx_messageInfo_Empty.DiscardUnknown(m) -} - -var xxx_messageInfo_Empty proto.InternalMessageInfo - -func init() { - proto.RegisterType((*Empty)(nil), "google.protobuf.Empty") -} - -func init() { proto.RegisterFile("google/protobuf/empty.proto", fileDescriptor_900544acb223d5b8) } - -var fileDescriptor_900544acb223d5b8 = []byte{ - // 148 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4e, 0xcf, 0xcf, 0x4f, - 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x4f, 0xcd, 0x2d, 0x28, - 0xa9, 0xd4, 0x03, 0x73, 0x85, 0xf8, 0x21, 0x92, 0x7a, 0x30, 0x49, 0x25, 0x76, 0x2e, 0x56, 0x57, - 0x90, 0xbc, 0x53, 0x19, 0x97, 0x70, 0x72, 0x7e, 0xae, 0x1e, 0x9a, 0xbc, 0x13, 0x17, 0x58, 0x36, - 0x00, 0xc4, 0x0d, 0x60, 0x8c, 0x52, 0x4f, 0xcf, 0x2c, 0xc9, 0x28, 0x4d, 0xd2, 0x4b, 0xce, 0xcf, - 0xd5, 0x4f, 0xcf, 0xcf, 0x49, 0xcc, 0x4b, 0x47, 0x58, 0x53, 0x50, 0x52, 0x59, 0x90, 0x5a, 0x0c, - 0xb1, 0xed, 0x07, 0x23, 0xe3, 0x22, 0x26, 0x66, 0xf7, 0x00, 0xa7, 0x55, 0x4c, 0x72, 0xee, 0x10, - 0x13, 0x03, 0xa0, 0xea, 0xf4, 0xc2, 0x53, 0x73, 0x72, 0xbc, 0xf3, 0xf2, 0xcb, 0xf3, 0x42, 0x40, - 0xea, 0x93, 0xd8, 0xc0, 0x06, 0x18, 0x03, 0x02, 0x00, 0x00, 0xff, 0xff, 0x64, 0xd4, 0xb3, 0xa6, - 0xb7, 0x00, 0x00, 0x00, +// Symbols defined in public import of google/protobuf/empty.proto. + +type Empty = emptypb.Empty + +var File_github_com_golang_protobuf_ptypes_empty_empty_proto protoreflect.FileDescriptor + +var file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = []byte{ + 0x0a, 0x33, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1b, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x42, 0x2f, 0x5a, 0x2d, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, + 0x2f, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2f, 0x70, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x65, 0x6d, 0x70, 0x74, 0x79, 0x3b, 0x65, 0x6d, + 0x70, 0x74, 0x79, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name +} + +func init() { file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() } +func file_github_com_golang_protobuf_ptypes_empty_empty_proto_init() { + if File_github_com_golang_protobuf_ptypes_empty_empty_proto != nil { + return + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_empty_empty_proto = out.File + file_github_com_golang_protobuf_ptypes_empty_empty_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_empty_empty_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_empty_empty_proto_depIdxs = nil } diff --git a/vendor/github.com/golang/protobuf/ptypes/empty/empty.proto b/vendor/github.com/golang/protobuf/ptypes/empty/empty.proto deleted file mode 100644 index 03cacd233..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/empty/empty.proto +++ /dev/null @@ -1,52 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package google.protobuf; - -option csharp_namespace = "Google.Protobuf.WellKnownTypes"; -option go_package = "github.com/golang/protobuf/ptypes/empty"; -option java_package = "com.google.protobuf"; -option java_outer_classname = "EmptyProto"; -option java_multiple_files = true; -option objc_class_prefix = "GPB"; -option cc_enable_arenas = true; - -// A generic empty message that you can re-use to avoid defining duplicated -// empty messages in your APIs. A typical example is to use it as the request -// or the response type of an API method. For instance: -// -// service Foo { -// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty); -// } -// -// The JSON representation for `Empty` is empty JSON object `{}`. -message Empty {} diff --git a/vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go b/vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go deleted file mode 100644 index 33daa73dd..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/struct/struct.pb.go +++ /dev/null @@ -1,336 +0,0 @@ -// Code generated by protoc-gen-go. DO NOT EDIT. -// source: google/protobuf/struct.proto - -package structpb - -import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" -) - -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf - -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package - -// `NullValue` is a singleton enumeration to represent the null value for the -// `Value` type union. -// -// The JSON representation for `NullValue` is JSON `null`. -type NullValue int32 - -const ( - // Null value. - NullValue_NULL_VALUE NullValue = 0 -) - -var NullValue_name = map[int32]string{ - 0: "NULL_VALUE", -} - -var NullValue_value = map[string]int32{ - "NULL_VALUE": 0, -} - -func (x NullValue) String() string { - return proto.EnumName(NullValue_name, int32(x)) -} - -func (NullValue) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_df322afd6c9fb402, []int{0} -} - -func (NullValue) XXX_WellKnownType() string { return "NullValue" } - -// `Struct` represents a structured data value, consisting of fields -// which map to dynamically typed values. In some languages, `Struct` -// might be supported by a native representation. For example, in -// scripting languages like JS a struct is represented as an -// object. The details of that representation are described together -// with the proto support for the language. -// -// The JSON representation for `Struct` is JSON object. -type Struct struct { - // Unordered map of dynamically typed values. - Fields map[string]*Value `protobuf:"bytes,1,rep,name=fields,proto3" json:"fields,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Struct) Reset() { *m = Struct{} } -func (m *Struct) String() string { return proto.CompactTextString(m) } -func (*Struct) ProtoMessage() {} -func (*Struct) Descriptor() ([]byte, []int) { - return fileDescriptor_df322afd6c9fb402, []int{0} -} - -func (*Struct) XXX_WellKnownType() string { return "Struct" } - -func (m *Struct) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Struct.Unmarshal(m, b) -} -func (m *Struct) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Struct.Marshal(b, m, deterministic) -} -func (m *Struct) XXX_Merge(src proto.Message) { - xxx_messageInfo_Struct.Merge(m, src) -} -func (m *Struct) XXX_Size() int { - return xxx_messageInfo_Struct.Size(m) -} -func (m *Struct) XXX_DiscardUnknown() { - xxx_messageInfo_Struct.DiscardUnknown(m) -} - -var xxx_messageInfo_Struct proto.InternalMessageInfo - -func (m *Struct) GetFields() map[string]*Value { - if m != nil { - return m.Fields - } - return nil -} - -// `Value` represents a dynamically typed value which can be either -// null, a number, a string, a boolean, a recursive struct value, or a -// list of values. A producer of value is expected to set one of that -// variants, absence of any variant indicates an error. -// -// The JSON representation for `Value` is JSON value. -type Value struct { - // The kind of value. - // - // Types that are valid to be assigned to Kind: - // *Value_NullValue - // *Value_NumberValue - // *Value_StringValue - // *Value_BoolValue - // *Value_StructValue - // *Value_ListValue - Kind isValue_Kind `protobuf_oneof:"kind"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *Value) Reset() { *m = Value{} } -func (m *Value) String() string { return proto.CompactTextString(m) } -func (*Value) ProtoMessage() {} -func (*Value) Descriptor() ([]byte, []int) { - return fileDescriptor_df322afd6c9fb402, []int{1} -} - -func (*Value) XXX_WellKnownType() string { return "Value" } - -func (m *Value) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Value.Unmarshal(m, b) -} -func (m *Value) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Value.Marshal(b, m, deterministic) -} -func (m *Value) XXX_Merge(src proto.Message) { - xxx_messageInfo_Value.Merge(m, src) -} -func (m *Value) XXX_Size() int { - return xxx_messageInfo_Value.Size(m) -} -func (m *Value) XXX_DiscardUnknown() { - xxx_messageInfo_Value.DiscardUnknown(m) -} - -var xxx_messageInfo_Value proto.InternalMessageInfo - -type isValue_Kind interface { - isValue_Kind() -} - -type Value_NullValue struct { - NullValue NullValue `protobuf:"varint,1,opt,name=null_value,json=nullValue,proto3,enum=google.protobuf.NullValue,oneof"` -} - -type Value_NumberValue struct { - NumberValue float64 `protobuf:"fixed64,2,opt,name=number_value,json=numberValue,proto3,oneof"` -} - -type Value_StringValue struct { - StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"` -} - -type Value_BoolValue struct { - BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof"` -} - -type Value_StructValue struct { - StructValue *Struct `protobuf:"bytes,5,opt,name=struct_value,json=structValue,proto3,oneof"` -} - -type Value_ListValue struct { - ListValue *ListValue `protobuf:"bytes,6,opt,name=list_value,json=listValue,proto3,oneof"` -} - -func (*Value_NullValue) isValue_Kind() {} - -func (*Value_NumberValue) isValue_Kind() {} - -func (*Value_StringValue) isValue_Kind() {} - -func (*Value_BoolValue) isValue_Kind() {} - -func (*Value_StructValue) isValue_Kind() {} - -func (*Value_ListValue) isValue_Kind() {} - -func (m *Value) GetKind() isValue_Kind { - if m != nil { - return m.Kind - } - return nil -} - -func (m *Value) GetNullValue() NullValue { - if x, ok := m.GetKind().(*Value_NullValue); ok { - return x.NullValue - } - return NullValue_NULL_VALUE -} - -func (m *Value) GetNumberValue() float64 { - if x, ok := m.GetKind().(*Value_NumberValue); ok { - return x.NumberValue - } - return 0 -} - -func (m *Value) GetStringValue() string { - if x, ok := m.GetKind().(*Value_StringValue); ok { - return x.StringValue - } - return "" -} - -func (m *Value) GetBoolValue() bool { - if x, ok := m.GetKind().(*Value_BoolValue); ok { - return x.BoolValue - } - return false -} - -func (m *Value) GetStructValue() *Struct { - if x, ok := m.GetKind().(*Value_StructValue); ok { - return x.StructValue - } - return nil -} - -func (m *Value) GetListValue() *ListValue { - if x, ok := m.GetKind().(*Value_ListValue); ok { - return x.ListValue - } - return nil -} - -// XXX_OneofWrappers is for the internal use of the proto package. -func (*Value) XXX_OneofWrappers() []interface{} { - return []interface{}{ - (*Value_NullValue)(nil), - (*Value_NumberValue)(nil), - (*Value_StringValue)(nil), - (*Value_BoolValue)(nil), - (*Value_StructValue)(nil), - (*Value_ListValue)(nil), - } -} - -// `ListValue` is a wrapper around a repeated field of values. -// -// The JSON representation for `ListValue` is JSON array. -type ListValue struct { - // Repeated field of dynamically typed values. - Values []*Value `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} - -func (m *ListValue) Reset() { *m = ListValue{} } -func (m *ListValue) String() string { return proto.CompactTextString(m) } -func (*ListValue) ProtoMessage() {} -func (*ListValue) Descriptor() ([]byte, []int) { - return fileDescriptor_df322afd6c9fb402, []int{2} -} - -func (*ListValue) XXX_WellKnownType() string { return "ListValue" } - -func (m *ListValue) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_ListValue.Unmarshal(m, b) -} -func (m *ListValue) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_ListValue.Marshal(b, m, deterministic) -} -func (m *ListValue) XXX_Merge(src proto.Message) { - xxx_messageInfo_ListValue.Merge(m, src) -} -func (m *ListValue) XXX_Size() int { - return xxx_messageInfo_ListValue.Size(m) -} -func (m *ListValue) XXX_DiscardUnknown() { - xxx_messageInfo_ListValue.DiscardUnknown(m) -} - -var xxx_messageInfo_ListValue proto.InternalMessageInfo - -func (m *ListValue) GetValues() []*Value { - if m != nil { - return m.Values - } - return nil -} - -func init() { - proto.RegisterEnum("google.protobuf.NullValue", NullValue_name, NullValue_value) - proto.RegisterType((*Struct)(nil), "google.protobuf.Struct") - proto.RegisterMapType((map[string]*Value)(nil), "google.protobuf.Struct.FieldsEntry") - proto.RegisterType((*Value)(nil), "google.protobuf.Value") - proto.RegisterType((*ListValue)(nil), "google.protobuf.ListValue") -} - -func init() { proto.RegisterFile("google/protobuf/struct.proto", fileDescriptor_df322afd6c9fb402) } - -var fileDescriptor_df322afd6c9fb402 = []byte{ - // 417 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x74, 0x92, 0x41, 0x8b, 0xd3, 0x40, - 0x14, 0xc7, 0x3b, 0xc9, 0x36, 0x98, 0x17, 0x59, 0x97, 0x11, 0xb4, 0xac, 0xa2, 0xa1, 0x7b, 0x09, - 0x22, 0x29, 0xd6, 0x8b, 0x18, 0x2f, 0x06, 0xd6, 0x5d, 0x30, 0x2c, 0x31, 0xba, 0x15, 0xbc, 0x94, - 0x26, 0x4d, 0x63, 0xe8, 0x74, 0x26, 0x24, 0x33, 0x4a, 0x8f, 0x7e, 0x0b, 0xcf, 0x1e, 0x3d, 0xfa, - 0xe9, 0x3c, 0xca, 0xcc, 0x24, 0xa9, 0xb4, 0xf4, 0x94, 0xbc, 0xf7, 0x7e, 0xef, 0x3f, 0xef, 0xff, - 0x66, 0xe0, 0x71, 0xc1, 0x58, 0x41, 0xf2, 0x49, 0x55, 0x33, 0xce, 0x52, 0xb1, 0x9a, 0x34, 0xbc, - 0x16, 0x19, 0xf7, 0x55, 0x8c, 0xef, 0xe9, 0xaa, 0xdf, 0x55, 0xc7, 0x3f, 0x11, 0x58, 0x1f, 0x15, - 0x81, 0x03, 0xb0, 0x56, 0x65, 0x4e, 0x96, 0xcd, 0x08, 0xb9, 0xa6, 0xe7, 0x4c, 0x2f, 0xfc, 0x3d, - 0xd8, 0xd7, 0xa0, 0xff, 0x4e, 0x51, 0x97, 0x94, 0xd7, 0xdb, 0xa4, 0x6d, 0x39, 0xff, 0x00, 0xce, - 0x7f, 0x69, 0x7c, 0x06, 0xe6, 0x3a, 0xdf, 0x8e, 0x90, 0x8b, 0x3c, 0x3b, 0x91, 0xbf, 0xf8, 0x39, - 0x0c, 0xbf, 0x2d, 0x88, 0xc8, 0x47, 0x86, 0x8b, 0x3c, 0x67, 0xfa, 0xe0, 0x40, 0x7c, 0x26, 0xab, - 0x89, 0x86, 0x5e, 0x1b, 0xaf, 0xd0, 0xf8, 0x8f, 0x01, 0x43, 0x95, 0xc4, 0x01, 0x00, 0x15, 0x84, - 0xcc, 0xb5, 0x80, 0x14, 0x3d, 0x9d, 0x9e, 0x1f, 0x08, 0xdc, 0x08, 0x42, 0x14, 0x7f, 0x3d, 0x48, - 0x6c, 0xda, 0x05, 0xf8, 0x02, 0xee, 0x52, 0xb1, 0x49, 0xf3, 0x7a, 0xbe, 0x3b, 0x1f, 0x5d, 0x0f, - 0x12, 0x47, 0x67, 0x7b, 0xa8, 0xe1, 0x75, 0x49, 0x8b, 0x16, 0x32, 0xe5, 0xe0, 0x12, 0xd2, 0x59, - 0x0d, 0x3d, 0x05, 0x48, 0x19, 0xeb, 0xc6, 0x38, 0x71, 0x91, 0x77, 0x47, 0x1e, 0x25, 0x73, 0x1a, - 0x78, 0xa3, 0x54, 0x44, 0xc6, 0x5b, 0x64, 0xa8, 0xac, 0x3e, 0x3c, 0xb2, 0xc7, 0x56, 0x5e, 0x64, - 0xbc, 0x77, 0x49, 0xca, 0xa6, 0xeb, 0xb5, 0x54, 0xef, 0xa1, 0xcb, 0xa8, 0x6c, 0x78, 0xef, 0x92, - 0x74, 0x41, 0x68, 0xc1, 0xc9, 0xba, 0xa4, 0xcb, 0x71, 0x00, 0x76, 0x4f, 0x60, 0x1f, 0x2c, 0x25, - 0xd6, 0xdd, 0xe8, 0xb1, 0xa5, 0xb7, 0xd4, 0xb3, 0x47, 0x60, 0xf7, 0x4b, 0xc4, 0xa7, 0x00, 0x37, - 0xb7, 0x51, 0x34, 0x9f, 0xbd, 0x8d, 0x6e, 0x2f, 0xcf, 0x06, 0xe1, 0x0f, 0x04, 0xf7, 0x33, 0xb6, - 0xd9, 0x97, 0x08, 0x1d, 0xed, 0x26, 0x96, 0x71, 0x8c, 0xbe, 0xbc, 0x28, 0x4a, 0xfe, 0x55, 0xa4, - 0x7e, 0xc6, 0x36, 0x93, 0x82, 0x91, 0x05, 0x2d, 0x76, 0x4f, 0xb1, 0xe2, 0xdb, 0x2a, 0x6f, 0xda, - 0x17, 0x19, 0xe8, 0x4f, 0x95, 0xfe, 0x45, 0xe8, 0x97, 0x61, 0x5e, 0xc5, 0xe1, 0x6f, 0xe3, 0xc9, - 0x95, 0x16, 0x8f, 0xbb, 0xf9, 0x3e, 0xe7, 0x84, 0xbc, 0xa7, 0xec, 0x3b, 0xfd, 0x24, 0x3b, 0x53, - 0x4b, 0x49, 0xbd, 0xfc, 0x17, 0x00, 0x00, 0xff, 0xff, 0xe8, 0x1b, 0x59, 0xf8, 0xe5, 0x02, 0x00, - 0x00, -} diff --git a/vendor/github.com/golang/protobuf/ptypes/struct/struct.proto b/vendor/github.com/golang/protobuf/ptypes/struct/struct.proto deleted file mode 100644 index 7d7808e7f..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/struct/struct.proto +++ /dev/null @@ -1,96 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package google.protobuf; - -option csharp_namespace = "Google.Protobuf.WellKnownTypes"; -option cc_enable_arenas = true; -option go_package = "github.com/golang/protobuf/ptypes/struct;structpb"; -option java_package = "com.google.protobuf"; -option java_outer_classname = "StructProto"; -option java_multiple_files = true; -option objc_class_prefix = "GPB"; - - -// `Struct` represents a structured data value, consisting of fields -// which map to dynamically typed values. In some languages, `Struct` -// might be supported by a native representation. For example, in -// scripting languages like JS a struct is represented as an -// object. The details of that representation are described together -// with the proto support for the language. -// -// The JSON representation for `Struct` is JSON object. -message Struct { - // Unordered map of dynamically typed values. - map fields = 1; -} - -// `Value` represents a dynamically typed value which can be either -// null, a number, a string, a boolean, a recursive struct value, or a -// list of values. A producer of value is expected to set one of that -// variants, absence of any variant indicates an error. -// -// The JSON representation for `Value` is JSON value. -message Value { - // The kind of value. - oneof kind { - // Represents a null value. - NullValue null_value = 1; - // Represents a double value. - double number_value = 2; - // Represents a string value. - string string_value = 3; - // Represents a boolean value. - bool bool_value = 4; - // Represents a structured value. - Struct struct_value = 5; - // Represents a repeated `Value`. - ListValue list_value = 6; - } -} - -// `NullValue` is a singleton enumeration to represent the null value for the -// `Value` type union. -// -// The JSON representation for `NullValue` is JSON `null`. -enum NullValue { - // Null value. - NULL_VALUE = 0; -} - -// `ListValue` is a wrapper around a repeated field of values. -// -// The JSON representation for `ListValue` is JSON array. -message ListValue { - // Repeated field of dynamically typed values. - repeated Value values = 1; -} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp.go b/vendor/github.com/golang/protobuf/ptypes/timestamp.go index 8da0df01a..8368a3f70 100644 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp.go +++ b/vendor/github.com/golang/protobuf/ptypes/timestamp.go @@ -1,46 +1,18 @@ -// Go support for Protocol Buffers - Google's data interchange format -// -// Copyright 2016 The Go Authors. All rights reserved. -// https://github.com/golang/protobuf -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// Copyright 2016 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. package ptypes -// This file implements operations on google.protobuf.Timestamp. - import ( "errors" "fmt" "time" - tspb "github.com/golang/protobuf/ptypes/timestamp" + timestamppb "github.com/golang/protobuf/ptypes/timestamp" ) +// Range of google.protobuf.Duration as specified in timestamp.proto. const ( // Seconds field of the earliest valid Timestamp. // This is time.Date(1, 1, 1, 0, 0, 0, 0, time.UTC).Unix(). @@ -50,44 +22,20 @@ const ( maxValidSeconds = 253402300800 ) -// validateTimestamp determines whether a Timestamp is valid. -// A valid timestamp represents a time in the range -// [0001-01-01, 10000-01-01) and has a Nanos field -// in the range [0, 1e9). -// -// If the Timestamp is valid, validateTimestamp returns nil. -// Otherwise, it returns an error that describes -// the problem. -// -// Every valid Timestamp can be represented by a time.Time, but the converse is not true. -func validateTimestamp(ts *tspb.Timestamp) error { - if ts == nil { - return errors.New("timestamp: nil Timestamp") - } - if ts.Seconds < minValidSeconds { - return fmt.Errorf("timestamp: %v before 0001-01-01", ts) - } - if ts.Seconds >= maxValidSeconds { - return fmt.Errorf("timestamp: %v after 10000-01-01", ts) - } - if ts.Nanos < 0 || ts.Nanos >= 1e9 { - return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) - } - return nil -} - -// Timestamp converts a google.protobuf.Timestamp proto to a time.Time. +// Timestamp converts a timestamppb.Timestamp to a time.Time. // It returns an error if the argument is invalid. // -// Unlike most Go functions, if Timestamp returns an error, the first return value -// is not the zero time.Time. Instead, it is the value obtained from the +// Unlike most Go functions, if Timestamp returns an error, the first return +// value is not the zero time.Time. Instead, it is the value obtained from the // time.Unix function when passed the contents of the Timestamp, in the UTC // locale. This may or may not be a meaningful time; many invalid Timestamps // do map to valid time.Times. // // A nil Timestamp returns an error. The first return value in that case is // undefined. -func Timestamp(ts *tspb.Timestamp) (time.Time, error) { +// +// Deprecated: Call the ts.AsTime and ts.CheckValid methods instead. +func Timestamp(ts *timestamppb.Timestamp) (time.Time, error) { // Don't return the zero value on error, because corresponds to a valid // timestamp. Instead return whatever time.Unix gives us. var t time.Time @@ -100,7 +48,9 @@ func Timestamp(ts *tspb.Timestamp) (time.Time, error) { } // TimestampNow returns a google.protobuf.Timestamp for the current time. -func TimestampNow() *tspb.Timestamp { +// +// Deprecated: Call the timestamppb.Now function instead. +func TimestampNow() *timestamppb.Timestamp { ts, err := TimestampProto(time.Now()) if err != nil { panic("ptypes: time.Now() out of Timestamp range") @@ -110,8 +60,10 @@ func TimestampNow() *tspb.Timestamp { // TimestampProto converts the time.Time to a google.protobuf.Timestamp proto. // It returns an error if the resulting Timestamp is invalid. -func TimestampProto(t time.Time) (*tspb.Timestamp, error) { - ts := &tspb.Timestamp{ +// +// Deprecated: Call the timestamppb.New function instead. +func TimestampProto(t time.Time) (*timestamppb.Timestamp, error) { + ts := ×tamppb.Timestamp{ Seconds: t.Unix(), Nanos: int32(t.Nanosecond()), } @@ -121,12 +73,40 @@ func TimestampProto(t time.Time) (*tspb.Timestamp, error) { return ts, nil } -// TimestampString returns the RFC 3339 string for valid Timestamps. For invalid -// Timestamps, it returns an error message in parentheses. -func TimestampString(ts *tspb.Timestamp) string { +// TimestampString returns the RFC 3339 string for valid Timestamps. +// For invalid Timestamps, it returns an error message in parentheses. +// +// Deprecated: Call the ts.AsTime method instead, +// followed by a call to the Format method on the time.Time value. +func TimestampString(ts *timestamppb.Timestamp) string { t, err := Timestamp(ts) if err != nil { return fmt.Sprintf("(%v)", err) } return t.Format(time.RFC3339Nano) } + +// validateTimestamp determines whether a Timestamp is valid. +// A valid timestamp represents a time in the range [0001-01-01, 10000-01-01) +// and has a Nanos field in the range [0, 1e9). +// +// If the Timestamp is valid, validateTimestamp returns nil. +// Otherwise, it returns an error that describes the problem. +// +// Every valid Timestamp can be represented by a time.Time, +// but the converse is not true. +func validateTimestamp(ts *timestamppb.Timestamp) error { + if ts == nil { + return errors.New("timestamp: nil Timestamp") + } + if ts.Seconds < minValidSeconds { + return fmt.Errorf("timestamp: %v before 0001-01-01", ts) + } + if ts.Seconds >= maxValidSeconds { + return fmt.Errorf("timestamp: %v after 10000-01-01", ts) + } + if ts.Nanos < 0 || ts.Nanos >= 1e9 { + return fmt.Errorf("timestamp: %v: nanos not in range [0, 1e9)", ts) + } + return nil +} diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go index 31cd846de..a76f80760 100644 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go +++ b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.pb.go @@ -1,179 +1,64 @@ // Code generated by protoc-gen-go. DO NOT EDIT. -// source: google/protobuf/timestamp.proto +// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto package timestamp import ( - fmt "fmt" - proto "github.com/golang/protobuf/proto" - math "math" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" + reflect "reflect" ) -// Reference imports to suppress errors if they are not otherwise used. -var _ = proto.Marshal -var _ = fmt.Errorf -var _ = math.Inf +// Symbols defined in public import of google/protobuf/timestamp.proto. -// This is a compile-time assertion to ensure that this generated file -// is compatible with the proto package it is being compiled against. -// A compilation error at this line likely means your copy of the -// proto package needs to be updated. -const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package +type Timestamp = timestamppb.Timestamp -// A Timestamp represents a point in time independent of any time zone -// or calendar, represented as seconds and fractions of seconds at -// nanosecond resolution in UTC Epoch time. It is encoded using the -// Proleptic Gregorian Calendar which extends the Gregorian calendar -// backwards to year one. It is encoded assuming all minutes are 60 -// seconds long, i.e. leap seconds are "smeared" so that no leap second -// table is needed for interpretation. Range is from -// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. -// By restricting to that range, we ensure that we can convert to -// and from RFC 3339 date strings. -// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). -// -// # Examples -// -// Example 1: Compute Timestamp from POSIX `time()`. -// -// Timestamp timestamp; -// timestamp.set_seconds(time(NULL)); -// timestamp.set_nanos(0); -// -// Example 2: Compute Timestamp from POSIX `gettimeofday()`. -// -// struct timeval tv; -// gettimeofday(&tv, NULL); -// -// Timestamp timestamp; -// timestamp.set_seconds(tv.tv_sec); -// timestamp.set_nanos(tv.tv_usec * 1000); -// -// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. -// -// FILETIME ft; -// GetSystemTimeAsFileTime(&ft); -// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; -// -// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z -// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. -// Timestamp timestamp; -// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); -// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); -// -// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. -// -// long millis = System.currentTimeMillis(); -// -// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) -// .setNanos((int) ((millis % 1000) * 1000000)).build(); -// -// -// Example 5: Compute Timestamp from current time in Python. -// -// timestamp = Timestamp() -// timestamp.GetCurrentTime() -// -// # JSON Mapping -// -// In JSON format, the Timestamp type is encoded as a string in the -// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the -// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" -// where {year} is always expressed using four digits while {month}, {day}, -// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional -// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), -// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone -// is required. A proto3 JSON serializer should always use UTC (as indicated by -// "Z") when printing the Timestamp type and a proto3 JSON parser should be -// able to accept both UTC and other timezones (as indicated by an offset). -// -// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past -// 01:30 UTC on January 15, 2017. -// -// In JavaScript, one can convert a Date object to this format using the -// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] -// method. In Python, a standard `datetime.datetime` object can be converted -// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) -// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one -// can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( -// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime-- -// ) to obtain a formatter capable of generating timestamps in this format. -// -// -type Timestamp struct { - // Represents seconds of UTC time since Unix epoch - // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - // 9999-12-31T23:59:59Z inclusive. - Seconds int64 `protobuf:"varint,1,opt,name=seconds,proto3" json:"seconds,omitempty"` - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - Nanos int32 `protobuf:"varint,2,opt,name=nanos,proto3" json:"nanos,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` -} +var File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto protoreflect.FileDescriptor -func (m *Timestamp) Reset() { *m = Timestamp{} } -func (m *Timestamp) String() string { return proto.CompactTextString(m) } -func (*Timestamp) ProtoMessage() {} -func (*Timestamp) Descriptor() ([]byte, []int) { - return fileDescriptor_292007bbfe81227e, []int{0} +var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = []byte{ + 0x0a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2f, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, + 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x42, 0x37, + 0x5a, 0x35, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x6f, 0x6c, + 0x61, 0x6e, 0x67, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x70, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x3b, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x50, 0x00, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x33, } -func (*Timestamp) XXX_WellKnownType() string { return "Timestamp" } - -func (m *Timestamp) XXX_Unmarshal(b []byte) error { - return xxx_messageInfo_Timestamp.Unmarshal(m, b) -} -func (m *Timestamp) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { - return xxx_messageInfo_Timestamp.Marshal(b, m, deterministic) -} -func (m *Timestamp) XXX_Merge(src proto.Message) { - xxx_messageInfo_Timestamp.Merge(m, src) -} -func (m *Timestamp) XXX_Size() int { - return xxx_messageInfo_Timestamp.Size(m) -} -func (m *Timestamp) XXX_DiscardUnknown() { - xxx_messageInfo_Timestamp.DiscardUnknown(m) +var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = []interface{}{} +var file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = []int32{ + 0, // [0:0] is the sub-list for method output_type + 0, // [0:0] is the sub-list for method input_type + 0, // [0:0] is the sub-list for extension type_name + 0, // [0:0] is the sub-list for extension extendee + 0, // [0:0] is the sub-list for field type_name } -var xxx_messageInfo_Timestamp proto.InternalMessageInfo - -func (m *Timestamp) GetSeconds() int64 { - if m != nil { - return m.Seconds +func init() { file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() } +func file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_init() { + if File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto != nil { + return } - return 0 -} - -func (m *Timestamp) GetNanos() int32 { - if m != nil { - return m.Nanos - } - return 0 -} - -func init() { - proto.RegisterType((*Timestamp)(nil), "google.protobuf.Timestamp") -} - -func init() { proto.RegisterFile("google/protobuf/timestamp.proto", fileDescriptor_292007bbfe81227e) } - -var fileDescriptor_292007bbfe81227e = []byte{ - // 191 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x92, 0x4f, 0xcf, 0xcf, 0x4f, - 0xcf, 0x49, 0xd5, 0x2f, 0x28, 0xca, 0x2f, 0xc9, 0x4f, 0x2a, 0x4d, 0xd3, 0x2f, 0xc9, 0xcc, 0x4d, - 0x2d, 0x2e, 0x49, 0xcc, 0x2d, 0xd0, 0x03, 0x0b, 0x09, 0xf1, 0x43, 0x14, 0xe8, 0xc1, 0x14, 0x28, - 0x59, 0x73, 0x71, 0x86, 0xc0, 0xd4, 0x08, 0x49, 0x70, 0xb1, 0x17, 0xa7, 0x26, 0xe7, 0xe7, 0xa5, - 0x14, 0x4b, 0x30, 0x2a, 0x30, 0x6a, 0x30, 0x07, 0xc1, 0xb8, 0x42, 0x22, 0x5c, 0xac, 0x79, 0x89, - 0x79, 0xf9, 0xc5, 0x12, 0x4c, 0x0a, 0x8c, 0x1a, 0xac, 0x41, 0x10, 0x8e, 0x53, 0x1d, 0x97, 0x70, - 0x72, 0x7e, 0xae, 0x1e, 0x9a, 0x99, 0x4e, 0x7c, 0x70, 0x13, 0x03, 0x40, 0x42, 0x01, 0x8c, 0x51, - 0xda, 0xe9, 0x99, 0x25, 0x19, 0xa5, 0x49, 0x7a, 0xc9, 0xf9, 0xb9, 0xfa, 0xe9, 0xf9, 0x39, 0x89, - 0x79, 0xe9, 0x08, 0x27, 0x16, 0x94, 0x54, 0x16, 0xa4, 0x16, 0x23, 0x5c, 0xfa, 0x83, 0x91, 0x71, - 0x11, 0x13, 0xb3, 0x7b, 0x80, 0xd3, 0x2a, 0x26, 0x39, 0x77, 0x88, 0xc9, 0x01, 0x50, 0xb5, 0x7a, - 0xe1, 0xa9, 0x39, 0x39, 0xde, 0x79, 0xf9, 0xe5, 0x79, 0x21, 0x20, 0x3d, 0x49, 0x6c, 0x60, 0x43, - 0x8c, 0x01, 0x01, 0x00, 0x00, 0xff, 0xff, 0xbc, 0x77, 0x4a, 0x07, 0xf7, 0x00, 0x00, 0x00, + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc, + NumEnums: 0, + NumMessages: 0, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes, + DependencyIndexes: file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs, + }.Build() + File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto = out.File + file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_rawDesc = nil + file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_goTypes = nil + file_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto_depIdxs = nil } diff --git a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto b/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto deleted file mode 100644 index eafb3fa03..000000000 --- a/vendor/github.com/golang/protobuf/ptypes/timestamp/timestamp.proto +++ /dev/null @@ -1,135 +0,0 @@ -// Protocol Buffers - Google's data interchange format -// Copyright 2008 Google Inc. All rights reserved. -// https://developers.google.com/protocol-buffers/ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -syntax = "proto3"; - -package google.protobuf; - -option csharp_namespace = "Google.Protobuf.WellKnownTypes"; -option cc_enable_arenas = true; -option go_package = "github.com/golang/protobuf/ptypes/timestamp"; -option java_package = "com.google.protobuf"; -option java_outer_classname = "TimestampProto"; -option java_multiple_files = true; -option objc_class_prefix = "GPB"; - -// A Timestamp represents a point in time independent of any time zone -// or calendar, represented as seconds and fractions of seconds at -// nanosecond resolution in UTC Epoch time. It is encoded using the -// Proleptic Gregorian Calendar which extends the Gregorian calendar -// backwards to year one. It is encoded assuming all minutes are 60 -// seconds long, i.e. leap seconds are "smeared" so that no leap second -// table is needed for interpretation. Range is from -// 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. -// By restricting to that range, we ensure that we can convert to -// and from RFC 3339 date strings. -// See [https://www.ietf.org/rfc/rfc3339.txt](https://www.ietf.org/rfc/rfc3339.txt). -// -// # Examples -// -// Example 1: Compute Timestamp from POSIX `time()`. -// -// Timestamp timestamp; -// timestamp.set_seconds(time(NULL)); -// timestamp.set_nanos(0); -// -// Example 2: Compute Timestamp from POSIX `gettimeofday()`. -// -// struct timeval tv; -// gettimeofday(&tv, NULL); -// -// Timestamp timestamp; -// timestamp.set_seconds(tv.tv_sec); -// timestamp.set_nanos(tv.tv_usec * 1000); -// -// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`. -// -// FILETIME ft; -// GetSystemTimeAsFileTime(&ft); -// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime; -// -// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z -// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z. -// Timestamp timestamp; -// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL)); -// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100)); -// -// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`. -// -// long millis = System.currentTimeMillis(); -// -// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000) -// .setNanos((int) ((millis % 1000) * 1000000)).build(); -// -// -// Example 5: Compute Timestamp from current time in Python. -// -// timestamp = Timestamp() -// timestamp.GetCurrentTime() -// -// # JSON Mapping -// -// In JSON format, the Timestamp type is encoded as a string in the -// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the -// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z" -// where {year} is always expressed using four digits while {month}, {day}, -// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional -// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution), -// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone -// is required. A proto3 JSON serializer should always use UTC (as indicated by -// "Z") when printing the Timestamp type and a proto3 JSON parser should be -// able to accept both UTC and other timezones (as indicated by an offset). -// -// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past -// 01:30 UTC on January 15, 2017. -// -// In JavaScript, one can convert a Date object to this format using the -// standard [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString] -// method. In Python, a standard `datetime.datetime` object can be converted -// to this format using [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) -// with the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one -// can use the Joda Time's [`ISODateTimeFormat.dateTime()`]( -// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime-- -// ) to obtain a formatter capable of generating timestamps in this format. -// -// -message Timestamp { - - // Represents seconds of UTC time since Unix epoch - // 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to - // 9999-12-31T23:59:59Z inclusive. - int64 seconds = 1; - - // Non-negative fractions of a second at nanosecond resolution. Negative - // second values with fractions must still have non-negative nanos values - // that count forward in time. Must be from 0 to 999,999,999 - // inclusive. - int32 nanos = 2; -} diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE b/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE deleted file mode 100644 index 14127cd83..000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -(The MIT License) - -Copyright (c) 2017 marvin + konsorten GmbH (open-source@konsorten.de) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md b/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md deleted file mode 100644 index 195333e51..000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/README.md +++ /dev/null @@ -1,41 +0,0 @@ -# Windows Terminal Sequences - -This library allow for enabling Windows terminal color support for Go. - -See [Console Virtual Terminal Sequences](https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences) for details. - -## Usage - -```go -import ( - "syscall" - - sequences "github.com/konsorten/go-windows-terminal-sequences" -) - -func main() { - sequences.EnableVirtualTerminalProcessing(syscall.Stdout, true) -} - -``` - -## Authors - -The tool is sponsored by the [marvin + konsorten GmbH](http://www.konsorten.de). - -We thank all the authors who provided code to this library: - -* Felix Kollmann -* Nicolas Perraut - -## License - -(The MIT License) - -Copyright (c) 2018 marvin + konsorten GmbH (open-source@konsorten.de) - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod b/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod deleted file mode 100644 index 716c61312..000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/go.mod +++ /dev/null @@ -1 +0,0 @@ -module github.com/konsorten/go-windows-terminal-sequences diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go deleted file mode 100644 index ef18d8f97..000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences.go +++ /dev/null @@ -1,36 +0,0 @@ -// +build windows - -package sequences - -import ( - "syscall" - "unsafe" -) - -var ( - kernel32Dll *syscall.LazyDLL = syscall.NewLazyDLL("Kernel32.dll") - setConsoleMode *syscall.LazyProc = kernel32Dll.NewProc("SetConsoleMode") -) - -func EnableVirtualTerminalProcessing(stream syscall.Handle, enable bool) error { - const ENABLE_VIRTUAL_TERMINAL_PROCESSING uint32 = 0x4 - - var mode uint32 - err := syscall.GetConsoleMode(syscall.Stdout, &mode) - if err != nil { - return err - } - - if enable { - mode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING - } else { - mode &^= ENABLE_VIRTUAL_TERMINAL_PROCESSING - } - - ret, _, err := setConsoleMode.Call(uintptr(unsafe.Pointer(stream)), uintptr(mode)) - if ret == 0 { - return err - } - - return nil -} diff --git a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go b/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go deleted file mode 100644 index df61a6f2f..000000000 --- a/vendor/github.com/konsorten/go-windows-terminal-sequences/sequences_dummy.go +++ /dev/null @@ -1,11 +0,0 @@ -// +build linux darwin - -package sequences - -import ( - "fmt" -) - -func EnableVirtualTerminalProcessing(stream uintptr, enable bool) error { - return fmt.Errorf("windows only package") -} diff --git a/vendor/github.com/kr/pretty/formatter.go b/vendor/github.com/kr/pretty/formatter.go index df61d8d19..bf4b598d0 100644 --- a/vendor/github.com/kr/pretty/formatter.go +++ b/vendor/github.com/kr/pretty/formatter.go @@ -37,7 +37,7 @@ func (fo formatter) passThrough(f fmt.State, c rune) { s := "%" for i := 0; i < 128; i++ { if f.Flag(i) { - s += string(i) + s += string(rune(i)) } } if w, ok := f.Width(); ok { diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/MAINTAINERS b/vendor/github.com/opencontainers/runc/libcontainer/user/MAINTAINERS deleted file mode 100644 index edbe20066..000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/MAINTAINERS +++ /dev/null @@ -1,2 +0,0 @@ -Tianon Gravi (@tianon) -Aleksa Sarai (@cyphar) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go deleted file mode 100644 index 6fd8dd0d4..000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup.go +++ /dev/null @@ -1,41 +0,0 @@ -package user - -import ( - "errors" -) - -var ( - // The current operating system does not provide the required data for user lookups. - ErrUnsupported = errors.New("user lookup: operating system does not provide passwd-formatted data") - // No matching entries found in file. - ErrNoPasswdEntries = errors.New("no matching entries in passwd file") - ErrNoGroupEntries = errors.New("no matching entries in group file") -) - -// LookupUser looks up a user by their username in /etc/passwd. If the user -// cannot be found (or there is no /etc/passwd file on the filesystem), then -// LookupUser returns an error. -func LookupUser(username string) (User, error) { - return lookupUser(username) -} - -// LookupUid looks up a user by their user id in /etc/passwd. If the user cannot -// be found (or there is no /etc/passwd file on the filesystem), then LookupId -// returns an error. -func LookupUid(uid int) (User, error) { - return lookupUid(uid) -} - -// LookupGroup looks up a group by its name in /etc/group. If the group cannot -// be found (or there is no /etc/group file on the filesystem), then LookupGroup -// returns an error. -func LookupGroup(groupname string) (Group, error) { - return lookupGroup(groupname) -} - -// LookupGid looks up a group by its group id in /etc/group. If the group cannot -// be found (or there is no /etc/group file on the filesystem), then LookupGid -// returns an error. -func LookupGid(gid int) (Group, error) { - return lookupGid(gid) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go index 92b5ae8de..f95c1409f 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_unix.go @@ -1,3 +1,4 @@ +//go:build darwin || dragonfly || freebsd || linux || netbsd || openbsd || solaris // +build darwin dragonfly freebsd linux netbsd openbsd solaris package user @@ -16,13 +17,19 @@ const ( unixGroupPath = "/etc/group" ) -func lookupUser(username string) (User, error) { +// LookupUser looks up a user by their username in /etc/passwd. If the user +// cannot be found (or there is no /etc/passwd file on the filesystem), then +// LookupUser returns an error. +func LookupUser(username string) (User, error) { return lookupUserFunc(func(u User) bool { return u.Name == username }) } -func lookupUid(uid int) (User, error) { +// LookupUid looks up a user by their user id in /etc/passwd. If the user cannot +// be found (or there is no /etc/passwd file on the filesystem), then LookupId +// returns an error. +func LookupUid(uid int) (User, error) { return lookupUserFunc(func(u User) bool { return u.Uid == uid }) @@ -51,13 +58,19 @@ func lookupUserFunc(filter func(u User) bool) (User, error) { return users[0], nil } -func lookupGroup(groupname string) (Group, error) { +// LookupGroup looks up a group by its name in /etc/group. If the group cannot +// be found (or there is no /etc/group file on the filesystem), then LookupGroup +// returns an error. +func LookupGroup(groupname string) (Group, error) { return lookupGroupFunc(func(g Group) bool { return g.Name == groupname }) } -func lookupGid(gid int) (Group, error) { +// LookupGid looks up a group by its group id in /etc/group. If the group cannot +// be found (or there is no /etc/group file on the filesystem), then LookupGid +// returns an error. +func LookupGid(gid int) (Group, error) { return lookupGroupFunc(func(g Group) bool { return g.Gid == gid }) diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go b/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go deleted file mode 100644 index 65cd40e92..000000000 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/lookup_windows.go +++ /dev/null @@ -1,40 +0,0 @@ -// +build windows - -package user - -import ( - "fmt" - "os/user" -) - -func lookupUser(username string) (User, error) { - u, err := user.Lookup(username) - if err != nil { - return User{}, err - } - return userFromOS(u) -} - -func lookupUid(uid int) (User, error) { - u, err := user.LookupId(fmt.Sprintf("%d", uid)) - if err != nil { - return User{}, err - } - return userFromOS(u) -} - -func lookupGroup(groupname string) (Group, error) { - g, err := user.LookupGroup(groupname) - if err != nil { - return Group{}, err - } - return groupFromOS(g) -} - -func lookupGid(gid int) (Group, error) { - g, err := user.LookupGroupId(fmt.Sprintf("%d", gid)) - if err != nil { - return Group{}, err - } - return groupFromOS(g) -} diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go index 7b912bbf8..2473c5ead 100644 --- a/vendor/github.com/opencontainers/runc/libcontainer/user/user.go +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user.go @@ -2,21 +2,27 @@ package user import ( "bufio" + "bytes" + "errors" "fmt" "io" "os" - "os/user" "strconv" "strings" ) const ( - minId = 0 - maxId = 1<<31 - 1 //for 32-bit systems compatibility + minID = 0 + maxID = 1<<31 - 1 // for 32-bit systems compatibility ) var ( - ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minId, maxId) + // ErrNoPasswdEntries is returned if no matching entries were found in /etc/group. + ErrNoPasswdEntries = errors.New("no matching entries in passwd file") + // ErrNoGroupEntries is returned if no matching entries were found in /etc/passwd. + ErrNoGroupEntries = errors.New("no matching entries in group file") + // ErrRange is returned if a UID or GID is outside of the valid range. + ErrRange = fmt.Errorf("uids and gids must be in range %d-%d", minID, maxID) ) type User struct { @@ -29,28 +35,6 @@ type User struct { Shell string } -// userFromOS converts an os/user.(*User) to local User -// -// (This does not include Pass, Shell or Gecos) -func userFromOS(u *user.User) (User, error) { - newUser := User{ - Name: u.Username, - Home: u.HomeDir, - } - id, err := strconv.Atoi(u.Uid) - if err != nil { - return newUser, err - } - newUser.Uid = id - - id, err = strconv.Atoi(u.Gid) - if err != nil { - return newUser, err - } - newUser.Gid = id - return newUser, nil -} - type Group struct { Name string Pass string @@ -58,23 +42,6 @@ type Group struct { List []string } -// groupFromOS converts an os/user.(*Group) to local Group -// -// (This does not include Pass, Shell or Gecos) -func groupFromOS(g *user.Group) (Group, error) { - newGroup := Group{ - Name: g.Name, - } - - id, err := strconv.Atoi(g.Gid) - if err != nil { - return newGroup, err - } - newGroup.Gid = id - - return newGroup, nil -} - // SubID represents an entry in /etc/sub{u,g}id type SubID struct { Name string @@ -89,11 +56,11 @@ type IDMap struct { Count int64 } -func parseLine(line string, v ...interface{}) { - parseParts(strings.Split(line, ":"), v...) +func parseLine(line []byte, v ...interface{}) { + parseParts(bytes.Split(line, []byte(":")), v...) } -func parseParts(parts []string, v ...interface{}) { +func parseParts(parts [][]byte, v ...interface{}) { if len(parts) == 0 { return } @@ -109,16 +76,16 @@ func parseParts(parts []string, v ...interface{}) { // This is legit. switch e := v[i].(type) { case *string: - *e = p + *e = string(p) case *int: // "numbers", with conversion errors ignored because of some misbehaving configuration files. - *e, _ = strconv.Atoi(p) + *e, _ = strconv.Atoi(string(p)) case *int64: - *e, _ = strconv.ParseInt(p, 10, 64) + *e, _ = strconv.ParseInt(string(p), 10, 64) case *[]string: // Comma-separated lists. - if p != "" { - *e = strings.Split(p, ",") + if len(p) != 0 { + *e = strings.Split(string(p), ",") } else { *e = []string{} } @@ -153,7 +120,7 @@ func ParsePasswdFileFilter(path string, filter func(User) bool) ([]User, error) func ParsePasswdFilter(r io.Reader, filter func(User) bool) ([]User, error) { if r == nil { - return nil, fmt.Errorf("nil source for passwd-formatted data") + return nil, errors.New("nil source for passwd-formatted data") } var ( @@ -162,12 +129,8 @@ func ParsePasswdFilter(r io.Reader, filter func(User) bool) ([]User, error) { ) for s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } - - line := strings.TrimSpace(s.Text()) - if line == "" { + line := bytes.TrimSpace(s.Bytes()) + if len(line) == 0 { continue } @@ -183,6 +146,9 @@ func ParsePasswdFilter(r io.Reader, filter func(User) bool) ([]User, error) { out = append(out, p) } } + if err := s.Err(); err != nil { + return nil, err + } return out, nil } @@ -212,21 +178,55 @@ func ParseGroupFileFilter(path string, filter func(Group) bool) ([]Group, error) func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) { if r == nil { - return nil, fmt.Errorf("nil source for group-formatted data") - } + return nil, errors.New("nil source for group-formatted data") + } + rd := bufio.NewReader(r) + out := []Group{} + + // Read the file line-by-line. + for { + var ( + isPrefix bool + wholeLine []byte + err error + ) + + // Read the next line. We do so in chunks (as much as reader's + // buffer is able to keep), check if we read enough columns + // already on each step and store final result in wholeLine. + for { + var line []byte + line, isPrefix, err = rd.ReadLine() - var ( - s = bufio.NewScanner(r) - out = []Group{} - ) + if err != nil { + // We should return no error if EOF is reached + // without a match. + if err == io.EOF { //nolint:errorlint // comparison with io.EOF is legit, https://github.com/polyfloyd/go-errorlint/pull/12 + err = nil + } + return out, err + } - for s.Scan() { - if err := s.Err(); err != nil { - return nil, err + // Simple common case: line is short enough to fit in a + // single reader's buffer. + if !isPrefix && len(wholeLine) == 0 { + wholeLine = line + break + } + + wholeLine = append(wholeLine, line...) + + // Check if we read the whole line already. + if !isPrefix { + break + } } - text := s.Text() - if text == "" { + // There's no spec for /etc/passwd or /etc/group, but we try to follow + // the same rules as the glibc parser, which allows comments and blank + // space at the beginning of a line. + wholeLine = bytes.TrimSpace(wholeLine) + if len(wholeLine) == 0 || wholeLine[0] == '#' { continue } @@ -236,14 +236,12 @@ func ParseGroupFilter(r io.Reader, filter func(Group) bool) ([]Group, error) { // root:x:0:root // adm:x:4:root,adm,daemon p := Group{} - parseLine(text, &p.Name, &p.Pass, &p.Gid, &p.List) + parseLine(wholeLine, &p.Name, &p.Pass, &p.Gid, &p.List) if filter == nil || filter(p) { out = append(out, p) } } - - return out, nil } type ExecUser struct { @@ -314,7 +312,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( // Allow for userArg to have either "user" syntax, or optionally "user:group" syntax var userArg, groupArg string - parseLine(userSpec, &userArg, &groupArg) + parseLine([]byte(userSpec), &userArg, &groupArg) // Convert userArg and groupArg to be numeric, so we don't have to execute // Atoi *twice* for each iteration over lines. @@ -341,7 +339,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( if userArg == "" { userArg = strconv.Itoa(user.Uid) } - return nil, fmt.Errorf("unable to find user %s: %v", userArg, err) + return nil, fmt.Errorf("unable to find user %s: %w", userArg, err) } var matchedUserName string @@ -357,12 +355,12 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( if uidErr != nil { // Not numeric. - return nil, fmt.Errorf("unable to find user %s: %v", userArg, ErrNoPasswdEntries) + return nil, fmt.Errorf("unable to find user %s: %w", userArg, ErrNoPasswdEntries) } user.Uid = uidArg // Must be inside valid uid range. - if user.Uid < minId || user.Uid > maxId { + if user.Uid < minID || user.Uid > maxID { return nil, ErrRange } @@ -392,7 +390,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( return g.Name == groupArg }) if err != nil && group != nil { - return nil, fmt.Errorf("unable to find groups for spec %v: %v", matchedUserName, err) + return nil, fmt.Errorf("unable to find groups for spec %v: %w", matchedUserName, err) } // Only start modifying user.Gid if it is in explicit form. @@ -406,12 +404,12 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( if gidErr != nil { // Not numeric. - return nil, fmt.Errorf("unable to find group %s: %v", groupArg, ErrNoGroupEntries) + return nil, fmt.Errorf("unable to find group %s: %w", groupArg, ErrNoGroupEntries) } user.Gid = gidArg // Must be inside valid gid range. - if user.Gid < minId || user.Gid > maxId { + if user.Gid < minID || user.Gid > maxID { return nil, ErrRange } @@ -435,7 +433,7 @@ func GetExecUser(userSpec string, defaults *ExecUser, passwd, group io.Reader) ( // or the given group data is nil, the id will be returned as-is // provided it is in the legal range. func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, error) { - var groups = []Group{} + groups := []Group{} if group != nil { var err error groups, err = ParseGroupFilter(group, func(g Group) bool { @@ -447,7 +445,7 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err return false }) if err != nil { - return nil, fmt.Errorf("Unable to find additional groups %v: %v", additionalGroups, err) + return nil, fmt.Errorf("Unable to find additional groups %v: %w", additionalGroups, err) } } @@ -468,15 +466,16 @@ func GetAdditionalGroups(additionalGroups []string, group io.Reader) ([]int, err // we asked for a group but didn't find it. let's check to see // if we wanted a numeric group if !found { - gid, err := strconv.Atoi(ag) + gid, err := strconv.ParseInt(ag, 10, 64) if err != nil { - return nil, fmt.Errorf("Unable to find group %s", ag) + // Not a numeric ID either. + return nil, fmt.Errorf("Unable to find group %s: %w", ag, ErrNoGroupEntries) } // Ensure gid is inside gid range. - if gid < minId || gid > maxId { + if gid < minID || gid > maxID { return nil, ErrRange } - gidMap[gid] = struct{}{} + gidMap[int(gid)] = struct{}{} } } gids := []int{} @@ -523,7 +522,7 @@ func ParseSubIDFileFilter(path string, filter func(SubID) bool) ([]SubID, error) func ParseSubIDFilter(r io.Reader, filter func(SubID) bool) ([]SubID, error) { if r == nil { - return nil, fmt.Errorf("nil source for subid-formatted data") + return nil, errors.New("nil source for subid-formatted data") } var ( @@ -532,12 +531,8 @@ func ParseSubIDFilter(r io.Reader, filter func(SubID) bool) ([]SubID, error) { ) for s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } - - line := strings.TrimSpace(s.Text()) - if line == "" { + line := bytes.TrimSpace(s.Bytes()) + if len(line) == 0 { continue } @@ -549,6 +544,9 @@ func ParseSubIDFilter(r io.Reader, filter func(SubID) bool) ([]SubID, error) { out = append(out, p) } } + if err := s.Err(); err != nil { + return nil, err + } return out, nil } @@ -577,7 +575,7 @@ func ParseIDMapFileFilter(path string, filter func(IDMap) bool) ([]IDMap, error) func ParseIDMapFilter(r io.Reader, filter func(IDMap) bool) ([]IDMap, error) { if r == nil { - return nil, fmt.Errorf("nil source for idmap-formatted data") + return nil, errors.New("nil source for idmap-formatted data") } var ( @@ -586,23 +584,22 @@ func ParseIDMapFilter(r io.Reader, filter func(IDMap) bool) ([]IDMap, error) { ) for s.Scan() { - if err := s.Err(); err != nil { - return nil, err - } - - line := strings.TrimSpace(s.Text()) - if line == "" { + line := bytes.TrimSpace(s.Bytes()) + if len(line) == 0 { continue } // see: man 7 user_namespaces p := IDMap{} - parseParts(strings.Fields(line), &p.ID, &p.ParentID, &p.Count) + parseParts(bytes.Fields(line), &p.ID, &p.ParentID, &p.Count) if filter == nil || filter(p) { out = append(out, p) } } + if err := s.Err(); err != nil { + return nil, err + } return out, nil } diff --git a/vendor/github.com/opencontainers/runc/libcontainer/user/user_fuzzer.go b/vendor/github.com/opencontainers/runc/libcontainer/user/user_fuzzer.go new file mode 100644 index 000000000..e018eae61 --- /dev/null +++ b/vendor/github.com/opencontainers/runc/libcontainer/user/user_fuzzer.go @@ -0,0 +1,43 @@ +//go:build gofuzz +// +build gofuzz + +package user + +import ( + "io" + "strings" +) + +func IsDivisbleBy(n int, divisibleby int) bool { + return (n % divisibleby) == 0 +} + +func FuzzUser(data []byte) int { + if len(data) == 0 { + return -1 + } + if !IsDivisbleBy(len(data), 5) { + return -1 + } + + var divided [][]byte + + chunkSize := len(data) / 5 + + for i := 0; i < len(data); i += chunkSize { + end := i + chunkSize + + divided = append(divided, data[i:end]) + } + + _, _ = ParsePasswdFilter(strings.NewReader(string(divided[0])), nil) + + var passwd, group io.Reader + + group = strings.NewReader(string(divided[1])) + _, _ = GetAdditionalGroups([]string{string(divided[2])}, group) + + passwd = strings.NewReader(string(divided[3])) + _, _ = GetExecUser(string(divided[4]), nil, passwd, group) + return 1 +} diff --git a/vendor/github.com/sirupsen/logrus/.gitignore b/vendor/github.com/sirupsen/logrus/.gitignore index 6b7d7d1e8..1fb13abeb 100644 --- a/vendor/github.com/sirupsen/logrus/.gitignore +++ b/vendor/github.com/sirupsen/logrus/.gitignore @@ -1,2 +1,4 @@ logrus vendor + +.idea/ diff --git a/vendor/github.com/sirupsen/logrus/.golangci.yml b/vendor/github.com/sirupsen/logrus/.golangci.yml new file mode 100644 index 000000000..65dc28503 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/.golangci.yml @@ -0,0 +1,40 @@ +run: + # do not run on test files yet + tests: false + +# all available settings of specific linters +linters-settings: + errcheck: + # report about not checking of errors in type assetions: `a := b.(MyStruct)`; + # default is false: such cases aren't reported by default. + check-type-assertions: false + + # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; + # default is false: such cases aren't reported by default. + check-blank: false + + lll: + line-length: 100 + tab-width: 4 + + prealloc: + simple: false + range-loops: false + for-loops: false + + whitespace: + multi-if: false # Enforces newlines (or comments) after every multi-line if statement + multi-func: false # Enforces newlines (or comments) after every multi-line function signature + +linters: + enable: + - megacheck + - govet + disable: + - maligned + - prealloc + disable-all: false + presets: + - bugs + - unused + fast: false diff --git a/vendor/github.com/sirupsen/logrus/.travis.yml b/vendor/github.com/sirupsen/logrus/.travis.yml index 848938a6d..c1dbd5a3a 100644 --- a/vendor/github.com/sirupsen/logrus/.travis.yml +++ b/vendor/github.com/sirupsen/logrus/.travis.yml @@ -4,22 +4,12 @@ git: depth: 1 env: - GO111MODULE=on - - GO111MODULE=off -go: [ 1.11.x, 1.12.x ] -os: [ linux, osx ] -matrix: - exclude: - - go: 1.12.x - env: GO111MODULE=off - - go: 1.11.x - os: osx +go: 1.15.x +os: linux install: - ./travis/install.sh - - if [[ "$GO111MODULE" == "on" ]]; then go mod download; fi - - if [[ "$GO111MODULE" == "off" ]]; then go get github.com/stretchr/testify/assert golang.org/x/sys/unix github.com/konsorten/go-windows-terminal-sequences; fi script: - - ./travis/cross_build.sh - - export GOMAXPROCS=4 - - export GORACE=halt_on_error=1 - - go test -race -v ./... - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then go test -race -v -tags appengine ./... ; fi + - cd ci + - go run mage.go -v -w ../ crossBuild + - go run mage.go -v -w ../ lint + - go run mage.go -v -w ../ test diff --git a/vendor/github.com/sirupsen/logrus/CHANGELOG.md b/vendor/github.com/sirupsen/logrus/CHANGELOG.md index 51a7ab0ca..7567f6128 100644 --- a/vendor/github.com/sirupsen/logrus/CHANGELOG.md +++ b/vendor/github.com/sirupsen/logrus/CHANGELOG.md @@ -1,9 +1,68 @@ +# 1.8.1 +Code quality: + * move magefile in its own subdir/submodule to remove magefile dependency on logrus consumer + * improve timestamp format documentation + +Fixes: + * fix race condition on logger hooks + + +# 1.8.0 + +Correct versioning number replacing v1.7.1. + +# 1.7.1 + +Beware this release has introduced a new public API and its semver is therefore incorrect. + +Code quality: + * use go 1.15 in travis + * use magefile as task runner + +Fixes: + * small fixes about new go 1.13 error formatting system + * Fix for long time race condiction with mutating data hooks + +Features: + * build support for zos + +# 1.7.0 +Fixes: + * the dependency toward a windows terminal library has been removed + +Features: + * a new buffer pool management API has been added + * a set of `Fn()` functions have been added + +# 1.6.0 +Fixes: + * end of line cleanup + * revert the entry concurrency bug fix whic leads to deadlock under some circumstances + * update dependency on go-windows-terminal-sequences to fix a crash with go 1.14 + +Features: + * add an option to the `TextFormatter` to completely disable fields quoting + +# 1.5.0 +Code quality: + * add golangci linter run on travis + +Fixes: + * add mutex for hooks concurrent access on `Entry` data + * caller function field for go1.14 + * fix build issue for gopherjs target + +Feature: + * add an hooks/writer sub-package whose goal is to split output on different stream depending on the trace level + * add a `DisableHTMLEscape` option in the `JSONFormatter` + * add `ForceQuote` and `PadLevelText` options in the `TextFormatter` + # 1.4.2 * Fixes build break for plan9, nacl, solaris # 1.4.1 This new release introduces: * Enhance TextFormatter to not print caller information when they are empty (#944) - * Remove dependency on golang.org/x/crypto (#932, #943) + * Remove dependency on golang.org/x/crypto (#932, #943) Fixes: * Fix Entry.WithContext method to return a copy of the initial entry (#941) @@ -11,7 +70,7 @@ Fixes: # 1.4.0 This new release introduces: * Add `DeferExitHandler`, similar to `RegisterExitHandler` but prepending the handler to the list of handlers (semantically like `defer`) (#848). - * Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter (#909, #911) + * Add `CallerPrettyfier` to `JSONFormatter` and `TextFormatter` (#909, #911) * Add `Entry.WithContext()` and `Entry.Context`, to set a context on entries to be used e.g. in hooks (#919). Fixes: diff --git a/vendor/github.com/sirupsen/logrus/README.md b/vendor/github.com/sirupsen/logrus/README.md index a4796eb07..5152b6aa4 100644 --- a/vendor/github.com/sirupsen/logrus/README.md +++ b/vendor/github.com/sirupsen/logrus/README.md @@ -1,8 +1,28 @@ -# Logrus :walrus: [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus) +# Logrus :walrus: [![Build Status](https://travis-ci.org/sirupsen/logrus.svg?branch=master)](https://travis-ci.org/sirupsen/logrus) [![GoDoc](https://godoc.org/github.com/sirupsen/logrus?status.svg)](https://godoc.org/github.com/sirupsen/logrus) Logrus is a structured logger for Go (golang), completely API compatible with the standard library logger. +**Logrus is in maintenance-mode.** We will not be introducing new features. It's +simply too hard to do in a way that won't break many people's projects, which is +the last thing you want from your Logging library (again...). + +This does not mean Logrus is dead. Logrus will continue to be maintained for +security, (backwards compatible) bug fixes, and performance (where we are +limited by the interface). + +I believe Logrus' biggest contribution is to have played a part in today's +widespread use of structured logging in Golang. There doesn't seem to be a +reason to do a major, breaking iteration into Logrus V2, since the fantastic Go +community has built those independently. Many fantastic alternatives have sprung +up. Logrus would look like those, had it been re-designed with what we know +about structured logging in Go today. Check out, for example, +[Zerolog][zerolog], [Zap][zap], and [Apex][apex]. + +[zerolog]: https://github.com/rs/zerolog +[zap]: https://github.com/uber-go/zap +[apex]: https://github.com/apex/log + **Seeing weird case-sensitive problems?** It's in the past been possible to import Logrus as both upper- and lower-case. Due to the Go package environment, this caused issues in the community and we needed a standard. Some environments @@ -15,11 +35,6 @@ comments](https://github.com/sirupsen/logrus/issues/553#issuecomment-306591437). For an in-depth explanation of the casing issue, see [this comment](https://github.com/sirupsen/logrus/issues/570#issuecomment-313933276). -**Are you interested in assisting in maintaining Logrus?** Currently I have a -lot of obligations, and I am unable to provide Logrus with the maintainership it -needs. If you'd like to help, please reach out to me at `simon at author's -username dot com`. - Nicely color-coded in development (when a TTY is attached, otherwise just plain text): @@ -187,7 +202,7 @@ func main() { log.Out = os.Stdout // You could set this to any `io.Writer` such as a file - // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY, 0666) + // file, err := os.OpenFile("logrus.log", os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) // if err == nil { // log.Out = file // } else { @@ -272,7 +287,7 @@ func init() { ``` Note: Syslog hook also support connecting to local syslog (Ex. "/dev/log" or "/var/run/syslog" or "/var/run/log"). For the detail, please check the [syslog hook README](hooks/syslog/README.md). -A list of currently known of service hook can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks) +A list of currently known service hooks can be found in this wiki [page](https://github.com/sirupsen/logrus/wiki/Hooks) #### Level logging @@ -354,6 +369,7 @@ The built-in logging formatters are: [github.com/mattn/go-colorable](https://github.com/mattn/go-colorable). * When colors are enabled, levels are truncated to 4 characters by default. To disable truncation set the `DisableLevelTruncation` field to `true`. + * When outputting to a TTY, it's often helpful to visually scan down a column where all the levels are the same width. Setting the `PadLevelText` field to `true` enables this behavior, by adding padding to the level text. * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#TextFormatter). * `logrus.JSONFormatter`. Logs fields as JSON. * All options are listed in the [generated docs](https://godoc.org/github.com/sirupsen/logrus#JSONFormatter). @@ -364,8 +380,10 @@ Third party logging formatters: * [`GELF`](https://github.com/fabienm/go-logrus-formatters). Formats entries so they comply to Graylog's [GELF 1.1 specification](http://docs.graylog.org/en/2.4/pages/gelf.html). * [`logstash`](https://github.com/bshuster-repo/logrus-logstash-hook). Logs fields as [Logstash](http://logstash.net) Events. * [`prefixed`](https://github.com/x-cray/logrus-prefixed-formatter). Displays log entry source along with alternative layout. -* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the P͉̫o̳̼̊w̖͈̰͎e̬͔̭͂r͚̼̹̲ ̫͓͉̳͈ō̠͕͖̚f̝͍̠ ͕̲̞͖͑Z̖̫̤̫ͪa͉̬͈̗l͖͎g̳̥o̰̥̅!̣͔̲̻͊̄ ̙̘̦̹̦. +* [`zalgo`](https://github.com/aybabtme/logzalgo). Invoking the Power of Zalgo. * [`nested-logrus-formatter`](https://github.com/antonfisher/nested-logrus-formatter). Converts logrus fields to a nested structure. +* [`powerful-logrus-formatter`](https://github.com/zput/zxcTool). get fileName, log's line number and the latest function's name when print log; Sava log to files. +* [`caption-json-formatter`](https://github.com/nolleh/caption_json_formatter). logrus's message json formatter with human-readable caption added. You can define your formatter by implementing the `Formatter` interface, requiring a `Format` method. `Format` takes an `*Entry`. `entry.Data` is a @@ -384,7 +402,7 @@ func (f *MyJSONFormatter) Format(entry *Entry) ([]byte, error) { // source of the official loggers. serialized, err := json.Marshal(entry.Data) if err != nil { - return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) + return nil, fmt.Errorf("Failed to marshal fields to JSON, %w", err) } return append(serialized, '\n'), nil } @@ -430,14 +448,14 @@ entries. It should not be a feature of the application-level logger. | Tool | Description | | ---- | ----------- | -|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will generated with different config at different environment.| +|[Logrus Mate](https://github.com/gogap/logrus_mate)|Logrus mate is a tool for Logrus to manage loggers, you can initial logger's level, hook and formatter by config file, the logger will be generated with different configs in different environments.| |[Logrus Viper Helper](https://github.com/heirko/go-contrib/tree/master/logrusHelper)|An Helper around Logrus to wrap with spf13/Viper to load configuration with fangs! And to simplify Logrus configuration use some behavior of [Logrus Mate](https://github.com/gogap/logrus_mate). [sample](https://github.com/heirko/iris-contrib/blob/master/middleware/logrus-logger/example) | #### Testing Logrus has a built in facility for asserting the presence of log messages. This is implemented through the `test` hook and provides: -* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just add the `test` hook +* decorators for existing logger (`test.NewLocal` and `test.NewGlobal`) which basically just adds the `test` hook * a test logger (`test.NewNullLogger`) that just records log messages (and does not output any): ```go @@ -465,7 +483,7 @@ func TestSomething(t*testing.T){ Logrus can register one or more functions that will be called when any `fatal` level message is logged. The registered handlers will be executed before -logrus performs a `os.Exit(1)`. This behavior may be helpful if callers need +logrus performs an `os.Exit(1)`. This behavior may be helpful if callers need to gracefully shutdown. Unlike a `panic("Something went wrong...")` call which can be intercepted with a deferred `recover` a call to `os.Exit(1)` can not be intercepted. ``` @@ -490,6 +508,6 @@ Situation when locking is not needed includes: 1) logger.Out is protected by locks. - 2) logger.Out is a os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allow multi-thread/multi-process writing) + 2) logger.Out is an os.File handler opened with `O_APPEND` flag, and every write is smaller than 4k. (This allows multi-thread/multi-process writing) (Refer to http://www.notthewizard.com/2014/06/17/are-files-appends-really-atomic/) diff --git a/vendor/github.com/sirupsen/logrus/appveyor.yml b/vendor/github.com/sirupsen/logrus/appveyor.yml index 96c2ce15f..df9d65c3a 100644 --- a/vendor/github.com/sirupsen/logrus/appveyor.yml +++ b/vendor/github.com/sirupsen/logrus/appveyor.yml @@ -1,14 +1,14 @@ -version: "{build}" -platform: x64 -clone_folder: c:\gopath\src\github.com\sirupsen\logrus -environment: - GOPATH: c:\gopath -branches: - only: - - master -install: - - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% - - go version -build_script: - - go get -t - - go test +version: "{build}" +platform: x64 +clone_folder: c:\gopath\src\github.com\sirupsen\logrus +environment: + GOPATH: c:\gopath +branches: + only: + - master +install: + - set PATH=%GOPATH%\bin;c:\go\bin;%PATH% + - go version +build_script: + - go get -t + - go test diff --git a/vendor/github.com/sirupsen/logrus/buffer_pool.go b/vendor/github.com/sirupsen/logrus/buffer_pool.go new file mode 100644 index 000000000..4545dec07 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/buffer_pool.go @@ -0,0 +1,52 @@ +package logrus + +import ( + "bytes" + "sync" +) + +var ( + bufferPool BufferPool +) + +type BufferPool interface { + Put(*bytes.Buffer) + Get() *bytes.Buffer +} + +type defaultPool struct { + pool *sync.Pool +} + +func (p *defaultPool) Put(buf *bytes.Buffer) { + p.pool.Put(buf) +} + +func (p *defaultPool) Get() *bytes.Buffer { + return p.pool.Get().(*bytes.Buffer) +} + +func getBuffer() *bytes.Buffer { + return bufferPool.Get() +} + +func putBuffer(buf *bytes.Buffer) { + buf.Reset() + bufferPool.Put(buf) +} + +// SetBufferPool allows to replace the default logrus buffer pool +// to better meets the specific needs of an application. +func SetBufferPool(bp BufferPool) { + bufferPool = bp +} + +func init() { + SetBufferPool(&defaultPool{ + pool: &sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, + }, + }) +} diff --git a/vendor/github.com/sirupsen/logrus/entry.go b/vendor/github.com/sirupsen/logrus/entry.go index 63e25583c..07a1e5fa7 100644 --- a/vendor/github.com/sirupsen/logrus/entry.go +++ b/vendor/github.com/sirupsen/logrus/entry.go @@ -13,7 +13,6 @@ import ( ) var ( - bufferPool *sync.Pool // qualified package name, cached at first use logrusPackage string @@ -31,12 +30,6 @@ const ( ) func init() { - bufferPool = &sync.Pool{ - New: func() interface{} { - return new(bytes.Buffer) - }, - } - // start at the bottom of the stack before the package-name cache is primed minimumCallerDepth = 1 } @@ -85,10 +78,23 @@ func NewEntry(logger *Logger) *Entry { } } +func (entry *Entry) Dup() *Entry { + data := make(Fields, len(entry.Data)) + for k, v := range entry.Data { + data[k] = v + } + return &Entry{Logger: entry.Logger, Data: data, Time: entry.Time, Context: entry.Context, err: entry.err} +} + +// Returns the bytes representation of this entry from the formatter. +func (entry *Entry) Bytes() ([]byte, error) { + return entry.Logger.Formatter.Format(entry) +} + // Returns the string representation from the reader and ultimately the // formatter. func (entry *Entry) String() (string, error) { - serialized, err := entry.Logger.Formatter.Format(entry) + serialized, err := entry.Bytes() if err != nil { return "", err } @@ -103,7 +109,11 @@ func (entry *Entry) WithError(err error) *Entry { // Add a context to the Entry. func (entry *Entry) WithContext(ctx context.Context) *Entry { - return &Entry{Logger: entry.Logger, Data: entry.Data, Time: entry.Time, err: entry.err, Context: ctx} + dataCopy := make(Fields, len(entry.Data)) + for k, v := range entry.Data { + dataCopy[k] = v + } + return &Entry{Logger: entry.Logger, Data: dataCopy, Time: entry.Time, err: entry.err, Context: ctx} } // Add a single field to the Entry. @@ -121,11 +131,9 @@ func (entry *Entry) WithFields(fields Fields) *Entry { for k, v := range fields { isErrField := false if t := reflect.TypeOf(v); t != nil { - switch t.Kind() { - case reflect.Func: + switch { + case t.Kind() == reflect.Func, t.Kind() == reflect.Ptr && t.Elem().Kind() == reflect.Func: isErrField = true - case reflect.Ptr: - isErrField = t.Elem().Kind() == reflect.Func } } if isErrField { @@ -144,7 +152,11 @@ func (entry *Entry) WithFields(fields Fields) *Entry { // Overrides the time of the Entry. func (entry *Entry) WithTime(t time.Time) *Entry { - return &Entry{Logger: entry.Logger, Data: entry.Data, Time: t, err: entry.err, Context: entry.Context} + dataCopy := make(Fields, len(entry.Data)) + for k, v := range entry.Data { + dataCopy[k] = v + } + return &Entry{Logger: entry.Logger, Data: dataCopy, Time: t, err: entry.err, Context: entry.Context} } // getPackageName reduces a fully qualified function name to the package name @@ -165,15 +177,20 @@ func getPackageName(f string) string { // getCaller retrieves the name of the first non-logrus calling function func getCaller() *runtime.Frame { - // cache this package's fully-qualified name callerInitOnce.Do(func() { - pcs := make([]uintptr, 2) + pcs := make([]uintptr, maximumCallerDepth) _ = runtime.Callers(0, pcs) - logrusPackage = getPackageName(runtime.FuncForPC(pcs[1]).Name()) - // now that we have the cache, we can skip a minimum count of known-logrus functions - // XXX this is dubious, the number of frames may vary + // dynamic get the package name and the minimum caller depth + for i := 0; i < maximumCallerDepth; i++ { + funcName := runtime.FuncForPC(pcs[i]).Name() + if strings.Contains(funcName, "getCaller") { + logrusPackage = getPackageName(funcName) + break + } + } + minimumCallerDepth = knownLogrusFrames }) @@ -187,7 +204,7 @@ func getCaller() *runtime.Frame { // If the caller isn't part of this package, we're done if pkg != logrusPackage { - return &f + return &f //nolint:scopelint } } @@ -201,65 +218,73 @@ func (entry Entry) HasCaller() (has bool) { entry.Caller != nil } -// This function is not declared with a pointer value because otherwise -// race conditions will occur when using multiple goroutines -func (entry Entry) log(level Level, msg string) { +func (entry *Entry) log(level Level, msg string) { var buffer *bytes.Buffer - // Default to now, but allow users to override if they want. - // - // We don't have to worry about polluting future calls to Entry#log() - // with this assignment because this function is declared with a - // non-pointer receiver. - if entry.Time.IsZero() { - entry.Time = time.Now() + newEntry := entry.Dup() + + if newEntry.Time.IsZero() { + newEntry.Time = time.Now() } - entry.Level = level - entry.Message = msg - if entry.Logger.ReportCaller { - entry.Caller = getCaller() + newEntry.Level = level + newEntry.Message = msg + + newEntry.Logger.mu.Lock() + reportCaller := newEntry.Logger.ReportCaller + newEntry.Logger.mu.Unlock() + + if reportCaller { + newEntry.Caller = getCaller() } - entry.fireHooks() + newEntry.fireHooks() - buffer = bufferPool.Get().(*bytes.Buffer) + buffer = getBuffer() + defer func() { + newEntry.Buffer = nil + putBuffer(buffer) + }() buffer.Reset() - defer bufferPool.Put(buffer) - entry.Buffer = buffer + newEntry.Buffer = buffer - entry.write() + newEntry.write() - entry.Buffer = nil + newEntry.Buffer = nil // To avoid Entry#log() returning a value that only would make sense for // panic() to use in Entry#Panic(), we avoid the allocation by checking // directly here. if level <= PanicLevel { - panic(&entry) + panic(newEntry) } } func (entry *Entry) fireHooks() { + var tmpHooks LevelHooks entry.Logger.mu.Lock() - defer entry.Logger.mu.Unlock() - err := entry.Logger.Hooks.Fire(entry.Level, entry) + tmpHooks = make(LevelHooks, len(entry.Logger.Hooks)) + for k, v := range entry.Logger.Hooks { + tmpHooks[k] = v + } + entry.Logger.mu.Unlock() + + err := tmpHooks.Fire(entry.Level, entry) if err != nil { fmt.Fprintf(os.Stderr, "Failed to fire hook: %v\n", err) } } func (entry *Entry) write() { - entry.Logger.mu.Lock() - defer entry.Logger.mu.Unlock() serialized, err := entry.Logger.Formatter.Format(entry) if err != nil { fmt.Fprintf(os.Stderr, "Failed to obtain reader, %v\n", err) - } else { - _, err = entry.Logger.Out.Write(serialized) - if err != nil { - fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) - } + return + } + entry.Logger.mu.Lock() + defer entry.Logger.mu.Unlock() + if _, err := entry.Logger.Out.Write(serialized); err != nil { + fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) } } @@ -304,7 +329,6 @@ func (entry *Entry) Fatal(args ...interface{}) { func (entry *Entry) Panic(args ...interface{}) { entry.Log(PanicLevel, args...) - panic(fmt.Sprint(args...)) } // Entry Printf family functions diff --git a/vendor/github.com/sirupsen/logrus/exported.go b/vendor/github.com/sirupsen/logrus/exported.go index 62fc2f219..017c30ce6 100644 --- a/vendor/github.com/sirupsen/logrus/exported.go +++ b/vendor/github.com/sirupsen/logrus/exported.go @@ -80,7 +80,7 @@ func WithFields(fields Fields) *Entry { return std.WithFields(fields) } -// WithTime creats an entry from the standard logger and overrides the time of +// WithTime creates an entry from the standard logger and overrides the time of // logs generated with it. // // Note that it doesn't log until you call Debug, Print, Info, Warn, Fatal @@ -134,6 +134,51 @@ func Fatal(args ...interface{}) { std.Fatal(args...) } +// TraceFn logs a message from a func at level Trace on the standard logger. +func TraceFn(fn LogFunction) { + std.TraceFn(fn) +} + +// DebugFn logs a message from a func at level Debug on the standard logger. +func DebugFn(fn LogFunction) { + std.DebugFn(fn) +} + +// PrintFn logs a message from a func at level Info on the standard logger. +func PrintFn(fn LogFunction) { + std.PrintFn(fn) +} + +// InfoFn logs a message from a func at level Info on the standard logger. +func InfoFn(fn LogFunction) { + std.InfoFn(fn) +} + +// WarnFn logs a message from a func at level Warn on the standard logger. +func WarnFn(fn LogFunction) { + std.WarnFn(fn) +} + +// WarningFn logs a message from a func at level Warn on the standard logger. +func WarningFn(fn LogFunction) { + std.WarningFn(fn) +} + +// ErrorFn logs a message from a func at level Error on the standard logger. +func ErrorFn(fn LogFunction) { + std.ErrorFn(fn) +} + +// PanicFn logs a message from a func at level Panic on the standard logger. +func PanicFn(fn LogFunction) { + std.PanicFn(fn) +} + +// FatalFn logs a message from a func at level Fatal on the standard logger then the process will exit with status set to 1. +func FatalFn(fn LogFunction) { + std.FatalFn(fn) +} + // Tracef logs a message at level Trace on the standard logger. func Tracef(format string, args ...interface{}) { std.Tracef(format, args...) diff --git a/vendor/github.com/sirupsen/logrus/go.mod b/vendor/github.com/sirupsen/logrus/go.mod index 12fdf9898..b3919d5ea 100644 --- a/vendor/github.com/sirupsen/logrus/go.mod +++ b/vendor/github.com/sirupsen/logrus/go.mod @@ -2,9 +2,9 @@ module github.com/sirupsen/logrus require ( github.com/davecgh/go-spew v1.1.1 // indirect - github.com/konsorten/go-windows-terminal-sequences v1.0.1 github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/stretchr/objx v0.1.1 // indirect github.com/stretchr/testify v1.2.2 - golang.org/x/sys v0.0.0-20190422165155-953cdadca894 + golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 ) + +go 1.13 diff --git a/vendor/github.com/sirupsen/logrus/go.sum b/vendor/github.com/sirupsen/logrus/go.sum index 596c318b9..694c18b84 100644 --- a/vendor/github.com/sirupsen/logrus/go.sum +++ b/vendor/github.com/sirupsen/logrus/go.sum @@ -1,16 +1,8 @@ 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/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe h1:CHRGQ8V7OlCYtwaKPJi3iA7J+YdNKdo8j7nG5IgDhjs= -github.com/konsorten/go-windows-terminal-sequences v0.0.0-20180402223658-b729f2633dfe/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 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.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8= -golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894 h1:Cz4ceDQGXuKRnVBDTS23GTn/pU5OE2C0WrNTOYK1Uuc= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= diff --git a/vendor/github.com/sirupsen/logrus/json_formatter.go b/vendor/github.com/sirupsen/logrus/json_formatter.go index 098a21a06..c96dc5636 100644 --- a/vendor/github.com/sirupsen/logrus/json_formatter.go +++ b/vendor/github.com/sirupsen/logrus/json_formatter.go @@ -23,11 +23,17 @@ func (f FieldMap) resolve(key fieldKey) string { // JSONFormatter formats logs into parsable json type JSONFormatter struct { // TimestampFormat sets the format used for marshaling timestamps. + // The format to use is the same than for time.Format or time.Parse from the standard + // library. + // The standard Library already provides a set of predefined format. TimestampFormat string // DisableTimestamp allows disabling automatic timestamps in output DisableTimestamp bool + // DisableHTMLEscape allows disabling html escaping in output + DisableHTMLEscape bool + // DataKey allows users to put all the log entry parameters into a nested dictionary at a given key. DataKey string @@ -110,11 +116,12 @@ func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { } encoder := json.NewEncoder(b) + encoder.SetEscapeHTML(!f.DisableHTMLEscape) if f.PrettyPrint { encoder.SetIndent("", " ") } if err := encoder.Encode(data); err != nil { - return nil, fmt.Errorf("failed to marshal fields to JSON, %v", err) + return nil, fmt.Errorf("failed to marshal fields to JSON, %w", err) } return b.Bytes(), nil diff --git a/vendor/github.com/sirupsen/logrus/logger.go b/vendor/github.com/sirupsen/logrus/logger.go index c0c0b1e55..337704457 100644 --- a/vendor/github.com/sirupsen/logrus/logger.go +++ b/vendor/github.com/sirupsen/logrus/logger.go @@ -9,6 +9,11 @@ import ( "time" ) +// LogFunction For big messages, it can be more efficient to pass a function +// and only call it if the log level is actually enables rather than +// generating the log message and then checking if the level is enabled +type LogFunction func() []interface{} + type Logger struct { // The logs are `io.Copy`'d to this in a mutex. It's common to set this to a // file, or leave it default which is `os.Stderr`. You can also set this to @@ -68,10 +73,10 @@ func (mw *MutexWrap) Disable() { // `Out` and `Hooks` directly on the default logger instance. You can also just // instantiate your own: // -// var log = &Logger{ +// var log = &logrus.Logger{ // Out: os.Stderr, -// Formatter: new(JSONFormatter), -// Hooks: make(LevelHooks), +// Formatter: new(logrus.TextFormatter), +// Hooks: make(logrus.LevelHooks), // Level: logrus.DebugLevel, // } // @@ -100,8 +105,9 @@ func (logger *Logger) releaseEntry(entry *Entry) { logger.entryPool.Put(entry) } -// Adds a field to the log entry, note that it doesn't log until you call -// Debug, Print, Info, Warn, Error, Fatal or Panic. It only creates a log entry. +// WithField allocates a new entry and adds a field to it. +// Debug, Print, Info, Warn, Error, Fatal or Panic must be then applied to +// this new returned entry. // If you want multiple fields, use `WithFields`. func (logger *Logger) WithField(key string, value interface{}) *Entry { entry := logger.newEntry() @@ -194,6 +200,14 @@ func (logger *Logger) Log(level Level, args ...interface{}) { } } +func (logger *Logger) LogFn(level Level, fn LogFunction) { + if logger.IsLevelEnabled(level) { + entry := logger.newEntry() + entry.Log(level, fn()...) + logger.releaseEntry(entry) + } +} + func (logger *Logger) Trace(args ...interface{}) { logger.Log(TraceLevel, args...) } @@ -233,6 +247,45 @@ func (logger *Logger) Panic(args ...interface{}) { logger.Log(PanicLevel, args...) } +func (logger *Logger) TraceFn(fn LogFunction) { + logger.LogFn(TraceLevel, fn) +} + +func (logger *Logger) DebugFn(fn LogFunction) { + logger.LogFn(DebugLevel, fn) +} + +func (logger *Logger) InfoFn(fn LogFunction) { + logger.LogFn(InfoLevel, fn) +} + +func (logger *Logger) PrintFn(fn LogFunction) { + entry := logger.newEntry() + entry.Print(fn()...) + logger.releaseEntry(entry) +} + +func (logger *Logger) WarnFn(fn LogFunction) { + logger.LogFn(WarnLevel, fn) +} + +func (logger *Logger) WarningFn(fn LogFunction) { + logger.WarnFn(fn) +} + +func (logger *Logger) ErrorFn(fn LogFunction) { + logger.LogFn(ErrorLevel, fn) +} + +func (logger *Logger) FatalFn(fn LogFunction) { + logger.LogFn(FatalLevel, fn) + logger.Exit(1) +} + +func (logger *Logger) PanicFn(fn LogFunction) { + logger.LogFn(PanicLevel, fn) +} + func (logger *Logger) Logln(level Level, args ...interface{}) { if logger.IsLevelEnabled(level) { entry := logger.newEntry() diff --git a/vendor/github.com/sirupsen/logrus/logrus.go b/vendor/github.com/sirupsen/logrus/logrus.go index 8644761f7..2f16224cb 100644 --- a/vendor/github.com/sirupsen/logrus/logrus.go +++ b/vendor/github.com/sirupsen/logrus/logrus.go @@ -51,7 +51,7 @@ func (level *Level) UnmarshalText(text []byte) error { return err } - *level = Level(l) + *level = l return nil } diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go index 3c4f43f91..499789984 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_bsd.go @@ -1,4 +1,5 @@ // +build darwin dragonfly freebsd netbsd openbsd +// +build !js package logrus @@ -10,4 +11,3 @@ func isTerminal(fd int) bool { _, err := unix.IoctlGetTermios(fd, ioctlReadTermios) return err == nil } - diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_js.go b/vendor/github.com/sirupsen/logrus/terminal_check_js.go new file mode 100644 index 000000000..ebdae3ec6 --- /dev/null +++ b/vendor/github.com/sirupsen/logrus/terminal_check_js.go @@ -0,0 +1,7 @@ +// +build js + +package logrus + +func isTerminal(fd int) bool { + return false +} diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go index 355dc966f..04748b851 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_unix.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_unix.go @@ -1,4 +1,5 @@ -// +build linux aix +// +build linux aix zos +// +build !js package logrus @@ -10,4 +11,3 @@ func isTerminal(fd int) bool { _, err := unix.IoctlGetTermios(fd, ioctlReadTermios) return err == nil } - diff --git a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go index 572889db2..2879eb50e 100644 --- a/vendor/github.com/sirupsen/logrus/terminal_check_windows.go +++ b/vendor/github.com/sirupsen/logrus/terminal_check_windows.go @@ -5,30 +5,23 @@ package logrus import ( "io" "os" - "syscall" - sequences "github.com/konsorten/go-windows-terminal-sequences" + "golang.org/x/sys/windows" ) -func initTerminal(w io.Writer) { - switch v := w.(type) { - case *os.File: - sequences.EnableVirtualTerminalProcessing(syscall.Handle(v.Fd()), true) - } -} - func checkIfTerminal(w io.Writer) bool { - var ret bool switch v := w.(type) { case *os.File: + handle := windows.Handle(v.Fd()) var mode uint32 - err := syscall.GetConsoleMode(syscall.Handle(v.Fd()), &mode) - ret = (err == nil) - default: - ret = false - } - if ret { - initTerminal(w) + if err := windows.GetConsoleMode(handle, &mode); err != nil { + return false + } + mode |= windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING + if err := windows.SetConsoleMode(handle, mode); err != nil { + return false + } + return true } - return ret + return false } diff --git a/vendor/github.com/sirupsen/logrus/text_formatter.go b/vendor/github.com/sirupsen/logrus/text_formatter.go index e01587c43..be2c6efe5 100644 --- a/vendor/github.com/sirupsen/logrus/text_formatter.go +++ b/vendor/github.com/sirupsen/logrus/text_formatter.go @@ -6,9 +6,11 @@ import ( "os" "runtime" "sort" + "strconv" "strings" "sync" "time" + "unicode/utf8" ) const ( @@ -32,6 +34,14 @@ type TextFormatter struct { // Force disabling colors. DisableColors bool + // Force quoting of all values + ForceQuote bool + + // DisableQuote disables quoting for all values. + // DisableQuote will have a lower priority than ForceQuote. + // If both of them are set to true, quote will be forced on all values. + DisableQuote bool + // Override coloring based on CLICOLOR and CLICOLOR_FORCE. - https://bixense.com/clicolors/ EnvironmentOverrideColors bool @@ -43,7 +53,10 @@ type TextFormatter struct { // the time passed since beginning of execution. FullTimestamp bool - // TimestampFormat to use for display when a full timestamp is printed + // TimestampFormat to use for display when a full timestamp is printed. + // The format to use is the same than for time.Format or time.Parse from the standard + // library. + // The standard Library already provides a set of predefined format. TimestampFormat string // The fields are sorted by default for a consistent output. For applications @@ -57,6 +70,10 @@ type TextFormatter struct { // Disables the truncation of the level text to 4 characters. DisableLevelTruncation bool + // PadLevelText Adds padding the level text so that all the levels output at the same length + // PadLevelText is a superset of the DisableLevelTruncation option + PadLevelText bool + // QuoteEmptyFields will wrap empty fields in quotes if true QuoteEmptyFields bool @@ -79,23 +96,32 @@ type TextFormatter struct { CallerPrettyfier func(*runtime.Frame) (function string, file string) terminalInitOnce sync.Once + + // The max length of the level text, generated dynamically on init + levelTextMaxLength int } func (f *TextFormatter) init(entry *Entry) { if entry.Logger != nil { f.isTerminal = checkIfTerminal(entry.Logger.Out) } + // Get the max length of the level text + for _, level := range AllLevels { + levelTextLength := utf8.RuneCount([]byte(level.String())) + if levelTextLength > f.levelTextMaxLength { + f.levelTextMaxLength = levelTextLength + } + } } func (f *TextFormatter) isColored() bool { isColored := f.ForceColors || (f.isTerminal && (runtime.GOOS != "windows")) if f.EnvironmentOverrideColors { - if force, ok := os.LookupEnv("CLICOLOR_FORCE"); ok && force != "0" { + switch force, ok := os.LookupEnv("CLICOLOR_FORCE"); { + case ok && force != "0": isColored = true - } else if ok && force == "0" { - isColored = false - } else if os.Getenv("CLICOLOR") == "0" { + case ok && force == "0", os.Getenv("CLICOLOR") == "0": isColored = false } } @@ -212,14 +238,25 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin levelColor = yellow case ErrorLevel, FatalLevel, PanicLevel: levelColor = red + case InfoLevel: + levelColor = blue default: levelColor = blue } levelText := strings.ToUpper(entry.Level.String()) - if !f.DisableLevelTruncation { + if !f.DisableLevelTruncation && !f.PadLevelText { levelText = levelText[0:4] } + if f.PadLevelText { + // Generates the format string used in the next line, for example "%-6s" or "%-7s". + // Based on the max level text length. + formatString := "%-" + strconv.Itoa(f.levelTextMaxLength) + "s" + // Formats the level text by appending spaces up to the max length, for example: + // - "INFO " + // - "WARNING" + levelText = fmt.Sprintf(formatString, levelText) + } // Remove a single newline if it already exists in the message to keep // the behavior of logrus text_formatter the same as the stdlib log package @@ -243,11 +280,12 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin } } - if f.DisableTimestamp { + switch { + case f.DisableTimestamp: fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m%s %-44s ", levelColor, levelText, caller, entry.Message) - } else if !f.FullTimestamp { + case !f.FullTimestamp: fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%04d]%s %-44s ", levelColor, levelText, int(entry.Time.Sub(baseTimestamp)/time.Second), caller, entry.Message) - } else { + default: fmt.Fprintf(b, "\x1b[%dm%s\x1b[0m[%s]%s %-44s ", levelColor, levelText, entry.Time.Format(timestampFormat), caller, entry.Message) } for _, k := range keys { @@ -258,9 +296,15 @@ func (f *TextFormatter) printColored(b *bytes.Buffer, entry *Entry, keys []strin } func (f *TextFormatter) needsQuoting(text string) bool { + if f.ForceQuote { + return true + } if f.QuoteEmptyFields && len(text) == 0 { return true } + if f.DisableQuote { + return false + } for _, ch := range text { if !((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || diff --git a/vendor/github.com/sirupsen/logrus/writer.go b/vendor/github.com/sirupsen/logrus/writer.go index 9e1f75135..72e8e3a1b 100644 --- a/vendor/github.com/sirupsen/logrus/writer.go +++ b/vendor/github.com/sirupsen/logrus/writer.go @@ -6,10 +6,16 @@ import ( "runtime" ) +// Writer at INFO level. See WriterLevel for details. func (logger *Logger) Writer() *io.PipeWriter { return logger.WriterLevel(InfoLevel) } +// WriterLevel returns an io.Writer that can be used to write arbitrary text to +// the logger at the given log level. Each line written to the writer will be +// printed in the usual way using formatters and hooks. The writer is part of an +// io.Pipe and it is the callers responsibility to close the writer when done. +// This can be used to override the standard library logger easily. func (logger *Logger) WriterLevel(level Level) *io.PipeWriter { return NewEntry(logger).WriterLevel(level) } diff --git a/vendor/github.com/willf/bloom/.gitignore b/vendor/github.com/willf/bloom/.gitignore new file mode 100644 index 000000000..5c204d28b --- /dev/null +++ b/vendor/github.com/willf/bloom/.gitignore @@ -0,0 +1,26 @@ +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +target diff --git a/vendor/github.com/willf/bloom/.travis.yml b/vendor/github.com/willf/bloom/.travis.yml new file mode 100644 index 000000000..7b8fd3006 --- /dev/null +++ b/vendor/github.com/willf/bloom/.travis.yml @@ -0,0 +1,38 @@ +language: go + +sudo: false + +branches: + except: + - release + +branches: + only: + - master + - develop + - travis + +go: + - 1.8 + - tip + +matrix: + allow_failures: + - go: tip + +before_install: + - if [ -n "$GH_USER" ]; then git config --global github.user ${GH_USER}; fi; + - if [ -n "$GH_TOKEN" ]; then git config --global github.token ${GH_TOKEN}; fi; + - go get github.com/mattn/goveralls + +before_script: + - make deps + +script: + - make qa + +after_failure: + - cat ./target/test/report.xml + +after_success: + - if [ "$TRAVIS_GO_VERSION" = "1.8" ]; then $HOME/gopath/bin/goveralls -covermode=count -coverprofile=target/report/coverage.out -service=travis-ci; fi; diff --git a/vendor/github.com/willf/bloom/bloom_test.go b/vendor/github.com/willf/bloom/bloom_test.go deleted file mode 100644 index 151548ab2..000000000 --- a/vendor/github.com/willf/bloom/bloom_test.go +++ /dev/null @@ -1,597 +0,0 @@ -package bloom - -import ( - "bytes" - "encoding/binary" - "encoding/gob" - "encoding/json" - "math" - "testing" -) - -// This implementation of Bloom filters is _not_ -// safe for concurrent use. Uncomment the following -// method and run go test -race -// -// func TestConcurrent(t *testing.T) { -// gmp := runtime.GOMAXPROCS(2) -// defer runtime.GOMAXPROCS(gmp) -// -// f := New(1000, 4) -// n1 := []byte("Bess") -// n2 := []byte("Jane") -// f.Add(n1) -// f.Add(n2) -// -// var wg sync.WaitGroup -// const try = 1000 -// var err1, err2 error -// -// wg.Add(1) -// go func() { -// for i := 0; i < try; i++ { -// n1b := f.Test(n1) -// if !n1b { -// err1 = fmt.Errorf("%v should be in", n1) -// break -// } -// } -// wg.Done() -// }() -// -// wg.Add(1) -// go func() { -// for i := 0; i < try; i++ { -// n2b := f.Test(n2) -// if !n2b { -// err2 = fmt.Errorf("%v should be in", n2) -// break -// } -// } -// wg.Done() -// }() -// -// wg.Wait() -// -// if err1 != nil { -// t.Fatal(err1) -// } -// if err2 != nil { -// t.Fatal(err2) -// } -// } - -func TestBasic(t *testing.T) { - f := New(1000, 4) - n1 := []byte("Bess") - n2 := []byte("Jane") - n3 := []byte("Emma") - f.Add(n1) - n3a := f.TestAndAdd(n3) - n1b := f.Test(n1) - n2b := f.Test(n2) - n3b := f.Test(n3) - if !n1b { - t.Errorf("%v should be in.", n1) - } - if n2b { - t.Errorf("%v should not be in.", n2) - } - if n3a { - t.Errorf("%v should not be in the first time we look.", n3) - } - if !n3b { - t.Errorf("%v should be in the second time we look.", n3) - } -} - -func TestBasicUint32(t *testing.T) { - f := New(1000, 4) - n1 := make([]byte, 4) - n2 := make([]byte, 4) - n3 := make([]byte, 4) - n4 := make([]byte, 4) - binary.BigEndian.PutUint32(n1, 100) - binary.BigEndian.PutUint32(n2, 101) - binary.BigEndian.PutUint32(n3, 102) - binary.BigEndian.PutUint32(n4, 103) - f.Add(n1) - n3a := f.TestAndAdd(n3) - n1b := f.Test(n1) - n2b := f.Test(n2) - n3b := f.Test(n3) - f.Test(n4) - if !n1b { - t.Errorf("%v should be in.", n1) - } - if n2b { - t.Errorf("%v should not be in.", n2) - } - if n3a { - t.Errorf("%v should not be in the first time we look.", n3) - } - if !n3b { - t.Errorf("%v should be in the second time we look.", n3) - } -} - -func TestNewWithLowNumbers(t *testing.T) { - f := New(0, 0) - if f.k != 1 { - t.Errorf("%v should be 1", f.k) - } - if f.m != 1 { - t.Errorf("%v should be 1", f.m) - } -} - -func TestString(t *testing.T) { - f := NewWithEstimates(1000, 0.001) - n1 := "Love" - n2 := "is" - n3 := "in" - n4 := "bloom" - f.AddString(n1) - n3a := f.TestAndAddString(n3) - n1b := f.TestString(n1) - n2b := f.TestString(n2) - n3b := f.TestString(n3) - f.TestString(n4) - if !n1b { - t.Errorf("%v should be in.", n1) - } - if n2b { - t.Errorf("%v should not be in.", n2) - } - if n3a { - t.Errorf("%v should not be in the first time we look.", n3) - } - if !n3b { - t.Errorf("%v should be in the second time we look.", n3) - } - -} - -func testEstimated(n uint, maxFp float64, t *testing.T) { - m, k := EstimateParameters(n, maxFp) - f := NewWithEstimates(n, maxFp) - fpRate := f.EstimateFalsePositiveRate(n) - if fpRate > 1.5*maxFp { - t.Errorf("False positive rate too high: n: %v; m: %v; k: %v; maxFp: %f; fpRate: %f, fpRate/maxFp: %f", n, m, k, maxFp, fpRate, fpRate/maxFp) - } -} - -func TestEstimated1000_0001(t *testing.T) { testEstimated(1000, 0.000100, t) } -func TestEstimated10000_0001(t *testing.T) { testEstimated(10000, 0.000100, t) } -func TestEstimated100000_0001(t *testing.T) { testEstimated(100000, 0.000100, t) } - -func TestEstimated1000_001(t *testing.T) { testEstimated(1000, 0.001000, t) } -func TestEstimated10000_001(t *testing.T) { testEstimated(10000, 0.001000, t) } -func TestEstimated100000_001(t *testing.T) { testEstimated(100000, 0.001000, t) } - -func TestEstimated1000_01(t *testing.T) { testEstimated(1000, 0.010000, t) } -func TestEstimated10000_01(t *testing.T) { testEstimated(10000, 0.010000, t) } -func TestEstimated100000_01(t *testing.T) { testEstimated(100000, 0.010000, t) } - -func min(a, b uint) uint { - if a < b { - return a - } - return b -} - -// The following function courtesy of Nick @turgon -// This helper function ranges over the input data, applying the hashing -// which returns the bit locations to set in the filter. -// For each location, increment a counter for that bit address. -// -// If the Bloom Filter's location() method distributes locations uniformly -// at random, a property it should inherit from its hash function, then -// each bit location in the filter should end up with roughly the same -// number of hits. Importantly, the value of k should not matter. -// -// Once the results are collected, we can run a chi squared goodness of fit -// test, comparing the result histogram with the uniform distribition. -// This yields a test statistic with degrees-of-freedom of m-1. -func chiTestBloom(m, k, rounds uint, elements [][]byte) (succeeds bool) { - f := New(m, k) - results := make([]uint, m) - chi := make([]float64, m) - - for _, data := range elements { - h := baseHashes(data) - for i := uint(0); i < f.k; i++ { - results[f.location(h, i)]++ - } - } - - // Each element of results should contain the same value: k * rounds / m. - // Let's run a chi-square goodness of fit and see how it fares. - var chiStatistic float64 - e := float64(k*rounds) / float64(m) - for i := uint(0); i < m; i++ { - chi[i] = math.Pow(float64(results[i])-e, 2.0) / e - chiStatistic += chi[i] - } - - // this tests at significant level 0.005 up to 20 degrees of freedom - table := [20]float64{ - 7.879, 10.597, 12.838, 14.86, 16.75, 18.548, 20.278, - 21.955, 23.589, 25.188, 26.757, 28.3, 29.819, 31.319, 32.801, 34.267, - 35.718, 37.156, 38.582, 39.997} - df := min(m-1, 20) - - succeeds = table[df-1] > chiStatistic - return - -} - -func TestLocation(t *testing.T) { - var m, k, rounds uint - - m = 8 - k = 3 - - rounds = 100000 // 15000000 - - elements := make([][]byte, rounds) - - for x := uint(0); x < rounds; x++ { - ctrlist := make([]uint8, 4) - ctrlist[0] = uint8(x) - ctrlist[1] = uint8(x >> 8) - ctrlist[2] = uint8(x >> 16) - ctrlist[3] = uint8(x >> 24) - data := []byte(ctrlist) - elements[x] = data - } - - succeeds := chiTestBloom(m, k, rounds, elements) - if !succeeds { - t.Error("random assignment is too unrandom") - } - -} - -func TestCap(t *testing.T) { - f := New(1000, 4) - if f.Cap() != f.m { - t.Error("not accessing Cap() correctly") - } -} - -func TestK(t *testing.T) { - f := New(1000, 4) - if f.K() != f.k { - t.Error("not accessing K() correctly") - } -} - -func TestMarshalUnmarshalJSON(t *testing.T) { - f := New(1000, 4) - data, err := json.Marshal(f) - if err != nil { - t.Fatal(err.Error()) - } - - var g BloomFilter - err = json.Unmarshal(data, &g) - if err != nil { - t.Fatal(err.Error()) - } - if g.m != f.m { - t.Error("invalid m value") - } - if g.k != f.k { - t.Error("invalid k value") - } - if g.b == nil { - t.Fatal("bitset is nil") - } - if !g.b.Equal(f.b) { - t.Error("bitsets are not equal") - } -} - -func TestUnmarshalInvalidJSON(t *testing.T) { - data := []byte("{invalid}") - - var g BloomFilter - err := g.UnmarshalJSON(data) - if err == nil { - t.Error("expected error while unmarshalling invalid data") - } -} - -func TestWriteToReadFrom(t *testing.T) { - var b bytes.Buffer - f := New(1000, 4) - _, err := f.WriteTo(&b) - if err != nil { - t.Fatal(err) - } - - g := New(1000, 1) - _, err = g.ReadFrom(&b) - if err != nil { - t.Fatal(err) - } - if g.m != f.m { - t.Error("invalid m value") - } - if g.k != f.k { - t.Error("invalid k value") - } - if g.b == nil { - t.Fatal("bitset is nil") - } - if !g.b.Equal(f.b) { - t.Error("bitsets are not equal") - } - - g.Test([]byte("")) -} - -func TestReadWriteBinary(t *testing.T) { - f := New(1000, 4) - var buf bytes.Buffer - bytesWritten, err := f.WriteTo(&buf) - if err != nil { - t.Fatal(err.Error()) - } - if bytesWritten != int64(buf.Len()) { - t.Errorf("incorrect write length %d != %d", bytesWritten, buf.Len()) - } - - var g BloomFilter - bytesRead, err := g.ReadFrom(&buf) - if err != nil { - t.Fatal(err.Error()) - } - if bytesRead != bytesWritten { - t.Errorf("read unexpected number of bytes %d != %d", bytesRead, bytesWritten) - } - if g.m != f.m { - t.Error("invalid m value") - } - if g.k != f.k { - t.Error("invalid k value") - } - if g.b == nil { - t.Fatal("bitset is nil") - } - if !g.b.Equal(f.b) { - t.Error("bitsets are not equal") - } -} - -func TestEncodeDecodeGob(t *testing.T) { - f := New(1000, 4) - f.Add([]byte("one")) - f.Add([]byte("two")) - f.Add([]byte("three")) - var buf bytes.Buffer - err := gob.NewEncoder(&buf).Encode(f) - if err != nil { - t.Fatal(err.Error()) - } - - var g BloomFilter - err = gob.NewDecoder(&buf).Decode(&g) - if err != nil { - t.Fatal(err.Error()) - } - if g.m != f.m { - t.Error("invalid m value") - } - if g.k != f.k { - t.Error("invalid k value") - } - if g.b == nil { - t.Fatal("bitset is nil") - } - if !g.b.Equal(f.b) { - t.Error("bitsets are not equal") - } - if !g.Test([]byte("three")) { - t.Errorf("missing value 'three'") - } - if !g.Test([]byte("two")) { - t.Errorf("missing value 'two'") - } - if !g.Test([]byte("one")) { - t.Errorf("missing value 'one'") - } -} - -func TestEqual(t *testing.T) { - f := New(1000, 4) - f1 := New(1000, 4) - g := New(1000, 20) - h := New(10, 20) - n1 := []byte("Bess") - f1.Add(n1) - if !f.Equal(f) { - t.Errorf("%v should be equal to itself", f) - } - if f.Equal(f1) { - t.Errorf("%v should not be equal to %v", f, f1) - } - if f.Equal(g) { - t.Errorf("%v should not be equal to %v", f, g) - } - if f.Equal(h) { - t.Errorf("%v should not be equal to %v", f, h) - } -} - -func BenchmarkEstimated(b *testing.B) { - for n := uint(100000); n <= 100000; n *= 10 { - for fp := 0.1; fp >= 0.0001; fp /= 10.0 { - f := NewWithEstimates(n, fp) - f.EstimateFalsePositiveRate(n) - } - } -} - -func BenchmarkSeparateTestAndAdd(b *testing.B) { - f := NewWithEstimates(uint(b.N), 0.0001) - key := make([]byte, 100) - b.ResetTimer() - for i := 0; i < b.N; i++ { - binary.BigEndian.PutUint32(key, uint32(i)) - f.Test(key) - f.Add(key) - } -} - -func BenchmarkCombinedTestAndAdd(b *testing.B) { - f := NewWithEstimates(uint(b.N), 0.0001) - key := make([]byte, 100) - b.ResetTimer() - for i := 0; i < b.N; i++ { - binary.BigEndian.PutUint32(key, uint32(i)) - f.TestAndAdd(key) - } -} - -func TestMerge(t *testing.T) { - f := New(1000, 4) - n1 := []byte("f") - f.Add(n1) - - g := New(1000, 4) - n2 := []byte("g") - g.Add(n2) - - h := New(999, 4) - n3 := []byte("h") - h.Add(n3) - - j := New(1000, 5) - n4 := []byte("j") - j.Add(n4) - - err := f.Merge(g) - if err != nil { - t.Errorf("There should be no error when merging two similar filters") - } - - err = f.Merge(h) - if err == nil { - t.Errorf("There should be an error when merging filters with mismatched m") - } - - err = f.Merge(j) - if err == nil { - t.Errorf("There should be an error when merging filters with mismatched k") - } - - n2b := f.Test(n2) - if !n2b { - t.Errorf("The value doesn't exist after a valid merge") - } - - n3b := f.Test(n3) - if n3b { - t.Errorf("The value exists after an invalid merge") - } - - n4b := f.Test(n4) - if n4b { - t.Errorf("The value exists after an invalid merge") - } -} - -func TestCopy(t *testing.T) { - f := New(1000, 4) - n1 := []byte("f") - f.Add(n1) - - // copy here instead of New - g := f.Copy() - n2 := []byte("g") - g.Add(n2) - - n1fb := f.Test(n1) - if !n1fb { - t.Errorf("The value doesn't exist in original after making a copy") - } - - n1gb := g.Test(n1) - if !n1gb { - t.Errorf("The value doesn't exist in the copy") - } - - n2fb := f.Test(n2) - if n2fb { - t.Errorf("The value exists in the original, it should only exist in copy") - } - - n2gb := g.Test(n2) - if !n2gb { - t.Errorf("The value doesn't exist in copy after Add()") - } -} - -func TestFrom(t *testing.T) { - var ( - k = uint(5) - data = make([]uint64, 10) - test = []byte("test") - ) - - bf := From(data, k) - if bf.K() != k { - t.Errorf("Constant k does not match the expected value") - } - - if bf.Cap() != uint(len(data)*64) { - t.Errorf("Capacity does not match the expected value") - } - - if bf.Test(test) { - t.Errorf("Bloom filter should not contain the value") - } - - bf.Add(test) - if !bf.Test(test) { - t.Errorf("Bloom filter should contain the value") - } - - // create a new Bloom filter from an existing (populated) data slice. - bf = From(data, k) - if !bf.Test(test) { - t.Errorf("Bloom filter should contain the value") - } -} - -func TestTestLocations(t *testing.T) { - f := NewWithEstimates(1000, 0.001) - n1 := []byte("Love") - n2 := []byte("is") - n3 := []byte("in") - n4 := []byte("bloom") - f.Add(n1) - n3a := f.TestLocations(Locations(n3, f.K())) - f.Add(n3) - n1b := f.TestLocations(Locations(n1, f.K())) - n2b := f.TestLocations(Locations(n2, f.K())) - n3b := f.TestLocations(Locations(n3, f.K())) - n4b := f.TestLocations(Locations(n4, f.K())) - if !n1b { - t.Errorf("%v should be in.", n1) - } - if n2b { - t.Errorf("%v should not be in.", n2) - } - if n3a { - t.Errorf("%v should not be in the first time we look.", n3) - } - if !n3b { - t.Errorf("%v should be in the second time we look.", n3) - } - if n4b { - t.Errorf("%v should be in.", n4) - } -} diff --git a/vendor/golang.org/x/net/html/const.go b/vendor/golang.org/x/net/html/const.go index a3a918f0b..ff7acf2d5 100644 --- a/vendor/golang.org/x/net/html/const.go +++ b/vendor/golang.org/x/net/html/const.go @@ -52,8 +52,7 @@ var isSpecialElementMap = map[string]bool{ "iframe": true, "img": true, "input": true, - "isindex": true, // The 'isindex' element has been removed, but keep it for backwards compatibility. - "keygen": true, + "keygen": true, // "keygen" has been removed from the spec, but are kept here for backwards compatibility. "li": true, "link": true, "listing": true, diff --git a/vendor/golang.org/x/net/html/foreign.go b/vendor/golang.org/x/net/html/foreign.go index 01477a963..9da9e9dc4 100644 --- a/vendor/golang.org/x/net/html/foreign.go +++ b/vendor/golang.org/x/net/html/foreign.go @@ -161,66 +161,62 @@ var mathMLAttributeAdjustments = map[string]string{ } var svgAttributeAdjustments = map[string]string{ - "attributename": "attributeName", - "attributetype": "attributeType", - "basefrequency": "baseFrequency", - "baseprofile": "baseProfile", - "calcmode": "calcMode", - "clippathunits": "clipPathUnits", - "contentscripttype": "contentScriptType", - "contentstyletype": "contentStyleType", - "diffuseconstant": "diffuseConstant", - "edgemode": "edgeMode", - "externalresourcesrequired": "externalResourcesRequired", - "filterres": "filterRes", - "filterunits": "filterUnits", - "glyphref": "glyphRef", - "gradienttransform": "gradientTransform", - "gradientunits": "gradientUnits", - "kernelmatrix": "kernelMatrix", - "kernelunitlength": "kernelUnitLength", - "keypoints": "keyPoints", - "keysplines": "keySplines", - "keytimes": "keyTimes", - "lengthadjust": "lengthAdjust", - "limitingconeangle": "limitingConeAngle", - "markerheight": "markerHeight", - "markerunits": "markerUnits", - "markerwidth": "markerWidth", - "maskcontentunits": "maskContentUnits", - "maskunits": "maskUnits", - "numoctaves": "numOctaves", - "pathlength": "pathLength", - "patterncontentunits": "patternContentUnits", - "patterntransform": "patternTransform", - "patternunits": "patternUnits", - "pointsatx": "pointsAtX", - "pointsaty": "pointsAtY", - "pointsatz": "pointsAtZ", - "preservealpha": "preserveAlpha", - "preserveaspectratio": "preserveAspectRatio", - "primitiveunits": "primitiveUnits", - "refx": "refX", - "refy": "refY", - "repeatcount": "repeatCount", - "repeatdur": "repeatDur", - "requiredextensions": "requiredExtensions", - "requiredfeatures": "requiredFeatures", - "specularconstant": "specularConstant", - "specularexponent": "specularExponent", - "spreadmethod": "spreadMethod", - "startoffset": "startOffset", - "stddeviation": "stdDeviation", - "stitchtiles": "stitchTiles", - "surfacescale": "surfaceScale", - "systemlanguage": "systemLanguage", - "tablevalues": "tableValues", - "targetx": "targetX", - "targety": "targetY", - "textlength": "textLength", - "viewbox": "viewBox", - "viewtarget": "viewTarget", - "xchannelselector": "xChannelSelector", - "ychannelselector": "yChannelSelector", - "zoomandpan": "zoomAndPan", + "attributename": "attributeName", + "attributetype": "attributeType", + "basefrequency": "baseFrequency", + "baseprofile": "baseProfile", + "calcmode": "calcMode", + "clippathunits": "clipPathUnits", + "diffuseconstant": "diffuseConstant", + "edgemode": "edgeMode", + "filterunits": "filterUnits", + "glyphref": "glyphRef", + "gradienttransform": "gradientTransform", + "gradientunits": "gradientUnits", + "kernelmatrix": "kernelMatrix", + "kernelunitlength": "kernelUnitLength", + "keypoints": "keyPoints", + "keysplines": "keySplines", + "keytimes": "keyTimes", + "lengthadjust": "lengthAdjust", + "limitingconeangle": "limitingConeAngle", + "markerheight": "markerHeight", + "markerunits": "markerUnits", + "markerwidth": "markerWidth", + "maskcontentunits": "maskContentUnits", + "maskunits": "maskUnits", + "numoctaves": "numOctaves", + "pathlength": "pathLength", + "patterncontentunits": "patternContentUnits", + "patterntransform": "patternTransform", + "patternunits": "patternUnits", + "pointsatx": "pointsAtX", + "pointsaty": "pointsAtY", + "pointsatz": "pointsAtZ", + "preservealpha": "preserveAlpha", + "preserveaspectratio": "preserveAspectRatio", + "primitiveunits": "primitiveUnits", + "refx": "refX", + "refy": "refY", + "repeatcount": "repeatCount", + "repeatdur": "repeatDur", + "requiredextensions": "requiredExtensions", + "requiredfeatures": "requiredFeatures", + "specularconstant": "specularConstant", + "specularexponent": "specularExponent", + "spreadmethod": "spreadMethod", + "startoffset": "startOffset", + "stddeviation": "stdDeviation", + "stitchtiles": "stitchTiles", + "surfacescale": "surfaceScale", + "systemlanguage": "systemLanguage", + "tablevalues": "tableValues", + "targetx": "targetX", + "targety": "targetY", + "textlength": "textLength", + "viewbox": "viewBox", + "viewtarget": "viewTarget", + "xchannelselector": "xChannelSelector", + "ychannelselector": "yChannelSelector", + "zoomandpan": "zoomAndPan", } diff --git a/vendor/golang.org/x/net/html/node.go b/vendor/golang.org/x/net/html/node.go index 633ee15dc..1350eef22 100644 --- a/vendor/golang.org/x/net/html/node.go +++ b/vendor/golang.org/x/net/html/node.go @@ -18,6 +18,11 @@ const ( ElementNode CommentNode DoctypeNode + // RawNode nodes are not returned by the parser, but can be part of the + // Node tree passed to func Render to insert raw HTML (without escaping). + // If so, this package makes no guarantee that the rendered HTML is secure + // (from e.g. Cross Site Scripting attacks) or well-formed. + RawNode scopeMarkerNode ) diff --git a/vendor/golang.org/x/net/html/parse.go b/vendor/golang.org/x/net/html/parse.go index 992cff2a3..f91466f7c 100644 --- a/vendor/golang.org/x/net/html/parse.go +++ b/vendor/golang.org/x/net/html/parse.go @@ -184,6 +184,17 @@ func (p *parser) clearStackToContext(s scope) { } } +// parseGenericRawTextElements implements the generic raw text element parsing +// algorithm defined in 12.2.6.2. +// https://html.spec.whatwg.org/multipage/parsing.html#parsing-elements-that-contain-only-text +// TODO: Since both RAWTEXT and RCDATA states are treated as tokenizer's part +// officially, need to make tokenizer consider both states. +func (p *parser) parseGenericRawTextElement() { + p.addElement() + p.originalIM = p.im + p.im = textIM +} + // generateImpliedEndTags pops nodes off the stack of open elements as long as // the top node has a tag name of dd, dt, li, optgroup, option, p, rb, rp, rt or rtc. // If exceptions are specified, nodes with that name will not be popped off. @@ -192,16 +203,17 @@ func (p *parser) generateImpliedEndTags(exceptions ...string) { loop: for i = len(p.oe) - 1; i >= 0; i-- { n := p.oe[i] - if n.Type == ElementNode { - switch n.DataAtom { - case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc: - for _, except := range exceptions { - if n.Data == except { - break loop - } + if n.Type != ElementNode { + break + } + switch n.DataAtom { + case a.Dd, a.Dt, a.Li, a.Optgroup, a.Option, a.P, a.Rb, a.Rp, a.Rt, a.Rtc: + for _, except := range exceptions { + if n.Data == except { + break loop } - continue } + continue } break } @@ -369,8 +381,7 @@ findIdenticalElements: // Section 12.2.4.3. func (p *parser) clearActiveFormattingElements() { for { - n := p.afe.pop() - if len(p.afe) == 0 || n.Type == scopeMarkerNode { + if n := p.afe.pop(); len(p.afe) == 0 || n.Type == scopeMarkerNode { return } } @@ -625,25 +636,29 @@ func inHeadIM(p *parser) bool { switch p.tok.DataAtom { case a.Html: return inBodyIM(p) - case a.Base, a.Basefont, a.Bgsound, a.Command, a.Link, a.Meta: + case a.Base, a.Basefont, a.Bgsound, a.Link, a.Meta: p.addElement() p.oe.pop() p.acknowledgeSelfClosingTag() return true case a.Noscript: - p.addElement() if p.scripting { - p.setOriginalIM() - p.im = textIM - } else { - p.im = inHeadNoscriptIM + p.parseGenericRawTextElement() + return true } + p.addElement() + p.im = inHeadNoscriptIM + // Don't let the tokenizer go into raw text mode when scripting is disabled. + p.tokenizer.NextIsNotRawText() return true - case a.Script, a.Title, a.Noframes, a.Style: + case a.Script, a.Title: p.addElement() p.setOriginalIM() p.im = textIM return true + case a.Noframes, a.Style: + p.parseGenericRawTextElement() + return true case a.Head: // Ignore the token. return true @@ -713,7 +728,13 @@ func inHeadNoscriptIM(p *parser) bool { return inBodyIM(p) case a.Basefont, a.Bgsound, a.Link, a.Meta, a.Noframes, a.Style: return inHeadIM(p) - case a.Head, a.Noscript: + case a.Head: + // Ignore the token. + return true + case a.Noscript: + // Don't let the tokenizer go into raw text mode even when a