diff --git a/go.mod b/go.mod index 456aaa2248..c5c19204d9 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/beevik/etree v1.6.0 github.com/blevesearch/bleve/v2 v2.5.7 github.com/cenkalti/backoff v2.2.1+incompatible + github.com/centrifugal/centrifuge-go v0.10.12 github.com/coreos/go-oidc/v3 v3.17.0 github.com/cs3org/go-cs3apis v0.0.0-20260310080202-fb97596763d6 github.com/davidbyttow/govips/v2 v2.17.0 @@ -71,7 +72,6 @@ require ( github.com/pkg/errors v0.9.1 github.com/pkg/xattr v0.4.12 github.com/prometheus/client_golang v1.23.2 - github.com/r3labs/sse/v2 v2.10.0 github.com/riandyrn/otelchi v0.12.2 github.com/rogpeppe/go-internal v1.14.1 github.com/rs/cors v1.11.1 @@ -89,6 +89,7 @@ require ( github.com/thejerf/suture/v4 v4.0.6 github.com/tidwall/gjson v1.18.0 github.com/tidwall/sjson v1.2.5 + github.com/tmaxmax/go-sse v0.11.0 github.com/tus/tusd/v2 v2.8.0 github.com/unrolled/secure v1.16.0 github.com/vmihailenco/msgpack/v5 v5.4.1 @@ -163,6 +164,7 @@ require ( github.com/bombsimon/logrusr/v3 v3.1.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cenkalti/backoff/v5 v5.0.3 // indirect + github.com/centrifugal/protocol v0.16.0 // indirect github.com/ceph/go-ceph v0.37.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73 // indirect @@ -245,6 +247,7 @@ require ( github.com/gookit/goutil v0.7.1 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/schema v1.4.1 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 // indirect github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-plugin v1.7.0 // indirect @@ -256,6 +259,8 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jonboulle/clockwork v0.5.0 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/juliangruber/go-intersect v1.1.0 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect @@ -277,6 +282,7 @@ require ( github.com/longsleep/rndm v1.2.0 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.10 // indirect + github.com/mailru/easyjson v0.7.7 // indirect github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect @@ -322,6 +328,7 @@ require ( github.com/philhofer/fwd v1.2.0 // indirect github.com/pierrec/lz4/v4 v4.1.15 // indirect github.com/pjbgf/sha1cd v0.3.2 // indirect + github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect github.com/pquerna/cachecontrol v0.2.0 // indirect @@ -340,12 +347,14 @@ require ( github.com/samber/slog-common v0.20.0 // indirect github.com/samber/slog-zerolog/v2 v2.9.1 // indirect github.com/segmentio/asm v1.2.1 // indirect + github.com/segmentio/encoding v0.4.0 // indirect github.com/segmentio/kafka-go v0.4.50 // indirect github.com/segmentio/ksuid v1.0.4 // indirect github.com/sercand/kuberesolver/v5 v5.1.1 // indirect github.com/sergi/go-diff v1.4.0 // indirect github.com/sethvargo/go-diceware v0.5.0 // indirect github.com/sethvargo/go-password v0.3.1 // indirect + github.com/shadowspore/fossil-delta v0.0.0-20241213113458-1d797d70cbe3 // indirect github.com/shamaton/msgpack/v2 v2.4.0 // indirect github.com/shirou/gopsutil/v4 v4.26.2 // indirect github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect @@ -366,6 +375,7 @@ require ( github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 // indirect github.com/trustelem/zxcvbn v1.0.1 // indirect github.com/urfave/cli/v2 v2.27.7 // indirect + github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fastjson v1.6.7 // indirect github.com/vektah/gqlparser/v2 v2.5.32 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect @@ -394,7 +404,6 @@ require ( golang.org/x/tools v0.42.0 // indirect google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260226221140-a57be14db171 // indirect - gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect sigs.k8s.io/yaml v1.6.0 // indirect diff --git a/go.sum b/go.sum index d321a6dab8..2c26f503f3 100644 --- a/go.sum +++ b/go.sum @@ -208,6 +208,10 @@ github.com/cenkalti/backoff/v5 v5.0.3 h1:ZN+IMa753KfX5hd8vVaMixjnqRZ3y8CuJKRKj1x github.com/cenkalti/backoff/v5 v5.0.3/go.mod h1:rkhZdG3JZukswDf7f0cwqPNk4K0sa+F97BxZthm/crw= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/centrifugal/centrifuge-go v0.10.12 h1:CX8zgXJ/WD0psI1bMdLiyz0HmXV+xV+IzDkYgpfN58Q= +github.com/centrifugal/centrifuge-go v0.10.12/go.mod h1:yONZBopAssVw7mluSRs/6YTYkqKe+llSGIokNVlBDZ4= +github.com/centrifugal/protocol v0.16.0 h1:bAQm4YvONSPqq6kR8UgBNyf5Yh63AHKnjSKj/g9anPk= +github.com/centrifugal/protocol v0.16.0/go.mod h1:7V5vI30VcoxJe4UD87xi7bOsvI0bmEhvbQuMjrFM2L4= github.com/ceph/go-ceph v0.37.0 h1:KXliBe3ZDr3/AtfY7n9d1MG7ippYNCVhMPcAgm05CFI= github.com/ceph/go-ceph v0.37.0/go.mod h1:3y2tOlITlyuVFhy8v6PpCEfjMwKPfXJiH0/2hKZZQRE= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -611,6 +615,8 @@ github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWS github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E= github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI= github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8= @@ -698,8 +704,11 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= @@ -797,6 +806,8 @@ github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czP github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE= github.com/magiconair/properties v1.8.10/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/matryer/moq v0.0.0-20190312154309-6cfb0558e1bd/go.mod h1:9ELz6aaclSIGnZBoaSLZ3NAl1VTufbOrXBPvtcy6WiQ= @@ -1005,6 +1016,8 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ github.com/pkg/term v1.1.0/go.mod h1:E25nymQcrSllhX42Ok8MRm1+hyBdHY0dCeiKZ9jpNGw= github.com/pkg/xattr v0.4.12 h1:rRTkSyFNTRElv6pkA3zpjHpQ90p/OdHQC1GmGh1aTjM= github.com/pkg/xattr v0.4.12/go.mod h1:di8WF84zAKk8jzR1UBTEWh9AUlIZZ7M/JNt8e9B6ktU= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -1066,8 +1079,6 @@ github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9 github.com/prometheus/statsd_exporter v0.22.8 h1:Qo2D9ZzaQG+id9i5NYNGmbf1aa/KxKbB9aKfMS+Yib0= github.com/prometheus/statsd_exporter v0.22.8/go.mod h1:/DzwbTEaFTE0Ojz5PqcSk6+PFHOPWGxdXVr6yC8eFOM= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/r3labs/sse/v2 v2.10.0 h1:hFEkLLFY4LDifoHdiCN/LlGBAdVJYsANaLqNYa1l/v0= -github.com/r3labs/sse/v2 v2.10.0/go.mod h1:Igau6Whc+F17QUgML1fYe1VPZzTV6EMCnYktEmkNJ7I= github.com/rainycape/memcache v0.0.0-20150622160815-1031fa0ce2f2/go.mod h1:7tZKcyumwBO6qip7RNQ5r77yrssm9bfCowcLEBcU5IA= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 h1:bsUq1dX0N8AOIL7EB/X911+m4EHsnWEHeJ0c+3TTBrg= @@ -1105,6 +1116,8 @@ github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f/ github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0= github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= +github.com/segmentio/encoding v0.4.0 h1:MEBYvRqiUB2nfR2criEXWqwdY6HJOUrCn5hboVOVmy8= +github.com/segmentio/encoding v0.4.0/go.mod h1:/d03Cd8PoaDeceuhUUUQWjU0KhWjrmYrWPgtJHYZSnI= github.com/segmentio/kafka-go v0.4.50 h1:mcyC3tT5WeyWzrFbd6O374t+hmcu1NKt2Pu1L3QaXmc= github.com/segmentio/kafka-go v0.4.50/go.mod h1:Y1gn60kzLEEaW28YshXyk2+VCUKbJ3Qr6DrnT3i4+9E= github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c= @@ -1117,6 +1130,8 @@ github.com/sethvargo/go-diceware v0.5.0 h1:exrQ7GpaBo00GqRVM1N8ChXSsi3oS7tjQiIeh github.com/sethvargo/go-diceware v0.5.0/go.mod h1:Lg1SyPS7yQO6BBgTN5r4f2MUDkqGfLWsOjHPY0kA8iw= github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU= github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs= +github.com/shadowspore/fossil-delta v0.0.0-20241213113458-1d797d70cbe3 h1:/4/IJi5iyTdh6mqOUaASW148HQpujYiHl0Wl78dSOSc= +github.com/shadowspore/fossil-delta v0.0.0-20241213113458-1d797d70cbe3/go.mod h1:aJIMhRsunltJR926EB2MUg8qHemFQDreSB33pyto2Ps= github.com/shamaton/msgpack/v2 v2.4.0 h1:O5Z08MRmbo0lA9o2xnQ4TXx6teJbPqEurqcCOQ8Oi/4= github.com/shamaton/msgpack/v2 v2.4.0/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= @@ -1224,6 +1239,8 @@ github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYI github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI= github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw= github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ= +github.com/tmaxmax/go-sse v0.11.0 h1:nogmJM6rJUoOLoAwEKeQe5XlVpt9l7N82SS1jI7lWFg= +github.com/tmaxmax/go-sse v0.11.0/go.mod h1:u/2kZQR1tyngo1lKaNCj1mJmhXGZWS1Zs5yiSOD+Eg8= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 h1:PM5hJF7HVfNWmCjMdEfbuOBNXSVF2cMFGgQTPdKCbwM= github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXzZUvMacR0oF/fbDDgUPO8L36tDMmRAf14ns= @@ -1237,6 +1254,7 @@ github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI= github.com/urfave/cli/v2 v2.27.7 h1:bH59vdhbjLv3LAvIu6gd0usJHgoTTPhCFib8qqOwXYU= github.com/urfave/cli/v2 v2.27.7/go.mod h1:CyNAG/xg+iAOg0N4MPGZqVmv2rCoP267496AOXUZjA4= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= github.com/valyala/fastjson v1.6.7 h1:ZE4tRy0CIkh+qDc5McjatheGX2czdn8slQjomexVpBM= github.com/valyala/fastjson v1.6.7/go.mod h1:CLCAqky6SMuOcxStkYQvblddUtoRxhYMGLrsQns1aXY= @@ -1429,7 +1447,6 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191116160921-f9c825593386/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1758,8 +1775,6 @@ google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqw google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE= google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= -gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y= -gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/opencloud/pkg/command/services.go b/opencloud/pkg/command/services.go index 3c0d3852d0..c1f80d4bde 100644 --- a/opencloud/pkg/command/services.go +++ b/opencloud/pkg/command/services.go @@ -19,6 +19,7 @@ import ( authservice "github.com/opencloud-eu/opencloud/services/auth-service/pkg/command" clientlog "github.com/opencloud-eu/opencloud/services/clientlog/pkg/command" collaboration "github.com/opencloud-eu/opencloud/services/collaboration/pkg/command" + console "github.com/opencloud-eu/opencloud/services/console/pkg/command" eventhistory "github.com/opencloud-eu/opencloud/services/eventhistory/pkg/command" frontend "github.com/opencloud-eu/opencloud/services/frontend/pkg/command" gateway "github.com/opencloud-eu/opencloud/services/gateway/pkg/command" @@ -113,6 +114,11 @@ var serviceCommands = []register.Command{ cfg.Collaboration.Commons = cfg.Commons }) }, + func(cfg *config.Config) *cobra.Command { + return ServiceCommand(cfg, cfg.Console.Service.Name, console.GetCommands(cfg.Console), func(c *config.Config) { + cfg.Console.Commons = cfg.Commons + }) + }, func(cfg *config.Config) *cobra.Command { return ServiceCommand(cfg, cfg.EventHistory.Service.Name, eventhistory.GetCommands(cfg.EventHistory), func(c *config.Config) { cfg.EventHistory.Commons = cfg.Commons diff --git a/opencloud/pkg/runtime/service/service.go b/opencloud/pkg/runtime/service/service.go index c83fdf78da..186f45e86b 100644 --- a/opencloud/pkg/runtime/service/service.go +++ b/opencloud/pkg/runtime/service/service.go @@ -30,6 +30,7 @@ import ( authservice "github.com/opencloud-eu/opencloud/services/auth-service/pkg/command" clientlog "github.com/opencloud-eu/opencloud/services/clientlog/pkg/command" collaboration "github.com/opencloud-eu/opencloud/services/collaboration/pkg/command" + console "github.com/opencloud-eu/opencloud/services/console/pkg/command" eventhistory "github.com/opencloud-eu/opencloud/services/eventhistory/pkg/command" frontend "github.com/opencloud-eu/opencloud/services/frontend/pkg/command" gateway "github.com/opencloud-eu/opencloud/services/gateway/pkg/command" @@ -327,6 +328,11 @@ func NewService(ctx context.Context, options ...Option) (*Service, error) { cfg.Collaboration.Commons = cfg.Commons return collaboration.Execute(cfg.Collaboration) }) + areg(opts.Config.Console.Service.Name, func(ctx context.Context, cfg *occfg.Config) error { + cfg.Console.Context = ctx + cfg.Console.Commons = cfg.Commons + return console.Execute(cfg.Console) + }) areg(opts.Config.Policies.Service.Name, func(ctx context.Context, cfg *occfg.Config) error { cfg.Policies.Context = ctx cfg.Policies.Commons = cfg.Commons diff --git a/pkg/config/config.go b/pkg/config/config.go index 36536c8064..89a66d8511 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -14,6 +14,7 @@ import ( authservice "github.com/opencloud-eu/opencloud/services/auth-service/pkg/config" clientlog "github.com/opencloud-eu/opencloud/services/clientlog/pkg/config" collaboration "github.com/opencloud-eu/opencloud/services/collaboration/pkg/config" + console "github.com/opencloud-eu/opencloud/services/console/pkg/config" eventhistory "github.com/opencloud-eu/opencloud/services/eventhistory/pkg/config" frontend "github.com/opencloud-eu/opencloud/services/frontend/pkg/config" gateway "github.com/opencloud-eu/opencloud/services/gateway/pkg/config" @@ -94,6 +95,7 @@ type Config struct { AuthService *authservice.Config `yaml:"auth_service"` Clientlog *clientlog.Config `yaml:"clientlog"` Collaboration *collaboration.Config `yaml:"collaboration"` + Console *console.Config `yaml:"console"` EventHistory *eventhistory.Config `yaml:"eventhistory"` Frontend *frontend.Config `yaml:"frontend"` Gateway *gateway.Config `yaml:"gateway"` diff --git a/pkg/config/defaultconfig.go b/pkg/config/defaultconfig.go index 59f5de02b2..bf775741b6 100644 --- a/pkg/config/defaultconfig.go +++ b/pkg/config/defaultconfig.go @@ -14,6 +14,7 @@ import ( authservice "github.com/opencloud-eu/opencloud/services/auth-service/pkg/config/defaults" clientlog "github.com/opencloud-eu/opencloud/services/clientlog/pkg/config/defaults" collaboration "github.com/opencloud-eu/opencloud/services/collaboration/pkg/config/defaults" + console "github.com/opencloud-eu/opencloud/services/console/pkg/config/defaults" eventhistory "github.com/opencloud-eu/opencloud/services/eventhistory/pkg/config/defaults" frontend "github.com/opencloud-eu/opencloud/services/frontend/pkg/config/defaults" gateway "github.com/opencloud-eu/opencloud/services/gateway/pkg/config/defaults" @@ -69,6 +70,7 @@ func DefaultConfig() *Config { AuthService: authservice.DefaultConfig(), Clientlog: clientlog.DefaultConfig(), Collaboration: collaboration.DefaultConfig(), + Console: console.DefaultConfig(), EventHistory: eventhistory.DefaultConfig(), Frontend: frontend.DefaultConfig(), Gateway: gateway.DefaultConfig(), diff --git a/pkg/x/io/fsx/cs3/metadata/file.go b/pkg/x/io/fsx/cs3/metadata/file.go new file mode 100644 index 0000000000..4980058e7b --- /dev/null +++ b/pkg/x/io/fsx/cs3/metadata/file.go @@ -0,0 +1,89 @@ +package metadata + +import ( + "bytes" + "context" + "io" + "io/fs" + "os" +) + +type File struct { + name string + fs *Fs + fileMode os.FileMode + content []byte + resource io.ReadCloser +} + +func newFile(name string, fs *Fs, fileMode os.FileMode, content []byte) (*File, error) { + return &File{ + name: name, + fs: fs, + fileMode: fileMode, + content: content, + resource: io.NopCloser(bytes.NewBuffer(content)), + }, nil +} + +func (f *File) Close() error { + return f.resource.Close() +} + +func (f *File) Read(p []byte) (n int, err error) { + return f.resource.Read(p) +} + +func (f *File) ReadAt(p []byte, off int64) (n int, err error) { + readerAt, ok := f.resource.(io.ReaderAt) + if !ok { + return -1, &fs.PathError{Op: "ReadAt", Path: f.name, Err: ErrNotImplemented} + } + + return readerAt.ReadAt(p, off) +} + +func (f *File) Seek(offset int64, whence int) (int64, error) { + seeker, ok := f.resource.(io.Seeker) + if !ok { + return -1, &fs.PathError{Op: "Seek", Path: f.name, Err: ErrNotImplemented} + } + + return seeker.Seek(offset, whence) +} + +func (f *File) Write(p []byte) (n int, err error) { + return len(p), f.fs.storage.SimpleUpload(context.Background(), f.name, p) +} + +func (f *File) WriteAt(_ []byte, _ int64) (n int, err error) { + return -1, &fs.PathError{Op: "Write", Path: f.name, Err: ErrNotImplemented} +} + +func (f *File) Name() string { + return f.name +} + +func (f *File) Readdir(_ int) ([]os.FileInfo, error) { + return nil, &fs.PathError{Op: "Readdir", Path: f.name, Err: ErrNotImplemented} +} + +func (f *File) Readdirnames(_ int) ([]string, error) { + return nil, &fs.PathError{Op: "Readdirnames", Path: f.name, Err: ErrNotImplemented} +} + +func (f *File) Sync() error { + return nil +} + +func (f *File) Truncate(_ int64) error { + return &fs.PathError{Op: "Truncate", Path: f.name, Err: ErrNotImplemented} +} + +func (f *File) WriteString(_ string) (ret int, err error) { + return -1, &fs.PathError{Op: "WriteString", Path: f.name, Err: ErrNotImplemented} +} + +func (f *File) Stat() (os.FileInfo, error) { + return newFileInfo(f.name, f.fs, f.fileMode) +} diff --git a/pkg/x/io/fsx/cs3/metadata/file_info.go b/pkg/x/io/fsx/cs3/metadata/file_info.go new file mode 100644 index 0000000000..562ca4c193 --- /dev/null +++ b/pkg/x/io/fsx/cs3/metadata/file_info.go @@ -0,0 +1,59 @@ +package metadata + +import ( + "context" + "io/fs" + "os" + "time" + + providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + + "github.com/opencloud-eu/reva/v2/pkg/utils" +) + +type FileInfo struct { + name string + size int64 + modTime time.Time + isDir bool + mode os.FileMode +} + +func newFileInfo(name string, fs *Fs, fileMode os.FileMode) (*FileInfo, error) { + info, err := fs.storage.Stat(context.Background(), name) + if err != nil { + return nil, err + } + + return &FileInfo{ + name: info.GetName(), + size: int64(info.GetSize()), + modTime: utils.TSToTime(info.GetMtime()), + isDir: info.GetType() == providerv1beta1.ResourceType_RESOURCE_TYPE_CONTAINER, + mode: fileMode, + }, nil +} + +func (f *FileInfo) Name() string { + return f.name +} + +func (f *FileInfo) Size() int64 { + return f.size +} + +func (f *FileInfo) ModTime() time.Time { + return f.modTime +} + +func (f *FileInfo) IsDir() bool { + return f.isDir +} + +func (f *FileInfo) Mode() fs.FileMode { + return f.mode +} + +func (f *FileInfo) Sys() any { + return nil +} diff --git a/pkg/x/io/fsx/cs3/metadata/fs.go b/pkg/x/io/fsx/cs3/metadata/fs.go new file mode 100644 index 0000000000..c62337a1c3 --- /dev/null +++ b/pkg/x/io/fsx/cs3/metadata/fs.go @@ -0,0 +1,96 @@ +package metadata + +import ( + "context" + "fmt" + "io/fs" + "os" + "path" + "strings" + "syscall" + "time" + + "github.com/spf13/afero" + + revaMetadata "github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata" + "github.com/opencloud-eu/reva/v2/pkg/storage/utils/metadata" +) + +func NewMetadataFs(storage metadata.Storage) *Fs { + return &Fs{storage: storage} +} + +type Fs struct { + storage metadata.Storage +} + +func (fs *Fs) Create(_ string) (afero.File, error) { + return nil, syscall.EPERM +} + +func (fs *Fs) Mkdir(name string, _ os.FileMode) error { + return fs.storage.MakeDirIfNotExist(context.Background(), name) +} + +func (fs *Fs) MkdirAll(name string, _ os.FileMode) error { + paths := strings.Split(name, string(os.PathSeparator)) + // Create all parent directories if they do not exist + for i := 0; i <= len(paths)-1; i++ { + c := path.Join(paths[:i+1]...) + if err := fs.storage.MakeDirIfNotExist(context.Background(), c); err != nil { + return fmt.Errorf("failed to create directory %s: %w", c, err) + } + } + + return nil +} + +func (fs *Fs) Open(name string) (afero.File, error) { + return fs.OpenFile(name, os.O_RDONLY, 0) +} + +func (fs *Fs) OpenFile(name string, _ int, _ os.FileMode) (afero.File, error) { + res, err := fs.storage.Download(context.Background(), metadata.DownloadRequest{Path: name}) + if err != nil && !revaMetadata.IsNotExist(err) { + return nil, err + } + + var contend []byte + if res != nil { + contend = res.Content + } + + return newFile(name, fs, 0, contend) +} + +func (fs *Fs) Remove(name string) error { + return fs.RemoveAll(name) +} + +func (fs *Fs) RemoveAll(path string) error { + return fs.storage.Delete(context.Background(), path) +} + +func (fs *Fs) Rename(_, _ string) error { + return syscall.EPERM +} + +func (fs *Fs) Stat(name string) (fs.FileInfo, error) { + return newFileInfo(name, fs, 0) +} + +func (fs *Fs) Name() string { + return "MetadataFS" +} + +func (fs *Fs) Chmod(_ string, _ os.FileMode) error { + return syscall.EPERM +} + +func (fs *Fs) Chown(_ string, _, _ int) error { + return syscall.EPERM +} + +func (fs *Fs) Chtimes(_ string, _ time.Time, _ time.Time) error { + return syscall.EPERM +} diff --git a/pkg/x/io/fsx/cs3/metadata/metadata.go b/pkg/x/io/fsx/cs3/metadata/metadata.go new file mode 100644 index 0000000000..aecf62fdaf --- /dev/null +++ b/pkg/x/io/fsx/cs3/metadata/metadata.go @@ -0,0 +1,9 @@ +package metadata + +import ( + "errors" +) + +var ( + ErrNotImplemented = errors.New("not implemented") +) diff --git a/protogen/gen/opencloud/services/web/v0/web.pb.go b/protogen/gen/opencloud/services/web/v0/web.pb.go new file mode 100644 index 0000000000..badb1022d2 --- /dev/null +++ b/protogen/gen/opencloud/services/web/v0/web.pb.go @@ -0,0 +1,499 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.28.1 +// protoc (unknown) +// source: opencloud/services/web/v0/web.proto + +package v0 + +import ( + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type ThemeAddRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The ID of the theme to add + Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` // The theme data in bytes +} + +func (x *ThemeAddRequest) Reset() { + *x = ThemeAddRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ThemeAddRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThemeAddRequest) ProtoMessage() {} + +func (x *ThemeAddRequest) ProtoReflect() protoreflect.Message { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThemeAddRequest.ProtoReflect.Descriptor instead. +func (*ThemeAddRequest) Descriptor() ([]byte, []int) { + return file_opencloud_services_web_v0_web_proto_rawDescGZIP(), []int{0} +} + +func (x *ThemeAddRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +func (x *ThemeAddRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type ThemeAddResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ThemeAddResponse) Reset() { + *x = ThemeAddResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ThemeAddResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThemeAddResponse) ProtoMessage() {} + +func (x *ThemeAddResponse) ProtoReflect() protoreflect.Message { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThemeAddResponse.ProtoReflect.Descriptor instead. +func (*ThemeAddResponse) Descriptor() ([]byte, []int) { + return file_opencloud_services_web_v0_web_proto_rawDescGZIP(), []int{1} +} + +type ThemeExistsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The ID of the theme to check +} + +func (x *ThemeExistsRequest) Reset() { + *x = ThemeExistsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ThemeExistsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThemeExistsRequest) ProtoMessage() {} + +func (x *ThemeExistsRequest) ProtoReflect() protoreflect.Message { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThemeExistsRequest.ProtoReflect.Descriptor instead. +func (*ThemeExistsRequest) Descriptor() ([]byte, []int) { + return file_opencloud_services_web_v0_web_proto_rawDescGZIP(), []int{2} +} + +func (x *ThemeExistsRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type ThemeExistsResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Exists bool `protobuf:"varint,1,opt,name=exists,proto3" json:"exists,omitempty"` // Indicates if the theme exists +} + +func (x *ThemeExistsResponse) Reset() { + *x = ThemeExistsResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ThemeExistsResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThemeExistsResponse) ProtoMessage() {} + +func (x *ThemeExistsResponse) ProtoReflect() protoreflect.Message { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThemeExistsResponse.ProtoReflect.Descriptor instead. +func (*ThemeExistsResponse) Descriptor() ([]byte, []int) { + return file_opencloud_services_web_v0_web_proto_rawDescGZIP(), []int{3} +} + +func (x *ThemeExistsResponse) GetExists() bool { + if x != nil { + return x.Exists + } + return false +} + +type ThemeRemoveRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // The ID of the theme to remove +} + +func (x *ThemeRemoveRequest) Reset() { + *x = ThemeRemoveRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ThemeRemoveRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThemeRemoveRequest) ProtoMessage() {} + +func (x *ThemeRemoveRequest) ProtoReflect() protoreflect.Message { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThemeRemoveRequest.ProtoReflect.Descriptor instead. +func (*ThemeRemoveRequest) Descriptor() ([]byte, []int) { + return file_opencloud_services_web_v0_web_proto_rawDescGZIP(), []int{4} +} + +func (x *ThemeRemoveRequest) GetId() string { + if x != nil { + return x.Id + } + return "" +} + +type ThemeRemoveResponse struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *ThemeRemoveResponse) Reset() { + *x = ThemeRemoveResponse{} + if protoimpl.UnsafeEnabled { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ThemeRemoveResponse) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ThemeRemoveResponse) ProtoMessage() {} + +func (x *ThemeRemoveResponse) ProtoReflect() protoreflect.Message { + mi := &file_opencloud_services_web_v0_web_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ThemeRemoveResponse.ProtoReflect.Descriptor instead. +func (*ThemeRemoveResponse) Descriptor() ([]byte, []int) { + return file_opencloud_services_web_v0_web_proto_rawDescGZIP(), []int{5} +} + +var File_opencloud_services_web_v0_web_proto protoreflect.FileDescriptor + +var file_opencloud_services_web_v0_web_proto_rawDesc = []byte{ + 0x0a, 0x23, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2f, 0x77, 0x65, 0x62, 0x2f, 0x76, 0x30, 0x2f, 0x77, 0x65, 0x62, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x19, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x77, 0x65, 0x62, 0x2e, 0x76, 0x30, + 0x1a, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x2d, 0x67, 0x65, 0x6e, 0x2d, 0x6f, 0x70, 0x65, + 0x6e, 0x61, 0x70, 0x69, 0x76, 0x32, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x61, + 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x22, 0x35, 0x0a, 0x0f, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x02, 0x69, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x12, 0x0a, 0x10, 0x54, 0x68, 0x65, 0x6d, 0x65, + 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x24, 0x0a, 0x12, 0x54, + 0x68, 0x65, 0x6d, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, + 0x64, 0x22, 0x2d, 0x0a, 0x13, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x65, 0x78, 0x69, 0x73, + 0x74, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x65, 0x78, 0x69, 0x73, 0x74, 0x73, + 0x22, 0x24, 0x0a, 0x12, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x15, 0x0a, 0x13, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0xcd, 0x02, + 0x0a, 0x0a, 0x57, 0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x63, 0x0a, 0x08, + 0x54, 0x68, 0x65, 0x6d, 0x65, 0x41, 0x64, 0x64, 0x12, 0x2a, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, + 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x77, 0x65, + 0x62, 0x2e, 0x76, 0x30, 0x2e, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x41, 0x64, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x77, 0x65, 0x62, 0x2e, 0x76, 0x30, + 0x2e, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x41, 0x64, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x6c, 0x0a, 0x0b, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, + 0x12, 0x2d, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x77, 0x65, 0x62, 0x2e, 0x76, 0x30, 0x2e, 0x54, 0x68, 0x65, + 0x6d, 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x2e, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x73, 0x2e, 0x77, 0x65, 0x62, 0x2e, 0x76, 0x30, 0x2e, 0x54, 0x68, 0x65, 0x6d, + 0x65, 0x45, 0x78, 0x69, 0x73, 0x74, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, + 0x6c, 0x0a, 0x0b, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x12, 0x2d, + 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2e, 0x77, 0x65, 0x62, 0x2e, 0x76, 0x30, 0x2e, 0x54, 0x68, 0x65, 0x6d, 0x65, + 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, + 0x65, 0x73, 0x2e, 0x77, 0x65, 0x62, 0x2e, 0x76, 0x30, 0x2e, 0x54, 0x68, 0x65, 0x6d, 0x65, 0x52, + 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0xea, 0x02, + 0x5a, 0x48, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, + 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, + 0x6f, 0x75, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e, + 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x73, 0x2f, 0x77, 0x65, 0x62, 0x2f, 0x76, 0x30, 0x92, 0x41, 0x9c, 0x02, 0x12, 0xb4, + 0x01, 0x0a, 0x0d, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x77, 0x65, 0x62, + 0x22, 0x51, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x47, 0x6d, + 0x62, 0x48, 0x12, 0x29, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x1a, 0x14, 0x73, + 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, + 0x2e, 0x65, 0x75, 0x2a, 0x49, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, + 0x30, 0x12, 0x3b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, + 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62, 0x6c, 0x6f, + 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, + 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x3b, 0x0a, + 0x10, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, + 0x6c, 0x12, 0x27, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x6f, 0x63, 0x73, 0x2e, + 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x65, 0x75, 0x2f, 0x73, 0x65, 0x72, + 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x77, 0x65, 0x62, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x33, +} + +var ( + file_opencloud_services_web_v0_web_proto_rawDescOnce sync.Once + file_opencloud_services_web_v0_web_proto_rawDescData = file_opencloud_services_web_v0_web_proto_rawDesc +) + +func file_opencloud_services_web_v0_web_proto_rawDescGZIP() []byte { + file_opencloud_services_web_v0_web_proto_rawDescOnce.Do(func() { + file_opencloud_services_web_v0_web_proto_rawDescData = protoimpl.X.CompressGZIP(file_opencloud_services_web_v0_web_proto_rawDescData) + }) + return file_opencloud_services_web_v0_web_proto_rawDescData +} + +var file_opencloud_services_web_v0_web_proto_msgTypes = make([]protoimpl.MessageInfo, 6) +var file_opencloud_services_web_v0_web_proto_goTypes = []interface{}{ + (*ThemeAddRequest)(nil), // 0: opencloud.services.web.v0.ThemeAddRequest + (*ThemeAddResponse)(nil), // 1: opencloud.services.web.v0.ThemeAddResponse + (*ThemeExistsRequest)(nil), // 2: opencloud.services.web.v0.ThemeExistsRequest + (*ThemeExistsResponse)(nil), // 3: opencloud.services.web.v0.ThemeExistsResponse + (*ThemeRemoveRequest)(nil), // 4: opencloud.services.web.v0.ThemeRemoveRequest + (*ThemeRemoveResponse)(nil), // 5: opencloud.services.web.v0.ThemeRemoveResponse +} +var file_opencloud_services_web_v0_web_proto_depIdxs = []int32{ + 0, // 0: opencloud.services.web.v0.WebService.ThemeAdd:input_type -> opencloud.services.web.v0.ThemeAddRequest + 2, // 1: opencloud.services.web.v0.WebService.ThemeExists:input_type -> opencloud.services.web.v0.ThemeExistsRequest + 4, // 2: opencloud.services.web.v0.WebService.ThemeRemove:input_type -> opencloud.services.web.v0.ThemeRemoveRequest + 1, // 3: opencloud.services.web.v0.WebService.ThemeAdd:output_type -> opencloud.services.web.v0.ThemeAddResponse + 3, // 4: opencloud.services.web.v0.WebService.ThemeExists:output_type -> opencloud.services.web.v0.ThemeExistsResponse + 5, // 5: opencloud.services.web.v0.WebService.ThemeRemove:output_type -> opencloud.services.web.v0.ThemeRemoveResponse + 3, // [3:6] is the sub-list for method output_type + 0, // [0:3] 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_opencloud_services_web_v0_web_proto_init() } +func file_opencloud_services_web_v0_web_proto_init() { + if File_opencloud_services_web_v0_web_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_opencloud_services_web_v0_web_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ThemeAddRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_opencloud_services_web_v0_web_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ThemeAddResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_opencloud_services_web_v0_web_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ThemeExistsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_opencloud_services_web_v0_web_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ThemeExistsResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_opencloud_services_web_v0_web_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ThemeRemoveRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_opencloud_services_web_v0_web_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ThemeRemoveResponse); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_opencloud_services_web_v0_web_proto_rawDesc, + NumEnums: 0, + NumMessages: 6, + NumExtensions: 0, + NumServices: 1, + }, + GoTypes: file_opencloud_services_web_v0_web_proto_goTypes, + DependencyIndexes: file_opencloud_services_web_v0_web_proto_depIdxs, + MessageInfos: file_opencloud_services_web_v0_web_proto_msgTypes, + }.Build() + File_opencloud_services_web_v0_web_proto = out.File + file_opencloud_services_web_v0_web_proto_rawDesc = nil + file_opencloud_services_web_v0_web_proto_goTypes = nil + file_opencloud_services_web_v0_web_proto_depIdxs = nil +} diff --git a/protogen/gen/opencloud/services/web/v0/web.pb.micro.go b/protogen/gen/opencloud/services/web/v0/web.pb.micro.go new file mode 100644 index 0000000000..4e351b033e --- /dev/null +++ b/protogen/gen/opencloud/services/web/v0/web.pb.micro.go @@ -0,0 +1,122 @@ +// Code generated by protoc-gen-micro. DO NOT EDIT. +// source: opencloud/services/web/v0/web.proto + +package v0 + +import ( + fmt "fmt" + _ "github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options" + proto "google.golang.org/protobuf/proto" + math "math" +) + +import ( + context "context" + api "go-micro.dev/v4/api" + client "go-micro.dev/v4/client" + server "go-micro.dev/v4/server" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// Reference imports to suppress errors if they are not otherwise used. +var _ api.Endpoint +var _ context.Context +var _ client.Option +var _ server.Option + +// Api Endpoints for WebService service + +func NewWebServiceEndpoints() []*api.Endpoint { + return []*api.Endpoint{} +} + +// Client API for WebService service + +type WebService interface { + ThemeAdd(ctx context.Context, in *ThemeAddRequest, opts ...client.CallOption) (*ThemeAddResponse, error) + ThemeExists(ctx context.Context, in *ThemeExistsRequest, opts ...client.CallOption) (*ThemeExistsResponse, error) + ThemeRemove(ctx context.Context, in *ThemeRemoveRequest, opts ...client.CallOption) (*ThemeRemoveResponse, error) +} + +type webService struct { + c client.Client + name string +} + +func NewWebService(name string, c client.Client) WebService { + return &webService{ + c: c, + name: name, + } +} + +func (c *webService) ThemeAdd(ctx context.Context, in *ThemeAddRequest, opts ...client.CallOption) (*ThemeAddResponse, error) { + req := c.c.NewRequest(c.name, "WebService.ThemeAdd", in) + out := new(ThemeAddResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webService) ThemeExists(ctx context.Context, in *ThemeExistsRequest, opts ...client.CallOption) (*ThemeExistsResponse, error) { + req := c.c.NewRequest(c.name, "WebService.ThemeExists", in) + out := new(ThemeExistsResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *webService) ThemeRemove(ctx context.Context, in *ThemeRemoveRequest, opts ...client.CallOption) (*ThemeRemoveResponse, error) { + req := c.c.NewRequest(c.name, "WebService.ThemeRemove", in) + out := new(ThemeRemoveResponse) + err := c.c.Call(ctx, req, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// Server API for WebService service + +type WebServiceHandler interface { + ThemeAdd(context.Context, *ThemeAddRequest, *ThemeAddResponse) error + ThemeExists(context.Context, *ThemeExistsRequest, *ThemeExistsResponse) error + ThemeRemove(context.Context, *ThemeRemoveRequest, *ThemeRemoveResponse) error +} + +func RegisterWebServiceHandler(s server.Server, hdlr WebServiceHandler, opts ...server.HandlerOption) error { + type webService interface { + ThemeAdd(ctx context.Context, in *ThemeAddRequest, out *ThemeAddResponse) error + ThemeExists(ctx context.Context, in *ThemeExistsRequest, out *ThemeExistsResponse) error + ThemeRemove(ctx context.Context, in *ThemeRemoveRequest, out *ThemeRemoveResponse) error + } + type WebService struct { + webService + } + h := &webServiceHandler{hdlr} + return s.Handle(s.NewHandler(&WebService{h}, opts...)) +} + +type webServiceHandler struct { + WebServiceHandler +} + +func (h *webServiceHandler) ThemeAdd(ctx context.Context, in *ThemeAddRequest, out *ThemeAddResponse) error { + return h.WebServiceHandler.ThemeAdd(ctx, in, out) +} + +func (h *webServiceHandler) ThemeExists(ctx context.Context, in *ThemeExistsRequest, out *ThemeExistsResponse) error { + return h.WebServiceHandler.ThemeExists(ctx, in, out) +} + +func (h *webServiceHandler) ThemeRemove(ctx context.Context, in *ThemeRemoveRequest, out *ThemeRemoveResponse) error { + return h.WebServiceHandler.ThemeRemove(ctx, in, out) +} diff --git a/protogen/gen/opencloud/services/web/v0/web.swagger.json b/protogen/gen/opencloud/services/web/v0/web.swagger.json new file mode 100644 index 0000000000..2e48770b69 --- /dev/null +++ b/protogen/gen/opencloud/services/web/v0/web.swagger.json @@ -0,0 +1,80 @@ +{ + "swagger": "2.0", + "info": { + "title": "OpenCloud web", + "version": "1.0.0", + "contact": { + "name": "OpenCloud GmbH", + "url": "https://github.com/opencloud-eu/opencloud", + "email": "support@opencloud.eu" + }, + "license": { + "name": "Apache-2.0", + "url": "https://github.com/opencloud-eu/opencloud/blob/main/LICENSE" + } + }, + "tags": [ + { + "name": "WebService" + } + ], + "schemes": [ + "http", + "https" + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": {}, + "definitions": { + "protobufAny": { + "type": "object", + "properties": { + "@type": { + "type": "string" + } + }, + "additionalProperties": {} + }, + "rpcStatus": { + "type": "object", + "properties": { + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/protobufAny" + } + } + } + }, + "v0ThemeAddResponse": { + "type": "object" + }, + "v0ThemeExistsResponse": { + "type": "object", + "properties": { + "exists": { + "type": "boolean", + "title": "Indicates if the theme exists" + } + } + }, + "v0ThemeRemoveResponse": { + "type": "object" + } + }, + "externalDocs": { + "description": "Developer Manual", + "url": "https://docs.opencloud.eu/services/web/" + } +} diff --git a/protogen/proto/buf.gen.yaml b/protogen/proto/buf.gen.yaml index 1e7689dce4..adca608319 100644 --- a/protogen/proto/buf.gen.yaml +++ b/protogen/proto/buf.gen.yaml @@ -25,6 +25,7 @@ plugins: opencloud.services.eventhistory.v0;\ opencloud.messages.eventhistory.v0;\ opencloud.services.policies.v0;\ + opencloud.services.web.v0;\ opencloud.messages.policies.v0" - name: openapiv2 diff --git a/protogen/proto/opencloud/services/web/v0/web.proto b/protogen/proto/opencloud/services/web/v0/web.proto new file mode 100644 index 0000000000..46da4b2a57 --- /dev/null +++ b/protogen/proto/opencloud/services/web/v0/web.proto @@ -0,0 +1,58 @@ +syntax = "proto3"; + +package opencloud.services.web.v0; + +option go_package = "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/web/v0"; + +import "protoc-gen-openapiv2/options/annotations.proto"; + +option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = { + info: { + title: "OpenCloud web"; + version: "1.0.0"; + contact: { + name: "OpenCloud GmbH"; + url: "https://github.com/opencloud-eu/opencloud"; + email: "support@opencloud.eu"; + }; + license: { + name: "Apache-2.0"; + url: "https://github.com/opencloud-eu/opencloud/blob/main/LICENSE"; + }; + }; + schemes: HTTP; + schemes: HTTPS; + consumes: "application/json"; + produces: "application/json"; + external_docs: { + description: "Developer Manual"; + url: "https://docs.opencloud.eu/services/web/"; + }; +}; + +service WebService { + rpc ThemeAdd(ThemeAddRequest) returns (ThemeAddResponse); + rpc ThemeExists(ThemeExistsRequest) returns (ThemeExistsResponse); + rpc ThemeRemove(ThemeRemoveRequest) returns (ThemeRemoveResponse); +} + +message ThemeAddRequest { + string id = 1; // The ID of the theme to add + bytes data = 2; // The theme data in bytes +} + +message ThemeAddResponse {} + +message ThemeExistsRequest { + string id = 1; // The ID of the theme to check +} + +message ThemeExistsResponse { + bool exists = 1; // Indicates if the theme exists +} + +message ThemeRemoveRequest { + string id = 1; // The ID of the theme to remove +} + +message ThemeRemoveResponse {} diff --git a/services/console/.mockery.yaml b/services/console/.mockery.yaml new file mode 100644 index 0000000000..029be12592 --- /dev/null +++ b/services/console/.mockery.yaml @@ -0,0 +1,15 @@ +# maintain v2 separate mocks dir +dir: "{{.InterfaceDir}}/mocks" +structname: "{{.InterfaceName}}" +filename: "{{.InterfaceName | snakecase }}.go" +pkgname: mocks + +template: testify +packages: + github.com/opencloud-eu/opencloud/services/console/pkg/web: + config: + dir: mocks + interfaces: + Service: {} + Repository: {} + ConsoleRepository: {} diff --git a/services/console/Makefile b/services/console/Makefile new file mode 100644 index 0000000000..c1e60e5846 --- /dev/null +++ b/services/console/Makefile @@ -0,0 +1,16 @@ +SHELL := bash +NAME := console + +ifneq (, $(shell command -v go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI +include ../../.bingo/Variables.mk +endif + +include ../../.make/default.mk +include ../../.make/go.mk +include ../../.make/release.mk +include ../../.make/docs.mk + + +.PHONY: go-generate +go-generate: $(MOCKERY) + $(MOCKERY) diff --git a/services/console/mocks/console_repository.go b/services/console/mocks/console_repository.go new file mode 100644 index 0000000000..6b8ec6170b --- /dev/null +++ b/services/console/mocks/console_repository.go @@ -0,0 +1,101 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "context" + "io" + + mock "github.com/stretchr/testify/mock" +) + +// NewConsoleRepository creates a new instance of ConsoleRepository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewConsoleRepository(t interface { + mock.TestingT + Cleanup(func()) +}) *ConsoleRepository { + mock := &ConsoleRepository{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// ConsoleRepository is an autogenerated mock type for the ConsoleRepository type +type ConsoleRepository struct { + mock.Mock +} + +type ConsoleRepository_Expecter struct { + mock *mock.Mock +} + +func (_m *ConsoleRepository) EXPECT() *ConsoleRepository_Expecter { + return &ConsoleRepository_Expecter{mock: &_m.Mock} +} + +// ThemeGet provides a mock function for the type ConsoleRepository +func (_mock *ConsoleRepository) ThemeGet(ctx context.Context) (io.ReadCloser, error) { + ret := _mock.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for ThemeGet") + } + + var r0 io.ReadCloser + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context) (io.ReadCloser, error)); ok { + return returnFunc(ctx) + } + if returnFunc, ok := ret.Get(0).(func(context.Context) io.ReadCloser); ok { + r0 = returnFunc(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + if returnFunc, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = returnFunc(ctx) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// ConsoleRepository_ThemeGet_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ThemeGet' +type ConsoleRepository_ThemeGet_Call struct { + *mock.Call +} + +// ThemeGet is a helper method to define mock.On call +// - ctx context.Context +func (_e *ConsoleRepository_Expecter) ThemeGet(ctx interface{}) *ConsoleRepository_ThemeGet_Call { + return &ConsoleRepository_ThemeGet_Call{Call: _e.mock.On("ThemeGet", ctx)} +} + +func (_c *ConsoleRepository_ThemeGet_Call) Run(run func(ctx context.Context)) *ConsoleRepository_ThemeGet_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *ConsoleRepository_ThemeGet_Call) Return(readCloser io.ReadCloser, err error) *ConsoleRepository_ThemeGet_Call { + _c.Call.Return(readCloser, err) + return _c +} + +func (_c *ConsoleRepository_ThemeGet_Call) RunAndReturn(run func(ctx context.Context) (io.ReadCloser, error)) *ConsoleRepository_ThemeGet_Call { + _c.Call.Return(run) + return _c +} diff --git a/services/console/mocks/repository.go b/services/console/mocks/repository.go new file mode 100644 index 0000000000..8f47fc0014 --- /dev/null +++ b/services/console/mocks/repository.go @@ -0,0 +1,225 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "context" + "io" + + mock "github.com/stretchr/testify/mock" +) + +// NewRepository creates a new instance of Repository. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewRepository(t interface { + mock.TestingT + Cleanup(func()) +}) *Repository { + mock := &Repository{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// Repository is an autogenerated mock type for the Repository type +type Repository struct { + mock.Mock +} + +type Repository_Expecter struct { + mock *mock.Mock +} + +func (_m *Repository) EXPECT() *Repository_Expecter { + return &Repository_Expecter{mock: &_m.Mock} +} + +// ThemeAdd provides a mock function for the type Repository +func (_mock *Repository) ThemeAdd(ctx context.Context, id string, r io.Reader) error { + ret := _mock.Called(ctx, id, r) + + if len(ret) == 0 { + panic("no return value specified for ThemeAdd") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string, io.Reader) error); ok { + r0 = returnFunc(ctx, id, r) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// Repository_ThemeAdd_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ThemeAdd' +type Repository_ThemeAdd_Call struct { + *mock.Call +} + +// ThemeAdd is a helper method to define mock.On call +// - ctx context.Context +// - id string +// - r io.Reader +func (_e *Repository_Expecter) ThemeAdd(ctx interface{}, id interface{}, r interface{}) *Repository_ThemeAdd_Call { + return &Repository_ThemeAdd_Call{Call: _e.mock.On("ThemeAdd", ctx, id, r)} +} + +func (_c *Repository_ThemeAdd_Call) Run(run func(ctx context.Context, id string, r io.Reader)) *Repository_ThemeAdd_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + var arg2 io.Reader + if args[2] != nil { + arg2 = args[2].(io.Reader) + } + run( + arg0, + arg1, + arg2, + ) + }) + return _c +} + +func (_c *Repository_ThemeAdd_Call) Return(err error) *Repository_ThemeAdd_Call { + _c.Call.Return(err) + return _c +} + +func (_c *Repository_ThemeAdd_Call) RunAndReturn(run func(ctx context.Context, id string, r io.Reader) error) *Repository_ThemeAdd_Call { + _c.Call.Return(run) + return _c +} + +// ThemeExists provides a mock function for the type Repository +func (_mock *Repository) ThemeExists(ctx context.Context, id string) (bool, error) { + ret := _mock.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for ThemeExists") + } + + var r0 bool + var r1 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string) (bool, error)); ok { + return returnFunc(ctx, id) + } + if returnFunc, ok := ret.Get(0).(func(context.Context, string) bool); ok { + r0 = returnFunc(ctx, id) + } else { + r0 = ret.Get(0).(bool) + } + if returnFunc, ok := ret.Get(1).(func(context.Context, string) error); ok { + r1 = returnFunc(ctx, id) + } else { + r1 = ret.Error(1) + } + return r0, r1 +} + +// Repository_ThemeExists_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ThemeExists' +type Repository_ThemeExists_Call struct { + *mock.Call +} + +// ThemeExists is a helper method to define mock.On call +// - ctx context.Context +// - id string +func (_e *Repository_Expecter) ThemeExists(ctx interface{}, id interface{}) *Repository_ThemeExists_Call { + return &Repository_ThemeExists_Call{Call: _e.mock.On("ThemeExists", ctx, id)} +} + +func (_c *Repository_ThemeExists_Call) Run(run func(ctx context.Context, id string)) *Repository_ThemeExists_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *Repository_ThemeExists_Call) Return(b bool, err error) *Repository_ThemeExists_Call { + _c.Call.Return(b, err) + return _c +} + +func (_c *Repository_ThemeExists_Call) RunAndReturn(run func(ctx context.Context, id string) (bool, error)) *Repository_ThemeExists_Call { + _c.Call.Return(run) + return _c +} + +// ThemeRemove provides a mock function for the type Repository +func (_mock *Repository) ThemeRemove(ctx context.Context, id string) error { + ret := _mock.Called(ctx, id) + + if len(ret) == 0 { + panic("no return value specified for ThemeRemove") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context, string) error); ok { + r0 = returnFunc(ctx, id) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// Repository_ThemeRemove_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ThemeRemove' +type Repository_ThemeRemove_Call struct { + *mock.Call +} + +// ThemeRemove is a helper method to define mock.On call +// - ctx context.Context +// - id string +func (_e *Repository_Expecter) ThemeRemove(ctx interface{}, id interface{}) *Repository_ThemeRemove_Call { + return &Repository_ThemeRemove_Call{Call: _e.mock.On("ThemeRemove", ctx, id)} +} + +func (_c *Repository_ThemeRemove_Call) Run(run func(ctx context.Context, id string)) *Repository_ThemeRemove_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + var arg1 string + if args[1] != nil { + arg1 = args[1].(string) + } + run( + arg0, + arg1, + ) + }) + return _c +} + +func (_c *Repository_ThemeRemove_Call) Return(err error) *Repository_ThemeRemove_Call { + _c.Call.Return(err) + return _c +} + +func (_c *Repository_ThemeRemove_Call) RunAndReturn(run func(ctx context.Context, id string) error) *Repository_ThemeRemove_Call { + _c.Call.Return(run) + return _c +} diff --git a/services/console/mocks/service.go b/services/console/mocks/service.go new file mode 100644 index 0000000000..222afd015b --- /dev/null +++ b/services/console/mocks/service.go @@ -0,0 +1,140 @@ +// Code generated by mockery; DO NOT EDIT. +// github.com/vektra/mockery +// template: testify + +package mocks + +import ( + "context" + + mock "github.com/stretchr/testify/mock" +) + +// NewService creates a new instance of Service. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewService(t interface { + mock.TestingT + Cleanup(func()) +}) *Service { + mock := &Service{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} + +// Service is an autogenerated mock type for the Service type +type Service struct { + mock.Mock +} + +type Service_Expecter struct { + mock *mock.Mock +} + +func (_m *Service) EXPECT() *Service_Expecter { + return &Service_Expecter{mock: &_m.Mock} +} + +// ThemeApply provides a mock function for the type Service +func (_mock *Service) ThemeApply(context1 context.Context) error { + ret := _mock.Called(context1) + + if len(ret) == 0 { + panic("no return value specified for ThemeApply") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = returnFunc(context1) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// Service_ThemeApply_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ThemeApply' +type Service_ThemeApply_Call struct { + *mock.Call +} + +// ThemeApply is a helper method to define mock.On call +// - context1 context.Context +func (_e *Service_Expecter) ThemeApply(context1 interface{}) *Service_ThemeApply_Call { + return &Service_ThemeApply_Call{Call: _e.mock.On("ThemeApply", context1)} +} + +func (_c *Service_ThemeApply_Call) Run(run func(context1 context.Context)) *Service_ThemeApply_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *Service_ThemeApply_Call) Return(err error) *Service_ThemeApply_Call { + _c.Call.Return(err) + return _c +} + +func (_c *Service_ThemeApply_Call) RunAndReturn(run func(context1 context.Context) error) *Service_ThemeApply_Call { + _c.Call.Return(run) + return _c +} + +// ThemeRemove provides a mock function for the type Service +func (_mock *Service) ThemeRemove(context1 context.Context) error { + ret := _mock.Called(context1) + + if len(ret) == 0 { + panic("no return value specified for ThemeRemove") + } + + var r0 error + if returnFunc, ok := ret.Get(0).(func(context.Context) error); ok { + r0 = returnFunc(context1) + } else { + r0 = ret.Error(0) + } + return r0 +} + +// Service_ThemeRemove_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ThemeRemove' +type Service_ThemeRemove_Call struct { + *mock.Call +} + +// ThemeRemove is a helper method to define mock.On call +// - context1 context.Context +func (_e *Service_Expecter) ThemeRemove(context1 interface{}) *Service_ThemeRemove_Call { + return &Service_ThemeRemove_Call{Call: _e.mock.On("ThemeRemove", context1)} +} + +func (_c *Service_ThemeRemove_Call) Run(run func(context1 context.Context)) *Service_ThemeRemove_Call { + _c.Call.Run(func(args mock.Arguments) { + var arg0 context.Context + if args[0] != nil { + arg0 = args[0].(context.Context) + } + run( + arg0, + ) + }) + return _c +} + +func (_c *Service_ThemeRemove_Call) Return(err error) *Service_ThemeRemove_Call { + _c.Call.Return(err) + return _c +} + +func (_c *Service_ThemeRemove_Call) RunAndReturn(run func(context1 context.Context) error) *Service_ThemeRemove_Call { + _c.Call.Return(run) + return _c +} diff --git a/services/console/pkg/command/command.go b/services/console/pkg/command/command.go new file mode 100644 index 0000000000..3328f31049 --- /dev/null +++ b/services/console/pkg/command/command.go @@ -0,0 +1,15 @@ +package command + +import ( + "github.com/spf13/cobra" + + "github.com/opencloud-eu/opencloud/pkg/config/configlog" + "github.com/opencloud-eu/opencloud/services/console/pkg/config" + "github.com/opencloud-eu/opencloud/services/console/pkg/config/parser" +) + +func preRunE(cfg *config.Config) func(cmd *cobra.Command, args []string) error { + return func(cmd *cobra.Command, args []string) error { + return configlog.ReturnError(parser.ParseConfig(cfg)) + } +} diff --git a/services/console/pkg/command/health.go b/services/console/pkg/command/health.go new file mode 100644 index 0000000000..74c3c62129 --- /dev/null +++ b/services/console/pkg/command/health.go @@ -0,0 +1,19 @@ +package command + +import ( + "github.com/spf13/cobra" + + "github.com/opencloud-eu/opencloud/services/console/pkg/config" +) + +// Health is the entrypoint for the health command. +func Health(cfg *config.Config) *cobra.Command { + return &cobra.Command{ + Use: "health", + Short: "check health status", + PreRunE: preRunE(cfg), + RunE: func(cmd *cobra.Command, args []string) error { + return nil // toDo + }, + } +} diff --git a/services/console/pkg/command/root.go b/services/console/pkg/command/root.go new file mode 100644 index 0000000000..88197e0b55 --- /dev/null +++ b/services/console/pkg/command/root.go @@ -0,0 +1,31 @@ +package command + +import ( + "os" + + "github.com/opencloud-eu/opencloud/pkg/clihelper" + "github.com/opencloud-eu/opencloud/services/console/pkg/config" + + "github.com/spf13/cobra" +) + +// GetCommands provides all commands for this service +func GetCommands(cfg *config.Config) []*cobra.Command { + return []*cobra.Command{ + Update(cfg), + Health(cfg), + Version(cfg), + } +} + +// Execute is the entry point for the web command. +func Execute(cfg *config.Config) error { + app := clihelper.DefaultApp(&cobra.Command{ + Use: "console", + Short: "OpenCloud console", + }) + app.AddCommand(GetCommands(cfg)...) + app.SetArgs(os.Args[1:]) + + return app.ExecuteContext(cfg.Context) +} diff --git a/services/console/pkg/command/update.go b/services/console/pkg/command/update.go new file mode 100644 index 0000000000..99b6287b62 --- /dev/null +++ b/services/console/pkg/command/update.go @@ -0,0 +1,185 @@ +package command + +import ( + "fmt" + + "github.com/centrifugal/centrifuge-go" + "github.com/golang-jwt/jwt/v5" + "github.com/spf13/cobra" + + "github.com/opencloud-eu/opencloud/pkg/generators" + websvc "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/web/v0" + "github.com/opencloud-eu/opencloud/services/console/pkg/config" + "github.com/opencloud-eu/opencloud/services/console/pkg/console" + "github.com/opencloud-eu/opencloud/services/console/pkg/console/remote" + "github.com/opencloud-eu/opencloud/services/console/pkg/web" + "github.com/opencloud-eu/reva/v2/pkg/events/stream" +) + +func Update(cfg *config.Config) *cobra.Command { + connectCmd := &cobra.Command{ + Use: "update", + Short: "update instance related console settings", + } + + subscribeCmd := &cobra.Command{ + Use: "subscribe", + Short: "get updates automatically", + PreRunE: preRunE(cfg), + RunE: func(cmd *cobra.Command, args []string) error { + env, err := newEnvironment(cfg) + if err != nil { + return fmt.Errorf("failed to build environment: %w", err) + } + + client, err := remote.NewCentrifugoSubscription(remote.CentrifugoSubscriptionOptions{ + Token: env.token, + URL: "ws://host.docker.internal:8000/connection/websocket", + Claims: env.claims, + CentrifugeConfig: centrifuge.Config{ + Token: env.token.Raw, + }, + CentrifugeSubscriptionConfig: centrifuge.SubscriptionConfig{ + Recoverable: true, + JoinLeave: true, + }, + }) + if err != nil { + return fmt.Errorf("failed to create client: %w", err) + } + defer func() { + _ = client.Close() + }() + + handler := remote.Handler{ + ThemeAssigned: func(m remote.Message[remote.MessagePayloadThemeAssigned]) error { + return env.webService.ThemeApply(cmd.Context()) + }, + ThemeUnassigned: func(m remote.Message[struct{}]) error { + return env.webService.ThemeRemove(cmd.Context()) + }, + } + + if err := client.Handle(handler); err != nil { + return fmt.Errorf("failed to subscribe: %w", err) + } + + <-cmd.Context().Done() + + return nil + }, + } + + pollCmd := &cobra.Command{ + Use: "poll", + Short: "get updates periodically", + PreRunE: preRunE(cfg), + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println("todo") + return nil + }, + } + + runCmd := &cobra.Command{ + Use: "run", + Short: "run update related commands manually", + } + + { + webThemeGetCmd := &cobra.Command{ + Use: "web-theme-get", + Short: "download and apply configured console web theme", + PreRunE: preRunE(cfg), + RunE: func(cmd *cobra.Command, args []string) error { + env, err := newEnvironment(cfg) + if err != nil { + return fmt.Errorf("failed to build environment: %w", err) + } + + if err := env.webService.ThemeApply(cmd.Context()); err != nil { + return fmt.Errorf("failed to apply theme: %w", err) + } + + return nil + }, + } + + runCmd.AddCommand( + webThemeGetCmd, + ) + } + + connectCmd.AddCommand( + runCmd, + subscribeCmd, + pollCmd, + ) + + return connectCmd +} + +type environment struct { + token *jwt.Token + claims *console.Claims + webService web.Service +} + +func newEnvironment(cfg *config.Config) (environment, error) { + grpcClient, err := console.NewGRPCClient(cfg.Context, cfg.Commons.TracesExporter, cfg.Service.Name, cfg.GRPCClientTLS) + if err != nil { + return environment{}, err + } + + token, claims, err := console.ParseUnverifiedJWTToken(cfg.RemoteConsole.JWTToken) + if err != nil { + return environment{}, err + } + + consoleRepository, err := remote.NewHTTPRepository(remote.HTTPRepositoryOptions{ + Client: console.DefaultHTTPClient, + Token: token, + Claims: claims, + URL: claims.Issuer, + }) + if err != nil { + return environment{}, fmt.Errorf("failed to create console repository: %w", err) + } + + webRepository, err := web.NewGRPCRepository(web.GRPCRepositoryOptions{ + WebService: websvc.NewWebService("eu.opencloud.api.web", grpcClient), + }) + if err != nil { + return environment{}, fmt.Errorf("failed to create web repository: %w", err) + } + + eventStream, err := stream.NatsFromConfig( + generators.GenerateConnectionName(cfg.Service.Name, generators.NTypeBus), + false, + stream.NatsConfig(cfg.Events), + ) + if err != nil { + return environment{}, err + } + + webSSEService, err := web.NewSSEService(web.SSEServiceOptions{ + EventStream: eventStream, + }) + if err != nil { + return environment{}, fmt.Errorf("failed to create web service: %w", err) + } + + webCoreService, err := web.NewCoreService(web.CoreServiceOptions{ + Repository: webRepository, + ConsoleRepository: consoleRepository, + Next: webSSEService, + }) + if err != nil { + return environment{}, fmt.Errorf("failed to create web service: %w", err) + } + + return environment{ + webService: webCoreService, + token: token, + claims: claims, + }, nil +} diff --git a/services/console/pkg/command/version.go b/services/console/pkg/command/version.go new file mode 100644 index 0000000000..02de50d9f1 --- /dev/null +++ b/services/console/pkg/command/version.go @@ -0,0 +1,51 @@ +package command + +import ( + "fmt" + "os" + + "github.com/opencloud-eu/opencloud/pkg/registry" + "github.com/opencloud-eu/opencloud/pkg/version" + "github.com/opencloud-eu/opencloud/services/console/pkg/config" + + "github.com/olekukonko/tablewriter" + "github.com/olekukonko/tablewriter/tw" + "github.com/spf13/cobra" +) + +// Version prints the service versions of all running instances. +func Version(cfg *config.Config) *cobra.Command { + return &cobra.Command{ + Use: "version", + Short: "print the version of this binary and the running service instances", + RunE: func(cmd *cobra.Command, args []string) error { + fmt.Println("Version: " + version.GetString()) + fmt.Printf("Compiled: %s\n", version.Compiled()) + fmt.Println("") + + reg := registry.GetRegistry() + services, err := reg.GetService(cfg.GRPC.Namespace + "." + cfg.Service.Name) + if err != nil { + fmt.Println(fmt.Errorf("could not get %s services from the registry: %v", cfg.Service.Name, err)) + return err + } + + if len(services) == 0 { + fmt.Println("No running " + cfg.Service.Name + " service found.") + return nil + } + + table := tablewriter.NewTable(os.Stdout, tablewriter.WithHeaderAutoFormat(tw.Off)) + table.Header([]string{"Version", "Address", "Id"}) + for _, s := range services { + for _, n := range s.Nodes { + if err := table.Append([]string{s.Version, n.Address, n.Id}); err != nil { + return err + } + } + } + + return table.Render() + }, + } +} diff --git a/services/console/pkg/config/config.go b/services/console/pkg/config/config.go new file mode 100644 index 0000000000..abd9cd22b2 --- /dev/null +++ b/services/console/pkg/config/config.go @@ -0,0 +1,69 @@ +package config + +import ( + "context" + + "go-micro.dev/v4/client" + + "github.com/opencloud-eu/opencloud/pkg/shared" +) + +// Config combines all available configuration parts. +type Config struct { + Commons *shared.Commons `yaml:"-"` // don't use this directly as configuration for a service + + Service Service `yaml:"-"` + + LogLevel string `yaml:"loglevel" env:"OC_LOG_LEVEL;THUMBNAILS_LOG_LEVEL" desc:"The log level. Valid values are: 'panic', 'fatal', 'error', 'warn', 'info', 'debug', 'trace'." introductionVersion:"1.0.0"` + Debug Debug `yaml:"debug"` + + GRPC GRPCConfig `yaml:"grpc"` + + GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"` + GrpcClient client.Client `yaml:"-"` + Events Events `yaml:"events"` + + RemoteConsole *ConsoleRemote `yaml:"remote"` + + Context context.Context `yaml:"-"` +} + +// Service defines the available service configuration. +type Service struct { + Name string `yaml:"-"` +} + +// Debug defines the available debug configuration. +type Debug struct { + Addr string `yaml:"addr" env:"CONSOLE_DEBUG_ADDR" desc:"Bind address of the debug server, where metrics, health, config and debug endpoints will be exposed." introductionVersion:"%%NEXT%%"` + Token string `yaml:"token" env:"CONSOLE_DEBUG_TOKEN" desc:"Token to secure the metrics endpoint." introductionVersion:"%%NEXT%%"` + Pprof bool `yaml:"pprof" env:"CONSOLE_DEBUG_PPROF" desc:"Enables pprof, which can be used for profiling." introductionVersion:"%%NEXT%%"` + Zpages bool `yaml:"zpages" env:"CONSOLE_DEBUG_ZPAGES" desc:"Enables zpages, which can be used for collecting and viewing in-memory traces." introductionVersion:"%%NEXT%%"` +} + +// GRPCConfig defines the available grpc configuration. +type GRPCConfig struct { + Disabled bool `yaml:"disabled" env:"CONSOLE_GRPC_DISABLED" desc:"Disables the GRPC service. Set this to true if the service should only handle events." introductionVersion:"%%NEXT%%"` + Addr string `yaml:"addr" env:"CONSOLE_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"%%NEXT%%"` + Namespace string `yaml:"-"` + TLS *shared.GRPCServiceTLS `yaml:"tls"` +} + +// Tracing defines the available tracing configuration. +type Tracing struct { + Enabled bool `yaml:"enabled" env:"OC_TRACING_ENABLED;CONSOLE_TRACING_ENABLED" desc:"Activates tracing." introductionVersion:"%%NEXT%%"` + Type string `yaml:"type" env:"OC_TRACING_TYPE;CONSOLE_TRACING_TYPE" desc:"The type of tracing. Defaults to '', which is the same as 'jaeger'. Allowed tracing types are 'jaeger' and '' as of now." introductionVersion:"%%NEXT%%"` + Endpoint string `yaml:"endpoint" env:"OC_TRACING_ENDPOINT;CONSOLE_TRACING_ENDPOINT" desc:"The endpoint of the tracing agent." introductionVersion:"%%NEXT%%"` + Collector string `yaml:"collector" env:"OC_TRACING_COLLECTOR;CONSOLE_TRACING_COLLECTOR" desc:"The HTTP endpoint for sending spans directly to a collector, i.e. http://jaeger-collector:14268/api/traces. Only used if the tracing endpoint is unset." introductionVersion:"%%NEXT%%"` +} + +// Events combines the configuration options for the event bus. +type Events struct { + Endpoint string `yaml:"endpoint" env:"OC_EVENTS_ENDPOINT;CONSOLE_EVENTS_ENDPOINT" desc:"The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture." introductionVersion:"1.0.0"` + Cluster string `yaml:"cluster" env:"OC_EVENTS_CLUSTER;CONSOLE_EVENTS_CLUSTER" desc:"The clusterID of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. Mandatory when using NATS as event system." introductionVersion:"1.0.0"` + TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_EVENTS_TLS_INSECURE;CONSOLE_EVENTS_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"1.0.0"` + TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_EVENTS_TLS_ROOT_CA_CERTIFICATE;CONSOLE_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided NOTIFICATIONS_EVENTS_TLS_INSECURE will be seen as false." introductionVersion:"1.0.0"` + EnableTLS bool `yaml:"enable_tls" env:"OC_EVENTS_ENABLE_TLS;CONSOLE_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"1.0.0"` + AuthUsername string `yaml:"username" env:"OC_EVENTS_AUTH_USERNAME;CONSOLE_EVENTS_AUTH_USERNAME" desc:"The username to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"1.0.0"` + AuthPassword string `yaml:"password" env:"OC_EVENTS_AUTH_PASSWORD;CONSOLE_EVENTS_AUTH_PASSWORD" desc:"The password to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"1.0.0"` +} diff --git a/services/console/pkg/config/console.go b/services/console/pkg/config/console.go new file mode 100644 index 0000000000..24359bee56 --- /dev/null +++ b/services/console/pkg/config/console.go @@ -0,0 +1,5 @@ +package config + +type ConsoleRemote struct { + JWTToken string `yaml:"jwt_token" env:"CONSOLE_REMOTE_JWT_TOKEN" desc:"The JWT token used to authenticate requests to the console service." introductionVersion:"%%NEXT%%"` +} diff --git a/services/console/pkg/config/defaults/defaultconfig.go b/services/console/pkg/config/defaults/defaultconfig.go new file mode 100644 index 0000000000..672391fe5b --- /dev/null +++ b/services/console/pkg/config/defaults/defaultconfig.go @@ -0,0 +1,58 @@ +package defaults + +import ( + "github.com/opencloud-eu/opencloud/pkg/structs" + "github.com/opencloud-eu/opencloud/services/console/pkg/config" +) + +// FullDefaultConfig returns a fully initialized default configuration +func FullDefaultConfig() *config.Config { + cfg := DefaultConfig() + EnsureDefaults(cfg) + Sanitize(cfg) + return cfg +} + +// DefaultConfig returns a basic default configuration +func DefaultConfig() *config.Config { + return &config.Config{ + Debug: config.Debug{ + Addr: "127.0.0.1:9225", + Token: "", + }, + GRPC: config.GRPCConfig{ + Addr: "127.0.0.1:9222", + Namespace: "eu.opencloud.api", + }, + Service: config.Service{ + Name: "console", + }, + Events: config.Events{ + Endpoint: "127.0.0.1:9233", + Cluster: "opencloud-cluster", + EnableTLS: false, + }, + } +} + +// EnsureDefaults adds default values to the configuration if they are not set yet +func EnsureDefaults(cfg *config.Config) { + if cfg.LogLevel == "" { + cfg.LogLevel = "error" + } + + if cfg.GRPC.TLS == nil && cfg.Commons != nil { + cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS) + } + + if cfg.RemoteConsole == nil { + cfg.RemoteConsole = &config.ConsoleRemote{} + } +} + +// Sanitize sanitizes the configuration +func Sanitize(cfg *config.Config) { + if cfg.GRPCClientTLS == nil && cfg.Commons != nil { + cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS) + } +} diff --git a/services/console/pkg/config/parser/parse.go b/services/console/pkg/config/parser/parse.go new file mode 100644 index 0000000000..bbc11eb625 --- /dev/null +++ b/services/console/pkg/config/parser/parse.go @@ -0,0 +1,41 @@ +package parser + +import ( + "errors" + + occfg "github.com/opencloud-eu/opencloud/pkg/config" + "github.com/opencloud-eu/opencloud/services/console/pkg/config" + "github.com/opencloud-eu/opencloud/services/console/pkg/config/defaults" + + "github.com/opencloud-eu/opencloud/pkg/config/envdecode" +) + +// ParseConfig loads configuration from known paths. +func ParseConfig(cfg *config.Config) error { + err := occfg.BindSourcesToStructs(cfg.Service.Name, cfg) + if err != nil { + return err + } + + defaults.EnsureDefaults(cfg) + + // load all env variables relevant to the config in the current context. + if err := envdecode.Decode(cfg); err != nil { + // no environment variable set for this config is an expected "error" + if !errors.Is(err, envdecode.ErrNoTargetFieldsAreSet) { + return err + } + } + + defaults.Sanitize(cfg) + + return Validate(cfg) +} + +func Validate(cfg *config.Config) error { + if cfg.RemoteConsole.JWTToken == "" { + return errors.New("jwt_token must be provided in remote console config") + } + + return nil +} diff --git a/services/console/pkg/console/console.go b/services/console/pkg/console/console.go new file mode 100644 index 0000000000..3e495a1ca5 --- /dev/null +++ b/services/console/pkg/console/console.go @@ -0,0 +1,13 @@ +package console + +import ( + "errors" + + "github.com/go-playground/validator/v10" +) + +var ( + Validate = validator.New() + ErrOptionsInvalid = errors.New("options are invalid") + ErrRequest = errors.New("request failed") +) diff --git a/services/console/pkg/console/grpc.go b/services/console/pkg/console/grpc.go new file mode 100644 index 0000000000..ba63c6a1e8 --- /dev/null +++ b/services/console/pkg/console/grpc.go @@ -0,0 +1,30 @@ +package console + +import ( + "context" + + "go-micro.dev/v4/client" + + "github.com/opencloud-eu/opencloud/pkg/service/grpc" + "github.com/opencloud-eu/opencloud/pkg/shared" + + "github.com/opencloud-eu/opencloud/pkg/tracing" +) + +func NewGRPCClient(ctx context.Context, exporter, name string, tlsConfig *shared.GRPCClientTLS) (client.Client, error) { + traceProvider, err := tracing.GetTraceProvider(ctx, exporter, name) + if err != nil { + return nil, err + } + + grpcClient, err := grpc.NewClient( + append(grpc.GetClientOptions(tlsConfig), + grpc.WithTraceProvider(traceProvider), + )..., + ) + if err != nil { + return nil, err + } + + return grpcClient, nil +} diff --git a/services/console/pkg/console/http.go b/services/console/pkg/console/http.go new file mode 100644 index 0000000000..e44664b6bc --- /dev/null +++ b/services/console/pkg/console/http.go @@ -0,0 +1,35 @@ +package console + +import ( + "crypto/tls" + "fmt" + "io" + "net/http" +) + +var DefaultHTTPClient = &http.Client{Transport: func() *http.Transport { + t := http.DefaultTransport.(*http.Transport).Clone() + t.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} + return t +}()} + +type HTTPRequest struct { + *http.Request +} + +func NewHTTPRequest(method, url string, body io.Reader) (*HTTPRequest, error) { + req, err := http.NewRequest(method, url, body) + if err != nil { + return nil, fmt.Errorf("failed to create http request: %w", err) + } + + return &HTTPRequest{req}, nil +} + +func (r *HTTPRequest) SetBearerAuth(bearer string) { + r.Header.Add("Authorization", "Bearer "+bearer) +} + +func (r *HTTPRequest) AsDefault() *http.Request { + return r.Request +} diff --git a/services/console/pkg/console/jwt.go b/services/console/pkg/console/jwt.go new file mode 100644 index 0000000000..10f04aeffb --- /dev/null +++ b/services/console/pkg/console/jwt.go @@ -0,0 +1,24 @@ +package console + +import ( + "fmt" + + "github.com/golang-jwt/jwt/v5" +) + +type Claims struct { + jwt.RegisteredClaims + TenantId string `json:"tenant_id,omitempty"` + InstanceId string `json:"instance_id,omitempty"` +} + +func ParseUnverifiedJWTToken(tokenString string) (*jwt.Token, *Claims, error) { + claims := &Claims{} + + token, _, err := new(jwt.Parser).ParseUnverified(tokenString, claims) + if err != nil { + return nil, nil, fmt.Errorf("failed to parse token: %w", err) + } + + return token, claims, nil +} diff --git a/services/console/pkg/console/remote/remote.go b/services/console/pkg/console/remote/remote.go new file mode 100644 index 0000000000..fbe5b64eba --- /dev/null +++ b/services/console/pkg/console/remote/remote.go @@ -0,0 +1 @@ +package remote diff --git a/services/console/pkg/console/remote/repository.go b/services/console/pkg/console/remote/repository.go new file mode 100644 index 0000000000..6ad7e6efd0 --- /dev/null +++ b/services/console/pkg/console/remote/repository.go @@ -0,0 +1,72 @@ +package remote + +import ( + "context" + "fmt" + "io" + "net/http" + "net/url" + + "github.com/golang-jwt/jwt/v5" + + "github.com/opencloud-eu/opencloud/services/console/pkg/console" +) + +type HTTPRepositoryOptions struct { + Client *http.Client `validate:"required"` + Token *jwt.Token `validate:"required"` + URL string `validate:"required,http_url"` + Claims *console.Claims `validate:"required"` +} + +func (o HTTPRepositoryOptions) Validate() error { + if err := console.Validate.Struct(o); err != nil { + return fmt.Errorf("(%w): %w", console.ErrOptionsInvalid, err) + } + + return nil +} + +type HTTPRepository struct { + client *http.Client + token *jwt.Token + url *url.URL + claims *console.Claims +} + +func NewHTTPRepository(o HTTPRepositoryOptions) (HTTPRepository, error) { + if err := o.Validate(); err != nil { + return HTTPRepository{}, err + } + + u, err := url.Parse(o.URL) + if err != nil { + return HTTPRepository{}, fmt.Errorf("failed to parse console api root url: %v", err) + } + + return HTTPRepository{ + client: o.Client, + token: o.Token, + url: u.JoinPath("api"), + claims: o.Claims, + }, nil +} + +func (r HTTPRepository) ThemeGet(ctx context.Context) (io.ReadCloser, error) { + req, err := console.NewHTTPRequest(http.MethodGet, r.url.JoinPath("deployment", "next-unstable", "theme").String(), nil) + if err != nil { + return nil, fmt.Errorf("failed to create http request: %w", err) + } + req.SetBearerAuth(r.token.Raw) + req.WithContext(ctx) + + res, err := r.client.Do(req.AsDefault()) + switch { + case err != nil: + return nil, fmt.Errorf("(%w) failed to execute http request: %w", console.ErrRequest, err) + case res.StatusCode != http.StatusOK: + return nil, fmt.Errorf("(%w) failed to fetch theme, status code: %d", console.ErrRequest, res.StatusCode) + } + + return res.Body, nil +} diff --git a/services/console/pkg/console/remote/subscription.go b/services/console/pkg/console/remote/subscription.go new file mode 100644 index 0000000000..67784f8a79 --- /dev/null +++ b/services/console/pkg/console/remote/subscription.go @@ -0,0 +1,43 @@ +package remote + +import ( + "encoding/json" + "time" +) + +type Notification any + +type Topic string + +const ( + TopicThemeCreated Topic = "theme.created" + TopicThemeUpdated Topic = "theme.updated" + TopicThemeAssigned Topic = "theme.assigned" + TopicThemeUnassigned Topic = "theme.unassigned" +) + +type Message[P any] struct { + Topic Topic `json:"topic"` + TenantId string `json:"tenantId"` + InstanceId string `json:"instanceId"` + Timestamp time.Time `json:"timestamp"` + Payload P `json:"payload"` +} + +type MessagePayloadThemeAssigned struct { + ThemeId string `json:"themeId"` +} + +func dispatchMessage[T any](h func(message Message[T]) error, b []byte) error { + var message Message[T] + if err := json.Unmarshal(b, &message); err != nil { + return err + } + + return h(message) +} + +type Handler struct { + ThemeAssigned func(Message[MessagePayloadThemeAssigned]) error + ThemeUnassigned func(Message[struct{}]) error +} diff --git a/services/console/pkg/console/remote/subscription_centrifugo.go b/services/console/pkg/console/remote/subscription_centrifugo.go new file mode 100644 index 0000000000..2c4b374096 --- /dev/null +++ b/services/console/pkg/console/remote/subscription_centrifugo.go @@ -0,0 +1,92 @@ +package remote + +import ( + "fmt" + + "github.com/centrifugal/centrifuge-go" + "github.com/golang-jwt/jwt/v5" + + "github.com/opencloud-eu/opencloud/services/console/pkg/console" +) + +type CentrifugoSubscriptionOptions struct { + Token *jwt.Token `validate:"required"` + URL string `validate:"required,url"` + Claims *console.Claims `validate:"required"` + CentrifugeConfig centrifuge.Config `validate:"required"` + CentrifugeSubscriptionConfig centrifuge.SubscriptionConfig `validate:"required"` +} + +func (o CentrifugoSubscriptionOptions) Validate() error { + if err := console.Validate.Struct(o); err != nil { + return fmt.Errorf("(%w): %w", console.ErrOptionsInvalid, err) + } + + return nil +} + +type CentrifugoSubscription struct { + client *centrifuge.Client + subscriptionConfig centrifuge.SubscriptionConfig + channel string +} + +func NewCentrifugoSubscription(o CentrifugoSubscriptionOptions) (CentrifugoSubscription, error) { + if err := o.Validate(); err != nil { + return CentrifugoSubscription{}, err + } + + client := centrifuge.NewJsonClient(o.URL, o.CentrifugeConfig) + if err := client.Connect(); err != nil { + return CentrifugoSubscription{}, fmt.Errorf("failed to connect to centrifugo: %w", err) + } + + return CentrifugoSubscription{ + client: client, + channel: fmt.Sprintf("#%s", o.Claims.TenantId), + subscriptionConfig: o.CentrifugeSubscriptionConfig, + }, nil +} + +func (cs CentrifugoSubscription) Close() error { + if cs.client != nil { + cs.client.Close() + } + + return nil +} + +func (cs CentrifugoSubscription) Handle(handler Handler) error { + if cs.client == nil { + return fmt.Errorf("client not initialized") + } + + subscription, err := cs.client.NewSubscription(cs.channel, cs.subscriptionConfig) + if err != nil { + return err + } + + subscription.OnPublication(func(e centrifuge.PublicationEvent) { + topic, ok := e.Tags["topic"] + if !ok { + return + } + + if err := cs.handle(Topic(topic), handler, e.Data); err != nil { + fmt.Println(err) + } + }) + + return subscription.Subscribe() +} + +func (cs CentrifugoSubscription) handle(topic Topic, handler Handler, b []byte) error { + switch { + case topic == TopicThemeAssigned && handler.ThemeAssigned != nil: + return dispatchMessage(handler.ThemeAssigned, b) + case topic == TopicThemeUnassigned && handler.ThemeUnassigned != nil: + return dispatchMessage(handler.ThemeUnassigned, b) + default: + return fmt.Errorf("no handler registered for topic: %s", topic) + } +} diff --git a/services/console/pkg/web/repository.go b/services/console/pkg/web/repository.go new file mode 100644 index 0000000000..1a42e517f5 --- /dev/null +++ b/services/console/pkg/web/repository.go @@ -0,0 +1,66 @@ +package web + +import ( + "context" + "fmt" + "io" + + webService "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/web/v0" + "github.com/opencloud-eu/opencloud/services/console/pkg/console" +) + +type GRPCRepositoryOptions struct { + WebService webService.WebService `validate:"required"` +} + +func (o GRPCRepositoryOptions) Validate() error { + if err := console.Validate.Struct(o); err != nil { + return fmt.Errorf("(%w): %w", console.ErrOptionsInvalid, err) + } + + return nil +} + +type GRPCRepository struct { + webService webService.WebService +} + +func NewGRPCRepository(o GRPCRepositoryOptions) (GRPCRepository, error) { + if err := o.Validate(); err != nil { + return GRPCRepository{}, err + } + + return GRPCRepository{ + webService: o.WebService, + }, nil +} + +func (r GRPCRepository) ThemeExists(ctx context.Context, id string) (bool, error) { + resp, err := r.webService.ThemeExists(ctx, &webService.ThemeExistsRequest{Id: id}) + if err != nil { + return false, fmt.Errorf("(%w) %w", console.ErrRequest, err) + } + + return resp.Exists, nil +} + +func (r GRPCRepository) ThemeAdd(ctx context.Context, id string, tr io.Reader) error { + tb, err := io.ReadAll(tr) + if err != nil { + return fmt.Errorf("failed to read theme data: %w", err) + } + + if _, err := r.webService.ThemeAdd(ctx, &webService.ThemeAddRequest{Id: id, Data: tb}); err != nil { + return fmt.Errorf("(%w) %w", console.ErrRequest, err) + } + + return nil +} + +func (r GRPCRepository) ThemeRemove(ctx context.Context, id string) error { + if _, err := r.webService.ThemeRemove(ctx, &webService.ThemeRemoveRequest{Id: id}); err != nil { + return fmt.Errorf("(%w) %w", console.ErrRequest, err) + } + + return nil +} diff --git a/services/console/pkg/web/service_core.go b/services/console/pkg/web/service_core.go new file mode 100644 index 0000000000..0520b5cce3 --- /dev/null +++ b/services/console/pkg/web/service_core.go @@ -0,0 +1,86 @@ +package web + +import ( + "context" + "fmt" + + "github.com/opencloud-eu/opencloud/services/console/pkg/console" +) + +const ( + ThemeID = "_console" +) + +type CoreServiceOptions struct { + Repository Repository `validate:"required"` + ConsoleRepository ConsoleRepository `validate:"required"` + Next Service `validate:"required"` +} + +func (o CoreServiceOptions) Validate() error { + if err := console.Validate.Struct(o); err != nil { + return fmt.Errorf("(%w): %w", console.ErrOptionsInvalid, err) + } + + return nil +} + +type CoreService struct { + repository Repository + consoleRepository ConsoleRepository + next Service +} + +func NewCoreService(o CoreServiceOptions) (CoreService, error) { + if err := o.Validate(); err != nil { + return CoreService{}, err + } + + return CoreService{ + repository: o.Repository, + consoleRepository: o.ConsoleRepository, + next: o.Next, + }, nil +} + +func (s CoreService) ThemeApply(ctx context.Context) error { + data, err := s.consoleRepository.ThemeGet(context.Background()) + if err != nil { + return fmt.Errorf("could not get theme: %w", err) + } + defer func() { + _ = data.Close() + }() + + exists, err := s.repository.ThemeExists(ctx, ThemeID) + if err != nil { + return fmt.Errorf("could not check if theme %s exists: %w", ThemeID, err) + } + + if exists { + if err := s.repository.ThemeRemove(ctx, ThemeID); err != nil { + return fmt.Errorf("could not remove existing theme %s: %w", ThemeID, err) + } + } + + if err := s.repository.ThemeAdd(ctx, ThemeID, data); err != nil { + return fmt.Errorf("could not add theme %s: %w", ThemeID, err) + } + + return s.next.ThemeApply(ctx) +} + +func (s CoreService) ThemeRemove(ctx context.Context) error { + exists, err := s.repository.ThemeExists(ctx, ThemeID) + if err != nil { + return fmt.Errorf("could not check if theme %s exists: %w", ThemeID, err) + } + + if exists { + if err := s.repository.ThemeRemove(ctx, ThemeID); err != nil { + return fmt.Errorf("could not remove existing theme %s: %w", ThemeID, err) + } + } + + return s.next.ThemeRemove(ctx) +} diff --git a/services/console/pkg/web/service_core_test.go b/services/console/pkg/web/service_core_test.go new file mode 100644 index 0000000000..1f556b0e9b --- /dev/null +++ b/services/console/pkg/web/service_core_test.go @@ -0,0 +1,31 @@ +package web_test + +import ( + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/opencloud-eu/opencloud/services/console/pkg/console" + "github.com/opencloud-eu/opencloud/services/console/pkg/web" +) + +func TestService_NewService(t *testing.T) { + t.Run("valid options", func(t *testing.T) { + _, err := web.NewCoreService(web.CoreServiceOptions{}) + assert.ErrorIs(t, err, console.ErrOptionsInvalid) + }) +} + +func TestService_ThemeApply(t *testing.T) { + //options := web.CoreServiceOptions{ + // Repository: mocks.NewRepository(t), + // ConsoleRepository: mocks.NewConsoleRepository(t), + //} + //service, err := web.NewCoreService(options) + //assert.NoError(t, err) + + t.Run("fails without tenantID claim", func(t *testing.T) { + //err := service.ThemeApply(t.Context()) + //assert.ErrorIs(t, err, console.ErrJWTTokenUnknownClaim) + }) +} diff --git a/services/console/pkg/web/service_sse.go b/services/console/pkg/web/service_sse.go new file mode 100644 index 0000000000..d72c175000 --- /dev/null +++ b/services/console/pkg/web/service_sse.go @@ -0,0 +1,48 @@ +package web + +import ( + "context" + "fmt" + + "github.com/google/uuid" + + "github.com/opencloud-eu/opencloud/services/console/pkg/console" + "github.com/opencloud-eu/opencloud/services/sse/pkg/service" + "github.com/opencloud-eu/reva/v2/pkg/events" +) + +type SSEServiceOptions struct { + EventStream events.Stream `validate:"required"` +} + +func (o SSEServiceOptions) Validate() error { + if err := console.Validate.Struct(o); err != nil { + return fmt.Errorf("(%w): %w", console.ErrOptionsInvalid, err) + } + + return nil +} + +type SSEService struct { + eventStream events.Stream +} + +func NewSSEService(o SSEServiceOptions) (SSEService, error) { + if err := o.Validate(); err != nil { + return SSEService{}, err + } + + return SSEService{eventStream: o.EventStream}, nil +} + +func (s SSEService) ThemeApply(ctx context.Context) error { + return events.Publish(ctx, s.eventStream, events.SendSSE{ + UserIDs: []string{service.SSETopicAllUsers}, + Type: "console-notification", + Message: []byte(fmt.Sprintf(`{"id":"%s", "itemid":"%s"}`, uuid.New().String(), "theme has changed, please reload")), + }) +} + +func (s SSEService) ThemeRemove(context.Context) error { + return nil +} diff --git a/services/console/pkg/web/web.go b/services/console/pkg/web/web.go new file mode 100644 index 0000000000..4f89f2fe57 --- /dev/null +++ b/services/console/pkg/web/web.go @@ -0,0 +1,21 @@ +package web + +import ( + "context" + "io" +) + +type Service interface { + ThemeApply(context.Context) error + ThemeRemove(context.Context) error +} + +type Repository interface { + ThemeExists(ctx context.Context, id string) (bool, error) + ThemeRemove(ctx context.Context, id string) error + ThemeAdd(ctx context.Context, id string, r io.Reader) error +} + +type ConsoleRepository interface { + ThemeGet(ctx context.Context) (io.ReadCloser, error) +} diff --git a/services/console/pkg/workflow/subscribe.go b/services/console/pkg/workflow/subscribe.go new file mode 100644 index 0000000000..21adbc680e --- /dev/null +++ b/services/console/pkg/workflow/subscribe.go @@ -0,0 +1,59 @@ +package workflow + +import ( + "fmt" + + "github.com/centrifugal/centrifuge-go" + + "github.com/opencloud-eu/opencloud/services/console/pkg/config" + "github.com/opencloud-eu/opencloud/services/console/pkg/console" +) + +func SubscribeAll(cfg *config.Config) error { + token, claims, err := console.ParseUnverifiedJWTToken(cfg.RemoteConsole.JWTToken) + if err != nil { + return err + } + + client := centrifuge.NewJsonClient( + // toDo: add to config + "ws://host.docker.internal:8000/connection/websocket", + centrifuge.Config{ + Token: token.Raw, + }, + ) + defer client.Close() + + client.OnError(func(e centrifuge.ErrorEvent) { + _ = fmt.Sprintf("Error: %s\n", e.Error.Error()) + }) + + if err := client.Connect(); err != nil { + return err + } + + subscription, err := client.NewSubscription(fmt.Sprintf("#%s", claims.TenantId), centrifuge.SubscriptionConfig{ + Recoverable: true, + JoinLeave: true, + }) + if err != nil { + return err + } + + subscription.OnError(func(e centrifuge.SubscriptionErrorEvent) { + _ = fmt.Sprintf("Subscription error %s: %s", subscription.Channel, e.Error) + }) + + subscription.OnPublication(func(e centrifuge.PublicationEvent) { + fmt.Println(e) + }) + err = subscription.Subscribe() + if err != nil { + return err + } + + // toDo: maeh + select {} + + return nil +} diff --git a/services/console/pkg/workflow/task.go b/services/console/pkg/workflow/task.go new file mode 100644 index 0000000000..0e59ea2793 --- /dev/null +++ b/services/console/pkg/workflow/task.go @@ -0,0 +1 @@ +package workflow diff --git a/services/console/pkg/workflow/web.go b/services/console/pkg/workflow/web.go new file mode 100644 index 0000000000..8e1a8a3c43 --- /dev/null +++ b/services/console/pkg/workflow/web.go @@ -0,0 +1,48 @@ +package workflow + +import ( + "context" + "fmt" + + websvc "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/web/v0" + "github.com/opencloud-eu/opencloud/services/console/pkg/config" + "github.com/opencloud-eu/opencloud/services/console/pkg/console" + "github.com/opencloud-eu/opencloud/services/console/pkg/console/remote" + "github.com/opencloud-eu/opencloud/services/console/pkg/web" +) + +func ConsoleGetAndApplyTheme(cfg *config.Config) error { + grpcClient, err := console.NewGRPCClient(cfg.Context, cfg.Commons.TracesExporter, cfg.Service.Name, cfg.GRPCClientTLS) + if err != nil { + return err + } + + consoleRepository, err := remote.NewHTTPRepository(remote.HTTPRepositoryOptions{ + Client: console.DefaultHTTPClient, + Token: cfg.RemoteConsole.JWTToken, + }) + if err != nil { + return fmt.Errorf("failed to create console repository: %w", err) + } + + webRepository, err := web.NewGRPCRepository(web.GRPCRepositoryOptions{ + WebService: websvc.NewWebService("eu.opencloud.api.web", grpcClient), + }) + if err != nil { + return fmt.Errorf("failed to create web repository: %w", err) + } + + webService, err := web.NewService(web.ServiceOptions{ + Repository: webRepository, + ConsoleRepository: consoleRepository, + }) + if err != nil { + return fmt.Errorf("failed to create web service: %w", err) + } + + if err := webService.ThemeApply(context.Background()); err != nil { + return fmt.Errorf("failed to apply theme: %w", err) + } + + return nil +} diff --git a/services/sse/pkg/server/http/server.go b/services/sse/pkg/server/http/server.go index 72e99e86f1..0bee2367c9 100644 --- a/services/sse/pkg/server/http/server.go +++ b/services/sse/pkg/server/http/server.go @@ -2,12 +2,14 @@ package http import ( "fmt" - stdhttp "net/http" "github.com/go-chi/chi/v5" chimiddleware "github.com/go-chi/chi/v5/middleware" "github.com/google/uuid" + "github.com/riandyrn/otelchi" + "go-micro.dev/v4" + "github.com/opencloud-eu/opencloud/pkg/account" "github.com/opencloud-eu/opencloud/pkg/cors" "github.com/opencloud-eu/opencloud/pkg/middleware" @@ -16,8 +18,6 @@ import ( "github.com/opencloud-eu/opencloud/pkg/version" svc "github.com/opencloud-eu/opencloud/services/sse/pkg/service" "github.com/opencloud-eu/reva/v2/pkg/events" - "github.com/riandyrn/otelchi" - "go-micro.dev/v4" ) // Service is the service interface @@ -83,12 +83,17 @@ func Server(opts ...Option) (http.Service, error) { return http.Service{}, err } - handle, err := svc.NewSSE(options.Config, options.Logger, ch, mux) + sseHandler, err := svc.NewSSEHandler(options.Context, options.Config, options.Logger, ch) + if err != nil { + return http.Service{}, err + } + + svcHandler, err := svc.New(mux, sseHandler) if err != nil { return http.Service{}, err } - if err := micro.RegisterHandler(service.Server(), handle); err != nil { + if err := micro.RegisterHandler(service.Server(), svcHandler); err != nil { return http.Service{}, err } diff --git a/services/sse/pkg/service/service.go b/services/sse/pkg/service/service.go index 97a211e215..91dbf4c7f5 100644 --- a/services/sse/pkg/service/service.go +++ b/services/sse/pkg/service/service.go @@ -2,102 +2,26 @@ package service import ( "net/http" - "time" "github.com/go-chi/chi/v5" - "github.com/r3labs/sse/v2" - - revactx "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/events" - - "github.com/opencloud-eu/opencloud/pkg/log" - "github.com/opencloud-eu/opencloud/services/sse/pkg/config" ) -// SSE defines implements the business logic for Service. -type SSE struct { - c *config.Config - l log.Logger - m *chi.Mux - sse *sse.Server - evChannel <-chan events.Event -} - -// NewSSE returns a service implementation for Service. -func NewSSE(c *config.Config, l log.Logger, ch <-chan events.Event, mux *chi.Mux) (SSE, error) { - s := SSE{ - c: c, - l: l, - m: mux, - sse: sse.New(), - evChannel: ch, - } - mux.Route("/ocs/v2.php/apps/notifications/api/v1/notifications", func(r chi.Router) { - r.Get("/sse", s.HandleSSE) - }) - - go s.ListenForEvents() +const ( + _httpEndpointSSE = "/ocs/v2.php/apps/notifications/api/v1/notifications/sse" +) - return s, nil +type Service struct { + handler http.Handler } -// ServeHTTP fulfills Handler interface -func (s SSE) ServeHTTP(w http.ResponseWriter, r *http.Request) { - s.m.ServeHTTP(w, r) -} +func New(mux *chi.Mux, sseHandler http.Handler) (Service, error) { + mux.Get(_httpEndpointSSE, sseHandler.ServeHTTP) -// ListenForEvents listens for events -func (s SSE) ListenForEvents() { - for e := range s.evChannel { - switch ev := e.Event.(type) { - default: - s.l.Error().Interface("event", ev).Msg("unhandled event") - case events.SendSSE: - for _, uid := range ev.UserIDs { - s.sse.Publish(uid, &sse.Event{ - Event: []byte(ev.Type), - Data: ev.Message, - }) - } - } - } + return Service{ + handler: mux, + }, nil } -// HandleSSE is the GET handler for events -func (s SSE) HandleSSE(w http.ResponseWriter, r *http.Request) { - u, ok := revactx.ContextGetUser(r.Context()) - if !ok { - s.l.Error().Msg("sse: no user in context") - w.WriteHeader(http.StatusInternalServerError) - return - } - - uid := u.GetId().GetOpaqueId() - if uid == "" { - s.l.Error().Msg("sse: user in context is broken") - w.WriteHeader(http.StatusInternalServerError) - return - } - - stream := s.sse.CreateStream(uid) - stream.AutoReplay = false - - if s.c.KeepAliveInterval != 0 { - ticker := time.NewTicker(s.c.KeepAliveInterval) - defer ticker.Stop() - go func() { - for range ticker.C { - s.sse.Publish(uid, &sse.Event{ - Comment: []byte("keepalive"), - }) - } - }() - } - - // add stream to URL - q := r.URL.Query() - q.Set("stream", uid) - r.URL.RawQuery = q.Encode() - - s.sse.ServeHTTP(w, r) +func (s Service) ServeHTTP(w http.ResponseWriter, r *http.Request) { + s.handler.ServeHTTP(w, r) } diff --git a/services/sse/pkg/service/sse.go b/services/sse/pkg/service/sse.go new file mode 100644 index 0000000000..b4e1ea1472 --- /dev/null +++ b/services/sse/pkg/service/sse.go @@ -0,0 +1,113 @@ +package service + +import ( + "context" + "net/http" + "time" + + "github.com/tmaxmax/go-sse" + + revactx "github.com/opencloud-eu/reva/v2/pkg/ctx" + "github.com/opencloud-eu/reva/v2/pkg/events" + + "github.com/opencloud-eu/opencloud/pkg/log" + "github.com/opencloud-eu/opencloud/services/sse/pkg/config" +) + +const ( + SSETopicAllUsers = "all-users" +) + +// SSEHandler defines implements the business logic for Service. +type SSEHandler struct { + conf *config.Config + logger log.Logger + server *sse.Server + channel <-chan events.Event +} + +// NewSSEHandler returns a service implementation for Service. +func NewSSEHandler(ctx context.Context, conf *config.Config, logger log.Logger, ch <-chan events.Event) (SSEHandler, error) { + handler := SSEHandler{ + conf: conf, + logger: logger, + channel: ch, + } + + handler.server = &sse.Server{ + OnSession: func(_ http.ResponseWriter, r *http.Request) (topics []string, allowed bool) { + return handler.topics(r) + }, + } + + go func() { + select { + case <-ctx.Done(): + if err := handler.server.Shutdown(ctx); err != nil { + logger.Error().Err(err).Msg("failed to shutdown SSE handler") + } + return + } + }() + + go handler.listen() + + return handler, nil +} + +// ServeHTTP fulfills Handler interface +func (h SSEHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + topics, ok := h.topics(r) + if !ok { + h.logger.Error().Msg("sse: failed to get topics") + w.WriteHeader(http.StatusInternalServerError) + return + } + + if h.conf.KeepAliveInterval != 0 { + ticker := time.NewTicker(h.conf.KeepAliveInterval) + defer ticker.Stop() + go func() { + for range ticker.C { + m := &sse.Message{} + m.AppendData("keep-alive") + if err := h.server.Publish(m, topics...); err != nil { + h.logger.Error().Err(err).Msg("sse: failed to publish message") + } + } + }() + } + h.server.ServeHTTP(w, r) +} + +// ListenForEvents listens for events +func (h SSEHandler) listen() { + for e := range h.channel { + switch ev := e.Event.(type) { + default: + h.logger.Error().Interface("event", ev).Msg("unhandled event") + case events.SendSSE: + m := &sse.Message{ + Type: sse.Type(ev.Type), + } + m.AppendData(string(ev.Message)) + if err := h.server.Publish(m, ev.UserIDs...); err != nil { + h.logger.Error().Err(err).Msg("sse: failed to publish message") + } + } + } +} + +func (h SSEHandler) topics(r *http.Request) ([]string, bool) { + u, ok := revactx.ContextGetUser(r.Context()) + if !ok { + return nil, false + } + + uid := u.GetId().GetOpaqueId() + if uid == "" { + return nil, false + } + + return append([]string{SSETopicAllUsers}, uid), true +} diff --git a/services/web/Makefile b/services/web/Makefile index 1b3c4f5d40..bb19c086c6 100644 --- a/services/web/Makefile +++ b/services/web/Makefile @@ -11,6 +11,13 @@ include ../../.make/default.mk include ../../.make/go.mk include ../../.make/release.mk include ../../.make/docs.mk +include ../../.make/protobuf.mk + +.PHONY: go-generate +go-generate: protobuf + +.PHONY: protobuf +protobuf: buf-generate .PHONY: node-generate-dev node-generate-dev: pull-assets diff --git a/services/web/pkg/command/server.go b/services/web/pkg/command/server.go index 38df9caec4..145decf00d 100644 --- a/services/web/pkg/command/server.go +++ b/services/web/pkg/command/server.go @@ -10,11 +10,13 @@ import ( "github.com/opencloud-eu/opencloud/pkg/config/configlog" "github.com/opencloud-eu/opencloud/pkg/log" "github.com/opencloud-eu/opencloud/pkg/runner" + ogrpc "github.com/opencloud-eu/opencloud/pkg/service/grpc" "github.com/opencloud-eu/opencloud/pkg/tracing" "github.com/opencloud-eu/opencloud/services/web/pkg/config" "github.com/opencloud-eu/opencloud/services/web/pkg/config/parser" "github.com/opencloud-eu/opencloud/services/web/pkg/metrics" "github.com/opencloud-eu/opencloud/services/web/pkg/server/debug" + "github.com/opencloud-eu/opencloud/services/web/pkg/server/grpc" "github.com/opencloud-eu/opencloud/services/web/pkg/server/http" "github.com/spf13/cobra" @@ -48,6 +50,10 @@ func Server(cfg *config.Config) *cobra.Command { } } + cfg.GrpcClient, err = ogrpc.NewClient( + append(ogrpc.GetClientOptions(cfg.GRPCClientTLS), ogrpc.WithTraceProvider(traceProvider))..., + ) + var cancel context.CancelFunc if cfg.Context == nil { cfg.Context, cancel = signal.NotifyContext(context.Background(), runner.StopSignals...) @@ -79,6 +85,23 @@ func Server(cfg *config.Config) *cobra.Command { gr.Add(runner.NewGoMicroHttpServerRunner(cfg.Service.Name+".http", server)) } + { + grpcServer, err := grpc.Server( + grpc.Config(cfg), + grpc.Logger(logger), + grpc.Name(cfg.Service.Name), + grpc.Context(ctx), + grpc.JWTSecret(cfg.TokenManager.JWTSecret), + grpc.TraceProvider(traceProvider), + ) + if err != nil { + logger.Info().Err(err).Str("transport", "grpc").Msg("Failed to initialize server") + return err + } + + gr.Add(runner.NewGoMicroGrpcServerRunner(cfg.Service.Name+".grpc", grpcServer)) + } + { debugServer, err := debug.Server( debug.Logger(logger), diff --git a/services/web/pkg/config/config.go b/services/web/pkg/config/config.go index e2edcab53a..ac391ded42 100644 --- a/services/web/pkg/config/config.go +++ b/services/web/pkg/config/config.go @@ -3,6 +3,8 @@ package config import ( "context" + "go-micro.dev/v4/client" + "github.com/opencloud-eu/opencloud/pkg/shared" ) @@ -17,6 +19,9 @@ type Config struct { HTTP HTTP `yaml:"http"` + GRPC GRPCConfig `yaml:"grpc"` + GrpcClient client.Client `yaml:"-"` + Asset Asset `yaml:"asset"` File string `yaml:"file" env:"WEB_UI_CONFIG_FILE" desc:"Read the OpenCloud Web json based configuration from this path/file. The config file takes precedence over WEB_OPTION_xxx environment variables. See the text description for more details." introductionVersion:"1.0.0"` Web Web `yaml:"web"` @@ -24,8 +29,21 @@ type Config struct { TokenManager *TokenManager `yaml:"token_manager"` - GatewayAddress string `yaml:"gateway_addr" env:"WEB_GATEWAY_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"1.0.0"` - Context context.Context `yaml:"-"` + GatewayAddress string `yaml:"gateway_addr" env:"WEB_GATEWAY_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"1.0.0"` + Context context.Context `yaml:"-"` + GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"` + + Metadata Metadata `yaml:"metadata_config"` +} + +// Metadata configures the metadata store to use +type Metadata struct { + GatewayAddress string `yaml:"gateway_addr" env:"WEB_STORAGE_GATEWAY_GRPC_ADDR;STORAGE_GATEWAY_GRPC_ADDR" desc:"GRPC address of the STORAGE-SYSTEM service." introductionVersion:"%%NEXT%%"` + StorageAddress string `yaml:"storage_addr" env:"WEB_STORAGE_GRPC_ADDR;STORAGE_GRPC_ADDR" desc:"GRPC address of the STORAGE-SYSTEM service." introductionVersion:"%%NEXT%%"` + + SystemUserID string `yaml:"system_user_id" env:"OC_SYSTEM_USER_ID;WEB_SYSTEM_USER_ID" desc:"ID of the OpenCloud STORAGE-SYSTEM system user. Admins need to set the ID for the STORAGE-SYSTEM system user in this config option which is then used to reference the user. Any reasonable long string is possible, preferably this would be an UUIDv4 format." introductionVersion:"%%NEXT%%"` + SystemUserIDP string `yaml:"system_user_idp" env:"OC_SYSTEM_USER_IDP;WEB_SYSTEM_USER_IDP" desc:"IDP of the OpenCloud STORAGE-SYSTEM system user." introductionVersion:"%%NEXT%%"` + SystemUserAPIKey string `yaml:"system_user_api_key" env:"OC_SYSTEM_USER_API_KEY" desc:"API key for the STORAGE-SYSTEM system user." introductionVersion:"%%NEXT%%"` } // Asset defines the available asset configuration. diff --git a/services/web/pkg/config/defaults/defaultconfig.go b/services/web/pkg/config/defaults/defaultconfig.go index 8120394aa6..98514dce79 100644 --- a/services/web/pkg/config/defaults/defaultconfig.go +++ b/services/web/pkg/config/defaults/defaultconfig.go @@ -5,6 +5,7 @@ import ( "strings" "github.com/opencloud-eu/opencloud/pkg/config/defaults" + "github.com/opencloud-eu/opencloud/pkg/structs" "github.com/opencloud-eu/opencloud/services/web/pkg/config" ) @@ -25,6 +26,11 @@ func DefaultConfig() *config.Config { Pprof: false, Zpages: false, }, + GRPC: config.GRPCConfig{ + Addr: "127.0.0.1:9221", + Namespace: "eu.opencloud.api", + Protocol: "tcp", + }, HTTP: config.HTTP{ Addr: "127.0.0.1:9100", Root: "/", @@ -85,12 +91,16 @@ func DefaultConfig() *config.Config { ThemesPath: filepath.Join(defaults.BaseDataPath(), "web/assets/themes"), }, GatewayAddress: "eu.opencloud.api.gateway", + Metadata: config.Metadata{ + GatewayAddress: "eu.opencloud.api.storage-system", + StorageAddress: "eu.opencloud.api.storage-system", + SystemUserIDP: "internal", + }, Web: config.Web{ ThemeServer: "https://localhost:9200", ThemePath: "/themes/opencloud/theme.json", Config: config.WebConfig{ Server: "https://localhost:9200", - Theme: "", OpenIDConnect: config.OIDC{ MetadataURL: "", Authority: "https://localhost:9200", @@ -140,6 +150,14 @@ func EnsureDefaults(cfg *config.Config) { cfg.HTTP.CORS.AllowedOrigins[0] == "https://localhost:9200") { cfg.HTTP.CORS.AllowedOrigins = []string{cfg.Commons.OpenCloudURL} } + + if cfg.Metadata.SystemUserAPIKey == "" && cfg.Commons != nil && cfg.Commons.SystemUserAPIKey != "" { + cfg.Metadata.SystemUserAPIKey = cfg.Commons.SystemUserAPIKey + } + + if cfg.Metadata.SystemUserID == "" && cfg.Commons != nil && cfg.Commons.SystemUserID != "" { + cfg.Metadata.SystemUserID = cfg.Commons.SystemUserID + } } // Sanitize sanitized the configuration @@ -183,4 +201,12 @@ func Sanitize(cfg *config.Config) { cfg.Web.Config.Options.Embed.DelegateAuthenticationOrigin == "" { cfg.Web.Config.Options.Embed = nil } + + if cfg.GRPCClientTLS == nil && cfg.Commons != nil { + cfg.GRPCClientTLS = structs.CopyOrZeroValue(cfg.Commons.GRPCClientTLS) + } + + if cfg.GRPC.TLS == nil && cfg.Commons != nil { + cfg.GRPC.TLS = structs.CopyOrZeroValue(cfg.Commons.GRPCServiceTLS) + } } diff --git a/services/web/pkg/config/grpc.go b/services/web/pkg/config/grpc.go new file mode 100644 index 0000000000..44eca8a5f6 --- /dev/null +++ b/services/web/pkg/config/grpc.go @@ -0,0 +1,11 @@ +package config + +import "github.com/opencloud-eu/opencloud/pkg/shared" + +// GRPCConfig defines the available grpc configuration. +type GRPCConfig struct { + Addr string `yaml:"addr" env:"WEB_GRPC_ADDR" desc:"The bind address of the GRPC service." introductionVersion:"%%NEXT%%"` + Namespace string `yaml:"-"` + TLS *shared.GRPCServiceTLS `yaml:"tls"` + Protocol string `yaml:"protocol" env:"OC_GRPC_PROTOCOL;WEB_GRPC_PROTOCOL" desc:"The transport protocol of the GRPC service." introductionVersion:"%%NEXT%%"` +} diff --git a/services/web/pkg/fs/fs.go b/services/web/pkg/fs/fs.go new file mode 100644 index 0000000000..bb6c74e7af --- /dev/null +++ b/services/web/pkg/fs/fs.go @@ -0,0 +1,52 @@ +package fs + +import ( + "context" + "fmt" + "time" + + revaMetadata "github.com/opencloud-eu/reva/v2/pkg/storage/utils/metadata" + + "github.com/opencloud-eu/opencloud/pkg/storage/metadata" + "github.com/opencloud-eu/opencloud/pkg/x/io/fsx" + metadataFs "github.com/opencloud-eu/opencloud/pkg/x/io/fsx/cs3/metadata" + "github.com/opencloud-eu/opencloud/services/web" + "github.com/opencloud-eu/opencloud/services/web/pkg/config" +) + +func NewThemeFS(c *config.Config) (*fsx.FallbackFS, error) { + storage, err := revaMetadata.NewCS3Storage( + c.Metadata.GatewayAddress, + c.Metadata.StorageAddress, + c.Metadata.SystemUserID, + c.Metadata.SystemUserIDP, + c.Metadata.SystemUserAPIKey, + ) + if err != nil { + return nil, err + } + + storage, err = metadata.NewLazyStorage(storage) + if err != nil { + return nil, err + } + + time.Sleep(3 * time.Second) // fixme: wait for the storage to be initialized + + if err := storage.Init(context.Background(), "web-storage"); err != nil { + return nil, err + } + + storageFS := metadataFs.NewMetadataFs(storage) + if err := storageFS.MkdirAll("assets/themes", 0755); err != nil { + return nil, fmt.Errorf("failed to create themes directory: %w", err) + } + + return fsx.NewFallbackFS( + fsx.NewBasePathFs(fsx.FromAfero(storageFS), "assets/themes"), + fsx.NewFallbackFS( + fsx.NewReadOnlyFs(fsx.NewBasePathFs(fsx.FromIOFS(web.Assets), "assets/themes")), + fsx.NewReadOnlyFs(fsx.NewBasePathFs(fsx.NewOsFs(), c.Asset.ThemesPath)), + ), + ), nil +} diff --git a/services/web/pkg/server/grpc/option.go b/services/web/pkg/server/grpc/option.go new file mode 100644 index 0000000000..d83163d748 --- /dev/null +++ b/services/web/pkg/server/grpc/option.go @@ -0,0 +1,94 @@ +package grpc + +import ( + "context" + + "go.opentelemetry.io/otel/trace" + + "github.com/opencloud-eu/opencloud/pkg/log" + svc "github.com/opencloud-eu/opencloud/services/search/pkg/service/grpc/v0" + "github.com/opencloud-eu/opencloud/services/web/pkg/config" + "github.com/opencloud-eu/opencloud/services/web/pkg/metrics" +) + +// Option defines a single option function. +type Option func(o *Options) + +// Options defines the available options for this package. +type Options struct { + Name string + Logger log.Logger + Context context.Context + Config *config.Config + Metrics *metrics.Metrics + Handler *svc.Service + JWTSecret string + TraceProvider trace.TracerProvider +} + +// newOptions initializes the available default options. +func newOptions(opts ...Option) Options { + opt := Options{} + + for _, o := range opts { + o(&opt) + } + + return opt +} + +// Name provides a name for the service. +func Name(val string) Option { + return func(o *Options) { + o.Name = val + } +} + +// Logger provides a function to set the logger option. +func Logger(val log.Logger) Option { + return func(o *Options) { + o.Logger = val + } +} + +// Context provides a function to set the context option. +func Context(val context.Context) Option { + return func(o *Options) { + o.Context = val + } +} + +// Config provides a function to set the config option. +func Config(val *config.Config) Option { + return func(o *Options) { + o.Config = val + } +} + +// Metrics provides a function to set the metrics option. +func Metrics(val *metrics.Metrics) Option { + return func(o *Options) { + o.Metrics = val + } +} + +// Handler provides a function to set the handler option. +func Handler(val *svc.Service) Option { + return func(o *Options) { + o.Handler = val + } +} + +// JWTSecret provides a function to set the Config option. +func JWTSecret(val string) Option { + return func(o *Options) { + o.JWTSecret = val + } +} + +// TraceProvider provides a function to set the trace provider option. +func TraceProvider(val trace.TracerProvider) Option { + return func(o *Options) { + o.TraceProvider = val + } +} diff --git a/services/web/pkg/server/grpc/server.go b/services/web/pkg/server/grpc/server.go new file mode 100644 index 0000000000..b349411323 --- /dev/null +++ b/services/web/pkg/server/grpc/server.go @@ -0,0 +1,67 @@ +package grpc + +import ( + "fmt" + + "github.com/opencloud-eu/opencloud/pkg/service/grpc" + "github.com/opencloud-eu/opencloud/pkg/version" + websvc "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/web/v0" + "github.com/opencloud-eu/opencloud/services/web/pkg/fs" + svc "github.com/opencloud-eu/opencloud/services/web/pkg/service/grpc/v0" +) + +// Server initializes a new go-micro service ready to run +func Server(opts ...Option) (grpc.Service, error) { + options := newOptions(opts...) + + service, err := grpc.NewServiceWithClient( + options.Config.GrpcClient, + grpc.TLSEnabled(options.Config.GRPC.TLS.Enabled), + grpc.TLSCert( + options.Config.GRPC.TLS.Cert, + options.Config.GRPC.TLS.Key, + ), + grpc.Name(options.Config.Service.Name), + grpc.Context(options.Context), + grpc.Address(options.Config.GRPC.Addr), + grpc.Namespace(options.Config.GRPC.Namespace), + grpc.Logger(options.Logger), + grpc.Version(version.GetString()), + grpc.TraceProvider(options.TraceProvider), + ) + if err != nil { + options.Logger.Fatal().Err(err).Msg("Error creating web service") + return grpc.Service{}, err + } + + themeFS, err := fs.NewThemeFS(options.Config) + if err != nil { + return grpc.Service{}, fmt.Errorf("could not initialize theme filesystem: %w", err) + } + + handle, err := svc.NewHandler( + svc.Config(options.Config), + svc.Logger(options.Logger), + svc.JWTSecret(options.JWTSecret), + svc.TracerProvider(options.TraceProvider), + svc.ThemeFS(themeFS), + ) + if err != nil { + options.Logger.Error(). + Err(err). + Msg("Error initializing web service") + return grpc.Service{}, err + } + + if err := websvc.RegisterWebServiceHandler( + service.Server(), + handle, + ); err != nil { + options.Logger.Error(). + Err(err). + Msg("Error registering web provider handler") + return grpc.Service{}, err + } + + return service, nil +} diff --git a/services/web/pkg/server/http/server.go b/services/web/pkg/server/http/server.go index 25f210b13b..5714d05c95 100644 --- a/services/web/pkg/server/http/server.go +++ b/services/web/pkg/server/http/server.go @@ -5,9 +5,12 @@ import ( "path" chimiddleware "github.com/go-chi/chi/v5/middleware" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" "go-micro.dev/v4" + "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" + + "github.com/opencloud-eu/opencloud/services/web/pkg/fs" + "github.com/opencloud-eu/opencloud/pkg/cors" "github.com/opencloud-eu/opencloud/pkg/middleware" "github.com/opencloud-eu/opencloud/pkg/registry" @@ -71,10 +74,11 @@ func Server(opts ...Option) (http.Service, error) { fsx.NewBasePathFs(fsx.NewOsFs(), options.Config.Asset.CorePath), fsx.NewBasePathFs(fsx.FromIOFS(web.Assets), "assets/core"), ) - themeFS := fsx.NewFallbackFS( - fsx.NewBasePathFs(fsx.NewOsFs(), options.Config.Asset.ThemesPath), - fsx.NewBasePathFs(fsx.FromIOFS(web.Assets), "assets/themes"), - ) + + themeFS, err := fs.NewThemeFS(options.Config) + if err != nil { + return http.Service{}, fmt.Errorf("could not initialize theme filesystem: %w", err) + } handle, err := svc.NewService( svc.Logger(options.Logger), diff --git a/services/web/pkg/service/grpc/v0/option.go b/services/web/pkg/service/grpc/v0/option.go new file mode 100644 index 0000000000..e0903033c4 --- /dev/null +++ b/services/web/pkg/service/grpc/v0/option.go @@ -0,0 +1,68 @@ +package service + +import ( + "go.opentelemetry.io/otel/trace" + + "github.com/opencloud-eu/opencloud/pkg/log" + "github.com/opencloud-eu/opencloud/pkg/x/io/fsx" + "github.com/opencloud-eu/opencloud/services/web/pkg/config" + "github.com/opencloud-eu/opencloud/services/web/pkg/theme" +) + +// Option defines a single option function. +type Option func(o *Options) + +// Options defines the available options for this package. +type Options struct { + Logger log.Logger + Config *config.Config + JWTSecret string + TracerProvider trace.TracerProvider + ThemeService *theme.Service + ThemeFS *fsx.FallbackFS +} + +func newOptions(opts ...Option) Options { + opt := Options{} + + for _, o := range opts { + o(&opt) + } + + return opt +} + +// Logger provides a function to set the Logger option. +func Logger(val log.Logger) Option { + return func(o *Options) { + o.Logger = val + } +} + +// Config provides a function to set the Config option. +func Config(val *config.Config) Option { + return func(o *Options) { + o.Config = val + } +} + +// JWTSecret provides a function to set the Config option. +func JWTSecret(val string) Option { + return func(o *Options) { + o.JWTSecret = val + } +} + +// TracerProvider provides a function to set the TracerProvider option +func TracerProvider(val trace.TracerProvider) Option { + return func(o *Options) { + o.TracerProvider = val + } +} + +// ThemeFS provides a function to set the themeFS option. +func ThemeFS(val *fsx.FallbackFS) Option { + return func(o *Options) { + o.ThemeFS = val + } +} diff --git a/services/web/pkg/service/grpc/v0/service.go b/services/web/pkg/service/grpc/v0/service.go new file mode 100644 index 0000000000..a305a1c6d7 --- /dev/null +++ b/services/web/pkg/service/grpc/v0/service.go @@ -0,0 +1,67 @@ +package service + +import ( + "archive/zip" + "bytes" + "context" + "fmt" + + "github.com/opencloud-eu/opencloud/pkg/log" + websvc "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/services/web/v0" + "github.com/opencloud-eu/opencloud/services/web/pkg/config" + "github.com/opencloud-eu/opencloud/services/web/pkg/theme" +) + +// NewHandler returns a service implementation for Service. +func NewHandler(opts ...Option) (websvc.WebServiceHandler, error) { + options := newOptions(opts...) + logger := options.Logger + cfg := options.Config + + themeService, err := theme.NewService( + theme.ServiceOptions{}. + WithThemeFS(options.ThemeFS.Primary()), + ) + if err != nil { + return nil, fmt.Errorf("could not initialize theme service: %w", err) + } + + return &Service{ + log: logger, + cfg: cfg, + themeService: themeService, + }, nil +} + +type Service struct { + log log.Logger + cfg *config.Config + themeService *theme.Service +} + +func (s Service) ThemeAdd(_ context.Context, req *websvc.ThemeAddRequest, res *websvc.ThemeAddResponse) error { + zr, err := zip.NewReader(bytes.NewReader(req.Data), int64(len(req.Data))) + if err != nil { + return err + } + + if err := s.themeService.Add(req.Id, zr); err != nil { + return fmt.Errorf("could not add theme %s: %w", req.Id, err) + } + + return nil +} + +func (s Service) ThemeRemove(_ context.Context, req *websvc.ThemeRemoveRequest, res *websvc.ThemeRemoveResponse) error { + if err := s.themeService.Remove(req.Id); err != nil { + return fmt.Errorf("could not remove theme %s: %w", req.Id, err) + } + + return nil +} + +func (s Service) ThemeExists(_ context.Context, req *websvc.ThemeExistsRequest, res *websvc.ThemeExistsResponse) error { + res.Exists = s.themeService.Exists(req.Id) + + return nil +} diff --git a/services/web/pkg/service/v0/service.go b/services/web/pkg/service/v0/service.go index a16ba5336f..a34aa33062 100644 --- a/services/web/pkg/service/v0/service.go +++ b/services/web/pkg/service/v0/service.go @@ -10,24 +10,19 @@ import ( "strings" "time" - gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" "github.com/go-chi/chi/v5" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" "github.com/riandyrn/otelchi" "github.com/opencloud-eu/opencloud/pkg/account" "github.com/opencloud-eu/opencloud/pkg/log" "github.com/opencloud-eu/opencloud/pkg/middleware" "github.com/opencloud-eu/opencloud/pkg/tracing" - "github.com/opencloud-eu/opencloud/pkg/x/io/fsx" + consoleWebService "github.com/opencloud-eu/opencloud/services/console/pkg/web" "github.com/opencloud-eu/opencloud/services/web/pkg/assets" "github.com/opencloud-eu/opencloud/services/web/pkg/config" "github.com/opencloud-eu/opencloud/services/web/pkg/theme" ) -// ErrConfigInvalid is returned when the config parse is invalid. -var ErrConfigInvalid = `Invalid or missing config` - // Service defines the service handlers. type Service interface { ServeHTTP(w http.ResponseWriter, r *http.Request) @@ -50,22 +45,28 @@ func NewService(opts ...Option) (Service, error) { ), ) - svc := Web{ - logger: options.Logger, - config: options.Config, - mux: m, - coreFS: options.CoreFS, - themeFS: options.ThemeFS, - gatewaySelector: options.GatewaySelector, - } - themeService, err := theme.NewService( theme.ServiceOptions{}. - WithThemeFS(options.ThemeFS). - WithGatewaySelector(options.GatewaySelector), + WithThemeFS(options.ThemeFS), ) if err != nil { - return svc, err + return Web{}, err + } + + themeAPI, err := theme.NewHTTP( + theme.HTTPOptions{}. + WithService(themeService). + WithLogger(options.Logger), + ) + if err != nil { + return Web{}, err + } + + svc := Web{ + logger: options.Logger, + config: options.Config, + mux: m, + themeService: themeService, } m.Route(options.Config.HTTP.Root, func(r chi.Router) { @@ -75,11 +76,9 @@ func NewService(opts ...Option) (Service, error) { account.Logger(options.Logger), account.JWTSecret(options.Config.TokenManager.JWTSecret), )) - r.Post("/", themeService.LogoUpload) - r.Delete("/", themeService.LogoReset) }) r.Route("/themes", func(r chi.Router) { - r.Get("/{id}/theme.json", themeService.Get) + r.Get("/{id}/theme.json", themeAPI.Get) r.Mount("/", svc.Static( options.ThemeFS.IOFS(), path.Join(svc.config.HTTP.Root, "/themes"), @@ -92,7 +91,7 @@ func NewService(opts ...Option) (Service, error) { options.Config.HTTP.CacheTTL, )) r.Mount("/", svc.Static( - svc.coreFS, + options.CoreFS, svc.config.HTTP.Root, options.Config.HTTP.CacheTTL, )) @@ -107,12 +106,10 @@ func NewService(opts ...Option) (Service, error) { // Web defines the handlers for the web service. type Web struct { - logger log.Logger - config *config.Config - mux *chi.Mux - coreFS fs.FS - themeFS *fsx.FallbackFS - gatewaySelector pool.Selectable[gateway.GatewayAPIClient] + logger log.Logger + config *config.Config + mux *chi.Mux + themeService *theme.Service } // ServeHTTP implements the Service interface. @@ -120,33 +117,35 @@ func (p Web) ServeHTTP(w http.ResponseWriter, r *http.Request) { p.mux.ServeHTTP(w, r) } -func (p Web) getPayload() (payload []byte, err error) { - // render dynamically using config +// Config handles HTTP requests to provide the current configuration as a JSON response. +func (p Web) Config(w http.ResponseWriter, _ *http.Request) { + // toDo: copy config to not mutate individual settings of the og (*pointer) config + conf := *p.config + // fixMe: fishy.... p.config.Web.ThemeServer == p.config.Web.Config.Server + // check if the console theme exists and apply it + if conf.Web.ThemeServer == conf.Web.Config.Server && p.themeService.Exists(consoleWebService.ThemeID) { + conf.Web.ThemePath = path.Join("themes", consoleWebService.ThemeID, "theme.json") + } // build theme url - if themeServer, err := url.Parse(p.config.Web.ThemeServer); err == nil { - p.config.Web.Config.Theme = themeServer.String() + p.config.Web.ThemePath + if themeServer, err := url.Parse(conf.Web.ThemeServer); err == nil { + themeServer.Path = conf.Web.ThemePath + conf.Web.Config.Theme = themeServer.String() } else { - p.config.Web.Config.Theme = p.config.Web.ThemePath + conf.Web.Config.Theme = conf.Web.ThemePath } - // make apps render as empty array if it is empty + // make apps render as an empty array if it is empty // TODO remove once https://github.com/golang/go/issues/27589 is fixed - if len(p.config.Web.Config.Apps) == 0 { - p.config.Web.Config.Apps = make([]string, 0) + if len(conf.Web.Config.Apps) == 0 { + conf.Web.Config.Apps = make([]string, 0) } - // ensure that the server url has a trailing slash - p.config.Web.Config.Server = strings.TrimRight(p.config.Web.Config.Server, "/") + "/" - - return json.Marshal(p.config.Web.Config) -} - -// Config implements the Service interface. -func (p Web) Config(w http.ResponseWriter, _ *http.Request) { - payload, err := p.getPayload() + payload, err := json.Marshal(conf.Web.Config) if err != nil { - http.Error(w, ErrConfigInvalid, http.StatusUnprocessableEntity) + msg := "Invalid or missing config" + p.logger.Error().Err(err).Msg(msg) + http.Error(w, msg, http.StatusUnprocessableEntity) return } diff --git a/services/web/pkg/theme/http.go b/services/web/pkg/theme/http.go new file mode 100644 index 0000000000..4612005e8e --- /dev/null +++ b/services/web/pkg/theme/http.go @@ -0,0 +1,72 @@ +package theme + +import ( + "encoding/json" + "errors" + "net/http" + + "github.com/opencloud-eu/opencloud/pkg/log" +) + +// HTTPOptions defines the options to configure HTTP. +type HTTPOptions struct { + service *Service + logger log.Logger +} + +// WithService sets the service for HTTPOptions. +func (o HTTPOptions) WithService(s *Service) HTTPOptions { + o.service = s + return o +} + +// WithLogger sets the logger for the Service. +func (o HTTPOptions) WithLogger(logger log.Logger) HTTPOptions { + o.logger = logger + return o +} + +// validate validates the input parameters. +func (o HTTPOptions) validate() error { + if o.service == nil { + return errors.New("service is required") + } + + return nil +} + +type HTTP struct { + service *Service + logger log.Logger +} + +// NewHTTP initializes a new HTTP. +func NewHTTP(options HTTPOptions) (HTTP, error) { + if err := options.validate(); err != nil { + return HTTP{}, err + } + + return HTTP(options), nil +} + +// Get renders the theme for the given ID. +func (h HTTP) Get(w http.ResponseWriter, r *http.Request) { + theme, err := h.service.Build(r.PathValue("id")) + if err != nil { + h.logger.Error().Err(err).Msg("failed to merge themes") + http.Error(w, ErrBuildingThemeFailed.Error(), http.StatusInternalServerError) + } + + b, err := json.Marshal(theme) + if err != nil { + h.logger.Error().Err(err).Msg("failed to marshal theme") + http.Error(w, ErrBuildingThemeFailed.Error(), http.StatusInternalServerError) + return + } + + if _, err = w.Write(b); err != nil { + h.logger.Error().Err(err).Msg("failed to write response") + http.Error(w, ErrBuildingThemeFailed.Error(), http.StatusInternalServerError) + return + } +} diff --git a/services/web/pkg/theme/http_test.go b/services/web/pkg/theme/http_test.go new file mode 100644 index 0000000000..28a667241b --- /dev/null +++ b/services/web/pkg/theme/http_test.go @@ -0,0 +1,57 @@ +package theme_test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "github.com/spf13/afero" + "github.com/stretchr/testify/assert" + "github.com/tidwall/gjson" + + "github.com/opencloud-eu/opencloud/pkg/x/io/fsx" + "github.com/opencloud-eu/opencloud/services/graph/pkg/unifiedrole" + "github.com/opencloud-eu/opencloud/services/web/pkg/theme" +) + +func TestHTTP_Get(t *testing.T) { + primaryFS := fsx.NewMemMapFs() + fallbackFS := fsx.NewFallbackFS(primaryFS, fsx.NewMemMapFs()) + + add := func(filename string, content interface{}) { + b, err := json.Marshal(content) + assert.Nil(t, err) + + assert.Nil(t, afero.WriteFile(primaryFS, filename, b, 0644)) + } + + // baseTheme + add("base/theme.json", map[string]interface{}{ + "base": "base", + }) + // brandingTheme + add("_branding/theme.json", map[string]interface{}{ + "_branding": "_branding", + }) + + service, err := theme.NewService(theme.ServiceOptions{}.WithThemeFS(fallbackFS)) + assert.NoError(t, err) + + handlers, err := theme.NewHTTP(theme.HTTPOptions{}.WithService(service)) + assert.NoError(t, err) + + r := httptest.NewRequest(http.MethodGet, "/", nil) + r.SetPathValue("id", "base") + + w := httptest.NewRecorder() + handlers.Get(w, r) + + jsonData := gjson.Parse(w.Body.String()) + // baseTheme + assert.Equal(t, jsonData.Get("base").String(), "base") + // brandingTheme + assert.Equal(t, jsonData.Get("_branding").String(), "_branding") + // themeDefaults + assert.Equal(t, jsonData.Get("common.shareRoles."+unifiedrole.UnifiedRoleViewerID+".name").String(), "UnifiedRoleViewer") +} diff --git a/services/web/pkg/theme/kv.go b/services/web/pkg/theme/kv.go index 1c8c7f9117..981c153840 100644 --- a/services/web/pkg/theme/kv.go +++ b/services/web/pkg/theme/kv.go @@ -1,12 +1,10 @@ package theme import ( - "bytes" "encoding/json" - "strings" + "io/fs" "dario.cat/mergo" - "github.com/spf13/afero" ) // KV is a generic key-value map. @@ -26,43 +24,15 @@ func MergeKV(values ...KV) (KV, error) { return kv, nil } -// PatchKV injects the given values into to v. -func PatchKV(v map[string]interface{}, values KV) KV { - if v == nil { - v = KV{} - } - for k, val := range values { - t := v - path := strings.Split(k, ".") - for i, p := range path { - if i == len(path)-1 { - switch val { - // if the value is nil, we delete the key - case nil: - delete(t, p) - default: - t[p] = val - } - break - } - - if _, ok := t[p]; !ok { - t[p] = map[string]interface{}{} - } - - t = t[p].(map[string]interface{}) - } - } - return v -} - // LoadKV loads a key-value map from the given file system. -func LoadKV(fsys afero.Fs, p string) (KV, error) { +func LoadKV(fsys fs.FS, p string) (KV, error) { f, err := fsys.Open(p) if err != nil { return nil, err } - defer f.Close() + defer func() { + _ = f.Close() + }() var kv KV err = json.NewDecoder(f).Decode(&kv) @@ -72,27 +42,3 @@ func LoadKV(fsys afero.Fs, p string) (KV, error) { return kv, nil } - -// WriteKV writes the given key-value map to the file system. -func WriteKV(fsys afero.Fs, p string, kv KV) error { - data, err := json.Marshal(kv) - if err != nil { - return err - } - - return afero.WriteReader(fsys, p, bytes.NewReader(data)) -} - -// UpdateKV updates the key-value map at the given path with the given values. -func UpdateKV(fsys afero.Fs, p string, values KV) error { - var kv KV - - existing, err := LoadKV(fsys, p) - if err == nil { - kv = existing - } - - kv = PatchKV(kv, values) - - return WriteKV(fsys, p, kv) -} diff --git a/services/web/pkg/theme/kv_test.go b/services/web/pkg/theme/kv_test.go index 11901619d7..b3f6b780bc 100644 --- a/services/web/pkg/theme/kv_test.go +++ b/services/web/pkg/theme/kv_test.go @@ -30,82 +30,6 @@ func TestMergeKV(t *testing.T) { }) } -func TestPatchKV(t *testing.T) { - in := theme.KV{ - "a": map[string]interface{}{ - "value": "a", - }, - "b": map[string]interface{}{ - "value": "b", - }, - } - out := theme.PatchKV(in, theme.KV{ - "b.value": "b-new", - "c.value": "c-new", - "d": "d-new", - "e.value.subvalue": "e-new", - }) - assert.Equal(t, theme.KV{ - "a": map[string]interface{}{ - "value": "a", - }, - "b": map[string]interface{}{ - "value": "b-new", - }, - "c": map[string]interface{}{ - "value": "c-new", - }, - "d": "d-new", - "e": map[string]interface{}{ - "value": map[string]interface{}{ - "subvalue": "e-new", - }, - }, - }, out) -} - -func TestPatchKVUnset(t *testing.T) { - in := theme.KV{ - "a": map[string]interface{}{ - "value": "a", - }, - "b": map[string]interface{}{ - "value": "b", - }, - } - out := theme.PatchKV(in, theme.KV{ - "a.value": nil, - "b": nil, - }) - assert.Equal(t, theme.KV{ - "a": map[string]interface{}{}, - }, out) -} - -func TestPatchKVwithNil(t *testing.T) { - var in theme.KV - out := theme.PatchKV(in, theme.KV{ - "b.value": "b-new", - "c.value": "c-new", - "d": "d-new", - "e.value.subvalue": "e-new", - }) - assert.Equal(t, theme.KV{ - "b": map[string]interface{}{ - "value": "b-new", - }, - "c": map[string]interface{}{ - "value": "c-new", - }, - "d": "d-new", - "e": map[string]interface{}{ - "value": map[string]interface{}{ - "subvalue": "e-new", - }, - }, - }, out) -} - func TestLoadKV(t *testing.T) { in := theme.KV{ "a": map[string]interface{}{ @@ -121,66 +45,7 @@ func TestLoadKV(t *testing.T) { fsys := fsx.NewMemMapFs() assert.Nil(t, afero.WriteFile(fsys, "some.json", b, 0644)) - out, err := theme.LoadKV(fsys, "some.json") - assert.Nil(t, err) - assert.Equal(t, in, out) -} - -func TestWriteKV(t *testing.T) { - in := theme.KV{ - "a": map[string]interface{}{ - "value": "a", - }, - "b": map[string]interface{}{ - "value": "b", - }, - } - - fsys := fsx.NewMemMapFs() - assert.Nil(t, theme.WriteKV(fsys, "some.json", in)) - - f, err := fsys.Open("some.json") + out, err := theme.LoadKV(fsys.IOFS(), "some.json") assert.Nil(t, err) - - var out theme.KV - assert.Nil(t, json.NewDecoder(f).Decode(&out)) assert.Equal(t, in, out) } - -func TestUpdateKV(t *testing.T) { - fileKV := theme.KV{ - "a": map[string]interface{}{ - "value": "a", - }, - "b": map[string]interface{}{ - "value": "b", - }, - } - - wb, err := json.Marshal(fileKV) - assert.Nil(t, err) - - fsys := fsx.NewMemMapFs() - assert.Nil(t, afero.WriteFile(fsys, "some.json", wb, 0644)) - _ = theme.UpdateKV(fsys, "some.json", theme.KV{ - "b.value": "b-new", - "c.value": "c-new", - }) - - f, err := fsys.Open("some.json") - assert.Nil(t, err) - - var out theme.KV - assert.Nil(t, json.NewDecoder(f).Decode(&out)) - assert.Equal(t, out, theme.KV{ - "a": map[string]interface{}{ - "value": "a", - }, - "b": map[string]interface{}{ - "value": "b-new", - }, - "c": map[string]interface{}{ - "value": "c-new", - }, - }) -} diff --git a/services/web/pkg/theme/service.go b/services/web/pkg/theme/service.go index 511671614c..1bce1d29f4 100644 --- a/services/web/pkg/theme/service.go +++ b/services/web/pkg/theme/service.go @@ -1,17 +1,12 @@ package theme import ( - "encoding/json" - "net/http" + "archive/zip" + "io" + "os" + "path/filepath" - gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" - permissionsapi "github.com/cs3org/go-cs3apis/cs3/permissions/v1beta1" - rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" "github.com/pkg/errors" - "github.com/spf13/afero" - - revactx "github.com/opencloud-eu/reva/v2/pkg/ctx" - "github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool" "github.com/opencloud-eu/opencloud/pkg/x/io/fsx" "github.com/opencloud-eu/opencloud/pkg/x/path/filepathx" @@ -19,57 +14,49 @@ import ( // ServiceOptions defines the options to configure the Service. type ServiceOptions struct { - themeFS *fsx.FallbackFS - gatewaySelector pool.Selectable[gateway.GatewayAPIClient] + themeFS fsx.FS } // WithThemeFS sets the theme filesystem. -func (o ServiceOptions) WithThemeFS(fSys *fsx.FallbackFS) ServiceOptions { +func (o ServiceOptions) WithThemeFS(fSys fsx.FS) ServiceOptions { o.themeFS = fSys return o } -// WithGatewaySelector sets the gateway selector. -func (o ServiceOptions) WithGatewaySelector(gws pool.Selectable[gateway.GatewayAPIClient]) ServiceOptions { - o.gatewaySelector = gws - return o -} - // validate validates the input parameters. func (o ServiceOptions) validate() error { if o.themeFS == nil { return errors.New("themeFS is required") } - if o.gatewaySelector == nil { - return errors.New("gatewaySelector is required") - } - return nil } // Service defines the http service. type Service struct { - themeFS *fsx.FallbackFS - gatewaySelector pool.Selectable[gateway.GatewayAPIClient] + themeFS fsx.FS } // NewService initializes a new Service. -func NewService(options ServiceOptions) (Service, error) { +func NewService(options ServiceOptions) (*Service, error) { if err := options.validate(); err != nil { - return Service{}, err + return nil, err } - return Service(options), nil + return &Service{ + themeFS: options.themeFS, + }, nil } -// Get renders the theme, the theme is a merge of the default theme, the base theme, and the branding theme. -func (s Service) Get(w http.ResponseWriter, r *http.Request) { +// Build builds the theme, the theme is a merge of the default theme, the base theme, and the branding theme. +func (s Service) Build(id string) (KV, error) { + themeFS := s.themeFS.IOFS() + // there is no guarantee that the theme exists, its optional; therefore, we ignore the error - baseTheme, _ := LoadKV(s.themeFS, filepathx.JailJoin(r.PathValue("id"), _themeFileName)) + baseTheme, _ := LoadKV(themeFS, filepathx.JailJoin(id, _themeFileName)) // there is no guarantee that the theme exists, its optional; therefore, we ignore the error here too - brandingTheme, _ := LoadKV(s.themeFS, filepathx.JailJoin(_brandingRoot, _themeFileName)) + brandingTheme, _ := LoadKV(themeFS, filepathx.JailJoin(_brandingRoot, _themeFileName)) // merge the themes, the order is important, the last one wins and overrides the previous ones // themeDefaults: contains all the default values, this is guaranteed to exist @@ -78,118 +65,63 @@ func (s Service) Get(w http.ResponseWriter, r *http.Request) { // mergedTheme = themeDefaults < baseTheme < brandingTheme mergedTheme, err := MergeKV(themeDefaults, baseTheme, brandingTheme) if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return + return nil, errors.Wrap(err, "failed to merge themes") } - b, err := json.Marshal(mergedTheme) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } + return mergedTheme, nil +} - _, err = w.Write(b) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } +func (s Service) Exists(id string) bool { + info, err := s.themeFS.Stat(filepathx.JailJoin(id, _themeFileName)) + return err == nil && !info.IsDir() && info.Size() > 0 } -// LogoUpload implements the endpoint to upload a custom logo for the OpenCloud instance. -func (s Service) LogoUpload(w http.ResponseWriter, r *http.Request) { - gatewayClient, err := s.gatewaySelector.Next() - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return +func (s Service) Remove(id string) error { + if !s.Exists(id) { + return errors.Errorf("theme %s does not exist", id) } - user := revactx.ContextMustGetUser(r.Context()) - rsp, err := gatewayClient.CheckPermission(r.Context(), &permissionsapi.CheckPermissionRequest{ - Permission: "Logo.Write", - SubjectRef: &permissionsapi.SubjectReference{ - Spec: &permissionsapi.SubjectReference_UserId{ - UserId: user.GetId(), - }, - }, - }) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - if rsp.GetStatus().GetCode() != rpc.Code_CODE_OK { - w.WriteHeader(http.StatusForbidden) - return - } + // remove the theme directory + return s.themeFS.RemoveAll(id) +} - file, fileHeader, err := r.FormFile("logo") - if err != nil { - if errors.Is(err, http.ErrMissingFile) { - w.WriteHeader(http.StatusBadRequest) - } - w.WriteHeader(http.StatusInternalServerError) - return +func (s Service) Add(id string, r *zip.Reader) error { + if s.Exists(id) { + return errors.Errorf("theme %s already exists", id) } - defer file.Close() - if !isFiletypePermitted(fileHeader.Filename, fileHeader.Header.Get("Content-Type")) { - w.WriteHeader(http.StatusBadRequest) - return - } + for _, f := range r.File { + filePath := filepath.Join(id, f.Name) + if f.FileInfo().IsDir() { + err := s.themeFS.MkdirAll(filePath, os.ModePerm) + if err != nil { + return err + } - fp := filepathx.JailJoin(_brandingRoot, fileHeader.Filename) - err = afero.WriteReader(s.themeFS, fp, file) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } + continue + } - err = UpdateKV(s.themeFS, filepathx.JailJoin(_brandingRoot, _themeFileName), KV{ - "common.logo": filepathx.JailJoin("themes", fp), - "clients.web.defaults.logo": filepathx.JailJoin("themes", fp), - }) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } + if err := s.themeFS.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil { + return err + } - w.WriteHeader(http.StatusOK) -} + source, err := f.Open() + if err != nil { + return err + } -// LogoReset implements the endpoint to reset the instance logo. -// The config will be changed back to use the embedded logo asset. -func (s Service) LogoReset(w http.ResponseWriter, r *http.Request) { - gatewayClient, err := s.gatewaySelector.Next() - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } + dest, err := s.themeFS.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode()) + if err != nil { + return err + } - user := revactx.ContextMustGetUser(r.Context()) - rsp, err := gatewayClient.CheckPermission(r.Context(), &permissionsapi.CheckPermissionRequest{ - Permission: "Logo.Write", - SubjectRef: &permissionsapi.SubjectReference{ - Spec: &permissionsapi.SubjectReference_UserId{ - UserId: user.GetId(), - }, - }, - }) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return - } - if rsp.GetStatus().GetCode() != rpc.Code_CODE_OK { - w.WriteHeader(http.StatusForbidden) - return - } + if _, err := io.Copy(dest, source); err != nil { + return err + } - err = UpdateKV(s.themeFS, filepathx.JailJoin(_brandingRoot, _themeFileName), KV{ - "common.logo": nil, - "clients.web.defaults.logo": nil, - }) - if err != nil { - w.WriteHeader(http.StatusInternalServerError) - return + _ = dest.Close() + _ = source.Close() } - w.WriteHeader(http.StatusOK) + return nil } diff --git a/services/web/pkg/theme/service_test.go b/services/web/pkg/theme/service_test.go index ca392582df..9418da4b2f 100644 --- a/services/web/pkg/theme/service_test.go +++ b/services/web/pkg/theme/service_test.go @@ -1,19 +1,11 @@ package theme_test import ( - "encoding/json" - "net/http" - "net/http/httptest" "testing" - gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1" - "github.com/spf13/afero" "github.com/stretchr/testify/assert" - "github.com/tidwall/gjson" "github.com/opencloud-eu/opencloud/pkg/x/io/fsx" - "github.com/opencloud-eu/opencloud/services/graph/mocks" - "github.com/opencloud-eu/opencloud/services/graph/pkg/unifiedrole" "github.com/opencloud-eu/opencloud/services/web/pkg/theme" ) @@ -26,49 +18,8 @@ func TestNewService(t *testing.T) { t.Run("success if the options are valid", func(t *testing.T) { _, err := theme.NewService( theme.ServiceOptions{}. - WithThemeFS(fsx.NewFallbackFS(fsx.NewMemMapFs(), fsx.NewMemMapFs())). - WithGatewaySelector(mocks.NewSelectable[gateway.GatewayAPIClient](t)), + WithThemeFS(fsx.NewFallbackFS(fsx.NewMemMapFs(), fsx.NewMemMapFs())), ) assert.NoError(t, err) }) } - -func TestService_Get(t *testing.T) { - primaryFS := fsx.NewMemMapFs() - fallbackFS := fsx.NewFallbackFS(primaryFS, fsx.NewMemMapFs()) - - add := func(filename string, content interface{}) { - b, err := json.Marshal(content) - assert.Nil(t, err) - - assert.Nil(t, afero.WriteFile(primaryFS, filename, b, 0644)) - } - - // baseTheme - add("base/theme.json", map[string]interface{}{ - "base": "base", - }) - // brandingTheme - add("_branding/theme.json", map[string]interface{}{ - "_branding": "_branding", - }) - - service, _ := theme.NewService( - theme.ServiceOptions{}. - WithThemeFS(fallbackFS). - WithGatewaySelector(mocks.NewSelectable[gateway.GatewayAPIClient](t)), - ) - r := httptest.NewRequest(http.MethodGet, "/", nil) - r.SetPathValue("id", "base") - - w := httptest.NewRecorder() - service.Get(w, r) - - jsonData := gjson.Parse(w.Body.String()) - // baseTheme - assert.Equal(t, jsonData.Get("base").String(), "base") - // brandingTheme - assert.Equal(t, jsonData.Get("_branding").String(), "_branding") - // themeDefaults - assert.Equal(t, jsonData.Get("common.shareRoles."+unifiedrole.UnifiedRoleViewerID+".name").String(), "UnifiedRoleViewer") -} diff --git a/services/web/pkg/theme/theme.go b/services/web/pkg/theme/theme.go index 56f190d04e..af23ccb788 100644 --- a/services/web/pkg/theme/theme.go +++ b/services/web/pkg/theme/theme.go @@ -1,6 +1,7 @@ package theme import ( + "errors" "path" "github.com/opencloud-eu/opencloud/pkg/capabilities" @@ -8,8 +9,9 @@ import ( ) var ( - _brandingRoot = "_branding" - _themeFileName = "theme.json" + _brandingRoot = "_branding" + _themeFileName = "theme.json" + ErrBuildingThemeFailed = errors.New("building theme failed") ) // themeDefaults contains the default values for the theme. diff --git a/vendor/github.com/centrifugal/centrifuge-go/.gitignore b/vendor/github.com/centrifugal/centrifuge-go/.gitignore new file mode 100644 index 0000000000..d6bad99da6 --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/.gitignore @@ -0,0 +1,34 @@ +.DS_Store +vendor/ + +# Compiled Object files, Static and Dynamic libs (Shared Objects) +*.o +*.a +*.so + +# Folders +_obj +_test + +# Architecture specific extensions/prefixes +*.[568vq] +[568vq].out + +*.cgo1.go +*.cgo2.c +_cgo_defun.c +_cgo_gotypes.go +_cgo_export.* + +_testmain.go + +*.exe +*.test +*.prof + +.idea/ +.vscode/ + +*.orig +examples/benchmark/benchmark +local/ \ No newline at end of file diff --git a/vendor/github.com/centrifugal/centrifuge-go/LICENSE b/vendor/github.com/centrifugal/centrifuge-go/LICENSE new file mode 100644 index 0000000000..624d2f8f73 --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Centrifugal Labs LTD + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/centrifugal/centrifuge-go/README.md b/vendor/github.com/centrifugal/centrifuge-go/README.md new file mode 100644 index 0000000000..3ddb665e0b --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/README.md @@ -0,0 +1,67 @@ +[![GoDoc](https://pkg.go.dev/badge/centrifugal/centrifuge-go)](https://pkg.go.dev/github.com/centrifugal/centrifuge-go) + +Websocket client for [Centrifugo](https://github.com/centrifugal/centrifugo) server and [Centrifuge](https://github.com/centrifugal/centrifuge) library. + +There is no v1 release of this library yet – API still evolves. At the moment patch version updates only contain backwards compatible changes, minor version updates can have backwards incompatible API changes. + +Check out [client SDK API specification](https://centrifugal.dev/docs/transports/client_api) to learn how this SDK behaves. It's recommended to read that before starting to work with this SDK as the spec covers common SDK behavior - describes client and subscription state transitions, main options and methods. Also check out examples folder. + +The features implemented by this SDK can be found in [SDK feature matrix](https://centrifugal.dev/docs/transports/client_sdk#sdk-feature-matrix). + +> **The latest `centrifuge-go` is compatible with [Centrifugo](https://github.com/centrifugal/centrifugo) server v6, v5 and v4, and [Centrifuge](https://github.com/centrifugal/centrifuge) >= 0.25.0. For Centrifugo v2, Centrifugo v3 and Centrifuge < 0.25.0 you should use `centrifuge-go` v0.8.x.** + +## Callbacks should not block + +When using this SDK you should not block for a long time inside event handlers since handlers called synchronously by the SDK and block the connection read loop. The fact that the read loop is blocked also means that you can not issue blocking `Client` requests such as `Publish`, `RPC`, `History`, `Presence`, `PresenceStats` from the event handler code – this will result into a deadlock. Use a separate goroutine if you really need to issue a blocking call from inside an event handler. + +I.e. this code is broken: + +```go +client.OnMessage(func(e centrifuge.MessageEvent) { + result, err := c.RPC(context.Background(), "method", []byte("{}")) + if err != nil { + log.Println(err) + return + } + // Will never be called. + log.Printf("RPC result: %s", string(result.Data)) +}) +``` + +This code is correct as it does not block event handler forever: + +```go +client.OnMessage(func(e centrifuge.MessageEvent) { + // When issue blocking requests from inside event handler we must use + // a goroutine. Otherwise, we will ge a deadlock since the connection + // read loop is blocked. + go func() { + result, err := c.RPC(context.Background(), "method", []byte("{}")) + if err != nil { + log.Println(err) + return + } + log.Printf("RPC result: %s", string(result.Data)) + }() +}) +``` + +You can find similar limitations in [eclipse/paho.mqtt.golang](https://github.com/eclipse/paho.mqtt.golang#common-problems). In short, this is caused by a challenging mix of asynchronous protocol, Go and callback approach. In the previous versions of this SDK we allowed blocking requests from within event handlers – but it contradicts with the real-time nature of Centrifugal ecosystem, because we had to use separate callback queue, and that queue could grow huge without a reasonable way to backpressure (which we were not able to find). + +If you are calling `Publish`, `RPC`, `History`, `Presence`, `PresenceStats` from the outside of event handler – you should not do any special care. Also, if you are calling your own blocking APIs from inside Centrifuge event handlers – you won't get the deadlock, but the read loop of the underlying connection will not proceed till the event handler returns. + +## Run tests + +First run Centrifugo instance: + +``` +docker run -it --rm -p 8000:8000 \ +-e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_DELTA_PUBLISH=true \ +-e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_ALLOWED_DELTA_TYPES="fossil" \ +-e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_HISTORY_SIZE="100" \ +-e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_HISTORY_TTL="300s" \ +-e CENTRIFUGO_CHANNEL_WITHOUT_NAMESPACE_FORCE_RECOVERY="true" \ +centrifugo/centrifugo:v6 centrifugo --client.insecure +``` + +Then run `go test` diff --git a/vendor/github.com/centrifugal/centrifuge-go/changelog.md b/vendor/github.com/centrifugal/centrifuge-go/changelog.md new file mode 100644 index 0000000000..ddeb2e72b3 --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/changelog.md @@ -0,0 +1,189 @@ +v0.10.0 +======= + +**Breaking change!** This release changes the semantics of working with connection tokens described in [Centrifugo v5 release post](https://centrifugal.dev/blog/2023/06/29/centrifugo-v5-released#token-behaviour-adjustments-in-sdks). + +Previously, returning an empty token string from `Config.GetToken` callback resulted in client disconnection with unauthorized reason. + +Now returning an empty string from `Config.GetToken` is a valid scenario which won't result into disconnect on the client side. It's still possible to disconnect client by returning a special error `ErrUnauthorized` from `GetToken` function. + +And we are putting back `Client.SetToken` method to the SDK – so it's now possible to reset the token to be empty upon user logout. + +v0.9.6 +====== + +* Properly handle disconnect push + +v0.9.5 +====== + +* Update protocol package to the latest one. + +v0.9.4 +====== + +* Fix wrong unsubscribe code handling – see commit. According to spec unsubscribe codes >= 2500 should result into resubscribe from the SDK side, centrifuge-go did not follow this, instead it never resubscribed upon receiving such codes from the server. Thus message recovery and automatic resubscribe did not work correctly. + +v0.9.3 +====== + +* Fix leaking connection when getting `token expired` error upon connect. + +v0.9.2 +====== + +* Fix Unlock of unlocked RWMutex panic when sending connect command and getting an error from it. + +v0.9.1 +====== + +* Fix setting `SubscriptionConfig.GetToken` - [#66](https://github.com/centrifugal/centrifuge-go/pull/66) + +v0.9.0 +====== + +This release adopts a new iteration of Centrifugal protocol and a new iteration of API. Client now behaves according to the client [SDK API specification](https://centrifugal.dev/docs/transports/client_api). The work has been done according to [Centrifugo v4 roadmap](https://github.com/centrifugal/centrifugo/issues/500). + +Check out [Centrifugo v4 release post](https://centrifugal.dev/blog/2022/07/19/centrifugo-v4-released) that covers the reasoning behind changes here. + +New release only works with Centrifugo >= v4.0.0 and [Centrifuge](https://github.com/centrifugal/centrifuge) >= 0.25.0. See [Centrifugo v4 migration guide](https://centrifugal.dev/docs/getting-started/migration_v4) for details about the changes in the ecosystem. + +Note, that Centrifugo v4 supports clients working over the previous protocol iteration, so you can update Centrifugo to v4 without any changes on the client side (but you need to turn on `use_client_protocol_v1_by_default` option in the configuration of Centrifugo, see Centrifugo v4 migration guide for details). + +Important change is that `centrifuge-go` **does not allow blocking calls from inside event handlers now**. See [a description in README](https://github.com/centrifugal/centrifuge-go/tree/master#callbacks-should-not-block). + +v0.8.3 +====== + +* Call OnServerSubscribe handler correctly for dynamic server subscriptions (happening after initial connect), see [#64](https://github.com/centrifugal/centrifuge-go/pull/64). + +v0.8.2 +====== + +* Update protocol to v0.7.3 + +v0.8.1 +====== + +* Support for History reverse option. + +``` +gorelease -base v0.8.0 -version v0.8.1 +github.com/centrifugal/centrifuge-go +------------------------------------ +Compatible changes: +- HistoryOptions.Reverse: added +- WithHistoryReverse: added + +v0.8.1 is a valid semantic version for this release. +``` + +v0.8.0 +====== + +Update to work with Centrifuge >= v0.18.0 and Centrifugo v3. + +Keep in mind that `New` is deprecated now, prefer using `NewJsonClient` or `NewProtobufClient` when server is based on Centrifuge >= v0.18.0 or Centrifugo >= v3.0.0 + +**Breaking change:** client History API behavior changed – Centrifuge >= v0.18.0 and Centrifugo >= v3.0.0 won't return all publications in a stream by default, see Centrifuge [v0.18.0 release notes](https://github.com/centrifugal/centrifuge/releases/tag/v0.18.0) or [Centrifugo v3 migration guide](https://centrifugal.dev/docs/getting-started/migration_v3) for more information and workaround on server-side. + +``` +gorelease -base v0.7.2 -version v0.8.0 +github.com/centrifugal/centrifuge-go +------------------------------------ +Incompatible changes: +- (*Client).History: changed from func(string) (HistoryResult, error) to func(string, ...HistoryOption) (HistoryResult, error) +- (*Subscription).History: changed from func() (HistoryResult, error) to func(...HistoryOption) (HistoryResult, error) +- (*Subscription).Subscribe: changed from func() error to func(...SubscribeOption) error +Compatible changes: +- HistoryOption: added +- HistoryOptions: added +- NewJsonClient: added +- NewProtobufClient: added +- StreamPosition: added +- SubscribeOption: added +- SubscribeOptions: added +- WithHistoryLimit: added +- WithHistorySince: added +- WithSubscribeSince: added + +v0.8.0 is a valid semantic version for this release. +``` + +v0.7.2 +====== + +* Bump protocol to v0.5.0 [#56](https://github.com/centrifugal/centrifuge-go/pull/56) + +v0.7.1 +====== + +* Fix atomic align on 32-bit [#49](https://github.com/centrifugal/centrifuge-go/pull/49) + +v0.7.0 +====== + +* Updated `github.com/centrifugal/protocol` package dependency to catch up with the latest changes in it +* Introduced `Error` type which is used where we previously exposed `protocol.Error` – so there is no need to import `protocol` package in application code to investigate error code or message +* Methods `Client.SetName` and `Client.SetVersion` removed in favour of `Name` and `Version` fields of `Config` +* Add top-level methods `Client.History`, `Client.Presence`, `Client.PresenceStats` – so it's possible to call corresponding client API methods when using server-side subscriptions + +``` +$ gorelease -base v0.6.5 -version v0.7.0 +github.com/centrifugal/centrifuge-go +------------------------------------ +Incompatible changes: +- (*Client).SetName: removed +- (*Client).SetVersion: removed +Compatible changes: +- (*Client).History: added +- (*Client).Presence: added +- (*Client).PresenceStats: added +- Config.Name: added +- Config.Version: added +- DefaultName: added +- Error: added + +v0.7.0 is a valid semantic version for this release. +``` + +v0.6.5 +====== + +* One more fix for memory align on 32bit arch, see [#46](https://github.com/centrifugal/centrifuge-go/pull/46) + +v0.6.4 +====== + +* Add `Subscription.Close` method to close Subscription when it's not needed anymore. This method unsubscribes from a channel and removes Subscription from internal `Client` subscription registry – thus freeing resources. Subscription is not usable after `Close` called. This method can be helpful if you work with lots of short-living subscriptions to different channels to prevent unlimited internal Subscription registry growth. + +v0.6.3 +====== + +* Fix memory align on 32bit arch, see [#40](https://github.com/centrifugal/centrifuge-go/pull/40) + +v0.6.2 +====== + +* fix deadlock on a private channel resubscribe - see [#38](https://github.com/centrifugal/centrifuge-go/pull/38) + +v0.6.1 +====== + +* fix setting server-side unsubscribe handler, call server-side unsubscribe event on disconnect + +v0.6.0 +====== + +* server-side subscriptions support +* get rid of Protobuf protocol struct `Publication` and `ClientInfo` aliases – use library scope structures instead +* change return values of `RPC`, `NamedRPC`, `History`, `Presence`, `PresenceStats`, `Publish` methods to be more meaningful and extensible +* much faster resubscribe to many subscriptions (previously we waited for each individual subscription response before moving further, now process is asynchronous) +* improved reconnect logic +* Client and Subscription status refactoring +* fix inconsistent join/subscribe event ordering – now both processed in order coming from server + +v0.5.2 +====== + +* `NamedRPC` method added - [#35](https://github.com/centrifugal/centrifuge-go/pull/35), thanks [@L11R](https://github.com/L11R) diff --git a/vendor/github.com/centrifugal/centrifuge-go/client.go b/vendor/github.com/centrifugal/centrifuge-go/client.go new file mode 100644 index 0000000000..dd2571fd4b --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/client.go @@ -0,0 +1,2132 @@ +package centrifuge + +import ( + "context" + "encoding/json" + "errors" + "fmt" + "io" + "math/rand" + "net/http" + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + "github.com/centrifugal/protocol" + "google.golang.org/protobuf/encoding/protojson" +) + +// State of client connection. +type State string + +// Describe client connection states. +const ( + StateDisconnected State = "disconnected" + StateConnecting State = "connecting" + StateConnected State = "connected" + StateClosed State = "closed" +) + +// Client represents client connection to Centrifugo or Centrifuge +// library based server. It provides methods to set various event +// handlers, subscribe channels, call RPC commands etc. Call client +// Connect method to trigger actual connection with a server. Call client +// Close method to clean up state when you don't need client instance +// anymore. +type Client struct { + futureID uint64 + cmdID uint32 + mu sync.RWMutex + endpoints []string + round int + protocolType protocol.Type + config Config + token string + data protocol.Raw + transport transport + disconnectedCh chan struct{} + state State + subs map[string]*Subscription + serverSubs map[string]*serverSub + requestsMu sync.RWMutex + requests map[uint32]request + receive chan []byte + reconnectAttempts int + reconnectStrategy reconnectStrategy + events *eventHub + sendPong bool + delayPing chan struct{} + closeCh chan struct{} + connectFutures map[uint64]connectFuture + cbQueue *cbQueue + reconnectTimer *time.Timer + refreshTimer *time.Timer + refreshRequired bool + logCh chan LogEntry + logCloseCh chan struct{} + logCloseOnce sync.Once +} + +// NewJsonClient initializes Client which uses JSON-based protocol internally. +// After client initialized call Client.Connect method. Use Client.NewSubscription to +// create Subscription objects. +// The provided endpoint must be a valid URL with ws:// or wss:// scheme – otherwise +// NewJsonClient will panic. +func NewJsonClient(endpoint string, config Config) *Client { + return newClient(endpoint, false, config) +} + +// NewProtobufClient initializes Client which uses Protobuf-based protocol internally. +// After client initialized call Client.Connect method. Use Client.NewSubscription to +// create Subscription objects. +// The provided endpoint must be a valid URL with ws:// or wss:// scheme – otherwise +// NewProtobufClient will panic. +func NewProtobufClient(endpoint string, config Config) *Client { + return newClient(endpoint, true, config) +} + +func (c *Client) logLevelEnabled(level LogLevel) bool { + return c.config.LogLevel > LogLevelNone && level >= c.config.LogLevel +} + +func (c *Client) log(level LogLevel, message string, fields map[string]string) { + logEntry := LogEntry{ + Level: level, + Message: message, + Fields: fields, + } + select { + case c.logCh <- logEntry: + default: + // If log channel is full, drop the log entry. + } +} + +func (c *Client) handleLogs() { + for { + select { + case entry := <-c.logCh: + c.config.LogHandler(entry) + case <-c.logCloseCh: + return + } + } +} + +func (c *Client) traceOutCmd(cmd *protocol.Command) { + jsonBytes, err := json.Marshal(cmd) + if err != nil { + jsonBytes, _ = protojson.Marshal(cmd) + } + c.log(LogLevelTrace, "-out->", map[string]string{"command": string(jsonBytes)}) +} + +func (c *Client) traceInReply(rep *protocol.Reply) { + jsonBytes, err := json.Marshal(rep) + if err != nil { + jsonBytes, _ = protojson.Marshal(rep) + } + c.log(LogLevelTrace, "<-in--", map[string]string{"reply": string(jsonBytes)}) +} + +func (c *Client) traceInPush(push *protocol.Push) { + jsonBytes, err := json.Marshal(push) + if err != nil { + jsonBytes, _ = protojson.Marshal(push) + } + c.log(LogLevelTrace, "<-in--", map[string]string{"push": string(jsonBytes)}) +} + +func newClient(endpoint string, isProtobuf bool, config Config) *Client { + if config.ReadTimeout == 0 { + config.ReadTimeout = 5 * time.Second + } + if config.WriteTimeout == 0 { + config.WriteTimeout = time.Second + } + if config.HandshakeTimeout == 0 { + config.HandshakeTimeout = time.Second + } + if config.MaxServerPingDelay == 0 { + config.MaxServerPingDelay = 10 * time.Second + } + if config.Header == nil { + config.Header = http.Header{} + } + if config.Name == "" { + config.Name = "go" + } + + // We support setting multiple endpoints to try in round-robin fashion. But + // for now this feature is not documented and used for internal tests. In most + // cases there should be a single public server WS endpoint. + endpoints := strings.Split(endpoint, ",") + if len(endpoints) == 0 { + panic("connection endpoint required") + } + rand.Shuffle(len(endpoints), func(i, j int) { + endpoints[i], endpoints[j] = endpoints[j], endpoints[i] + }) + for _, e := range endpoints { + if !strings.HasPrefix(e, "ws") { + panic(fmt.Sprintf("unsupported connection endpoint: %s", e)) + } + } + + protocolType := protocol.TypeJSON + if isProtobuf { + protocolType = protocol.TypeProtobuf + } + + client := &Client{ + endpoints: endpoints, + config: config, + state: StateDisconnected, + protocolType: protocolType, + subs: make(map[string]*Subscription), + serverSubs: make(map[string]*serverSub), + requests: make(map[uint32]request), + reconnectStrategy: newBackoffReconnect(config.MinReconnectDelay, config.MaxReconnectDelay), + delayPing: make(chan struct{}, 32), + events: newEventHub(), + connectFutures: make(map[uint64]connectFuture), + token: config.Token, + data: config.Data, + logCh: make(chan LogEntry, 256), + logCloseCh: make(chan struct{}), + } + + // Queue to run callbacks on. + client.cbQueue = &cbQueue{ + closeCh: make(chan struct{}), + } + client.cbQueue.cond = sync.NewCond(&client.cbQueue.mu) + go client.cbQueue.dispatch() + if client.config.LogLevel > 0 { + go client.handleLogs() + } + return client +} + +// Connect dials to server and sends connect message. Will return an error if first +// dial with a server failed. In case of failure client will automatically reconnect. +// To temporary disconnect from a server call Client.Disconnect. +func (c *Client) Connect() error { + return c.startConnecting() +} + +// Disconnect client from server. It's still possible to connect again later. If +// you don't need Client anymore – use Client.Close. +func (c *Client) Disconnect() error { + if c.isClosed() { + return ErrClientClosed + } + c.moveToDisconnected(disconnectedDisconnectCalled, "disconnect called") + return nil +} + +// Close closes Client and cleanups resources. Client is unusable after this. Use this +// method if you don't need client anymore, otherwise look at Client.Disconnect. +func (c *Client) Close() { + if c.isClosed() { + return + } + c.moveToDisconnected(disconnectedDisconnectCalled, "disconnect called") + c.moveToClosed() + c.logCloseOnce.Do(func() { + close(c.logCloseCh) + }) +} + +// State returns current Client state. Note that while you are processing +// this state - Client can move to a new one. +func (c *Client) State() State { + c.mu.RLock() + defer c.mu.RUnlock() + return c.state +} + +// SetToken allows updating Client's connection token. +func (c *Client) SetToken(token string) { + c.mu.Lock() + c.token = token + c.mu.Unlock() +} + +// NewSubscription allocates new Subscription on a channel. As soon as Subscription +// successfully created Client keeps reference to it inside internal map registry to +// manage automatic resubscribe on reconnect. After creating Subscription call its +// Subscription.Subscribe method to actually start subscribing process. To temporarily +// unsubscribe call Subscription.Unsubscribe. If you finished with Subscription then +// you can remove it from the internal registry by calling Client.RemoveSubscription +// method. +func (c *Client) NewSubscription(channel string, config ...SubscriptionConfig) (*Subscription, error) { + c.mu.Lock() + defer c.mu.Unlock() + var sub *Subscription + if _, ok := c.subs[channel]; ok { + return nil, ErrDuplicateSubscription + } + sub = newSubscription(c, channel, config...) + c.subs[channel] = sub + return sub, nil +} + +// RemoveSubscription removes Subscription from the internal client registry. +// Make sure Subscription is in unsubscribed state before removing it. +func (c *Client) RemoveSubscription(sub *Subscription) error { + if sub.State() != SubStateUnsubscribed { + return errors.New("subscription must be unsubscribed to be removed") + } + c.mu.Lock() + defer c.mu.Unlock() + delete(c.subs, sub.Channel) + return nil +} + +// GetSubscription allows getting Subscription from the internal client registry. +func (c *Client) GetSubscription(channel string) (*Subscription, bool) { + c.mu.RLock() + defer c.mu.RUnlock() + s, ok := c.subs[channel] + return s, ok +} + +// Subscriptions returns a map with all currently registered client-side subscriptions. +func (c *Client) Subscriptions() map[string]*Subscription { + subs := make(map[string]*Subscription) + c.mu.Lock() + defer c.mu.Unlock() + for k, v := range c.subs { + subs[k] = v + } + return subs +} + +// Send message to server without waiting for response. +// Message handler must be registered on server. +func (c *Client) Send(ctx context.Context, data []byte) error { + if c.isClosed() { + return ErrClientClosed + } + errCh := make(chan error, 1) + c.onConnect(func(err error) { + if err != nil { + errCh <- err + return + } + select { + case <-ctx.Done(): + errCh <- ctx.Err() + return + default: + } + cmd := &protocol.Command{} + params := &protocol.SendRequest{ + Data: data, + } + cmd.Send = params + errCh <- c.send(cmd) + }) + + select { + case <-ctx.Done(): + return ctx.Err() + case err := <-errCh: + return err + } +} + +// RPCResult contains data returned from server as RPC result. +type RPCResult struct { + Data []byte +} + +// RPC allows sending data to a server and waiting for a response. +// RPC handler must be registered on server. +func (c *Client) RPC(ctx context.Context, method string, data []byte) (RPCResult, error) { + if c.isClosed() { + return RPCResult{}, ErrClientClosed + } + resCh := make(chan RPCResult, 1) + errCh := make(chan error, 1) + c.sendRPC(ctx, method, data, func(result RPCResult, err error) { + resCh <- result + errCh <- err + }) + + select { + case <-ctx.Done(): + return RPCResult{}, ctx.Err() + case res := <-resCh: + return res, <-errCh + } +} + +func (c *Client) nextCmdID() uint32 { + return atomic.AddUint32(&c.cmdID, 1) +} + +func (c *Client) isConnected() bool { + c.mu.RLock() + defer c.mu.RUnlock() + return c.state == StateConnected +} + +func (c *Client) isClosed() bool { + c.mu.RLock() + defer c.mu.RUnlock() + return c.state == StateClosed +} + +func (c *Client) isSubscribed(channel string) bool { + c.mu.RLock() + _, ok := c.subs[channel] + c.mu.RUnlock() + return ok +} + +func (c *Client) sendRPC(ctx context.Context, method string, data []byte, fn func(RPCResult, error)) { + c.onConnect(func(err error) { + select { + case <-ctx.Done(): + fn(RPCResult{}, ctx.Err()) + return + default: + } + if err != nil { + fn(RPCResult{}, err) + return + } + cmd := &protocol.Command{ + Id: c.nextCmdID(), + } + + params := &protocol.RPCRequest{ + Data: data, + Method: method, + } + + cmd.Rpc = params + + err = c.sendAsync(cmd, func(r *protocol.Reply, err error) { + if err != nil { + fn(RPCResult{}, err) + return + } + if r.Error != nil { + fn(RPCResult{}, errorFromProto(r.Error)) + return + } + fn(RPCResult{Data: r.Rpc.Data}, nil) + }) + if err != nil { + fn(RPCResult{}, err) + return + } + }) +} + +func (c *Client) moveToDisconnected(code uint32, reason string) { + c.mu.Lock() + if c.state == StateDisconnected || c.state == StateClosed { + c.mu.Unlock() + return + } + if c.transport != nil { + _ = c.transport.Close() + c.transport = nil + } + + prevState := c.state + c.state = StateDisconnected + c.clearConnectedState() + c.resolveConnectFutures(ErrClientDisconnected) + + subsToUnsubscribe := make([]*Subscription, 0, len(c.subs)) + for _, s := range c.subs { + s.mu.Lock() + if s.state == SubStateUnsubscribed { + s.mu.Unlock() + continue + } + s.mu.Unlock() + subsToUnsubscribe = append(subsToUnsubscribe, s) + } + serverSubsToUnsubscribe := make([]string, 0, len(c.serverSubs)) + for ch := range c.serverSubs { + serverSubsToUnsubscribe = append(serverSubsToUnsubscribe, ch) + } + c.mu.Unlock() + + for _, s := range subsToUnsubscribe { + s.moveToSubscribing(subscribingTransportClosed, "transport closed") + } + + if prevState == StateConnected { + var serverSubscribingHandler ServerSubscribingHandler + if c.events != nil && c.events.onServerSubscribing != nil { + serverSubscribingHandler = c.events.onServerSubscribing + } + if serverSubscribingHandler != nil { + c.runHandlerAsync(func() { + for _, ch := range serverSubsToUnsubscribe { + serverSubscribingHandler(ServerSubscribingEvent{Channel: ch}) + } + }) + } + } + + var handler DisconnectHandler + if c.events != nil && c.events.onDisconnected != nil { + handler = c.events.onDisconnected + } + if handler != nil { + c.runHandlerAsync(func() { + event := DisconnectedEvent{Code: code, Reason: reason} + handler(event) + }) + } +} + +func (c *Client) moveToConnecting(code uint32, reason string) { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "moving client to connecting state", map[string]string{ + "code": strconv.Itoa(int(code)), + "reason": reason, + }) + } + c.mu.Lock() + if c.state == StateDisconnected || c.state == StateClosed || c.state == StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "client already in state that does not require extra work", map[string]string{ + "state": string(c.state), + }) + } + c.mu.Unlock() + return + } + if c.transport != nil { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "closing non-nil transport", nil) + } + _ = c.transport.Close() + c.transport = nil + } + + c.state = StateConnecting + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "client moved to connecting state", nil) + } + c.clearConnectedState() + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "cleared connected state", nil) + } + c.resolveConnectFutures(ErrClientDisconnected) + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "resolved connect futures", nil) + } + + subsToUnsubscribe := make([]*Subscription, 0, len(c.subs)) + for _, s := range c.subs { + s.mu.Lock() + if s.state == SubStateUnsubscribed { + s.mu.Unlock() + continue + } + s.mu.Unlock() + subsToUnsubscribe = append(subsToUnsubscribe, s) + } + serverSubsToUnsubscribe := make([]string, 0, len(c.serverSubs)) + for ch := range c.serverSubs { + serverSubsToUnsubscribe = append(serverSubsToUnsubscribe, ch) + } + c.mu.Unlock() + + for _, s := range subsToUnsubscribe { + s.moveToSubscribing(subscribingTransportClosed, "transport closed") + } + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "client-side subs unsubscribe events called", map[string]string{ + "num_subs": strconv.Itoa(len(subsToUnsubscribe)), + }) + } + + var serverSubscribingHandler ServerSubscribingHandler + if c.events != nil && c.events.onServerSubscribing != nil { + serverSubscribingHandler = c.events.onServerSubscribing + } + if serverSubscribingHandler != nil { + c.runHandlerSync(func() { + for _, ch := range serverSubsToUnsubscribe { + serverSubscribingHandler(ServerSubscribingEvent{Channel: ch}) + } + }) + } + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "server-side subs unsubscribe events called", map[string]string{ + "num_subs": strconv.Itoa(len(serverSubsToUnsubscribe)), + }) + } + + var handler ConnectingHandler + if c.events != nil && c.events.onConnecting != nil { + handler = c.events.onConnecting + } + if handler != nil { + c.runHandlerSync(func() { + event := ConnectingEvent{Code: code, Reason: reason} + handler(event) + }) + } + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "connecting event called", nil) + } + + c.mu.Lock() + if c.state != StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not in connecting state, no need to reconnect", map[string]string{ + "state": string(c.state), + }) + } + c.mu.Unlock() + return + } + c.scheduleReconnectLocked() + c.mu.Unlock() +} + +func (c *Client) scheduleReconnectLocked() { + c.reconnectAttempts++ + if c.reconnectTimer != nil { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "stopping previous reconnect timer", nil) + } + c.reconnectTimer.Stop() + c.reconnectTimer = nil + } + reconnectDelay := c.getReconnectDelay() + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "reconnect with delay", map[string]string{ + "delay": reconnectDelay.String(), + }) + } + c.reconnectTimer = time.AfterFunc(reconnectDelay, func() { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "reconnect timer fired, start reconnecting", nil) + } + _ = c.startReconnecting() + }) +} + +func (c *Client) moveToClosed() { + c.mu.Lock() + if c.state == StateClosed { + c.mu.Unlock() + return + } + c.state = StateClosed + + subsToUnsubscribe := make([]*Subscription, 0, len(c.subs)) + for _, s := range c.subs { + s.mu.Lock() + if s.state == SubStateUnsubscribed { + s.mu.Unlock() + continue + } + s.mu.Unlock() + subsToUnsubscribe = append(subsToUnsubscribe, s) + } + serverSubsToUnsubscribe := make([]string, 0, len(c.serverSubs)) + for ch := range c.serverSubs { + serverSubsToUnsubscribe = append(serverSubsToUnsubscribe, ch) + } + c.mu.Unlock() + + for _, s := range subsToUnsubscribe { + s.moveToUnsubscribed(unsubscribedClientClosed, "client closed") + } + + var serverUnsubscribedHandler ServerUnsubscribedHandler + if c.events != nil && c.events.onServerUnsubscribed != nil { + serverUnsubscribedHandler = c.events.onServerUnsubscribed + } + if serverUnsubscribedHandler != nil { + c.runHandlerAsync(func() { + for _, ch := range serverSubsToUnsubscribe { + serverUnsubscribedHandler(ServerUnsubscribedEvent{Channel: ch}) + } + }) + } + + c.mu.RLock() + disconnectedCh := c.disconnectedCh + c.mu.RUnlock() + // At this point connection close was issued, so we wait until the reader goroutine + // finishes its work, after that it's safe to close the callback queue. + if disconnectedCh != nil { + <-disconnectedCh + } + + c.mu.Lock() + defer c.mu.Unlock() + c.disconnectedCh = nil + c.cbQueue.close() + c.cbQueue = nil +} + +func (c *Client) handleError(err error) { + var handler ErrorHandler + if c.events != nil && c.events.onError != nil { + handler = c.events.onError + } + if handler != nil { + c.runHandlerSync(func() { + handler(ErrorEvent{Error: err}) + }) + } +} + +// Lock must be held outside. +func (c *Client) clearConnectedState() { + if c.reconnectTimer != nil { + c.reconnectTimer.Stop() + c.reconnectTimer = nil + } + if c.refreshTimer != nil { + c.refreshTimer.Stop() + c.refreshTimer = nil + } + if c.closeCh != nil { + close(c.closeCh) + c.closeCh = nil + } + + c.requestsMu.Lock() + reqs := make(map[uint32]request, len(c.requests)) + for uid, req := range c.requests { + reqs[uid] = req + } + c.requests = make(map[uint32]request) + c.requestsMu.Unlock() + + for _, req := range reqs { + if req.cb != nil { + go req.cb(nil, ErrClientDisconnected) + } + } +} + +func (c *Client) handleDisconnect(d *disconnect) { + if d == nil { + d = &disconnect{ + Code: connectingTransportClosed, + Reason: "transport closed", + Reconnect: true, + } + } + if d.Reconnect { + c.moveToConnecting(d.Code, d.Reason) + } else { + c.moveToDisconnected(d.Code, d.Reason) + } +} + +func (c *Client) waitServerPing(disconnectCh chan struct{}, pingInterval uint32) { + timeout := c.config.MaxServerPingDelay + time.Duration(pingInterval)*time.Second + for { + select { + case <-c.delayPing: + case <-time.After(timeout): + go c.handleDisconnect(&disconnect{Code: connectingNoPing, Reason: "no ping", Reconnect: true}) + case <-disconnectCh: + return + } + } +} + +func (c *Client) readOnce(t transport) error { + reply, disconnect, err := t.Read() + if err != nil { + go c.handleDisconnect(disconnect) + return err + } + c.handle(reply) + return nil +} + +func (c *Client) reader(t transport, disconnectCh chan struct{}) { + defer close(disconnectCh) + for { + err := c.readOnce(t) + if err != nil { + return + } + } +} + +func (c *Client) runHandlerSync(fn func()) { + c.mu.RLock() + queue := c.cbQueue + c.mu.RUnlock() + if queue == nil { + return + } + waitCh := make(chan struct{}) + queue.push(func(delay time.Duration) { + defer close(waitCh) + fn() + }) + <-waitCh +} + +func (c *Client) runHandlerAsync(fn func()) { + c.mu.RLock() + queue := c.cbQueue + c.mu.RUnlock() + if queue == nil { + return + } + queue.push(func(delay time.Duration) { + fn() + }) +} + +func (c *Client) handle(reply *protocol.Reply) { + if reply.Id > 0 { + if c.logLevelEnabled(LogLevelTrace) { + c.traceInReply(reply) + } + c.requestsMu.RLock() + req, ok := c.requests[reply.Id] + c.requestsMu.RUnlock() + if ok { + if req.cb != nil { + req.cb(reply, nil) + } + } + c.removeRequest(reply.Id) + } else { + if reply.Push == nil { + if c.logLevelEnabled(LogLevelTrace) { + c.traceInReply(reply) + } + // Ping from server, send pong if needed. + select { + case c.delayPing <- struct{}{}: + default: + } + c.mu.RLock() + sendPong := c.sendPong + c.mu.RUnlock() + if sendPong { + cmd := &protocol.Command{} + _ = c.send(cmd) + } + return + } + if c.logLevelEnabled(LogLevelTrace) { + c.traceInPush(reply.Push) + } + c.mu.Lock() + if c.state != StateConnected { + c.mu.Unlock() + return + } + c.mu.Unlock() + c.handlePush(reply.Push) + } +} + +func (c *Client) handleMessage(msg *protocol.Message) error { + var handler MessageHandler + if c.events != nil && c.events.onMessage != nil { + handler = c.events.onMessage + } + if handler != nil { + event := MessageEvent{Data: msg.Data} + c.runHandlerSync(func() { + handler(event) + }) + } + return nil +} + +func (c *Client) handlePush(push *protocol.Push) { + channel := push.Channel + c.mu.RLock() + sub, ok := c.subs[channel] + c.mu.RUnlock() + switch { + case push.Message != nil: + _ = c.handleMessage(push.Message) + case push.Unsubscribe != nil: + if !ok { + c.handleServerUnsub(channel, push.Unsubscribe) + return + } + sub.handleUnsubscribe(push.Unsubscribe) + case push.Pub != nil: + if !ok { + c.handleServerPublication(channel, push.Pub) + return + } + sub.handlePublication(push.Pub) + case push.Join != nil: + if !ok { + c.handleServerJoin(channel, push.Join) + return + } + sub.handleJoin(push.Join.Info) + case push.Leave != nil: + if !ok { + c.handleServerLeave(channel, push.Leave) + return + } + sub.handleLeave(push.Leave.Info) + case push.Subscribe != nil: + if ok { + // Client-side subscription exists. + return + } + c.handleServerSub(channel, push.Subscribe) + return + case push.Disconnect != nil: + code := push.Disconnect.Code + reconnect := code < 3500 || code >= 5000 || (code >= 4000 && code < 4500) + if reconnect { + c.moveToConnecting(code, push.Disconnect.Reason) + } else { + c.moveToDisconnected(code, push.Disconnect.Reason) + } + default: + } +} + +func (c *Client) handleServerPublication(channel string, pub *protocol.Publication) { + c.mu.Lock() + serverSub, ok := c.serverSubs[channel] + if !ok { + c.mu.Unlock() + return + } + if serverSub.Recoverable && pub.Offset > 0 { + serverSub.Offset = pub.Offset + } + c.mu.Unlock() + + var handler ServerPublicationHandler + if c.events != nil && c.events.onServerPublication != nil { + handler = c.events.onServerPublication + } + if handler != nil { + c.runHandlerSync(func() { + handler(ServerPublicationEvent{Channel: channel, Publication: pubFromProto(pub)}) + }) + } +} + +func (c *Client) handleServerJoin(channel string, join *protocol.Join) { + c.mu.Lock() + _, ok := c.serverSubs[channel] + if !ok { + c.mu.Unlock() + return + } + c.mu.Unlock() + + var handler ServerJoinHandler + if c.events != nil && c.events.onServerJoin != nil { + handler = c.events.onServerJoin + } + if handler != nil { + c.runHandlerSync(func() { + handler(ServerJoinEvent{Channel: channel, ClientInfo: infoFromProto(join.Info)}) + }) + } +} + +func (c *Client) handleServerLeave(channel string, leave *protocol.Leave) { + c.mu.Lock() + _, ok := c.serverSubs[channel] + if !ok { + c.mu.Unlock() + return + } + c.mu.Unlock() + + var handler ServerLeaveHandler + if c.events != nil && c.events.onServerLeave != nil { + handler = c.events.onServerLeave + } + if handler != nil { + c.runHandlerSync(func() { + handler(ServerLeaveEvent{Channel: channel, ClientInfo: infoFromProto(leave.Info)}) + }) + } +} + +func (c *Client) handleServerSub(channel string, sub *protocol.Subscribe) { + c.mu.Lock() + _, ok := c.serverSubs[channel] + if ok { + c.mu.Unlock() + return + } + c.serverSubs[channel] = &serverSub{ + Offset: sub.Offset, + Epoch: sub.Epoch, + Recoverable: sub.Recoverable, + } + c.mu.Unlock() + + var handler ServerSubscribedHandler + if c.events != nil && c.events.onServerSubscribe != nil { + handler = c.events.onServerSubscribe + } + if handler != nil { + c.runHandlerSync(func() { + ev := ServerSubscribedEvent{ + Channel: channel, + Positioned: sub.GetPositioned(), + Recoverable: sub.GetRecoverable(), + Data: sub.GetData(), + } + if ev.Positioned || ev.Recoverable { + ev.StreamPosition = &StreamPosition{ + Epoch: sub.GetEpoch(), + Offset: sub.GetOffset(), + } + } + handler(ev) + }) + } +} + +func (c *Client) handleServerUnsub(channel string, _ *protocol.Unsubscribe) { + c.mu.Lock() + _, ok := c.serverSubs[channel] + if ok { + delete(c.serverSubs, channel) + } + c.mu.Unlock() + if !ok { + return + } + + var handler ServerUnsubscribedHandler + if c.events != nil && c.events.onServerUnsubscribed != nil { + handler = c.events.onServerUnsubscribed + } + if handler != nil { + c.runHandlerSync(func() { + handler(ServerUnsubscribedEvent{Channel: channel}) + }) + } +} + +func (c *Client) getReconnectDelay() time.Duration { + return c.reconnectStrategy.timeBeforeNextAttempt(c.reconnectAttempts) +} + +func (c *Client) startReconnecting() error { + c.mu.Lock() + c.round++ + round := c.round + if c.state != StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not in connecting state, no need to reconnect", map[string]string{ + "state": string(c.state), + }) + } + c.mu.Unlock() + return nil + } + refreshRequired := c.refreshRequired + token := c.token + getTokenFunc := c.config.GetToken + c.mu.Unlock() + + wsConfig := websocketConfig{ + Proxy: c.config.Proxy, + NetDialContext: c.config.NetDialContext, + TLSConfig: c.config.TLSConfig, + HandshakeTimeout: c.config.HandshakeTimeout, + EnableCompression: c.config.EnableCompression, + CookieJar: c.config.CookieJar, + Header: c.config.Header, + } + + u := c.endpoints[round%len(c.endpoints)] + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "creating new transport", nil) + } + t, err := newWebsocketTransport(u, c.protocolType, wsConfig) + if err != nil { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "error creating new transport", map[string]string{ + "error": err.Error(), + }) + } + c.handleError(TransportError{err}) + c.mu.Lock() + if c.state != StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not in connecting state, no need to reconnect", map[string]string{ + "state": string(c.state), + }) + } + c.mu.Unlock() + return nil + } + c.scheduleReconnectLocked() + c.mu.Unlock() + return err + } + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "new transport created", nil) + } + + if refreshRequired || (token == "" && getTokenFunc != nil) { + // Try to refresh token. + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "refreshing token", nil) + } + newToken, err := c.refreshToken() + if err != nil { + if errors.Is(err, ErrUnauthorized) { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "unauthorized error, move to disconnected", nil) + } + c.moveToDisconnected(disconnectedUnauthorized, "unauthorized") + return nil + } + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "error refreshing token", map[string]string{ + "error": err.Error(), + }) + } + c.handleError(RefreshError{err}) + c.mu.Lock() + if c.state != StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not in connecting state, no need to continue", map[string]string{ + "state": string(c.state), + }) + } + _ = t.Close() + c.mu.Unlock() + return nil + } + c.scheduleReconnectLocked() + c.mu.Unlock() + return err + } else { + c.mu.Lock() + c.token = newToken + if c.state != StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "got token, but not in connecting state anymore", map[string]string{ + "state": string(c.state), + }) + } + c.mu.Unlock() + return nil + } + c.mu.Unlock() + } + } + + c.mu.Lock() + if c.state != StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not in connecting state, no need to reconnect", map[string]string{ + "state": string(c.state), + }) + } + _ = t.Close() + c.mu.Unlock() + return nil + } + c.refreshRequired = false + disconnectCh := make(chan struct{}) + c.receive = make(chan []byte, 64) + c.transport = t + c.disconnectedCh = disconnectCh + + go c.reader(t, disconnectCh) + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "started reader loop, sending connect frame", nil) + } + err = c.sendConnect(func(res *protocol.ConnectResult, err error) { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "connect result received", nil) + } + c.mu.Lock() + if c.state != StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not in connecting state, no need to continue", map[string]string{ + "state": string(c.state), + }) + } + c.mu.Unlock() + return + } + c.mu.Unlock() + if err != nil { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "connect error", map[string]string{ + "error": err.Error(), + }) + } + c.handleError(ConnectError{err}) + _ = t.Close() + if isTokenExpiredError(err) { + c.mu.Lock() + defer c.mu.Unlock() + if c.state != StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not in connecting state, no need to continue", map[string]string{ + "state": string(c.state), + }) + } + return + } + c.refreshRequired = true + c.scheduleReconnectLocked() + return + } else if isServerError(err) && !isTemporaryError(err) { + var serverError *Error + if errors.As(err, &serverError) { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "server error, move to disconnected", map[string]string{ + "code": strconv.Itoa(int(serverError.Code)), + "message": serverError.Message, + }) + } + c.moveToDisconnected(serverError.Code, serverError.Message) + } else { + // Should not happen, but just in case. + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not a server error", map[string]string{ + "error": err.Error(), + }) + } + } + return + } else { + c.mu.Lock() + defer c.mu.Unlock() + if c.state != StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not in connecting state, no need to continue", map[string]string{ + "state": string(c.state), + }) + } + return + } + c.scheduleReconnectLocked() + return + } + } + c.mu.Lock() + if c.state != StateConnecting { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not in connecting state, no need to continue", map[string]string{ + "state": string(c.state), + }) + } + _ = t.Close() + c.mu.Unlock() + return + } + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "connect ok, move to connected", map[string]string{ + "client_id": res.Client, + }) + } + c.state = StateConnected + + if res.Expires { + c.refreshTimer = time.AfterFunc(time.Duration(res.Ttl)*time.Second, c.sendRefresh) + } + c.resolveConnectFutures(nil) + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "resolved connect futures", nil) + } + c.mu.Unlock() + + if c.events != nil && c.events.onConnected != nil { + handler := c.events.onConnected + ev := ConnectedEvent{ + ClientID: res.Client, + Version: res.Version, + Data: res.Data, + } + c.runHandlerSync(func() { + handler(ev) + }) + } + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "connected event called", nil) + } + + var subscribeHandler ServerSubscribedHandler + if c.events != nil && c.events.onServerSubscribe != nil { + subscribeHandler = c.events.onServerSubscribe + } + + var publishHandler ServerPublicationHandler + if c.events != nil && c.events.onServerPublication != nil { + publishHandler = c.events.onServerPublication + } + + for channel, subRes := range res.Subs { + c.mu.Lock() + sub, ok := c.serverSubs[channel] + if ok { + sub.Epoch = subRes.Epoch + sub.Recoverable = subRes.Recoverable + } else { + sub = &serverSub{ + Epoch: subRes.Epoch, + Offset: subRes.Offset, + Recoverable: subRes.Recoverable, + } + } + if len(subRes.Publications) == 0 { + sub.Offset = subRes.Offset + } + c.serverSubs[channel] = sub + c.mu.Unlock() + + if subscribeHandler != nil { + c.runHandlerSync(func() { + ev := ServerSubscribedEvent{ + Channel: channel, + Data: subRes.GetData(), + Recovered: subRes.GetRecovered(), + WasRecovering: subRes.GetWasRecovering(), + Positioned: subRes.GetPositioned(), + Recoverable: subRes.GetRecoverable(), + } + if ev.Positioned || ev.Recoverable { + ev.StreamPosition = &StreamPosition{ + Epoch: subRes.GetEpoch(), + Offset: subRes.GetOffset(), + } + } + subscribeHandler(ev) + }) + } + if publishHandler != nil { + c.runHandlerSync(func() { + for _, pub := range subRes.Publications { + c.mu.Lock() + if sub, ok := c.serverSubs[channel]; ok { + sub.Offset = pub.Offset + } + c.serverSubs[channel] = sub + c.mu.Unlock() + publishHandler(ServerPublicationEvent{Channel: channel, Publication: pubFromProto(pub)}) + } + }) + } + } + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "connect server-side subscriptions processed", nil) + } + + for ch := range c.serverSubs { + if _, ok := res.Subs[ch]; !ok { + var serverUnsubscribedHandler ServerUnsubscribedHandler + if c.events != nil && c.events.onServerUnsubscribed != nil { + serverUnsubscribedHandler = c.events.onServerUnsubscribed + } + if serverUnsubscribedHandler != nil { + c.runHandlerSync(func() { + serverUnsubscribedHandler(ServerUnsubscribedEvent{Channel: ch}) + }) + } + } + } + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "connect server-side unsubscriptions processed", nil) + } + + c.mu.Lock() + defer c.mu.Unlock() + // Successfully connected – can reset reconnect attempts. + c.reconnectAttempts = 0 + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "reset reconnect attempts counter", nil) + } + + if c.state != StateConnected { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "not in connected state, no need to continue", map[string]string{ + "state": string(c.state), + }) + } + return + } + + if res.Ping > 0 { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "start waiting server ping", map[string]string{ + "ping": strconv.Itoa(int(res.Ping)), + }) + } + c.sendPong = res.Pong + go c.waitServerPing(disconnectCh, res.Ping) + } + c.resubscribe() + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "client-side subscriptions resubscribe called", nil) + } + }) + if err != nil { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "error sending connect frame", map[string]string{ + "error": err.Error(), + }) + } + _ = t.Close() + c.scheduleReconnectLocked() + } else { + if c.logLevelEnabled(LogLevelDebug) { + c.log(LogLevelDebug, "connect frame successfully sent", nil) + } + } + c.mu.Unlock() + if err != nil { + c.handleError(ConnectError{err}) + } + return err +} + +func (c *Client) startConnecting() error { + c.mu.Lock() + if c.state == StateClosed { + c.mu.Unlock() + return ErrClientClosed + } + if c.state == StateConnected || c.state == StateConnecting { + c.mu.Unlock() + return nil + } + if c.closeCh == nil { + c.closeCh = make(chan struct{}) + } + c.state = StateConnecting + c.mu.Unlock() + + var handler ConnectingHandler + if c.events != nil && c.events.onConnecting != nil { + handler = c.events.onConnecting + } + if handler != nil { + c.runHandlerSync(func() { + event := ConnectingEvent{Code: connectingConnectCalled, Reason: "connect called"} + handler(event) + }) + } + + return c.startReconnecting() +} + +func (c *Client) resubscribe() { + for _, sub := range c.subs { + sub.resubscribe() + } +} + +func isTokenExpiredError(err error) bool { + if e, ok := err.(*Error); ok && e.Code == 109 { + return true + } + return false +} + +func isServerError(err error) bool { + if _, ok := err.(*Error); ok { + return true + } + return false +} + +func isTemporaryError(err error) bool { + if e, ok := err.(*Error); ok && e.Temporary { + return true + } + return false +} + +func (c *Client) refreshToken() (string, error) { + handler := c.config.GetToken + if handler == nil { + c.handleError(ConfigurationError{Err: errors.New("GetToken must be set to handle expired token")}) + return "", ErrUnauthorized + } + return handler(ConnectionTokenEvent{}) +} + +func (c *Client) sendRefresh() { + token, err := c.refreshToken() + if err != nil { + if errors.Is(err, ErrUnauthorized) { + c.moveToDisconnected(disconnectedUnauthorized, "unauthorized") + return + } + c.handleError(RefreshError{err}) + c.mu.Lock() + defer c.mu.Unlock() + c.handleRefreshError() + return + } + c.mu.Lock() + c.token = token + c.mu.Unlock() + + cmd := &protocol.Command{ + Id: c.nextCmdID(), + } + params := &protocol.RefreshRequest{ + Token: c.token, + } + cmd.Refresh = params + + _ = c.sendAsync(cmd, func(r *protocol.Reply, err error) { + if err != nil { + c.handleError(RefreshError{err}) + c.mu.Lock() + defer c.mu.Unlock() + c.handleRefreshError() + return + } + if r.Error != nil { + c.mu.Lock() + if c.state != StateConnected { + c.mu.Unlock() + return + } + if r.Error.Temporary { + c.handleError(RefreshError{err}) + c.refreshTimer = time.AfterFunc(10*time.Second, c.sendRefresh) + c.mu.Unlock() + } else { + c.mu.Unlock() + c.moveToDisconnected(r.Error.Code, r.Error.Message) + } + return + } + expires := r.Refresh.Expires + ttl := r.Refresh.Ttl + if expires { + c.mu.Lock() + if c.state == StateConnected { + c.refreshTimer = time.AfterFunc(time.Duration(ttl)*time.Second, c.sendRefresh) + } + c.mu.Unlock() + } + }) +} + +// Lock must be held outside. +func (c *Client) handleRefreshError() { + if c.state != StateConnected { + return + } + c.refreshTimer = time.AfterFunc(10*time.Second, c.sendRefresh) +} + +func (c *Client) sendSubRefresh(channel string, token string, fn func(*protocol.SubRefreshResult, error)) { + cmd := &protocol.Command{ + Id: c.nextCmdID(), + } + params := &protocol.SubRefreshRequest{ + Channel: channel, + Token: token, + } + cmd.SubRefresh = params + + _ = c.sendAsync(cmd, func(r *protocol.Reply, err error) { + if err != nil { + fn(nil, err) + return + } + if r.Error != nil { + fn(nil, errorFromProto(r.Error)) + return + } + fn(r.SubRefresh, nil) + }) +} + +func (c *Client) sendConnect(fn func(*protocol.ConnectResult, error)) error { + cmd := &protocol.Command{ + Id: c.nextCmdID(), + } + + req := &protocol.ConnectRequest{} + req.Token = c.token + req.Name = c.config.Name + req.Version = c.config.Version + req.Data = c.data + + if len(c.serverSubs) > 0 { + subs := make(map[string]*protocol.SubscribeRequest) + for channel, serverSub := range c.serverSubs { + if !serverSub.Recoverable { + continue + } + subs[channel] = &protocol.SubscribeRequest{ + Recover: true, + Epoch: serverSub.Epoch, + Offset: serverSub.Offset, + } + } + req.Subs = subs + } + cmd.Connect = req + + return c.sendAsync(cmd, func(reply *protocol.Reply, err error) { + if err != nil { + fn(nil, err) + return + } + if reply.Error != nil { + fn(nil, errorFromProto(reply.Error)) + return + } + fn(reply.Connect, nil) + }) +} + +type StreamPosition struct { + Offset uint64 + Epoch string +} + +func (c *Client) sendSubscribe( + channel string, data []byte, recover bool, streamPos StreamPosition, token string, + positioned bool, recoverable bool, joinLeave bool, deltaType DeltaType, + fn func(res *protocol.SubscribeResult, err error), +) error { + params := &protocol.SubscribeRequest{ + Channel: channel, + } + + if recover { + params.Recover = true + if streamPos.Offset > 0 { + params.Offset = streamPos.Offset + } + params.Epoch = streamPos.Epoch + } + params.Token = token + params.Data = data + params.Positioned = positioned + params.Recoverable = recoverable + params.JoinLeave = joinLeave + + if deltaType != DeltaTypeNone { + params.Delta = string(deltaType) + } + + cmd := &protocol.Command{ + Id: c.nextCmdID(), + } + cmd.Subscribe = params + + return c.sendAsync(cmd, func(reply *protocol.Reply, err error) { + if err != nil { + fn(nil, err) + return + } + if reply.Error != nil { + fn(nil, errorFromProto(reply.Error)) + return + } + fn(reply.Subscribe, nil) + }) +} + +func (c *Client) nextFutureID() uint64 { + return atomic.AddUint64(&c.futureID, 1) +} + +type connectFuture struct { + fn func(error) + closeCh chan struct{} +} + +func newConnectFuture(fn func(error)) connectFuture { + return connectFuture{fn: fn, closeCh: make(chan struct{})} +} + +// lock must be held outside. +func (c *Client) resolveConnectFutures(err error) { + for _, fut := range c.connectFutures { + fut.fn(err) + close(fut.closeCh) + } + c.connectFutures = make(map[uint64]connectFuture) +} + +func (c *Client) onConnect(fn func(err error)) { + c.mu.Lock() + if c.state == StateConnected { + c.mu.Unlock() + fn(nil) + } else if c.state == StateDisconnected { + c.mu.Unlock() + fn(ErrClientDisconnected) + } else { + defer c.mu.Unlock() + id := c.nextFutureID() + fut := newConnectFuture(fn) + c.connectFutures[id] = fut + go func() { + select { + case <-fut.closeCh: + case <-time.After(c.config.ReadTimeout): + c.mu.Lock() + defer c.mu.Unlock() + fut, ok := c.connectFutures[id] + if !ok { + return + } + delete(c.connectFutures, id) + fut.fn(ErrTimeout) + } + }() + } +} + +// PublishResult contains the result of publish. +type PublishResult struct{} + +// Publish data into channel. +func (c *Client) Publish(ctx context.Context, channel string, data []byte) (PublishResult, error) { + if c.isClosed() { + return PublishResult{}, ErrClientClosed + } + resCh := make(chan PublishResult, 1) + errCh := make(chan error, 1) + c.publish(ctx, channel, data, func(result PublishResult, err error) { + resCh <- result + errCh <- err + }) + select { + case <-ctx.Done(): + return PublishResult{}, ctx.Err() + case res := <-resCh: + return res, <-errCh + } +} + +func (c *Client) publish(ctx context.Context, channel string, data []byte, fn func(PublishResult, error)) { + c.onConnect(func(err error) { + select { + case <-ctx.Done(): + fn(PublishResult{}, ctx.Err()) + return + default: + } + if err != nil { + fn(PublishResult{}, err) + return + } + c.sendPublish(channel, data, fn) + }) +} + +func (c *Client) sendPublish(channel string, data []byte, fn func(PublishResult, error)) { + params := &protocol.PublishRequest{ + Channel: channel, + Data: protocol.Raw(data), + } + + cmd := &protocol.Command{ + Id: c.nextCmdID(), + } + cmd.Publish = params + err := c.sendAsync(cmd, func(r *protocol.Reply, err error) { + if err != nil { + fn(PublishResult{}, err) + return + } + if r.Error != nil { + fn(PublishResult{}, errorFromProto(r.Error)) + return + } + fn(PublishResult{}, nil) + }) + if err != nil { + fn(PublishResult{}, err) + } +} + +// HistoryResult contains the result of history op. +type HistoryResult struct { + Publications []Publication + Offset uint64 + Epoch string +} + +// History for a channel without being subscribed. +func (c *Client) History(ctx context.Context, channel string, opts ...HistoryOption) (HistoryResult, error) { + if c.isClosed() { + return HistoryResult{}, ErrClientClosed + } + resCh := make(chan HistoryResult, 1) + errCh := make(chan error, 1) + historyOpts := &HistoryOptions{} + for _, opt := range opts { + opt(historyOpts) + } + c.history(ctx, channel, *historyOpts, func(result HistoryResult, err error) { + resCh <- result + errCh <- err + }) + select { + case <-ctx.Done(): + return HistoryResult{}, ctx.Err() + case res := <-resCh: + return res, <-errCh + } +} + +func (c *Client) history(ctx context.Context, channel string, opts HistoryOptions, fn func(HistoryResult, error)) { + c.onConnect(func(err error) { + select { + case <-ctx.Done(): + fn(HistoryResult{}, ctx.Err()) + return + default: + } + if err != nil { + fn(HistoryResult{}, err) + return + } + c.sendHistory(channel, opts, fn) + }) +} + +func (c *Client) sendHistory(channel string, opts HistoryOptions, fn func(HistoryResult, error)) { + params := &protocol.HistoryRequest{ + Channel: channel, + Limit: opts.Limit, + Reverse: opts.Reverse, + } + if opts.Since != nil { + params.Since = &protocol.StreamPosition{ + Offset: opts.Since.Offset, + Epoch: opts.Since.Epoch, + } + } + + cmd := &protocol.Command{ + Id: c.nextCmdID(), + } + cmd.History = params + + err := c.sendAsync(cmd, func(r *protocol.Reply, err error) { + if err != nil { + fn(HistoryResult{}, err) + return + } + if r.Error != nil { + fn(HistoryResult{}, errorFromProto(r.Error)) + return + } + + publications := r.History.Publications + offset := r.History.Offset + epoch := r.History.Epoch + + pubs := make([]Publication, len(publications)) + for i, m := range publications { + pubs[i] = pubFromProto(m) + } + fn(HistoryResult{ + Publications: pubs, + Offset: offset, + Epoch: epoch, + }, nil) + }) + if err != nil { + fn(HistoryResult{}, err) + return + } +} + +// PresenceResult contains the result of presence op. +type PresenceResult struct { + Clients map[string]ClientInfo +} + +// Presence for a channel without being subscribed. +func (c *Client) Presence(ctx context.Context, channel string) (PresenceResult, error) { + if c.isClosed() { + return PresenceResult{}, ErrClientClosed + } + resCh := make(chan PresenceResult, 1) + errCh := make(chan error, 1) + c.presence(ctx, channel, func(result PresenceResult, err error) { + resCh <- result + errCh <- err + }) + select { + case <-ctx.Done(): + return PresenceResult{}, ctx.Err() + case res := <-resCh: + return res, <-errCh + } +} + +func (c *Client) presence(ctx context.Context, channel string, fn func(PresenceResult, error)) { + c.onConnect(func(err error) { + select { + case <-ctx.Done(): + fn(PresenceResult{}, ctx.Err()) + return + default: + } + if err != nil { + fn(PresenceResult{}, err) + return + } + c.sendPresence(channel, fn) + }) +} + +func (c *Client) sendPresence(channel string, fn func(PresenceResult, error)) { + params := &protocol.PresenceRequest{ + Channel: channel, + } + + cmd := &protocol.Command{ + Id: c.nextCmdID(), + } + cmd.Presence = params + + err := c.sendAsync(cmd, func(r *protocol.Reply, err error) { + if err != nil { + fn(PresenceResult{}, err) + return + } + if r.Error != nil { + fn(PresenceResult{}, errorFromProto(r.Error)) + return + } + + p := make(map[string]ClientInfo) + + for uid, info := range r.Presence.Presence { + p[uid] = infoFromProto(info) + } + fn(PresenceResult{Clients: p}, nil) + }) + if err != nil { + fn(PresenceResult{}, err) + } +} + +// PresenceStats represents short presence information. +type PresenceStats struct { + NumClients int + NumUsers int +} + +// PresenceStatsResult wraps presence stats. +type PresenceStatsResult struct { + PresenceStats +} + +// PresenceStats for a channel without being subscribed. +func (c *Client) PresenceStats(ctx context.Context, channel string) (PresenceStatsResult, error) { + if c.isClosed() { + return PresenceStatsResult{}, ErrClientClosed + } + resCh := make(chan PresenceStatsResult, 1) + errCh := make(chan error, 1) + c.presenceStats(ctx, channel, func(result PresenceStatsResult, err error) { + resCh <- result + errCh <- err + }) + select { + case <-ctx.Done(): + return PresenceStatsResult{}, ctx.Err() + case res := <-resCh: + return res, <-errCh + } +} + +func (c *Client) presenceStats(ctx context.Context, channel string, fn func(PresenceStatsResult, error)) { + c.onConnect(func(err error) { + select { + case <-ctx.Done(): + fn(PresenceStatsResult{}, ctx.Err()) + return + default: + } + if err != nil { + fn(PresenceStatsResult{}, err) + return + } + c.sendPresenceStats(channel, fn) + }) +} + +func (c *Client) sendPresenceStats(channel string, fn func(PresenceStatsResult, error)) { + params := &protocol.PresenceStatsRequest{ + Channel: channel, + } + + cmd := &protocol.Command{ + Id: c.nextCmdID(), + } + cmd.PresenceStats = params + + err := c.sendAsync(cmd, func(r *protocol.Reply, err error) { + if err != nil { + fn(PresenceStatsResult{}, err) + return + } + if r.Error != nil { + fn(PresenceStatsResult{}, errorFromProto(r.Error)) + return + } + fn(PresenceStatsResult{PresenceStats{ + NumClients: int(r.PresenceStats.NumClients), + NumUsers: int(r.PresenceStats.NumUsers), + }}, nil) + }) + if err != nil { + fn(PresenceStatsResult{}, err) + return + } +} + +type UnsubscribeResult struct{} + +func (c *Client) unsubscribe(channel string, fn func(UnsubscribeResult, error)) { + if !c.isSubscribed(channel) { + return + } + c.mu.Lock() + defer c.mu.Unlock() + if c.state != StateConnected { + return + } + c.sendUnsubscribe(channel, fn) +} + +func (c *Client) sendUnsubscribe(channel string, fn func(UnsubscribeResult, error)) { + params := &protocol.UnsubscribeRequest{ + Channel: channel, + } + + cmd := &protocol.Command{ + Id: c.nextCmdID(), + } + cmd.Unsubscribe = params + + err := c.sendAsync(cmd, func(r *protocol.Reply, err error) { + if err != nil { + fn(UnsubscribeResult{}, err) + return + } + if r.Error != nil { + fn(UnsubscribeResult{}, errorFromProto(r.Error)) + return + } + fn(UnsubscribeResult{}, nil) + }) + if err != nil { + fn(UnsubscribeResult{}, err) + } +} + +func (c *Client) sendAsync(cmd *protocol.Command, cb func(*protocol.Reply, error)) error { + c.addRequest(cmd.Id, cb) + + err := c.send(cmd) + if err != nil { + return err + } + go func() { + c.mu.Lock() + closeCh := c.closeCh + c.mu.Unlock() + defer c.removeRequest(cmd.Id) + select { + case <-time.After(c.config.ReadTimeout): + c.requestsMu.RLock() + req, ok := c.requests[cmd.Id] + c.requestsMu.RUnlock() + if !ok { + return + } + req.cb(nil, ErrTimeout) + case <-closeCh: + c.requestsMu.RLock() + req, ok := c.requests[cmd.Id] + c.requestsMu.RUnlock() + if !ok { + return + } + req.cb(nil, ErrClientDisconnected) + } + }() + return nil +} + +func (c *Client) send(cmd *protocol.Command) error { + transport := c.transport + if transport == nil { + return ErrClientDisconnected + } + if c.logLevelEnabled(LogLevelTrace) { + c.traceOutCmd(cmd) + } + err := transport.Write(cmd, c.config.WriteTimeout) + if err != nil { + go c.handleDisconnect(&disconnect{Code: connectingTransportClosed, Reason: "write error", Reconnect: true}) + return io.EOF + } + return nil +} + +type request struct { + cb func(*protocol.Reply, error) +} + +func (c *Client) addRequest(id uint32, cb func(*protocol.Reply, error)) { + c.requestsMu.Lock() + defer c.requestsMu.Unlock() + c.requests[id] = request{cb} +} + +func (c *Client) removeRequest(id uint32) { + c.requestsMu.Lock() + defer c.requestsMu.Unlock() + delete(c.requests, id) +} + +type disconnect struct { + Code uint32 + Reason string + Reconnect bool +} + +type serverSub struct { + Offset uint64 + Epoch string + Recoverable bool +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/client_events.go b/vendor/github.com/centrifugal/centrifuge-go/client_events.go new file mode 100644 index 0000000000..d863424fa8 --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/client_events.go @@ -0,0 +1,194 @@ +package centrifuge + +// ConnectionTokenEvent may contain some useful contextual information in the future. +// For now, it's empty. +type ConnectionTokenEvent struct { +} + +// SubscriptionTokenEvent contains info required to get subscription token when +// client wants to subscribe on private channel. +type SubscriptionTokenEvent struct { + Channel string +} + +// ServerPublicationEvent has info about received channel Publication. +type ServerPublicationEvent struct { + Channel string + Publication +} + +// ServerSubscribedEvent has info about server-side subscription. +type ServerSubscribedEvent struct { + Channel string + WasRecovering bool + Recovered bool + Recoverable bool + Positioned bool + StreamPosition *StreamPosition + Data []byte +} + +// ServerJoinEvent has info about user who joined channel. +type ServerJoinEvent struct { + Channel string + ClientInfo +} + +// ServerLeaveEvent has info about user who left channel. +type ServerLeaveEvent struct { + Channel string + ClientInfo +} + +// ServerUnsubscribedEvent is an event passed to unsubscribe event handler. +type ServerUnsubscribedEvent struct { + Channel string +} + +// ServerSubscribingEvent is an event passed to subscribing event handler. +type ServerSubscribingEvent struct { + Channel string +} + +// ConnectedEvent is a connected event context passed to OnConnected callback. +type ConnectedEvent struct { + ClientID string + Version string + Data []byte +} + +// ConnectingEvent is a connecting event context passed to OnConnecting callback. +type ConnectingEvent struct { + Code uint32 + Reason string +} + +// DisconnectedEvent is a disconnected event context passed to OnDisconnected callback. +type DisconnectedEvent struct { + Code uint32 + Reason string +} + +// ErrorEvent is an error event context passed to OnError callback. +type ErrorEvent struct { + Error error +} + +// MessageEvent is an event for async message from server to client. +type MessageEvent struct { + Data []byte +} + +// ConnectingHandler is an interface describing how to handle connecting event. +type ConnectingHandler func(ConnectingEvent) + +// ConnectedHandler is an interface describing how to handle connect event. +type ConnectedHandler func(ConnectedEvent) + +// DisconnectHandler is an interface describing how to handle moveToDisconnected event. +type DisconnectHandler func(DisconnectedEvent) + +// MessageHandler is an interface describing how to handle async message from server. +type MessageHandler func(MessageEvent) + +// ServerPublicationHandler is an interface describing how to handle Publication from +// server-side subscriptions. +type ServerPublicationHandler func(ServerPublicationEvent) + +// ServerSubscribedHandler is an interface describing how to handle subscribe events from +// server-side subscriptions. +type ServerSubscribedHandler func(ServerSubscribedEvent) + +// ServerSubscribingHandler is an interface describing how to handle subscribing events for +// server-side subscriptions. +type ServerSubscribingHandler func(ServerSubscribingEvent) + +// ServerUnsubscribedHandler is an interface describing how to handle unsubscribe events from +// server-side subscriptions. +type ServerUnsubscribedHandler func(ServerUnsubscribedEvent) + +// ServerJoinHandler is an interface describing how to handle Join events from +// server-side subscriptions. +type ServerJoinHandler func(ServerJoinEvent) + +// ServerLeaveHandler is an interface describing how to handle Leave events from +// server-side subscriptions. +type ServerLeaveHandler func(ServerLeaveEvent) + +// ErrorHandler is an interface describing how to handle error event. +type ErrorHandler func(ErrorEvent) + +// eventHub has all event handlers for client. +type eventHub struct { + onConnected ConnectedHandler + onDisconnected DisconnectHandler + onConnecting ConnectingHandler + onError ErrorHandler + onMessage MessageHandler + onServerSubscribe ServerSubscribedHandler + onServerSubscribing ServerSubscribingHandler + onServerUnsubscribed ServerUnsubscribedHandler + onServerPublication ServerPublicationHandler + onServerJoin ServerJoinHandler + onServerLeave ServerLeaveHandler +} + +// newEventHub initializes new eventHub. +func newEventHub() *eventHub { + return &eventHub{} +} + +// OnConnected is a function to handle connect event. +func (c *Client) OnConnected(handler ConnectedHandler) { + c.events.onConnected = handler +} + +// OnConnecting is a function to handle connecting event. +func (c *Client) OnConnecting(handler ConnectingHandler) { + c.events.onConnecting = handler +} + +// OnDisconnected is a function to handle moveToDisconnected event. +func (c *Client) OnDisconnected(handler DisconnectHandler) { + c.events.onDisconnected = handler +} + +// OnError is a function that will receive unhandled errors for logging. +func (c *Client) OnError(handler ErrorHandler) { + c.events.onError = handler +} + +// OnMessage allows processing async message from server to client. +func (c *Client) OnMessage(handler MessageHandler) { + c.events.onMessage = handler +} + +// OnPublication sets function to handle Publications from server-side subscriptions. +func (c *Client) OnPublication(handler ServerPublicationHandler) { + c.events.onServerPublication = handler +} + +// OnSubscribed sets function to handle server-side subscription subscribe events. +func (c *Client) OnSubscribed(handler ServerSubscribedHandler) { + c.events.onServerSubscribe = handler +} + +// OnSubscribing sets function to handle server-side subscription subscribing events. +func (c *Client) OnSubscribing(handler ServerSubscribingHandler) { + c.events.onServerSubscribing = handler +} + +// OnUnsubscribed sets function to handle unsubscribe from server-side subscriptions. +func (c *Client) OnUnsubscribed(handler ServerUnsubscribedHandler) { + c.events.onServerUnsubscribed = handler +} + +// OnJoin sets function to handle Join event from server-side subscriptions. +func (c *Client) OnJoin(handler ServerJoinHandler) { + c.events.onServerJoin = handler +} + +// OnLeave sets function to handle Leave event from server-side subscriptions. +func (c *Client) OnLeave(handler ServerLeaveHandler) { + c.events.onServerLeave = handler +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/codes.go b/vendor/github.com/centrifugal/centrifuge-go/codes.go new file mode 100644 index 0000000000..1b23208fe5 --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/codes.go @@ -0,0 +1,27 @@ +package centrifuge + +const ( + disconnectedDisconnectCalled uint32 = 0 + disconnectedUnauthorized uint32 = 1 + disconnectBadProtocol uint32 = 2 + disconnectMessageSizeLimit uint32 = 3 +) + +const ( + connectingConnectCalled uint32 = 0 + connectingTransportClosed uint32 = 1 + connectingNoPing uint32 = 2 + connectingSubscribeTimeout uint32 = 3 + connectingUnsubscribeError uint32 = 4 +) + +const ( + subscribingSubscribeCalled uint32 = 0 + subscribingTransportClosed uint32 = 1 +) + +const ( + unsubscribedUnsubscribeCalled uint32 = 0 + unsubscribedUnauthorized uint32 = 1 + unsubscribedClientClosed uint32 = 2 +) diff --git a/vendor/github.com/centrifugal/centrifuge-go/config.go b/vendor/github.com/centrifugal/centrifuge-go/config.go new file mode 100644 index 0000000000..e62159c7fe --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/config.go @@ -0,0 +1,78 @@ +package centrifuge + +import ( + "context" + "crypto/tls" + "net" + "net/http" + "net/url" + "time" +) + +// Config contains various client options. +type Config struct { + // Token for a connection authentication. + Token string + // GetToken called by SDK to get or refresh connection token. + GetToken func(ConnectionTokenEvent) (string, error) + // Data is an arbitrary data which can be sent to a server in a Connect command. + // Make sure it's a valid JSON when using JSON protocol client. + Data []byte + // CookieJar specifies the cookie jar to send in WebSocket Upgrade request. + CookieJar http.CookieJar + // Header specifies custom HTTP Header to send in WebSocket Upgrade request. + Header http.Header + // Name allows setting client name. You should only use a limited + // amount of client names throughout your applications – i.e. don't + // make it unique per user for example, this name semantically represents + // an environment from which client connects. + // Zero value means "go". + Name string + // Version allows setting client version. This is an application + // specific information. By default, no version set. + Version string + // Proxy specifies a function to return a proxy for a given Request. + // If the function returns a non-nil error, the request is aborted with the + // provided error. If function returns a nil *URL, no proxy is used. + // If Proxy is nil then http.ProxyFromEnvironment will be used. + Proxy func(*http.Request) (*url.URL, error) + // NetDialContext specifies the dial function for creating TCP connections. If + // NetDialContext is nil, net.DialContext is used. + NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error) + // ReadTimeout is how long to wait read operations to complete. + // Zero value means 5 * time.Second. + ReadTimeout time.Duration + // WriteTimeout is Websocket write timeout. + // Zero value means 1 * time.Second. + WriteTimeout time.Duration + // HandshakeTimeout specifies the duration for the handshake to complete. + // Zero value means 1 * time.Second. + HandshakeTimeout time.Duration + // MaxServerPingDelay used to set maximum delay of ping from server. + // Zero value means 10 * time.Second. + MaxServerPingDelay time.Duration + // MinReconnectDelay is the minimum delay between reconnection attempts. + // This delay is jittered. + // Zero value means 200 * time.Millisecond. + MinReconnectDelay time.Duration + // MaxReconnectDelay is the maximum delay between reconnection attempts. + // Zero value means 20 * time.Second. + MaxReconnectDelay time.Duration + // TLSConfig specifies the TLS configuration to use with tls.Client. + // If nil, the default configuration is used. + TLSConfig *tls.Config + // EnableCompression specifies if the client should attempt to negotiate + // per message compression (RFC 7692). Setting this value to true does not + // guarantee that compression will be supported. Currently, only "no context + // takeover" modes are supported. + EnableCompression bool + // LogLevel to use, by default no logs will be exposed by centrifuge-go. Most of the + // time available protocol callbacks cover all necessary information about client-server + // communication. + LogLevel LogLevel + // LogHandler is a function that will be called for each log entry. Log entries + // are sent asynchronously and from a separate goroutine by centrifuge-go with an + // intermediary channel buffer (fixed capacity 256). If your LogHandler is not + // processing log entries fast enough, centrifuge-go will drop log entries. + LogHandler func(LogEntry) +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/errors.go b/vendor/github.com/centrifugal/centrifuge-go/errors.go new file mode 100644 index 0000000000..6b9ff9360f --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/errors.go @@ -0,0 +1,98 @@ +package centrifuge + +import ( + "errors" + "fmt" +) + +var ( + // ErrTimeout returned if operation timed out. + ErrTimeout = errors.New("timeout") + // ErrClientDisconnected can be returned if client goes to + // disconnected state while operation in progress. + ErrClientDisconnected = errors.New("client disconnected") + // ErrClientClosed can be returned if client is closed. + ErrClientClosed = errors.New("client closed") + // ErrSubscriptionUnsubscribed returned if Subscription is unsubscribed. + ErrSubscriptionUnsubscribed = errors.New("subscription unsubscribed") + // ErrDuplicateSubscription returned if subscription to the same channel + // already registered in current client instance. This is due to the fact + // that server does not allow subscribing to the same channel twice for + // the same connection. + ErrDuplicateSubscription = errors.New("duplicate subscription") + // ErrUnauthorized is a special error which may be returned by application + // from GetToken function to indicate lack of operation permission. + ErrUnauthorized = errors.New("unauthorized") +) + +type TransportError struct { + Err error +} + +func (t TransportError) Error() string { + return fmt.Sprintf("transport error: %v", t.Err) +} + +func (t TransportError) Unwrap() error { + return t.Err +} + +type ConnectError struct { + Err error +} + +func (c ConnectError) Error() string { + return fmt.Sprintf("connect error: %v", c.Err) +} + +func (c ConnectError) Unwrap() error { + return c.Err +} + +type RefreshError struct { + Err error +} + +func (r RefreshError) Error() string { + return fmt.Sprintf("refresh error: %v", r.Err) +} + +func (r RefreshError) Unwrap() error { + return r.Err +} + +type ConfigurationError struct { + Err error +} + +func (c ConfigurationError) Error() string { + return fmt.Sprintf("configuration error: %v", c.Err) +} + +func (c ConfigurationError) Unwrap() error { + return c.Err +} + +type SubscriptionSubscribeError struct { + Err error +} + +func (s SubscriptionSubscribeError) Error() string { + return fmt.Sprintf("subscribe error: %v", s.Err) +} + +func (s SubscriptionSubscribeError) Unwrap() error { + return s.Err +} + +type SubscriptionRefreshError struct { + Err error +} + +func (s SubscriptionRefreshError) Error() string { + return fmt.Sprintf("refresh error: %v", s.Err) +} + +func (s SubscriptionRefreshError) Unwrap() error { + return s.Err +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/log.go b/vendor/github.com/centrifugal/centrifuge-go/log.go new file mode 100644 index 0000000000..ad22c34deb --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/log.go @@ -0,0 +1,39 @@ +package centrifuge + +// LogHandler handles log entries - i.e. writes into correct destination if necessary. +type LogHandler func(LogEntry) + +// LogLevel describes the chosen log level. +type LogLevel int + +func (l LogLevel) String() string { + switch l { + case LogLevelNone: + return "NONE" + case LogLevelTrace: + return "TRACE" + case LogLevelDebug: + return "DEBUG" + default: + return "UNKNOWN" + } +} + +const ( + // LogLevelNone means no logging. + LogLevelNone LogLevel = iota + // LogLevelTrace turns on trace logs - should only be used during development. This + // log level shows all client-server communication (including token content) and + // affects performance significantly. + LogLevelTrace + // LogLevelDebug turns on debug logs - it's generally too much for production in normal + // conditions but can help when developing and investigating problems in production. + LogLevelDebug +) + +// LogEntry describes a log entry. +type LogEntry struct { + Level LogLevel + Message string + Fields map[string]string +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/protocol.go b/vendor/github.com/centrifugal/centrifuge-go/protocol.go new file mode 100644 index 0000000000..2986be2b49 --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/protocol.go @@ -0,0 +1,90 @@ +package centrifuge + +import ( + "fmt" + + "github.com/centrifugal/protocol" +) + +// Publication is a data sent to channel. +type Publication struct { + // Offset is an incremental position number inside history stream. + // Zero value means that channel does not maintain Publication stream. + Offset uint64 + // Data published to channel. + Data []byte + // Info is optional information about client connection published + // this data to channel. + Info *ClientInfo + // Tags contain custom key-value pairs attached to Publication. + Tags map[string]string +} + +// ClientInfo contains information about client connection. +type ClientInfo struct { + // Client is a client unique id. + Client string + // User is an ID of authenticated user. Zero value means anonymous user. + User string + // ConnInfo is additional information about connection. + ConnInfo []byte + // ChanInfo is additional information about connection in context of + // channel subscription. + ChanInfo []byte +} + +// Error represents protocol-level error. +type Error struct { + Code uint32 + Message string + Temporary bool +} + +func errorFromProto(err *protocol.Error) *Error { + return &Error{Code: err.Code, Message: err.Message, Temporary: err.Temporary} +} + +func (e Error) Error() string { + return fmt.Sprintf("%d: %s", e.Code, e.Message) +} + +func newReplyDecoder(enc protocol.Type, data []byte) protocol.ReplyDecoder { + if enc == protocol.TypeJSON { + return protocol.NewJSONReplyDecoder(data) + } + return protocol.NewProtobufReplyDecoder(data) +} + +func newCommandEncoder(enc protocol.Type) protocol.CommandEncoder { + if enc == protocol.TypeJSON { + return protocol.NewJSONCommandEncoder() + } + return protocol.NewProtobufCommandEncoder() +} + +func infoFromProto(v *protocol.ClientInfo) ClientInfo { + info := ClientInfo{ + Client: v.GetClient(), + User: v.GetUser(), + } + if len(v.ConnInfo) > 0 { + info.ConnInfo = v.ConnInfo + } + if len(v.ChanInfo) > 0 { + info.ChanInfo = v.ChanInfo + } + return info +} + +func pubFromProto(pub *protocol.Publication) Publication { + p := Publication{ + Offset: pub.GetOffset(), + Data: pub.Data, + Tags: pub.GetTags(), + } + if pub.GetInfo() != nil { + info := infoFromProto(pub.GetInfo()) + p.Info = &info + } + return p +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/queue.go b/vendor/github.com/centrifugal/centrifuge-go/queue.go new file mode 100644 index 0000000000..20595e4c23 --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/queue.go @@ -0,0 +1,96 @@ +package centrifuge + +import ( + "sync" + "time" +) + +// cbQueue allows processing callbacks in separate goroutine with +// preserved order. +// This queue implementation is a slightly modified code borrowed from +// https://github.com/nats-io/nats.go client released under Apache 2.0 +// license: see https://github.com/nats-io/nats.go/blob/master/LICENSE. +type cbQueue struct { + mu sync.Mutex + cond *sync.Cond + head *asyncCB + tail *asyncCB + closeCh chan struct{} + closed bool +} + +type asyncCB struct { + fn func(delay time.Duration) + tm time.Time + next *asyncCB +} + +// dispatch is responsible for calling async callbacks. Should be run +// in separate goroutine. +func (q *cbQueue) dispatch() { + for { + q.mu.Lock() + // Protect for spurious wake-ups. We should get out of the + // wait only if there is an element to pop from the list. + for q.head == nil { + q.cond.Wait() + } + curr := q.head + q.head = curr.next + if curr == q.tail { + q.tail = nil + } + q.mu.Unlock() + + // This signals that the dispatcher has been closed and all + // previous callbacks have been dispatched. + if curr.fn == nil { + close(q.closeCh) + return + } + curr.fn(time.Since(curr.tm)) + } +} + +// Push adds the given function to the tail of the list and +// signals the dispatcher. +func (q *cbQueue) push(f func(duration time.Duration)) { + q.pushOrClose(f, false) +} + +// Close signals that async queue must be closed. +// Queue won't accept any more callbacks after that – ignoring them if pushed. +func (q *cbQueue) close() { + q.pushOrClose(nil, true) + q.waitClose() +} + +func (q *cbQueue) waitClose() { + <-q.closeCh +} + +func (q *cbQueue) pushOrClose(f func(time.Duration), close bool) { + q.mu.Lock() + defer q.mu.Unlock() + if q.closed { + return + } + // Make sure that library is not calling push with nil function, + // since this is used to notify the dispatcher that it must stop. + if !close && f == nil { + panic("pushing a nil callback with false close") + } + cb := &asyncCB{fn: f, tm: time.Now()} + if q.tail != nil { + q.tail.next = cb + } else { + q.head = cb + } + q.tail = cb + if close { + q.closed = true + q.cond.Broadcast() + } else { + q.cond.Signal() + } +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/reconnect.go b/vendor/github.com/centrifugal/centrifuge-go/reconnect.go new file mode 100644 index 0000000000..fa1880f88b --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/reconnect.go @@ -0,0 +1,49 @@ +package centrifuge + +import ( + "time" + + "github.com/jpillora/backoff" +) + +type reconnectStrategy interface { + timeBeforeNextAttempt(attempt int) time.Duration +} + +type backoffReconnect struct { + // Factor is the multiplying factor for each increment step. + Factor float64 + // Jitter eases contention by randomizing backoff steps. + Jitter bool + // MinMilliseconds is a minimum value of reconnect interval. + MinDelay time.Duration + // MaxMilliseconds is a maximum value of reconnect interval. + MaxDelay time.Duration +} + +func (r *backoffReconnect) timeBeforeNextAttempt(attempt int) time.Duration { + b := &backoff.Backoff{ + Min: r.MinDelay, + Max: r.MaxDelay, + Factor: r.Factor, + Jitter: r.Jitter, + } + return b.ForAttempt(float64(attempt)) +} + +// newBackoffReconnect creates a new backoff reconnect strategy with custom min and max delays. +// If minDelay or maxDelay is zero, it uses the default values. +func newBackoffReconnect(minDelay, maxDelay time.Duration) reconnectStrategy { + if minDelay == 0 { + minDelay = 200 * time.Millisecond + } + if maxDelay == 0 { + maxDelay = 20 * time.Second + } + return &backoffReconnect{ + MinDelay: minDelay, + MaxDelay: maxDelay, + Factor: 2, + Jitter: true, + } +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/subscription.go b/vendor/github.com/centrifugal/centrifuge-go/subscription.go new file mode 100644 index 0000000000..038d02eb17 --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/subscription.go @@ -0,0 +1,862 @@ +package centrifuge + +import ( + "context" + "encoding/json" + "errors" + "sync" + "sync/atomic" + "time" + + "github.com/centrifugal/protocol" + fossil "github.com/shadowspore/fossil-delta" +) + +// SubState represents state of Subscription. +type SubState string + +// Different states of Subscription. +const ( + SubStateUnsubscribed SubState = "unsubscribed" + SubStateSubscribing SubState = "subscribing" + SubStateSubscribed SubState = "subscribed" +) + +// DeltaType represents type of delta used for Subscription. +type DeltaType string + +const ( + // DeltaTypeNone means that no delta is used for this subscription. + DeltaTypeNone DeltaType = "" + // DeltaTypeFossil means Fossil-based delta. + DeltaTypeFossil DeltaType = "fossil" +) + +// SubscriptionConfig allows setting Subscription options. +type SubscriptionConfig struct { + // Data is an arbitrary data to pass to a server in each subscribe request. + Data []byte + // Token for Subscription. + Token string + // GetToken called to get or refresh private channel subscription token. + GetToken func(SubscriptionTokenEvent) (string, error) + // Positioned flag asks server to make Subscription positioned. Only makes sense + // in channels with history stream on. + Positioned bool + // Recoverable flag asks server to make Subscription recoverable. Only makes sense + // in channels with history stream on. + Recoverable bool + // JoinLeave flag asks server to push join/leave messages. + JoinLeave bool + // Delta allows to specify delta type for the subscription. By default, no delta is used. + Delta DeltaType + // MinResubscribeDelay is the minimum delay between resubscription attempts. + // This delay is jittered. + // Zero value means 200 * time.Millisecond. + MinResubscribeDelay time.Duration + // MaxResubscribeDelay is the maximum delay between resubscription attempts. + // Zero value means 20 * time.Second. + MaxResubscribeDelay time.Duration +} + +func newSubscription(c *Client, channel string, config ...SubscriptionConfig) *Subscription { + var resubscribeStrategy reconnectStrategy + var minResubscribeDelay, maxResubscribeDelay time.Duration + if len(config) == 1 { + minResubscribeDelay = config[0].MinResubscribeDelay + maxResubscribeDelay = config[0].MaxResubscribeDelay + } + resubscribeStrategy = newBackoffReconnect(minResubscribeDelay, maxResubscribeDelay) + s := &Subscription{ + Channel: channel, + centrifuge: c, + state: SubStateUnsubscribed, + events: newSubscriptionEventHub(), + subFutures: make(map[uint64]subFuture), + resubscribeStrategy: resubscribeStrategy, + } + if len(config) == 1 { + cfg := config[0] + s.token = cfg.Token + s.getToken = cfg.GetToken + s.data = cfg.Data + s.positioned = cfg.Positioned + s.recoverable = cfg.Recoverable + s.joinLeave = cfg.JoinLeave + s.deltaType = cfg.Delta + } + return s +} + +// Subscription represents client subscription to channel. DO NOT initialize this struct +// directly, instead use Client.NewSubscription method to create channel subscriptions. +type Subscription struct { + futureID uint64 // Keep atomic on top! + + mu sync.RWMutex + centrifuge *Client + + // Channel for a subscription. + Channel string + + state SubState + + events *subscriptionEventHub + offset uint64 + epoch string + recover bool + subFutures map[uint64]subFuture + data []byte + + positioned bool + recoverable bool + joinLeave bool + + token string + getToken func(SubscriptionTokenEvent) (string, error) + + resubscribeAttempts int + resubscribeStrategy reconnectStrategy + + resubscribeTimer *time.Timer + refreshTimer *time.Timer + + deltaType DeltaType + deltaNegotiated bool + prevData []byte + + inflight atomic.Bool +} + +func (s *Subscription) State() SubState { + s.mu.RLock() + defer s.mu.RUnlock() + return s.state +} + +type subFuture struct { + fn func(error) + closeCh chan struct{} +} + +func newSubFuture(fn func(error)) subFuture { + return subFuture{fn: fn, closeCh: make(chan struct{})} +} + +func (s *Subscription) nextFutureID() uint64 { + return atomic.AddUint64(&s.futureID, 1) +} + +// Lock must be held outside. +func (s *Subscription) resolveSubFutures(err error) { + for _, fut := range s.subFutures { + fut.fn(err) + close(fut.closeCh) + } + s.subFutures = make(map[uint64]subFuture) +} + +// Publish allows publishing data to the subscription channel. +func (s *Subscription) Publish(ctx context.Context, data []byte) (PublishResult, error) { + s.mu.Lock() + if s.state == SubStateUnsubscribed { + s.mu.Unlock() + return PublishResult{}, ErrSubscriptionUnsubscribed + } + s.mu.Unlock() + + resCh := make(chan PublishResult, 1) + errCh := make(chan error, 1) + s.publish(ctx, data, func(result PublishResult, err error) { + resCh <- result + errCh <- err + }) + select { + case <-ctx.Done(): + return PublishResult{}, ctx.Err() + case res := <-resCh: + return res, <-errCh + } +} + +type HistoryOptions struct { + Limit int32 + Since *StreamPosition + Reverse bool +} + +type HistoryOption func(options *HistoryOptions) + +func WithHistorySince(sp *StreamPosition) HistoryOption { + return func(options *HistoryOptions) { + options.Since = sp + } +} + +func WithHistoryLimit(limit int32) HistoryOption { + return func(options *HistoryOptions) { + options.Limit = limit + } +} + +func WithHistoryReverse(reverse bool) HistoryOption { + return func(options *HistoryOptions) { + options.Reverse = reverse + } +} + +// History allows extracting channel history. By default, it returns current stream top +// position without publications. Use WithHistoryLimit with a value > 0 to make this func +// to return publications. +func (s *Subscription) History(ctx context.Context, opts ...HistoryOption) (HistoryResult, error) { + historyOpts := &HistoryOptions{} + for _, opt := range opts { + opt(historyOpts) + } + s.mu.Lock() + if s.state == SubStateUnsubscribed { + s.mu.Unlock() + return HistoryResult{}, ErrSubscriptionUnsubscribed + } + s.mu.Unlock() + + resCh := make(chan HistoryResult, 1) + errCh := make(chan error, 1) + s.history(ctx, *historyOpts, func(result HistoryResult, err error) { + resCh <- result + errCh <- err + }) + select { + case <-ctx.Done(): + return HistoryResult{}, ctx.Err() + case res := <-resCh: + return res, <-errCh + } +} + +// Presence allows extracting channel presence. +func (s *Subscription) Presence(ctx context.Context) (PresenceResult, error) { + s.mu.Lock() + if s.state == SubStateUnsubscribed { + s.mu.Unlock() + return PresenceResult{}, ErrSubscriptionUnsubscribed + } + s.mu.Unlock() + + resCh := make(chan PresenceResult, 1) + errCh := make(chan error, 1) + s.presence(ctx, func(result PresenceResult, err error) { + resCh <- result + errCh <- err + }) + select { + case <-ctx.Done(): + return PresenceResult{}, ctx.Err() + case res := <-resCh: + return res, <-errCh + } +} + +// PresenceStats allows extracting channel presence stats. +func (s *Subscription) PresenceStats(ctx context.Context) (PresenceStatsResult, error) { + s.mu.Lock() + if s.state == SubStateUnsubscribed { + s.mu.Unlock() + return PresenceStatsResult{}, ErrSubscriptionUnsubscribed + } + s.mu.Unlock() + + resCh := make(chan PresenceStatsResult, 1) + errCh := make(chan error, 1) + s.presenceStats(ctx, func(result PresenceStatsResult, err error) { + resCh <- result + errCh <- err + }) + select { + case <-ctx.Done(): + return PresenceStatsResult{}, ctx.Err() + case res := <-resCh: + return res, <-errCh + } +} + +func (s *Subscription) onSubscribe(fn func(err error)) { + s.mu.Lock() + defer s.mu.Unlock() + if s.state == SubStateSubscribed { + go fn(nil) + } else if s.state == SubStateUnsubscribed { + go fn(ErrSubscriptionUnsubscribed) + } else { + id := s.nextFutureID() + fut := newSubFuture(fn) + s.subFutures[id] = fut + go func() { + select { + case <-fut.closeCh: + case <-time.After(s.centrifuge.config.ReadTimeout): + s.mu.Lock() + defer s.mu.Unlock() + fut, ok := s.subFutures[id] + if !ok { + return + } + delete(s.subFutures, id) + fut.fn(ErrTimeout) + } + }() + } +} + +func (s *Subscription) publish(ctx context.Context, data []byte, fn func(PublishResult, error)) { + s.onSubscribe(func(err error) { + select { + case <-ctx.Done(): + fn(PublishResult{}, ctx.Err()) + return + default: + } + if err != nil { + fn(PublishResult{}, err) + return + } + s.centrifuge.publish(ctx, s.Channel, data, fn) + }) +} + +func (s *Subscription) history(ctx context.Context, opts HistoryOptions, fn func(HistoryResult, error)) { + s.onSubscribe(func(err error) { + select { + case <-ctx.Done(): + fn(HistoryResult{}, ctx.Err()) + return + default: + } + if err != nil { + fn(HistoryResult{}, err) + return + } + s.centrifuge.history(ctx, s.Channel, opts, fn) + }) +} + +func (s *Subscription) presence(ctx context.Context, fn func(PresenceResult, error)) { + s.onSubscribe(func(err error) { + select { + case <-ctx.Done(): + fn(PresenceResult{}, ctx.Err()) + return + default: + } + if err != nil { + fn(PresenceResult{}, err) + return + } + s.centrifuge.presence(ctx, s.Channel, fn) + }) +} + +func (s *Subscription) presenceStats(ctx context.Context, fn func(PresenceStatsResult, error)) { + s.onSubscribe(func(err error) { + select { + case <-ctx.Done(): + fn(PresenceStatsResult{}, ctx.Err()) + return + default: + } + if err != nil { + fn(PresenceStatsResult{}, err) + return + } + s.centrifuge.presenceStats(ctx, s.Channel, fn) + }) +} + +// Unsubscribe allows unsubscribing from channel. +func (s *Subscription) Unsubscribe() error { + if s.centrifuge.isClosed() { + return ErrClientClosed + } + s.unsubscribe(unsubscribedUnsubscribeCalled, "unsubscribe called", true) + return nil +} + +func (s *Subscription) unsubscribe(code uint32, reason string, sendUnsubscribe bool) { + s.moveToUnsubscribed(code, reason) + if sendUnsubscribe { + s.centrifuge.unsubscribe(s.Channel, func(result UnsubscribeResult, err error) { + if err != nil { + go s.centrifuge.handleDisconnect(&disconnect{Code: connectingUnsubscribeError, Reason: "unsubscribe error", Reconnect: true}) + return + } + }) + } +} + +// Subscribe allows initiating subscription process. +func (s *Subscription) Subscribe() error { + if s.centrifuge.isClosed() { + return ErrClientClosed + } + s.mu.Lock() + if s.state == SubStateSubscribed || s.state == SubStateSubscribing { + s.mu.Unlock() + return nil + } + s.state = SubStateSubscribing + s.mu.Unlock() + + if s.events != nil && s.events.onSubscribing != nil { + handler := s.events.onSubscribing + s.centrifuge.runHandlerAsync(func() { + handler(SubscribingEvent{ + Code: subscribingSubscribeCalled, + Reason: "subscribe called", + }) + }) + } + + if !s.centrifuge.isConnected() { + return nil + } + s.resubscribe() + return nil +} + +func (s *Subscription) moveToUnsubscribed(code uint32, reason string) { + s.mu.Lock() + s.resubscribeAttempts = 0 + if s.resubscribeTimer != nil { + s.resubscribeTimer.Stop() + } + if s.refreshTimer != nil { + s.refreshTimer.Stop() + } + + needEvent := s.state != SubStateUnsubscribed + s.state = SubStateUnsubscribed + s.mu.Unlock() + + if needEvent && s.events != nil && s.events.onUnsubscribe != nil { + handler := s.events.onUnsubscribe + s.centrifuge.runHandlerAsync(func() { + handler(UnsubscribedEvent{ + Code: code, + Reason: reason, + }) + }) + } +} + +func (s *Subscription) moveToSubscribing(code uint32, reason string) { + s.mu.Lock() + s.resubscribeAttempts = 0 + if s.resubscribeTimer != nil { + s.resubscribeTimer.Stop() + } + if s.refreshTimer != nil { + s.refreshTimer.Stop() + } + needEvent := s.state != SubStateSubscribing + s.state = SubStateSubscribing + s.mu.Unlock() + + if needEvent && s.events != nil && s.events.onSubscribing != nil { + handler := s.events.onSubscribing + s.centrifuge.runHandlerAsync(func() { + handler(SubscribingEvent{ + Code: code, + Reason: reason, + }) + }) + } +} + +func (s *Subscription) moveToSubscribed(res *protocol.SubscribeResult) { + s.mu.Lock() + if s.state != SubStateSubscribing { + s.mu.Unlock() + return + } + s.state = SubStateSubscribed + if res.Expires { + s.scheduleSubRefresh(res.Ttl) + } + if res.Recoverable { + s.recover = true + } + s.resubscribeAttempts = 0 + if s.resubscribeTimer != nil { + s.resubscribeTimer.Stop() + } + s.resolveSubFutures(nil) + s.offset = res.Offset + s.epoch = res.Epoch + s.deltaNegotiated = res.Delta + s.mu.Unlock() + + if s.events != nil && s.events.onSubscribed != nil { + handler := s.events.onSubscribed + ev := SubscribedEvent{ + Data: res.GetData(), + Recovered: res.GetRecovered(), + WasRecovering: res.GetWasRecovering(), + Recoverable: res.GetRecoverable(), + Positioned: res.GetPositioned(), + } + if ev.Positioned || ev.Recoverable { + ev.StreamPosition = &StreamPosition{ + Epoch: res.GetEpoch(), + Offset: res.GetOffset(), + } + } + s.centrifuge.runHandlerSync(func() { + handler(ev) + }) + } + + if len(res.Publications) > 0 { + s.centrifuge.runHandlerSync(func() { + pubs := res.Publications + for i := 0; i < len(pubs); i++ { + pub := res.Publications[i] + s.mu.Lock() + if s.state != SubStateSubscribed { + s.mu.Unlock() + return + } + if pub.Offset > 0 { + s.offset = pub.Offset + } + publicationEvent := PublicationEvent{Publication: pubFromProto(pub)} + publicationEvent = s.applyDeltaLocked(pub, publicationEvent) + s.mu.Unlock() + var handler PublicationHandler + if s.events != nil && s.events.onPublication != nil { + handler = s.events.onPublication + } + if handler != nil { + handler(publicationEvent) + } + } + }) + } +} + +func (s *Subscription) applyDeltaLocked(pub *protocol.Publication, event PublicationEvent) PublicationEvent { + if !s.deltaNegotiated { + return event + } + if s.centrifuge.protocolType == protocol.TypeJSON { + if pub.Delta { + // pub.Data is JSON string delta, let's decode to []byte and apply it to prevData. + var delta string + err := json.Unmarshal(pub.Data, &delta) + if err != nil { + panic(err) + } + newData, err := fossil.Apply(s.prevData, []byte(delta)) + if err != nil { + panic(err) + } + event.Data = newData + s.prevData = newData + } else { + // pub.Data is JSON string, let's decode to []byte and keep as prevData. + var data string + err := json.Unmarshal(pub.Data, &data) + if err != nil { + panic(err) + } + s.prevData = []byte(data) + event.Data = s.prevData + } + } else { + if pub.Delta { + newData, err := fossil.Apply(s.prevData, pub.Data) + if err != nil { + panic(err) + } + event.Data = newData + s.prevData = newData + } else { + s.prevData = pub.Data + } + } + return event +} + +// Lock must be held outside. +func (s *Subscription) scheduleResubscribe() { + if s.resubscribeTimer != nil { + if s.centrifuge.logLevelEnabled(LogLevelDebug) { + s.centrifuge.log(LogLevelDebug, "stopping previous resubscribe timer", map[string]string{ + "channel": s.Channel, + }) + } + s.resubscribeTimer.Stop() + s.resubscribeTimer = nil + } + delay := s.resubscribeStrategy.timeBeforeNextAttempt(s.resubscribeAttempts) + s.resubscribeAttempts++ + s.resubscribeTimer = time.AfterFunc(delay, func() { + s.mu.Lock() + if s.state != SubStateSubscribing { + s.mu.Unlock() + return + } + s.mu.Unlock() + s.resubscribe() + }) +} + +func (s *Subscription) subscribeError(err error) { + s.mu.Lock() + if s.state != SubStateSubscribing { + s.mu.Unlock() + return + } + s.mu.Unlock() + + if errors.Is(err, ErrTimeout) { + go s.centrifuge.handleDisconnect(&disconnect{Code: connectingSubscribeTimeout, Reason: "subscribe timeout", Reconnect: true}) + return + } + + s.emitError(SubscriptionSubscribeError{Err: err}) + + var serverError *Error + if errors.As(err, &serverError) { + if serverError.Code == 109 { // Token expired. + s.mu.Lock() + s.token = "" + s.scheduleResubscribe() + s.mu.Unlock() + } else if serverError.Temporary { + s.mu.Lock() + s.scheduleResubscribe() + s.mu.Unlock() + } else { + s.mu.Lock() + s.resolveSubFutures(err) + s.mu.Unlock() + s.unsubscribe(serverError.Code, serverError.Message, false) + } + } else { + s.mu.Lock() + s.scheduleResubscribe() + s.mu.Unlock() + } +} + +// Lock must be held outside. +func (s *Subscription) emitError(err error) { + if s.events != nil && s.events.onError != nil { + handler := s.events.onError + s.centrifuge.runHandlerSync(func() { + handler(SubscriptionErrorEvent{Error: err}) + }) + } +} + +func (s *Subscription) handlePublication(pub *protocol.Publication) { + s.mu.Lock() + if s.state != SubStateSubscribed { + s.mu.Unlock() + return + } + if pub.Offset > 0 { + s.offset = pub.Offset + } + publicationEvent := PublicationEvent{Publication: pubFromProto(pub)} + publicationEvent = s.applyDeltaLocked(pub, publicationEvent) + s.mu.Unlock() + + var handler PublicationHandler + if s.events != nil && s.events.onPublication != nil { + handler = s.events.onPublication + } + if handler == nil { + return + } + s.centrifuge.runHandlerSync(func() { + handler(publicationEvent) + }) +} + +func (s *Subscription) handleJoin(info *protocol.ClientInfo) { + var handler JoinHandler + if s.events != nil && s.events.onJoin != nil { + handler = s.events.onJoin + } + if handler != nil { + s.centrifuge.runHandlerSync(func() { + handler(JoinEvent{ClientInfo: infoFromProto(info)}) + }) + } +} + +func (s *Subscription) handleLeave(info *protocol.ClientInfo) { + var handler LeaveHandler + if s.events != nil && s.events.onLeave != nil { + handler = s.events.onLeave + } + if handler != nil { + s.centrifuge.runHandlerSync(func() { + handler(LeaveEvent{ClientInfo: infoFromProto(info)}) + }) + } +} + +func (s *Subscription) handleUnsubscribe(unsubscribe *protocol.Unsubscribe) { + if unsubscribe.Code < 2500 { + s.moveToUnsubscribed(unsubscribe.Code, unsubscribe.Reason) + } else { + s.moveToSubscribing(unsubscribe.Code, unsubscribe.Reason) + s.resubscribe() + } +} + +func (s *Subscription) resubscribe() { + s.mu.Lock() + if s.state != SubStateSubscribing { + s.mu.Unlock() + return + } + if s.inflight.Load() { + s.mu.Unlock() + if s.centrifuge.logLevelEnabled(LogLevelDebug) { + s.centrifuge.log(LogLevelDebug, "avoid subscribe since inflight", map[string]string{ + "channel": s.Channel, + }) + } + return + } + token := s.token + s.inflight.Store(true) + s.mu.Unlock() + + if token == "" && s.getToken != nil { + var err error + token, err = s.getSubscriptionToken(s.Channel) + if err != nil { + if errors.Is(err, ErrUnauthorized) { + s.inflight.Store(false) + s.unsubscribe(unsubscribedUnauthorized, "unauthorized", false) + return + } + s.inflight.Store(false) + s.subscribeError(err) + return + } + s.mu.Lock() + if token == "" { + s.mu.Unlock() + s.inflight.Store(false) + s.unsubscribe(unsubscribedUnauthorized, "unauthorized", false) + return + } + s.token = token + s.mu.Unlock() + } + + s.mu.Lock() + defer s.mu.Unlock() + if s.state != SubStateSubscribing { + s.inflight.Store(false) + return + } + + var isRecover bool + var sp StreamPosition + if s.recover { + isRecover = true + sp.Offset = s.offset + sp.Epoch = s.epoch + } + + err := s.centrifuge.sendSubscribe(s.Channel, s.data, isRecover, sp, token, s.positioned, s.recoverable, s.joinLeave, s.deltaType, func(res *protocol.SubscribeResult, err error) { + if err != nil { + s.inflight.Store(false) + s.subscribeError(err) + return + } + s.inflight.Store(false) + s.moveToSubscribed(res) + }) + if err != nil { + s.inflight.Store(false) + s.scheduleResubscribe() + } +} + +func (s *Subscription) getSubscriptionToken(channel string) (string, error) { + handler := s.getToken + if handler != nil { + ev := SubscriptionTokenEvent{ + Channel: channel, + } + return handler(ev) + } + return "", errors.New("GetToken must be set to get subscription token") +} + +// Lock must be held outside. +func (s *Subscription) scheduleSubRefresh(ttl uint32) { + if s.state != SubStateSubscribed { + return + } + s.refreshTimer = time.AfterFunc(time.Duration(ttl)*time.Second, func() { + s.mu.Lock() + if s.state != SubStateSubscribed { + s.mu.Unlock() + return + } + s.mu.Unlock() + + token, err := s.getSubscriptionToken(s.Channel) + if err != nil { + if errors.Is(err, ErrUnauthorized) { + s.unsubscribe(unsubscribedUnauthorized, "unauthorized", true) + return + } + s.mu.Lock() + defer s.mu.Unlock() + s.emitError(SubscriptionRefreshError{Err: err}) + s.scheduleSubRefresh(10) + return + } + if token == "" { + s.unsubscribe(unsubscribedUnauthorized, "unauthorized", true) + return + } + + s.centrifuge.sendSubRefresh(s.Channel, token, func(result *protocol.SubRefreshResult, err error) { + if err != nil { + s.emitError(SubscriptionSubscribeError{Err: err}) + var serverError *Error + if errors.As(err, &serverError) { + if serverError.Temporary { + s.mu.Lock() + defer s.mu.Unlock() + s.scheduleSubRefresh(10) + return + } else { + s.unsubscribe(serverError.Code, serverError.Message, true) + return + } + } else { + s.mu.Lock() + defer s.mu.Unlock() + s.scheduleSubRefresh(10) + return + } + } + if result.Expires { + s.mu.Lock() + s.scheduleSubRefresh(result.Ttl) + s.mu.Unlock() + } + }) + }) +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/subscription_events.go b/vendor/github.com/centrifugal/centrifuge-go/subscription_events.go new file mode 100644 index 0000000000..b9dca8bbf3 --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/subscription_events.go @@ -0,0 +1,119 @@ +package centrifuge + +// SubscribedEvent is an event context passed +// to subscribe success callback. +type SubscribedEvent struct { + Positioned bool + Recoverable bool + StreamPosition *StreamPosition + WasRecovering bool + Recovered bool + Data []byte +} + +// SubscriptionErrorEvent is a subscribe error event context passed to +// event callback. +type SubscriptionErrorEvent struct { + Error error +} + +// SubscribingEvent is an event passed to subscribing event handler. +type SubscribingEvent struct { + Code uint32 + Reason string +} + +// UnsubscribedEvent is an event passed to unsubscribe event handler. +type UnsubscribedEvent struct { + Code uint32 + Reason string +} + +// LeaveEvent has info about user who left channel. +type LeaveEvent struct { + ClientInfo +} + +// JoinEvent has info about user who joined channel. +type JoinEvent struct { + ClientInfo +} + +// PublicationEvent has info about received channel Publication. +type PublicationEvent struct { + Publication +} + +// PublicationHandler is a function to handle messages published in +// channels. +type PublicationHandler func(PublicationEvent) + +// JoinHandler is a function to handle join messages. +type JoinHandler func(JoinEvent) + +// LeaveHandler is a function to handle leave messages. +type LeaveHandler func(LeaveEvent) + +// UnsubscribedHandler is a function to handle unsubscribe event. +type UnsubscribedHandler func(UnsubscribedEvent) + +// SubscribingHandler is a function to handle subscribe success event. +type SubscribingHandler func(SubscribingEvent) + +// SubscribedHandler is a function to handle subscribe success event. +type SubscribedHandler func(SubscribedEvent) + +// SubscriptionErrorHandler is a function to handle subscribe error event. +type SubscriptionErrorHandler func(SubscriptionErrorEvent) + +// subscriptionEventHub contains callback functions that will be called when +// corresponding event happens with subscription to channel. +type subscriptionEventHub struct { + onSubscribing SubscribingHandler + onSubscribed SubscribedHandler + onUnsubscribe UnsubscribedHandler + onError SubscriptionErrorHandler + onPublication PublicationHandler + onJoin JoinHandler + onLeave LeaveHandler +} + +// newSubscriptionEventHub initializes new subscriptionEventHub. +func newSubscriptionEventHub() *subscriptionEventHub { + return &subscriptionEventHub{} +} + +// OnSubscribing allows setting SubscribingHandler to SubEventHandler. +func (s *Subscription) OnSubscribing(handler SubscribingHandler) { + s.events.onSubscribing = handler +} + +// OnSubscribed allows setting SubscribedHandler to SubEventHandler. +func (s *Subscription) OnSubscribed(handler SubscribedHandler) { + s.events.onSubscribed = handler +} + +// OnUnsubscribed allows setting UnsubscribedHandler to SubEventHandler. +func (s *Subscription) OnUnsubscribed(handler UnsubscribedHandler) { + s.events.onUnsubscribe = handler +} + +// OnError allows setting SubscriptionErrorHandler to SubEventHandler. +func (s *Subscription) OnError(handler SubscriptionErrorHandler) { + s.events.onError = handler +} + +// OnPublication allows setting PublicationHandler to SubEventHandler. +func (s *Subscription) OnPublication(handler PublicationHandler) { + s.events.onPublication = handler +} + +// OnJoin allows setting JoinHandler to SubEventHandler. +func (s *Subscription) OnJoin(handler JoinHandler) { + s.events.onJoin = handler +} + +// OnLeave allows setting LeaveHandler to SubEventHandler. +func (s *Subscription) OnLeave(handler LeaveHandler) { + s.events.onLeave = handler +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/transport.go b/vendor/github.com/centrifugal/centrifuge-go/transport.go new file mode 100644 index 0000000000..b225281d20 --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/transport.go @@ -0,0 +1,20 @@ +package centrifuge + +import ( + "time" + + "github.com/centrifugal/protocol" +) + +type transport interface { + // Read should read new Reply messages from connection. + // It should not be thread-safe as we will call it from one goroutine. + Read() (*protocol.Reply, *disconnect, error) + // Write should write Command to connection with specified write timeout. + // It should not be thread-safe as we will call it from one goroutine. + Write(cmd *protocol.Command, timeout time.Duration) error + // Close should close connection and do all cleanups required. + // It must be safe to call Close several times and concurrently with Read + // and Write methods. + Close() error +} diff --git a/vendor/github.com/centrifugal/centrifuge-go/transport_websocket.go b/vendor/github.com/centrifugal/centrifuge-go/transport_websocket.go new file mode 100644 index 0000000000..a0f39dd18e --- /dev/null +++ b/vendor/github.com/centrifugal/centrifuge-go/transport_websocket.go @@ -0,0 +1,220 @@ +package centrifuge + +import ( + "context" + "crypto/tls" + "encoding/json" + "fmt" + "io" + "net" + "net/http" + "net/url" + "sync" + "time" + + "github.com/centrifugal/protocol" + "github.com/gorilla/websocket" +) + +func extractDisconnectWebsocket(err error) *disconnect { + if err != nil { + if closeErr, ok := err.(*websocket.CloseError); ok { + var d disconnect + err := json.Unmarshal([]byte(closeErr.Text), &d) + if err == nil { + return &d + } else { + code := uint32(closeErr.Code) + reason := closeErr.Text + reconnect := code < 3500 || code >= 5000 || (code >= 4000 && code < 4500) + if code < 3000 { + switch code { + case websocket.CloseMessageTooBig: + code = disconnectMessageSizeLimit + default: + // We expose codes defined by Centrifuge protocol, hiding + // details about transport-specific error codes. We may have extra + // optional transportCode field in the future. + code = connectingTransportClosed + } + } + return &disconnect{ + Code: code, + Reason: reason, + Reconnect: reconnect, + } + } + } + } + return nil +} + +type websocketTransport struct { + mu sync.Mutex + conn *websocket.Conn + protocolType protocol.Type + commandEncoder protocol.CommandEncoder + replyCh chan *protocol.Reply + config websocketConfig + disconnect *disconnect + closed bool + closeCh chan struct{} +} + +// websocketConfig configures Websocket transport. +type websocketConfig struct { + // Proxy specifies a function to return a proxy for a given Request. + // If the function returns a non-nil error, the request is aborted with the + // provided error. If function returns a nil *URL, no proxy is used. + // If Proxy is nil then http.ProxyFromEnvironment will be used. + Proxy func(*http.Request) (*url.URL, error) + + // NetDialContext specifies the dial function for creating TCP connections. If + // NetDialContext is nil, net.DialContext is used. + NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error) + + // TLSConfig specifies the TLS configuration to use with tls.Client. + // If nil, the default configuration is used. + TLSConfig *tls.Config + + // HandshakeTimeout specifies the duration for the handshake to complete. + HandshakeTimeout time.Duration + + // EnableCompression specifies if the client should attempt to negotiate + // per message compression (RFC 7692). Setting this value to true does not + // guarantee that compression will be supported. Currently only "no context + // takeover" modes are supported. + EnableCompression bool + + // CookieJar specifies the cookie jar. + // If CookieJar is nil, cookies are not sent in requests and ignored + // in responses. + CookieJar http.CookieJar + + // Header specifies custom HTTP Header to send. + Header http.Header +} + +func newWebsocketTransport(url string, protocolType protocol.Type, config websocketConfig) (transport, error) { + wsHeaders := config.Header + + dialer := &websocket.Dialer{} + if config.Proxy != nil { + dialer.Proxy = config.Proxy + } else { + dialer.Proxy = http.ProxyFromEnvironment + } + dialer.NetDialContext = config.NetDialContext + + dialer.HandshakeTimeout = config.HandshakeTimeout + dialer.EnableCompression = config.EnableCompression + dialer.TLSClientConfig = config.TLSConfig + dialer.Jar = config.CookieJar + + if protocolType == protocol.TypeProtobuf { + dialer.Subprotocols = []string{"centrifuge-protobuf"} + } + + conn, resp, err := dialer.Dial(url, wsHeaders) + if err != nil { + return nil, fmt.Errorf("error dial: %v", err) + } + if resp.StatusCode != http.StatusSwitchingProtocols { + return nil, fmt.Errorf("wrong status code while connecting to server: %d", resp.StatusCode) + } + + t := &websocketTransport{ + conn: conn, + replyCh: make(chan *protocol.Reply), + config: config, + closeCh: make(chan struct{}), + commandEncoder: newCommandEncoder(protocolType), + protocolType: protocolType, + } + go t.reader() + return t, nil +} + +func (t *websocketTransport) Close() error { + t.mu.Lock() + defer t.mu.Unlock() + if t.closed { + return nil + } + t.closed = true + close(t.closeCh) + _ = t.conn.WriteControl(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""), time.Now().Add(time.Second)) + return t.conn.Close() +} + +func (t *websocketTransport) reader() { + defer func() { _ = t.Close() }() + defer close(t.replyCh) + + for { + _, data, err := t.conn.ReadMessage() + if err != nil { + disconnect := extractDisconnectWebsocket(err) + t.disconnect = disconnect + return + } + //println("<----", strings.Trim(string(data), "\n")) + loop: + for { + decoder := newReplyDecoder(t.protocolType, data) + for { + reply, err := decoder.Decode() + if err != nil { + if err == io.EOF { + break loop + } + t.disconnect = &disconnect{Code: disconnectBadProtocol, Reason: "decode error", Reconnect: false} + return + } + select { + case <-t.closeCh: + return + case t.replyCh <- reply: + // Send is blocking here, but slow client will be disconnected + // eventually with `no ping` reason – so we will exit from this + // goroutine. + } + } + } + } +} + +func (t *websocketTransport) Write(cmd *protocol.Command, timeout time.Duration) error { + data, err := t.commandEncoder.Encode(cmd) + if err != nil { + return err + } + return t.writeData(data, timeout) +} + +func (t *websocketTransport) writeData(data []byte, timeout time.Duration) error { + t.mu.Lock() + defer t.mu.Unlock() + if timeout > 0 { + _ = t.conn.SetWriteDeadline(time.Now().Add(timeout)) + } + //println("---->", strings.Trim(string(data), "\n")) + var err error + if t.protocolType == protocol.TypeJSON { + err = t.conn.WriteMessage(websocket.TextMessage, data) + } else { + err = t.conn.WriteMessage(websocket.BinaryMessage, data) + } + if timeout > 0 { + _ = t.conn.SetWriteDeadline(time.Time{}) + } + return err +} + +func (t *websocketTransport) Read() (*protocol.Reply, *disconnect, error) { + reply, ok := <-t.replyCh + if !ok { + return nil, t.disconnect, io.EOF + } + return reply, nil, nil +} diff --git a/vendor/github.com/centrifugal/protocol/.gitignore b/vendor/github.com/centrifugal/protocol/.gitignore new file mode 100644 index 0000000000..178b098c53 --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/.gitignore @@ -0,0 +1,5 @@ +.vscode/ +.idea/ +vendor/ +build/ +*.orig diff --git a/vendor/github.com/centrifugal/protocol/LICENSE b/vendor/github.com/centrifugal/protocol/LICENSE new file mode 100644 index 0000000000..624d2f8f73 --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2023 Centrifugal Labs LTD + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/vendor/github.com/centrifugal/protocol/Makefile b/vendor/github.com/centrifugal/protocol/Makefile new file mode 100644 index 0000000000..c6a6091d8d --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/Makefile @@ -0,0 +1,7 @@ +all: generate + +generate: + bash generate.sh + +test: + go test -v ./... diff --git a/vendor/github.com/centrifugal/protocol/bpool.go b/vendor/github.com/centrifugal/protocol/bpool.go new file mode 100644 index 0000000000..3578944b74 --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/bpool.go @@ -0,0 +1,81 @@ +package protocol + +import ( + "io" + "math/bits" + "sync" +) + +var ( + // Verify ByteBuffer implements io.Writer. + _ io.Writer = &ByteBuffer{} +) + +// ByteBuffer implements a simple byte buffer. +type ByteBuffer struct { + // B is the underlying byte slice. + B []byte +} + +// Reset resets bb. +func (bb *ByteBuffer) Reset() { + bb.B = bb.B[:0] +} + +// Write appends p to bb. +func (bb *ByteBuffer) Write(p []byte) (int, error) { + bb.B = append(bb.B, p...) + return len(p), nil +} + +// pools contain pools for byte slices of various capacities. +var pools [19]sync.Pool + +// maxBufferLength is the maximum length of an element that can be added to the Pool. +const maxBufferLength = 262144 // 2^18 + +// Log of base two, round up (for v > 0). +func nextLogBase2(v uint32) uint32 { + return uint32(bits.Len32(v - 1)) +} + +// Log of base two, round down (for v > 0) +func prevLogBase2(num uint32) uint32 { + next := nextLogBase2(num) + if num == (1 << next) { + return next + } + return next - 1 +} + +// getByteBuffer returns byte buffer with the given capacity. +func getByteBuffer(length int) *ByteBuffer { + if length == 0 { + return &ByteBuffer{ + B: nil, + } + } + if length > maxBufferLength { + return &ByteBuffer{ + B: make([]byte, 0, length), + } + } + idx := nextLogBase2(uint32(length)) + if v := pools[idx].Get(); v != nil { + return v.(*ByteBuffer) + } + return &ByteBuffer{ + B: make([]byte, 0, 1< maxBufferLength { + return // drop. + } + idx := prevLogBase2(uint32(capacity)) + bb.Reset() + pools[idx].Put(bb) +} diff --git a/vendor/github.com/centrifugal/protocol/client.pb.go b/vendor/github.com/centrifugal/protocol/client.pb.go new file mode 100644 index 0000000000..39307bfbc0 --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/client.pb.go @@ -0,0 +1,3811 @@ +// Code generated by protoc-gen-go. DO NOT EDIT. +// versions: +// protoc-gen-go v1.34.1 +// protoc v5.26.1 +// source: client.proto + +package protocol + +import ( + protoreflect "google.golang.org/protobuf/reflect/protoreflect" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + reflect "reflect" + sync "sync" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +type Error struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Message string `protobuf:"bytes,2,opt,name=message,proto3" json:"message,omitempty"` + Temporary bool `protobuf:"varint,3,opt,name=temporary,proto3" json:"temporary,omitempty"` +} + +func (x *Error) Reset() { + *x = Error{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[0] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Error) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Error) ProtoMessage() {} + +func (x *Error) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[0] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Error.ProtoReflect.Descriptor instead. +func (*Error) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{0} +} + +func (x *Error) GetCode() uint32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *Error) GetMessage() string { + if x != nil { + return x.Message + } + return "" +} + +func (x *Error) GetTemporary() bool { + if x != nil { + return x.Temporary + } + return false +} + +type EmulationRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Node string `protobuf:"bytes,1,opt,name=node,proto3" json:"node,omitempty"` + Session string `protobuf:"bytes,2,opt,name=session,proto3" json:"session,omitempty"` + Data Raw `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *EmulationRequest) Reset() { + *x = EmulationRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[1] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *EmulationRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*EmulationRequest) ProtoMessage() {} + +func (x *EmulationRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[1] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use EmulationRequest.ProtoReflect.Descriptor instead. +func (*EmulationRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{1} +} + +func (x *EmulationRequest) GetNode() string { + if x != nil { + return x.Node + } + return "" +} + +func (x *EmulationRequest) GetSession() string { + if x != nil { + return x.Session + } + return "" +} + +func (x *EmulationRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +// Command sent from a client to a server. +// ProtocolVersion2 uses id and one of the possible request messages. +type Command struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Id of command to let client match replies to commands. + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // ProtocolVersion2 client can send one of the following requests. Server will + // only take the first non-null request out of these and may return an error if + // client passed more than one request. We are not using oneof here due to JSON + // interoperability concerns. + Connect *ConnectRequest `protobuf:"bytes,4,opt,name=connect,proto3" json:"connect,omitempty"` + Subscribe *SubscribeRequest `protobuf:"bytes,5,opt,name=subscribe,proto3" json:"subscribe,omitempty"` + Unsubscribe *UnsubscribeRequest `protobuf:"bytes,6,opt,name=unsubscribe,proto3" json:"unsubscribe,omitempty"` + Publish *PublishRequest `protobuf:"bytes,7,opt,name=publish,proto3" json:"publish,omitempty"` + Presence *PresenceRequest `protobuf:"bytes,8,opt,name=presence,proto3" json:"presence,omitempty"` + PresenceStats *PresenceStatsRequest `protobuf:"bytes,9,opt,name=presence_stats,json=presenceStats,proto3" json:"presence_stats,omitempty"` + History *HistoryRequest `protobuf:"bytes,10,opt,name=history,proto3" json:"history,omitempty"` + Ping *PingRequest `protobuf:"bytes,11,opt,name=ping,proto3" json:"ping,omitempty"` + Send *SendRequest `protobuf:"bytes,12,opt,name=send,proto3" json:"send,omitempty"` + Rpc *RPCRequest `protobuf:"bytes,13,opt,name=rpc,proto3" json:"rpc,omitempty"` + Refresh *RefreshRequest `protobuf:"bytes,14,opt,name=refresh,proto3" json:"refresh,omitempty"` + SubRefresh *SubRefreshRequest `protobuf:"bytes,15,opt,name=sub_refresh,json=subRefresh,proto3" json:"sub_refresh,omitempty"` +} + +func (x *Command) Reset() { + *x = Command{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Command) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Command) ProtoMessage() {} + +func (x *Command) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[2] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Command.ProtoReflect.Descriptor instead. +func (*Command) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{2} +} + +func (x *Command) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Command) GetConnect() *ConnectRequest { + if x != nil { + return x.Connect + } + return nil +} + +func (x *Command) GetSubscribe() *SubscribeRequest { + if x != nil { + return x.Subscribe + } + return nil +} + +func (x *Command) GetUnsubscribe() *UnsubscribeRequest { + if x != nil { + return x.Unsubscribe + } + return nil +} + +func (x *Command) GetPublish() *PublishRequest { + if x != nil { + return x.Publish + } + return nil +} + +func (x *Command) GetPresence() *PresenceRequest { + if x != nil { + return x.Presence + } + return nil +} + +func (x *Command) GetPresenceStats() *PresenceStatsRequest { + if x != nil { + return x.PresenceStats + } + return nil +} + +func (x *Command) GetHistory() *HistoryRequest { + if x != nil { + return x.History + } + return nil +} + +func (x *Command) GetPing() *PingRequest { + if x != nil { + return x.Ping + } + return nil +} + +func (x *Command) GetSend() *SendRequest { + if x != nil { + return x.Send + } + return nil +} + +func (x *Command) GetRpc() *RPCRequest { + if x != nil { + return x.Rpc + } + return nil +} + +func (x *Command) GetRefresh() *RefreshRequest { + if x != nil { + return x.Refresh + } + return nil +} + +func (x *Command) GetSubRefresh() *SubRefreshRequest { + if x != nil { + return x.SubRefresh + } + return nil +} + +// Reply sent from a server to a client. +// ProtocolVersion2 uses id and one of the possible concrete result messages. +type Reply struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Id will only be set to a value > 0 for replies to commands. For pushes + // it will have zero value. + Id uint32 `protobuf:"varint,1,opt,name=id,proto3" json:"id,omitempty"` + // Error can only be set in replies to commands. For pushes it will have zero value. + Error *Error `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + // ProtocolVersion2 server can send one of the following fields. We are not using + // oneof here due to JSON interoperability concerns. + Push *Push `protobuf:"bytes,4,opt,name=push,proto3" json:"push,omitempty"` + Connect *ConnectResult `protobuf:"bytes,5,opt,name=connect,proto3" json:"connect,omitempty"` + Subscribe *SubscribeResult `protobuf:"bytes,6,opt,name=subscribe,proto3" json:"subscribe,omitempty"` + Unsubscribe *UnsubscribeResult `protobuf:"bytes,7,opt,name=unsubscribe,proto3" json:"unsubscribe,omitempty"` + Publish *PublishResult `protobuf:"bytes,8,opt,name=publish,proto3" json:"publish,omitempty"` + Presence *PresenceResult `protobuf:"bytes,9,opt,name=presence,proto3" json:"presence,omitempty"` + PresenceStats *PresenceStatsResult `protobuf:"bytes,10,opt,name=presence_stats,json=presenceStats,proto3" json:"presence_stats,omitempty"` + History *HistoryResult `protobuf:"bytes,11,opt,name=history,proto3" json:"history,omitempty"` + Ping *PingResult `protobuf:"bytes,12,opt,name=ping,proto3" json:"ping,omitempty"` + Rpc *RPCResult `protobuf:"bytes,13,opt,name=rpc,proto3" json:"rpc,omitempty"` + Refresh *RefreshResult `protobuf:"bytes,14,opt,name=refresh,proto3" json:"refresh,omitempty"` + SubRefresh *SubRefreshResult `protobuf:"bytes,15,opt,name=sub_refresh,json=subRefresh,proto3" json:"sub_refresh,omitempty"` +} + +func (x *Reply) Reset() { + *x = Reply{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[3] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Reply) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Reply) ProtoMessage() {} + +func (x *Reply) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[3] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Reply.ProtoReflect.Descriptor instead. +func (*Reply) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{3} +} + +func (x *Reply) GetId() uint32 { + if x != nil { + return x.Id + } + return 0 +} + +func (x *Reply) GetError() *Error { + if x != nil { + return x.Error + } + return nil +} + +func (x *Reply) GetPush() *Push { + if x != nil { + return x.Push + } + return nil +} + +func (x *Reply) GetConnect() *ConnectResult { + if x != nil { + return x.Connect + } + return nil +} + +func (x *Reply) GetSubscribe() *SubscribeResult { + if x != nil { + return x.Subscribe + } + return nil +} + +func (x *Reply) GetUnsubscribe() *UnsubscribeResult { + if x != nil { + return x.Unsubscribe + } + return nil +} + +func (x *Reply) GetPublish() *PublishResult { + if x != nil { + return x.Publish + } + return nil +} + +func (x *Reply) GetPresence() *PresenceResult { + if x != nil { + return x.Presence + } + return nil +} + +func (x *Reply) GetPresenceStats() *PresenceStatsResult { + if x != nil { + return x.PresenceStats + } + return nil +} + +func (x *Reply) GetHistory() *HistoryResult { + if x != nil { + return x.History + } + return nil +} + +func (x *Reply) GetPing() *PingResult { + if x != nil { + return x.Ping + } + return nil +} + +func (x *Reply) GetRpc() *RPCResult { + if x != nil { + return x.Rpc + } + return nil +} + +func (x *Reply) GetRefresh() *RefreshResult { + if x != nil { + return x.Refresh + } + return nil +} + +func (x *Reply) GetSubRefresh() *SubRefreshResult { + if x != nil { + return x.SubRefresh + } + return nil +} + +// Push can be sent to a client as part of Reply in case of bidirectional transport or +// without additional wrapping in case of unidirectional transports. +// ProtocolVersion2 uses channel and one of the possible concrete push messages. +type Push struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Channel string `protobuf:"bytes,2,opt,name=channel,proto3" json:"channel,omitempty"` + // ProtocolVersion2 server can push one of the following fields to the client. We are + // not using oneof here due to JSON interoperability concerns. + Pub *Publication `protobuf:"bytes,4,opt,name=pub,proto3" json:"pub,omitempty"` + Join *Join `protobuf:"bytes,5,opt,name=join,proto3" json:"join,omitempty"` + Leave *Leave `protobuf:"bytes,6,opt,name=leave,proto3" json:"leave,omitempty"` + Unsubscribe *Unsubscribe `protobuf:"bytes,7,opt,name=unsubscribe,proto3" json:"unsubscribe,omitempty"` + Message *Message `protobuf:"bytes,8,opt,name=message,proto3" json:"message,omitempty"` + Subscribe *Subscribe `protobuf:"bytes,9,opt,name=subscribe,proto3" json:"subscribe,omitempty"` + Connect *Connect `protobuf:"bytes,10,opt,name=connect,proto3" json:"connect,omitempty"` + Disconnect *Disconnect `protobuf:"bytes,11,opt,name=disconnect,proto3" json:"disconnect,omitempty"` + Refresh *Refresh `protobuf:"bytes,12,opt,name=refresh,proto3" json:"refresh,omitempty"` +} + +func (x *Push) Reset() { + *x = Push{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Push) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Push) ProtoMessage() {} + +func (x *Push) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Push.ProtoReflect.Descriptor instead. +func (*Push) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{4} +} + +func (x *Push) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +func (x *Push) GetPub() *Publication { + if x != nil { + return x.Pub + } + return nil +} + +func (x *Push) GetJoin() *Join { + if x != nil { + return x.Join + } + return nil +} + +func (x *Push) GetLeave() *Leave { + if x != nil { + return x.Leave + } + return nil +} + +func (x *Push) GetUnsubscribe() *Unsubscribe { + if x != nil { + return x.Unsubscribe + } + return nil +} + +func (x *Push) GetMessage() *Message { + if x != nil { + return x.Message + } + return nil +} + +func (x *Push) GetSubscribe() *Subscribe { + if x != nil { + return x.Subscribe + } + return nil +} + +func (x *Push) GetConnect() *Connect { + if x != nil { + return x.Connect + } + return nil +} + +func (x *Push) GetDisconnect() *Disconnect { + if x != nil { + return x.Disconnect + } + return nil +} + +func (x *Push) GetRefresh() *Refresh { + if x != nil { + return x.Refresh + } + return nil +} + +type ClientInfo struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + User string `protobuf:"bytes,1,opt,name=user,proto3" json:"user"` + Client string `protobuf:"bytes,2,opt,name=client,proto3" json:"client"` + ConnInfo Raw `protobuf:"bytes,3,opt,name=conn_info,json=connInfo,proto3" json:"conn_info,omitempty"` + ChanInfo Raw `protobuf:"bytes,4,opt,name=chan_info,json=chanInfo,proto3" json:"chan_info,omitempty"` +} + +func (x *ClientInfo) Reset() { + *x = ClientInfo{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ClientInfo) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ClientInfo) ProtoMessage() {} + +func (x *ClientInfo) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ClientInfo.ProtoReflect.Descriptor instead. +func (*ClientInfo) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{5} +} + +func (x *ClientInfo) GetUser() string { + if x != nil { + return x.User + } + return "" +} + +func (x *ClientInfo) GetClient() string { + if x != nil { + return x.Client + } + return "" +} + +func (x *ClientInfo) GetConnInfo() []byte { + if x != nil { + return x.ConnInfo + } + return nil +} + +func (x *ClientInfo) GetChanInfo() []byte { + if x != nil { + return x.ChanInfo + } + return nil +} + +type Publication struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data Raw `protobuf:"bytes,4,opt,name=data,proto3" json:"data,omitempty"` + Info *ClientInfo `protobuf:"bytes,5,opt,name=info,proto3" json:"info,omitempty"` + Offset uint64 `protobuf:"varint,6,opt,name=offset,proto3" json:"offset,omitempty"` + Tags map[string]string `protobuf:"bytes,7,rep,name=tags,proto3" json:"tags,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Delta bool `protobuf:"varint,8,opt,name=delta,proto3" json:"delta,omitempty"` // When set indicates that data in Publication is a delta from previous data. + Time int64 `protobuf:"varint,9,opt,name=time,proto3" json:"time,omitempty"` // Optional time of publication as Unix timestamp milliseconds. + Channel string `protobuf:"bytes,10,opt,name=channel,proto3" json:"channel,omitempty"` // Optional channel name if Publication relates to wildcard subscription. +} + +func (x *Publication) Reset() { + *x = Publication{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Publication) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Publication) ProtoMessage() {} + +func (x *Publication) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[6] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Publication.ProtoReflect.Descriptor instead. +func (*Publication) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{6} +} + +func (x *Publication) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *Publication) GetInfo() *ClientInfo { + if x != nil { + return x.Info + } + return nil +} + +func (x *Publication) GetOffset() uint64 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *Publication) GetTags() map[string]string { + if x != nil { + return x.Tags + } + return nil +} + +func (x *Publication) GetDelta() bool { + if x != nil { + return x.Delta + } + return false +} + +func (x *Publication) GetTime() int64 { + if x != nil { + return x.Time + } + return 0 +} + +func (x *Publication) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +type Join struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Info *ClientInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"` +} + +func (x *Join) Reset() { + *x = Join{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[7] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Join) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Join) ProtoMessage() {} + +func (x *Join) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[7] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Join.ProtoReflect.Descriptor instead. +func (*Join) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{7} +} + +func (x *Join) GetInfo() *ClientInfo { + if x != nil { + return x.Info + } + return nil +} + +type Leave struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Info *ClientInfo `protobuf:"bytes,1,opt,name=info,proto3" json:"info,omitempty"` +} + +func (x *Leave) Reset() { + *x = Leave{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[8] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Leave) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Leave) ProtoMessage() {} + +func (x *Leave) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[8] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Leave.ProtoReflect.Descriptor instead. +func (*Leave) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{8} +} + +func (x *Leave) GetInfo() *ClientInfo { + if x != nil { + return x.Info + } + return nil +} + +type Unsubscribe struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code uint32 `protobuf:"varint,2,opt,name=code,proto3" json:"code,omitempty"` + Reason string `protobuf:"bytes,3,opt,name=reason,proto3" json:"reason,omitempty"` +} + +func (x *Unsubscribe) Reset() { + *x = Unsubscribe{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[9] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Unsubscribe) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Unsubscribe) ProtoMessage() {} + +func (x *Unsubscribe) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[9] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Unsubscribe.ProtoReflect.Descriptor instead. +func (*Unsubscribe) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{9} +} + +func (x *Unsubscribe) GetCode() uint32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *Unsubscribe) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +type Subscribe struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Recoverable bool `protobuf:"varint,1,opt,name=recoverable,proto3" json:"recoverable,omitempty"` + Epoch string `protobuf:"bytes,4,opt,name=epoch,proto3" json:"epoch,omitempty"` + Offset uint64 `protobuf:"varint,5,opt,name=offset,proto3" json:"offset,omitempty"` + Positioned bool `protobuf:"varint,6,opt,name=positioned,proto3" json:"positioned,omitempty"` + Data Raw `protobuf:"bytes,7,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *Subscribe) Reset() { + *x = Subscribe{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[10] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Subscribe) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Subscribe) ProtoMessage() {} + +func (x *Subscribe) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[10] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Subscribe.ProtoReflect.Descriptor instead. +func (*Subscribe) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{10} +} + +func (x *Subscribe) GetRecoverable() bool { + if x != nil { + return x.Recoverable + } + return false +} + +func (x *Subscribe) GetEpoch() string { + if x != nil { + return x.Epoch + } + return "" +} + +func (x *Subscribe) GetOffset() uint64 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *Subscribe) GetPositioned() bool { + if x != nil { + return x.Positioned + } + return false +} + +func (x *Subscribe) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type Message struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data Raw `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *Message) Reset() { + *x = Message{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[11] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Message) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Message) ProtoMessage() {} + +func (x *Message) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[11] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Message.ProtoReflect.Descriptor instead. +func (*Message) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{11} +} + +func (x *Message) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type Connect struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Client string `protobuf:"bytes,1,opt,name=client,proto3" json:"client,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Data Raw `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` + Subs map[string]*SubscribeResult `protobuf:"bytes,4,rep,name=subs,proto3" json:"subs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Expires bool `protobuf:"varint,5,opt,name=expires,proto3" json:"expires,omitempty"` + Ttl uint32 `protobuf:"varint,6,opt,name=ttl,proto3" json:"ttl,omitempty"` + Ping uint32 `protobuf:"varint,7,opt,name=ping,proto3" json:"ping,omitempty"` + Pong bool `protobuf:"varint,8,opt,name=pong,proto3" json:"pong,omitempty"` + Session string `protobuf:"bytes,9,opt,name=session,proto3" json:"session,omitempty"` + Node string `protobuf:"bytes,10,opt,name=node,proto3" json:"node,omitempty"` + Time int64 `protobuf:"varint,11,opt,name=time,proto3" json:"time,omitempty"` // Server time as Unix timestamp in milliseconds (not sent by default). +} + +func (x *Connect) Reset() { + *x = Connect{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[12] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Connect) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Connect) ProtoMessage() {} + +func (x *Connect) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[12] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Connect.ProtoReflect.Descriptor instead. +func (*Connect) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{12} +} + +func (x *Connect) GetClient() string { + if x != nil { + return x.Client + } + return "" +} + +func (x *Connect) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *Connect) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *Connect) GetSubs() map[string]*SubscribeResult { + if x != nil { + return x.Subs + } + return nil +} + +func (x *Connect) GetExpires() bool { + if x != nil { + return x.Expires + } + return false +} + +func (x *Connect) GetTtl() uint32 { + if x != nil { + return x.Ttl + } + return 0 +} + +func (x *Connect) GetPing() uint32 { + if x != nil { + return x.Ping + } + return 0 +} + +func (x *Connect) GetPong() bool { + if x != nil { + return x.Pong + } + return false +} + +func (x *Connect) GetSession() string { + if x != nil { + return x.Session + } + return "" +} + +func (x *Connect) GetNode() string { + if x != nil { + return x.Node + } + return "" +} + +func (x *Connect) GetTime() int64 { + if x != nil { + return x.Time + } + return 0 +} + +type Disconnect struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Code uint32 `protobuf:"varint,1,opt,name=code,proto3" json:"code,omitempty"` + Reason string `protobuf:"bytes,2,opt,name=reason,proto3" json:"reason,omitempty"` + Reconnect bool `protobuf:"varint,3,opt,name=reconnect,proto3" json:"reconnect,omitempty"` +} + +func (x *Disconnect) Reset() { + *x = Disconnect{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[13] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Disconnect) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Disconnect) ProtoMessage() {} + +func (x *Disconnect) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[13] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Disconnect.ProtoReflect.Descriptor instead. +func (*Disconnect) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{13} +} + +func (x *Disconnect) GetCode() uint32 { + if x != nil { + return x.Code + } + return 0 +} + +func (x *Disconnect) GetReason() string { + if x != nil { + return x.Reason + } + return "" +} + +func (x *Disconnect) GetReconnect() bool { + if x != nil { + return x.Reconnect + } + return false +} + +type Refresh struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Expires bool `protobuf:"varint,1,opt,name=expires,proto3" json:"expires,omitempty"` + Ttl uint32 `protobuf:"varint,2,opt,name=ttl,proto3" json:"ttl,omitempty"` +} + +func (x *Refresh) Reset() { + *x = Refresh{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[14] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Refresh) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Refresh) ProtoMessage() {} + +func (x *Refresh) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[14] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Refresh.ProtoReflect.Descriptor instead. +func (*Refresh) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{14} +} + +func (x *Refresh) GetExpires() bool { + if x != nil { + return x.Expires + } + return false +} + +func (x *Refresh) GetTtl() uint32 { + if x != nil { + return x.Ttl + } + return 0 +} + +type ConnectRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` + Data Raw `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` + Subs map[string]*SubscribeRequest `protobuf:"bytes,3,rep,name=subs,proto3" json:"subs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Name string `protobuf:"bytes,4,opt,name=name,proto3" json:"name,omitempty"` + Version string `protobuf:"bytes,5,opt,name=version,proto3" json:"version,omitempty"` + Headers map[string]string `protobuf:"bytes,6,rep,name=headers,proto3" json:"headers,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *ConnectRequest) Reset() { + *x = ConnectRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[15] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConnectRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConnectRequest) ProtoMessage() {} + +func (x *ConnectRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[15] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConnectRequest.ProtoReflect.Descriptor instead. +func (*ConnectRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{15} +} + +func (x *ConnectRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *ConnectRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *ConnectRequest) GetSubs() map[string]*SubscribeRequest { + if x != nil { + return x.Subs + } + return nil +} + +func (x *ConnectRequest) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *ConnectRequest) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *ConnectRequest) GetHeaders() map[string]string { + if x != nil { + return x.Headers + } + return nil +} + +type ConnectResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Client string `protobuf:"bytes,1,opt,name=client,proto3" json:"client,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Expires bool `protobuf:"varint,3,opt,name=expires,proto3" json:"expires,omitempty"` + Ttl uint32 `protobuf:"varint,4,opt,name=ttl,proto3" json:"ttl,omitempty"` + Data Raw `protobuf:"bytes,5,opt,name=data,proto3" json:"data,omitempty"` + Subs map[string]*SubscribeResult `protobuf:"bytes,6,rep,name=subs,proto3" json:"subs,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + Ping uint32 `protobuf:"varint,7,opt,name=ping,proto3" json:"ping,omitempty"` + Pong bool `protobuf:"varint,8,opt,name=pong,proto3" json:"pong,omitempty"` + Session string `protobuf:"bytes,9,opt,name=session,proto3" json:"session,omitempty"` + Node string `protobuf:"bytes,10,opt,name=node,proto3" json:"node,omitempty"` + Time int64 `protobuf:"varint,11,opt,name=time,proto3" json:"time,omitempty"` // Server time as Unix timestamp in milliseconds (not sent by default). +} + +func (x *ConnectResult) Reset() { + *x = ConnectResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ConnectResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ConnectResult) ProtoMessage() {} + +func (x *ConnectResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use ConnectResult.ProtoReflect.Descriptor instead. +func (*ConnectResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{16} +} + +func (x *ConnectResult) GetClient() string { + if x != nil { + return x.Client + } + return "" +} + +func (x *ConnectResult) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *ConnectResult) GetExpires() bool { + if x != nil { + return x.Expires + } + return false +} + +func (x *ConnectResult) GetTtl() uint32 { + if x != nil { + return x.Ttl + } + return 0 +} + +func (x *ConnectResult) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *ConnectResult) GetSubs() map[string]*SubscribeResult { + if x != nil { + return x.Subs + } + return nil +} + +func (x *ConnectResult) GetPing() uint32 { + if x != nil { + return x.Ping + } + return 0 +} + +func (x *ConnectResult) GetPong() bool { + if x != nil { + return x.Pong + } + return false +} + +func (x *ConnectResult) GetSession() string { + if x != nil { + return x.Session + } + return "" +} + +func (x *ConnectResult) GetNode() string { + if x != nil { + return x.Node + } + return "" +} + +func (x *ConnectResult) GetTime() int64 { + if x != nil { + return x.Time + } + return 0 +} + +type RefreshRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Token string `protobuf:"bytes,1,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *RefreshRequest) Reset() { + *x = RefreshRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[17] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RefreshRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RefreshRequest) ProtoMessage() {} + +func (x *RefreshRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[17] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RefreshRequest.ProtoReflect.Descriptor instead. +func (*RefreshRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{17} +} + +func (x *RefreshRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type RefreshResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Client string `protobuf:"bytes,1,opt,name=client,proto3" json:"client,omitempty"` + Version string `protobuf:"bytes,2,opt,name=version,proto3" json:"version,omitempty"` + Expires bool `protobuf:"varint,3,opt,name=expires,proto3" json:"expires,omitempty"` + Ttl uint32 `protobuf:"varint,4,opt,name=ttl,proto3" json:"ttl,omitempty"` +} + +func (x *RefreshResult) Reset() { + *x = RefreshResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[18] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RefreshResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RefreshResult) ProtoMessage() {} + +func (x *RefreshResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[18] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RefreshResult.ProtoReflect.Descriptor instead. +func (*RefreshResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{18} +} + +func (x *RefreshResult) GetClient() string { + if x != nil { + return x.Client + } + return "" +} + +func (x *RefreshResult) GetVersion() string { + if x != nil { + return x.Version + } + return "" +} + +func (x *RefreshResult) GetExpires() bool { + if x != nil { + return x.Expires + } + return false +} + +func (x *RefreshResult) GetTtl() uint32 { + if x != nil { + return x.Ttl + } + return 0 +} + +type SubscribeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Channel string `protobuf:"bytes,1,opt,name=channel,proto3" json:"channel,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` + Recover bool `protobuf:"varint,3,opt,name=recover,proto3" json:"recover,omitempty"` + Epoch string `protobuf:"bytes,6,opt,name=epoch,proto3" json:"epoch,omitempty"` + Offset uint64 `protobuf:"varint,7,opt,name=offset,proto3" json:"offset,omitempty"` + Data Raw `protobuf:"bytes,8,opt,name=data,proto3" json:"data,omitempty"` + Positioned bool `protobuf:"varint,9,opt,name=positioned,proto3" json:"positioned,omitempty"` + Recoverable bool `protobuf:"varint,10,opt,name=recoverable,proto3" json:"recoverable,omitempty"` + JoinLeave bool `protobuf:"varint,11,opt,name=join_leave,json=joinLeave,proto3" json:"join_leave,omitempty"` + Delta string `protobuf:"bytes,12,opt,name=delta,proto3" json:"delta,omitempty"` +} + +func (x *SubscribeRequest) Reset() { + *x = SubscribeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[19] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubscribeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscribeRequest) ProtoMessage() {} + +func (x *SubscribeRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[19] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscribeRequest.ProtoReflect.Descriptor instead. +func (*SubscribeRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{19} +} + +func (x *SubscribeRequest) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +func (x *SubscribeRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +func (x *SubscribeRequest) GetRecover() bool { + if x != nil { + return x.Recover + } + return false +} + +func (x *SubscribeRequest) GetEpoch() string { + if x != nil { + return x.Epoch + } + return "" +} + +func (x *SubscribeRequest) GetOffset() uint64 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *SubscribeRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *SubscribeRequest) GetPositioned() bool { + if x != nil { + return x.Positioned + } + return false +} + +func (x *SubscribeRequest) GetRecoverable() bool { + if x != nil { + return x.Recoverable + } + return false +} + +func (x *SubscribeRequest) GetJoinLeave() bool { + if x != nil { + return x.JoinLeave + } + return false +} + +func (x *SubscribeRequest) GetDelta() string { + if x != nil { + return x.Delta + } + return "" +} + +type SubscribeResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Expires bool `protobuf:"varint,1,opt,name=expires,proto3" json:"expires,omitempty"` + Ttl uint32 `protobuf:"varint,2,opt,name=ttl,proto3" json:"ttl,omitempty"` + Recoverable bool `protobuf:"varint,3,opt,name=recoverable,proto3" json:"recoverable,omitempty"` + Epoch string `protobuf:"bytes,6,opt,name=epoch,proto3" json:"epoch,omitempty"` + Publications []*Publication `protobuf:"bytes,7,rep,name=publications,proto3" json:"publications,omitempty"` + Recovered bool `protobuf:"varint,8,opt,name=recovered,proto3" json:"recovered,omitempty"` + Offset uint64 `protobuf:"varint,9,opt,name=offset,proto3" json:"offset,omitempty"` + Positioned bool `protobuf:"varint,10,opt,name=positioned,proto3" json:"positioned,omitempty"` + Data Raw `protobuf:"bytes,11,opt,name=data,proto3" json:"data,omitempty"` + WasRecovering bool `protobuf:"varint,12,opt,name=was_recovering,json=wasRecovering,proto3" json:"was_recovering,omitempty"` + Delta bool `protobuf:"varint,13,opt,name=delta,proto3" json:"delta,omitempty"` +} + +func (x *SubscribeResult) Reset() { + *x = SubscribeResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[20] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubscribeResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubscribeResult) ProtoMessage() {} + +func (x *SubscribeResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[20] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubscribeResult.ProtoReflect.Descriptor instead. +func (*SubscribeResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{20} +} + +func (x *SubscribeResult) GetExpires() bool { + if x != nil { + return x.Expires + } + return false +} + +func (x *SubscribeResult) GetTtl() uint32 { + if x != nil { + return x.Ttl + } + return 0 +} + +func (x *SubscribeResult) GetRecoverable() bool { + if x != nil { + return x.Recoverable + } + return false +} + +func (x *SubscribeResult) GetEpoch() string { + if x != nil { + return x.Epoch + } + return "" +} + +func (x *SubscribeResult) GetPublications() []*Publication { + if x != nil { + return x.Publications + } + return nil +} + +func (x *SubscribeResult) GetRecovered() bool { + if x != nil { + return x.Recovered + } + return false +} + +func (x *SubscribeResult) GetOffset() uint64 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *SubscribeResult) GetPositioned() bool { + if x != nil { + return x.Positioned + } + return false +} + +func (x *SubscribeResult) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *SubscribeResult) GetWasRecovering() bool { + if x != nil { + return x.WasRecovering + } + return false +} + +func (x *SubscribeResult) GetDelta() bool { + if x != nil { + return x.Delta + } + return false +} + +type SubRefreshRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Channel string `protobuf:"bytes,1,opt,name=channel,proto3" json:"channel,omitempty"` + Token string `protobuf:"bytes,2,opt,name=token,proto3" json:"token,omitempty"` +} + +func (x *SubRefreshRequest) Reset() { + *x = SubRefreshRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[21] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubRefreshRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubRefreshRequest) ProtoMessage() {} + +func (x *SubRefreshRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[21] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubRefreshRequest.ProtoReflect.Descriptor instead. +func (*SubRefreshRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{21} +} + +func (x *SubRefreshRequest) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +func (x *SubRefreshRequest) GetToken() string { + if x != nil { + return x.Token + } + return "" +} + +type SubRefreshResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Expires bool `protobuf:"varint,1,opt,name=expires,proto3" json:"expires,omitempty"` + Ttl uint32 `protobuf:"varint,2,opt,name=ttl,proto3" json:"ttl,omitempty"` +} + +func (x *SubRefreshResult) Reset() { + *x = SubRefreshResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[22] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SubRefreshResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SubRefreshResult) ProtoMessage() {} + +func (x *SubRefreshResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[22] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SubRefreshResult.ProtoReflect.Descriptor instead. +func (*SubRefreshResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{22} +} + +func (x *SubRefreshResult) GetExpires() bool { + if x != nil { + return x.Expires + } + return false +} + +func (x *SubRefreshResult) GetTtl() uint32 { + if x != nil { + return x.Ttl + } + return 0 +} + +type UnsubscribeRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Channel string `protobuf:"bytes,1,opt,name=channel,proto3" json:"channel,omitempty"` +} + +func (x *UnsubscribeRequest) Reset() { + *x = UnsubscribeRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[23] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnsubscribeRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnsubscribeRequest) ProtoMessage() {} + +func (x *UnsubscribeRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[23] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnsubscribeRequest.ProtoReflect.Descriptor instead. +func (*UnsubscribeRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{23} +} + +func (x *UnsubscribeRequest) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +type UnsubscribeResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *UnsubscribeResult) Reset() { + *x = UnsubscribeResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[24] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *UnsubscribeResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*UnsubscribeResult) ProtoMessage() {} + +func (x *UnsubscribeResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[24] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use UnsubscribeResult.ProtoReflect.Descriptor instead. +func (*UnsubscribeResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{24} +} + +type PublishRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Channel string `protobuf:"bytes,1,opt,name=channel,proto3" json:"channel,omitempty"` + Data Raw `protobuf:"bytes,2,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *PublishRequest) Reset() { + *x = PublishRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[25] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublishRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublishRequest) ProtoMessage() {} + +func (x *PublishRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[25] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublishRequest.ProtoReflect.Descriptor instead. +func (*PublishRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{25} +} + +func (x *PublishRequest) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +func (x *PublishRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type PublishResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PublishResult) Reset() { + *x = PublishResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[26] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PublishResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PublishResult) ProtoMessage() {} + +func (x *PublishResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[26] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PublishResult.ProtoReflect.Descriptor instead. +func (*PublishResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{26} +} + +type PresenceRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Channel string `protobuf:"bytes,1,opt,name=channel,proto3" json:"channel,omitempty"` +} + +func (x *PresenceRequest) Reset() { + *x = PresenceRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[27] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PresenceRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PresenceRequest) ProtoMessage() {} + +func (x *PresenceRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[27] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PresenceRequest.ProtoReflect.Descriptor instead. +func (*PresenceRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{27} +} + +func (x *PresenceRequest) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +type PresenceResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Presence map[string]*ClientInfo `protobuf:"bytes,1,rep,name=presence,proto3" json:"presence" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` +} + +func (x *PresenceResult) Reset() { + *x = PresenceResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[28] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PresenceResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PresenceResult) ProtoMessage() {} + +func (x *PresenceResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[28] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PresenceResult.ProtoReflect.Descriptor instead. +func (*PresenceResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{28} +} + +func (x *PresenceResult) GetPresence() map[string]*ClientInfo { + if x != nil { + return x.Presence + } + return nil +} + +type PresenceStatsRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Channel string `protobuf:"bytes,1,opt,name=channel,proto3" json:"channel,omitempty"` +} + +func (x *PresenceStatsRequest) Reset() { + *x = PresenceStatsRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PresenceStatsRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PresenceStatsRequest) ProtoMessage() {} + +func (x *PresenceStatsRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PresenceStatsRequest.ProtoReflect.Descriptor instead. +func (*PresenceStatsRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{29} +} + +func (x *PresenceStatsRequest) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +type PresenceStatsResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + NumClients uint32 `protobuf:"varint,1,opt,name=num_clients,json=numClients,proto3" json:"num_clients"` + NumUsers uint32 `protobuf:"varint,2,opt,name=num_users,json=numUsers,proto3" json:"num_users"` +} + +func (x *PresenceStatsResult) Reset() { + *x = PresenceStatsResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PresenceStatsResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PresenceStatsResult) ProtoMessage() {} + +func (x *PresenceStatsResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PresenceStatsResult.ProtoReflect.Descriptor instead. +func (*PresenceStatsResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{30} +} + +func (x *PresenceStatsResult) GetNumClients() uint32 { + if x != nil { + return x.NumClients + } + return 0 +} + +func (x *PresenceStatsResult) GetNumUsers() uint32 { + if x != nil { + return x.NumUsers + } + return 0 +} + +type StreamPosition struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Offset uint64 `protobuf:"varint,1,opt,name=offset,proto3" json:"offset,omitempty"` + Epoch string `protobuf:"bytes,2,opt,name=epoch,proto3" json:"epoch,omitempty"` +} + +func (x *StreamPosition) Reset() { + *x = StreamPosition{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StreamPosition) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StreamPosition) ProtoMessage() {} + +func (x *StreamPosition) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use StreamPosition.ProtoReflect.Descriptor instead. +func (*StreamPosition) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{31} +} + +func (x *StreamPosition) GetOffset() uint64 { + if x != nil { + return x.Offset + } + return 0 +} + +func (x *StreamPosition) GetEpoch() string { + if x != nil { + return x.Epoch + } + return "" +} + +type HistoryRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Channel string `protobuf:"bytes,1,opt,name=channel,proto3" json:"channel,omitempty"` + Limit int32 `protobuf:"varint,7,opt,name=limit,proto3" json:"limit,omitempty"` + Since *StreamPosition `protobuf:"bytes,8,opt,name=since,proto3" json:"since,omitempty"` + Reverse bool `protobuf:"varint,9,opt,name=reverse,proto3" json:"reverse,omitempty"` +} + +func (x *HistoryRequest) Reset() { + *x = HistoryRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[32] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HistoryRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HistoryRequest) ProtoMessage() {} + +func (x *HistoryRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[32] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HistoryRequest.ProtoReflect.Descriptor instead. +func (*HistoryRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{32} +} + +func (x *HistoryRequest) GetChannel() string { + if x != nil { + return x.Channel + } + return "" +} + +func (x *HistoryRequest) GetLimit() int32 { + if x != nil { + return x.Limit + } + return 0 +} + +func (x *HistoryRequest) GetSince() *StreamPosition { + if x != nil { + return x.Since + } + return nil +} + +func (x *HistoryRequest) GetReverse() bool { + if x != nil { + return x.Reverse + } + return false +} + +type HistoryResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Publications []*Publication `protobuf:"bytes,1,rep,name=publications,proto3" json:"publications"` + Epoch string `protobuf:"bytes,2,opt,name=epoch,proto3" json:"epoch"` + Offset uint64 `protobuf:"varint,3,opt,name=offset,proto3" json:"offset"` +} + +func (x *HistoryResult) Reset() { + *x = HistoryResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[33] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *HistoryResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*HistoryResult) ProtoMessage() {} + +func (x *HistoryResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[33] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use HistoryResult.ProtoReflect.Descriptor instead. +func (*HistoryResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{33} +} + +func (x *HistoryResult) GetPublications() []*Publication { + if x != nil { + return x.Publications + } + return nil +} + +func (x *HistoryResult) GetEpoch() string { + if x != nil { + return x.Epoch + } + return "" +} + +func (x *HistoryResult) GetOffset() uint64 { + if x != nil { + return x.Offset + } + return 0 +} + +type PingRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PingRequest) Reset() { + *x = PingRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[34] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PingRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PingRequest) ProtoMessage() {} + +func (x *PingRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[34] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PingRequest.ProtoReflect.Descriptor instead. +func (*PingRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{34} +} + +type PingResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields +} + +func (x *PingResult) Reset() { + *x = PingResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[35] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PingResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PingResult) ProtoMessage() {} + +func (x *PingResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[35] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use PingResult.ProtoReflect.Descriptor instead. +func (*PingResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{35} +} + +type RPCRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data Raw `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + Method string `protobuf:"bytes,2,opt,name=method,proto3" json:"method,omitempty"` +} + +func (x *RPCRequest) Reset() { + *x = RPCRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[36] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RPCRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RPCRequest) ProtoMessage() {} + +func (x *RPCRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[36] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RPCRequest.ProtoReflect.Descriptor instead. +func (*RPCRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{36} +} + +func (x *RPCRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +func (x *RPCRequest) GetMethod() string { + if x != nil { + return x.Method + } + return "" +} + +type RPCResult struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data Raw `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *RPCResult) Reset() { + *x = RPCResult{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[37] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *RPCResult) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*RPCResult) ProtoMessage() {} + +func (x *RPCResult) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[37] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use RPCResult.ProtoReflect.Descriptor instead. +func (*RPCResult) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{37} +} + +func (x *RPCResult) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +type SendRequest struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Data Raw `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` +} + +func (x *SendRequest) Reset() { + *x = SendRequest{} + if protoimpl.UnsafeEnabled { + mi := &file_client_proto_msgTypes[38] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *SendRequest) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*SendRequest) ProtoMessage() {} + +func (x *SendRequest) ProtoReflect() protoreflect.Message { + mi := &file_client_proto_msgTypes[38] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use SendRequest.ProtoReflect.Descriptor instead. +func (*SendRequest) Descriptor() ([]byte, []int) { + return file_client_proto_rawDescGZIP(), []int{38} +} + +func (x *SendRequest) GetData() []byte { + if x != nil { + return x.Data + } + return nil +} + +var File_client_proto protoreflect.FileDescriptor + +var file_client_proto_rawDesc = []byte{ + 0x0a, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1f, + 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x22, + 0x53, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, + 0x61, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x74, 0x65, 0x6d, 0x70, 0x6f, + 0x72, 0x61, 0x72, 0x79, 0x22, 0x54, 0x0a, 0x10, 0x45, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, + 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0xbd, 0x07, 0x0a, 0x07, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x02, 0x69, 0x64, 0x12, 0x49, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, + 0x74, 0x12, 0x4f, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, + 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, + 0x62, 0x65, 0x12, 0x55, 0x0a, 0x0b, 0x75, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x33, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, + 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x0b, 0x75, 0x6e, + 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x49, 0x0a, 0x07, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, + 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x07, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x73, 0x68, 0x12, 0x4c, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, + 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, + 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x08, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, + 0x63, 0x65, 0x12, 0x5c, 0x0a, 0x0e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, + 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x72, 0x65, + 0x73, 0x65, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x52, 0x0d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, + 0x12, 0x49, 0x0a, 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, + 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x52, 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x40, 0x0a, 0x04, 0x70, + 0x69, 0x6e, 0x67, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, + 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x40, 0x0a, + 0x04, 0x73, 0x65, 0x6e, 0x64, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x65, + 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x64, 0x12, + 0x3d, 0x0a, 0x03, 0x72, 0x70, 0x63, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, + 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, + 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x52, + 0x50, 0x43, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x52, 0x03, 0x72, 0x70, 0x63, 0x12, 0x49, + 0x0a, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2f, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x52, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x12, 0x53, 0x0a, 0x0b, 0x73, 0x75, 0x62, + 0x5f, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, + 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x2e, 0x53, 0x75, 0x62, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x52, 0x0a, 0x73, 0x75, 0x62, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4a, 0x04, + 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0xe1, 0x07, 0x0a, 0x05, 0x52, + 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x02, 0x69, 0x64, 0x12, 0x3c, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, + 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x12, 0x39, 0x0a, 0x04, 0x70, 0x75, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x25, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, + 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2e, 0x50, 0x75, 0x73, 0x68, 0x52, 0x04, 0x70, 0x75, 0x73, 0x68, 0x12, 0x48, 0x0a, + 0x07, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, + 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x4e, 0x0a, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, + 0x72, 0x69, 0x62, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, + 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x09, 0x73, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x54, 0x0a, 0x0b, 0x75, 0x6e, 0x73, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, + 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, + 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x55, + 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x52, 0x0b, 0x75, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x48, 0x0a, + 0x07, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, + 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x12, 0x4b, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x73, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, + 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x72, 0x65, 0x73, + 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x08, 0x70, 0x72, 0x65, 0x73, + 0x65, 0x6e, 0x63, 0x65, 0x12, 0x5b, 0x0a, 0x0e, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, + 0x5f, 0x73, 0x74, 0x61, 0x74, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x63, + 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, + 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, + 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x52, 0x0d, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, + 0x73, 0x12, 0x48, 0x0a, 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x0b, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, + 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x52, 0x07, 0x68, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x3f, 0x0a, 0x04, 0x70, + 0x69, 0x6e, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, + 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x69, 0x6e, 0x67, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x04, 0x70, 0x69, 0x6e, 0x67, 0x12, 0x3c, 0x0a, 0x03, + 0x72, 0x70, 0x63, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, + 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x52, 0x50, 0x43, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x03, 0x72, 0x70, 0x63, 0x12, 0x48, 0x0a, 0x07, 0x72, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x52, 0x65, + 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x12, 0x52, 0x0a, 0x0b, 0x73, 0x75, 0x62, 0x5f, 0x72, 0x65, 0x66, 0x72, + 0x65, 0x73, 0x68, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x63, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, + 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x75, 0x62, 0x52, + 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x0a, 0x73, 0x75, + 0x62, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x98, + 0x05, 0x0a, 0x04, 0x50, 0x75, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, + 0x65, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, + 0x6c, 0x12, 0x3e, 0x0a, 0x03, 0x70, 0x75, 0x62, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2c, + 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, + 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x03, 0x70, 0x75, + 0x62, 0x12, 0x39, 0x0a, 0x04, 0x6a, 0x6f, 0x69, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x25, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2e, 0x4a, 0x6f, 0x69, 0x6e, 0x52, 0x04, 0x6a, 0x6f, 0x69, 0x6e, 0x12, 0x3c, 0x0a, 0x05, + 0x6c, 0x65, 0x61, 0x76, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x4c, 0x65, + 0x61, 0x76, 0x65, 0x52, 0x05, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x4e, 0x0a, 0x0b, 0x75, 0x6e, + 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2e, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x0b, 0x75, + 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x42, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x4d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x48, + 0x0a, 0x09, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2a, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, + 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x09, 0x73, + 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x42, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x65, 0x6e, 0x74, + 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, + 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x4b, 0x0a, 0x0a, + 0x64, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2b, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, + 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2e, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x0a, 0x64, + 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, 0x42, 0x0a, 0x07, 0x72, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, + 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x52, 0x07, 0x72, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x4a, 0x04, 0x08, + 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x72, 0x0a, 0x0a, 0x43, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x75, 0x73, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x75, 0x73, 0x65, 0x72, 0x12, 0x16, 0x0a, 0x06, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6c, 0x69, + 0x65, 0x6e, 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x6e, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x08, 0x63, 0x68, 0x61, 0x6e, 0x49, 0x6e, 0x66, 0x6f, 0x22, 0xd5, 0x02, + 0x0a, 0x0b, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x12, 0x3f, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x2b, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, + 0x6c, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, + 0x66, 0x6f, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x4a, 0x0a, 0x04, 0x74, 0x61, + 0x67, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x36, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, + 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x54, 0x61, 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x04, 0x74, 0x61, 0x67, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x18, + 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x12, 0x12, 0x0a, 0x04, + 0x74, 0x69, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x1a, 0x37, 0x0a, 0x09, 0x54, 0x61, + 0x67, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, + 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x47, 0x0a, 0x04, 0x4a, 0x6f, 0x69, 0x6e, 0x12, 0x3f, 0x0a, + 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x43, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x48, + 0x0a, 0x05, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x3f, 0x0a, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, + 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, + 0x66, 0x6f, 0x52, 0x04, 0x69, 0x6e, 0x66, 0x6f, 0x22, 0x3f, 0x0a, 0x0b, 0x55, 0x6e, 0x73, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, + 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, + 0x73, 0x6f, 0x6e, 0x4a, 0x04, 0x08, 0x01, 0x10, 0x02, 0x22, 0x9b, 0x01, 0x0a, 0x09, 0x53, 0x75, + 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, 0x72, 0x65, + 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, + 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, + 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x4a, 0x04, 0x08, 0x02, 0x10, + 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, 0x22, 0x1d, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x98, 0x03, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x6e, 0x65, + 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x46, 0x0a, 0x04, 0x73, 0x75, 0x62, 0x73, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, + 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, + 0x2e, 0x53, 0x75, 0x62, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x73, 0x75, 0x62, 0x73, + 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, + 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x12, 0x12, 0x0a, 0x04, + 0x70, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x69, 0x6e, 0x67, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, + 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, + 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x1a, 0x69, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, + 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x56, 0x0a, 0x0a, 0x44, 0x69, 0x73, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x72, + 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, + 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x22, 0x35, 0x0a, 0x07, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x10, + 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x74, 0x74, 0x6c, + 0x22, 0xb7, 0x03, 0x0a, 0x0e, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, + 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4d, 0x0a, + 0x04, 0x73, 0x75, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x39, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x53, 0x75, 0x62, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x73, 0x75, 0x62, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x56, 0x0a, 0x07, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3c, 0x2e, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, + 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x43, 0x6f, + 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x48, 0x65, 0x61, + 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, + 0x72, 0x73, 0x1a, 0x6a, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x47, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x31, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, + 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3a, + 0x0a, 0x0c, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xa4, 0x03, 0x0a, 0x0d, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, + 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x4c, + 0x0a, 0x04, 0x73, 0x75, 0x62, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x38, 0x2e, 0x63, + 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, + 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x43, + 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x53, 0x75, 0x62, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x04, 0x73, 0x75, 0x62, 0x73, 0x12, 0x12, 0x0a, 0x04, + 0x70, 0x69, 0x6e, 0x67, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x70, 0x69, 0x6e, 0x67, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x6f, 0x6e, 0x67, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, + 0x70, 0x6f, 0x6e, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x6f, 0x64, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x6f, + 0x64, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x1a, 0x69, 0x0a, 0x09, 0x53, 0x75, 0x62, 0x73, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x46, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, + 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, + 0x01, 0x22, 0x26, 0x0a, 0x0e, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x6d, 0x0a, 0x0d, 0x52, 0x65, 0x66, + 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x18, 0x0a, 0x07, + 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, + 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, 0x6c, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x22, 0xa1, 0x02, 0x0a, 0x10, 0x53, 0x75, 0x62, + 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, + 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, + 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x18, 0x0a, + 0x07, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, + 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x16, 0x0a, + 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, + 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x1e, 0x0a, 0x0a, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x70, + 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x12, 0x20, 0x0a, 0x0b, 0x72, 0x65, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0b, + 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x6a, + 0x6f, 0x69, 0x6e, 0x5f, 0x6c, 0x65, 0x61, 0x76, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x09, 0x6a, 0x6f, 0x69, 0x6e, 0x4c, 0x65, 0x61, 0x76, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, + 0x6c, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x74, 0x61, + 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0xfa, 0x02, 0x0a, + 0x0f, 0x53, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x74, + 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x12, 0x20, 0x0a, 0x0b, + 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x08, 0x52, 0x0b, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, + 0x70, 0x6f, 0x63, 0x68, 0x12, 0x50, 0x0a, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, + 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, + 0x72, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x72, 0x65, 0x63, 0x6f, 0x76, + 0x65, 0x72, 0x65, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1e, 0x0a, 0x0a, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x08, + 0x52, 0x0a, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x65, 0x64, 0x12, 0x12, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x69, + 0x6e, 0x67, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x77, 0x61, 0x73, 0x52, 0x65, 0x63, + 0x6f, 0x76, 0x65, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x6c, 0x74, 0x61, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x64, 0x65, 0x6c, 0x74, 0x61, 0x4a, 0x04, 0x08, + 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x22, 0x43, 0x0a, 0x11, 0x53, 0x75, 0x62, + 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, + 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, + 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x3e, + 0x0a, 0x10, 0x53, 0x75, 0x62, 0x52, 0x65, 0x66, 0x72, 0x65, 0x73, 0x68, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x12, 0x10, 0x0a, 0x03, + 0x74, 0x74, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x74, 0x74, 0x6c, 0x22, 0x2e, + 0x0a, 0x12, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, 0x13, + 0x0a, 0x11, 0x55, 0x6e, 0x73, 0x75, 0x62, 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x22, 0x3e, 0x0a, 0x0e, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x22, 0x0f, 0x0a, 0x0d, 0x50, 0x75, 0x62, 0x6c, 0x69, 0x73, 0x68, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x22, 0x2b, 0x0a, 0x0f, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, + 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, + 0x6c, 0x22, 0xd5, 0x01, 0x0a, 0x0e, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x59, 0x0a, 0x08, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, + 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3d, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, + 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, + 0x65, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x2e, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x08, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x1a, + 0x68, 0x0a, 0x0d, 0x50, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, + 0x65, 0x79, 0x12, 0x41, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x2b, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, + 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x63, 0x6f, 0x6c, 0x2e, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x30, 0x0a, 0x14, 0x50, 0x72, 0x65, + 0x73, 0x65, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, + 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x22, 0x53, 0x0a, 0x13, 0x50, + 0x72, 0x65, 0x73, 0x65, 0x6e, 0x63, 0x65, 0x53, 0x74, 0x61, 0x74, 0x73, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x6e, 0x75, 0x6d, 0x5f, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6e, 0x75, 0x6d, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x74, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x75, 0x6d, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x73, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x6e, 0x75, 0x6d, 0x55, 0x73, 0x65, 0x72, 0x73, + 0x22, 0x3e, 0x0a, 0x0e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, + 0x6f, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, + 0x22, 0xbf, 0x01, 0x0a, 0x0e, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x18, 0x0a, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x12, 0x14, 0x0a, + 0x05, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x12, 0x45, 0x0a, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, + 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x50, 0x6f, 0x73, 0x69, 0x74, + 0x69, 0x6f, 0x6e, 0x52, 0x05, 0x73, 0x69, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, + 0x76, 0x65, 0x72, 0x73, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x72, 0x65, 0x76, + 0x65, 0x72, 0x73, 0x65, 0x4a, 0x04, 0x08, 0x02, 0x10, 0x03, 0x4a, 0x04, 0x08, 0x03, 0x10, 0x04, + 0x4a, 0x04, 0x08, 0x04, 0x10, 0x05, 0x4a, 0x04, 0x08, 0x05, 0x10, 0x06, 0x4a, 0x04, 0x08, 0x06, + 0x10, 0x07, 0x22, 0x8f, 0x01, 0x0a, 0x0d, 0x48, 0x69, 0x73, 0x74, 0x6f, 0x72, 0x79, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x12, 0x50, 0x0a, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x63, 0x65, 0x6e, + 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2e, 0x63, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x66, + 0x75, 0x67, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x70, 0x6f, 0x63, 0x68, 0x12, 0x16, 0x0a, 0x06, + 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x6f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x22, 0x0d, 0x0a, 0x0b, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x22, 0x0c, 0x0a, 0x0a, 0x50, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x22, 0x38, 0x0a, 0x0a, 0x52, 0x50, 0x43, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x22, 0x1f, 0x0a, 0x09, 0x52, + 0x50, 0x43, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x21, 0x0a, 0x0b, + 0x53, 0x65, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x42, + 0x21, 0x5a, 0x1f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x66, 0x75, 0x67, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +} + +var ( + file_client_proto_rawDescOnce sync.Once + file_client_proto_rawDescData = file_client_proto_rawDesc +) + +func file_client_proto_rawDescGZIP() []byte { + file_client_proto_rawDescOnce.Do(func() { + file_client_proto_rawDescData = protoimpl.X.CompressGZIP(file_client_proto_rawDescData) + }) + return file_client_proto_rawDescData +} + +var file_client_proto_msgTypes = make([]protoimpl.MessageInfo, 45) +var file_client_proto_goTypes = []interface{}{ + (*Error)(nil), // 0: centrifugal.centrifuge.protocol.Error + (*EmulationRequest)(nil), // 1: centrifugal.centrifuge.protocol.EmulationRequest + (*Command)(nil), // 2: centrifugal.centrifuge.protocol.Command + (*Reply)(nil), // 3: centrifugal.centrifuge.protocol.Reply + (*Push)(nil), // 4: centrifugal.centrifuge.protocol.Push + (*ClientInfo)(nil), // 5: centrifugal.centrifuge.protocol.ClientInfo + (*Publication)(nil), // 6: centrifugal.centrifuge.protocol.Publication + (*Join)(nil), // 7: centrifugal.centrifuge.protocol.Join + (*Leave)(nil), // 8: centrifugal.centrifuge.protocol.Leave + (*Unsubscribe)(nil), // 9: centrifugal.centrifuge.protocol.Unsubscribe + (*Subscribe)(nil), // 10: centrifugal.centrifuge.protocol.Subscribe + (*Message)(nil), // 11: centrifugal.centrifuge.protocol.Message + (*Connect)(nil), // 12: centrifugal.centrifuge.protocol.Connect + (*Disconnect)(nil), // 13: centrifugal.centrifuge.protocol.Disconnect + (*Refresh)(nil), // 14: centrifugal.centrifuge.protocol.Refresh + (*ConnectRequest)(nil), // 15: centrifugal.centrifuge.protocol.ConnectRequest + (*ConnectResult)(nil), // 16: centrifugal.centrifuge.protocol.ConnectResult + (*RefreshRequest)(nil), // 17: centrifugal.centrifuge.protocol.RefreshRequest + (*RefreshResult)(nil), // 18: centrifugal.centrifuge.protocol.RefreshResult + (*SubscribeRequest)(nil), // 19: centrifugal.centrifuge.protocol.SubscribeRequest + (*SubscribeResult)(nil), // 20: centrifugal.centrifuge.protocol.SubscribeResult + (*SubRefreshRequest)(nil), // 21: centrifugal.centrifuge.protocol.SubRefreshRequest + (*SubRefreshResult)(nil), // 22: centrifugal.centrifuge.protocol.SubRefreshResult + (*UnsubscribeRequest)(nil), // 23: centrifugal.centrifuge.protocol.UnsubscribeRequest + (*UnsubscribeResult)(nil), // 24: centrifugal.centrifuge.protocol.UnsubscribeResult + (*PublishRequest)(nil), // 25: centrifugal.centrifuge.protocol.PublishRequest + (*PublishResult)(nil), // 26: centrifugal.centrifuge.protocol.PublishResult + (*PresenceRequest)(nil), // 27: centrifugal.centrifuge.protocol.PresenceRequest + (*PresenceResult)(nil), // 28: centrifugal.centrifuge.protocol.PresenceResult + (*PresenceStatsRequest)(nil), // 29: centrifugal.centrifuge.protocol.PresenceStatsRequest + (*PresenceStatsResult)(nil), // 30: centrifugal.centrifuge.protocol.PresenceStatsResult + (*StreamPosition)(nil), // 31: centrifugal.centrifuge.protocol.StreamPosition + (*HistoryRequest)(nil), // 32: centrifugal.centrifuge.protocol.HistoryRequest + (*HistoryResult)(nil), // 33: centrifugal.centrifuge.protocol.HistoryResult + (*PingRequest)(nil), // 34: centrifugal.centrifuge.protocol.PingRequest + (*PingResult)(nil), // 35: centrifugal.centrifuge.protocol.PingResult + (*RPCRequest)(nil), // 36: centrifugal.centrifuge.protocol.RPCRequest + (*RPCResult)(nil), // 37: centrifugal.centrifuge.protocol.RPCResult + (*SendRequest)(nil), // 38: centrifugal.centrifuge.protocol.SendRequest + nil, // 39: centrifugal.centrifuge.protocol.Publication.TagsEntry + nil, // 40: centrifugal.centrifuge.protocol.Connect.SubsEntry + nil, // 41: centrifugal.centrifuge.protocol.ConnectRequest.SubsEntry + nil, // 42: centrifugal.centrifuge.protocol.ConnectRequest.HeadersEntry + nil, // 43: centrifugal.centrifuge.protocol.ConnectResult.SubsEntry + nil, // 44: centrifugal.centrifuge.protocol.PresenceResult.PresenceEntry +} +var file_client_proto_depIdxs = []int32{ + 15, // 0: centrifugal.centrifuge.protocol.Command.connect:type_name -> centrifugal.centrifuge.protocol.ConnectRequest + 19, // 1: centrifugal.centrifuge.protocol.Command.subscribe:type_name -> centrifugal.centrifuge.protocol.SubscribeRequest + 23, // 2: centrifugal.centrifuge.protocol.Command.unsubscribe:type_name -> centrifugal.centrifuge.protocol.UnsubscribeRequest + 25, // 3: centrifugal.centrifuge.protocol.Command.publish:type_name -> centrifugal.centrifuge.protocol.PublishRequest + 27, // 4: centrifugal.centrifuge.protocol.Command.presence:type_name -> centrifugal.centrifuge.protocol.PresenceRequest + 29, // 5: centrifugal.centrifuge.protocol.Command.presence_stats:type_name -> centrifugal.centrifuge.protocol.PresenceStatsRequest + 32, // 6: centrifugal.centrifuge.protocol.Command.history:type_name -> centrifugal.centrifuge.protocol.HistoryRequest + 34, // 7: centrifugal.centrifuge.protocol.Command.ping:type_name -> centrifugal.centrifuge.protocol.PingRequest + 38, // 8: centrifugal.centrifuge.protocol.Command.send:type_name -> centrifugal.centrifuge.protocol.SendRequest + 36, // 9: centrifugal.centrifuge.protocol.Command.rpc:type_name -> centrifugal.centrifuge.protocol.RPCRequest + 17, // 10: centrifugal.centrifuge.protocol.Command.refresh:type_name -> centrifugal.centrifuge.protocol.RefreshRequest + 21, // 11: centrifugal.centrifuge.protocol.Command.sub_refresh:type_name -> centrifugal.centrifuge.protocol.SubRefreshRequest + 0, // 12: centrifugal.centrifuge.protocol.Reply.error:type_name -> centrifugal.centrifuge.protocol.Error + 4, // 13: centrifugal.centrifuge.protocol.Reply.push:type_name -> centrifugal.centrifuge.protocol.Push + 16, // 14: centrifugal.centrifuge.protocol.Reply.connect:type_name -> centrifugal.centrifuge.protocol.ConnectResult + 20, // 15: centrifugal.centrifuge.protocol.Reply.subscribe:type_name -> centrifugal.centrifuge.protocol.SubscribeResult + 24, // 16: centrifugal.centrifuge.protocol.Reply.unsubscribe:type_name -> centrifugal.centrifuge.protocol.UnsubscribeResult + 26, // 17: centrifugal.centrifuge.protocol.Reply.publish:type_name -> centrifugal.centrifuge.protocol.PublishResult + 28, // 18: centrifugal.centrifuge.protocol.Reply.presence:type_name -> centrifugal.centrifuge.protocol.PresenceResult + 30, // 19: centrifugal.centrifuge.protocol.Reply.presence_stats:type_name -> centrifugal.centrifuge.protocol.PresenceStatsResult + 33, // 20: centrifugal.centrifuge.protocol.Reply.history:type_name -> centrifugal.centrifuge.protocol.HistoryResult + 35, // 21: centrifugal.centrifuge.protocol.Reply.ping:type_name -> centrifugal.centrifuge.protocol.PingResult + 37, // 22: centrifugal.centrifuge.protocol.Reply.rpc:type_name -> centrifugal.centrifuge.protocol.RPCResult + 18, // 23: centrifugal.centrifuge.protocol.Reply.refresh:type_name -> centrifugal.centrifuge.protocol.RefreshResult + 22, // 24: centrifugal.centrifuge.protocol.Reply.sub_refresh:type_name -> centrifugal.centrifuge.protocol.SubRefreshResult + 6, // 25: centrifugal.centrifuge.protocol.Push.pub:type_name -> centrifugal.centrifuge.protocol.Publication + 7, // 26: centrifugal.centrifuge.protocol.Push.join:type_name -> centrifugal.centrifuge.protocol.Join + 8, // 27: centrifugal.centrifuge.protocol.Push.leave:type_name -> centrifugal.centrifuge.protocol.Leave + 9, // 28: centrifugal.centrifuge.protocol.Push.unsubscribe:type_name -> centrifugal.centrifuge.protocol.Unsubscribe + 11, // 29: centrifugal.centrifuge.protocol.Push.message:type_name -> centrifugal.centrifuge.protocol.Message + 10, // 30: centrifugal.centrifuge.protocol.Push.subscribe:type_name -> centrifugal.centrifuge.protocol.Subscribe + 12, // 31: centrifugal.centrifuge.protocol.Push.connect:type_name -> centrifugal.centrifuge.protocol.Connect + 13, // 32: centrifugal.centrifuge.protocol.Push.disconnect:type_name -> centrifugal.centrifuge.protocol.Disconnect + 14, // 33: centrifugal.centrifuge.protocol.Push.refresh:type_name -> centrifugal.centrifuge.protocol.Refresh + 5, // 34: centrifugal.centrifuge.protocol.Publication.info:type_name -> centrifugal.centrifuge.protocol.ClientInfo + 39, // 35: centrifugal.centrifuge.protocol.Publication.tags:type_name -> centrifugal.centrifuge.protocol.Publication.TagsEntry + 5, // 36: centrifugal.centrifuge.protocol.Join.info:type_name -> centrifugal.centrifuge.protocol.ClientInfo + 5, // 37: centrifugal.centrifuge.protocol.Leave.info:type_name -> centrifugal.centrifuge.protocol.ClientInfo + 40, // 38: centrifugal.centrifuge.protocol.Connect.subs:type_name -> centrifugal.centrifuge.protocol.Connect.SubsEntry + 41, // 39: centrifugal.centrifuge.protocol.ConnectRequest.subs:type_name -> centrifugal.centrifuge.protocol.ConnectRequest.SubsEntry + 42, // 40: centrifugal.centrifuge.protocol.ConnectRequest.headers:type_name -> centrifugal.centrifuge.protocol.ConnectRequest.HeadersEntry + 43, // 41: centrifugal.centrifuge.protocol.ConnectResult.subs:type_name -> centrifugal.centrifuge.protocol.ConnectResult.SubsEntry + 6, // 42: centrifugal.centrifuge.protocol.SubscribeResult.publications:type_name -> centrifugal.centrifuge.protocol.Publication + 44, // 43: centrifugal.centrifuge.protocol.PresenceResult.presence:type_name -> centrifugal.centrifuge.protocol.PresenceResult.PresenceEntry + 31, // 44: centrifugal.centrifuge.protocol.HistoryRequest.since:type_name -> centrifugal.centrifuge.protocol.StreamPosition + 6, // 45: centrifugal.centrifuge.protocol.HistoryResult.publications:type_name -> centrifugal.centrifuge.protocol.Publication + 20, // 46: centrifugal.centrifuge.protocol.Connect.SubsEntry.value:type_name -> centrifugal.centrifuge.protocol.SubscribeResult + 19, // 47: centrifugal.centrifuge.protocol.ConnectRequest.SubsEntry.value:type_name -> centrifugal.centrifuge.protocol.SubscribeRequest + 20, // 48: centrifugal.centrifuge.protocol.ConnectResult.SubsEntry.value:type_name -> centrifugal.centrifuge.protocol.SubscribeResult + 5, // 49: centrifugal.centrifuge.protocol.PresenceResult.PresenceEntry.value:type_name -> centrifugal.centrifuge.protocol.ClientInfo + 50, // [50:50] is the sub-list for method output_type + 50, // [50:50] is the sub-list for method input_type + 50, // [50:50] is the sub-list for extension type_name + 50, // [50:50] is the sub-list for extension extendee + 0, // [0:50] is the sub-list for field type_name +} + +func init() { file_client_proto_init() } +func file_client_proto_init() { + if File_client_proto != nil { + return + } + if !protoimpl.UnsafeEnabled { + file_client_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Error); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*EmulationRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Command); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Reply); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Push); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ClientInfo); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Publication); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Join); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Leave); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Unsubscribe); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Subscribe); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Message); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Connect); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Disconnect); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Refresh); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConnectRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ConnectResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RefreshRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RefreshResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubscribeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubscribeResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[21].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubRefreshRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SubRefreshResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnsubscribeRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[24].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*UnsubscribeResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[25].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PublishRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[26].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PublishResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[27].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PresenceRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[28].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PresenceResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PresenceStatsRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PresenceStatsResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*StreamPosition); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[32].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HistoryRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[33].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*HistoryResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[34].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PingRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[35].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*PingResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[36].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RPCRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[37].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*RPCResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_client_proto_msgTypes[38].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*SendRequest); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + } + type x struct{} + out := protoimpl.TypeBuilder{ + File: protoimpl.DescBuilder{ + GoPackagePath: reflect.TypeOf(x{}).PkgPath(), + RawDescriptor: file_client_proto_rawDesc, + NumEnums: 0, + NumMessages: 45, + NumExtensions: 0, + NumServices: 0, + }, + GoTypes: file_client_proto_goTypes, + DependencyIndexes: file_client_proto_depIdxs, + MessageInfos: file_client_proto_msgTypes, + }.Build() + File_client_proto = out.File + file_client_proto_rawDesc = nil + file_client_proto_goTypes = nil + file_client_proto_depIdxs = nil +} diff --git a/vendor/github.com/centrifugal/protocol/client.pb_easyjson.go b/vendor/github.com/centrifugal/protocol/client.pb_easyjson.go new file mode 100644 index 0000000000..f4df945408 --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/client.pb_easyjson.go @@ -0,0 +1,4034 @@ +// Code generated by easyjson for marshaling/unmarshaling. DO NOT EDIT. + +package protocol + +import ( + json "encoding/json" + + easyjson "github.com/mailru/easyjson" + jlexer "github.com/mailru/easyjson/jlexer" +) + +// suppress unused package warning +var ( + _ *json.RawMessage + _ *jlexer.Lexer + _ *writer + _ easyjson.Marshaler +) + +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild(in *jlexer.Lexer, out *UnsubscribeResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild(out *writer, in UnsubscribeResult) { + out.RawByte('{') + first := true + _ = first + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v UnsubscribeResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *UnsubscribeResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild1(in *jlexer.Lexer, out *UnsubscribeRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "channel": + out.Channel = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild1(out *writer, in UnsubscribeRequest) { + out.RawByte('{') + first := true + _ = first + if in.Channel != "" { + const prefix string = ",\"channel\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Channel)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v UnsubscribeRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild1(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *UnsubscribeRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild1(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild2(in *jlexer.Lexer, out *Unsubscribe) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "code": + out.Code = uint32(in.Uint32()) + case "reason": + out.Reason = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild2(out *writer, in Unsubscribe) { + out.RawByte('{') + first := true + _ = first + if in.Code != 0 { + const prefix string = ",\"code\":" + first = false + out.RawString(prefix[1:]) + out.Uint32(uint32(in.Code)) + } + if in.Reason != "" { + const prefix string = ",\"reason\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Reason)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Unsubscribe) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild2(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Unsubscribe) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild2(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild3(in *jlexer.Lexer, out *SubscribeResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "expires": + out.Expires = bool(in.Bool()) + case "ttl": + out.Ttl = uint32(in.Uint32()) + case "recoverable": + out.Recoverable = bool(in.Bool()) + case "epoch": + out.Epoch = string(in.String()) + case "publications": + if in.IsNull() { + in.Skip() + out.Publications = nil + } else { + in.Delim('[') + if out.Publications == nil { + if !in.IsDelim(']') { + out.Publications = make([]*Publication, 0, 8) + } else { + out.Publications = []*Publication{} + } + } else { + out.Publications = (out.Publications)[:0] + } + for !in.IsDelim(']') { + var v1 *Publication + if in.IsNull() { + in.Skip() + v1 = nil + } else { + if v1 == nil { + v1 = new(Publication) + } + (*v1).UnmarshalEasyJSON(in) + } + out.Publications = append(out.Publications, v1) + in.WantComma() + } + in.Delim(']') + } + case "recovered": + out.Recovered = bool(in.Bool()) + case "offset": + out.Offset = uint64(in.Uint64()) + case "positioned": + out.Positioned = bool(in.Bool()) + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + case "was_recovering": + out.WasRecovering = bool(in.Bool()) + case "delta": + out.Delta = bool(in.Bool()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild3(out *writer, in SubscribeResult) { + out.RawByte('{') + first := true + _ = first + if in.Expires { + const prefix string = ",\"expires\":" + first = false + out.RawString(prefix[1:]) + out.Bool(bool(in.Expires)) + } + if in.Ttl != 0 { + const prefix string = ",\"ttl\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint32(uint32(in.Ttl)) + } + if in.Recoverable { + const prefix string = ",\"recoverable\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Recoverable)) + } + if in.Epoch != "" { + const prefix string = ",\"epoch\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Epoch)) + } + if len(in.Publications) != 0 { + const prefix string = ",\"publications\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + { + out.RawByte('[') + for v2, v3 := range in.Publications { + if v2 > 0 { + out.RawByte(',') + } + if v3 == nil { + out.RawString("null") + } else { + (*v3).MarshalEasyJSON(out) + } + } + out.RawByte(']') + } + } + if in.Recovered { + const prefix string = ",\"recovered\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Recovered)) + } + if in.Offset != 0 { + const prefix string = ",\"offset\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint64(uint64(in.Offset)) + } + if in.Positioned { + const prefix string = ",\"positioned\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Positioned)) + } + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.Data).MarshalJSON()) + } + if in.WasRecovering { + const prefix string = ",\"was_recovering\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.WasRecovering)) + } + if in.Delta { + const prefix string = ",\"delta\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Delta)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v SubscribeResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild3(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *SubscribeResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild3(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild4(in *jlexer.Lexer, out *SubscribeRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "channel": + out.Channel = string(in.String()) + case "token": + out.Token = string(in.String()) + case "recover": + out.Recover = bool(in.Bool()) + case "epoch": + out.Epoch = string(in.String()) + case "offset": + out.Offset = uint64(in.Uint64()) + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + case "positioned": + out.Positioned = bool(in.Bool()) + case "recoverable": + out.Recoverable = bool(in.Bool()) + case "join_leave": + out.JoinLeave = bool(in.Bool()) + case "delta": + out.Delta = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild4(out *writer, in SubscribeRequest) { + out.RawByte('{') + first := true + _ = first + if in.Channel != "" { + const prefix string = ",\"channel\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Channel)) + } + if in.Token != "" { + const prefix string = ",\"token\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Token)) + } + if in.Recover { + const prefix string = ",\"recover\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Recover)) + } + if in.Epoch != "" { + const prefix string = ",\"epoch\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Epoch)) + } + if in.Offset != 0 { + const prefix string = ",\"offset\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint64(uint64(in.Offset)) + } + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.Data).MarshalJSON()) + } + if in.Positioned { + const prefix string = ",\"positioned\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Positioned)) + } + if in.Recoverable { + const prefix string = ",\"recoverable\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Recoverable)) + } + if in.JoinLeave { + const prefix string = ",\"join_leave\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.JoinLeave)) + } + if in.Delta != "" { + const prefix string = ",\"delta\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Delta)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v SubscribeRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild4(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *SubscribeRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild4(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild5(in *jlexer.Lexer, out *Subscribe) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "recoverable": + out.Recoverable = bool(in.Bool()) + case "epoch": + out.Epoch = string(in.String()) + case "offset": + out.Offset = uint64(in.Uint64()) + case "positioned": + out.Positioned = bool(in.Bool()) + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild5(out *writer, in Subscribe) { + out.RawByte('{') + first := true + _ = first + if in.Recoverable { + const prefix string = ",\"recoverable\":" + first = false + out.RawString(prefix[1:]) + out.Bool(bool(in.Recoverable)) + } + if in.Epoch != "" { + const prefix string = ",\"epoch\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Epoch)) + } + if in.Offset != 0 { + const prefix string = ",\"offset\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint64(uint64(in.Offset)) + } + if in.Positioned { + const prefix string = ",\"positioned\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Positioned)) + } + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.Data).MarshalJSON()) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Subscribe) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild5(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Subscribe) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild5(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild6(in *jlexer.Lexer, out *SubRefreshResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "expires": + out.Expires = bool(in.Bool()) + case "ttl": + out.Ttl = uint32(in.Uint32()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild6(out *writer, in SubRefreshResult) { + out.RawByte('{') + first := true + _ = first + if in.Expires { + const prefix string = ",\"expires\":" + first = false + out.RawString(prefix[1:]) + out.Bool(bool(in.Expires)) + } + if in.Ttl != 0 { + const prefix string = ",\"ttl\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint32(uint32(in.Ttl)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v SubRefreshResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild6(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *SubRefreshResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild6(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild7(in *jlexer.Lexer, out *SubRefreshRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "channel": + out.Channel = string(in.String()) + case "token": + out.Token = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild7(out *writer, in SubRefreshRequest) { + out.RawByte('{') + first := true + _ = first + if in.Channel != "" { + const prefix string = ",\"channel\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Channel)) + } + if in.Token != "" { + const prefix string = ",\"token\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Token)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v SubRefreshRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild7(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *SubRefreshRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild7(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild8(in *jlexer.Lexer, out *StreamPosition) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "offset": + out.Offset = uint64(in.Uint64()) + case "epoch": + out.Epoch = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild8(out *writer, in StreamPosition) { + out.RawByte('{') + first := true + _ = first + if in.Offset != 0 { + const prefix string = ",\"offset\":" + first = false + out.RawString(prefix[1:]) + out.Uint64(uint64(in.Offset)) + } + if in.Epoch != "" { + const prefix string = ",\"epoch\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Epoch)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v StreamPosition) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild8(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *StreamPosition) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild8(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild9(in *jlexer.Lexer, out *SendRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild9(out *writer, in SendRequest) { + out.RawByte('{') + first := true + _ = first + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + first = false + out.RawString(prefix[1:]) + out.Raw((in.Data).MarshalJSON()) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v SendRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild9(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *SendRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild9(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild10(in *jlexer.Lexer, out *Reply) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "id": + out.Id = uint32(in.Uint32()) + case "error": + if in.IsNull() { + in.Skip() + out.Error = nil + } else { + if out.Error == nil { + out.Error = new(Error) + } + (*out.Error).UnmarshalEasyJSON(in) + } + case "push": + if in.IsNull() { + in.Skip() + out.Push = nil + } else { + if out.Push == nil { + out.Push = new(Push) + } + (*out.Push).UnmarshalEasyJSON(in) + } + case "connect": + if in.IsNull() { + in.Skip() + out.Connect = nil + } else { + if out.Connect == nil { + out.Connect = new(ConnectResult) + } + (*out.Connect).UnmarshalEasyJSON(in) + } + case "subscribe": + if in.IsNull() { + in.Skip() + out.Subscribe = nil + } else { + if out.Subscribe == nil { + out.Subscribe = new(SubscribeResult) + } + (*out.Subscribe).UnmarshalEasyJSON(in) + } + case "unsubscribe": + if in.IsNull() { + in.Skip() + out.Unsubscribe = nil + } else { + if out.Unsubscribe == nil { + out.Unsubscribe = new(UnsubscribeResult) + } + (*out.Unsubscribe).UnmarshalEasyJSON(in) + } + case "publish": + if in.IsNull() { + in.Skip() + out.Publish = nil + } else { + if out.Publish == nil { + out.Publish = new(PublishResult) + } + (*out.Publish).UnmarshalEasyJSON(in) + } + case "presence": + if in.IsNull() { + in.Skip() + out.Presence = nil + } else { + if out.Presence == nil { + out.Presence = new(PresenceResult) + } + (*out.Presence).UnmarshalEasyJSON(in) + } + case "presence_stats": + if in.IsNull() { + in.Skip() + out.PresenceStats = nil + } else { + if out.PresenceStats == nil { + out.PresenceStats = new(PresenceStatsResult) + } + (*out.PresenceStats).UnmarshalEasyJSON(in) + } + case "history": + if in.IsNull() { + in.Skip() + out.History = nil + } else { + if out.History == nil { + out.History = new(HistoryResult) + } + (*out.History).UnmarshalEasyJSON(in) + } + case "ping": + if in.IsNull() { + in.Skip() + out.Ping = nil + } else { + if out.Ping == nil { + out.Ping = new(PingResult) + } + (*out.Ping).UnmarshalEasyJSON(in) + } + case "rpc": + if in.IsNull() { + in.Skip() + out.Rpc = nil + } else { + if out.Rpc == nil { + out.Rpc = new(RPCResult) + } + (*out.Rpc).UnmarshalEasyJSON(in) + } + case "refresh": + if in.IsNull() { + in.Skip() + out.Refresh = nil + } else { + if out.Refresh == nil { + out.Refresh = new(RefreshResult) + } + (*out.Refresh).UnmarshalEasyJSON(in) + } + case "sub_refresh": + if in.IsNull() { + in.Skip() + out.SubRefresh = nil + } else { + if out.SubRefresh == nil { + out.SubRefresh = new(SubRefreshResult) + } + (*out.SubRefresh).UnmarshalEasyJSON(in) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild10(out *writer, in Reply) { + out.RawByte('{') + first := true + _ = first + if in.Id != 0 { + const prefix string = ",\"id\":" + first = false + out.RawString(prefix[1:]) + out.Uint32(uint32(in.Id)) + } + if in.Error != nil { + const prefix string = ",\"error\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Error).MarshalEasyJSON(out) + } + if in.Push != nil { + const prefix string = ",\"push\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Push).MarshalEasyJSON(out) + } + if in.Connect != nil { + const prefix string = ",\"connect\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Connect).MarshalEasyJSON(out) + } + if in.Subscribe != nil { + const prefix string = ",\"subscribe\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Subscribe).MarshalEasyJSON(out) + } + if in.Unsubscribe != nil { + const prefix string = ",\"unsubscribe\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Unsubscribe).MarshalEasyJSON(out) + } + if in.Publish != nil { + const prefix string = ",\"publish\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Publish).MarshalEasyJSON(out) + } + if in.Presence != nil { + const prefix string = ",\"presence\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Presence).MarshalEasyJSON(out) + } + if in.PresenceStats != nil { + const prefix string = ",\"presence_stats\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.PresenceStats).MarshalEasyJSON(out) + } + if in.History != nil { + const prefix string = ",\"history\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.History).MarshalEasyJSON(out) + } + if in.Ping != nil { + const prefix string = ",\"ping\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Ping).MarshalEasyJSON(out) + } + if in.Rpc != nil { + const prefix string = ",\"rpc\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Rpc).MarshalEasyJSON(out) + } + if in.Refresh != nil { + const prefix string = ",\"refresh\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Refresh).MarshalEasyJSON(out) + } + if in.SubRefresh != nil { + const prefix string = ",\"sub_refresh\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.SubRefresh).MarshalEasyJSON(out) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Reply) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild10(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Reply) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild10(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild11(in *jlexer.Lexer, out *RefreshResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "client": + out.Client = string(in.String()) + case "version": + out.Version = string(in.String()) + case "expires": + out.Expires = bool(in.Bool()) + case "ttl": + out.Ttl = uint32(in.Uint32()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild11(out *writer, in RefreshResult) { + out.RawByte('{') + first := true + _ = first + if in.Client != "" { + const prefix string = ",\"client\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Client)) + } + if in.Version != "" { + const prefix string = ",\"version\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Version)) + } + if in.Expires { + const prefix string = ",\"expires\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Expires)) + } + if in.Ttl != 0 { + const prefix string = ",\"ttl\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint32(uint32(in.Ttl)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v RefreshResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild11(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *RefreshResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild11(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild12(in *jlexer.Lexer, out *RefreshRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "token": + out.Token = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild12(out *writer, in RefreshRequest) { + out.RawByte('{') + first := true + _ = first + if in.Token != "" { + const prefix string = ",\"token\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Token)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v RefreshRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild12(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *RefreshRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild12(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild13(in *jlexer.Lexer, out *Refresh) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "expires": + out.Expires = bool(in.Bool()) + case "ttl": + out.Ttl = uint32(in.Uint32()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild13(out *writer, in Refresh) { + out.RawByte('{') + first := true + _ = first + if in.Expires { + const prefix string = ",\"expires\":" + first = false + out.RawString(prefix[1:]) + out.Bool(bool(in.Expires)) + } + if in.Ttl != 0 { + const prefix string = ",\"ttl\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint32(uint32(in.Ttl)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Refresh) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild13(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Refresh) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild13(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild14(in *jlexer.Lexer, out *RPCResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild14(out *writer, in RPCResult) { + out.RawByte('{') + first := true + _ = first + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + first = false + out.RawString(prefix[1:]) + out.Raw((in.Data).MarshalJSON()) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v RPCResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild14(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *RPCResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild14(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild15(in *jlexer.Lexer, out *RPCRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + case "method": + out.Method = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild15(out *writer, in RPCRequest) { + out.RawByte('{') + first := true + _ = first + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + first = false + out.RawString(prefix[1:]) + out.Raw((in.Data).MarshalJSON()) + } + if in.Method != "" { + const prefix string = ",\"method\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Method)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v RPCRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild15(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *RPCRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild15(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild16(in *jlexer.Lexer, out *Push) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "channel": + out.Channel = string(in.String()) + case "pub": + if in.IsNull() { + in.Skip() + out.Pub = nil + } else { + if out.Pub == nil { + out.Pub = new(Publication) + } + (*out.Pub).UnmarshalEasyJSON(in) + } + case "join": + if in.IsNull() { + in.Skip() + out.Join = nil + } else { + if out.Join == nil { + out.Join = new(Join) + } + (*out.Join).UnmarshalEasyJSON(in) + } + case "leave": + if in.IsNull() { + in.Skip() + out.Leave = nil + } else { + if out.Leave == nil { + out.Leave = new(Leave) + } + (*out.Leave).UnmarshalEasyJSON(in) + } + case "unsubscribe": + if in.IsNull() { + in.Skip() + out.Unsubscribe = nil + } else { + if out.Unsubscribe == nil { + out.Unsubscribe = new(Unsubscribe) + } + (*out.Unsubscribe).UnmarshalEasyJSON(in) + } + case "message": + if in.IsNull() { + in.Skip() + out.Message = nil + } else { + if out.Message == nil { + out.Message = new(Message) + } + (*out.Message).UnmarshalEasyJSON(in) + } + case "subscribe": + if in.IsNull() { + in.Skip() + out.Subscribe = nil + } else { + if out.Subscribe == nil { + out.Subscribe = new(Subscribe) + } + (*out.Subscribe).UnmarshalEasyJSON(in) + } + case "connect": + if in.IsNull() { + in.Skip() + out.Connect = nil + } else { + if out.Connect == nil { + out.Connect = new(Connect) + } + (*out.Connect).UnmarshalEasyJSON(in) + } + case "disconnect": + if in.IsNull() { + in.Skip() + out.Disconnect = nil + } else { + if out.Disconnect == nil { + out.Disconnect = new(Disconnect) + } + (*out.Disconnect).UnmarshalEasyJSON(in) + } + case "refresh": + if in.IsNull() { + in.Skip() + out.Refresh = nil + } else { + if out.Refresh == nil { + out.Refresh = new(Refresh) + } + (*out.Refresh).UnmarshalEasyJSON(in) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild16(out *writer, in Push) { + out.RawByte('{') + first := true + _ = first + if in.Channel != "" { + const prefix string = ",\"channel\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Channel)) + } + if in.Pub != nil { + const prefix string = ",\"pub\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Pub).MarshalEasyJSON(out) + } + if in.Join != nil { + const prefix string = ",\"join\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Join).MarshalEasyJSON(out) + } + if in.Leave != nil { + const prefix string = ",\"leave\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Leave).MarshalEasyJSON(out) + } + if in.Unsubscribe != nil { + const prefix string = ",\"unsubscribe\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Unsubscribe).MarshalEasyJSON(out) + } + if in.Message != nil { + const prefix string = ",\"message\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Message).MarshalEasyJSON(out) + } + if in.Subscribe != nil { + const prefix string = ",\"subscribe\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Subscribe).MarshalEasyJSON(out) + } + if in.Connect != nil { + const prefix string = ",\"connect\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Connect).MarshalEasyJSON(out) + } + if in.Disconnect != nil { + const prefix string = ",\"disconnect\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Disconnect).MarshalEasyJSON(out) + } + if in.Refresh != nil { + const prefix string = ",\"refresh\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Refresh).MarshalEasyJSON(out) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Push) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild16(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Push) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild16(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild17(in *jlexer.Lexer, out *PublishResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild17(out *writer, in PublishResult) { + out.RawByte('{') + first := true + _ = first + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v PublishResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild17(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *PublishResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild17(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild18(in *jlexer.Lexer, out *PublishRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "channel": + out.Channel = string(in.String()) + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild18(out *writer, in PublishRequest) { + out.RawByte('{') + first := true + _ = first + if in.Channel != "" { + const prefix string = ",\"channel\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Channel)) + } + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.Data).MarshalJSON()) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v PublishRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild18(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *PublishRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild18(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild19(in *jlexer.Lexer, out *Publication) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + case "info": + if in.IsNull() { + in.Skip() + out.Info = nil + } else { + if out.Info == nil { + out.Info = new(ClientInfo) + } + (*out.Info).UnmarshalEasyJSON(in) + } + case "offset": + out.Offset = uint64(in.Uint64()) + case "tags": + if in.IsNull() { + in.Skip() + } else { + in.Delim('{') + if !in.IsDelim('}') { + out.Tags = make(map[string]string) + } else { + out.Tags = nil + } + for !in.IsDelim('}') { + key := string(in.String()) + in.WantColon() + var v4 string + v4 = string(in.String()) + (out.Tags)[key] = v4 + in.WantComma() + } + in.Delim('}') + } + case "delta": + out.Delta = bool(in.Bool()) + case "time": + out.Time = int64(in.Int64()) + case "channel": + out.Channel = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild19(out *writer, in Publication) { + out.RawByte('{') + first := true + _ = first + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + first = false + out.RawString(prefix[1:]) + out.Raw((in.Data).MarshalJSON()) + } + if in.Info != nil { + const prefix string = ",\"info\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Info).MarshalEasyJSON(out) + } + if in.Offset != 0 { + const prefix string = ",\"offset\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint64(uint64(in.Offset)) + } + if len(in.Tags) != 0 { + const prefix string = ",\"tags\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + { + out.RawByte('{') + v5First := true + for v5Name, v5Value := range in.Tags { + if v5First { + v5First = false + } else { + out.RawByte(',') + } + out.String(string(v5Name)) + out.RawByte(':') + out.String(string(v5Value)) + } + out.RawByte('}') + } + } + if in.Delta { + const prefix string = ",\"delta\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Delta)) + } + if in.Time != 0 { + const prefix string = ",\"time\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int64(int64(in.Time)) + } + if in.Channel != "" { + const prefix string = ",\"channel\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Channel)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Publication) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild19(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Publication) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild19(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild20(in *jlexer.Lexer, out *PresenceStatsResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "num_clients": + out.NumClients = uint32(in.Uint32()) + case "num_users": + out.NumUsers = uint32(in.Uint32()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild20(out *writer, in PresenceStatsResult) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"num_clients\":" + out.RawString(prefix[1:]) + out.Uint32(uint32(in.NumClients)) + } + { + const prefix string = ",\"num_users\":" + out.RawString(prefix) + out.Uint32(uint32(in.NumUsers)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v PresenceStatsResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild20(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *PresenceStatsResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild20(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild21(in *jlexer.Lexer, out *PresenceStatsRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "channel": + out.Channel = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild21(out *writer, in PresenceStatsRequest) { + out.RawByte('{') + first := true + _ = first + if in.Channel != "" { + const prefix string = ",\"channel\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Channel)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v PresenceStatsRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild21(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *PresenceStatsRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild21(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild22(in *jlexer.Lexer, out *PresenceResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "presence": + if in.IsNull() { + in.Skip() + } else { + in.Delim('{') + out.Presence = make(map[string]*ClientInfo) + for !in.IsDelim('}') { + key := string(in.String()) + in.WantColon() + var v6 *ClientInfo + if in.IsNull() { + in.Skip() + v6 = nil + } else { + if v6 == nil { + v6 = new(ClientInfo) + } + (*v6).UnmarshalEasyJSON(in) + } + (out.Presence)[key] = v6 + in.WantComma() + } + in.Delim('}') + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild22(out *writer, in PresenceResult) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"presence\":" + out.RawString(prefix[1:]) + if in.Presence == nil && (out.Flags&nilMapAsEmpty) == 0 { + out.RawString(`null`) + } else { + out.RawByte('{') + v7First := true + for v7Name, v7Value := range in.Presence { + if v7First { + v7First = false + } else { + out.RawByte(',') + } + out.String(string(v7Name)) + out.RawByte(':') + if v7Value == nil { + out.RawString("null") + } else { + (*v7Value).MarshalEasyJSON(out) + } + } + out.RawByte('}') + } + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v PresenceResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild22(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *PresenceResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild22(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild23(in *jlexer.Lexer, out *PresenceRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "channel": + out.Channel = string(in.String()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild23(out *writer, in PresenceRequest) { + out.RawByte('{') + first := true + _ = first + if in.Channel != "" { + const prefix string = ",\"channel\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Channel)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v PresenceRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild23(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *PresenceRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild23(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild24(in *jlexer.Lexer, out *PingResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild24(out *writer, in PingResult) { + out.RawByte('{') + first := true + _ = first + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v PingResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild24(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *PingResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild24(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild25(in *jlexer.Lexer, out *PingRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild25(out *writer, in PingRequest) { + out.RawByte('{') + first := true + _ = first + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v PingRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild25(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *PingRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild25(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild26(in *jlexer.Lexer, out *Message) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild26(out *writer, in Message) { + out.RawByte('{') + first := true + _ = first + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + first = false + out.RawString(prefix[1:]) + out.Raw((in.Data).MarshalJSON()) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Message) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild26(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Message) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild26(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild27(in *jlexer.Lexer, out *Leave) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "info": + if in.IsNull() { + in.Skip() + out.Info = nil + } else { + if out.Info == nil { + out.Info = new(ClientInfo) + } + (*out.Info).UnmarshalEasyJSON(in) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild27(out *writer, in Leave) { + out.RawByte('{') + first := true + _ = first + if in.Info != nil { + const prefix string = ",\"info\":" + first = false + out.RawString(prefix[1:]) + (*in.Info).MarshalEasyJSON(out) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Leave) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild27(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Leave) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild27(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild28(in *jlexer.Lexer, out *Join) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "info": + if in.IsNull() { + in.Skip() + out.Info = nil + } else { + if out.Info == nil { + out.Info = new(ClientInfo) + } + (*out.Info).UnmarshalEasyJSON(in) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild28(out *writer, in Join) { + out.RawByte('{') + first := true + _ = first + if in.Info != nil { + const prefix string = ",\"info\":" + first = false + out.RawString(prefix[1:]) + (*in.Info).MarshalEasyJSON(out) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Join) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild28(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Join) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild28(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild29(in *jlexer.Lexer, out *HistoryResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "publications": + if in.IsNull() { + in.Skip() + out.Publications = nil + } else { + in.Delim('[') + if out.Publications == nil { + if !in.IsDelim(']') { + out.Publications = make([]*Publication, 0, 8) + } else { + out.Publications = []*Publication{} + } + } else { + out.Publications = (out.Publications)[:0] + } + for !in.IsDelim(']') { + var v8 *Publication + if in.IsNull() { + in.Skip() + v8 = nil + } else { + if v8 == nil { + v8 = new(Publication) + } + (*v8).UnmarshalEasyJSON(in) + } + out.Publications = append(out.Publications, v8) + in.WantComma() + } + in.Delim(']') + } + case "epoch": + out.Epoch = string(in.String()) + case "offset": + out.Offset = uint64(in.Uint64()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild29(out *writer, in HistoryResult) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"publications\":" + out.RawString(prefix[1:]) + if in.Publications == nil && (out.Flags&nilSliceAsEmpty) == 0 { + out.RawString("null") + } else { + out.RawByte('[') + for v9, v10 := range in.Publications { + if v9 > 0 { + out.RawByte(',') + } + if v10 == nil { + out.RawString("null") + } else { + (*v10).MarshalEasyJSON(out) + } + } + out.RawByte(']') + } + } + { + const prefix string = ",\"epoch\":" + out.RawString(prefix) + out.String(string(in.Epoch)) + } + { + const prefix string = ",\"offset\":" + out.RawString(prefix) + out.Uint64(uint64(in.Offset)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v HistoryResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild29(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *HistoryResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild29(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild30(in *jlexer.Lexer, out *HistoryRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "channel": + out.Channel = string(in.String()) + case "limit": + out.Limit = int32(in.Int32()) + case "since": + if in.IsNull() { + in.Skip() + out.Since = nil + } else { + if out.Since == nil { + out.Since = new(StreamPosition) + } + (*out.Since).UnmarshalEasyJSON(in) + } + case "reverse": + out.Reverse = bool(in.Bool()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild30(out *writer, in HistoryRequest) { + out.RawByte('{') + first := true + _ = first + if in.Channel != "" { + const prefix string = ",\"channel\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Channel)) + } + if in.Limit != 0 { + const prefix string = ",\"limit\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int32(int32(in.Limit)) + } + if in.Since != nil { + const prefix string = ",\"since\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Since).MarshalEasyJSON(out) + } + if in.Reverse { + const prefix string = ",\"reverse\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Reverse)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v HistoryRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild30(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *HistoryRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild30(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild31(in *jlexer.Lexer, out *Error) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "code": + out.Code = uint32(in.Uint32()) + case "message": + out.Message = string(in.String()) + case "temporary": + out.Temporary = bool(in.Bool()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild31(out *writer, in Error) { + out.RawByte('{') + first := true + _ = first + if in.Code != 0 { + const prefix string = ",\"code\":" + first = false + out.RawString(prefix[1:]) + out.Uint32(uint32(in.Code)) + } + if in.Message != "" { + const prefix string = ",\"message\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Message)) + } + if in.Temporary { + const prefix string = ",\"temporary\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Temporary)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Error) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild31(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Error) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild31(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild32(in *jlexer.Lexer, out *EmulationRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "node": + out.Node = string(in.String()) + case "session": + out.Session = string(in.String()) + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild32(out *writer, in EmulationRequest) { + out.RawByte('{') + first := true + _ = first + if in.Node != "" { + const prefix string = ",\"node\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Node)) + } + if in.Session != "" { + const prefix string = ",\"session\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Session)) + } + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.Data).MarshalJSON()) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v EmulationRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild32(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *EmulationRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild32(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild33(in *jlexer.Lexer, out *Disconnect) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "code": + out.Code = uint32(in.Uint32()) + case "reason": + out.Reason = string(in.String()) + case "reconnect": + out.Reconnect = bool(in.Bool()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild33(out *writer, in Disconnect) { + out.RawByte('{') + first := true + _ = first + if in.Code != 0 { + const prefix string = ",\"code\":" + first = false + out.RawString(prefix[1:]) + out.Uint32(uint32(in.Code)) + } + if in.Reason != "" { + const prefix string = ",\"reason\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Reason)) + } + if in.Reconnect { + const prefix string = ",\"reconnect\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Reconnect)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Disconnect) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild33(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Disconnect) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild33(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild34(in *jlexer.Lexer, out *ConnectResult) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "client": + out.Client = string(in.String()) + case "version": + out.Version = string(in.String()) + case "expires": + out.Expires = bool(in.Bool()) + case "ttl": + out.Ttl = uint32(in.Uint32()) + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + case "subs": + if in.IsNull() { + in.Skip() + } else { + in.Delim('{') + if !in.IsDelim('}') { + out.Subs = make(map[string]*SubscribeResult) + } else { + out.Subs = nil + } + for !in.IsDelim('}') { + key := string(in.String()) + in.WantColon() + var v11 *SubscribeResult + if in.IsNull() { + in.Skip() + v11 = nil + } else { + if v11 == nil { + v11 = new(SubscribeResult) + } + (*v11).UnmarshalEasyJSON(in) + } + (out.Subs)[key] = v11 + in.WantComma() + } + in.Delim('}') + } + case "ping": + out.Ping = uint32(in.Uint32()) + case "pong": + out.Pong = bool(in.Bool()) + case "session": + out.Session = string(in.String()) + case "node": + out.Node = string(in.String()) + case "time": + out.Time = int64(in.Int64()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild34(out *writer, in ConnectResult) { + out.RawByte('{') + first := true + _ = first + if in.Client != "" { + const prefix string = ",\"client\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Client)) + } + if in.Version != "" { + const prefix string = ",\"version\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Version)) + } + if in.Expires { + const prefix string = ",\"expires\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Expires)) + } + if in.Ttl != 0 { + const prefix string = ",\"ttl\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint32(uint32(in.Ttl)) + } + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.Data).MarshalJSON()) + } + if len(in.Subs) != 0 { + const prefix string = ",\"subs\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + { + out.RawByte('{') + v12First := true + for v12Name, v12Value := range in.Subs { + if v12First { + v12First = false + } else { + out.RawByte(',') + } + out.String(string(v12Name)) + out.RawByte(':') + if v12Value == nil { + out.RawString("null") + } else { + (*v12Value).MarshalEasyJSON(out) + } + } + out.RawByte('}') + } + } + if in.Ping != 0 { + const prefix string = ",\"ping\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint32(uint32(in.Ping)) + } + if in.Pong { + const prefix string = ",\"pong\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Pong)) + } + if in.Session != "" { + const prefix string = ",\"session\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Session)) + } + if in.Node != "" { + const prefix string = ",\"node\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Node)) + } + if in.Time != 0 { + const prefix string = ",\"time\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int64(int64(in.Time)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v ConnectResult) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild34(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *ConnectResult) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild34(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild35(in *jlexer.Lexer, out *ConnectRequest) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "token": + out.Token = string(in.String()) + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + case "subs": + if in.IsNull() { + in.Skip() + } else { + in.Delim('{') + if !in.IsDelim('}') { + out.Subs = make(map[string]*SubscribeRequest) + } else { + out.Subs = nil + } + for !in.IsDelim('}') { + key := string(in.String()) + in.WantColon() + var v13 *SubscribeRequest + if in.IsNull() { + in.Skip() + v13 = nil + } else { + if v13 == nil { + v13 = new(SubscribeRequest) + } + (*v13).UnmarshalEasyJSON(in) + } + (out.Subs)[key] = v13 + in.WantComma() + } + in.Delim('}') + } + case "name": + out.Name = string(in.String()) + case "version": + out.Version = string(in.String()) + case "headers": + if in.IsNull() { + in.Skip() + } else { + in.Delim('{') + if !in.IsDelim('}') { + out.Headers = make(map[string]string) + } else { + out.Headers = nil + } + for !in.IsDelim('}') { + key := string(in.String()) + in.WantColon() + var v14 string + v14 = string(in.String()) + (out.Headers)[key] = v14 + in.WantComma() + } + in.Delim('}') + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild35(out *writer, in ConnectRequest) { + out.RawByte('{') + first := true + _ = first + if in.Token != "" { + const prefix string = ",\"token\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Token)) + } + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.Data).MarshalJSON()) + } + if len(in.Subs) != 0 { + const prefix string = ",\"subs\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + { + out.RawByte('{') + v15First := true + for v15Name, v15Value := range in.Subs { + if v15First { + v15First = false + } else { + out.RawByte(',') + } + out.String(string(v15Name)) + out.RawByte(':') + if v15Value == nil { + out.RawString("null") + } else { + (*v15Value).MarshalEasyJSON(out) + } + } + out.RawByte('}') + } + } + if in.Name != "" { + const prefix string = ",\"name\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Name)) + } + if in.Version != "" { + const prefix string = ",\"version\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Version)) + } + if len(in.Headers) != 0 { + const prefix string = ",\"headers\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + { + out.RawByte('{') + v16First := true + for v16Name, v16Value := range in.Headers { + if v16First { + v16First = false + } else { + out.RawByte(',') + } + out.String(string(v16Name)) + out.RawByte(':') + out.String(string(v16Value)) + } + out.RawByte('}') + } + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v ConnectRequest) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild35(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *ConnectRequest) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild35(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild36(in *jlexer.Lexer, out *Connect) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "client": + out.Client = string(in.String()) + case "version": + out.Version = string(in.String()) + case "data": + if data := in.Raw(); in.Ok() { + in.AddError((out.Data).UnmarshalJSON(data)) + } + case "subs": + if in.IsNull() { + in.Skip() + } else { + in.Delim('{') + if !in.IsDelim('}') { + out.Subs = make(map[string]*SubscribeResult) + } else { + out.Subs = nil + } + for !in.IsDelim('}') { + key := string(in.String()) + in.WantColon() + var v17 *SubscribeResult + if in.IsNull() { + in.Skip() + v17 = nil + } else { + if v17 == nil { + v17 = new(SubscribeResult) + } + (*v17).UnmarshalEasyJSON(in) + } + (out.Subs)[key] = v17 + in.WantComma() + } + in.Delim('}') + } + case "expires": + out.Expires = bool(in.Bool()) + case "ttl": + out.Ttl = uint32(in.Uint32()) + case "ping": + out.Ping = uint32(in.Uint32()) + case "pong": + out.Pong = bool(in.Bool()) + case "session": + out.Session = string(in.String()) + case "node": + out.Node = string(in.String()) + case "time": + out.Time = int64(in.Int64()) + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild36(out *writer, in Connect) { + out.RawByte('{') + first := true + _ = first + if in.Client != "" { + const prefix string = ",\"client\":" + first = false + out.RawString(prefix[1:]) + out.String(string(in.Client)) + } + if in.Version != "" { + const prefix string = ",\"version\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Version)) + } + if len(in.Data) != 0 { + const prefix string = ",\"data\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Raw((in.Data).MarshalJSON()) + } + if len(in.Subs) != 0 { + const prefix string = ",\"subs\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + { + out.RawByte('{') + v18First := true + for v18Name, v18Value := range in.Subs { + if v18First { + v18First = false + } else { + out.RawByte(',') + } + out.String(string(v18Name)) + out.RawByte(':') + if v18Value == nil { + out.RawString("null") + } else { + (*v18Value).MarshalEasyJSON(out) + } + } + out.RawByte('}') + } + } + if in.Expires { + const prefix string = ",\"expires\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Expires)) + } + if in.Ttl != 0 { + const prefix string = ",\"ttl\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint32(uint32(in.Ttl)) + } + if in.Ping != 0 { + const prefix string = ",\"ping\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Uint32(uint32(in.Ping)) + } + if in.Pong { + const prefix string = ",\"pong\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Bool(bool(in.Pong)) + } + if in.Session != "" { + const prefix string = ",\"session\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Session)) + } + if in.Node != "" { + const prefix string = ",\"node\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.String(string(in.Node)) + } + if in.Time != 0 { + const prefix string = ",\"time\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + out.Int64(int64(in.Time)) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Connect) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild36(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Connect) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild36(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild37(in *jlexer.Lexer, out *Command) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "id": + out.Id = uint32(in.Uint32()) + case "connect": + if in.IsNull() { + in.Skip() + out.Connect = nil + } else { + if out.Connect == nil { + out.Connect = new(ConnectRequest) + } + (*out.Connect).UnmarshalEasyJSON(in) + } + case "subscribe": + if in.IsNull() { + in.Skip() + out.Subscribe = nil + } else { + if out.Subscribe == nil { + out.Subscribe = new(SubscribeRequest) + } + (*out.Subscribe).UnmarshalEasyJSON(in) + } + case "unsubscribe": + if in.IsNull() { + in.Skip() + out.Unsubscribe = nil + } else { + if out.Unsubscribe == nil { + out.Unsubscribe = new(UnsubscribeRequest) + } + (*out.Unsubscribe).UnmarshalEasyJSON(in) + } + case "publish": + if in.IsNull() { + in.Skip() + out.Publish = nil + } else { + if out.Publish == nil { + out.Publish = new(PublishRequest) + } + (*out.Publish).UnmarshalEasyJSON(in) + } + case "presence": + if in.IsNull() { + in.Skip() + out.Presence = nil + } else { + if out.Presence == nil { + out.Presence = new(PresenceRequest) + } + (*out.Presence).UnmarshalEasyJSON(in) + } + case "presence_stats": + if in.IsNull() { + in.Skip() + out.PresenceStats = nil + } else { + if out.PresenceStats == nil { + out.PresenceStats = new(PresenceStatsRequest) + } + (*out.PresenceStats).UnmarshalEasyJSON(in) + } + case "history": + if in.IsNull() { + in.Skip() + out.History = nil + } else { + if out.History == nil { + out.History = new(HistoryRequest) + } + (*out.History).UnmarshalEasyJSON(in) + } + case "ping": + if in.IsNull() { + in.Skip() + out.Ping = nil + } else { + if out.Ping == nil { + out.Ping = new(PingRequest) + } + (*out.Ping).UnmarshalEasyJSON(in) + } + case "send": + if in.IsNull() { + in.Skip() + out.Send = nil + } else { + if out.Send == nil { + out.Send = new(SendRequest) + } + (*out.Send).UnmarshalEasyJSON(in) + } + case "rpc": + if in.IsNull() { + in.Skip() + out.Rpc = nil + } else { + if out.Rpc == nil { + out.Rpc = new(RPCRequest) + } + (*out.Rpc).UnmarshalEasyJSON(in) + } + case "refresh": + if in.IsNull() { + in.Skip() + out.Refresh = nil + } else { + if out.Refresh == nil { + out.Refresh = new(RefreshRequest) + } + (*out.Refresh).UnmarshalEasyJSON(in) + } + case "sub_refresh": + if in.IsNull() { + in.Skip() + out.SubRefresh = nil + } else { + if out.SubRefresh == nil { + out.SubRefresh = new(SubRefreshRequest) + } + (*out.SubRefresh).UnmarshalEasyJSON(in) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild37(out *writer, in Command) { + out.RawByte('{') + first := true + _ = first + if in.Id != 0 { + const prefix string = ",\"id\":" + first = false + out.RawString(prefix[1:]) + out.Uint32(uint32(in.Id)) + } + if in.Connect != nil { + const prefix string = ",\"connect\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Connect).MarshalEasyJSON(out) + } + if in.Subscribe != nil { + const prefix string = ",\"subscribe\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Subscribe).MarshalEasyJSON(out) + } + if in.Unsubscribe != nil { + const prefix string = ",\"unsubscribe\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Unsubscribe).MarshalEasyJSON(out) + } + if in.Publish != nil { + const prefix string = ",\"publish\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Publish).MarshalEasyJSON(out) + } + if in.Presence != nil { + const prefix string = ",\"presence\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Presence).MarshalEasyJSON(out) + } + if in.PresenceStats != nil { + const prefix string = ",\"presence_stats\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.PresenceStats).MarshalEasyJSON(out) + } + if in.History != nil { + const prefix string = ",\"history\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.History).MarshalEasyJSON(out) + } + if in.Ping != nil { + const prefix string = ",\"ping\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Ping).MarshalEasyJSON(out) + } + if in.Send != nil { + const prefix string = ",\"send\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Send).MarshalEasyJSON(out) + } + if in.Rpc != nil { + const prefix string = ",\"rpc\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Rpc).MarshalEasyJSON(out) + } + if in.Refresh != nil { + const prefix string = ",\"refresh\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.Refresh).MarshalEasyJSON(out) + } + if in.SubRefresh != nil { + const prefix string = ",\"sub_refresh\":" + if first { + first = false + out.RawString(prefix[1:]) + } else { + out.RawString(prefix) + } + (*in.SubRefresh).MarshalEasyJSON(out) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v Command) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild37(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *Command) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild37(l, v) +} +func easyjson19c08265DecodeGithubComCentrifugalProtocolBuild38(in *jlexer.Lexer, out *ClientInfo) { + isTopLevel := in.IsStart() + if in.IsNull() { + if isTopLevel { + in.Consumed() + } + in.Skip() + return + } + in.Delim('{') + for !in.IsDelim('}') { + key := in.UnsafeFieldName(false) + in.WantColon() + if in.IsNull() { + in.Skip() + in.WantComma() + continue + } + switch key { + case "user": + out.User = string(in.String()) + case "client": + out.Client = string(in.String()) + case "conn_info": + if data := in.Raw(); in.Ok() { + in.AddError((out.ConnInfo).UnmarshalJSON(data)) + } + case "chan_info": + if data := in.Raw(); in.Ok() { + in.AddError((out.ChanInfo).UnmarshalJSON(data)) + } + default: + in.SkipRecursive() + } + in.WantComma() + } + in.Delim('}') + if isTopLevel { + in.Consumed() + } +} +func easyjson19c08265EncodeGithubComCentrifugalProtocolBuild38(out *writer, in ClientInfo) { + out.RawByte('{') + first := true + _ = first + { + const prefix string = ",\"user\":" + out.RawString(prefix[1:]) + out.String(string(in.User)) + } + { + const prefix string = ",\"client\":" + out.RawString(prefix) + out.String(string(in.Client)) + } + if len(in.ConnInfo) != 0 { + const prefix string = ",\"conn_info\":" + out.RawString(prefix) + out.Raw((in.ConnInfo).MarshalJSON()) + } + if len(in.ChanInfo) != 0 { + const prefix string = ",\"chan_info\":" + out.RawString(prefix) + out.Raw((in.ChanInfo).MarshalJSON()) + } + out.RawByte('}') +} + +// MarshalEasyJSON supports easyjson.Marshaler interface +func (v ClientInfo) MarshalEasyJSON(w *writer) { + easyjson19c08265EncodeGithubComCentrifugalProtocolBuild38(w, v) +} + +// UnmarshalEasyJSON supports easyjson.Unmarshaler interface +func (v *ClientInfo) UnmarshalEasyJSON(l *jlexer.Lexer) { + easyjson19c08265DecodeGithubComCentrifugalProtocolBuild38(l, v) +} diff --git a/vendor/github.com/centrifugal/protocol/client.proto b/vendor/github.com/centrifugal/protocol/client.proto new file mode 100644 index 0000000000..15fd696926 --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/client.proto @@ -0,0 +1,299 @@ +syntax = "proto3"; + +package centrifugal.centrifuge.protocol; + +option go_package = "github.com/centrifugal/protocol"; + +message Error { + uint32 code = 1; + string message = 2; + bool temporary = 3; +} + +message EmulationRequest { + string node = 1; + string session = 2; + bytes data = 3; +} + +// Command sent from a client to a server. +// ProtocolVersion2 uses id and one of the possible request messages. +message Command { + // Id of command to let client match replies to commands. + uint32 id = 1; + + reserved 2, 3; + + // ProtocolVersion2 client can send one of the following requests. Server will + // only take the first non-null request out of these and may return an error if + // client passed more than one request. We are not using oneof here due to JSON + // interoperability concerns. + ConnectRequest connect = 4; + SubscribeRequest subscribe = 5; + UnsubscribeRequest unsubscribe = 6; + PublishRequest publish = 7; + PresenceRequest presence = 8; + PresenceStatsRequest presence_stats = 9; + HistoryRequest history = 10; + PingRequest ping = 11; + SendRequest send = 12; + RPCRequest rpc = 13; + RefreshRequest refresh = 14; + SubRefreshRequest sub_refresh = 15; +} + +// Reply sent from a server to a client. +// ProtocolVersion2 uses id and one of the possible concrete result messages. +message Reply { + // Id will only be set to a value > 0 for replies to commands. For pushes + // it will have zero value. + uint32 id = 1; + // Error can only be set in replies to commands. For pushes it will have zero value. + Error error = 2; + + reserved 3; + + // ProtocolVersion2 server can send one of the following fields. We are not using + // oneof here due to JSON interoperability concerns. + Push push = 4; + ConnectResult connect = 5; + SubscribeResult subscribe = 6; + UnsubscribeResult unsubscribe = 7; + PublishResult publish = 8; + PresenceResult presence = 9; + PresenceStatsResult presence_stats = 10; + HistoryResult history = 11; + PingResult ping = 12; + RPCResult rpc = 13; + RefreshResult refresh = 14; + SubRefreshResult sub_refresh = 15; +} + +// Push can be sent to a client as part of Reply in case of bidirectional transport or +// without additional wrapping in case of unidirectional transports. +// ProtocolVersion2 uses channel and one of the possible concrete push messages. +message Push { + reserved 1, 3; + string channel = 2; + + // ProtocolVersion2 server can push one of the following fields to the client. We are + // not using oneof here due to JSON interoperability concerns. + Publication pub = 4; + Join join = 5; + Leave leave = 6; + Unsubscribe unsubscribe = 7; + Message message = 8; + Subscribe subscribe = 9; + Connect connect = 10; + Disconnect disconnect = 11; + Refresh refresh = 12; +} + +message ClientInfo { + string user = 1; + string client = 2; + bytes conn_info = 3; + bytes chan_info = 4; +} + +message Publication { + reserved 1, 2, 3; + bytes data = 4; + ClientInfo info = 5; + uint64 offset = 6; + map tags = 7; + bool delta = 8; // When set indicates that data in Publication is a delta from previous data. + int64 time = 9; // Optional time of publication as Unix timestamp milliseconds. + string channel = 10; // Optional channel name if Publication relates to wildcard subscription. +} + +message Join { + ClientInfo info = 1; +} + +message Leave { + ClientInfo info = 1; +} + +message Unsubscribe { + reserved 1; + uint32 code = 2; + string reason = 3; +} + +message Subscribe { + bool recoverable = 1; + reserved 2, 3; + string epoch = 4; + uint64 offset = 5; + bool positioned = 6; + bytes data = 7; +} + +message Message { + bytes data = 1; +} + +message Connect { + string client = 1; + string version = 2; + bytes data = 3; + map subs = 4; + bool expires = 5; + uint32 ttl = 6; + uint32 ping = 7; + bool pong = 8; + string session = 9; + string node = 10; + int64 time = 11; // Server time as Unix timestamp in milliseconds (not sent by default). +} + +message Disconnect { + uint32 code = 1; + string reason = 2; + bool reconnect = 3; +} + +message Refresh { + bool expires = 1; + uint32 ttl = 2; +} + +message ConnectRequest { + string token = 1; + bytes data = 2; + map subs = 3; + string name = 4; + string version = 5; + map headers = 6; +} + +message ConnectResult { + string client = 1; + string version = 2; + bool expires = 3; + uint32 ttl = 4; + bytes data = 5; + map subs = 6; + uint32 ping = 7; + bool pong = 8; + string session = 9; + string node = 10; + int64 time = 11; // Server time as Unix timestamp in milliseconds (not sent by default). +} + +message RefreshRequest { + string token = 1; +} + +message RefreshResult { + string client = 1; + string version = 2; + bool expires = 3; + uint32 ttl = 4; +} + +message SubscribeRequest { + string channel = 1; + string token = 2; + bool recover = 3; + reserved 4, 5; + string epoch = 6; + uint64 offset = 7; + bytes data = 8; + bool positioned = 9; + bool recoverable = 10; + bool join_leave = 11; + string delta = 12; +} + +message SubscribeResult { + bool expires = 1; + uint32 ttl = 2; + bool recoverable = 3; + reserved 4, 5; + string epoch = 6; + repeated Publication publications = 7; + bool recovered = 8; + uint64 offset = 9; + bool positioned = 10; + bytes data = 11; + bool was_recovering = 12; + bool delta = 13; +} + +message SubRefreshRequest { + string channel = 1; + string token = 2; +} + +message SubRefreshResult { + bool expires = 1; + uint32 ttl = 2; +} + +message UnsubscribeRequest { + string channel = 1; +} + +message UnsubscribeResult {} + +message PublishRequest { + string channel = 1; + bytes data = 2; +} + +message PublishResult {} + +message PresenceRequest { + string channel = 1; +} + +message PresenceResult { + map presence = 1; +} + +message PresenceStatsRequest { + string channel = 1; +} + +message PresenceStatsResult { + uint32 num_clients = 1; + uint32 num_users = 2; +} + +message StreamPosition { + uint64 offset = 1; + string epoch = 2; +} + +message HistoryRequest { + string channel = 1; + reserved 2, 3, 4, 5, 6; + int32 limit = 7; + StreamPosition since = 8; + bool reverse = 9; +} + +message HistoryResult { + repeated Publication publications = 1; + string epoch = 2; + uint64 offset = 3; +} + +message PingRequest {} + +message PingResult {} + +message RPCRequest{ + bytes data = 1; + string method = 2; +} + +message RPCResult { + bytes data = 1 ; +} + +message SendRequest{ + bytes data = 1; +} diff --git a/vendor/github.com/centrifugal/protocol/client_vtproto.pb.go b/vendor/github.com/centrifugal/protocol/client_vtproto.pb.go new file mode 100644 index 0000000000..500e4df418 --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/client_vtproto.pb.go @@ -0,0 +1,10440 @@ +// Code generated by protoc-gen-go-vtproto. DO NOT EDIT. +// protoc-gen-go-vtproto version: v0.6.0 +// source: client.proto + +package protocol + +import ( + fmt "fmt" + protohelpers "github.com/planetscale/vtprotobuf/protohelpers" + protoimpl "google.golang.org/protobuf/runtime/protoimpl" + io "io" +) + +const ( + // Verify that this generated code is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) + // Verify that runtime/protoimpl is sufficiently up-to-date. + _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) +) + +func (m *Error) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Error) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Error) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Temporary { + i-- + if m.Temporary { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.Message) > 0 { + i -= len(m.Message) + copy(dAtA[i:], m.Message) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Message))) + i-- + dAtA[i] = 0x12 + } + if m.Code != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Code)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *EmulationRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EmulationRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *EmulationRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x1a + } + if len(m.Session) > 0 { + i -= len(m.Session) + copy(dAtA[i:], m.Session) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Session))) + i-- + dAtA[i] = 0x12 + } + if len(m.Node) > 0 { + i -= len(m.Node) + copy(dAtA[i:], m.Node) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Node))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Command) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Command) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Command) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.SubRefresh != nil { + size, err := m.SubRefresh.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x7a + } + if m.Refresh != nil { + size, err := m.Refresh.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x72 + } + if m.Rpc != nil { + size, err := m.Rpc.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x6a + } + if m.Send != nil { + size, err := m.Send.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x62 + } + if m.Ping != nil { + size, err := m.Ping.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x5a + } + if m.History != nil { + size, err := m.History.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x52 + } + if m.PresenceStats != nil { + size, err := m.PresenceStats.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x4a + } + if m.Presence != nil { + size, err := m.Presence.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x42 + } + if m.Publish != nil { + size, err := m.Publish.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x3a + } + if m.Unsubscribe != nil { + size, err := m.Unsubscribe.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x32 + } + if m.Subscribe != nil { + size, err := m.Subscribe.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a + } + if m.Connect != nil { + size, err := m.Connect.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 + } + if m.Id != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Reply) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Reply) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Reply) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.SubRefresh != nil { + size, err := m.SubRefresh.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x7a + } + if m.Refresh != nil { + size, err := m.Refresh.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x72 + } + if m.Rpc != nil { + size, err := m.Rpc.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x6a + } + if m.Ping != nil { + size, err := m.Ping.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x62 + } + if m.History != nil { + size, err := m.History.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x5a + } + if m.PresenceStats != nil { + size, err := m.PresenceStats.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x52 + } + if m.Presence != nil { + size, err := m.Presence.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x4a + } + if m.Publish != nil { + size, err := m.Publish.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x42 + } + if m.Unsubscribe != nil { + size, err := m.Unsubscribe.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x3a + } + if m.Subscribe != nil { + size, err := m.Subscribe.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x32 + } + if m.Connect != nil { + size, err := m.Connect.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a + } + if m.Push != nil { + size, err := m.Push.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 + } + if m.Error != nil { + size, err := m.Error.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + } + if m.Id != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Id)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Push) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Push) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Push) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Refresh != nil { + size, err := m.Refresh.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x62 + } + if m.Disconnect != nil { + size, err := m.Disconnect.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x5a + } + if m.Connect != nil { + size, err := m.Connect.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x52 + } + if m.Subscribe != nil { + size, err := m.Subscribe.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x4a + } + if m.Message != nil { + size, err := m.Message.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x42 + } + if m.Unsubscribe != nil { + size, err := m.Unsubscribe.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x3a + } + if m.Leave != nil { + size, err := m.Leave.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x32 + } + if m.Join != nil { + size, err := m.Join.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a + } + if m.Pub != nil { + size, err := m.Pub.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x22 + } + if len(m.Channel) > 0 { + i -= len(m.Channel) + copy(dAtA[i:], m.Channel) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Channel))) + i-- + dAtA[i] = 0x12 + } + return len(dAtA) - i, nil +} + +func (m *ClientInfo) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ClientInfo) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ClientInfo) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.ChanInfo) > 0 { + i -= len(m.ChanInfo) + copy(dAtA[i:], m.ChanInfo) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ChanInfo))) + i-- + dAtA[i] = 0x22 + } + if len(m.ConnInfo) > 0 { + i -= len(m.ConnInfo) + copy(dAtA[i:], m.ConnInfo) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.ConnInfo))) + i-- + dAtA[i] = 0x1a + } + if len(m.Client) > 0 { + i -= len(m.Client) + copy(dAtA[i:], m.Client) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Client))) + i-- + dAtA[i] = 0x12 + } + if len(m.User) > 0 { + i -= len(m.User) + copy(dAtA[i:], m.User) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.User))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Publication) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Publication) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Publication) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Channel) > 0 { + i -= len(m.Channel) + copy(dAtA[i:], m.Channel) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Channel))) + i-- + dAtA[i] = 0x52 + } + if m.Time != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Time)) + i-- + dAtA[i] = 0x48 + } + if m.Delta { + i-- + if m.Delta { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } + if len(m.Tags) > 0 { + for k := range m.Tags { + v := m.Tags[k] + baseI := i + i -= len(v) + copy(dAtA[i:], v) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(v))) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x3a + } + } + if m.Offset != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Offset)) + i-- + dAtA[i] = 0x30 + } + if m.Info != nil { + size, err := m.Info.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x2a + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x22 + } + return len(dAtA) - i, nil +} + +func (m *Join) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Join) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Join) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Info != nil { + size, err := m.Info.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Leave) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Leave) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Leave) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Info != nil { + size, err := m.Info.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Unsubscribe) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Unsubscribe) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Unsubscribe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Reason) > 0 { + i -= len(m.Reason) + copy(dAtA[i:], m.Reason) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Reason))) + i-- + dAtA[i] = 0x1a + } + if m.Code != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Code)) + i-- + dAtA[i] = 0x10 + } + return len(dAtA) - i, nil +} + +func (m *Subscribe) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Subscribe) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Subscribe) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x3a + } + if m.Positioned { + i-- + if m.Positioned { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } + if m.Offset != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Offset)) + i-- + dAtA[i] = 0x28 + } + if len(m.Epoch) > 0 { + i -= len(m.Epoch) + copy(dAtA[i:], m.Epoch) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Epoch))) + i-- + dAtA[i] = 0x22 + } + if m.Recoverable { + i-- + if m.Recoverable { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Message) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Message) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Message) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Connect) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Connect) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Connect) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Time != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Time)) + i-- + dAtA[i] = 0x58 + } + if len(m.Node) > 0 { + i -= len(m.Node) + copy(dAtA[i:], m.Node) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Node))) + i-- + dAtA[i] = 0x52 + } + if len(m.Session) > 0 { + i -= len(m.Session) + copy(dAtA[i:], m.Session) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Session))) + i-- + dAtA[i] = 0x4a + } + if m.Pong { + i-- + if m.Pong { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } + if m.Ping != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Ping)) + i-- + dAtA[i] = 0x38 + } + if m.Ttl != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Ttl)) + i-- + dAtA[i] = 0x30 + } + if m.Expires { + i-- + if m.Expires { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x28 + } + if len(m.Subs) > 0 { + for k := range m.Subs { + v := m.Subs[k] + baseI := i + size, err := v.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x22 + } + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x1a + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x12 + } + if len(m.Client) > 0 { + i -= len(m.Client) + copy(dAtA[i:], m.Client) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Client))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Disconnect) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Disconnect) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Disconnect) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Reconnect { + i-- + if m.Reconnect { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.Reason) > 0 { + i -= len(m.Reason) + copy(dAtA[i:], m.Reason) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Reason))) + i-- + dAtA[i] = 0x12 + } + if m.Code != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Code)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *Refresh) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Refresh) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *Refresh) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Ttl != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Ttl)) + i-- + dAtA[i] = 0x10 + } + if m.Expires { + i-- + if m.Expires { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ConnectRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConnectRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ConnectRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Headers) > 0 { + for k := range m.Headers { + v := m.Headers[k] + baseI := i + i -= len(v) + copy(dAtA[i:], v) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(v))) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x32 + } + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x2a + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0x22 + } + if len(m.Subs) > 0 { + for k := range m.Subs { + v := m.Subs[k] + baseI := i + size, err := v.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x1a + } + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x12 + } + if len(m.Token) > 0 { + i -= len(m.Token) + copy(dAtA[i:], m.Token) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Token))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ConnectResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ConnectResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *ConnectResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Time != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Time)) + i-- + dAtA[i] = 0x58 + } + if len(m.Node) > 0 { + i -= len(m.Node) + copy(dAtA[i:], m.Node) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Node))) + i-- + dAtA[i] = 0x52 + } + if len(m.Session) > 0 { + i -= len(m.Session) + copy(dAtA[i:], m.Session) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Session))) + i-- + dAtA[i] = 0x4a + } + if m.Pong { + i-- + if m.Pong { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } + if m.Ping != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Ping)) + i-- + dAtA[i] = 0x38 + } + if len(m.Subs) > 0 { + for k := range m.Subs { + v := m.Subs[k] + baseI := i + size, err := v.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0x32 + } + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x2a + } + if m.Ttl != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Ttl)) + i-- + dAtA[i] = 0x20 + } + if m.Expires { + i-- + if m.Expires { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x12 + } + if len(m.Client) > 0 { + i -= len(m.Client) + copy(dAtA[i:], m.Client) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Client))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RefreshRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RefreshRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *RefreshRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Token) > 0 { + i -= len(m.Token) + copy(dAtA[i:], m.Token) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Token))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RefreshResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RefreshResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *RefreshResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Ttl != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Ttl)) + i-- + dAtA[i] = 0x20 + } + if m.Expires { + i-- + if m.Expires { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.Version) > 0 { + i -= len(m.Version) + copy(dAtA[i:], m.Version) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Version))) + i-- + dAtA[i] = 0x12 + } + if len(m.Client) > 0 { + i -= len(m.Client) + copy(dAtA[i:], m.Client) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Client))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SubscribeRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SubscribeRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *SubscribeRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Delta) > 0 { + i -= len(m.Delta) + copy(dAtA[i:], m.Delta) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Delta))) + i-- + dAtA[i] = 0x62 + } + if m.JoinLeave { + i-- + if m.JoinLeave { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x58 + } + if m.Recoverable { + i-- + if m.Recoverable { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x50 + } + if m.Positioned { + i-- + if m.Positioned { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x48 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x42 + } + if m.Offset != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Offset)) + i-- + dAtA[i] = 0x38 + } + if len(m.Epoch) > 0 { + i -= len(m.Epoch) + copy(dAtA[i:], m.Epoch) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Epoch))) + i-- + dAtA[i] = 0x32 + } + if m.Recover { + i-- + if m.Recover { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if len(m.Token) > 0 { + i -= len(m.Token) + copy(dAtA[i:], m.Token) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Token))) + i-- + dAtA[i] = 0x12 + } + if len(m.Channel) > 0 { + i -= len(m.Channel) + copy(dAtA[i:], m.Channel) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Channel))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SubscribeResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SubscribeResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *SubscribeResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Delta { + i-- + if m.Delta { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x68 + } + if m.WasRecovering { + i-- + if m.WasRecovering { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x60 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x5a + } + if m.Positioned { + i-- + if m.Positioned { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x50 + } + if m.Offset != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Offset)) + i-- + dAtA[i] = 0x48 + } + if m.Recovered { + i-- + if m.Recovered { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } + if len(m.Publications) > 0 { + for iNdEx := len(m.Publications) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Publications[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x3a + } + } + if len(m.Epoch) > 0 { + i -= len(m.Epoch) + copy(dAtA[i:], m.Epoch) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Epoch))) + i-- + dAtA[i] = 0x32 + } + if m.Recoverable { + i-- + if m.Recoverable { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x18 + } + if m.Ttl != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Ttl)) + i-- + dAtA[i] = 0x10 + } + if m.Expires { + i-- + if m.Expires { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *SubRefreshRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SubRefreshRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *SubRefreshRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Token) > 0 { + i -= len(m.Token) + copy(dAtA[i:], m.Token) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Token))) + i-- + dAtA[i] = 0x12 + } + if len(m.Channel) > 0 { + i -= len(m.Channel) + copy(dAtA[i:], m.Channel) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Channel))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SubRefreshResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SubRefreshResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *SubRefreshResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Ttl != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Ttl)) + i-- + dAtA[i] = 0x10 + } + if m.Expires { + i-- + if m.Expires { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *UnsubscribeRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UnsubscribeRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *UnsubscribeRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Channel) > 0 { + i -= len(m.Channel) + copy(dAtA[i:], m.Channel) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Channel))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *UnsubscribeResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *UnsubscribeResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *UnsubscribeResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *PublishRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PublishRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *PublishRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0x12 + } + if len(m.Channel) > 0 { + i -= len(m.Channel) + copy(dAtA[i:], m.Channel) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Channel))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PublishResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PublishResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *PublishResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *PresenceRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PresenceRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *PresenceRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Channel) > 0 { + i -= len(m.Channel) + copy(dAtA[i:], m.Channel) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Channel))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PresenceResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PresenceResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *PresenceResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Presence) > 0 { + for k := range m.Presence { + v := m.Presence[k] + baseI := i + size, err := v.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x12 + i -= len(k) + copy(dAtA[i:], k) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(k))) + i-- + dAtA[i] = 0xa + i = protohelpers.EncodeVarint(dAtA, i, uint64(baseI-i)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PresenceStatsRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PresenceStatsRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *PresenceStatsRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Channel) > 0 { + i -= len(m.Channel) + copy(dAtA[i:], m.Channel) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Channel))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *PresenceStatsResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PresenceStatsResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *PresenceStatsResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.NumUsers != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.NumUsers)) + i-- + dAtA[i] = 0x10 + } + if m.NumClients != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.NumClients)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *StreamPosition) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StreamPosition) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *StreamPosition) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Epoch) > 0 { + i -= len(m.Epoch) + copy(dAtA[i:], m.Epoch) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Epoch))) + i-- + dAtA[i] = 0x12 + } + if m.Offset != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Offset)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *HistoryRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HistoryRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *HistoryRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Reverse { + i-- + if m.Reverse { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x48 + } + if m.Since != nil { + size, err := m.Since.MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0x42 + } + if m.Limit != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Limit)) + i-- + dAtA[i] = 0x38 + } + if len(m.Channel) > 0 { + i -= len(m.Channel) + copy(dAtA[i:], m.Channel) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Channel))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *HistoryResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *HistoryResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *HistoryResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if m.Offset != 0 { + i = protohelpers.EncodeVarint(dAtA, i, uint64(m.Offset)) + i-- + dAtA[i] = 0x18 + } + if len(m.Epoch) > 0 { + i -= len(m.Epoch) + copy(dAtA[i:], m.Epoch) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Epoch))) + i-- + dAtA[i] = 0x12 + } + if len(m.Publications) > 0 { + for iNdEx := len(m.Publications) - 1; iNdEx >= 0; iNdEx-- { + size, err := m.Publications[iNdEx].MarshalToSizedBufferVT(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = protohelpers.EncodeVarint(dAtA, i, uint64(size)) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *PingRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PingRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *PingRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *PingResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PingResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *PingResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + return len(dAtA) - i, nil +} + +func (m *RPCRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RPCRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *RPCRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Method) > 0 { + i -= len(m.Method) + copy(dAtA[i:], m.Method) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Method))) + i-- + dAtA[i] = 0x12 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *RPCResult) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *RPCResult) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *RPCResult) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SendRequest) MarshalVT() (dAtA []byte, err error) { + if m == nil { + return nil, nil + } + size := m.SizeVT() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBufferVT(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SendRequest) MarshalToVT(dAtA []byte) (int, error) { + size := m.SizeVT() + return m.MarshalToSizedBufferVT(dAtA[:size]) +} + +func (m *SendRequest) MarshalToSizedBufferVT(dAtA []byte) (int, error) { + if m == nil { + return 0, nil + } + i := len(dAtA) + _ = i + var l int + _ = l + if m.unknownFields != nil { + i -= len(m.unknownFields) + copy(dAtA[i:], m.unknownFields) + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = protohelpers.EncodeVarint(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Error) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Code != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Code)) + } + l = len(m.Message) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Temporary { + n += 2 + } + n += len(m.unknownFields) + return n +} + +func (m *EmulationRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Node) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Session) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Command) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Id)) + } + if m.Connect != nil { + l = m.Connect.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Subscribe != nil { + l = m.Subscribe.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Unsubscribe != nil { + l = m.Unsubscribe.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Publish != nil { + l = m.Publish.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Presence != nil { + l = m.Presence.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.PresenceStats != nil { + l = m.PresenceStats.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.History != nil { + l = m.History.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Ping != nil { + l = m.Ping.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Send != nil { + l = m.Send.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Rpc != nil { + l = m.Rpc.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Refresh != nil { + l = m.Refresh.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.SubRefresh != nil { + l = m.SubRefresh.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Reply) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Id != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Id)) + } + if m.Error != nil { + l = m.Error.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Push != nil { + l = m.Push.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Connect != nil { + l = m.Connect.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Subscribe != nil { + l = m.Subscribe.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Unsubscribe != nil { + l = m.Unsubscribe.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Publish != nil { + l = m.Publish.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Presence != nil { + l = m.Presence.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.PresenceStats != nil { + l = m.PresenceStats.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.History != nil { + l = m.History.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Ping != nil { + l = m.Ping.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Rpc != nil { + l = m.Rpc.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Refresh != nil { + l = m.Refresh.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.SubRefresh != nil { + l = m.SubRefresh.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Push) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Channel) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Pub != nil { + l = m.Pub.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Join != nil { + l = m.Join.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Leave != nil { + l = m.Leave.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Unsubscribe != nil { + l = m.Unsubscribe.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Message != nil { + l = m.Message.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Subscribe != nil { + l = m.Subscribe.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Connect != nil { + l = m.Connect.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Disconnect != nil { + l = m.Disconnect.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Refresh != nil { + l = m.Refresh.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *ClientInfo) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.User) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Client) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.ConnInfo) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.ChanInfo) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Publication) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Info != nil { + l = m.Info.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Offset != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Offset)) + } + if len(m.Tags) > 0 { + for k, v := range m.Tags { + _ = k + _ = v + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + 1 + len(v) + protohelpers.SizeOfVarint(uint64(len(v))) + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) + } + } + if m.Delta { + n += 2 + } + if m.Time != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Time)) + } + l = len(m.Channel) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Join) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Info != nil { + l = m.Info.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Leave) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Info != nil { + l = m.Info.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Unsubscribe) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Code != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Code)) + } + l = len(m.Reason) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Subscribe) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Recoverable { + n += 2 + } + l = len(m.Epoch) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Offset != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Offset)) + } + if m.Positioned { + n += 2 + } + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Message) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Connect) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Client) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Subs) > 0 { + for k, v := range m.Subs { + _ = k + _ = v + l = 0 + if v != nil { + l = v.SizeVT() + } + l += 1 + protohelpers.SizeOfVarint(uint64(l)) + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + l + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) + } + } + if m.Expires { + n += 2 + } + if m.Ttl != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Ttl)) + } + if m.Ping != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Ping)) + } + if m.Pong { + n += 2 + } + l = len(m.Session) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Node) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Time != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Time)) + } + n += len(m.unknownFields) + return n +} + +func (m *Disconnect) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Code != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Code)) + } + l = len(m.Reason) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Reconnect { + n += 2 + } + n += len(m.unknownFields) + return n +} + +func (m *Refresh) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Expires { + n += 2 + } + if m.Ttl != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Ttl)) + } + n += len(m.unknownFields) + return n +} + +func (m *ConnectRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Token) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Subs) > 0 { + for k, v := range m.Subs { + _ = k + _ = v + l = 0 + if v != nil { + l = v.SizeVT() + } + l += 1 + protohelpers.SizeOfVarint(uint64(l)) + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + l + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) + } + } + l = len(m.Name) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Headers) > 0 { + for k, v := range m.Headers { + _ = k + _ = v + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + 1 + len(v) + protohelpers.SizeOfVarint(uint64(len(v))) + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *ConnectResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Client) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Expires { + n += 2 + } + if m.Ttl != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Ttl)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Subs) > 0 { + for k, v := range m.Subs { + _ = k + _ = v + l = 0 + if v != nil { + l = v.SizeVT() + } + l += 1 + protohelpers.SizeOfVarint(uint64(l)) + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + l + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) + } + } + if m.Ping != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Ping)) + } + if m.Pong { + n += 2 + } + l = len(m.Session) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Node) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Time != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Time)) + } + n += len(m.unknownFields) + return n +} + +func (m *RefreshRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Token) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *RefreshResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Client) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Version) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Expires { + n += 2 + } + if m.Ttl != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Ttl)) + } + n += len(m.unknownFields) + return n +} + +func (m *SubscribeRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Channel) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Token) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Recover { + n += 2 + } + l = len(m.Epoch) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Offset != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Offset)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Positioned { + n += 2 + } + if m.Recoverable { + n += 2 + } + if m.JoinLeave { + n += 2 + } + l = len(m.Delta) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *SubscribeResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Expires { + n += 2 + } + if m.Ttl != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Ttl)) + } + if m.Recoverable { + n += 2 + } + l = len(m.Epoch) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if len(m.Publications) > 0 { + for _, e := range m.Publications { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + if m.Recovered { + n += 2 + } + if m.Offset != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Offset)) + } + if m.Positioned { + n += 2 + } + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.WasRecovering { + n += 2 + } + if m.Delta { + n += 2 + } + n += len(m.unknownFields) + return n +} + +func (m *SubRefreshRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Channel) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Token) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *SubRefreshResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Expires { + n += 2 + } + if m.Ttl != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Ttl)) + } + n += len(m.unknownFields) + return n +} + +func (m *UnsubscribeRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Channel) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *UnsubscribeResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *PublishRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Channel) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *PublishResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *PresenceRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Channel) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *PresenceResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Presence) > 0 { + for k, v := range m.Presence { + _ = k + _ = v + l = 0 + if v != nil { + l = v.SizeVT() + } + l += 1 + protohelpers.SizeOfVarint(uint64(l)) + mapEntrySize := 1 + len(k) + protohelpers.SizeOfVarint(uint64(len(k))) + l + n += mapEntrySize + 1 + protohelpers.SizeOfVarint(uint64(mapEntrySize)) + } + } + n += len(m.unknownFields) + return n +} + +func (m *PresenceStatsRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Channel) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *PresenceStatsResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.NumClients != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.NumClients)) + } + if m.NumUsers != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.NumUsers)) + } + n += len(m.unknownFields) + return n +} + +func (m *StreamPosition) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Offset != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Offset)) + } + l = len(m.Epoch) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *HistoryRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Channel) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Limit != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Limit)) + } + if m.Since != nil { + l = m.Since.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Reverse { + n += 2 + } + n += len(m.unknownFields) + return n +} + +func (m *HistoryResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Publications) > 0 { + for _, e := range m.Publications { + l = e.SizeVT() + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + } + l = len(m.Epoch) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + if m.Offset != 0 { + n += 1 + protohelpers.SizeOfVarint(uint64(m.Offset)) + } + n += len(m.unknownFields) + return n +} + +func (m *PingRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *PingResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + n += len(m.unknownFields) + return n +} + +func (m *RPCRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + l = len(m.Method) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *RPCResult) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *SendRequest) SizeVT() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + protohelpers.SizeOfVarint(uint64(l)) + } + n += len(m.unknownFields) + return n +} + +func (m *Error) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Error: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Error: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + m.Code = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Code |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Message = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Temporary", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Temporary = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *EmulationRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: EmulationRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EmulationRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Node", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Node = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Session", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Session = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Command) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Command: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Command: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Connect", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Connect == nil { + m.Connect = &ConnectRequest{} + } + if err := m.Connect.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subscribe", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Subscribe == nil { + m.Subscribe = &SubscribeRequest{} + } + if err := m.Subscribe.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Unsubscribe", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Unsubscribe == nil { + m.Unsubscribe = &UnsubscribeRequest{} + } + if err := m.Unsubscribe.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Publish", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Publish == nil { + m.Publish = &PublishRequest{} + } + if err := m.Publish.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Presence", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Presence == nil { + m.Presence = &PresenceRequest{} + } + if err := m.Presence.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PresenceStats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PresenceStats == nil { + m.PresenceStats = &PresenceStatsRequest{} + } + if err := m.PresenceStats.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field History", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.History == nil { + m.History = &HistoryRequest{} + } + if err := m.History.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ping", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ping == nil { + m.Ping = &PingRequest{} + } + if err := m.Ping.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Send", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Send == nil { + m.Send = &SendRequest{} + } + if err := m.Send.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rpc", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Rpc == nil { + m.Rpc = &RPCRequest{} + } + if err := m.Rpc.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Refresh", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Refresh == nil { + m.Refresh = &RefreshRequest{} + } + if err := m.Refresh.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubRefresh", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SubRefresh == nil { + m.SubRefresh = &SubRefreshRequest{} + } + if err := m.SubRefresh.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Reply) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Reply: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Reply: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Id", wireType) + } + m.Id = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Id |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Error == nil { + m.Error = &Error{} + } + if err := m.Error.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Push", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Push == nil { + m.Push = &Push{} + } + if err := m.Push.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Connect", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Connect == nil { + m.Connect = &ConnectResult{} + } + if err := m.Connect.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subscribe", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Subscribe == nil { + m.Subscribe = &SubscribeResult{} + } + if err := m.Subscribe.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Unsubscribe", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Unsubscribe == nil { + m.Unsubscribe = &UnsubscribeResult{} + } + if err := m.Unsubscribe.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Publish", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Publish == nil { + m.Publish = &PublishResult{} + } + if err := m.Publish.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Presence", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Presence == nil { + m.Presence = &PresenceResult{} + } + if err := m.Presence.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field PresenceStats", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.PresenceStats == nil { + m.PresenceStats = &PresenceStatsResult{} + } + if err := m.PresenceStats.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field History", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.History == nil { + m.History = &HistoryResult{} + } + if err := m.History.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Ping", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Ping == nil { + m.Ping = &PingResult{} + } + if err := m.Ping.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 13: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Rpc", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Rpc == nil { + m.Rpc = &RPCResult{} + } + if err := m.Rpc.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Refresh", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Refresh == nil { + m.Refresh = &RefreshResult{} + } + if err := m.Refresh.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubRefresh", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.SubRefresh == nil { + m.SubRefresh = &SubRefreshResult{} + } + if err := m.SubRefresh.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Push) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Push: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Push: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Channel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Pub", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Pub == nil { + m.Pub = &Publication{} + } + if err := m.Pub.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Join", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Join == nil { + m.Join = &Join{} + } + if err := m.Join.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Leave", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Leave == nil { + m.Leave = &Leave{} + } + if err := m.Leave.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Unsubscribe", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Unsubscribe == nil { + m.Unsubscribe = &Unsubscribe{} + } + if err := m.Unsubscribe.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Message", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Message == nil { + m.Message = &Message{} + } + if err := m.Message.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subscribe", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Subscribe == nil { + m.Subscribe = &Subscribe{} + } + if err := m.Subscribe.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Connect", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Connect == nil { + m.Connect = &Connect{} + } + if err := m.Connect.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Disconnect", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Disconnect == nil { + m.Disconnect = &Disconnect{} + } + if err := m.Disconnect.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Refresh", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Refresh == nil { + m.Refresh = &Refresh{} + } + if err := m.Refresh.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ClientInfo) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ClientInfo: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ClientInfo: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field User", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.User = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Client", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Client = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnInfo", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ConnInfo = append(m.ConnInfo[:0], dAtA[iNdEx:postIndex]...) + if m.ConnInfo == nil { + m.ConnInfo = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ChanInfo", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.ChanInfo = append(m.ChanInfo[:0], dAtA[iNdEx:postIndex]...) + if m.ChanInfo == nil { + m.ChanInfo = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Publication) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Publication: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Publication: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Info == nil { + m.Info = &ClientInfo{} + } + if err := m.Info.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + } + m.Offset = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Offset |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Tags", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Tags == nil { + m.Tags = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return protohelpers.ErrInvalidLength + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return protohelpers.ErrInvalidLength + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return protohelpers.ErrInvalidLength + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return protohelpers.ErrInvalidLength + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Tags[mapkey] = mapvalue + iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Delta", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Delta = bool(v != 0) + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType) + } + m.Time = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Time |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Channel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Join) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Join: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Join: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Info == nil { + m.Info = &ClientInfo{} + } + if err := m.Info.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Leave) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Leave: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Leave: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Info", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Info == nil { + m.Info = &ClientInfo{} + } + if err := m.Info.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Unsubscribe) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Unsubscribe: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Unsubscribe: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + m.Code = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Code |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Reason = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Subscribe) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Subscribe: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Subscribe: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Recoverable", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Recoverable = bool(v != 0) + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Epoch", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Epoch = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + } + m.Offset = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Offset |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Positioned", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Positioned = bool(v != 0) + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Message) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Message: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Message: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Connect) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Connect: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Connect: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Client", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Client = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Subs == nil { + m.Subs = make(map[string]*SubscribeResult) + } + var mapkey string + var mapvalue *SubscribeResult + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return protohelpers.ErrInvalidLength + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return protohelpers.ErrInvalidLength + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return protohelpers.ErrInvalidLength + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &SubscribeResult{} + if err := mapvalue.UnmarshalVT(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Subs[mapkey] = mapvalue + iNdEx = postIndex + case 5: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Expires = bool(v != 0) + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) + } + m.Ttl = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ttl |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ping", wireType) + } + m.Ping = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ping |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Pong", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Pong = bool(v != 0) + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Session", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Session = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Node", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Node = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType) + } + m.Time = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Time |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Disconnect) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Disconnect: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Disconnect: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Code", wireType) + } + m.Code = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Code |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Reason", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Reason = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Reconnect", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Reconnect = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Refresh) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Refresh: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Refresh: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Expires = bool(v != 0) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) + } + m.Ttl = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ttl |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConnectRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConnectRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConnectRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Token = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Subs == nil { + m.Subs = make(map[string]*SubscribeRequest) + } + var mapkey string + var mapvalue *SubscribeRequest + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return protohelpers.ErrInvalidLength + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return protohelpers.ErrInvalidLength + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return protohelpers.ErrInvalidLength + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &SubscribeRequest{} + if err := mapvalue.UnmarshalVT(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Subs[mapkey] = mapvalue + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Headers", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Headers == nil { + m.Headers = make(map[string]string) + } + var mapkey string + var mapvalue string + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return protohelpers.ErrInvalidLength + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return protohelpers.ErrInvalidLength + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var stringLenmapvalue uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapvalue |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapvalue := int(stringLenmapvalue) + if intStringLenmapvalue < 0 { + return protohelpers.ErrInvalidLength + } + postStringIndexmapvalue := iNdEx + intStringLenmapvalue + if postStringIndexmapvalue < 0 { + return protohelpers.ErrInvalidLength + } + if postStringIndexmapvalue > l { + return io.ErrUnexpectedEOF + } + mapvalue = string(dAtA[iNdEx:postStringIndexmapvalue]) + iNdEx = postStringIndexmapvalue + } else { + iNdEx = entryPreIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Headers[mapkey] = mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ConnectResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ConnectResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ConnectResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Client", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Client = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Expires = bool(v != 0) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) + } + m.Ttl = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ttl |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Subs", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Subs == nil { + m.Subs = make(map[string]*SubscribeResult) + } + var mapkey string + var mapvalue *SubscribeResult + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return protohelpers.ErrInvalidLength + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return protohelpers.ErrInvalidLength + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return protohelpers.ErrInvalidLength + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &SubscribeResult{} + if err := mapvalue.UnmarshalVT(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Subs[mapkey] = mapvalue + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ping", wireType) + } + m.Ping = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ping |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Pong", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Pong = bool(v != 0) + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Session", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Session = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Node", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Node = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Time", wireType) + } + m.Time = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Time |= int64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RefreshRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RefreshRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RefreshRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Token = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RefreshResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RefreshResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RefreshResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Client", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Client = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Version", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Version = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Expires = bool(v != 0) + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) + } + m.Ttl = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ttl |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SubscribeRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SubscribeRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SubscribeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Channel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Token = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Recover", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Recover = bool(v != 0) + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Epoch", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Epoch = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + } + m.Offset = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Offset |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Positioned", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Positioned = bool(v != 0) + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Recoverable", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Recoverable = bool(v != 0) + case 11: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field JoinLeave", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.JoinLeave = bool(v != 0) + case 12: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Delta", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Delta = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SubscribeResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SubscribeResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SubscribeResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Expires = bool(v != 0) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) + } + m.Ttl = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ttl |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Recoverable", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Recoverable = bool(v != 0) + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Epoch", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Epoch = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Publications", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Publications = append(m.Publications, &Publication{}) + if err := m.Publications[len(m.Publications)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Recovered", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Recovered = bool(v != 0) + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + } + m.Offset = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Offset |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Positioned", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Positioned = bool(v != 0) + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 12: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field WasRecovering", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.WasRecovering = bool(v != 0) + case 13: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Delta", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Delta = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SubRefreshRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SubRefreshRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SubRefreshRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Channel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Token", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Token = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SubRefreshResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SubRefreshResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SubRefreshResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Expires", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Expires = bool(v != 0) + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Ttl", wireType) + } + m.Ttl = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Ttl |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UnsubscribeRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UnsubscribeRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UnsubscribeRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Channel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *UnsubscribeResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: UnsubscribeResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: UnsubscribeResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PublishRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PublishRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PublishRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Channel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PublishResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PublishResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PublishResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PresenceRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PresenceRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PresenceRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Channel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PresenceResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PresenceResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PresenceResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Presence", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Presence == nil { + m.Presence = make(map[string]*ClientInfo) + } + var mapkey string + var mapvalue *ClientInfo + for iNdEx < postIndex { + entryPreIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + if fieldNum == 1 { + var stringLenmapkey uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLenmapkey |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLenmapkey := int(stringLenmapkey) + if intStringLenmapkey < 0 { + return protohelpers.ErrInvalidLength + } + postStringIndexmapkey := iNdEx + intStringLenmapkey + if postStringIndexmapkey < 0 { + return protohelpers.ErrInvalidLength + } + if postStringIndexmapkey > l { + return io.ErrUnexpectedEOF + } + mapkey = string(dAtA[iNdEx:postStringIndexmapkey]) + iNdEx = postStringIndexmapkey + } else if fieldNum == 2 { + var mapmsglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + mapmsglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if mapmsglen < 0 { + return protohelpers.ErrInvalidLength + } + postmsgIndex := iNdEx + mapmsglen + if postmsgIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postmsgIndex > l { + return io.ErrUnexpectedEOF + } + mapvalue = &ClientInfo{} + if err := mapvalue.UnmarshalVT(dAtA[iNdEx:postmsgIndex]); err != nil { + return err + } + iNdEx = postmsgIndex + } else { + iNdEx = entryPreIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > postIndex { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + m.Presence[mapkey] = mapvalue + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PresenceStatsRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PresenceStatsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PresenceStatsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Channel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PresenceStatsResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PresenceStatsResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PresenceStatsResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumClients", wireType) + } + m.NumClients = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumClients |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field NumUsers", wireType) + } + m.NumUsers = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.NumUsers |= uint32(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StreamPosition) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: StreamPosition: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StreamPosition: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + } + m.Offset = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Offset |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Epoch", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Epoch = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HistoryRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HistoryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HistoryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Channel", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Channel = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 7: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Limit", wireType) + } + m.Limit = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Limit |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Since", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Since == nil { + m.Since = &StreamPosition{} + } + if err := m.Since.UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 9: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Reverse", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Reverse = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *HistoryResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: HistoryResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: HistoryResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Publications", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Publications = append(m.Publications, &Publication{}) + if err := m.Publications[len(m.Publications)-1].UnmarshalVT(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Epoch", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Epoch = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Offset", wireType) + } + m.Offset = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Offset |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PingRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PingRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PingRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PingResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PingResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PingResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RPCRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RPCRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RPCRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Method", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Method = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *RPCResult) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: RPCResult: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: RPCResult: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SendRequest) UnmarshalVT(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SendRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SendRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protohelpers.ErrIntOverflow + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return protohelpers.ErrInvalidLength + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return protohelpers.ErrInvalidLength + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := protohelpers.Skip(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return protohelpers.ErrInvalidLength + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.unknownFields = append(m.unknownFields, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} diff --git a/vendor/github.com/centrifugal/protocol/decode.go b/vendor/github.com/centrifugal/protocol/decode.go new file mode 100644 index 0000000000..199e03c9ae --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/decode.go @@ -0,0 +1,217 @@ +package protocol + +import ( + "bytes" + "encoding/binary" + "io" + + "github.com/segmentio/encoding/json" +) + +// CommandDecoder ... +type CommandDecoder interface { + Reset([]byte) error + Decode() (*Command, error) +} + +// JSONCommandDecoder ... +type JSONCommandDecoder struct { + data []byte + messageCount int + prevNewLine int + numMessagesRead int +} + +// NewJSONCommandDecoder ... +func NewJSONCommandDecoder(data []byte) *JSONCommandDecoder { + // Protocol message must be separated by exactly one `\n`. + messageCount := bytes.Count(data, []byte("\n")) + 1 + if len(data) == 0 || data[len(data)-1] == '\n' { + // Protocol message must have zero or one `\n` at the end. + messageCount-- + } + return &JSONCommandDecoder{ + data: data, + messageCount: messageCount, + prevNewLine: 0, + numMessagesRead: 0, + } +} + +// Reset ... +func (d *JSONCommandDecoder) Reset(data []byte) error { + // We have a strict contract that protocol messages should be separated by at most one `\n`. + messageCount := bytes.Count(data, []byte("\n")) + 1 + if len(data) == 0 || data[len(data)-1] == '\n' { + // We have a strict contract that protocol message should use at most one `\n` at the end. + messageCount-- + } + d.data = data + d.messageCount = messageCount + d.prevNewLine = 0 + d.numMessagesRead = 0 + return nil +} + +// Decode ... +func (d *JSONCommandDecoder) Decode() (*Command, error) { + if d.messageCount == 0 { + return nil, io.ErrUnexpectedEOF + } + var c Command + if d.messageCount == 1 { + _, err := json.Parse(d.data, &c, json.ZeroCopy) + if err != nil { + return nil, err + } + return &c, io.EOF + } + var nextNewLine int + if d.numMessagesRead == d.messageCount-1 { + // Last message, no need to search for a new line. + nextNewLine = len(d.data[d.prevNewLine:]) + } else if len(d.data) > d.prevNewLine { + nextNewLine = bytes.Index(d.data[d.prevNewLine:], []byte("\n")) + if nextNewLine < 0 { + return nil, io.ErrShortBuffer + } + } else { + return nil, io.ErrShortBuffer + } + if len(d.data) >= d.prevNewLine+nextNewLine { + _, err := json.Parse(d.data[d.prevNewLine:d.prevNewLine+nextNewLine], &c, json.ZeroCopy) + if err != nil { + return nil, err + } + d.numMessagesRead++ + d.prevNewLine = d.prevNewLine + nextNewLine + 1 + if d.numMessagesRead == d.messageCount { + return &c, io.EOF + } + return &c, nil + } else { + return nil, io.ErrShortBuffer + } +} + +// ProtobufCommandDecoder ... +type ProtobufCommandDecoder struct { + data []byte + offset int +} + +// NewProtobufCommandDecoder ... +func NewProtobufCommandDecoder(data []byte) *ProtobufCommandDecoder { + return &ProtobufCommandDecoder{ + data: data, + } +} + +// Reset ... +func (d *ProtobufCommandDecoder) Reset(data []byte) error { + d.data = data + d.offset = 0 + return nil +} + +// Decode ... +func (d *ProtobufCommandDecoder) Decode() (*Command, error) { + if d.offset < len(d.data) { + var c Command + l, n := binary.Uvarint(d.data[d.offset:]) + if n <= 0 { + return nil, io.EOF + } + from := d.offset + n + to := d.offset + n + int(l) + if to > 0 && to <= len(d.data) { + cmdBytes := d.data[from:to] + err := c.UnmarshalVT(cmdBytes) // Check whether UnmarshalVTUnsafe here is OK. + if err != nil { + return nil, err + } + d.offset = to + if d.offset == len(d.data) { + err = io.EOF + } + return &c, err + } else { + return nil, io.ErrShortBuffer + } + } + return nil, io.EOF +} + +// ReplyDecoder ... +type ReplyDecoder interface { + Reset([]byte) error + Decode() (*Reply, error) +} + +var _ ReplyDecoder = NewJSONReplyDecoder(nil) + +// JSONReplyDecoder ... +type JSONReplyDecoder struct { + decoder *json.Decoder +} + +// NewJSONReplyDecoder ... +func NewJSONReplyDecoder(data []byte) *JSONReplyDecoder { + return &JSONReplyDecoder{ + decoder: json.NewDecoder(bytes.NewReader(data)), + } +} + +// Reset ... +func (d *JSONReplyDecoder) Reset(data []byte) error { + d.decoder = json.NewDecoder(bytes.NewReader(data)) + return nil +} + +// Decode ... +func (d *JSONReplyDecoder) Decode() (*Reply, error) { + var c Reply + err := d.decoder.Decode(&c) + if err != nil { + return nil, err + } + return &c, nil +} + +var _ ReplyDecoder = NewProtobufReplyDecoder(nil) + +// ProtobufReplyDecoder ... +type ProtobufReplyDecoder struct { + data []byte + offset int +} + +// NewProtobufReplyDecoder ... +func NewProtobufReplyDecoder(data []byte) *ProtobufReplyDecoder { + return &ProtobufReplyDecoder{ + data: data, + } +} + +// Reset ... +func (d *ProtobufReplyDecoder) Reset(data []byte) error { + d.data = data + d.offset = 0 + return nil +} + +// Decode ... +func (d *ProtobufReplyDecoder) Decode() (*Reply, error) { + if d.offset < len(d.data) { + var c Reply + l, n := binary.Uvarint(d.data[d.offset:]) + replyBytes := d.data[d.offset+n : d.offset+n+int(l)] + err := c.UnmarshalVT(replyBytes) + if err != nil { + return nil, err + } + d.offset = d.offset + n + int(l) + return &c, nil + } + return nil, io.EOF +} diff --git a/vendor/github.com/centrifugal/protocol/decode_stream.go b/vendor/github.com/centrifugal/protocol/decode_stream.go new file mode 100644 index 0000000000..99b5e6403e --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/decode_stream.go @@ -0,0 +1,161 @@ +package protocol + +import ( + "bufio" + "encoding/binary" + "errors" + "io" + "sync" + + "github.com/segmentio/encoding/json" +) + +var ( + streamJsonCommandDecoderPool sync.Pool + streamProtobufCommandDecoderPool sync.Pool +) + +func GetStreamCommandDecoder(protoType Type, reader io.Reader) StreamCommandDecoder { + return GetStreamCommandDecoderLimited(protoType, reader, 0) +} + +func GetStreamCommandDecoderLimited(protoType Type, reader io.Reader, messageSizeLimit int64) StreamCommandDecoder { + if protoType == TypeJSON { + e := streamJsonCommandDecoderPool.Get() + if e == nil { + return NewJSONStreamCommandDecoder(reader, messageSizeLimit) + } + commandDecoder := e.(*JSONStreamCommandDecoder) + commandDecoder.Reset(reader, messageSizeLimit) + return commandDecoder + } + e := streamProtobufCommandDecoderPool.Get() + if e == nil { + return NewProtobufStreamCommandDecoder(reader, messageSizeLimit) + } + commandDecoder := e.(*ProtobufStreamCommandDecoder) + commandDecoder.Reset(reader, messageSizeLimit) + return commandDecoder +} + +func PutStreamCommandDecoder(protoType Type, e StreamCommandDecoder) { + e.Reset(nil, 0) + if protoType == TypeJSON { + streamJsonCommandDecoderPool.Put(e) + return + } + streamProtobufCommandDecoderPool.Put(e) +} + +type StreamCommandDecoder interface { + Decode() (*Command, int, error) + Reset(reader io.Reader, messageSizeLimit int64) +} + +// ErrMessageTooLarge for when the message exceeds the limit. +var ErrMessageTooLarge = errors.New("message size exceeds the limit") + +type JSONStreamCommandDecoder struct { + reader *bufio.Reader + limitedReader *io.LimitedReader + messageSizeLimit int64 +} + +func NewJSONStreamCommandDecoder(reader io.Reader, messageSizeLimit int64) *JSONStreamCommandDecoder { + var limitedReader *io.LimitedReader + var bufioReader *bufio.Reader + if messageSizeLimit > 0 { + limitedReader = &io.LimitedReader{R: reader, N: messageSizeLimit + 1} + bufioReader = bufio.NewReader(limitedReader) + } else { + bufioReader = bufio.NewReader(reader) + } + return &JSONStreamCommandDecoder{ + reader: bufioReader, + limitedReader: limitedReader, + messageSizeLimit: messageSizeLimit, + } +} + +func (d *JSONStreamCommandDecoder) Decode() (*Command, int, error) { + if d.messageSizeLimit > 0 { + d.limitedReader.N = int64(d.messageSizeLimit) + 1 + } + cmdBytes, err := d.reader.ReadBytes('\n') + if err != nil { + if d.messageSizeLimit > 0 && int64(len(cmdBytes)) > d.messageSizeLimit { + return nil, 0, ErrMessageTooLarge + } + if err == io.EOF && len(cmdBytes) > 0 { + var c Command + _, parseErr := json.Parse(cmdBytes, &c, 0) + if parseErr != nil { + return nil, 0, parseErr + } + return &c, len(cmdBytes), err + } + return nil, 0, err + } + + var c Command + _, err = json.Parse(cmdBytes, &c, 0) + if err != nil { + return nil, 0, err + } + return &c, len(cmdBytes), nil +} + +func (d *JSONStreamCommandDecoder) Reset(reader io.Reader, messageSizeLimit int64) { + d.messageSizeLimit = messageSizeLimit + if messageSizeLimit > 0 { + limitedReader := &io.LimitedReader{R: reader, N: messageSizeLimit + 1} + bufioReader := bufio.NewReader(limitedReader) + d.limitedReader = limitedReader + d.reader.Reset(bufioReader) + } else { + d.limitedReader = nil + d.reader.Reset(reader) + } +} + +type ProtobufStreamCommandDecoder struct { + reader *bufio.Reader + messageSizeLimit int64 +} + +func NewProtobufStreamCommandDecoder(reader io.Reader, messageSizeLimit int64) *ProtobufStreamCommandDecoder { + return &ProtobufStreamCommandDecoder{reader: bufio.NewReader(reader), messageSizeLimit: messageSizeLimit} +} + +func (d *ProtobufStreamCommandDecoder) Decode() (*Command, int, error) { + msgLength, err := binary.ReadUvarint(d.reader) + if err != nil { + return nil, 0, err + } + + if d.messageSizeLimit > 0 && msgLength > uint64(d.messageSizeLimit) { + return nil, 0, ErrMessageTooLarge + } + + bb := getByteBuffer(int(msgLength)) + defer putByteBuffer(bb) + + n, err := io.ReadFull(d.reader, bb.B[:int(msgLength)]) + if err != nil { + return nil, 0, err + } + if uint64(n) != msgLength { + return nil, 0, io.ErrShortBuffer + } + var c Command + err = c.UnmarshalVT(bb.B[:int(msgLength)]) // Note, UnmarshalVTUnsafe here will result into issues. + if err != nil { + return nil, 0, err + } + return &c, int(msgLength) + 8, nil +} + +func (d *ProtobufStreamCommandDecoder) Reset(reader io.Reader, messageSizeLimit int64) { + d.messageSizeLimit = messageSizeLimit + d.reader.Reset(reader) +} diff --git a/vendor/github.com/centrifugal/protocol/encode.go b/vendor/github.com/centrifugal/protocol/encode.go new file mode 100644 index 0000000000..021f4805f5 --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/encode.go @@ -0,0 +1,609 @@ +package protocol + +import ( + "bytes" + "encoding/binary" + "errors" + fastJSON "github.com/segmentio/encoding/json" +) + +var errInvalidJSON = errors.New("invalid JSON data") + +// checks that JSON is valid. +func isValidJSON(b []byte) error { + if b == nil { + return nil + } + if !fastJSON.Valid(b) { + return errInvalidJSON + } + return nil +} + +// PushEncoder ... +type PushEncoder interface { + Encode(*Push) ([]byte, error) + EncodeMessage(*Message, ...[]byte) ([]byte, error) + EncodePublication(*Publication, ...[]byte) ([]byte, error) + EncodeJoin(*Join, ...[]byte) ([]byte, error) + EncodeLeave(*Leave, ...[]byte) ([]byte, error) + EncodeUnsubscribe(*Unsubscribe, ...[]byte) ([]byte, error) + EncodeSubscribe(*Subscribe, ...[]byte) ([]byte, error) + EncodeConnect(*Connect, ...[]byte) ([]byte, error) + EncodeDisconnect(*Disconnect, ...[]byte) ([]byte, error) + EncodeRefresh(*Refresh, ...[]byte) ([]byte, error) +} + +var _ PushEncoder = (*JSONPushEncoder)(nil) +var _ PushEncoder = (*ProtobufPushEncoder)(nil) + +// JSONPushEncoder ... +type JSONPushEncoder struct { +} + +// NewJSONPushEncoder ... +func NewJSONPushEncoder() *JSONPushEncoder { + return &JSONPushEncoder{} +} + +// Encode Push to bytes. +func (e *JSONPushEncoder) Encode(message *Push) ([]byte, error) { + jw := newWriter() + message.MarshalEasyJSON(jw) + res, err := jw.BuildBytes() + if err != nil { + return nil, err + } + if err := isValidJSON(res); err != nil { + return nil, err + } + return res, nil +} + +// EncodePublication to bytes. +func (e *JSONPushEncoder) EncodePublication(message *Publication, reuse ...[]byte) ([]byte, error) { + jw := newWriter() + message.MarshalEasyJSON(jw) + return jw.BuildBytes(reuse...) +} + +// EncodeMessage to bytes. +func (e *JSONPushEncoder) EncodeMessage(message *Message, reuse ...[]byte) ([]byte, error) { + jw := newWriter() + message.MarshalEasyJSON(jw) + return jw.BuildBytes(reuse...) +} + +// EncodeJoin to bytes. +func (e *JSONPushEncoder) EncodeJoin(message *Join, reuse ...[]byte) ([]byte, error) { + jw := newWriter() + message.MarshalEasyJSON(jw) + return jw.BuildBytes(reuse...) +} + +// EncodeLeave to bytes. +func (e *JSONPushEncoder) EncodeLeave(message *Leave, reuse ...[]byte) ([]byte, error) { + jw := newWriter() + message.MarshalEasyJSON(jw) + return jw.BuildBytes(reuse...) +} + +// EncodeUnsubscribe to bytes. +func (e *JSONPushEncoder) EncodeUnsubscribe(message *Unsubscribe, reuse ...[]byte) ([]byte, error) { + jw := newWriter() + message.MarshalEasyJSON(jw) + return jw.BuildBytes(reuse...) +} + +// EncodeSubscribe to bytes. +func (e *JSONPushEncoder) EncodeSubscribe(message *Subscribe, reuse ...[]byte) ([]byte, error) { + jw := newWriter() + message.MarshalEasyJSON(jw) + return jw.BuildBytes(reuse...) +} + +// EncodeConnect to bytes. +func (e *JSONPushEncoder) EncodeConnect(message *Connect, reuse ...[]byte) ([]byte, error) { + jw := newWriter() + message.MarshalEasyJSON(jw) + return jw.BuildBytes(reuse...) +} + +// EncodeDisconnect to bytes. +func (e *JSONPushEncoder) EncodeDisconnect(message *Disconnect, reuse ...[]byte) ([]byte, error) { + jw := newWriter() + message.MarshalEasyJSON(jw) + return jw.BuildBytes(reuse...) +} + +// EncodeRefresh to bytes. +func (e *JSONPushEncoder) EncodeRefresh(message *Refresh, reuse ...[]byte) ([]byte, error) { + jw := newWriter() + message.MarshalEasyJSON(jw) + return jw.BuildBytes(reuse...) +} + +// ProtobufPushEncoder ... +type ProtobufPushEncoder struct { +} + +// NewProtobufPushEncoder ... +func NewProtobufPushEncoder() *ProtobufPushEncoder { + return &ProtobufPushEncoder{} +} + +// Encode Push to bytes. +func (e *ProtobufPushEncoder) Encode(message *Push) ([]byte, error) { + return message.MarshalVT() +} + +// EncodePublication to bytes. +func (e *ProtobufPushEncoder) EncodePublication(message *Publication, reuse ...[]byte) ([]byte, error) { + if len(reuse) == 1 { + size := message.SizeVT() + if cap(reuse[0]) >= size { + n, err := message.MarshalToSizedBufferVT(reuse[0][:size]) + if err != nil { + return nil, err + } + return reuse[0][:n], nil + } + } + return message.MarshalVT() +} + +// EncodeMessage to bytes. +func (e *ProtobufPushEncoder) EncodeMessage(message *Message, reuse ...[]byte) ([]byte, error) { + if len(reuse) == 1 { + size := message.SizeVT() + if cap(reuse[0]) >= size { + n, err := message.MarshalToSizedBufferVT(reuse[0][:size]) + if err != nil { + return nil, err + } + return reuse[0][:n], nil + } + } + return message.MarshalVT() +} + +// EncodeJoin to bytes. +func (e *ProtobufPushEncoder) EncodeJoin(message *Join, reuse ...[]byte) ([]byte, error) { + if len(reuse) == 1 { + size := message.SizeVT() + if cap(reuse[0]) >= size { + n, err := message.MarshalToSizedBufferVT(reuse[0][:size]) + if err != nil { + return nil, err + } + return reuse[0][:n], nil + } + } + return message.MarshalVT() +} + +// EncodeLeave to bytes. +func (e *ProtobufPushEncoder) EncodeLeave(message *Leave, reuse ...[]byte) ([]byte, error) { + if len(reuse) == 1 { + size := message.SizeVT() + if cap(reuse[0]) >= size { + n, err := message.MarshalToSizedBufferVT(reuse[0][:size]) + if err != nil { + return nil, err + } + return reuse[0][:n], nil + } + } + return message.MarshalVT() +} + +// EncodeUnsubscribe to bytes. +func (e *ProtobufPushEncoder) EncodeUnsubscribe(message *Unsubscribe, reuse ...[]byte) ([]byte, error) { + if len(reuse) == 1 { + size := message.SizeVT() + if cap(reuse[0]) >= size { + n, err := message.MarshalToSizedBufferVT(reuse[0][:size]) + if err != nil { + return nil, err + } + return reuse[0][:n], nil + } + } + return message.MarshalVT() +} + +// EncodeSubscribe to bytes. +func (e *ProtobufPushEncoder) EncodeSubscribe(message *Subscribe, reuse ...[]byte) ([]byte, error) { + if len(reuse) == 1 { + size := message.SizeVT() + if cap(reuse[0]) >= size { + n, err := message.MarshalToSizedBufferVT(reuse[0][:size]) + if err != nil { + return nil, err + } + return reuse[0][:n], nil + } + } + return message.MarshalVT() +} + +// EncodeConnect to bytes. +func (e *ProtobufPushEncoder) EncodeConnect(message *Connect, reuse ...[]byte) ([]byte, error) { + if len(reuse) == 1 { + size := message.SizeVT() + if cap(reuse[0]) >= size { + n, err := message.MarshalToSizedBufferVT(reuse[0][:size]) + if err != nil { + return nil, err + } + return reuse[0][:n], nil + } + } + return message.MarshalVT() +} + +// EncodeDisconnect to bytes. +func (e *ProtobufPushEncoder) EncodeDisconnect(message *Disconnect, reuse ...[]byte) ([]byte, error) { + if len(reuse) == 1 { + size := message.SizeVT() + if cap(reuse[0]) >= size { + n, err := message.MarshalToSizedBufferVT(reuse[0][:size]) + if err != nil { + return nil, err + } + return reuse[0][:n], nil + } + } + return message.MarshalVT() +} + +// EncodeRefresh to bytes. +func (e *ProtobufPushEncoder) EncodeRefresh(message *Refresh, reuse ...[]byte) ([]byte, error) { + if len(reuse) == 1 { + size := message.SizeVT() + if cap(reuse[0]) >= size { + n, err := message.MarshalToSizedBufferVT(reuse[0][:size]) + if err != nil { + return nil, err + } + return reuse[0][:n], nil + } + } + return message.MarshalVT() +} + +// ReplyEncoder ... +type ReplyEncoder interface { + Encode(*Reply) ([]byte, error) +} + +// JSONReplyEncoder ... +type JSONReplyEncoder struct{} + +// NewJSONReplyEncoder ... +func NewJSONReplyEncoder() *JSONReplyEncoder { + return &JSONReplyEncoder{} +} + +// Encode Reply to bytes. +func (e *JSONReplyEncoder) Encode(r *Reply) ([]byte, error) { + jw := newWriter() + r.MarshalEasyJSON(jw) + result, err := jw.BuildBytes() + if err != nil { + return nil, err + } + if err := isValidJSON(result); err != nil { + return nil, err + } + return result, nil +} + +//func (e *JSONReplyEncoder) EncodeNoCopy(r *Reply, _ []byte) ([]byte, error) { +// // No copy is not supported for JSON encoding. Just use Encode method, ignore pre-allocated buffer. +// return e.Encode(r) +//} + +// ProtobufReplyEncoder ... +type ProtobufReplyEncoder struct{} + +// NewProtobufReplyEncoder ... +func NewProtobufReplyEncoder() *ProtobufReplyEncoder { + return &ProtobufReplyEncoder{} +} + +// Encode Reply to bytes. +func (e *ProtobufReplyEncoder) Encode(r *Reply) ([]byte, error) { + return r.MarshalVT() +} + +//// EncodeNoCopy Reply to bytes without making copy of buffer byte slice. +//func (e *ProtobufReplyEncoder) EncodeNoCopy(r *Reply, buf []byte) ([]byte, error) { +// size := r.SizeVT() +// n, err := r.MarshalToSizedBufferVT(buf[:size]) +// if err != nil { +// return nil, err +// } +// return buf[:n], nil +//} + +// DataEncoder ... +type DataEncoder interface { + Reset() + Encode([]byte) error + Finish() []byte +} + +// JSONDataEncoder ... +type JSONDataEncoder struct { + count int + buffer bytes.Buffer +} + +// NewJSONDataEncoder ... +func NewJSONDataEncoder() *JSONDataEncoder { + return &JSONDataEncoder{} +} + +// Reset ... +func (e *JSONDataEncoder) Reset() { + e.count = 0 + e.buffer.Reset() +} + +// Encode ... +func (e *JSONDataEncoder) Encode(data []byte) error { + if e.count > 0 { + e.buffer.WriteString("\n") + } + e.buffer.Write(data) + e.count++ + return nil +} + +// Finish ... +func (e *JSONDataEncoder) Finish() []byte { + data := e.buffer.Bytes() + dataCopy := make([]byte, len(data)) + copy(dataCopy, data) + return dataCopy +} + +// ProtobufDataEncoder ... +type ProtobufDataEncoder struct { + buffer bytes.Buffer +} + +// NewProtobufDataEncoder ... +func NewProtobufDataEncoder() *ProtobufDataEncoder { + return &ProtobufDataEncoder{} +} + +// Encode ... +func (e *ProtobufDataEncoder) Encode(data []byte) error { + bs := make([]byte, 8) + n := binary.PutUvarint(bs, uint64(len(data))) + e.buffer.Write(bs[:n]) + e.buffer.Write(data) + return nil +} + +// Reset ... +func (e *ProtobufDataEncoder) Reset() { + e.buffer.Reset() +} + +// Finish ... +func (e *ProtobufDataEncoder) Finish() []byte { + data := e.buffer.Bytes() + dataCopy := make([]byte, len(data)) + copy(dataCopy, data) + return dataCopy +} + +// ResultEncoder ... +type ResultEncoder interface { + EncodeConnectResult(*ConnectResult) ([]byte, error) + EncodeRefreshResult(*RefreshResult) ([]byte, error) + EncodeSubscribeResult(*SubscribeResult) ([]byte, error) + EncodeSubRefreshResult(*SubRefreshResult) ([]byte, error) + EncodeUnsubscribeResult(*UnsubscribeResult) ([]byte, error) + EncodePublishResult(*PublishResult) ([]byte, error) + EncodePresenceResult(*PresenceResult) ([]byte, error) + EncodePresenceStatsResult(*PresenceStatsResult) ([]byte, error) + EncodeHistoryResult(*HistoryResult) ([]byte, error) + EncodePingResult(*PingResult) ([]byte, error) + EncodeRPCResult(*RPCResult) ([]byte, error) +} + +// JSONResultEncoder ... +type JSONResultEncoder struct{} + +// NewJSONResultEncoder ... +func NewJSONResultEncoder() *JSONResultEncoder { + return &JSONResultEncoder{} +} + +// EncodeConnectResult ... +func (e *JSONResultEncoder) EncodeConnectResult(res *ConnectResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// EncodeRefreshResult ... +func (e *JSONResultEncoder) EncodeRefreshResult(res *RefreshResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// EncodeSubscribeResult ... +func (e *JSONResultEncoder) EncodeSubscribeResult(res *SubscribeResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// EncodeSubRefreshResult ... +func (e *JSONResultEncoder) EncodeSubRefreshResult(res *SubRefreshResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// EncodeUnsubscribeResult ... +func (e *JSONResultEncoder) EncodeUnsubscribeResult(res *UnsubscribeResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// EncodePublishResult ... +func (e *JSONResultEncoder) EncodePublishResult(res *PublishResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// EncodePresenceResult ... +func (e *JSONResultEncoder) EncodePresenceResult(res *PresenceResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// EncodePresenceStatsResult ... +func (e *JSONResultEncoder) EncodePresenceStatsResult(res *PresenceStatsResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// EncodeHistoryResult ... +func (e *JSONResultEncoder) EncodeHistoryResult(res *HistoryResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// EncodePingResult ... +func (e *JSONResultEncoder) EncodePingResult(res *PingResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// EncodeRPCResult ... +func (e *JSONResultEncoder) EncodeRPCResult(res *RPCResult) ([]byte, error) { + jw := newWriter() + res.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// ProtobufResultEncoder ... +type ProtobufResultEncoder struct{} + +// NewProtobufResultEncoder ... +func NewProtobufResultEncoder() *ProtobufResultEncoder { + return &ProtobufResultEncoder{} +} + +// EncodeConnectResult ... +func (e *ProtobufResultEncoder) EncodeConnectResult(res *ConnectResult) ([]byte, error) { + return res.MarshalVT() +} + +// EncodeRefreshResult ... +func (e *ProtobufResultEncoder) EncodeRefreshResult(res *RefreshResult) ([]byte, error) { + return res.MarshalVT() +} + +// EncodeSubscribeResult ... +func (e *ProtobufResultEncoder) EncodeSubscribeResult(res *SubscribeResult) ([]byte, error) { + return res.MarshalVT() +} + +// EncodeSubRefreshResult ... +func (e *ProtobufResultEncoder) EncodeSubRefreshResult(res *SubRefreshResult) ([]byte, error) { + return res.MarshalVT() +} + +// EncodeUnsubscribeResult ... +func (e *ProtobufResultEncoder) EncodeUnsubscribeResult(res *UnsubscribeResult) ([]byte, error) { + return res.MarshalVT() +} + +// EncodePublishResult ... +func (e *ProtobufResultEncoder) EncodePublishResult(res *PublishResult) ([]byte, error) { + return res.MarshalVT() +} + +// EncodePresenceResult ... +func (e *ProtobufResultEncoder) EncodePresenceResult(res *PresenceResult) ([]byte, error) { + return res.MarshalVT() +} + +// EncodePresenceStatsResult ... +func (e *ProtobufResultEncoder) EncodePresenceStatsResult(res *PresenceStatsResult) ([]byte, error) { + return res.MarshalVT() +} + +// EncodeHistoryResult ... +func (e *ProtobufResultEncoder) EncodeHistoryResult(res *HistoryResult) ([]byte, error) { + return res.MarshalVT() +} + +// EncodePingResult ... +func (e *ProtobufResultEncoder) EncodePingResult(res *PingResult) ([]byte, error) { + return res.MarshalVT() +} + +// EncodeRPCResult ... +func (e *ProtobufResultEncoder) EncodeRPCResult(res *RPCResult) ([]byte, error) { + return res.MarshalVT() +} + +// CommandEncoder ... +type CommandEncoder interface { + Encode(cmd *Command) ([]byte, error) +} + +// JSONCommandEncoder ... +type JSONCommandEncoder struct { +} + +// NewJSONCommandEncoder ... +func NewJSONCommandEncoder() *JSONCommandEncoder { + return &JSONCommandEncoder{} +} + +// Encode ... +func (e *JSONCommandEncoder) Encode(cmd *Command) ([]byte, error) { + jw := newWriter() + cmd.MarshalEasyJSON(jw) + return jw.BuildBytes() +} + +// ProtobufCommandEncoder ... +type ProtobufCommandEncoder struct { +} + +// NewProtobufCommandEncoder ... +func NewProtobufCommandEncoder() *ProtobufCommandEncoder { + return &ProtobufCommandEncoder{} +} + +// Encode ... +func (e *ProtobufCommandEncoder) Encode(cmd *Command) ([]byte, error) { + commandBytes, err := cmd.MarshalVT() + if err != nil { + return nil, err + } + bs := make([]byte, 8) + n := binary.PutUvarint(bs, uint64(len(commandBytes))) + var buf bytes.Buffer + buf.Write(bs[:n]) + buf.Write(commandBytes) + return buf.Bytes(), nil +} diff --git a/vendor/github.com/centrifugal/protocol/encode_writer.go b/vendor/github.com/centrifugal/protocol/encode_writer.go new file mode 100644 index 0000000000..fb028e7923 --- /dev/null +++ b/vendor/github.com/centrifugal/protocol/encode_writer.go @@ -0,0 +1,396 @@ +package protocol + +import ( + "strconv" + "unicode/utf8" + + "github.com/valyala/bytebufferpool" +) + +// Flags describe various encoding options. The behavior may be actually implemented in the encoder, but +// Flags field in writer is used to set and pass them around. +type flags int + +const ( + nilMapAsEmpty flags = 1 << iota // Encode nil map as '{}' rather than 'null'. + nilSliceAsEmpty // Encode nil slice as '[]' rather than 'null'. +) + +// writer is a JSON writer. +type writer struct { + Buffer *bytebufferpool.ByteBuffer + Flags flags + Error error + NoEscapeHTML bool +} + +func newWriter() *writer { + return &writer{ + Buffer: bytebufferpool.Get(), + } +} + +// BuildBytes returns writer data as a single byte slice. +func (w *writer) BuildBytes(reuse ...[]byte) ([]byte, error) { + if w.Error != nil { + return nil, w.Error + } + var ret []byte + size := w.Buffer.Len() + // If we got a buffer as argument and it is big enough, reuse it. + if len(reuse) == 1 && cap(reuse[0]) >= size { + ret = reuse[0][:0] + } else { + ret = make([]byte, 0, size) + } + ret = append(ret, w.Buffer.Bytes()...) + bytebufferpool.Put(w.Buffer) + // Make writer non-usable after building bytes - writes will panic. + w.Buffer = nil + return ret, nil +} + +// BuildBytesNoCopy returns writer data as a single byte slice and returns function to call when data is no longer needed. +func (w *writer) BuildBytesNoCopy() ([]byte, error) { + if w.Error != nil { + return nil, w.Error + } + buffer := w.Buffer + // Make writer non-usable after building bytes - writes will panic. + w.Buffer = nil + return buffer.Bytes(), nil +} + +// RawByte appends raw binary data to the buffer. +func (w *writer) RawByte(c byte) { + _ = w.Buffer.WriteByte(c) +} + +// RawString appends string to the buffer. +func (w *writer) RawString(s string) { + _, _ = w.Buffer.WriteString(s) +} + +// Raw appends raw binary data to the buffer or sets the error if it is given. Useful for +// calling with results of MarshalJSON-like functions. +func (w *writer) Raw(src []byte, err error) { + switch { + case w.Error != nil: + return + case err != nil: + w.Error = err + case len(src) > 0: + _, _ = w.Buffer.Write(src) + default: + w.RawString("null") + } +} + +func (w *writer) Uint32(n uint32) { + _, _ = w.Buffer.WriteString(strconv.FormatUint(uint64(n), 10)) +} + +func (w *writer) Uint64(n uint64) { + _, _ = w.Buffer.WriteString(strconv.FormatUint(n, 10)) +} + +func (w *writer) Int32(n int32) { + _, _ = w.Buffer.WriteString(strconv.FormatInt(int64(n), 10)) +} + +func (w *writer) Int64(n int64) { + _, _ = w.Buffer.WriteString(strconv.FormatInt(n, 10)) +} + +func (w *writer) Bool(v bool) { + if v { + _, _ = w.Buffer.Write([]byte(`true`)) + } else { + _, _ = w.Buffer.Write([]byte(`false`)) + } +} + +var hex = "0123456789abcdef" + +func (w *writer) String(s string) { + escapeHTML := !w.NoEscapeHTML + _ = w.Buffer.WriteByte('"') + start := 0 + for i := 0; i < len(s); { + if b := s[i]; b < utf8.RuneSelf { + if htmlSafeSet[b] || (!escapeHTML && safeSet[b]) { + i++ + continue + } + if start < i { + _, _ = w.Buffer.WriteString(s[start:i]) + } + _ = w.Buffer.WriteByte('\\') + switch b { + case '\\', '"': + _ = w.Buffer.WriteByte(b) + case '\n': + _ = w.Buffer.WriteByte('n') + case '\r': + _ = w.Buffer.WriteByte('r') + case '\t': + _ = w.Buffer.WriteByte('t') + default: + // This encodes bytes < 0x20 except for \t, \n and \r. + // If escapeHTML is set, it also escapes <, >, and & + // because they can lead to security holes when + // user-controlled strings are rendered into JSON + // and served to some browsers. + _, _ = w.Buffer.WriteString(`u00`) + _ = w.Buffer.WriteByte(hex[b>>4]) + _ = w.Buffer.WriteByte(hex[b&0xF]) + } + i++ + start = i + continue + } + c, size := utf8.DecodeRuneInString(s[i:]) + if c == utf8.RuneError && size == 1 { + if start < i { + _, _ = w.Buffer.WriteString(s[start:i]) + } + _, _ = w.Buffer.WriteString(`\ufffd`) + i += size + start = i + continue + } + // U+2028 is LINE SEPARATOR. + // U+2029 is PARAGRAPH SEPARATOR. + // They are both technically valid characters in JSON strings, + // but don't work in JSONP, which has to be evaluated as JavaScript, + // and can lead to security holes there. It is valid JSON to + // escape them, so we do so unconditionally. + // See http://timelessrepo.com/json-isnt-a-javascript-subset for discussion. + if c == '\u2028' || c == '\u2029' { + if start < i { + _, _ = w.Buffer.WriteString(s[start:i]) + } + _, _ = w.Buffer.WriteString(`\u202`) + _ = w.Buffer.WriteByte(hex[c&0xF]) + i += size + start = i + continue + } + i += size + } + if start < len(s) { + _, _ = w.Buffer.WriteString(s[start:]) + } + _ = w.Buffer.WriteByte('"') +} + +// safeSet holds the value true if the ASCII character with the given array +// position can be represented inside a JSON string without any further +// escaping. +// +// All values are true except for the ASCII control characters (0-31), the +// double quote ("), and the backslash character ("\"). +var safeSet = [utf8.RuneSelf]bool{ + ' ': true, + '!': true, + '"': false, + '#': true, + '$': true, + '%': true, + '&': true, + '\'': true, + '(': true, + ')': true, + '*': true, + '+': true, + ',': true, + '-': true, + '.': true, + '/': true, + '0': true, + '1': true, + '2': true, + '3': true, + '4': true, + '5': true, + '6': true, + '7': true, + '8': true, + '9': true, + ':': true, + ';': true, + '<': true, + '=': true, + '>': true, + '?': true, + '@': true, + 'A': true, + 'B': true, + 'C': true, + 'D': true, + 'E': true, + 'F': true, + 'G': true, + 'H': true, + 'I': true, + 'J': true, + 'K': true, + 'L': true, + 'M': true, + 'N': true, + 'O': true, + 'P': true, + 'Q': true, + 'R': true, + 'S': true, + 'T': true, + 'U': true, + 'V': true, + 'W': true, + 'X': true, + 'Y': true, + 'Z': true, + '[': true, + '\\': false, + ']': true, + '^': true, + '_': true, + '`': true, + 'a': true, + 'b': true, + 'c': true, + 'd': true, + 'e': true, + 'f': true, + 'g': true, + 'h': true, + 'i': true, + 'j': true, + 'k': true, + 'l': true, + 'm': true, + 'n': true, + 'o': true, + 'p': true, + 'q': true, + 'r': true, + 's': true, + 't': true, + 'u': true, + 'v': true, + 'w': true, + 'x': true, + 'y': true, + 'z': true, + '{': true, + '|': true, + '}': true, + '~': true, + '\u007f': true, +} + +// htmlSafeSet holds the value true if the ASCII character with the given +// array position can be safely represented inside a JSON string, embedded +// inside of HTML