mirror of https://github.com/k3d-io/k3d
parent
1a371d7852
commit
85c49b7279
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,395 @@ |
||||
bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= |
||||
cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= |
||||
cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= |
||||
cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= |
||||
cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= |
||||
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= |
||||
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= |
||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= |
||||
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= |
||||
cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= |
||||
cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= |
||||
cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= |
||||
cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= |
||||
cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= |
||||
cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= |
||||
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= |
||||
cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= |
||||
github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= |
||||
github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= |
||||
github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= |
||||
github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= |
||||
github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= |
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= |
||||
github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= |
||||
github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= |
||||
github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= |
||||
github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= |
||||
github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= |
||||
github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= |
||||
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= |
||||
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= |
||||
github.com/armon/go-metrics v0.3.10/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= |
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= |
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= |
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= |
||||
github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= |
||||
github.com/bitly/go-simplejson v0.5.0 h1:6IH+V8/tVMab511d5bn4M7EwGXZf9Hj6i2xSwkNEM+Y= |
||||
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= |
||||
github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= |
||||
github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= |
||||
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= |
||||
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= |
||||
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= |
||||
github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= |
||||
github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= |
||||
github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= |
||||
github.com/cncf/xds/go v0.0.0-20211130200136-a8f946100490/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= |
||||
github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= |
||||
github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= |
||||
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= |
||||
github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= |
||||
github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= |
||||
github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0NpumIq9ODB0kLtoE= |
||||
github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= |
||||
github.com/containerd/go-cni v1.1.0/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= |
||||
github.com/containerd/go-cni v1.1.3/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= |
||||
github.com/containerd/go-cni v1.1.6/go.mod h1:BWtoWl5ghVymxu6MBjg79W9NZrCRyHIdUtk4cauMe34= |
||||
github.com/containerd/imgcrypt v1.1.3/go.mod h1:/TPA1GIDXMzbj01yd8pIbQiLdQxed5ue1wb8bP7PQu4= |
||||
github.com/containerd/imgcrypt v1.1.4/go.mod h1:LorQnPtzL/T0IyCeftcsMEO7AqxUDbdO8j/tSUpgxvo= |
||||
github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y= |
||||
github.com/containernetworking/cni v1.1.1/go.mod h1:sDpYKmGVENF3s6uvMvGgldDWeG8dMxakj/u+i9ht9vw= |
||||
github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE= |
||||
github.com/containernetworking/plugins v1.1.1/go.mod h1:Sr5TH/eBsGLXK/h71HeLfX19sZPp3ry5uHSkI4LPxV8= |
||||
github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= |
||||
github.com/containers/ocicrypt v1.1.3/go.mod h1:xpdkbVAuaH3WzbEabUd5yDsl9SwJA5pABH85425Es2g= |
||||
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= |
||||
github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= |
||||
github.com/emicklei/go-restful/v3 v3.8.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= |
||||
github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= |
||||
github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= |
||||
github.com/envoyproxy/protoc-gen-validate v0.6.2/go.mod h1:2t7qjJNvHPx8IjnBOzl9E9/baC+qXE/TeeyBRzgJDws= |
||||
github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= |
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= |
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= |
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= |
||||
github.com/frankban/quicktest v1.14.3/go.mod h1:mgiwOwqx65TmIk1wJ6Q7wvnVMocbUorkibMOrVTHZps= |
||||
github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= |
||||
github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= |
||||
github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= |
||||
github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= |
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= |
||||
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= |
||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= |
||||
github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= |
||||
github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= |
||||
github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= |
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= |
||||
github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= |
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= |
||||
github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= |
||||
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= |
||||
github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= |
||||
github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= |
||||
github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= |
||||
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= |
||||
github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= |
||||
github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= |
||||
github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= |
||||
github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= |
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= |
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= |
||||
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= |
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= |
||||
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= |
||||
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= |
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= |
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= |
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= |
||||
github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= |
||||
github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= |
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= |
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= |
||||
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= |
||||
github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= |
||||
github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= |
||||
github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= |
||||
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= |
||||
github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= |
||||
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= |
||||
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= |
||||
github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= |
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= |
||||
github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= |
||||
github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= |
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= |
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= |
||||
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= |
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= |
||||
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= |
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= |
||||
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= |
||||
github.com/hashicorp/serf v0.9.7/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= |
||||
github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= |
||||
github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= |
||||
github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= |
||||
github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= |
||||
github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= |
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= |
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= |
||||
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= |
||||
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= |
||||
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= |
||||
github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= |
||||
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= |
||||
github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= |
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= |
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= |
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= |
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= |
||||
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= |
||||
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= |
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= |
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= |
||||
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= |
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= |
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= |
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= |
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= |
||||
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= |
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= |
||||
github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= |
||||
github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= |
||||
github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= |
||||
github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= |
||||
github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= |
||||
github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= |
||||
github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= |
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= |
||||
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= |
||||
github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= |
||||
github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= |
||||
github.com/onsi/ginkgo/v2 v2.1.3/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= |
||||
github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= |
||||
github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= |
||||
github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= |
||||
github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= |
||||
github.com/opencontainers/selinux v1.10.1/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= |
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= |
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= |
||||
github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= |
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= |
||||
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= |
||||
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= |
||||
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= |
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= |
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= |
||||
github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= |
||||
github.com/sagikazarmark/crypt v0.6.0/go.mod h1:U8+INwJo3nBv1m6A/8OBXAq7Jnpspk5AxSgDyEQcea8= |
||||
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= |
||||
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= |
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= |
||||
github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= |
||||
github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= |
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= |
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= |
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48= |
||||
github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= |
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= |
||||
github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= |
||||
github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= |
||||
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= |
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= |
||||
go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= |
||||
go.etcd.io/etcd/api/v3 v3.5.4/go.mod h1:5GB2vv4A4AOn3yk7MftYGHkUfGtDHnEraIjym4dYz5A= |
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= |
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.4/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= |
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= |
||||
go.etcd.io/etcd/client/v2 v2.305.4/go.mod h1:Ud+VUwIi9/uQHOMA+4ekToJ12lTxlv0zB/+DHwTGEbU= |
||||
go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= |
||||
go.etcd.io/etcd/client/v3 v3.5.4/go.mod h1:ZaRkVgBZC+L+dLCjTcF1hRXpgZXQPOvnA/Ak/gq3kiY= |
||||
go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= |
||||
go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= |
||||
go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= |
||||
go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= |
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= |
||||
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= |
||||
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= |
||||
go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= |
||||
go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= |
||||
go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= |
||||
go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= |
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= |
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= |
||||
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= |
||||
go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= |
||||
go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= |
||||
go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= |
||||
go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= |
||||
go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= |
||||
go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= |
||||
go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= |
||||
go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= |
||||
go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= |
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= |
||||
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= |
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= |
||||
go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= |
||||
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= |
||||
golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= |
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= |
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= |
||||
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= |
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= |
||||
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= |
||||
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= |
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= |
||||
golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
||||
golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
||||
golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= |
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= |
||||
golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= |
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= |
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= |
||||
golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= |
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= |
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= |
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= |
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= |
||||
golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= |
||||
golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= |
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= |
||||
golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= |
||||
golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= |
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= |
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= |
||||
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= |
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= |
||||
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= |
||||
golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= |
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= |
||||
golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
||||
golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
||||
golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= |
||||
golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= |
||||
golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= |
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= |
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= |
||||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= |
||||
golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= |
||||
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= |
||||
google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= |
||||
google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= |
||||
google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= |
||||
google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= |
||||
google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= |
||||
google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= |
||||
google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= |
||||
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= |
||||
google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= |
||||
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= |
||||
google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= |
||||
google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= |
||||
google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= |
||||
google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= |
||||
google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= |
||||
google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= |
||||
google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= |
||||
google.golang.org/api v0.81.0/go.mod h1:FA6Mb/bZxj706H2j+j2d6mHEEaHBmbbWnkfvmorOCko= |
||||
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= |
||||
google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= |
||||
google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= |
||||
google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= |
||||
google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= |
||||
google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= |
||||
google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= |
||||
google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= |
||||
google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= |
||||
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= |
||||
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= |
||||
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= |
||||
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= |
||||
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= |
||||
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= |
||||
google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= |
||||
google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= |
||||
google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= |
||||
google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= |
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= |
||||
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= |
||||
google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= |
||||
google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= |
||||
google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= |
||||
google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= |
||||
google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= |
||||
google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= |
||||
google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= |
||||
google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= |
||||
google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= |
||||
google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= |
||||
google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= |
||||
google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= |
||||
google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= |
||||
google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= |
||||
google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= |
||||
google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= |
||||
google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= |
||||
google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= |
||||
google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= |
||||
google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= |
||||
google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= |
||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= |
||||
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= |
||||
google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= |
||||
google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= |
||||
google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= |
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= |
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= |
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= |
||||
k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= |
||||
k8s.io/api v0.25.0/go.mod h1:ttceV1GyV1i1rnmvzT3BST08N6nGt+dudGrquzVQWPk= |
||||
k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= |
||||
k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= |
||||
k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ= |
||||
k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y= |
||||
k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= |
||||
k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4= |
||||
k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= |
||||
k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= |
||||
k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= |
||||
k8s.io/kube-openapi v0.0.0-20220803162953-67bda5d908f1/go.mod h1:C/N6wCaBHeBHkHUesQOQy2/MZqGgMAFPqGsGQLdbZBU= |
||||
k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= |
||||
k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= |
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= |
||||
sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,15 @@ |
||||
// +build !windows
|
||||
|
||||
package guid |
||||
|
||||
// GUID represents a GUID/UUID. It has the same structure as
|
||||
// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
|
||||
// that type. It is defined as its own type as that is only available to builds
|
||||
// targeted at `windows`. The representation matches that used by native Windows
|
||||
// code.
|
||||
type GUID struct { |
||||
Data1 uint32 |
||||
Data2 uint16 |
||||
Data3 uint16 |
||||
Data4 [8]byte |
||||
} |
@ -0,0 +1,10 @@ |
||||
package guid |
||||
|
||||
import "golang.org/x/sys/windows" |
||||
|
||||
// GUID represents a GUID/UUID. It has the same structure as
|
||||
// golang.org/x/sys/windows.GUID so that it can be used with functions expecting
|
||||
// that type. It is defined as its own type so that stringification and
|
||||
// marshaling can be supported. The representation matches that used by native
|
||||
// Windows code.
|
||||
type GUID windows.GUID |
@ -1,191 +0,0 @@ |
||||
|
||||
Apache License |
||||
Version 2.0, January 2004 |
||||
https://www.apache.org/licenses/ |
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION |
||||
|
||||
1. Definitions. |
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, |
||||
and distribution as defined by Sections 1 through 9 of this document. |
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by |
||||
the copyright owner that is granting the License. |
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all |
||||
other entities that control, are controlled by, or are under common |
||||
control with that entity. For the purposes of this definition, |
||||
"control" means (i) the power, direct or indirect, to cause the |
||||
direction or management of such entity, whether by contract or |
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the |
||||
outstanding shares, or (iii) beneficial ownership of such entity. |
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity |
||||
exercising permissions granted by this License. |
||||
|
||||
"Source" form shall mean the preferred form for making modifications, |
||||
including but not limited to software source code, documentation |
||||
source, and configuration files. |
||||
|
||||
"Object" form shall mean any form resulting from mechanical |
||||
transformation or translation of a Source form, including but |
||||
not limited to compiled object code, generated documentation, |
||||
and conversions to other media types. |
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or |
||||
Object form, made available under the License, as indicated by a |
||||
copyright notice that is included in or attached to the work |
||||
(an example is provided in the Appendix below). |
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object |
||||
form, that is based on (or derived from) the Work and for which the |
||||
editorial revisions, annotations, elaborations, or other modifications |
||||
represent, as a whole, an original work of authorship. For the purposes |
||||
of this License, Derivative Works shall not include works that remain |
||||
separable from, or merely link (or bind by name) to the interfaces of, |
||||
the Work and Derivative Works thereof. |
||||
|
||||
"Contribution" shall mean any work of authorship, including |
||||
the original version of the Work and any modifications or additions |
||||
to that Work or Derivative Works thereof, that is intentionally |
||||
submitted to Licensor for inclusion in the Work by the copyright owner |
||||
or by an individual or Legal Entity authorized to submit on behalf of |
||||
the copyright owner. For the purposes of this definition, "submitted" |
||||
means any form of electronic, verbal, or written communication sent |
||||
to the Licensor or its representatives, including but not limited to |
||||
communication on electronic mailing lists, source code control systems, |
||||
and issue tracking systems that are managed by, or on behalf of, the |
||||
Licensor for the purpose of discussing and improving the Work, but |
||||
excluding communication that is conspicuously marked or otherwise |
||||
designated in writing by the copyright owner as "Not a Contribution." |
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity |
||||
on behalf of whom a Contribution has been received by Licensor and |
||||
subsequently incorporated within the Work. |
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
copyright license to reproduce, prepare Derivative Works of, |
||||
publicly display, publicly perform, sublicense, and distribute the |
||||
Work and such Derivative Works in Source or Object form. |
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of |
||||
this License, each Contributor hereby grants to You a perpetual, |
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable |
||||
(except as stated in this section) patent license to make, have made, |
||||
use, offer to sell, sell, import, and otherwise transfer the Work, |
||||
where such license applies only to those patent claims licensable |
||||
by such Contributor that are necessarily infringed by their |
||||
Contribution(s) alone or by combination of their Contribution(s) |
||||
with the Work to which such Contribution(s) was submitted. If You |
||||
institute patent litigation against any entity (including a |
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work |
||||
or a Contribution incorporated within the Work constitutes direct |
||||
or contributory patent infringement, then any patent licenses |
||||
granted to You under this License for that Work shall terminate |
||||
as of the date such litigation is filed. |
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the |
||||
Work or Derivative Works thereof in any medium, with or without |
||||
modifications, and in Source or Object form, provided that You |
||||
meet the following conditions: |
||||
|
||||
(a) You must give any other recipients of the Work or |
||||
Derivative Works a copy of this License; and |
||||
|
||||
(b) You must cause any modified files to carry prominent notices |
||||
stating that You changed the files; and |
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works |
||||
that You distribute, all copyright, patent, trademark, and |
||||
attribution notices from the Source form of the Work, |
||||
excluding those notices that do not pertain to any part of |
||||
the Derivative Works; and |
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its |
||||
distribution, then any Derivative Works that You distribute must |
||||
include a readable copy of the attribution notices contained |
||||
within such NOTICE file, excluding those notices that do not |
||||
pertain to any part of the Derivative Works, in at least one |
||||
of the following places: within a NOTICE text file distributed |
||||
as part of the Derivative Works; within the Source form or |
||||
documentation, if provided along with the Derivative Works; or, |
||||
within a display generated by the Derivative Works, if and |
||||
wherever such third-party notices normally appear. The contents |
||||
of the NOTICE file are for informational purposes only and |
||||
do not modify the License. You may add Your own attribution |
||||
notices within Derivative Works that You distribute, alongside |
||||
or as an addendum to the NOTICE text from the Work, provided |
||||
that such additional attribution notices cannot be construed |
||||
as modifying the License. |
||||
|
||||
You may add Your own copyright statement to Your modifications and |
||||
may provide additional or different license terms and conditions |
||||
for use, reproduction, or distribution of Your modifications, or |
||||
for any such Derivative Works as a whole, provided Your use, |
||||
reproduction, and distribution of the Work otherwise complies with |
||||
the conditions stated in this License. |
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise, |
||||
any Contribution intentionally submitted for inclusion in the Work |
||||
by You to the Licensor shall be under the terms and conditions of |
||||
this License, without any additional terms or conditions. |
||||
Notwithstanding the above, nothing herein shall supersede or modify |
||||
the terms of any separate license agreement you may have executed |
||||
with Licensor regarding such Contributions. |
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade |
||||
names, trademarks, service marks, or product names of the Licensor, |
||||
except as required for reasonable and customary use in describing the |
||||
origin of the Work and reproducing the content of the NOTICE file. |
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or |
||||
agreed to in writing, Licensor provides the Work (and each |
||||
Contributor provides its Contributions) on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or |
||||
implied, including, without limitation, any warranties or conditions |
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A |
||||
PARTICULAR PURPOSE. You are solely responsible for determining the |
||||
appropriateness of using or redistributing the Work and assume any |
||||
risks associated with Your exercise of permissions under this License. |
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory, |
||||
whether in tort (including negligence), contract, or otherwise, |
||||
unless required by applicable law (such as deliberate and grossly |
||||
negligent acts) or agreed to in writing, shall any Contributor be |
||||
liable to You for damages, including any direct, indirect, special, |
||||
incidental, or consequential damages of any character arising as a |
||||
result of this License or out of the use or inability to use the |
||||
Work (including but not limited to damages for loss of goodwill, |
||||
work stoppage, computer failure or malfunction, or any and all |
||||
other commercial damages or losses), even if such Contributor |
||||
has been advised of the possibility of such damages. |
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing |
||||
the Work or Derivative Works thereof, You may choose to offer, |
||||
and charge a fee for, acceptance of support, warranty, indemnity, |
||||
or other liability obligations and/or rights consistent with this |
||||
License. However, in accepting such obligations, You may act only |
||||
on Your own behalf and on Your sole responsibility, not on behalf |
||||
of any other Contributor, and only if You agree to indemnify, |
||||
defend, and hold each Contributor harmless for any liability |
||||
incurred by, or claims asserted against, such Contributor by reason |
||||
of your accepting any such warranty or additional liability. |
||||
|
||||
END OF TERMS AND CONDITIONS |
||||
|
||||
Copyright The containerd Authors |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0 |
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
@ -1,16 +0,0 @@ |
||||
Docker |
||||
Copyright 2012-2015 Docker, Inc. |
||||
|
||||
This product includes software developed at Docker, Inc. (https://www.docker.com). |
||||
|
||||
The following is courtesy of our legal counsel: |
||||
|
||||
|
||||
Use and transfer of Docker may be subject to certain restrictions by the |
||||
United States and other governments. |
||||
It is your responsibility to ensure that your use and/or transfer does not |
||||
violate applicable laws. |
||||
|
||||
For more information, please see https://www.bis.doc.gov |
||||
|
||||
See also https://www.apache.org/dev/crypto.html and/or seek legal counsel. |
@ -1,93 +0,0 @@ |
||||
/* |
||||
Copyright The containerd Authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
// Package errdefs defines the common errors used throughout containerd
|
||||
// packages.
|
||||
//
|
||||
// Use with errors.Wrap and error.Wrapf to add context to an error.
|
||||
//
|
||||
// To detect an error class, use the IsXXX functions to tell whether an error
|
||||
// is of a certain type.
|
||||
//
|
||||
// The functions ToGRPC and FromGRPC can be used to map server-side and
|
||||
// client-side errors to the correct types.
|
||||
package errdefs |
||||
|
||||
import ( |
||||
"context" |
||||
|
||||
"github.com/pkg/errors" |
||||
) |
||||
|
||||
// Definitions of common error types used throughout containerd. All containerd
|
||||
// errors returned by most packages will map into one of these errors classes.
|
||||
// Packages should return errors of these types when they want to instruct a
|
||||
// client to take a particular action.
|
||||
//
|
||||
// For the most part, we just try to provide local grpc errors. Most conditions
|
||||
// map very well to those defined by grpc.
|
||||
var ( |
||||
ErrUnknown = errors.New("unknown") // used internally to represent a missed mapping.
|
||||
ErrInvalidArgument = errors.New("invalid argument") |
||||
ErrNotFound = errors.New("not found") |
||||
ErrAlreadyExists = errors.New("already exists") |
||||
ErrFailedPrecondition = errors.New("failed precondition") |
||||
ErrUnavailable = errors.New("unavailable") |
||||
ErrNotImplemented = errors.New("not implemented") // represents not supported and unimplemented
|
||||
) |
||||
|
||||
// IsInvalidArgument returns true if the error is due to an invalid argument
|
||||
func IsInvalidArgument(err error) bool { |
||||
return errors.Is(err, ErrInvalidArgument) |
||||
} |
||||
|
||||
// IsNotFound returns true if the error is due to a missing object
|
||||
func IsNotFound(err error) bool { |
||||
return errors.Is(err, ErrNotFound) |
||||
} |
||||
|
||||
// IsAlreadyExists returns true if the error is due to an already existing
|
||||
// metadata item
|
||||
func IsAlreadyExists(err error) bool { |
||||
return errors.Is(err, ErrAlreadyExists) |
||||
} |
||||
|
||||
// IsFailedPrecondition returns true if an operation could not proceed to the
|
||||
// lack of a particular condition
|
||||
func IsFailedPrecondition(err error) bool { |
||||
return errors.Is(err, ErrFailedPrecondition) |
||||
} |
||||
|
||||
// IsUnavailable returns true if the error is due to a resource being unavailable
|
||||
func IsUnavailable(err error) bool { |
||||
return errors.Is(err, ErrUnavailable) |
||||
} |
||||
|
||||
// IsNotImplemented returns true if the error is due to not being implemented
|
||||
func IsNotImplemented(err error) bool { |
||||
return errors.Is(err, ErrNotImplemented) |
||||
} |
||||
|
||||
// IsCanceled returns true if the error is due to `context.Canceled`.
|
||||
func IsCanceled(err error) bool { |
||||
return errors.Is(err, context.Canceled) |
||||
} |
||||
|
||||
// IsDeadlineExceeded returns true if the error is due to
|
||||
// `context.DeadlineExceeded`.
|
||||
func IsDeadlineExceeded(err error) bool { |
||||
return errors.Is(err, context.DeadlineExceeded) |
||||
} |
@ -1,147 +0,0 @@ |
||||
/* |
||||
Copyright The containerd Authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
package errdefs |
||||
|
||||
import ( |
||||
"context" |
||||
"strings" |
||||
|
||||
"github.com/pkg/errors" |
||||
"google.golang.org/grpc/codes" |
||||
"google.golang.org/grpc/status" |
||||
) |
||||
|
||||
// ToGRPC will attempt to map the backend containerd error into a grpc error,
|
||||
// using the original error message as a description.
|
||||
//
|
||||
// Further information may be extracted from certain errors depending on their
|
||||
// type.
|
||||
//
|
||||
// If the error is unmapped, the original error will be returned to be handled
|
||||
// by the regular grpc error handling stack.
|
||||
func ToGRPC(err error) error { |
||||
if err == nil { |
||||
return nil |
||||
} |
||||
|
||||
if isGRPCError(err) { |
||||
// error has already been mapped to grpc
|
||||
return err |
||||
} |
||||
|
||||
switch { |
||||
case IsInvalidArgument(err): |
||||
return status.Errorf(codes.InvalidArgument, err.Error()) |
||||
case IsNotFound(err): |
||||
return status.Errorf(codes.NotFound, err.Error()) |
||||
case IsAlreadyExists(err): |
||||
return status.Errorf(codes.AlreadyExists, err.Error()) |
||||
case IsFailedPrecondition(err): |
||||
return status.Errorf(codes.FailedPrecondition, err.Error()) |
||||
case IsUnavailable(err): |
||||
return status.Errorf(codes.Unavailable, err.Error()) |
||||
case IsNotImplemented(err): |
||||
return status.Errorf(codes.Unimplemented, err.Error()) |
||||
case IsCanceled(err): |
||||
return status.Errorf(codes.Canceled, err.Error()) |
||||
case IsDeadlineExceeded(err): |
||||
return status.Errorf(codes.DeadlineExceeded, err.Error()) |
||||
} |
||||
|
||||
return err |
||||
} |
||||
|
||||
// ToGRPCf maps the error to grpc error codes, assembling the formatting string
|
||||
// and combining it with the target error string.
|
||||
//
|
||||
// This is equivalent to errors.ToGRPC(errors.Wrapf(err, format, args...))
|
||||
func ToGRPCf(err error, format string, args ...interface{}) error { |
||||
return ToGRPC(errors.Wrapf(err, format, args...)) |
||||
} |
||||
|
||||
// FromGRPC returns the underlying error from a grpc service based on the grpc error code
|
||||
func FromGRPC(err error) error { |
||||
if err == nil { |
||||
return nil |
||||
} |
||||
|
||||
var cls error // divide these into error classes, becomes the cause
|
||||
|
||||
switch code(err) { |
||||
case codes.InvalidArgument: |
||||
cls = ErrInvalidArgument |
||||
case codes.AlreadyExists: |
||||
cls = ErrAlreadyExists |
||||
case codes.NotFound: |
||||
cls = ErrNotFound |
||||
case codes.Unavailable: |
||||
cls = ErrUnavailable |
||||
case codes.FailedPrecondition: |
||||
cls = ErrFailedPrecondition |
||||
case codes.Unimplemented: |
||||
cls = ErrNotImplemented |
||||
case codes.Canceled: |
||||
cls = context.Canceled |
||||
case codes.DeadlineExceeded: |
||||
cls = context.DeadlineExceeded |
||||
default: |
||||
cls = ErrUnknown |
||||
} |
||||
|
||||
msg := rebaseMessage(cls, err) |
||||
if msg != "" { |
||||
err = errors.Wrap(cls, msg) |
||||
} else { |
||||
err = errors.WithStack(cls) |
||||
} |
||||
|
||||
return err |
||||
} |
||||
|
||||
// rebaseMessage removes the repeats for an error at the end of an error
|
||||
// string. This will happen when taking an error over grpc then remapping it.
|
||||
//
|
||||
// Effectively, we just remove the string of cls from the end of err if it
|
||||
// appears there.
|
||||
func rebaseMessage(cls error, err error) string { |
||||
desc := errDesc(err) |
||||
clss := cls.Error() |
||||
if desc == clss { |
||||
return "" |
||||
} |
||||
|
||||
return strings.TrimSuffix(desc, ": "+clss) |
||||
} |
||||
|
||||
func isGRPCError(err error) bool { |
||||
_, ok := status.FromError(err) |
||||
return ok |
||||
} |
||||
|
||||
func code(err error) codes.Code { |
||||
if s, ok := status.FromError(err); ok { |
||||
return s.Code() |
||||
} |
||||
return codes.Unknown |
||||
} |
||||
|
||||
func errDesc(err error) string { |
||||
if s, ok := status.FromError(err); ok { |
||||
return s.Message() |
||||
} |
||||
return err.Error() |
||||
} |
@ -1,68 +0,0 @@ |
||||
/* |
||||
Copyright The containerd Authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
package log |
||||
|
||||
import ( |
||||
"context" |
||||
|
||||
"github.com/sirupsen/logrus" |
||||
) |
||||
|
||||
var ( |
||||
// G is an alias for GetLogger.
|
||||
//
|
||||
// We may want to define this locally to a package to get package tagged log
|
||||
// messages.
|
||||
G = GetLogger |
||||
|
||||
// L is an alias for the standard logger.
|
||||
L = logrus.NewEntry(logrus.StandardLogger()) |
||||
) |
||||
|
||||
type ( |
||||
loggerKey struct{} |
||||
) |
||||
|
||||
const ( |
||||
// RFC3339NanoFixed is time.RFC3339Nano with nanoseconds padded using zeros to
|
||||
// ensure the formatted time is always the same number of characters.
|
||||
RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00" |
||||
|
||||
// TextFormat represents the text logging format
|
||||
TextFormat = "text" |
||||
|
||||
// JSONFormat represents the JSON logging format
|
||||
JSONFormat = "json" |
||||
) |
||||
|
||||
// WithLogger returns a new context with the provided logger. Use in
|
||||
// combination with logger.WithField(s) for great effect.
|
||||
func WithLogger(ctx context.Context, logger *logrus.Entry) context.Context { |
||||
return context.WithValue(ctx, loggerKey{}, logger) |
||||
} |
||||
|
||||
// GetLogger retrieves the current logger from the context. If no logger is
|
||||
// available, the default logger is returned.
|
||||
func GetLogger(ctx context.Context) *logrus.Entry { |
||||
logger := ctx.Value(loggerKey{}) |
||||
|
||||
if logger == nil { |
||||
return L |
||||
} |
||||
|
||||
return logger.(*logrus.Entry) |
||||
} |
@ -1,193 +0,0 @@ |
||||
/* |
||||
Copyright The containerd Authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
package platforms |
||||
|
||||
import ( |
||||
"strconv" |
||||
"strings" |
||||
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1" |
||||
) |
||||
|
||||
// MatchComparer is able to match and compare platforms to
|
||||
// filter and sort platforms.
|
||||
type MatchComparer interface { |
||||
Matcher |
||||
|
||||
Less(specs.Platform, specs.Platform) bool |
||||
} |
||||
|
||||
// platformVector returns an (ordered) vector of appropriate specs.Platform
|
||||
// objects to try matching for the given platform object (see platforms.Only).
|
||||
func platformVector(platform specs.Platform) []specs.Platform { |
||||
vector := []specs.Platform{platform} |
||||
|
||||
switch platform.Architecture { |
||||
case "amd64": |
||||
vector = append(vector, specs.Platform{ |
||||
Architecture: "386", |
||||
OS: platform.OS, |
||||
OSVersion: platform.OSVersion, |
||||
OSFeatures: platform.OSFeatures, |
||||
Variant: platform.Variant, |
||||
}) |
||||
case "arm": |
||||
if armVersion, err := strconv.Atoi(strings.TrimPrefix(platform.Variant, "v")); err == nil && armVersion > 5 { |
||||
for armVersion--; armVersion >= 5; armVersion-- { |
||||
vector = append(vector, specs.Platform{ |
||||
Architecture: platform.Architecture, |
||||
OS: platform.OS, |
||||
OSVersion: platform.OSVersion, |
||||
OSFeatures: platform.OSFeatures, |
||||
Variant: "v" + strconv.Itoa(armVersion), |
||||
}) |
||||
} |
||||
} |
||||
case "arm64": |
||||
variant := platform.Variant |
||||
if variant == "" { |
||||
variant = "v8" |
||||
} |
||||
vector = append(vector, platformVector(specs.Platform{ |
||||
Architecture: "arm", |
||||
OS: platform.OS, |
||||
OSVersion: platform.OSVersion, |
||||
OSFeatures: platform.OSFeatures, |
||||
Variant: variant, |
||||
})...) |
||||
} |
||||
|
||||
return vector |
||||
} |
||||
|
||||
// Only returns a match comparer for a single platform
|
||||
// using default resolution logic for the platform.
|
||||
//
|
||||
// For arm/v8, will also match arm/v7, arm/v6 and arm/v5
|
||||
// For arm/v7, will also match arm/v6 and arm/v5
|
||||
// For arm/v6, will also match arm/v5
|
||||
// For amd64, will also match 386
|
||||
func Only(platform specs.Platform) MatchComparer { |
||||
return Ordered(platformVector(Normalize(platform))...) |
||||
} |
||||
|
||||
// OnlyStrict returns a match comparer for a single platform.
|
||||
//
|
||||
// Unlike Only, OnlyStrict does not match sub platforms.
|
||||
// So, "arm/vN" will not match "arm/vM" where M < N,
|
||||
// and "amd64" will not also match "386".
|
||||
//
|
||||
// OnlyStrict matches non-canonical forms.
|
||||
// So, "arm64" matches "arm/64/v8".
|
||||
func OnlyStrict(platform specs.Platform) MatchComparer { |
||||
return Ordered(Normalize(platform)) |
||||
} |
||||
|
||||
// Ordered returns a platform MatchComparer which matches any of the platforms
|
||||
// but orders them in order they are provided.
|
||||
func Ordered(platforms ...specs.Platform) MatchComparer { |
||||
matchers := make([]Matcher, len(platforms)) |
||||
for i := range platforms { |
||||
matchers[i] = NewMatcher(platforms[i]) |
||||
} |
||||
return orderedPlatformComparer{ |
||||
matchers: matchers, |
||||
} |
||||
} |
||||
|
||||
// Any returns a platform MatchComparer which matches any of the platforms
|
||||
// with no preference for ordering.
|
||||
func Any(platforms ...specs.Platform) MatchComparer { |
||||
matchers := make([]Matcher, len(platforms)) |
||||
for i := range platforms { |
||||
matchers[i] = NewMatcher(platforms[i]) |
||||
} |
||||
return anyPlatformComparer{ |
||||
matchers: matchers, |
||||
} |
||||
} |
||||
|
||||
// All is a platform MatchComparer which matches all platforms
|
||||
// with preference for ordering.
|
||||
var All MatchComparer = allPlatformComparer{} |
||||
|
||||
type orderedPlatformComparer struct { |
||||
matchers []Matcher |
||||
} |
||||
|
||||
func (c orderedPlatformComparer) Match(platform specs.Platform) bool { |
||||
for _, m := range c.matchers { |
||||
if m.Match(platform) { |
||||
return true |
||||
} |
||||
} |
||||
return false |
||||
} |
||||
|
||||
func (c orderedPlatformComparer) Less(p1 specs.Platform, p2 specs.Platform) bool { |
||||
for _, m := range c.matchers { |
||||
p1m := m.Match(p1) |
||||
p2m := m.Match(p2) |
||||
if p1m && !p2m { |
||||
return true |
||||
} |
||||
if p1m || p2m { |
||||
return false |
||||
} |
||||
} |
||||
return false |
||||
} |
||||
|
||||
type anyPlatformComparer struct { |
||||
matchers []Matcher |
||||
} |
||||
|
||||
func (c anyPlatformComparer) Match(platform specs.Platform) bool { |
||||
for _, m := range c.matchers { |
||||
if m.Match(platform) { |
||||
return true |
||||
} |
||||
} |
||||
return false |
||||
} |
||||
|
||||
func (c anyPlatformComparer) Less(p1, p2 specs.Platform) bool { |
||||
var p1m, p2m bool |
||||
for _, m := range c.matchers { |
||||
if !p1m && m.Match(p1) { |
||||
p1m = true |
||||
} |
||||
if !p2m && m.Match(p2) { |
||||
p2m = true |
||||
} |
||||
if p1m && p2m { |
||||
return false |
||||
} |
||||
} |
||||
// If one matches, and the other does, sort match first
|
||||
return p1m && !p2m |
||||
} |
||||
|
||||
type allPlatformComparer struct{} |
||||
|
||||
func (allPlatformComparer) Match(specs.Platform) bool { |
||||
return true |
||||
} |
||||
|
||||
func (allPlatformComparer) Less(specs.Platform, specs.Platform) bool { |
||||
return false |
||||
} |
@ -1,131 +0,0 @@ |
||||
/* |
||||
Copyright The containerd Authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
package platforms |
||||
|
||||
import ( |
||||
"bufio" |
||||
"os" |
||||
"runtime" |
||||
"strings" |
||||
"sync" |
||||
|
||||
"github.com/containerd/containerd/errdefs" |
||||
"github.com/containerd/containerd/log" |
||||
"github.com/pkg/errors" |
||||
) |
||||
|
||||
// Present the ARM instruction set architecture, eg: v7, v8
|
||||
// Don't use this value directly; call cpuVariant() instead.
|
||||
var cpuVariantValue string |
||||
|
||||
var cpuVariantOnce sync.Once |
||||
|
||||
func cpuVariant() string { |
||||
cpuVariantOnce.Do(func() { |
||||
if isArmArch(runtime.GOARCH) { |
||||
cpuVariantValue = getCPUVariant() |
||||
} |
||||
}) |
||||
return cpuVariantValue |
||||
} |
||||
|
||||
// For Linux, the kernel has already detected the ABI, ISA and Features.
|
||||
// So we don't need to access the ARM registers to detect platform information
|
||||
// by ourselves. We can just parse these information from /proc/cpuinfo
|
||||
func getCPUInfo(pattern string) (info string, err error) { |
||||
if !isLinuxOS(runtime.GOOS) { |
||||
return "", errors.Wrapf(errdefs.ErrNotImplemented, "getCPUInfo for OS %s", runtime.GOOS) |
||||
} |
||||
|
||||
cpuinfo, err := os.Open("/proc/cpuinfo") |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
defer cpuinfo.Close() |
||||
|
||||
// Start to Parse the Cpuinfo line by line. For SMP SoC, we parse
|
||||
// the first core is enough.
|
||||
scanner := bufio.NewScanner(cpuinfo) |
||||
for scanner.Scan() { |
||||
newline := scanner.Text() |
||||
list := strings.Split(newline, ":") |
||||
|
||||
if len(list) > 1 && strings.EqualFold(strings.TrimSpace(list[0]), pattern) { |
||||
return strings.TrimSpace(list[1]), nil |
||||
} |
||||
} |
||||
|
||||
// Check whether the scanner encountered errors
|
||||
err = scanner.Err() |
||||
if err != nil { |
||||
return "", err |
||||
} |
||||
|
||||
return "", errors.Wrapf(errdefs.ErrNotFound, "getCPUInfo for pattern: %s", pattern) |
||||
} |
||||
|
||||
func getCPUVariant() string { |
||||
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" { |
||||
// Windows/Darwin only supports v7 for ARM32 and v8 for ARM64 and so we can use
|
||||
// runtime.GOARCH to determine the variants
|
||||
var variant string |
||||
switch runtime.GOARCH { |
||||
case "arm64": |
||||
variant = "v8" |
||||
case "arm": |
||||
variant = "v7" |
||||
default: |
||||
variant = "unknown" |
||||
} |
||||
|
||||
return variant |
||||
} |
||||
|
||||
variant, err := getCPUInfo("Cpu architecture") |
||||
if err != nil { |
||||
log.L.WithError(err).Error("failure getting variant") |
||||
return "" |
||||
} |
||||
|
||||
// handle edge case for Raspberry Pi ARMv6 devices (which due to a kernel quirk, report "CPU architecture: 7")
|
||||
// https://www.raspberrypi.org/forums/viewtopic.php?t=12614
|
||||
if runtime.GOARCH == "arm" && variant == "7" { |
||||
model, err := getCPUInfo("model name") |
||||
if err == nil && strings.HasPrefix(strings.ToLower(model), "armv6-compatible") { |
||||
variant = "6" |
||||
} |
||||
} |
||||
|
||||
switch strings.ToLower(variant) { |
||||
case "8", "aarch64": |
||||
variant = "v8" |
||||
case "7", "7m", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)": |
||||
variant = "v7" |
||||
case "6", "6tej": |
||||
variant = "v6" |
||||
case "5", "5t", "5te", "5tej": |
||||
variant = "v5" |
||||
case "4", "4t": |
||||
variant = "v4" |
||||
case "3": |
||||
variant = "v3" |
||||
default: |
||||
variant = "unknown" |
||||
} |
||||
|
||||
return variant |
||||
} |
@ -1,114 +0,0 @@ |
||||
/* |
||||
Copyright The containerd Authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
package platforms |
||||
|
||||
import ( |
||||
"runtime" |
||||
"strings" |
||||
) |
||||
|
||||
// isLinuxOS returns true if the operating system is Linux.
|
||||
//
|
||||
// The OS value should be normalized before calling this function.
|
||||
func isLinuxOS(os string) bool { |
||||
return os == "linux" |
||||
} |
||||
|
||||
// These function are generated from https://golang.org/src/go/build/syslist.go.
|
||||
//
|
||||
// We use switch statements because they are slightly faster than map lookups
|
||||
// and use a little less memory.
|
||||
|
||||
// isKnownOS returns true if we know about the operating system.
|
||||
//
|
||||
// The OS value should be normalized before calling this function.
|
||||
func isKnownOS(os string) bool { |
||||
switch os { |
||||
case "aix", "android", "darwin", "dragonfly", "freebsd", "hurd", "illumos", "js", "linux", "nacl", "netbsd", "openbsd", "plan9", "solaris", "windows", "zos": |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
|
||||
// isArmArch returns true if the architecture is ARM.
|
||||
//
|
||||
// The arch value should be normalized before being passed to this function.
|
||||
func isArmArch(arch string) bool { |
||||
switch arch { |
||||
case "arm", "arm64": |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
|
||||
// isKnownArch returns true if we know about the architecture.
|
||||
//
|
||||
// The arch value should be normalized before being passed to this function.
|
||||
func isKnownArch(arch string) bool { |
||||
switch arch { |
||||
case "386", "amd64", "amd64p32", "arm", "armbe", "arm64", "arm64be", "ppc64", "ppc64le", "mips", "mipsle", "mips64", "mips64le", "mips64p32", "mips64p32le", "ppc", "riscv", "riscv64", "s390", "s390x", "sparc", "sparc64", "wasm": |
||||
return true |
||||
} |
||||
return false |
||||
} |
||||
|
||||
func normalizeOS(os string) string { |
||||
if os == "" { |
||||
return runtime.GOOS |
||||
} |
||||
os = strings.ToLower(os) |
||||
|
||||
switch os { |
||||
case "macos": |
||||
os = "darwin" |
||||
} |
||||
return os |
||||
} |
||||
|
||||
// normalizeArch normalizes the architecture.
|
||||
func normalizeArch(arch, variant string) (string, string) { |
||||
arch, variant = strings.ToLower(arch), strings.ToLower(variant) |
||||
switch arch { |
||||
case "i386": |
||||
arch = "386" |
||||
variant = "" |
||||
case "x86_64", "x86-64": |
||||
arch = "amd64" |
||||
variant = "" |
||||
case "aarch64", "arm64": |
||||
arch = "arm64" |
||||
switch variant { |
||||
case "8", "v8": |
||||
variant = "" |
||||
} |
||||
case "armhf": |
||||
arch = "arm" |
||||
variant = "v7" |
||||
case "armel": |
||||
arch = "arm" |
||||
variant = "v6" |
||||
case "arm": |
||||
switch variant { |
||||
case "", "7": |
||||
variant = "v7" |
||||
case "5", "6", "8": |
||||
variant = "v" + variant |
||||
} |
||||
} |
||||
|
||||
return arch, variant |
||||
} |
@ -1,43 +0,0 @@ |
||||
/* |
||||
Copyright The containerd Authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
package platforms |
||||
|
||||
import ( |
||||
"runtime" |
||||
|
||||
specs "github.com/opencontainers/image-spec/specs-go/v1" |
||||
) |
||||
|
||||
// DefaultString returns the default string specifier for the platform.
|
||||
func DefaultString() string { |
||||
return Format(DefaultSpec()) |
||||
} |
||||
|
||||
// DefaultSpec returns the current platform's default platform specification.
|
||||
func DefaultSpec() specs.Platform { |
||||
return specs.Platform{ |
||||
OS: runtime.GOOS, |
||||
Architecture: runtime.GOARCH, |
||||
// The Variant field will be empty if arch != ARM.
|
||||
Variant: cpuVariant(), |
||||
} |
||||
} |
||||
|
||||
// DefaultStrict returns strict form of Default.
|
||||
func DefaultStrict() MatchComparer { |
||||
return OnlyStrict(DefaultSpec()) |
||||
} |
@ -1,24 +0,0 @@ |
||||
// +build !windows
|
||||
|
||||
/* |
||||
Copyright The containerd Authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
package platforms |
||||
|
||||
// Default returns the default matcher for the platform.
|
||||
func Default() MatchComparer { |
||||
return Only(DefaultSpec()) |
||||
} |
@ -1,81 +0,0 @@ |
||||
// +build windows
|
||||
|
||||
/* |
||||
Copyright The containerd Authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
package platforms |
||||
|
||||
import ( |
||||
"fmt" |
||||
"runtime" |
||||
"strconv" |
||||
"strings" |
||||
|
||||
imagespec "github.com/opencontainers/image-spec/specs-go/v1" |
||||
specs "github.com/opencontainers/image-spec/specs-go/v1" |
||||
"golang.org/x/sys/windows" |
||||
) |
||||
|
||||
type matchComparer struct { |
||||
defaults Matcher |
||||
osVersionPrefix string |
||||
} |
||||
|
||||
// Match matches platform with the same windows major, minor
|
||||
// and build version.
|
||||
func (m matchComparer) Match(p imagespec.Platform) bool { |
||||
if m.defaults.Match(p) { |
||||
// TODO(windows): Figure out whether OSVersion is deprecated.
|
||||
return strings.HasPrefix(p.OSVersion, m.osVersionPrefix) |
||||
} |
||||
return false |
||||
} |
||||
|
||||
// Less sorts matched platforms in front of other platforms.
|
||||
// For matched platforms, it puts platforms with larger revision
|
||||
// number in front.
|
||||
func (m matchComparer) Less(p1, p2 imagespec.Platform) bool { |
||||
m1, m2 := m.Match(p1), m.Match(p2) |
||||
if m1 && m2 { |
||||
r1, r2 := revision(p1.OSVersion), revision(p2.OSVersion) |
||||
return r1 > r2 |
||||
} |
||||
return m1 && !m2 |
||||
} |
||||
|
||||
func revision(v string) int { |
||||
parts := strings.Split(v, ".") |
||||
if len(parts) < 4 { |
||||
return 0 |
||||
} |
||||
r, err := strconv.Atoi(parts[3]) |
||||
if err != nil { |
||||
return 0 |
||||
} |
||||
return r |
||||
} |
||||
|
||||
// Default returns the current platform's default platform specification.
|
||||
func Default() MatchComparer { |
||||
major, minor, build := windows.RtlGetNtVersionNumbers() |
||||
return matchComparer{ |
||||
defaults: Ordered(DefaultSpec(), specs.Platform{ |
||||
OS: "linux", |
||||
Architecture: runtime.GOARCH, |
||||
}), |
||||
osVersionPrefix: fmt.Sprintf("%d.%d.%d", major, minor, build), |
||||
} |
||||
} |
@ -1,278 +0,0 @@ |
||||
/* |
||||
Copyright The containerd Authors. |
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); |
||||
you may not use this file except in compliance with the License. |
||||
You may obtain a copy of the License at |
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software |
||||
distributed under the License is distributed on an "AS IS" BASIS, |
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
See the License for the specific language governing permissions and |
||||
limitations under the License. |
||||
*/ |
||||
|
||||
// Package platforms provides a toolkit for normalizing, matching and
|
||||
// specifying container platforms.
|
||||
//
|
||||
// Centered around OCI platform specifications, we define a string-based
|
||||
// specifier syntax that can be used for user input. With a specifier, users
|
||||
// only need to specify the parts of the platform that are relevant to their
|
||||
// context, providing an operating system or architecture or both.
|
||||
//
|
||||
// How do I use this package?
|
||||
//
|
||||
// The vast majority of use cases should simply use the match function with
|
||||
// user input. The first step is to parse a specifier into a matcher:
|
||||
//
|
||||
// m, err := Parse("linux")
|
||||
// if err != nil { ... }
|
||||
//
|
||||
// Once you have a matcher, use it to match against the platform declared by a
|
||||
// component, typically from an image or runtime. Since extracting an images
|
||||
// platform is a little more involved, we'll use an example against the
|
||||
// platform default:
|
||||
//
|
||||
// if ok := m.Match(Default()); !ok { /* doesn't match */ }
|
||||
//
|
||||
// This can be composed in loops for resolving runtimes or used as a filter for
|
||||
// fetch and select images.
|
||||
//
|
||||
// More details of the specifier syntax and platform spec follow.
|
||||
//
|
||||
// Declaring Platform Support
|
||||
//
|
||||
// Components that have strict platform requirements should use the OCI
|
||||
// platform specification to declare their support. Typically, this will be
|
||||
// images and runtimes that should make these declaring which platform they
|
||||
// support specifically. This looks roughly as follows:
|
||||
//
|
||||
// type Platform struct {
|
||||
// Architecture string
|
||||
// OS string
|
||||
// Variant string
|
||||
// }
|
||||
//
|
||||
// Most images and runtimes should at least set Architecture and OS, according
|
||||
// to their GOARCH and GOOS values, respectively (follow the OCI image
|
||||
// specification when in doubt). ARM should set variant under certain
|
||||
// discussions, which are outlined below.
|
||||
//
|
||||
// Platform Specifiers
|
||||
//
|
||||
// While the OCI platform specifications provide a tool for components to
|
||||
// specify structured information, user input typically doesn't need the full
|
||||
// context and much can be inferred. To solve this problem, we introduced
|
||||
// "specifiers". A specifier has the format
|
||||
// `<os>|<arch>|<os>/<arch>[/<variant>]`. The user can provide either the
|
||||
// operating system or the architecture or both.
|
||||
//
|
||||
// An example of a common specifier is `linux/amd64`. If the host has a default
|
||||
// of runtime that matches this, the user can simply provide the component that
|
||||
// matters. For example, if a image provides amd64 and arm64 support, the
|
||||
// operating system, `linux` can be inferred, so they only have to provide
|
||||
// `arm64` or `amd64`. Similar behavior is implemented for operating systems,
|
||||
// where the architecture may be known but a runtime may support images from
|
||||
// different operating systems.
|
||||
//
|
||||
// Normalization
|
||||
//
|
||||
// Because not all users are familiar with the way the Go runtime represents
|
||||
// platforms, several normalizations have been provided to make this package
|
||||
// easier to user.
|
||||
//
|
||||
// The following are performed for architectures:
|
||||
//
|
||||
// Value Normalized
|
||||
// aarch64 arm64
|
||||
// armhf arm
|
||||
// armel arm/v6
|
||||
// i386 386
|
||||
// x86_64 amd64
|
||||
// x86-64 amd64
|
||||
//
|
||||
// We also normalize the operating system `macos` to `darwin`.
|
||||
//
|
||||
// ARM Support
|
||||
//
|
||||
// To qualify ARM architecture, the Variant field is used to qualify the arm
|
||||
// version. The most common arm version, v7, is represented without the variant
|
||||
// unless it is explicitly provided. This is treated as equivalent to armhf. A
|
||||
// previous architecture, armel, will be normalized to arm/v6.
|
||||
//
|
||||
// While these normalizations are provided, their support on arm platforms has
|
||||
// not yet been fully implemented and tested.
|
||||
package platforms |
||||
|
||||
import ( |
||||
"regexp" |
||||
"runtime" |
||||
"strconv" |
||||
"strings" |
||||
|
||||
"github.com/containerd/containerd/errdefs" |
||||
specs "github.com/opencontainers/image-spec/specs-go/v1" |
||||
"github.com/pkg/errors" |
||||
) |
||||
|
||||
var ( |
||||
specifierRe = regexp.MustCompile(`^[A-Za-z0-9_-]+$`) |
||||
) |
||||
|
||||
// Matcher matches platforms specifications, provided by an image or runtime.
|
||||
type Matcher interface { |
||||
Match(platform specs.Platform) bool |
||||
} |
||||
|
||||
// NewMatcher returns a simple matcher based on the provided platform
|
||||
// specification. The returned matcher only looks for equality based on os,
|
||||
// architecture and variant.
|
||||
//
|
||||
// One may implement their own matcher if this doesn't provide the required
|
||||
// functionality.
|
||||
//
|
||||
// Applications should opt to use `Match` over directly parsing specifiers.
|
||||
func NewMatcher(platform specs.Platform) Matcher { |
||||
return &matcher{ |
||||
Platform: Normalize(platform), |
||||
} |
||||
} |
||||
|
||||
type matcher struct { |
||||
specs.Platform |
||||
} |
||||
|
||||
func (m *matcher) Match(platform specs.Platform) bool { |
||||
normalized := Normalize(platform) |
||||
return m.OS == normalized.OS && |
||||
m.Architecture == normalized.Architecture && |
||||
m.Variant == normalized.Variant |
||||
} |
||||
|
||||
func (m *matcher) String() string { |
||||
return Format(m.Platform) |
||||
} |
||||
|
||||
// Parse parses the platform specifier syntax into a platform declaration.
|
||||
//
|
||||
// Platform specifiers are in the format `<os>|<arch>|<os>/<arch>[/<variant>]`.
|
||||
// The minimum required information for a platform specifier is the operating
|
||||
// system or architecture. If there is only a single string (no slashes), the
|
||||
// value will be matched against the known set of operating systems, then fall
|
||||
// back to the known set of architectures. The missing component will be
|
||||
// inferred based on the local environment.
|
||||
func Parse(specifier string) (specs.Platform, error) { |
||||
if strings.Contains(specifier, "*") { |
||||
// TODO(stevvooe): need to work out exact wildcard handling
|
||||
return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: wildcards not yet supported", specifier) |
||||
} |
||||
|
||||
parts := strings.Split(specifier, "/") |
||||
|
||||
for _, part := range parts { |
||||
if !specifierRe.MatchString(part) { |
||||
return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q is an invalid component of %q: platform specifier component must match %q", part, specifier, specifierRe.String()) |
||||
} |
||||
} |
||||
|
||||
var p specs.Platform |
||||
switch len(parts) { |
||||
case 1: |
||||
// in this case, we will test that the value might be an OS, then look
|
||||
// it up. If it is not known, we'll treat it as an architecture. Since
|
||||
// we have very little information about the platform here, we are
|
||||
// going to be a little more strict if we don't know about the argument
|
||||
// value.
|
||||
p.OS = normalizeOS(parts[0]) |
||||
if isKnownOS(p.OS) { |
||||
// picks a default architecture
|
||||
p.Architecture = runtime.GOARCH |
||||
if p.Architecture == "arm" && cpuVariant() != "v7" { |
||||
p.Variant = cpuVariant() |
||||
} |
||||
|
||||
return p, nil |
||||
} |
||||
|
||||
p.Architecture, p.Variant = normalizeArch(parts[0], "") |
||||
if p.Architecture == "arm" && p.Variant == "v7" { |
||||
p.Variant = "" |
||||
} |
||||
if isKnownArch(p.Architecture) { |
||||
p.OS = runtime.GOOS |
||||
return p, nil |
||||
} |
||||
|
||||
return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: unknown operating system or architecture", specifier) |
||||
case 2: |
||||
// In this case, we treat as a regular os/arch pair. We don't care
|
||||
// about whether or not we know of the platform.
|
||||
p.OS = normalizeOS(parts[0]) |
||||
p.Architecture, p.Variant = normalizeArch(parts[1], "") |
||||
if p.Architecture == "arm" && p.Variant == "v7" { |
||||
p.Variant = "" |
||||
} |
||||
|
||||
return p, nil |
||||
case 3: |
||||
// we have a fully specified variant, this is rare
|
||||
p.OS = normalizeOS(parts[0]) |
||||
p.Architecture, p.Variant = normalizeArch(parts[1], parts[2]) |
||||
if p.Architecture == "arm64" && p.Variant == "" { |
||||
p.Variant = "v8" |
||||
} |
||||
|
||||
return p, nil |
||||
} |
||||
|
||||
return specs.Platform{}, errors.Wrapf(errdefs.ErrInvalidArgument, "%q: cannot parse platform specifier", specifier) |
||||
} |
||||
|
||||
// MustParse is like Parses but panics if the specifier cannot be parsed.
|
||||
// Simplifies initialization of global variables.
|
||||
func MustParse(specifier string) specs.Platform { |
||||
p, err := Parse(specifier) |
||||
if err != nil { |
||||
panic("platform: Parse(" + strconv.Quote(specifier) + "): " + err.Error()) |
||||
} |
||||
return p |
||||
} |
||||
|
||||
// Format returns a string specifier from the provided platform specification.
|
||||
func Format(platform specs.Platform) string { |
||||
if platform.OS == "" { |
||||
return "unknown" |
||||
} |
||||
|
||||
return joinNotEmpty(platform.OS, platform.Architecture, platform.Variant) |
||||
} |
||||
|
||||
func joinNotEmpty(s ...string) string { |
||||
var ss []string |
||||
for _, s := range s { |
||||
if s == "" { |
||||
continue |
||||
} |
||||
|
||||
ss = append(ss, s) |
||||
} |
||||
|
||||
return strings.Join(ss, "/") |
||||
} |
||||
|
||||
// Normalize validates and translate the platform to the canonical value.
|
||||
//
|
||||
// For example, if "Aarch64" is encountered, we change it to "arm64" or if
|
||||
// "x86_64" is encountered, it becomes "amd64".
|
||||
func Normalize(platform specs.Platform) specs.Platform { |
||||
platform.OS = normalizeOS(platform.OS) |
||||
platform.Architecture, platform.Variant = normalizeArch(platform.Architecture, platform.Variant) |
||||
|
||||
// these fields are deprecated, remove them
|
||||
platform.OSFeatures = nil |
||||
platform.OSVersion = "" |
||||
|
||||
return platform |
||||
} |
@ -1,267 +0,0 @@ |
||||
package errcode |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"fmt" |
||||
"strings" |
||||
) |
||||
|
||||
// ErrorCoder is the base interface for ErrorCode and Error allowing
|
||||
// users of each to just call ErrorCode to get the real ID of each
|
||||
type ErrorCoder interface { |
||||
ErrorCode() ErrorCode |
||||
} |
||||
|
||||
// ErrorCode represents the error type. The errors are serialized via strings
|
||||
// and the integer format may change and should *never* be exported.
|
||||
type ErrorCode int |
||||
|
||||
var _ error = ErrorCode(0) |
||||
|
||||
// ErrorCode just returns itself
|
||||
func (ec ErrorCode) ErrorCode() ErrorCode { |
||||
return ec |
||||
} |
||||
|
||||
// Error returns the ID/Value
|
||||
func (ec ErrorCode) Error() string { |
||||
// NOTE(stevvooe): Cannot use message here since it may have unpopulated args.
|
||||
return strings.ToLower(strings.Replace(ec.String(), "_", " ", -1)) |
||||
} |
||||
|
||||
// Descriptor returns the descriptor for the error code.
|
||||
func (ec ErrorCode) Descriptor() ErrorDescriptor { |
||||
d, ok := errorCodeToDescriptors[ec] |
||||
|
||||
if !ok { |
||||
return ErrorCodeUnknown.Descriptor() |
||||
} |
||||
|
||||
return d |
||||
} |
||||
|
||||
// String returns the canonical identifier for this error code.
|
||||
func (ec ErrorCode) String() string { |
||||
return ec.Descriptor().Value |
||||
} |
||||
|
||||
// Message returned the human-readable error message for this error code.
|
||||
func (ec ErrorCode) Message() string { |
||||
return ec.Descriptor().Message |
||||
} |
||||
|
||||
// MarshalText encodes the receiver into UTF-8-encoded text and returns the
|
||||
// result.
|
||||
func (ec ErrorCode) MarshalText() (text []byte, err error) { |
||||
return []byte(ec.String()), nil |
||||
} |
||||
|
||||
// UnmarshalText decodes the form generated by MarshalText.
|
||||
func (ec *ErrorCode) UnmarshalText(text []byte) error { |
||||
desc, ok := idToDescriptors[string(text)] |
||||
|
||||
if !ok { |
||||
desc = ErrorCodeUnknown.Descriptor() |
||||
} |
||||
|
||||
*ec = desc.Code |
||||
|
||||
return nil |
||||
} |
||||
|
||||
// WithMessage creates a new Error struct based on the passed-in info and
|
||||
// overrides the Message property.
|
||||
func (ec ErrorCode) WithMessage(message string) Error { |
||||
return Error{ |
||||
Code: ec, |
||||
Message: message, |
||||
} |
||||
} |
||||
|
||||
// WithDetail creates a new Error struct based on the passed-in info and
|
||||
// set the Detail property appropriately
|
||||
func (ec ErrorCode) WithDetail(detail interface{}) Error { |
||||
return Error{ |
||||
Code: ec, |
||||
Message: ec.Message(), |
||||
}.WithDetail(detail) |
||||
} |
||||
|
||||
// WithArgs creates a new Error struct and sets the Args slice
|
||||
func (ec ErrorCode) WithArgs(args ...interface{}) Error { |
||||
return Error{ |
||||
Code: ec, |
||||
Message: ec.Message(), |
||||
}.WithArgs(args...) |
||||
} |
||||
|
||||
// Error provides a wrapper around ErrorCode with extra Details provided.
|
||||
type Error struct { |
||||
Code ErrorCode `json:"code"` |
||||
Message string `json:"message"` |
||||
Detail interface{} `json:"detail,omitempty"` |
||||
|
||||
// TODO(duglin): See if we need an "args" property so we can do the
|
||||
// variable substitution right before showing the message to the user
|
||||
} |
||||
|
||||
var _ error = Error{} |
||||
|
||||
// ErrorCode returns the ID/Value of this Error
|
||||
func (e Error) ErrorCode() ErrorCode { |
||||
return e.Code |
||||
} |
||||
|
||||
// Error returns a human readable representation of the error.
|
||||
func (e Error) Error() string { |
||||
return fmt.Sprintf("%s: %s", e.Code.Error(), e.Message) |
||||
} |
||||
|
||||
// WithDetail will return a new Error, based on the current one, but with
|
||||
// some Detail info added
|
||||
func (e Error) WithDetail(detail interface{}) Error { |
||||
return Error{ |
||||
Code: e.Code, |
||||
Message: e.Message, |
||||
Detail: detail, |
||||
} |
||||
} |
||||
|
||||
// WithArgs uses the passed-in list of interface{} as the substitution
|
||||
// variables in the Error's Message string, but returns a new Error
|
||||
func (e Error) WithArgs(args ...interface{}) Error { |
||||
return Error{ |
||||
Code: e.Code, |
||||
Message: fmt.Sprintf(e.Code.Message(), args...), |
||||
Detail: e.Detail, |
||||
} |
||||
} |
||||
|
||||
// ErrorDescriptor provides relevant information about a given error code.
|
||||
type ErrorDescriptor struct { |
||||
// Code is the error code that this descriptor describes.
|
||||
Code ErrorCode |
||||
|
||||
// Value provides a unique, string key, often captilized with
|
||||
// underscores, to identify the error code. This value is used as the
|
||||
// keyed value when serializing api errors.
|
||||
Value string |
||||
|
||||
// Message is a short, human readable decription of the error condition
|
||||
// included in API responses.
|
||||
Message string |
||||
|
||||
// Description provides a complete account of the errors purpose, suitable
|
||||
// for use in documentation.
|
||||
Description string |
||||
|
||||
// HTTPStatusCode provides the http status code that is associated with
|
||||
// this error condition.
|
||||
HTTPStatusCode int |
||||
} |
||||
|
||||
// ParseErrorCode returns the value by the string error code.
|
||||
// `ErrorCodeUnknown` will be returned if the error is not known.
|
||||
func ParseErrorCode(value string) ErrorCode { |
||||
ed, ok := idToDescriptors[value] |
||||
if ok { |
||||
return ed.Code |
||||
} |
||||
|
||||
return ErrorCodeUnknown |
||||
} |
||||
|
||||
// Errors provides the envelope for multiple errors and a few sugar methods
|
||||
// for use within the application.
|
||||
type Errors []error |
||||
|
||||
var _ error = Errors{} |
||||
|
||||
func (errs Errors) Error() string { |
||||
switch len(errs) { |
||||
case 0: |
||||
return "<nil>" |
||||
case 1: |
||||
return errs[0].Error() |
||||
default: |
||||
msg := "errors:\n" |
||||
for _, err := range errs { |
||||
msg += err.Error() + "\n" |
||||
} |
||||
return msg |
||||
} |
||||
} |
||||
|
||||
// Len returns the current number of errors.
|
||||
func (errs Errors) Len() int { |
||||
return len(errs) |
||||
} |
||||
|
||||
// MarshalJSON converts slice of error, ErrorCode or Error into a
|
||||
// slice of Error - then serializes
|
||||
func (errs Errors) MarshalJSON() ([]byte, error) { |
||||
var tmpErrs struct { |
||||
Errors []Error `json:"errors,omitempty"` |
||||
} |
||||
|
||||
for _, daErr := range errs { |
||||
var err Error |
||||
|
||||
switch daErr.(type) { |
||||
case ErrorCode: |
||||
err = daErr.(ErrorCode).WithDetail(nil) |
||||
case Error: |
||||
err = daErr.(Error) |
||||
default: |
||||
err = ErrorCodeUnknown.WithDetail(daErr) |
||||
|
||||
} |
||||
|
||||
// If the Error struct was setup and they forgot to set the
|
||||
// Message field (meaning its "") then grab it from the ErrCode
|
||||
msg := err.Message |
||||
if msg == "" { |
||||
msg = err.Code.Message() |
||||
} |
||||
|
||||
tmpErrs.Errors = append(tmpErrs.Errors, Error{ |
||||
Code: err.Code, |
||||
Message: msg, |
||||
Detail: err.Detail, |
||||
}) |
||||
} |
||||
|
||||
return json.Marshal(tmpErrs) |
||||
} |
||||
|
||||
// UnmarshalJSON deserializes []Error and then converts it into slice of
|
||||
// Error or ErrorCode
|
||||
func (errs *Errors) UnmarshalJSON(data []byte) error { |
||||
var tmpErrs struct { |
||||
Errors []Error |
||||
} |
||||
|
||||
if err := json.Unmarshal(data, &tmpErrs); err != nil { |
||||
return err |
||||
} |
||||
|
||||
var newErrs Errors |
||||
for _, daErr := range tmpErrs.Errors { |
||||
// If Message is empty or exactly matches the Code's message string
|
||||
// then just use the Code, no need for a full Error struct
|
||||
if daErr.Detail == nil && (daErr.Message == "" || daErr.Message == daErr.Code.Message()) { |
||||
// Error's w/o details get converted to ErrorCode
|
||||
newErrs = append(newErrs, daErr.Code) |
||||
} else { |
||||
// Error's w/ details are untouched
|
||||
newErrs = append(newErrs, Error{ |
||||
Code: daErr.Code, |
||||
Message: daErr.Message, |
||||
Detail: daErr.Detail, |
||||
}) |
||||
} |
||||
} |
||||
|
||||
*errs = newErrs |
||||
return nil |
||||
} |
@ -1,40 +0,0 @@ |
||||
package errcode |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"net/http" |
||||
) |
||||
|
||||
// ServeJSON attempts to serve the errcode in a JSON envelope. It marshals err
|
||||
// and sets the content-type header to 'application/json'. It will handle
|
||||
// ErrorCoder and Errors, and if necessary will create an envelope.
|
||||
func ServeJSON(w http.ResponseWriter, err error) error { |
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8") |
||||
var sc int |
||||
|
||||
switch errs := err.(type) { |
||||
case Errors: |
||||
if len(errs) < 1 { |
||||
break |
||||
} |
||||
|
||||
if err, ok := errs[0].(ErrorCoder); ok { |
||||
sc = err.ErrorCode().Descriptor().HTTPStatusCode |
||||
} |
||||
case ErrorCoder: |
||||
sc = errs.ErrorCode().Descriptor().HTTPStatusCode |
||||
err = Errors{err} // create an envelope.
|
||||
default: |
||||
// We just have an unhandled error type, so just place in an envelope
|
||||
// and move along.
|
||||
err = Errors{err} |
||||
} |
||||
|
||||
if sc == 0 { |
||||
sc = http.StatusInternalServerError |
||||
} |
||||
|
||||
w.WriteHeader(sc) |
||||
|
||||
return json.NewEncoder(w).Encode(err) |
||||
} |
@ -1,138 +0,0 @@ |
||||
package errcode |
||||
|
||||
import ( |
||||
"fmt" |
||||
"net/http" |
||||
"sort" |
||||
"sync" |
||||
) |
||||
|
||||
var ( |
||||
errorCodeToDescriptors = map[ErrorCode]ErrorDescriptor{} |
||||
idToDescriptors = map[string]ErrorDescriptor{} |
||||
groupToDescriptors = map[string][]ErrorDescriptor{} |
||||
) |
||||
|
||||
var ( |
||||
// ErrorCodeUnknown is a generic error that can be used as a last
|
||||
// resort if there is no situation-specific error message that can be used
|
||||
ErrorCodeUnknown = Register("errcode", ErrorDescriptor{ |
||||
Value: "UNKNOWN", |
||||
Message: "unknown error", |
||||
Description: `Generic error returned when the error does not have an |
||||
API classification.`, |
||||
HTTPStatusCode: http.StatusInternalServerError, |
||||
}) |
||||
|
||||
// ErrorCodeUnsupported is returned when an operation is not supported.
|
||||
ErrorCodeUnsupported = Register("errcode", ErrorDescriptor{ |
||||
Value: "UNSUPPORTED", |
||||
Message: "The operation is unsupported.", |
||||
Description: `The operation was unsupported due to a missing |
||||
implementation or invalid set of parameters.`, |
||||
HTTPStatusCode: http.StatusMethodNotAllowed, |
||||
}) |
||||
|
||||
// ErrorCodeUnauthorized is returned if a request requires
|
||||
// authentication.
|
||||
ErrorCodeUnauthorized = Register("errcode", ErrorDescriptor{ |
||||
Value: "UNAUTHORIZED", |
||||
Message: "authentication required", |
||||
Description: `The access controller was unable to authenticate |
||||
the client. Often this will be accompanied by a |
||||
Www-Authenticate HTTP response header indicating how to |
||||
authenticate.`, |
||||
HTTPStatusCode: http.StatusUnauthorized, |
||||
}) |
||||
|
||||
// ErrorCodeDenied is returned if a client does not have sufficient
|
||||
// permission to perform an action.
|
||||
ErrorCodeDenied = Register("errcode", ErrorDescriptor{ |
||||
Value: "DENIED", |
||||
Message: "requested access to the resource is denied", |
||||
Description: `The access controller denied access for the |
||||
operation on a resource.`, |
||||
HTTPStatusCode: http.StatusForbidden, |
||||
}) |
||||
|
||||
// ErrorCodeUnavailable provides a common error to report unavailability
|
||||
// of a service or endpoint.
|
||||
ErrorCodeUnavailable = Register("errcode", ErrorDescriptor{ |
||||
Value: "UNAVAILABLE", |
||||
Message: "service unavailable", |
||||
Description: "Returned when a service is not available", |
||||
HTTPStatusCode: http.StatusServiceUnavailable, |
||||
}) |
||||
|
||||
// ErrorCodeTooManyRequests is returned if a client attempts too many
|
||||
// times to contact a service endpoint.
|
||||
ErrorCodeTooManyRequests = Register("errcode", ErrorDescriptor{ |
||||
Value: "TOOMANYREQUESTS", |
||||
Message: "too many requests", |
||||
Description: `Returned when a client attempts to contact a |
||||
service too many times`, |
||||
HTTPStatusCode: http.StatusTooManyRequests, |
||||
}) |
||||
) |
||||
|
||||
var nextCode = 1000 |
||||
var registerLock sync.Mutex |
||||
|
||||
// Register will make the passed-in error known to the environment and
|
||||
// return a new ErrorCode
|
||||
func Register(group string, descriptor ErrorDescriptor) ErrorCode { |
||||
registerLock.Lock() |
||||
defer registerLock.Unlock() |
||||
|
||||
descriptor.Code = ErrorCode(nextCode) |
||||
|
||||
if _, ok := idToDescriptors[descriptor.Value]; ok { |
||||
panic(fmt.Sprintf("ErrorValue %q is already registered", descriptor.Value)) |
||||
} |
||||
if _, ok := errorCodeToDescriptors[descriptor.Code]; ok { |
||||
panic(fmt.Sprintf("ErrorCode %v is already registered", descriptor.Code)) |
||||
} |
||||
|
||||
groupToDescriptors[group] = append(groupToDescriptors[group], descriptor) |
||||
errorCodeToDescriptors[descriptor.Code] = descriptor |
||||
idToDescriptors[descriptor.Value] = descriptor |
||||
|
||||
nextCode++ |
||||
return descriptor.Code |
||||
} |
||||
|
||||
type byValue []ErrorDescriptor |
||||
|
||||
func (a byValue) Len() int { return len(a) } |
||||
func (a byValue) Swap(i, j int) { a[i], a[j] = a[j], a[i] } |
||||
func (a byValue) Less(i, j int) bool { return a[i].Value < a[j].Value } |
||||
|
||||
// GetGroupNames returns the list of Error group names that are registered
|
||||
func GetGroupNames() []string { |
||||
keys := []string{} |
||||
|
||||
for k := range groupToDescriptors { |
||||
keys = append(keys, k) |
||||
} |
||||
sort.Strings(keys) |
||||
return keys |
||||
} |
||||
|
||||
// GetErrorCodeGroup returns the named group of error descriptors
|
||||
func GetErrorCodeGroup(name string) []ErrorDescriptor { |
||||
desc := groupToDescriptors[name] |
||||
sort.Sort(byValue(desc)) |
||||
return desc |
||||
} |
||||
|
||||
// GetErrorAllDescriptors returns a slice of all ErrorDescriptors that are
|
||||
// registered, irrespective of what group they're in
|
||||
func GetErrorAllDescriptors() []ErrorDescriptor { |
||||
result := []ErrorDescriptor{} |
||||
|
||||
for _, group := range GetGroupNames() { |
||||
result = append(result, GetErrorCodeGroup(group)...) |
||||
} |
||||
sort.Sort(byValue(result)) |
||||
return result |
||||
} |
@ -1,3 +0,0 @@ |
||||
# This source code refers to The Go Authors for copyright purposes. |
||||
# The master list of authors is in the main Go distribution, |
||||
# visible at http://tip.golang.org/AUTHORS. |
@ -1,3 +0,0 @@ |
||||
# This source code was written by the Go contributors. |
||||
# The master list of contributors is in the main Go distribution, |
||||
# visible at http://tip.golang.org/CONTRIBUTORS. |
@ -1,28 +0,0 @@ |
||||
Copyright 2010 The Go Authors. All rights reserved. |
||||
|
||||
Redistribution and use in source and binary forms, with or without |
||||
modification, are permitted provided that the following conditions are |
||||
met: |
||||
|
||||
* Redistributions of source code must retain the above copyright |
||||
notice, this list of conditions and the following disclaimer. |
||||
* Redistributions in binary form must reproduce the above |
||||
copyright notice, this list of conditions and the following disclaimer |
||||
in the documentation and/or other materials provided with the |
||||
distribution. |
||||
* Neither the name of Google Inc. nor the names of its |
||||
contributors may be used to endorse or promote products derived from |
||||
this software without specific prior written permission. |
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
||||
|
@ -1,324 +0,0 @@ |
||||
// 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 |
||||
} |
||||
} |
||||
} |
@ -1,63 +0,0 @@ |
||||
// 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 |
||||
}) |
||||
} |
@ -1,113 +0,0 @@ |
||||
// 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 ( |
||||
"encoding/json" |
||||
"errors" |
||||
"fmt" |
||||
"strconv" |
||||
|
||||
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.
|
||||
func GetStats() Stats { return Stats{} } |
||||
|
||||
// Deprecated: Do not use.
|
||||
func MarshalMessageSet(interface{}) ([]byte, error) { |
||||
return nil, errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: Do not use.
|
||||
func UnmarshalMessageSet([]byte, interface{}) error { |
||||
return errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: Do not use.
|
||||
func MarshalMessageSetJSON(interface{}) ([]byte, error) { |
||||
return nil, errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// Deprecated: Do not use.
|
||||
func UnmarshalMessageSetJSON([]byte, interface{}) error { |
||||
return errors.New("proto: not implemented") |
||||
} |
||||
|
||||
// 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)) |
||||
} |
@ -1,58 +0,0 @@ |
||||
// 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" |
||||
) |
||||
|
||||
// DiscardUnknown recursively discards all unknown fields from this message
|
||||
// and all embedded messages.
|
||||
//
|
||||
// When unmarshaling a message with unrecognized fields, the tags and values
|
||||
// of such fields are preserved in the Message. This allows a later call to
|
||||
// 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.
|
||||
func DiscardUnknown(m Message) { |
||||
if m != nil { |
||||
discardUnknown(MessageReflect(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()) |
||||
} |
||||
// 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()) |
||||
} |
||||
} |
||||
// 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 |
||||
}) |
||||
} |
||||
} |
||||
return true |
||||
}) |
||||
|
||||
// Discard unknown fields.
|
||||
if len(m.GetUnknown()) > 0 { |
||||
m.SetUnknown(nil) |
||||
} |
||||
} |
@ -1,356 +0,0 @@ |
||||
// 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 ( |
||||
"errors" |
||||
"fmt" |
||||
"reflect" |
||||
|
||||
"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" |
||||
) |
||||
|
||||
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 |
||||
|
||||
// ExtensionRange represents a range of message extensions.
|
||||
// Used in code generated by protoc-gen-go.
|
||||
ExtensionRange = protoiface.ExtensionRangeV1 |
||||
|
||||
// Deprecated: Do not use; this is an internal type.
|
||||
Extension = protoimpl.ExtensionFieldV1 |
||||
|
||||
// Deprecated: Do not use; this is an internal type.
|
||||
XXX_InternalExtensions = protoimpl.ExtensionFields |
||||
) |
||||
|
||||
// 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") |
||||
|
||||
// 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 |
||||
} |
||||
|
||||
// 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 |
||||
}) |
||||
} |
||||
|
||||
// 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 has |
||||
} |
||||
|
||||
// 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 |
||||
} |
||||
|
||||
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 |
||||
}) |
||||
} |
||||
clearUnknown(mr, fieldNum(xt.Field)) |
||||
} |
||||
|
||||
// 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 |
||||
} |
||||
|
||||
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 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 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:] |
||||
} |
||||
|
||||
// For type incomplete descriptors, only retrieve the unknown fields.
|
||||
if xt.ExtensionType == nil { |
||||
return []byte(bo), 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) |
||||
} |
||||
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)) |
||||
} |
||||
} |
||||
|
||||
// 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 |
||||
} |
||||
|
||||
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 |
||||
} |
||||
|
||||
// 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 } |
||||
|
||||
func (r extensionResolver) FindExtensionByName(field protoreflect.FullName) (protoreflect.ExtensionType, error) { |
||||
if xtd := r.xt.TypeDescriptor(); xtd.FullName() == field { |
||||
return r.xt, nil |
||||
} |
||||
return protoregistry.GlobalTypes.FindExtensionByName(field) |
||||
} |
||||
|
||||
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 protoregistry.GlobalTypes.FindExtensionByNumber(message, field) |
||||
} |
||||
|
||||
// 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 |
||||
} |
||||
|
||||
vs := make([]interface{}, len(xts)) |
||||
for i, xt := range xts { |
||||
v, err := GetExtension(m, xt) |
||||
if err != nil { |
||||
if err == ErrMissingExtension { |
||||
continue |
||||
} |
||||
return vs, err |
||||
} |
||||
vs[i] = v |
||||
} |
||||
return vs, nil |
||||
} |
||||
|
||||
// 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 |
||||
} |
||||
|
||||
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) |
||||
} |
||||
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() |
||||
} |
||||
} |
||||
|
||||
xtd := xt.TypeDescriptor() |
||||
if !isValidExtension(mr.Descriptor(), xtd) { |
||||
return fmt.Errorf("proto: bad extended type; %T does not extend %T", xt.ExtendedType, m) |
||||
} |
||||
mr.Set(xtd, xt.ValueOf(v)) |
||||
clearUnknown(mr, fieldNum(xt.Field)) |
||||
return 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 |
||||
} |
||||
|
||||
// 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:] |
||||
} |
||||
|
||||
ClearExtension(m, &ExtensionDesc{Field: fnum}) |
||||
mr.SetUnknown(append(mr.GetUnknown(), b...)) |
||||
} |
||||
|
||||
// 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 |
||||
} |
||||
|
||||
// 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:] |
||||
} |
||||
|
||||
// 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) |
||||
} |
||||
return xts, nil |
||||
} |
||||
|
||||
// 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()) |
||||
} |
||||
|
||||
// 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: |
||||
return true |
||||
default: |
||||
return false |
||||
} |
||||
} |
||||
|
||||
// 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:] |
||||
} |
||||
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 |
||||
} |
@ -1,306 +0,0 @@ |
||||
// 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 ( |
||||
"fmt" |
||||
"reflect" |
||||
"strconv" |
||||
"strings" |
||||
"sync" |
||||
|
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
"google.golang.org/protobuf/runtime/protoimpl" |
||||
) |
||||
|
||||
// StructProperties represents protocol buffer type information for a
|
||||
// generated protobuf message in the open-struct API.
|
||||
//
|
||||
// Deprecated: Do not use.
|
||||
type StructProperties struct { |
||||
// 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 protobuf field name.
|
||||
OneofTypes map[string]*OneofProperties |
||||
} |
||||
|
||||
// Properties represents the type information for a protobuf message field.
|
||||
//
|
||||
// Deprecated: Do not use.
|
||||
type Properties struct { |
||||
// 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 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 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 |
||||
} |
||||
|
||||
// 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 += "," + strconv.Itoa(p.Tag) |
||||
if p.Required { |
||||
s += ",req" |
||||
} |
||||
if p.Optional { |
||||
s += ",opt" |
||||
} |
||||
if p.Repeated { |
||||
s += ",rep" |
||||
} |
||||
if p.Packed { |
||||
s += ",packed" |
||||
} |
||||
s += ",name=" + p.OrigName |
||||
if p.JSONName != "" { |
||||
s += ",json=" + p.JSONName |
||||
} |
||||
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 { |
||||
s += ",oneof" |
||||
} |
||||
if p.HasDefault { |
||||
s += ",def=" + p.Default |
||||
} |
||||
return s |
||||
} |
||||
|
||||
// Parse populates p by parsing a string in the protobuf struct field tag style.
|
||||
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 s == "req": |
||||
p.Required = true |
||||
case s == "rep": |
||||
p.Repeated = true |
||||
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 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, i = tag[len("def="):], len(tag) |
||||
} |
||||
tag = strings.TrimPrefix(tag[i:], ",") |
||||
} |
||||
} |
||||
|
||||
// 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.Name = name |
||||
p.OrigName = name |
||||
if tag == "" { |
||||
return |
||||
} |
||||
p.Parse(tag) |
||||
|
||||
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 propertiesCache sync.Map // map[reflect.Type]*StructProperties
|
||||
|
||||
// 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 p, ok := propertiesCache.Load(t); ok { |
||||
return p.(*StructProperties) |
||||
} |
||||
p, _ := propertiesCache.LoadOrStore(t, newProperties(t)) |
||||
return p.(*StructProperties) |
||||
} |
||||
|
||||
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) |
||||
|
||||
// Construct a list of properties for each field in the struct.
|
||||
for i := 0; i < t.NumField(); i++ { |
||||
p := new(Properties) |
||||
f := t.Field(i) |
||||
tagField := f.Tag.Get("protobuf") |
||||
p.Init(f.Type, f.Name, tagField, &f) |
||||
|
||||
tagOneof := f.Tag.Get("protobuf_oneof") |
||||
if tagOneof != "" { |
||||
hasOneof = true |
||||
p.OrigName = tagOneof |
||||
} |
||||
|
||||
// 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) |
||||
} |
||||
|
||||
// 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 |
||||
} |
||||
} |
||||
|
||||
prop.OneofTypes = make(map[string]*OneofProperties) |
||||
for _, wrapper := range oneofWrappers { |
||||
p := &OneofProperties{ |
||||
Type: reflect.ValueOf(wrapper).Type(), // *T
|
||||
Prop: new(Properties), |
||||
} |
||||
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 !foundOneof { |
||||
panic(fmt.Sprintf("%v is not a generated message in the open-struct API", t)) |
||||
} |
||||
prop.OneofTypes[p.Prop.OrigName] = p |
||||
} |
||||
} |
||||
|
||||
return prop |
||||
} |
||||
|
||||
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 } |
@ -1,167 +0,0 @@ |
||||
// 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() |
||||
} |
@ -1,317 +0,0 @@ |
||||
// 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 |
||||
} |
@ -1,801 +0,0 @@ |
||||
// 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 |
||||
} |
@ -1,560 +0,0 @@ |
||||
// 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>"), 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 |
||||
} |
@ -1,78 +0,0 @@ |
||||
// 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) |
||||
} |
@ -1,34 +0,0 @@ |
||||
// 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 } |
@ -1,179 +0,0 @@ |
||||
// 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 |
||||
|
||||
import ( |
||||
"fmt" |
||||
"strings" |
||||
|
||||
"github.com/golang/protobuf/proto" |
||||
"google.golang.org/protobuf/reflect/protoreflect" |
||||
"google.golang.org/protobuf/reflect/protoregistry" |
||||
|
||||
anypb "github.com/golang/protobuf/ptypes/any" |
||||
) |
||||
|
||||
const urlPrefix = "type.googleapis.com/" |
||||
|
||||
// AnyMessageName returns the message name contained in an anypb.Any message.
|
||||
// Most type assertions should use the Is function instead.
|
||||
//
|
||||
// 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") |
||||
} |
||||
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 name, nil |
||||
} |
||||
|
||||
// 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 &anypb.Any{TypeUrl: urlPrefix + proto.MessageName(m), Value: b}, nil |
||||
} |
||||
|
||||
// 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.
|
||||
//
|
||||
// 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 |
||||
} |
||||
mt, err := protoregistry.GlobalTypes.FindMessageByName(name) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
return proto.MessageV1(mt.New().Interface()), nil |
||||
} |
||||
|
||||
// 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.
|
||||
//
|
||||
// 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 |
||||
dm.Message, err = Empty(any) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
} |
||||
m = dm.Message |
||||
} |
||||
|
||||
anyName, err := AnyMessageName(any) |
||||
if err != nil { |
||||
return err |
||||
} |
||||
msgName := proto.MessageName(m) |
||||
if anyName != msgName { |
||||
return fmt.Errorf("mismatched message type: got %q want %q", anyName, msgName) |
||||
} |
||||
return proto.Unmarshal(any.Value, m) |
||||
} |
||||
|
||||
// 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(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 "<nil>" |
||||
} |
||||
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()} |
||||
} |
@ -1,62 +0,0 @@ |
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/any/any.proto
|
||||
|
||||
package any |
||||
|
||||
import ( |
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect" |
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl" |
||||
anypb "google.golang.org/protobuf/types/known/anypb" |
||||
reflect "reflect" |
||||
) |
||||
|
||||
// Symbols defined in public import of google/protobuf/any.proto.
|
||||
|
||||
type Any = anypb.Any |
||||
|
||||
var File_github_com_golang_protobuf_ptypes_any_any_proto protoreflect.FileDescriptor |
||||
|
||||
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, |
||||
} |
||||
|
||||
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
|
||||
} |
||||
|
||||
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 |
||||
} |
||||
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 |
||||
} |
@ -1,10 +0,0 @@ |
||||
// 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 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 |
@ -1,76 +0,0 @@ |
||||
// 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 |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"time" |
||||
|
||||
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 ( |
||||
maxSeconds = int64(10000 * 365.25 * 24 * 60 * 60) |
||||
minSeconds = -maxSeconds |
||||
) |
||||
|
||||
// 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(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 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 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 &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 |
||||
} |
@ -1,63 +0,0 @@ |
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/duration/duration.proto
|
||||
|
||||
package duration |
||||
|
||||
import ( |
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect" |
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl" |
||||
durationpb "google.golang.org/protobuf/types/known/durationpb" |
||||
reflect "reflect" |
||||
) |
||||
|
||||
// Symbols defined in public import of google/protobuf/duration.proto.
|
||||
|
||||
type Duration = durationpb.Duration |
||||
|
||||
var File_github_com_golang_protobuf_ptypes_duration_duration_proto protoreflect.FileDescriptor |
||||
|
||||
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, |
||||
} |
||||
|
||||
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
|
||||
} |
||||
|
||||
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 |
||||
} |
||||
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 |
||||
} |
@ -1,112 +0,0 @@ |
||||
// 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 |
||||
|
||||
import ( |
||||
"errors" |
||||
"fmt" |
||||
"time" |
||||
|
||||
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().
|
||||
minValidSeconds = -62135596800 |
||||
// Seconds field just after the latest valid Timestamp.
|
||||
// This is time.Date(10000, 1, 1, 0, 0, 0, 0, time.UTC).Unix().
|
||||
maxValidSeconds = 253402300800 |
||||
) |
||||
|
||||
// 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
|
||||
// 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.
|
||||
//
|
||||
// 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 |
||||
if ts == nil { |
||||
t = time.Unix(0, 0).UTC() // treat nil like the empty Timestamp
|
||||
} else { |
||||
t = time.Unix(ts.Seconds, int64(ts.Nanos)).UTC() |
||||
} |
||||
return t, validateTimestamp(ts) |
||||
} |
||||
|
||||
// TimestampNow returns a google.protobuf.Timestamp for the current time.
|
||||
//
|
||||
// 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") |
||||
} |
||||
return ts |
||||
} |
||||
|
||||
// TimestampProto converts the time.Time to a google.protobuf.Timestamp proto.
|
||||
// It returns an error if the resulting Timestamp is invalid.
|
||||
//
|
||||
// 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()), |
||||
} |
||||
if err := validateTimestamp(ts); err != nil { |
||||
return nil, err |
||||
} |
||||
return ts, nil |
||||
} |
||||
|
||||
// TimestampString returns the RFC 3339 string for valid Timestamps.
|
||||
// For invalid Timestamps, it returns an error message in parentheses.
|
||||
//
|
||||
// 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 |
||||
} |
@ -1,64 +0,0 @@ |
||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||
// source: github.com/golang/protobuf/ptypes/timestamp/timestamp.proto
|
||||
|
||||
package timestamp |
||||
|
||||
import ( |
||||
protoreflect "google.golang.org/protobuf/reflect/protoreflect" |
||||
protoimpl "google.golang.org/protobuf/runtime/protoimpl" |
||||
timestamppb "google.golang.org/protobuf/types/known/timestamppb" |
||||
reflect "reflect" |
||||
) |
||||
|
||||
// Symbols defined in public import of google/protobuf/timestamp.proto.
|
||||
|
||||
type Timestamp = timestamppb.Timestamp |
||||
|
||||
var File_github_com_golang_protobuf_ptypes_timestamp_timestamp_proto protoreflect.FileDescriptor |
||||
|
||||
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, |
||||
} |
||||
|
||||
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
|
||||
} |
||||
|
||||
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 |
||||
} |
||||
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 |
||||
} |
File diff suppressed because it is too large
Load Diff
@ -1,16 +0,0 @@ |
||||
sudo: false |
||||
language: go |
||||
go: |
||||
- 1.x |
||||
- master |
||||
matrix: |
||||
allow_failures: |
||||
- go: master |
||||
fast_finish: true |
||||
install: |
||||
- # Do nothing. This is needed to prevent default install action "go get -t -v ./..." from happening here (we want it to happen inside script step). |
||||
script: |
||||
- go get -t -v ./... |
||||
- diff -u <(echo -n) <(gofmt -d -s .) |
||||
- go tool vet . |
||||
- go test -v -race ./... |
@ -1,21 +0,0 @@ |
||||
MIT License |
||||
|
||||
Copyright (c) 2015 Dmitri Shuralyov |
||||
|
||||
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. |
@ -1,36 +0,0 @@ |
||||
sanitized_anchor_name |
||||
===================== |
||||
|
||||
[![Build Status](https://travis-ci.org/shurcooL/sanitized_anchor_name.svg?branch=master)](https://travis-ci.org/shurcooL/sanitized_anchor_name) [![GoDoc](https://godoc.org/github.com/shurcooL/sanitized_anchor_name?status.svg)](https://godoc.org/github.com/shurcooL/sanitized_anchor_name) |
||||
|
||||
Package sanitized_anchor_name provides a func to create sanitized anchor names. |
||||
|
||||
Its logic can be reused by multiple packages to create interoperable anchor names |
||||
and links to those anchors. |
||||
|
||||
At this time, it does not try to ensure that generated anchor names |
||||
are unique, that responsibility falls on the caller. |
||||
|
||||
Installation |
||||
------------ |
||||
|
||||
```bash |
||||
go get -u github.com/shurcooL/sanitized_anchor_name |
||||
``` |
||||
|
||||
Example |
||||
------- |
||||
|
||||
```Go |
||||
anchorName := sanitized_anchor_name.Create("This is a header") |
||||
|
||||
fmt.Println(anchorName) |
||||
|
||||
// Output: |
||||
// this-is-a-header |
||||
``` |
||||
|
||||
License |
||||
------- |
||||
|
||||
- [MIT License](LICENSE) |
@ -1,29 +0,0 @@ |
||||
// Package sanitized_anchor_name provides a func to create sanitized anchor names.
|
||||
//
|
||||
// Its logic can be reused by multiple packages to create interoperable anchor names
|
||||
// and links to those anchors.
|
||||
//
|
||||
// At this time, it does not try to ensure that generated anchor names
|
||||
// are unique, that responsibility falls on the caller.
|
||||
package sanitized_anchor_name // import "github.com/shurcooL/sanitized_anchor_name"
|
||||
|
||||
import "unicode" |
||||
|
||||
// Create returns a sanitized anchor name for the given text.
|
||||
func Create(text string) string { |
||||
var anchorName []rune |
||||
var futureDash = false |
||||
for _, r := range text { |
||||
switch { |
||||
case unicode.IsLetter(r) || unicode.IsNumber(r): |
||||
if futureDash && len(anchorName) > 0 { |
||||
anchorName = append(anchorName, '-') |
||||
} |
||||
futureDash = false |
||||
anchorName = append(anchorName, unicode.ToLower(r)) |
||||
default: |
||||
futureDash = true |
||||
} |
||||
} |
||||
return string(anchorName) |
||||
} |
@ -1,3 +1,5 @@ |
||||
*.coverprofile |
||||
coverage.txt |
||||
node_modules/ |
||||
vendor |
||||
vendor |
||||
.idea |
||||
|
@ -1,35 +0,0 @@ |
||||
language: go |
||||
sudo: false |
||||
dist: bionic |
||||
osx_image: xcode10 |
||||
go: |
||||
- 1.11.x |
||||
- 1.12.x |
||||
- 1.13.x |
||||
|
||||
os: |
||||
- linux |
||||
- osx |
||||
|
||||
env: |
||||
GO111MODULE=on |
||||
GOPROXY=https://proxy.golang.org |
||||
|
||||
cache: |
||||
directories: |
||||
- node_modules |
||||
|
||||
before_script: |
||||
- go get github.com/urfave/gfmrun/cmd/gfmrun |
||||
- go get golang.org/x/tools/cmd/goimports |
||||
- npm install markdown-toc |
||||
- go mod tidy |
||||
|
||||
script: |
||||
- go run build.go vet |
||||
- go run build.go test |
||||
- go run build.go gfmrun docs/v1/manual.md |
||||
- go run build.go toc docs/v1/manual.md |
||||
|
||||
after_success: |
||||
- bash <(curl -s https://codecov.io/bash) |
@ -1,3 +0,0 @@ |
||||
# This source code refers to The Go Authors for copyright purposes. |
||||
# The master list of authors is in the main Go distribution, |
||||
# visible at http://tip.golang.org/AUTHORS. |
@ -1,3 +0,0 @@ |
||||
# This source code was written by the Go contributors. |
||||
# The master list of contributors is in the main Go distribution, |
||||
# visible at http://tip.golang.org/CONTRIBUTORS. |
@ -1,3 +0,0 @@ |
||||
# This source code refers to The Go Authors for copyright purposes. |
||||
# The master list of authors is in the main Go distribution, |
||||
# visible at http://tip.golang.org/AUTHORS. |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue