[
  {
    "path": ".gitignore",
    "content": "examples/helloworld/greeter_client/greeter_client\nexamples/helloworld/greeter_server/greeter_server\nexamples/alloptions/alloptions\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: go\n\ngo:\n  - 1.13\n\nbefore_script:\n  - curl -sSL https://github.com/google/protobuf/releases/download/v3.12.1/protoc-3.12.1-linux-x86_64.zip -o protoc.zip\n  - sudo unzip -d /usr/local protoc.zip\n  - sudo chmod a+x /usr/local/bin/protoc\n  - sudo chmod -R a+rx /usr/local/include/google\n  - go get google.golang.org/protobuf/cmd/protoc-gen-go\n  - go install google.golang.org/protobuf/cmd/protoc-gen-go\n\nscript:\n  - go test ./...\n"
  },
  {
    "path": "AUTHORS",
    "content": "RapidLoop, Inc.\nChristophe de Vienne, Orus.io\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n"
  },
  {
    "path": "README.md",
    "content": "# nRPC\n\n[![Build Status](https://travis-ci.org/nats-rpc/nrpc.svg?branch=master)](https://travis-ci.org/nats-rpc/nrpc)\n\nnRPC is an RPC framework like [gRPC](https://grpc.io/), but for\n[NATS](https://nats.io/).\n\nIt can generate a Go client and server from the same .proto file that you'd\nuse to generate gRPC clients and servers. The server is generated as a NATS\n[MsgHandler](https://godoc.org/github.com/nats-io/nats.go#MsgHandler).\n\nThe [Specifications](https://github.com/nats-rpc/nrpc/wiki/Specifications) \ndescribes how nRPC translates protobuf services and methods into NATS patterns.\n\n## Why NATS?\n\nDoing RPC over NATS'\n[request-response model](http://nats.io/documentation/concepts/nats-req-rep/)\nhas some advantages over a gRPC model:\n\n- **Minimal service discovery**: The clients and servers only need to know the\n  endpoints of a NATS cluster. The clients do not need to discover the\n  endpoints of individual services they depend on.\n- **Load balancing without load balancers**: Stateless microservices can be\n  hosted redundantly and connected to the same NATS cluster. The incoming\n  requests can then be random-routed among these using NATS\n  [queueing](http://nats.io/documentation/concepts/nats-queueing/). There is\n  no need to setup a (high availability) load balancer per microservice.\n\nThe lunch is not always free, however. At scale, the NATS cluster itself can\nbecome a bottleneck. Features of gRPC like streaming and advanced auth are not\navailable.\n\nStill, NATS - and nRPC - offer much lower operational complexity if your\nscale and requirements fit.\n\nAt RapidLoop, we use this model for our [OpsDash](https://www.opsdash.com)\nSaaS product in production and are quite happy with it. nRPC is the third\niteration of an internal library.\n\n## Overview\n\nnRPC comes with a protobuf compiler plugin `protoc-gen-nrpc`, which generates\nGo code from a .proto file.\n\nGiven a .proto file like [helloworld.proto](https://github.com/grpc/grpc-go/blob/master/examples/helloworld/helloworld/helloworld.proto), the usage is like this:\n\n```\n$ ls\nhelloworld.proto\n$ protoc --go_out=. --nrpc_out=. helloworld.proto\n$ ls\nhelloworld.nrpc.go\thelloworld.pb.go\thelloworld.proto\n```\n\nThe .pb.go file, which contains the definitions for the message classes, is\ngenerated by the standard Go plugin for protoc. The .nrpc.go file, which\ncontains the definitions for a client, a server interface, and a NATS handler\nis generated by the nRPC plugin.\n\nHave a look at the generated and example files:\n\n- the service definition [helloworld.proto](https://github.com/nats-rpc/nrpc/tree/master/examples/helloworld/helloworld/helloworld.proto)\n- the generated nrpc go file [helloworld.nrpc.go](https://github.com/nats-rpc/nrpc/tree/master/examples/helloworld/helloworld/helloworld.nrpc.go)\n- an example server [greeter_server/main.go](https://github.com/nats-rpc/nrpc/tree/master/examples/helloworld/greeter_server/main.go)\n- an example client [greeter_client/main.go](https://github.com/nats-rpc/nrpc/tree/master/examples/helloworld/greeter_client/main.go)\n\n### How It Works\n\nThe .proto file defines messages (like HelloRequest and HelloReply in the\nexample) and services (Greeter) that have methods (SayHello).\n\nThe messages are generated as Go structs by the regular Go protobuf compiler\nplugin and gets written out to \\*.pb.go files.\n\nFor the rest, nRPC generates three logical pieces.\n\nThe first is a Go interface type (GreeterServer) which your actual\nmicroservice code should implement:\n\n```\n// This is what is contained in the .proto file\nservice Greeter {\n    rpc SayHello (HelloRequest) returns (HelloReply) {}\n}\n\n// This is the generated interface which you've to implement\ntype GreeterServer interface {\n    SayHello(ctx context.Context, req HelloRequest) (resp HelloReply, err error)\n}\n```\n\nThe second is a client (GreeterClient struct). This struct has\nmethods with appropriate types, that correspond to the service definition. The\nclient code will marshal and wrap the request object (HelloRequest) and do a\nNATS `Request`.\n\n```\n// The client is associated with a NATS connection.\nfunc NewGreeterClient(nc *nats.Conn) *GreeterClient {...}\n\n// And has properly typed methods that will marshal and perform a NATS request.\nfunc (c *GreeterClient) SayHello(req HelloRequest) (resp HelloReply, err error) {...}\n```\n\nThe third and final piece is the handler (GreeterHandler). Given a NATS\nconnection and a server implementation, it can accept NATS requests in the\nformat sent by the client above. It should be installed as a message handler for\na particular NATS subject (defaults to the name of the service) using the\nNATS Subscribe() or QueueSubscribe() methods. It will invoke the appropriate\nmethod of the GreeterServer interface upon receiving the appropriate request.\n\n```\n// A handler is associated with a NATS connection and a server implementation.\nfunc NewGreeterHandler(ctx context.Context, nc *nats.Conn, s GreeterServer) *GreeterHandler {...}\n\n// It has a method that can (should) be used as a NATS message handler.\nfunc (h *GreeterHandler) Handler(msg *nats.Msg) {...}\n```\n\nStanding up a microservice involves:\n\n- writing the .proto service definition file\n- generating the \\*.pb.go and \\*.nrpc.go files\n- implementing the server interface\n- writing a main app that will connect to NATS and start the handler ([see\n  example](https://github.com/nats-rpc/nrpc/blob/master/examples/helloworld/greeter_server/main.go))\n\nTo call the service:\n\n- import the package that contains the generated *.nrpc.go files\n- in the client code, connect to NATS\n- create a Caller object and call the methods as necessary ([see example](https://github.com/nats-rpc/nrpc/blob/master/examples/helloworld/greeter_client/main.go))\n\n## Features\n\nThe following wiki pages describe nRPC features in more detail:\n\n- [Load Balancing](https://github.com/nats-rpc/nrpc/wiki/Load-Balancing)\n- [Metrics Instrumentation](https://github.com/nats-rpc/nrpc/wiki/Metrics-Instrumentation)\n  using Prometheus\n\n## Installation\n\nnRPC needs Go 1.11 or higher. $GOPATH/bin needs to be in $PATH for the protoc\ninvocation to work. To generate code, you need the protobuf compiler (which\nyou can install from [here](https://github.com/google/protobuf/releases))\nand the nRPC protoc plugin.\n\nTo install the nRPC protoc plugin:\n\n```\n$ go install github.com/nats-rpc/nrpc/protoc-gen-nrpc@latest\n```\n\nTo build and run the example greeter_server:\n\n```\n$ go install github.com/nats-rpc/nrpc/examples/helloworld/greeter_server@latest\n$ greeter_server\nserver is running, ^C quits.\n```\n\nTo build and run the example greeter_client:\n\n```\n$ go install github.com/nats-rpc/nrpc/examples/helloworld/greeter_client@latest\n$ greeter_client\nGreeting: Hello world\n$\n```\n\n## Documentation\n\nTo learn more about describing gRPC services using .proto files, see [here](https://grpc.io/docs/guides/concepts.html).\nTo learn more about NATS, start with their [website](https://nats.io/). To\nlearn more about nRPC, um, read the source code.\n\n## Status\n\nnRPC is in alpha. This means that it will work, but APIs may change without\nnotice.\n\nCurrently there is support only for Go clients and servers.\n\nBuilt by RapidLoop. Released under Apache 2.0 license.\n"
  },
  {
    "path": "alloptions_test.go",
    "content": "package nrpc\n\nimport (\n\t//\"bytes\"\n\t//\"os\"\n\t\"os/exec\"\n\t\"testing\"\n\t//\"time\"\n)\n\nfunc TestAllOptionsExample(t *testing.T) {\n\t// make sure protoc-gen-nrpc is up to date\n\tinstallGenRPC := exec.Command(\"go\", \"install\", \"./protoc-gen-nrpc\")\n\tif out, err := installGenRPC.CombinedOutput(); err != nil {\n\t\tt.Fatal(\"Install protoc-gen-nrpc failed\", err, \":\\n\", string(out))\n\t}\n\t// generate the sources\n\tgenerate := exec.Command(\"go\", \"generate\", \"./examples/alloptions\")\n\tif out, err := generate.CombinedOutput(); err != nil {\n\t\tt.Fatal(\"Generate failed\", err, \":\\n\", string(out))\n\t}\n\t// build\n\tbuild := exec.Command(\"go\", \"build\",\n\t\t\"-o\", \"./examples/alloptions/alloptions\",\n\t\t\"./examples/alloptions\")\n\tif out, err := build.CombinedOutput(); err != nil {\n\t\tt.Fatal(\"Buid failed\", err, string(out))\n\t}\n}\n"
  },
  {
    "path": "examples/alloptions/alloptions.nrpc.go",
    "content": "// This code was autogenerated from alloptions.proto, do not edit.\npackage main\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"google.golang.org/protobuf/proto\"\n\t\"github.com/nats-io/nats.go\"\n\tgithub_com_nats_rpc_nrpc \"github.com/nats-rpc/nrpc\"\n\t\"github.com/nats-rpc/nrpc\"\n)\n\n// SvcCustomSubjectServer is the interface that providers of the service\n// SvcCustomSubject should implement.\ntype SvcCustomSubjectServer interface {\n\tMtSimpleReply(ctx context.Context, req *StringArg) (*SimpleStringReply, error)\n\tMtVoidReply(ctx context.Context, req *StringArg) (error)\n\tMtStreamedReply(ctx context.Context, req *StringArg, pushRep func(*SimpleStringReply)) (error)\n\tMtVoidReqStreamedReply(ctx context.Context, pushRep func(*SimpleStringReply)) (error)\n}\n\n// SvcCustomSubjectHandler provides a NATS subscription handler that can serve a\n// subscription using a given SvcCustomSubjectServer implementation.\ntype SvcCustomSubjectHandler struct {\n\tctx     context.Context\n\tworkers *nrpc.WorkerPool\n\tnc      nrpc.NatsConn\n\tserver  SvcCustomSubjectServer\n\n\tencodings []string\n}\n\nfunc NewSvcCustomSubjectHandler(ctx context.Context, nc nrpc.NatsConn, s SvcCustomSubjectServer) *SvcCustomSubjectHandler {\n\treturn &SvcCustomSubjectHandler{\n\t\tctx:    ctx,\n\t\tnc:     nc,\n\t\tserver: s,\n\n\t\tencodings: []string{\"protobuf\"},\n\t}\n}\n\nfunc NewSvcCustomSubjectConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s SvcCustomSubjectServer) *SvcCustomSubjectHandler {\n\treturn &SvcCustomSubjectHandler{\n\t\tworkers: workers,\n\t\tnc:      nc,\n\t\tserver:  s,\n\t}\n}\n\n// SetEncodings sets the output encodings when using a '*Publish' function\nfunc (h *SvcCustomSubjectHandler) SetEncodings(encodings []string) {\n\th.encodings = encodings\n}\n\nfunc (h *SvcCustomSubjectHandler) Subject() string {\n\treturn \"root.*.custom_subject.>\"\n}\n\nfunc (h *SvcCustomSubjectHandler) MtNoRequestPublish(pkginstance string, msg *SimpleStringReply) error {\n\tfor _, encoding := range h.encodings {\n\t\trawMsg, err := nrpc.Marshal(encoding, msg)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"SvcCustomSubjectHandler.MtNoRequestPublish: error marshaling the message: %s\", err)\n\t\t\treturn err\n\t\t}\n\t\tsubject := \"root.\" + pkginstance + \".\"+ \"custom_subject.\"+ \"mtnorequest\"\n\t\tif encoding != \"protobuf\" {\n\t\t\tsubject += \".\" + encoding\n\t\t}\n\t\tif err := h.nc.Publish(subject, rawMsg); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (h *SvcCustomSubjectHandler) Handler(msg *nats.Msg) {\n\tvar ctx context.Context\n\tif h.workers != nil {\n\t\tctx = h.workers.Context\n\t} else {\n\t\tctx = h.ctx\n\t}\n\trequest := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)\n\t// extract method name & encoding from subject\n\tpkgParams, _, name, tail, err := nrpc.ParseSubject(\n\t\t\"root\", 1, \"custom_subject\", 0, msg.Subject)\n\tif err != nil {\n\t\tlog.Printf(\"SvcCustomSubjectHanlder: SvcCustomSubject subject parsing failed: %v\", err)\n\t\treturn\n\t}\n\n\trequest.MethodName = name\n\trequest.SubjectTail = tail\n\trequest.SetPackageParam(\"instance\", pkgParams[0])\n\n\t// call handler and form response\n\tvar immediateError *nrpc.Error\n\tswitch name {\n\tcase \"mt_simple_reply\":\n\t\t_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"MtSimpleReplyHanlder: MtSimpleReply subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req StringArg\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"MtSimpleReplyHandler: MtSimpleReply request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n\t\t} else {\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\tinnerResp, err := h.server.MtSimpleReply(ctx, &req)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn innerResp, err\n\t\t\t}\n\t\t}\n\tcase \"mtvoidreply\":\n\t\t_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"MtVoidReplyHanlder: MtVoidReply subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req StringArg\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"MtVoidReplyHandler: MtVoidReply request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n\t\t} else {\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\tvar innerResp = &nrpc.Void{}\n\t\t\t\terr := h.server.MtVoidReply(ctx, &req)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn innerResp, err\n\t\t\t}\n\t\t}\n\tcase \"mtnorequest\":\n\t\t// MtNoRequest is a no-request method. Ignore it.\n\t\treturn\n\tcase \"mtstreamedreply\":\n\t\t_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"MtStreamedReplyHanlder: MtStreamedReply subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req StringArg\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"MtStreamedReplyHandler: MtStreamedReply request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n\t\t} else {\n\t\t\trequest.EnableStreamedReply()\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\terr := h.server.MtStreamedReply(ctx, &req, func(rep *SimpleStringReply){\n\t\t\t\t\trequest.SendStreamReply(rep)\n\t\t\t\t})\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\tcase \"mtvoidreqstreamedreply\":\n\t\t_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"MtVoidReqStreamedReplyHanlder: MtVoidReqStreamedReply subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req github_com_nats_rpc_nrpc.Void\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"MtVoidReqStreamedReplyHandler: MtVoidReqStreamedReply request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n\t\t} else {\n\t\t\trequest.EnableStreamedReply()\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\terr := h.server.MtVoidReqStreamedReply(ctx, func(rep *SimpleStringReply){\n\t\t\t\t\trequest.SendStreamReply(rep)\n\t\t\t\t})\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tlog.Printf(\"SvcCustomSubjectHandler: unknown name %q\", name)\n\t\timmediateError = &nrpc.Error{\n\t\t\tType: nrpc.Error_CLIENT,\n\t\t\tMessage: \"unknown name: \" + name,\n\t\t}\n\t}\n\tif immediateError == nil {\n\t\tif h.workers != nil {\n\t\t\t// Try queuing the request\n\t\t\tif err := h.workers.QueueRequest(request); err != nil {\n\t\t\t\tlog.Printf(\"nrpc: Error queuing the request: %s\", err)\n\t\t\t}\n\t\t} else {\n\t\t\t// Run the handler synchronously\n\t\t\trequest.RunAndReply()\n\t\t}\n\t}\n\n\tif immediateError != nil {\n\t\tif err := request.SendReply(nil, immediateError); err != nil {\n\t\t\tlog.Printf(\"SvcCustomSubjectHandler: SvcCustomSubject handler failed to publish the response: %s\", err)\n\t\t}\n\t} else {\n\t}\n}\n\ntype SvcCustomSubjectClient struct {\n\tnc      nrpc.NatsConn\n\tPkgSubject string\n\tPkgParaminstance string\n\tSubject string\n\tEncoding string\n\tTimeout time.Duration\n}\n\nfunc NewSvcCustomSubjectClient(nc nrpc.NatsConn, pkgParaminstance string) *SvcCustomSubjectClient {\n\treturn &SvcCustomSubjectClient{\n\t\tnc:      nc,\n\t\tPkgSubject: \"root\",\n\t\tPkgParaminstance: pkgParaminstance,\n\t\tSubject: \"custom_subject\",\n\t\tEncoding: \"protobuf\",\n\t\tTimeout: 5 * time.Second,\n\t}\n}\n\nfunc (c *SvcCustomSubjectClient) MtSimpleReply(req *StringArg) (*SimpleStringReply, error) {\n\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + \"mt_simple_reply\"\n\n\t// call\n\tvar resp = SimpleStringReply{}\n\tif err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &resp, nil\n}\n\nfunc (c *SvcCustomSubjectClient) MtSimpleReplyPoll(req *StringArg,maxreplies int, cb func (*SimpleStringReply) error,\n) (error) {\n\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + \"mt_simple_reply\"\n\n\tvar resp SimpleStringReply\n\n\terr := nrpc.Poll(req, &resp, c.nc, subject, c.Encoding, c.Timeout, maxreplies,\n\t\tfunc() error {\n\t\t\treturn cb(&resp)\n\t\t},\n\t)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (c *SvcCustomSubjectClient) MtVoidReply(req *StringArg) (error) {\n\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + \"mtvoidreply\"\n\n\t// call\n\tvar resp = github_com_nats_rpc_nrpc.Void{}\n\tif err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (c *SvcCustomSubjectClient) MtNoRequestSubject(\n\t\n) string {\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + \"mtnorequest\"\n\tif c.Encoding != \"protobuf\" {\n\t\tsubject += \".\" + c.Encoding\n\t}\n\treturn subject\n}\n\ntype SvcCustomSubjectMtNoRequestSubscription struct {\n\t*nats.Subscription\n\t\n\tencoding string\n}\n\nfunc (s *SvcCustomSubjectMtNoRequestSubscription) Next(timeout time.Duration) (next SimpleStringReply, err error) {\n\tmsg, err := s.Subscription.NextMsg(timeout)\n\tif err != nil {\n\t\treturn\n\t}\n\terr = nrpc.Unmarshal(s.encoding, msg.Data, &next)\n\treturn\n}\n\nfunc (c *SvcCustomSubjectClient) MtNoRequestSubscribeSync(\n\t\n) (sub *SvcCustomSubjectMtNoRequestSubscription, err error) {\n\tsubject := c.MtNoRequestSubject(\n\t\t\n\t)\n\tnatsSub, err := c.nc.SubscribeSync(subject)\n\tif err != nil {\n\t\treturn\n\t}\n\tsub = &SvcCustomSubjectMtNoRequestSubscription{natsSub, c.Encoding}\n\treturn\n}\n\nfunc (c *SvcCustomSubjectClient) MtNoRequestSubscribe(\n\t\n\thandler func (*SimpleStringReply),\n) (sub *nats.Subscription, err error) {\n\tsubject := c.MtNoRequestSubject(\n\t\t\n\t)\n\tsub, err = c.nc.Subscribe(subject, func(msg *nats.Msg){\n\t\tvar pmsg SimpleStringReply\n\t\terr := nrpc.Unmarshal(c.Encoding, msg.Data, &pmsg)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"SvcCustomSubjectClient.MtNoRequestSubscribe: Error decoding, %s\", err)\n\t\t\treturn\n\t\t}\n\t\thandler(&pmsg)\n\t})\n\treturn\n}\n\nfunc (c *SvcCustomSubjectClient) MtNoRequestSubscribeChan(\n\t\n) (<-chan *SimpleStringReply, *nats.Subscription, error) {\n\tch := make(chan *SimpleStringReply)\n\tsub, err := c.MtNoRequestSubscribe(func (msg *SimpleStringReply) {\n\t\tch <- msg\n\t})\n\treturn ch, sub, err\n}\n\nfunc (c *SvcCustomSubjectClient) MtStreamedReply(\n\tctx context.Context,\n\treq *StringArg,\n\tcb func (context.Context, *SimpleStringReply),\n) error {\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + \"mtstreamedreply\"\n\n\tsub, err := nrpc.StreamCall(ctx, c.nc, subject, req, c.Encoding, c.Timeout)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar res SimpleStringReply\n\tfor {\n\t\terr = sub.Next(&res)\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t\tcb(ctx, &res)\n\t}\n\tif err == nrpc.ErrEOS {\n\t\terr = nil\n\t}\n\treturn err\n}\n\nfunc (c *SvcCustomSubjectClient) MtVoidReqStreamedReply(\n\tctx context.Context,\n\tcb func (context.Context, *SimpleStringReply),\n) error {\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + \"mtvoidreqstreamedreply\"\n\n\tsub, err := nrpc.StreamCall(ctx, c.nc, subject, &nrpc.Void{}, c.Encoding, c.Timeout)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar res SimpleStringReply\n\tfor {\n\t\terr = sub.Next(&res)\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t\tcb(ctx, &res)\n\t}\n\tif err == nrpc.ErrEOS {\n\t\terr = nil\n\t}\n\treturn err\n}\n\n// SvcSubjectParamsServer is the interface that providers of the service\n// SvcSubjectParams should implement.\ntype SvcSubjectParamsServer interface {\n\tMtWithSubjectParams(ctx context.Context, mp1 string, mp2 string) (*SimpleStringReply, error)\n\tMtStreamedReplyWithSubjectParams(ctx context.Context, mp1 string, mp2 string, pushRep func(*SimpleStringReply)) (error)\n\tMtNoReply(ctx context.Context)\n}\n\n// SvcSubjectParamsHandler provides a NATS subscription handler that can serve a\n// subscription using a given SvcSubjectParamsServer implementation.\ntype SvcSubjectParamsHandler struct {\n\tctx     context.Context\n\tworkers *nrpc.WorkerPool\n\tnc      nrpc.NatsConn\n\tserver  SvcSubjectParamsServer\n\n\tencodings []string\n}\n\nfunc NewSvcSubjectParamsHandler(ctx context.Context, nc nrpc.NatsConn, s SvcSubjectParamsServer) *SvcSubjectParamsHandler {\n\treturn &SvcSubjectParamsHandler{\n\t\tctx:    ctx,\n\t\tnc:     nc,\n\t\tserver: s,\n\n\t\tencodings: []string{\"protobuf\"},\n\t}\n}\n\nfunc NewSvcSubjectParamsConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s SvcSubjectParamsServer) *SvcSubjectParamsHandler {\n\treturn &SvcSubjectParamsHandler{\n\t\tworkers: workers,\n\t\tnc:      nc,\n\t\tserver:  s,\n\t}\n}\n\n// SetEncodings sets the output encodings when using a '*Publish' function\nfunc (h *SvcSubjectParamsHandler) SetEncodings(encodings []string) {\n\th.encodings = encodings\n}\n\nfunc (h *SvcSubjectParamsHandler) Subject() string {\n\treturn \"root.*.svcsubjectparams.*.>\"\n}\n\nfunc (h *SvcSubjectParamsHandler) MtNoRequestWParamsPublish(pkginstance string, svcclientid string, mtmp1 string, msg *SimpleStringReply) error {\n\tfor _, encoding := range h.encodings {\n\t\trawMsg, err := nrpc.Marshal(encoding, msg)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"SvcSubjectParamsHandler.MtNoRequestWParamsPublish: error marshaling the message: %s\", err)\n\t\t\treturn err\n\t\t}\n\t\tsubject := \"root.\" + pkginstance + \".\"+ \"svcsubjectparams.\" + svcclientid + \".\"+ \"mtnorequestwparams\" + \".\" + mtmp1\n\t\tif encoding != \"protobuf\" {\n\t\t\tsubject += \".\" + encoding\n\t\t}\n\t\tif err := h.nc.Publish(subject, rawMsg); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc (h *SvcSubjectParamsHandler) Handler(msg *nats.Msg) {\n\tvar ctx context.Context\n\tif h.workers != nil {\n\t\tctx = h.workers.Context\n\t} else {\n\t\tctx = h.ctx\n\t}\n\trequest := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)\n\t// extract method name & encoding from subject\n\tpkgParams, svcParams, name, tail, err := nrpc.ParseSubject(\n\t\t\"root\", 1, \"svcsubjectparams\", 1, msg.Subject)\n\tif err != nil {\n\t\tlog.Printf(\"SvcSubjectParamsHanlder: SvcSubjectParams subject parsing failed: %v\", err)\n\t\treturn\n\t}\n\n\trequest.MethodName = name\n\trequest.SubjectTail = tail\n\trequest.SetPackageParam(\"instance\", pkgParams[0])\n\trequest.SetServiceParam(\"clientid\", svcParams[0])\n\n\t// call handler and form response\n\tvar immediateError *nrpc.Error\n\tswitch name {\n\tcase \"mtwithsubjectparams\":\n\t\tvar mtParams []string\n\t\tmtParams, request.Encoding, err = nrpc.ParseSubjectTail(2, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"MtWithSubjectParamsHanlder: MtWithSubjectParams subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req github_com_nats_rpc_nrpc.Void\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"MtWithSubjectParamsHandler: MtWithSubjectParams request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n\t\t} else {\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\tinnerResp, err := h.server.MtWithSubjectParams(ctx, mtParams[0], mtParams[1])\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn innerResp, err\n\t\t\t}\n\t\t}\n\tcase \"mtstreamedreplywithsubjectparams\":\n\t\tvar mtParams []string\n\t\tmtParams, request.Encoding, err = nrpc.ParseSubjectTail(2, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"MtStreamedReplyWithSubjectParamsHanlder: MtStreamedReplyWithSubjectParams subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req github_com_nats_rpc_nrpc.Void\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"MtStreamedReplyWithSubjectParamsHandler: MtStreamedReplyWithSubjectParams request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n\t\t} else {\n\t\t\trequest.EnableStreamedReply()\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\terr := h.server.MtStreamedReplyWithSubjectParams(ctx, mtParams[0], mtParams[1], func(rep *SimpleStringReply){\n\t\t\t\t\trequest.SendStreamReply(rep)\n\t\t\t\t})\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\tcase \"mtnoreply\":\n\t\trequest.NoReply = true\n\t\t_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"MtNoReplyHanlder: MtNoReply subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req github_com_nats_rpc_nrpc.Void\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"MtNoReplyHandler: MtNoReply request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n\t\t} else {\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){var innerResp = &nrpc.NoReply{}\n\t\t\t\th.server.MtNoReply(ctx)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn innerResp, err\n\t\t\t}\n\t\t}\n\tcase \"mtnorequestwparams\":\n\t\t// MtNoRequestWParams is a no-request method. Ignore it.\n\t\treturn\n\tdefault:\n\t\tlog.Printf(\"SvcSubjectParamsHandler: unknown name %q\", name)\n\t\timmediateError = &nrpc.Error{\n\t\t\tType: nrpc.Error_CLIENT,\n\t\t\tMessage: \"unknown name: \" + name,\n\t\t}\n\t}\n\tif immediateError == nil {\n\t\tif h.workers != nil {\n\t\t\t// Try queuing the request\n\t\t\tif err := h.workers.QueueRequest(request); err != nil {\n\t\t\t\tlog.Printf(\"nrpc: Error queuing the request: %s\", err)\n\t\t\t}\n\t\t} else {\n\t\t\t// Run the handler synchronously\n\t\t\trequest.RunAndReply()\n\t\t}\n\t}\n\n\tif immediateError != nil {\n\t\tif err := request.SendReply(nil, immediateError); err != nil {\n\t\t\tlog.Printf(\"SvcSubjectParamsHandler: SvcSubjectParams handler failed to publish the response: %s\", err)\n\t\t}\n\t} else {\n\t}\n}\n\ntype SvcSubjectParamsClient struct {\n\tnc      nrpc.NatsConn\n\tPkgSubject string\n\tPkgParaminstance string\n\tSubject string\n\tSvcParamclientid string\n\tEncoding string\n\tTimeout time.Duration\n}\n\nfunc NewSvcSubjectParamsClient(nc nrpc.NatsConn, pkgParaminstance string, svcParamclientid string) *SvcSubjectParamsClient {\n\treturn &SvcSubjectParamsClient{\n\t\tnc:      nc,\n\t\tPkgSubject: \"root\",\n\t\tPkgParaminstance: pkgParaminstance,\n\t\tSubject: \"svcsubjectparams\",\n\t\tSvcParamclientid: svcParamclientid,\n\t\tEncoding: \"protobuf\",\n\t\tTimeout: 5 * time.Second,\n\t}\n}\n\nfunc (c *SvcSubjectParamsClient) MtWithSubjectParams(mp1 string, mp2 string, ) (*SimpleStringReply, error) {\n\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + c.SvcParamclientid + \".\" + \"mtwithsubjectparams\" + \".\" + mp1 + \".\" + mp2\n\n\t// call\n\tvar req = &github_com_nats_rpc_nrpc.Void{}\n\tvar resp = SimpleStringReply{}\n\tif err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &resp, nil\n}\n\nfunc (c *SvcSubjectParamsClient) MtStreamedReplyWithSubjectParams(\n\tctx context.Context,mp1 string,mp2 string,\n\tcb func (context.Context, *SimpleStringReply),\n) error {\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + c.SvcParamclientid + \".\" + \"mtstreamedreplywithsubjectparams\" + \".\" + mp1 + \".\" + mp2\n\n\tsub, err := nrpc.StreamCall(ctx, c.nc, subject, &nrpc.Void{}, c.Encoding, c.Timeout)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvar res SimpleStringReply\n\tfor {\n\t\terr = sub.Next(&res)\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t\tcb(ctx, &res)\n\t}\n\tif err == nrpc.ErrEOS {\n\t\terr = nil\n\t}\n\treturn err\n}\n\nfunc (c *SvcSubjectParamsClient) MtNoReply() (error) {\n\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + c.SvcParamclientid + \".\" + \"mtnoreply\"\n\n\t// call\n\tvar req = &github_com_nats_rpc_nrpc.Void{}\n\tvar resp = github_com_nats_rpc_nrpc.NoReply{}\n\tif err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc (c *SvcSubjectParamsClient) MtNoRequestWParamsSubject(\n\tmtmp1 string,\n) string {\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + c.SvcParamclientid + \".\" + \"mtnorequestwparams\" + \".\" + mtmp1\n\tif c.Encoding != \"protobuf\" {\n\t\tsubject += \".\" + c.Encoding\n\t}\n\treturn subject\n}\n\ntype SvcSubjectParamsMtNoRequestWParamsSubscription struct {\n\t*nats.Subscription\n\t\n\tencoding string\n}\n\nfunc (s *SvcSubjectParamsMtNoRequestWParamsSubscription) Next(timeout time.Duration) (next SimpleStringReply, err error) {\n\tmsg, err := s.Subscription.NextMsg(timeout)\n\tif err != nil {\n\t\treturn\n\t}\n\terr = nrpc.Unmarshal(s.encoding, msg.Data, &next)\n\treturn\n}\n\nfunc (c *SvcSubjectParamsClient) MtNoRequestWParamsSubscribeSync(\n\tmtmp1 string,\n) (sub *SvcSubjectParamsMtNoRequestWParamsSubscription, err error) {\n\tsubject := c.MtNoRequestWParamsSubject(\n\t\tmtmp1,\n\t)\n\tnatsSub, err := c.nc.SubscribeSync(subject)\n\tif err != nil {\n\t\treturn\n\t}\n\tsub = &SvcSubjectParamsMtNoRequestWParamsSubscription{natsSub, c.Encoding}\n\treturn\n}\n\nfunc (c *SvcSubjectParamsClient) MtNoRequestWParamsSubscribe(\n\tmtmp1 string,\n\thandler func (*SimpleStringReply),\n) (sub *nats.Subscription, err error) {\n\tsubject := c.MtNoRequestWParamsSubject(\n\t\tmtmp1,\n\t)\n\tsub, err = c.nc.Subscribe(subject, func(msg *nats.Msg){\n\t\tvar pmsg SimpleStringReply\n\t\terr := nrpc.Unmarshal(c.Encoding, msg.Data, &pmsg)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"SvcSubjectParamsClient.MtNoRequestWParamsSubscribe: Error decoding, %s\", err)\n\t\t\treturn\n\t\t}\n\t\thandler(&pmsg)\n\t})\n\treturn\n}\n\nfunc (c *SvcSubjectParamsClient) MtNoRequestWParamsSubscribeChan(\n\tmtmp1 string,\n) (<-chan *SimpleStringReply, *nats.Subscription, error) {\n\tch := make(chan *SimpleStringReply)\n\tsub, err := c.MtNoRequestWParamsSubscribe(mtmp1, func (msg *SimpleStringReply) {\n\t\tch <- msg\n\t})\n\treturn ch, sub, err\n}\n\n// NoRequestServiceServer is the interface that providers of the service\n// NoRequestService should implement.\ntype NoRequestServiceServer interface {\n}\n\n// NoRequestServiceHandler provides a NATS subscription handler that can serve a\n// subscription using a given NoRequestServiceServer implementation.\ntype NoRequestServiceHandler struct {\n\tctx     context.Context\n\tworkers *nrpc.WorkerPool\n\tnc      nrpc.NatsConn\n\tserver  NoRequestServiceServer\n\n\tencodings []string\n}\n\nfunc NewNoRequestServiceHandler(ctx context.Context, nc nrpc.NatsConn, s NoRequestServiceServer) *NoRequestServiceHandler {\n\treturn &NoRequestServiceHandler{\n\t\tctx:    ctx,\n\t\tnc:     nc,\n\t\tserver: s,\n\n\t\tencodings: []string{\"protobuf\"},\n\t}\n}\n\nfunc NewNoRequestServiceConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s NoRequestServiceServer) *NoRequestServiceHandler {\n\treturn &NoRequestServiceHandler{\n\t\tworkers: workers,\n\t\tnc:      nc,\n\t\tserver:  s,\n\t}\n}\n\n// SetEncodings sets the output encodings when using a '*Publish' function\nfunc (h *NoRequestServiceHandler) SetEncodings(encodings []string) {\n\th.encodings = encodings\n}\n\nfunc (h *NoRequestServiceHandler) Subject() string {\n\treturn \"root.*.norequestservice.>\"\n}\n\nfunc (h *NoRequestServiceHandler) MtNoRequestPublish(pkginstance string, msg *SimpleStringReply) error {\n\tfor _, encoding := range h.encodings {\n\t\trawMsg, err := nrpc.Marshal(encoding, msg)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"NoRequestServiceHandler.MtNoRequestPublish: error marshaling the message: %s\", err)\n\t\t\treturn err\n\t\t}\n\t\tsubject := \"root.\" + pkginstance + \".\"+ \"norequestservice.\"+ \"mtnorequest\"\n\t\tif encoding != \"protobuf\" {\n\t\t\tsubject += \".\" + encoding\n\t\t}\n\t\tif err := h.nc.Publish(subject, rawMsg); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n\ntype NoRequestServiceClient struct {\n\tnc      nrpc.NatsConn\n\tPkgSubject string\n\tPkgParaminstance string\n\tSubject string\n\tEncoding string\n\tTimeout time.Duration\n}\n\nfunc NewNoRequestServiceClient(nc nrpc.NatsConn, pkgParaminstance string) *NoRequestServiceClient {\n\treturn &NoRequestServiceClient{\n\t\tnc:      nc,\n\t\tPkgSubject: \"root\",\n\t\tPkgParaminstance: pkgParaminstance,\n\t\tSubject: \"norequestservice\",\n\t\tEncoding: \"protobuf\",\n\t\tTimeout: 5 * time.Second,\n\t}\n}\n\nfunc (c *NoRequestServiceClient) MtNoRequestSubject(\n\t\n) string {\n\tsubject := c.PkgSubject + \".\" + c.PkgParaminstance + \".\" + c.Subject + \".\" + \"mtnorequest\"\n\tif c.Encoding != \"protobuf\" {\n\t\tsubject += \".\" + c.Encoding\n\t}\n\treturn subject\n}\n\ntype NoRequestServiceMtNoRequestSubscription struct {\n\t*nats.Subscription\n\t\n\tencoding string\n}\n\nfunc (s *NoRequestServiceMtNoRequestSubscription) Next(timeout time.Duration) (next SimpleStringReply, err error) {\n\tmsg, err := s.Subscription.NextMsg(timeout)\n\tif err != nil {\n\t\treturn\n\t}\n\terr = nrpc.Unmarshal(s.encoding, msg.Data, &next)\n\treturn\n}\n\nfunc (c *NoRequestServiceClient) MtNoRequestSubscribeSync(\n\t\n) (sub *NoRequestServiceMtNoRequestSubscription, err error) {\n\tsubject := c.MtNoRequestSubject(\n\t\t\n\t)\n\tnatsSub, err := c.nc.SubscribeSync(subject)\n\tif err != nil {\n\t\treturn\n\t}\n\tsub = &NoRequestServiceMtNoRequestSubscription{natsSub, c.Encoding}\n\treturn\n}\n\nfunc (c *NoRequestServiceClient) MtNoRequestSubscribe(\n\t\n\thandler func (*SimpleStringReply),\n) (sub *nats.Subscription, err error) {\n\tsubject := c.MtNoRequestSubject(\n\t\t\n\t)\n\tsub, err = c.nc.Subscribe(subject, func(msg *nats.Msg){\n\t\tvar pmsg SimpleStringReply\n\t\terr := nrpc.Unmarshal(c.Encoding, msg.Data, &pmsg)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"NoRequestServiceClient.MtNoRequestSubscribe: Error decoding, %s\", err)\n\t\t\treturn\n\t\t}\n\t\thandler(&pmsg)\n\t})\n\treturn\n}\n\nfunc (c *NoRequestServiceClient) MtNoRequestSubscribeChan(\n\t\n) (<-chan *SimpleStringReply, *nats.Subscription, error) {\n\tch := make(chan *SimpleStringReply)\n\tsub, err := c.MtNoRequestSubscribe(func (msg *SimpleStringReply) {\n\t\tch <- msg\n\t})\n\treturn ch, sub, err\n}\n\ntype Client struct {\n\tnc      nrpc.NatsConn\n\tdefaultEncoding string\n\tdefaultTimeout time.Duration\n\tpkgSubject string\n\tpkgParaminstance string\n\tSvcCustomSubject *SvcCustomSubjectClient\n\tSvcSubjectParams *SvcSubjectParamsClient\n\tNoRequestService *NoRequestServiceClient\n}\n\nfunc NewClient(nc nrpc.NatsConn, pkgParaminstance string) *Client {\n\tc := Client{\n\t\tnc: nc,\n\t\tdefaultEncoding: \"protobuf\",\n\t\tdefaultTimeout: 5*time.Second,\n\t\tpkgSubject: \"root\",\n\t\tpkgParaminstance: pkgParaminstance,\n\t}\n\tc.SvcCustomSubject = NewSvcCustomSubjectClient(nc, c.pkgParaminstance)\n\tc.NoRequestService = NewNoRequestServiceClient(nc, c.pkgParaminstance)\n\treturn &c\n}\n\nfunc (c *Client) SetEncoding(encoding string) {\n\tc.defaultEncoding = encoding\n\tif c.SvcCustomSubject != nil {\n\t\tc.SvcCustomSubject.Encoding = encoding\n\t}\n\tif c.SvcSubjectParams != nil {\n\t\tc.SvcSubjectParams.Encoding = encoding\n\t}\n\tif c.NoRequestService != nil {\n\t\tc.NoRequestService.Encoding = encoding\n\t}\n}\n\nfunc (c *Client) SetTimeout(t time.Duration) {\n\tc.defaultTimeout = t\n\tif c.SvcCustomSubject != nil {\n\t\tc.SvcCustomSubject.Timeout = t\n\t}\n\tif c.SvcSubjectParams != nil {\n\t\tc.SvcSubjectParams.Timeout = t\n\t}\n\tif c.NoRequestService != nil {\n\t\tc.NoRequestService.Timeout = t\n\t}\n}\n\nfunc (c *Client) SetSvcSubjectParamsParams(\n\tclientid string,\n) {\n\tc.SvcSubjectParams = NewSvcSubjectParamsClient(\n\t\tc.nc,\n\t\tc.pkgParaminstance,\n\t\tclientid,\n\t)\n\tc.SvcSubjectParams.Encoding = c.defaultEncoding\n\tc.SvcSubjectParams.Timeout = c.defaultTimeout\n}\n\nfunc (c *Client) NewSvcSubjectParams(\n\tclientid string,\n) *SvcSubjectParamsClient {\n\tclient := NewSvcSubjectParamsClient(\n\t\tc.nc,\n\t\tc.pkgParaminstance,\n\t\tclientid,\n\t)\n\tclient.Encoding = c.defaultEncoding\n\tclient.Timeout = c.defaultTimeout\n\treturn client\n}"
  },
  {
    "path": "examples/alloptions/alloptions.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.29.0\n// \tprotoc        v4.22.2\n// source: alloptions.proto\n\npackage main\n\nimport (\n\tnrpc \"github.com/nats-rpc/nrpc\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype StringArg struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tArg1 string `protobuf:\"bytes,1,opt,name=arg1,proto3\" json:\"arg1,omitempty\"`\n}\n\nfunc (x *StringArg) Reset() {\n\t*x = StringArg{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_alloptions_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *StringArg) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*StringArg) ProtoMessage() {}\n\nfunc (x *StringArg) ProtoReflect() protoreflect.Message {\n\tmi := &file_alloptions_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use StringArg.ProtoReflect.Descriptor instead.\nfunc (*StringArg) Descriptor() ([]byte, []int) {\n\treturn file_alloptions_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *StringArg) GetArg1() string {\n\tif x != nil {\n\t\treturn x.Arg1\n\t}\n\treturn \"\"\n}\n\ntype SimpleStringReply struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tReply string `protobuf:\"bytes,1,opt,name=reply,proto3\" json:\"reply,omitempty\"`\n}\n\nfunc (x *SimpleStringReply) Reset() {\n\t*x = SimpleStringReply{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_alloptions_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *SimpleStringReply) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*SimpleStringReply) ProtoMessage() {}\n\nfunc (x *SimpleStringReply) ProtoReflect() protoreflect.Message {\n\tmi := &file_alloptions_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use SimpleStringReply.ProtoReflect.Descriptor instead.\nfunc (*SimpleStringReply) Descriptor() ([]byte, []int) {\n\treturn file_alloptions_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *SimpleStringReply) GetReply() string {\n\tif x != nil {\n\t\treturn x.Reply\n\t}\n\treturn \"\"\n}\n\nvar File_alloptions_proto protoreflect.FileDescriptor\n\nvar file_alloptions_proto_rawDesc = []byte{\n\t0x0a, 0x10, 0x61, 0x6c, 0x6c, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72, 0x6f,\n\t0x74, 0x6f, 0x12, 0x04, 0x6d, 0x61, 0x69, 0x6e, 0x1a, 0x0f, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x6e,\n\t0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x1f, 0x0a, 0x09, 0x53, 0x74, 0x72,\n\t0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x72, 0x67, 0x31, 0x18, 0x01,\n\t0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x61, 0x72, 0x67, 0x31, 0x22, 0x29, 0x0a, 0x11, 0x53, 0x69,\n\t0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12,\n\t0x14, 0x0a, 0x05, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05,\n\t0x72, 0x65, 0x70, 0x6c, 0x79, 0x32, 0xeb, 0x02, 0x0a, 0x10, 0x53, 0x76, 0x63, 0x43, 0x75, 0x73,\n\t0x74, 0x6f, 0x6d, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x52, 0x0a, 0x0d, 0x4d, 0x74,\n\t0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0f, 0x2e, 0x6d, 0x61,\n\t0x69, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x1a, 0x17, 0x2e, 0x6d,\n\t0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,\n\t0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x17, 0x82, 0xb2, 0x19, 0x0f, 0x6d, 0x74, 0x5f, 0x73, 0x69,\n\t0x6d, 0x70, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x98, 0xb2, 0x19, 0x01, 0x12, 0x2c,\n\t0x0a, 0x0b, 0x4d, 0x74, 0x56, 0x6f, 0x69, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0f, 0x2e,\n\t0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x1a, 0x0a,\n\t0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x6f, 0x69, 0x64, 0x22, 0x00, 0x12, 0x39, 0x0a, 0x0b,\n\t0x4d, 0x74, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0f, 0x2e, 0x6e, 0x72,\n\t0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d,\n\t0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67,\n\t0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x0f, 0x4d, 0x74, 0x53, 0x74, 0x72,\n\t0x65, 0x61, 0x6d, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0f, 0x2e, 0x6d, 0x61, 0x69,\n\t0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x41, 0x72, 0x67, 0x1a, 0x17, 0x2e, 0x6d, 0x61,\n\t0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52,\n\t0x65, 0x70, 0x6c, 0x79, 0x22, 0x04, 0x90, 0xb2, 0x19, 0x01, 0x12, 0x43, 0x0a, 0x16, 0x4d, 0x74,\n\t0x56, 0x6f, 0x69, 0x64, 0x52, 0x65, 0x71, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x65, 0x64, 0x52,\n\t0x65, 0x70, 0x6c, 0x79, 0x12, 0x0a, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x6f, 0x69, 0x64,\n\t0x1a, 0x17, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74,\n\t0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x04, 0x90, 0xb2, 0x19, 0x01, 0x1a,\n\t0x12, 0xc2, 0xf3, 0x18, 0x0e, 0x63, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x5f, 0x73, 0x75, 0x62, 0x6a,\n\t0x65, 0x63, 0x74, 0x32, 0xbc, 0x02, 0x0a, 0x10, 0x53, 0x76, 0x63, 0x53, 0x75, 0x62, 0x6a, 0x65,\n\t0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x4a, 0x0a, 0x13, 0x4d, 0x74, 0x57, 0x69,\n\t0x74, 0x68, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12,\n\t0x0a, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x6f, 0x69, 0x64, 0x1a, 0x17, 0x2e, 0x6d, 0x61,\n\t0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52,\n\t0x65, 0x70, 0x6c, 0x79, 0x22, 0x0e, 0x8a, 0xb2, 0x19, 0x03, 0x6d, 0x70, 0x31, 0x8a, 0xb2, 0x19,\n\t0x03, 0x6d, 0x70, 0x32, 0x12, 0x5b, 0x0a, 0x20, 0x4d, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d,\n\t0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x57, 0x69, 0x74, 0x68, 0x53, 0x75, 0x62, 0x6a, 0x65,\n\t0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x0a, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e,\n\t0x56, 0x6f, 0x69, 0x64, 0x1a, 0x17, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70,\n\t0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x12, 0x8a,\n\t0xb2, 0x19, 0x03, 0x6d, 0x70, 0x31, 0x8a, 0xb2, 0x19, 0x03, 0x6d, 0x70, 0x32, 0x90, 0xb2, 0x19,\n\t0x01, 0x12, 0x28, 0x0a, 0x09, 0x4d, 0x74, 0x4e, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x0a,\n\t0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x56, 0x6f, 0x69, 0x64, 0x1a, 0x0d, 0x2e, 0x6e, 0x72, 0x70,\n\t0x63, 0x2e, 0x4e, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x12, 0x47, 0x0a, 0x12, 0x4d,\n\t0x74, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x57, 0x50, 0x61, 0x72, 0x61, 0x6d,\n\t0x73, 0x12, 0x0f, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65,\n\t0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65,\n\t0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x07, 0x8a, 0xb2, 0x19,\n\t0x03, 0x6d, 0x70, 0x31, 0x1a, 0x0c, 0xca, 0xf3, 0x18, 0x08, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74,\n\t0x69, 0x64, 0x32, 0x4d, 0x0a, 0x10, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x53,\n\t0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x39, 0x0a, 0x0b, 0x4d, 0x74, 0x4e, 0x6f, 0x52, 0x65,\n\t0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0f, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x4e, 0x6f, 0x52,\n\t0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x6d, 0x61, 0x69, 0x6e, 0x2e, 0x53, 0x69,\n\t0x6d, 0x70, 0x6c, 0x65, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22,\n\t0x00, 0x42, 0x24, 0x82, 0xb5, 0x18, 0x04, 0x72, 0x6f, 0x6f, 0x74, 0x8a, 0xb5, 0x18, 0x08, 0x69,\n\t0x6e, 0x73, 0x74, 0x61, 0x6e, 0x63, 0x65, 0x90, 0xb5, 0x18, 0x01, 0x98, 0xb5, 0x18, 0x01, 0x5a,\n\t0x06, 0x2e, 0x3b, 0x6d, 0x61, 0x69, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_alloptions_proto_rawDescOnce sync.Once\n\tfile_alloptions_proto_rawDescData = file_alloptions_proto_rawDesc\n)\n\nfunc file_alloptions_proto_rawDescGZIP() []byte {\n\tfile_alloptions_proto_rawDescOnce.Do(func() {\n\t\tfile_alloptions_proto_rawDescData = protoimpl.X.CompressGZIP(file_alloptions_proto_rawDescData)\n\t})\n\treturn file_alloptions_proto_rawDescData\n}\n\nvar file_alloptions_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_alloptions_proto_goTypes = []interface{}{\n\t(*StringArg)(nil),         // 0: main.StringArg\n\t(*SimpleStringReply)(nil), // 1: main.SimpleStringReply\n\t(*nrpc.NoRequest)(nil),    // 2: nrpc.NoRequest\n\t(*nrpc.Void)(nil),         // 3: nrpc.Void\n\t(*nrpc.NoReply)(nil),      // 4: nrpc.NoReply\n}\nvar file_alloptions_proto_depIdxs = []int32{\n\t0,  // 0: main.SvcCustomSubject.MtSimpleReply:input_type -> main.StringArg\n\t0,  // 1: main.SvcCustomSubject.MtVoidReply:input_type -> main.StringArg\n\t2,  // 2: main.SvcCustomSubject.MtNoRequest:input_type -> nrpc.NoRequest\n\t0,  // 3: main.SvcCustomSubject.MtStreamedReply:input_type -> main.StringArg\n\t3,  // 4: main.SvcCustomSubject.MtVoidReqStreamedReply:input_type -> nrpc.Void\n\t3,  // 5: main.SvcSubjectParams.MtWithSubjectParams:input_type -> nrpc.Void\n\t3,  // 6: main.SvcSubjectParams.MtStreamedReplyWithSubjectParams:input_type -> nrpc.Void\n\t3,  // 7: main.SvcSubjectParams.MtNoReply:input_type -> nrpc.Void\n\t2,  // 8: main.SvcSubjectParams.MtNoRequestWParams:input_type -> nrpc.NoRequest\n\t2,  // 9: main.NoRequestService.MtNoRequest:input_type -> nrpc.NoRequest\n\t1,  // 10: main.SvcCustomSubject.MtSimpleReply:output_type -> main.SimpleStringReply\n\t3,  // 11: main.SvcCustomSubject.MtVoidReply:output_type -> nrpc.Void\n\t1,  // 12: main.SvcCustomSubject.MtNoRequest:output_type -> main.SimpleStringReply\n\t1,  // 13: main.SvcCustomSubject.MtStreamedReply:output_type -> main.SimpleStringReply\n\t1,  // 14: main.SvcCustomSubject.MtVoidReqStreamedReply:output_type -> main.SimpleStringReply\n\t1,  // 15: main.SvcSubjectParams.MtWithSubjectParams:output_type -> main.SimpleStringReply\n\t1,  // 16: main.SvcSubjectParams.MtStreamedReplyWithSubjectParams:output_type -> main.SimpleStringReply\n\t4,  // 17: main.SvcSubjectParams.MtNoReply:output_type -> nrpc.NoReply\n\t1,  // 18: main.SvcSubjectParams.MtNoRequestWParams:output_type -> main.SimpleStringReply\n\t1,  // 19: main.NoRequestService.MtNoRequest:output_type -> main.SimpleStringReply\n\t10, // [10:20] is the sub-list for method output_type\n\t0,  // [0:10] is the sub-list for method input_type\n\t0,  // [0:0] is the sub-list for extension type_name\n\t0,  // [0:0] is the sub-list for extension extendee\n\t0,  // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_alloptions_proto_init() }\nfunc file_alloptions_proto_init() {\n\tif File_alloptions_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_alloptions_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*StringArg); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_alloptions_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*SimpleStringReply); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_alloptions_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   3,\n\t\t},\n\t\tGoTypes:           file_alloptions_proto_goTypes,\n\t\tDependencyIndexes: file_alloptions_proto_depIdxs,\n\t\tMessageInfos:      file_alloptions_proto_msgTypes,\n\t}.Build()\n\tFile_alloptions_proto = out.File\n\tfile_alloptions_proto_rawDesc = nil\n\tfile_alloptions_proto_goTypes = nil\n\tfile_alloptions_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "examples/alloptions/alloptions.proto",
    "content": "syntax = \"proto3\";\n\npackage main;\n\noption go_package = \".;main\";\n\nimport \"nrpc/nrpc.proto\";\n\noption (nrpc.packageSubject) = \"root\";\noption (nrpc.packageSubjectParams) = \"instance\";\n\noption (nrpc.serviceSubjectRule) = TOLOWER;\noption (nrpc.methodSubjectRule) = TOLOWER;\n\nservice SvcCustomSubject {\n    option (nrpc.serviceSubject) = 'custom_subject';\n\n    rpc MtSimpleReply(StringArg) returns (SimpleStringReply) {\n        option (nrpc.methodSubject) = \"mt_simple_reply\";\n        option (nrpc.pollingEnabled) = true;\n    }\n    rpc MtVoidReply(StringArg) returns (nrpc.Void) {}\n    rpc MtNoRequest(nrpc.NoRequest) returns (SimpleStringReply) {}\n\n    rpc MtStreamedReply(StringArg) returns (SimpleStringReply) {\n        option (nrpc.streamedReply) = true;\n    }\n    rpc MtVoidReqStreamedReply(nrpc.Void) returns (SimpleStringReply) {\n        option (nrpc.streamedReply) = true;\n    }\n}\n\nservice SvcSubjectParams {\n    option (nrpc.serviceSubjectParams) = \"clientid\";\n\n    rpc MtWithSubjectParams(nrpc.Void) returns (SimpleStringReply) {\n        option (nrpc.methodSubjectParams) = \"mp1\";\n        option (nrpc.methodSubjectParams) = \"mp2\";\n    }\n    rpc MtStreamedReplyWithSubjectParams(nrpc.Void) returns (SimpleStringReply) {\n        option (nrpc.streamedReply) = true;\n        option (nrpc.methodSubjectParams) = \"mp1\";\n        option (nrpc.methodSubjectParams) = \"mp2\";\n    }\n    rpc MtNoReply(nrpc.Void) returns (nrpc.NoReply) {}\n    rpc MtNoRequestWParams(nrpc.NoRequest) returns (SimpleStringReply) {\n        option (nrpc.methodSubjectParams) = \"mp1\";\n    }\n}\n\nservice NoRequestService {\n    rpc MtNoRequest(nrpc.NoRequest) returns (SimpleStringReply) {}\n}\n\nmessage StringArg {\n    string arg1 = 1;\n}\n\nmessage SimpleStringReply {\n    string reply = 1;\n}\n"
  },
  {
    "path": "examples/alloptions/alloptions_test.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"sync\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\t\"github.com/nats-rpc/nrpc\"\n\t\"github.com/stretchr/testify/require\"\n)\n\ntype TestingLogWriter struct {\n\tt *testing.T\n}\n\nfunc (w TestingLogWriter) Write(p []byte) (int, error) {\n\tw.t.Log(string(p))\n\treturn len(p), nil\n}\n\ntype BasicServerImpl struct {\n\tt        *testing.T\n\thandler  *SvcCustomSubjectHandler\n\thandler2 *SvcSubjectParamsHandler\n}\n\nfunc (s BasicServerImpl) MtSimpleReply(\n\tctx context.Context, args *StringArg,\n) (*SimpleStringReply, error) {\n\tif instance := nrpc.GetRequest(ctx).PackageParam(\"instance\"); instance != \"default\" {\n\t\ts.t.Errorf(\"Got an invalid package param instance: '%s'\", instance)\n\t}\n\treturn &SimpleStringReply{Reply: args.Arg1}, nil\n}\n\nfunc (s BasicServerImpl) MtVoidReply(\n\tctx context.Context, args *StringArg,\n) error {\n\tif args.GetArg1() == \"please fail\" {\n\t\treturn errors.New(\"Error\")\n\t}\n\treturn nil\n}\n\nfunc (s BasicServerImpl) MtStreamedReply(\n\tctx context.Context, req *StringArg, send func(rep *SimpleStringReply),\n) error {\n\tif req.GetArg1() == \"please fail\" {\n\t\tpanic(\"Failing\")\n\t}\n\tif req.GetArg1() == \"very long call\" {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-time.After(time.Minute):\n\t\t\ttime.Sleep(time.Minute)\n\t\t\treturn nil\n\t\t}\n\t}\n\ttime.Sleep(time.Second)\n\tsend(&SimpleStringReply{Reply: \"msg1\"})\n\ttime.Sleep(250 * time.Millisecond)\n\tsend(&SimpleStringReply{Reply: \"msg2\"})\n\ttime.Sleep(250 * time.Millisecond)\n\tsend(&SimpleStringReply{Reply: \"msg3\"})\n\ttime.Sleep(250 * time.Millisecond)\n\treturn nil\n}\n\nfunc (s BasicServerImpl) MtVoidReqStreamedReply(\n\tctx context.Context, send func(rep *SimpleStringReply),\n) error {\n\ttime.Sleep(2 * time.Second)\n\tsend(&SimpleStringReply{Reply: \"hi\"})\n\treturn nil\n}\n\nfunc (s BasicServerImpl) MtNoReply(ctx context.Context) {\n\ts.t.Log(\"Will publish to MtNoRequest\")\n\ts.handler.MtNoRequestPublish(\"default\", &SimpleStringReply{Reply: \"Hi there\"})\n\ts.handler2.MtNoRequestWParamsPublish(\"default\", \"me\", \"mtvalue\", &SimpleStringReply{Reply: \"Hi there\"})\n}\n\nfunc (s BasicServerImpl) MtWithSubjectParams(\n\tctx context.Context, mp1 string, mp2 string,\n) (*SimpleStringReply, error) {\n\tvar err error\n\tif mp1 != \"p1\" {\n\t\terr = fmt.Errorf(\"Expects method param mp1 = 'p1', got '%s'\", mp1)\n\t}\n\tif mp2 != \"p2\" {\n\t\terr = fmt.Errorf(\"Expects method param mp2 = 'p2', got '%s'\", mp2)\n\t}\n\treturn &SimpleStringReply{Reply: \"Hi\"}, err\n}\n\nfunc (s BasicServerImpl) MtStreamedReplyWithSubjectParams(\n\tctx context.Context, mp1 string, mp2 string, send func(rep *SimpleStringReply),\n) error {\n\tsend(&SimpleStringReply{Reply: mp1})\n\tsend(&SimpleStringReply{Reply: mp2})\n\treturn nil\n}\n\nfunc TestAll(t *testing.T) {\n\tc, err := nats.Connect(natsURL)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tlog.SetOutput(TestingLogWriter{t})\n\n\tt.Run(\"MultiProtocolPublish\", func(t *testing.T) {\n\t\tlog.SetOutput(TestingLogWriter{t})\n\t\thandler := NewSvcCustomSubjectHandler(context.Background(), c, BasicServerImpl{t, nil, nil})\n\t\thandler.SetEncodings([]string{\"protobuf\", \"json\"})\n\n\t\tc1 := NewSvcCustomSubjectClient(c, \"default\")\n\n\t\tfor _, protocol := range []string{\"protobuf\", \"json\"} {\n\t\t\tt.Run(protocol, func(t *testing.T) {\n\t\t\t\tc1.Encoding = protocol\n\t\t\t\tif protocol == \"protobuf\" {\n\t\t\t\t\trequire.Equal(t, \"root.default.custom_subject.mtnorequest\", c1.MtNoRequestSubject())\n\t\t\t\t} else {\n\t\t\t\t\trequire.Equal(t, \"root.default.custom_subject.mtnorequest.\"+protocol, c1.MtNoRequestSubject())\n\t\t\t\t}\n\t\t\t\tsub, err := c1.MtNoRequestSubscribeSync()\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\t\t\t\tdefer sub.Unsubscribe()\n\n\t\t\t\tif err := handler.MtNoRequestPublish(\n\t\t\t\t\t\"default\", &SimpleStringReply{Reply: \"test\"},\n\t\t\t\t); err != nil {\n\t\t\t\t\tt.Fatal(t)\n\t\t\t\t}\n\n\t\t\t\tmsg, err := sub.Next(time.Second)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\t\t\t\trequire.Equal(t, \"test\", msg.GetReply())\n\t\t\t})\n\t\t}\n\t})\n\n\tt.Run(\"NoConcurrency\", func(t *testing.T) {\n\t\tlog.SetOutput(TestingLogWriter{t})\n\t\thandler1 := NewSvcCustomSubjectHandler(context.Background(), c, BasicServerImpl{t, nil, nil})\n\t\timpl := BasicServerImpl{t, handler1, nil}\n\t\thandler2 := NewSvcSubjectParamsHandler(context.Background(), c, &impl)\n\t\timpl.handler2 = handler2\n\n\t\tif handler1.Subject() != \"root.*.custom_subject.>\" {\n\t\t\tt.Fatal(\"Invalid subject\", handler1.Subject())\n\t\t}\n\t\tif handler2.Subject() != \"root.*.svcsubjectparams.*.>\" {\n\t\t\tt.Fatal(\"Invalid subject\", handler2.Subject())\n\t\t}\n\n\t\tfor _, encoding := range []string{\"protobuf\", \"json\"} {\n\t\t\tt.Run(\"Encoding_\"+encoding, commonTests(c, handler1, handler2, encoding))\n\t\t}\n\t})\n\n\tt.Run(\"WithConcurrency\", func(t *testing.T) {\n\t\tlog.SetOutput(TestingLogWriter{t})\n\t\tpool := nrpc.NewWorkerPool(context.Background(), 2, 5, 4*time.Second)\n\n\t\thandler1 := NewSvcCustomSubjectConcurrentHandler(pool, c, BasicServerImpl{t, nil, nil})\n\t\timpl := BasicServerImpl{t, handler1, nil}\n\t\thandler2 := NewSvcSubjectParamsConcurrentHandler(pool, c, &impl)\n\t\timpl.handler2 = handler2\n\n\t\tif handler1.Subject() != \"root.*.custom_subject.>\" {\n\t\t\tt.Fatal(\"Invalid subject\", handler1.Subject())\n\t\t}\n\t\tif handler2.Subject() != \"root.*.svcsubjectparams.*.>\" {\n\t\t\tt.Fatal(\"Invalid subject\", handler2.Subject())\n\t\t}\n\n\t\tfor _, encoding := range []string{\"protobuf\", \"json\"} {\n\t\t\tt.Run(\"Encoding_\"+encoding, commonTests(c, handler1, handler2, encoding))\n\t\t}\n\n\t\t// Now a few tests very specific to concurrency handling\n\n\t\ts, err := c.QueueSubscribe(handler1.Subject(), \"queue\", handler1.Handler)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tdefer s.Unsubscribe()\n\t\ts, err = c.QueueSubscribe(handler2.Subject(), \"queue\", handler2.Handler)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tdefer s.Unsubscribe()\n\n\t\tc1 := NewSvcCustomSubjectClient(c, \"default\")\n\t\t// c2 := NewSvcSubjectParamsClient(c, \"default\", \"me\")\n\n\t\tt.Run(\"Concurrent Stream calls\", func(t *testing.T) {\n\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\tvar resList []string\n\t\t\tvar wg sync.WaitGroup\n\t\t\tresChan := make(chan string, 2)\n\t\t\tgo func() {\n\t\t\t\tfor r := range resChan {\n\t\t\t\t\tresList = append(resList, r)\n\t\t\t\t}\n\t\t\t}()\n\t\t\tfor i := 0; i != 2; i++ {\n\t\t\t\twg.Add(1)\n\t\t\t\tgo func() {\n\t\t\t\t\tdefer wg.Done()\n\t\t\t\t\terr := c1.MtStreamedReply(\n\t\t\t\t\t\tcontext.Background(),\n\t\t\t\t\t\t&StringArg{Arg1: \"arg\"},\n\t\t\t\t\t\tfunc(ctx context.Context, rep *SimpleStringReply) {\n\t\t\t\t\t\t\tfmt.Println(\"received\", rep)\n\t\t\t\t\t\t\tresChan <- rep.GetReply()\n\t\t\t\t\t\t})\n\t\t\t\t\tif err != nil {\n\t\t\t\t\t\tt.Error(err)\n\t\t\t\t\t}\n\t\t\t\t}()\n\t\t\t}\n\t\t\twg.Wait()\n\t\t\tclose(resChan)\n\n\t\t\texpectsStringSlice(t,\n\t\t\t\t[]string{\"msg1\", \"msg1\", \"msg2\", \"msg2\", \"msg3\", \"msg3\"},\n\t\t\t\tresList)\n\t\t})\n\n\t\tt.Run(\"Too many concurrent Stream calls\", func(t *testing.T) {\n\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\tpool.SetMaxPendingDuration(2 * time.Second)\n\t\t\tvar resList []string\n\t\t\tvar wg sync.WaitGroup\n\t\t\tresChan := make(chan string, 2)\n\t\t\tgo func() {\n\t\t\t\tfor r := range resChan {\n\t\t\t\t\tresList = append(resList, r)\n\t\t\t\t}\n\t\t\t}()\n\t\t\tfor i := 0; i != 7; i++ {\n\t\t\t\twg.Add(1)\n\t\t\t\ttime.Sleep(50 * time.Millisecond)\n\t\t\t\tgo func(i int) {\n\t\t\t\t\tdefer wg.Done()\n\t\t\t\t\terr := c1.MtStreamedReply(\n\t\t\t\t\t\tcontext.Background(),\n\t\t\t\t\t\t&StringArg{Arg1: \"arg\"},\n\t\t\t\t\t\tfunc(ctx context.Context, rep *SimpleStringReply) {\n\t\t\t\t\t\t\tfmt.Println(\"received\", rep)\n\t\t\t\t\t\t\tresChan <- rep.GetReply()\n\t\t\t\t\t\t})\n\t\t\t\t\tif i >= 4 {\n\t\t\t\t\t\tif nrpcErr, ok := err.(*nrpc.Error); !ok || nrpcErr.Type != nrpc.Error_SERVERTOOBUSY {\n\t\t\t\t\t\t\tt.Errorf(\"Should get a SERVERTOOBUSY error, got %v\", err)\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if err != nil {\n\t\t\t\t\t\tt.Errorf(\"Should succeed but got: %s\", err)\n\t\t\t\t\t}\n\t\t\t\t}(i)\n\t\t\t}\n\n\t\t\t// Wait so the 7 calls are already queued\n\t\t\ttime.Sleep(200 * time.Millisecond)\n\n\t\t\t// The 7th call should get a SERVERTOOBUSY error\n\t\t\terr := c1.MtStreamedReply(\n\t\t\t\tcontext.Background(),\n\t\t\t\t&StringArg{Arg1: \"arg\"},\n\t\t\t\tfunc(ctx context.Context, rep *SimpleStringReply) {\n\t\t\t\t\tfmt.Println(\"received\", rep)\n\t\t\t\t})\n\t\t\tif err == nil {\n\t\t\t\tt.Error(\"Should get an error\")\n\t\t\t} else if nrpcErr, ok := err.(*nrpc.Error); ok {\n\t\t\t\tif nrpcErr.Type != nrpc.Error_SERVERTOOBUSY {\n\t\t\t\t\tt.Errorf(\"Should get a SERVERTOOBUSY, got %v\", nrpcErr.Type)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tt.Errorf(\"Should get a nrpcError, got %v\", err)\n\t\t\t}\n\n\t\t\twg.Wait()\n\t\t\tclose(resChan)\n\t\t})\n\n\t\tpool.Close(time.Second)\n\t})\n}\n\nfunc commonTests(\n\tconn *nats.Conn,\n\thandler1 *SvcCustomSubjectHandler,\n\thandler2 *SvcSubjectParamsHandler,\n\tencoding string,\n) func(t *testing.T) {\n\treturn func(t *testing.T) {\n\t\thandler1.SetEncodings([]string{encoding})\n\t\thandler2.SetEncodings([]string{encoding})\n\t\ts, err := conn.QueueSubscribe(handler1.Subject(), \"queue\", handler1.Handler)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tdefer s.Unsubscribe()\n\t\ts, err = conn.QueueSubscribe(handler2.Subject(), \"queue\", handler2.Handler)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tdefer s.Unsubscribe()\n\n\t\tc1 := NewSvcCustomSubjectClient(conn, \"default\")\n\t\tc2 := NewSvcSubjectParamsClient(conn, \"default\", \"me\")\n\n\t\tc1.Encoding = encoding\n\t\tc2.Encoding = encoding\n\n\t\tr, err := c1.MtSimpleReply(&StringArg{Arg1: \"hi\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif r.GetReply() != \"hi\" {\n\t\t\tt.Error(\"Invalid reply:\", r.GetReply())\n\t\t}\n\n\t\tif err := c1.MtSimpleReplyPoll(&StringArg{Arg1: \"hi\"}, 1,\n\t\t\tfunc(r *SimpleStringReply) error {\n\t\t\t\tif r.GetReply() != \"hi\" {\n\t\t\t\t\treturn fmt.Errorf(\"Invalid reply: %s\", r.GetReply())\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tif err := c1.MtVoidReply(&StringArg{Arg1: \"hi\"}); err != nil {\n\t\t\tt.Error(\"Unexpected error:\", err)\n\t\t}\n\n\t\terr = c1.MtVoidReply(&StringArg{Arg1: \"please fail\"})\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error\")\n\t\t}\n\n\t\tt.Run(\"StreamedReply\", func(t *testing.T) {\n\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\tt.Run(\"Simple\", func(t *testing.T) {\n\t\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\t\tvar resList []string\n\t\t\t\terr := c1.MtStreamedReply(\n\t\t\t\t\tcontext.Background(),\n\t\t\t\t\t&StringArg{Arg1: \"arg\"},\n\t\t\t\t\tfunc(ctx context.Context, rep *SimpleStringReply) {\n\t\t\t\t\t\tfmt.Println(\"received\", rep)\n\t\t\t\t\t\tresList = append(resList, rep.GetReply())\n\t\t\t\t\t})\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Fatal(err)\n\t\t\t\t}\n\t\t\t\tif resList[0] != \"msg1\" {\n\t\t\t\t\tt.Errorf(\"Expected 'msg1', got '%s'\", resList[0])\n\t\t\t\t}\n\t\t\t\tif resList[1] != \"msg2\" {\n\t\t\t\t\tt.Errorf(\"Expected 'msg2', got '%s'\", resList[1])\n\t\t\t\t}\n\t\t\t\tif resList[2] != \"msg3\" {\n\t\t\t\t\tt.Errorf(\"Expected 'msg3', got '%s'\", resList[2])\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tt.Run(\"Error\", func(t *testing.T) {\n\t\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\t\terr := c1.MtStreamedReply(context.Background(),\n\t\t\t\t\t&StringArg{Arg1: \"please fail\"},\n\t\t\t\t\tfunc(ctx context.Context, rep *SimpleStringReply) {\n\t\t\t\t\t\tt.Fatal(\"Should not receive anything\")\n\t\t\t\t\t})\n\t\t\t\tif err == nil {\n\t\t\t\t\tt.Fatal(\"Expected an error, got nil\")\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tt.Run(\"Cancel\", func(t *testing.T) {\n\t\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\t\tctx, cancel := context.WithTimeout(context.Background(), 7*time.Second)\n\t\t\t\tdefer cancel()\n\t\t\t\terr := c1.MtStreamedReply(ctx,\n\t\t\t\t\t&StringArg{Arg1: \"very long call\"},\n\t\t\t\t\tfunc(context.Context, *SimpleStringReply) {\n\t\t\t\t\t\tt.Fatal(\"Should not receive anything\")\n\t\t\t\t\t})\n\t\t\t\tif err != nrpc.ErrCanceled {\n\t\t\t\t\tt.Fatal(\"Expects a ErrCanceled error, got \", err)\n\t\t\t\t}\n\t\t\t})\n\n\t\t\tt.Run(\"VoidRequest\", func(t *testing.T) {\n\t\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\t\tctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)\n\t\t\t\tdefer cancel()\n\t\t\t\terr := c1.MtVoidReqStreamedReply(ctx, func(context.Context, *SimpleStringReply) {})\n\t\t\t\tif err != nil {\n\t\t\t\t\tfmt.Print(err)\n\t\t\t\t\tt.Error(err)\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\n\t\tt.Run(\"SubjectParams\", func(t *testing.T) {\n\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\tr, err = c2.MtWithSubjectParams(\"p1\", \"p2\")\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif r.GetReply() != \"Hi\" {\n\t\t\t\tt.Error(\"Invalid reply:\", r.GetReply())\n\t\t\t}\n\n\t\t\tr, err = c2.MtWithSubjectParams(\"invalid\", \"p2\")\n\t\t\tif err == nil {\n\t\t\t\tt.Error(\"Expected an error\")\n\t\t\t}\n\t\t\tif nErr, ok := err.(*nrpc.Error); ok {\n\t\t\t\tif nErr.Type != nrpc.Error_CLIENT || nErr.Message != \"Expects method param mp1 = 'p1', got 'invalid'\" {\n\t\t\t\t\tt.Errorf(\"Unexpected error %#v\", nErr)\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tt.Errorf(\"Expected a nrpc.Error, got %#v\", err)\n\t\t\t}\n\t\t})\n\n\t\tt.Run(\"StreamedReply with SubjectParams\", func(t *testing.T) {\n\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\tvar resList []string\n\t\t\terr := c2.MtStreamedReplyWithSubjectParams(\n\t\t\t\tcontext.Background(),\n\t\t\t\t\"arg1\", \"arg2\",\n\t\t\t\tfunc(ctx context.Context, rep *SimpleStringReply) {\n\t\t\t\t\tresList = append(resList, rep.GetReply())\n\t\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif resList[0] != \"arg1\" {\n\t\t\t\tt.Errorf(\"Expected 'arg1', got '%s'\", resList[0])\n\t\t\t}\n\t\t\tif resList[1] != \"arg2\" {\n\t\t\t\tt.Errorf(\"Expected 'arg2', got '%s'\", resList[1])\n\t\t\t}\n\t\t})\n\n\t\tt.Run(\"NoRequest method with params\", func(t *testing.T) {\n\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\tsub, err := c2.MtNoRequestWParamsSubscribeSync(\n\t\t\t\t\"mtvalue\",\n\t\t\t)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tdefer sub.Unsubscribe()\n\t\t\tc2.MtNoReply()\n\t\t\treply, err := sub.Next(time.Second)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif reply.GetReply() != \"Hi there\" {\n\t\t\t\tt.Errorf(\"Expected 'Hi there', got %s\", reply.GetReply())\n\t\t\t}\n\t\t})\n\t\tt.Run(\"NoRequest method subscriptions\", func(t *testing.T) {\n\t\t\tlog.SetOutput(TestingLogWriter{t})\n\t\t\tif encoding != \"protobuf\" {\n\t\t\t\tt.Skip()\n\t\t\t}\n\t\t\tfmt.Println(\"Subscribing\")\n\t\t\tsub1, err := c1.MtNoRequestSubscribeSync()\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tdefer sub1.Unsubscribe()\n\t\t\trepChan := make(chan string, 2)\n\t\t\tsub2, err := c1.MtNoRequestSubscribe(func(msg *SimpleStringReply) {\n\t\t\t\trepChan <- msg.GetReply()\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tdefer sub2.Unsubscribe()\n\t\t\tmsgChan, sub3, err := c1.MtNoRequestSubscribeChan()\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tdefer sub3.Unsubscribe()\n\t\t\tgo func() {\n\t\t\t\tmsg := <-msgChan\n\t\t\t\trepChan <- msg.GetReply()\n\t\t\t}()\n\n\t\t\terr = c2.MtNoReply()\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tmsg, err := sub1.Next(time.Second)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif msg.GetReply() != \"Hi there\" {\n\t\t\t\tt.Errorf(\"Expected 'Hi there', got '%s'\", msg.GetReply())\n\t\t\t}\n\t\t\tfor range []int{0, 1} {\n\t\t\t\tselect {\n\t\t\t\tcase rep := <-repChan:\n\t\t\t\t\tif rep != \"Hi there\" {\n\t\t\t\t\t\tt.Errorf(\"Expected 'Hi there', got '%s'\", rep)\n\t\t\t\t\t}\n\t\t\t\tcase <-time.After(time.Second):\n\t\t\t\t\tt.Fatal(\"timeout\")\n\t\t\t\t}\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc expectsStringSlice(t *testing.T, expected, actual []string) {\n\tif len(expected) != len(actual) {\n\t\tt.Errorf(\"Expected %v, got %v\", expected, actual)\n\t\treturn\n\t}\n\tfor i := range expected {\n\t\tif expected[i] != actual[i] {\n\t\t\tt.Errorf(\"Expected %v, got %v\", expected, actual)\n\t\t\treturn\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "examples/alloptions/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/signal\"\n\t\"syscall\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\t\"github.com/nats-rpc/nrpc\"\n)\n\n//go:generate protoc -I. -I ../../.. --go_out . --nrpc_out . alloptions.proto\n\ntype ServerImpl struct {\n\thandler  *SvcCustomSubjectHandler\n\thandler2 *SvcSubjectParamsHandler\n}\n\nfunc (s ServerImpl) MtSimpleReply(\n\tctx context.Context, args *StringArg,\n) (*SimpleStringReply, error) {\n\tfmt.Println(\"MtSimpleReply: \" + args.GetArg1())\n\tif instance := nrpc.GetRequest(ctx).PackageParam(\"instance\"); instance != \"default\" {\n\t\treturn nil, fmt.Errorf(\"Got an invalid package param instance: '%s'\", instance)\n\t}\n\treturn &SimpleStringReply{Reply: args.Arg1}, nil\n}\n\nfunc (s ServerImpl) MtVoidReply(\n\tctx context.Context, args *StringArg,\n) error {\n\tfmt.Println(\"MtVoidReply: \" + args.GetArg1())\n\tif args.GetArg1() == \"please fail\" {\n\t\treturn errors.New(\"Error\")\n\t}\n\treturn nil\n}\n\nfunc (s ServerImpl) MtStreamedReply(\n\tctx context.Context, req *StringArg, send func(rep *SimpleStringReply),\n) error {\n\tfmt.Println(\"MtStreamedReply: \" + req.GetArg1())\n\tif req.GetArg1() == \"please fail\" {\n\t\tpanic(\"Failing\")\n\t}\n\tif req.GetArg1() == \"very long call\" {\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn ctx.Err()\n\t\tcase <-time.After(time.Minute):\n\t\t\ttime.Sleep(time.Minute)\n\t\t\treturn nil\n\t\t}\n\t}\n\ttime.Sleep(time.Second)\n\tsend(&SimpleStringReply{Reply: \"msg1\"})\n\ttime.Sleep(250 * time.Millisecond)\n\tsend(&SimpleStringReply{Reply: \"msg2\"})\n\ttime.Sleep(250 * time.Millisecond)\n\tsend(&SimpleStringReply{Reply: \"msg3\"})\n\ttime.Sleep(250 * time.Millisecond)\n\treturn nil\n}\n\nfunc (s ServerImpl) MtVoidReqStreamedReply(\n\tctx context.Context, send func(rep *SimpleStringReply),\n) error {\n\tfmt.Println(\"MtVoidReqStreamedReply\")\n\ttime.Sleep(2 * time.Second)\n\tsend(&SimpleStringReply{Reply: \"hi\"})\n\treturn nil\n}\n\nfunc (s ServerImpl) MtNoReply(ctx context.Context) {\n\tfmt.Println(\"MtNoReply\")\n\tif err := s.handler.MtNoRequestPublish(\"default\", &SimpleStringReply{Reply: \"Hi there\"}); err != nil {\n\t\tfmt.Println(err)\n\t}\n\tif err := s.handler2.MtNoRequestWParamsPublish(\"default\", \"me\", \"mtvalue\", &SimpleStringReply{Reply: \"Hi there\"}); err != nil {\n\t\tfmt.Println(err)\n\t}\n}\n\nfunc (s ServerImpl) MtWithSubjectParams(\n\tctx context.Context, mp1 string, mp2 string,\n) (*SimpleStringReply, error) {\n\tfmt.Println(\"MtWithSubjectParams: \", mp1, mp2)\n\tvar err error\n\tif mp1 != \"p1\" {\n\t\terr = fmt.Errorf(\"Expects method param mp1 = 'p1', got '%s'\", mp1)\n\t}\n\tif mp2 != \"p2\" {\n\t\terr = fmt.Errorf(\"Expects method param mp2 = 'p2', got '%s'\", mp2)\n\t}\n\treturn &SimpleStringReply{Reply: \"Hi\"}, err\n}\n\nfunc (s ServerImpl) MtStreamedReplyWithSubjectParams(\n\tctx context.Context, mp1 string, mp2 string, send func(rep *SimpleStringReply),\n) error {\n\tfmt.Println(\"MtStreamedReplyWithSubjectParams: \", mp1, mp2)\n\tsend(&SimpleStringReply{Reply: mp1})\n\tsend(&SimpleStringReply{Reply: mp2})\n\treturn nil\n}\n\nfunc main() {\n\tc, err := nats.Connect(\"localhost:4222\")\n\tif err != nil {\n\t\tfmt.Println(err)\n\t\treturn\n\t}\n\n\tpool := nrpc.NewWorkerPool(context.Background(), 2, 5, 4*time.Second)\n\n\timpl := ServerImpl{nil, nil}\n\thandler1 := NewSvcCustomSubjectConcurrentHandler(pool, c, &impl)\n\thandler2 := NewSvcSubjectParamsConcurrentHandler(pool, c, &impl)\n\timpl.handler = handler1\n\timpl.handler2 = handler2\n\n\ts, err := c.QueueSubscribe(handler1.Subject(), \"queue\", handler1.Handler)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer s.Unsubscribe()\n\ts, err = c.QueueSubscribe(handler2.Subject(), \"queue\", handler2.Handler)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\tdefer s.Unsubscribe()\n\n\tdone := make(chan os.Signal, 1)\n\tsignal.Notify(done, syscall.SIGINT, syscall.SIGTERM)\n\tfmt.Println(\"Blocking, press ctrl+c to continue...\")\n\t<-done // Will block here until user hits ctrl+c\n}\n"
  },
  {
    "path": "examples/alloptions/testrunner_test.go",
    "content": "package main\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats-server/v2/logger\"\n\tnatsServer \"github.com/nats-io/nats-server/v2/server\"\n)\n\nvar natsURL string\n\nfunc TestMain(m *testing.M) {\n\tgnatsd := natsServer.New(&natsServer.Options{Port: natsServer.RANDOM_PORT})\n\tgnatsd.SetLogger(\n\t\tlogger.NewStdLogger(false, false, false, false, false),\n\t\tfalse, false)\n\tgo gnatsd.Start()\n\tdefer gnatsd.Shutdown()\n\n\tif !gnatsd.ReadyForConnections(time.Second) {\n\t\tlog.Fatal(\"Cannot start the gnatsd server\")\n\t}\n\tnatsURL = \"nats://\" + gnatsd.Addr().String()\n\n\tos.Exit(m.Run())\n}\n"
  },
  {
    "path": "examples/helloworld/greeter_client/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\n\t// This is the package containing the generated *.pb.go and *.nrpc.go\n\t// files.\n\t\"github.com/nats-rpc/nrpc/examples/helloworld/helloworld\"\n)\n\nfunc main() {\n\tvar natsURL = nats.DefaultURL\n\tif len(os.Args) == 2 {\n\t\tnatsURL = os.Args[1]\n\t}\n\t// Connect to the NATS server.\n\tnc, err := nats.Connect(natsURL, nats.Timeout(5*time.Second))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer nc.Close()\n\n\t// This is our generated client.\n\tcli := helloworld.NewGreeterClient(nc)\n\n\t// Contact the server and print out its response.\n\tresp, err := cli.SayHello(&helloworld.HelloRequest{Name: \"world\"})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// print\n\tfmt.Printf(\"Greeting: %s\\n\", resp.GetMessage())\n}\n"
  },
  {
    "path": "examples/helloworld/greeter_server/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"os/signal\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\n\t// This is the package containing the generated *.pb.go and *.nrpc.go\n\t// files.\n\t\"github.com/nats-rpc/nrpc/examples/helloworld/helloworld\"\n)\n\n// server implements the helloworld.GreeterServer interface.\ntype server struct{}\n\n// SayHello is an implementation of the SayHello method from the definition of\n// the Greeter service.\nfunc (s *server) SayHello(ctx context.Context, req *helloworld.HelloRequest) (resp *helloworld.HelloReply, err error) {\n\treturn &helloworld.HelloReply{Message: \"Hello \" + req.Name}, nil\n}\n\nfunc main() {\n\tvar natsURL = nats.DefaultURL\n\tif len(os.Args) == 2 {\n\t\tnatsURL = os.Args[1]\n\t}\n\t// Connect to the NATS server.\n\tnc, err := nats.Connect(natsURL, nats.Timeout(5*time.Second))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer nc.Close()\n\n\t// Our server implementation.\n\ts := &server{}\n\n\t// The NATS handler from the helloworld.nrpc.proto file.\n\th := helloworld.NewGreeterHandler(context.TODO(), nc, s)\n\n\t// Start a NATS subscription using the handler. You can also use the\n\t// QueueSubscribe() method for a load-balanced set of servers.\n\tsub, err := nc.Subscribe(h.Subject(), h.Handler)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer sub.Unsubscribe()\n\n\t// Keep running until ^C.\n\tfmt.Println(\"server is running, ^C quits.\")\n\tc := make(chan os.Signal, 1)\n\tsignal.Notify(c, os.Interrupt)\n\t<-c\n\tclose(c)\n}\n"
  },
  {
    "path": "examples/helloworld/greeter_server/main_test.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\n\t// This is the package containing the generated *.pb.go and *.nrpc.go\n\t// files.\n\t\"github.com/nats-rpc/nrpc/examples/helloworld/helloworld\"\n)\n\nfunc TestBasic(t *testing.T) {\n\t// Connect to the NATS server.\n\tnc, err := nats.Connect(natsURL, nats.Timeout(5*time.Second))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer nc.Close()\n\n\t// Our server implementation.\n\ts := &server{}\n\n\t// The NATS handler from the helloworld.nrpc.proto file.\n\th := helloworld.NewGreeterHandler(context.TODO(), nc, s)\n\n\t// Start a NATS subscription using the handler. You can also use the\n\t// QueueSubscribe() method for a load-balanced set of servers.\n\tsub, err := nc.Subscribe(h.Subject(), h.Handler)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer sub.Unsubscribe()\n\n\t// This is our generated client.\n\tcli := helloworld.NewGreeterClient(nc)\n\n\t// Contact the server and print out its response.\n\tresp, err := cli.SayHello(&helloworld.HelloRequest{Name: \"world\"})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif resp.GetMessage() != \"Hello world\" {\n\t\tt.Fatalf(\"unexpected message: %s\", resp.GetMessage())\n\t}\n}\n"
  },
  {
    "path": "examples/helloworld/greeter_server/testrunner_test.go",
    "content": "package main\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats-server/v2/logger\"\n\tnatsServer \"github.com/nats-io/nats-server/v2/server\"\n)\n\nvar natsURL string\n\nfunc TestMain(m *testing.M) {\n\tgnatsd := natsServer.New(&natsServer.Options{Port: natsServer.RANDOM_PORT})\n\tgnatsd.SetLogger(\n\t\tlogger.NewStdLogger(false, false, false, false, false),\n\t\tfalse, false)\n\tgo gnatsd.Start()\n\tdefer gnatsd.Shutdown()\n\n\tif !gnatsd.ReadyForConnections(time.Second) {\n\t\tlog.Fatal(\"Cannot start the gnatsd server\")\n\t}\n\tnatsURL = \"nats://\" + gnatsd.Addr().String()\n\n\tos.Exit(m.Run())\n}\n"
  },
  {
    "path": "examples/helloworld/helloworld/helloworld.go",
    "content": "package helloworld\n\n//go:generate protoc -I. -I../../.. --go_out . --go_opt=paths=source_relative --nrpc_out . --nrpc_opt=paths=source_relative helloworld.proto\n"
  },
  {
    "path": "examples/helloworld/helloworld/helloworld.nrpc.go",
    "content": "// This code was autogenerated from helloworld.proto, do not edit.\npackage helloworld\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"google.golang.org/protobuf/proto\"\n\t\"github.com/nats-io/nats.go\"\n\t\"github.com/nats-rpc/nrpc\"\n)\n\n// GreeterServer is the interface that providers of the service\n// Greeter should implement.\ntype GreeterServer interface {\n\tSayHello(ctx context.Context, req *HelloRequest) (*HelloReply, error)\n}\n\n// GreeterHandler provides a NATS subscription handler that can serve a\n// subscription using a given GreeterServer implementation.\ntype GreeterHandler struct {\n\tctx     context.Context\n\tworkers *nrpc.WorkerPool\n\tnc      nrpc.NatsConn\n\tserver  GreeterServer\n\n\tencodings []string\n}\n\nfunc NewGreeterHandler(ctx context.Context, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {\n\treturn &GreeterHandler{\n\t\tctx:    ctx,\n\t\tnc:     nc,\n\t\tserver: s,\n\n\t\tencodings: []string{\"protobuf\"},\n\t}\n}\n\nfunc NewGreeterConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {\n\treturn &GreeterHandler{\n\t\tworkers: workers,\n\t\tnc:      nc,\n\t\tserver:  s,\n\t}\n}\n\n// SetEncodings sets the output encodings when using a '*Publish' function\nfunc (h *GreeterHandler) SetEncodings(encodings []string) {\n\th.encodings = encodings\n}\n\nfunc (h *GreeterHandler) Subject() string {\n\treturn \"Greeter.>\"\n}\n\nfunc (h *GreeterHandler) Handler(msg *nats.Msg) {\n\tvar ctx context.Context\n\tif h.workers != nil {\n\t\tctx = h.workers.Context\n\t} else {\n\t\tctx = h.ctx\n\t}\n\trequest := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)\n\t// extract method name & encoding from subject\n\t_, _, name, tail, err := nrpc.ParseSubject(\n\t\t\"\", 0, \"Greeter\", 0, msg.Subject)\n\tif err != nil {\n\t\tlog.Printf(\"GreeterHanlder: Greeter subject parsing failed: %v\", err)\n\t\treturn\n\t}\n\n\trequest.MethodName = name\n\trequest.SubjectTail = tail\n\n\t// call handler and form response\n\tvar immediateError *nrpc.Error\n\tswitch name {\n\tcase \"SayHello\":\n\t\t_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"SayHelloHanlder: SayHello subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req HelloRequest\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"SayHelloHandler: SayHello request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n\t\t} else {\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\tinnerResp, err := h.server.SayHello(ctx, &req)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn innerResp, err\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tlog.Printf(\"GreeterHandler: unknown name %q\", name)\n\t\timmediateError = &nrpc.Error{\n\t\t\tType: nrpc.Error_CLIENT,\n\t\t\tMessage: \"unknown name: \" + name,\n\t\t}\n\t}\n\tif immediateError == nil {\n\t\tif h.workers != nil {\n\t\t\t// Try queuing the request\n\t\t\tif err := h.workers.QueueRequest(request); err != nil {\n\t\t\t\tlog.Printf(\"nrpc: Error queuing the request: %s\", err)\n\t\t\t}\n\t\t} else {\n\t\t\t// Run the handler synchronously\n\t\t\trequest.RunAndReply()\n\t\t}\n\t}\n\n\tif immediateError != nil {\n\t\tif err := request.SendReply(nil, immediateError); err != nil {\n\t\t\tlog.Printf(\"GreeterHandler: Greeter handler failed to publish the response: %s\", err)\n\t\t}\n\t} else {\n\t}\n}\n\ntype GreeterClient struct {\n\tnc      nrpc.NatsConn\n\tSubject string\n\tEncoding string\n\tTimeout time.Duration\n}\n\nfunc NewGreeterClient(nc nrpc.NatsConn) *GreeterClient {\n\treturn &GreeterClient{\n\t\tnc:      nc,\n\t\tSubject: \"Greeter\",\n\t\tEncoding: \"protobuf\",\n\t\tTimeout: 5 * time.Second,\n\t}\n}\n\nfunc (c *GreeterClient) SayHello(req *HelloRequest) (*HelloReply, error) {\n\n\tsubject := c.Subject + \".\" + \"SayHello\"\n\n\t// call\n\tvar resp = HelloReply{}\n\tif err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &resp, nil\n}\n\ntype Client struct {\n\tnc      nrpc.NatsConn\n\tdefaultEncoding string\n\tdefaultTimeout time.Duration\n\tGreeter *GreeterClient\n}\n\nfunc NewClient(nc nrpc.NatsConn) *Client {\n\tc := Client{\n\t\tnc: nc,\n\t\tdefaultEncoding: \"protobuf\",\n\t\tdefaultTimeout: 5*time.Second,\n\t}\n\tc.Greeter = NewGreeterClient(nc)\n\treturn &c\n}\n\nfunc (c *Client) SetEncoding(encoding string) {\n\tc.defaultEncoding = encoding\n\tif c.Greeter != nil {\n\t\tc.Greeter.Encoding = encoding\n\t}\n}\n\nfunc (c *Client) SetTimeout(t time.Duration) {\n\tc.defaultTimeout = t\n\tif c.Greeter != nil {\n\t\tc.Greeter.Timeout = t\n\t}\n}"
  },
  {
    "path": "examples/helloworld/helloworld/helloworld.pb.go",
    "content": "// Copyright 2015 gRPC authors.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.29.0\n// \tprotoc        v4.22.2\n// source: helloworld.proto\n\npackage helloworld\n\nimport (\n\t_ \"github.com/nats-rpc/nrpc\"\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\n// The request message containing the user's name.\ntype HelloRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n}\n\nfunc (x *HelloRequest) Reset() {\n\t*x = HelloRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_helloworld_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HelloRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HelloRequest) ProtoMessage() {}\n\nfunc (x *HelloRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_helloworld_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.\nfunc (*HelloRequest) Descriptor() ([]byte, []int) {\n\treturn file_helloworld_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *HelloRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\n// The response message containing the greetings\ntype HelloReply struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tMessage string `protobuf:\"bytes,1,opt,name=message,proto3\" json:\"message,omitempty\"`\n}\n\nfunc (x *HelloReply) Reset() {\n\t*x = HelloReply{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_helloworld_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HelloReply) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HelloReply) ProtoMessage() {}\n\nfunc (x *HelloReply) ProtoReflect() protoreflect.Message {\n\tmi := &file_helloworld_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use HelloReply.ProtoReflect.Descriptor instead.\nfunc (*HelloReply) Descriptor() ([]byte, []int) {\n\treturn file_helloworld_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *HelloReply) GetMessage() string {\n\tif x != nil {\n\t\treturn x.Message\n\t}\n\treturn \"\"\n}\n\nvar File_helloworld_proto protoreflect.FileDescriptor\n\nvar file_helloworld_proto_rawDesc = []byte{\n\t0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f,\n\t0x74, 0x6f, 0x12, 0x0a, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x1a, 0x0a,\n\t0x6e, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x22, 0x0a, 0x0c, 0x48, 0x65,\n\t0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,\n\t0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x26,\n\t0x0a, 0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07,\n\t0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d,\n\t0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x49, 0x0a, 0x07, 0x47, 0x72, 0x65, 0x65, 0x74, 0x65,\n\t0x72, 0x12, 0x3e, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x18, 0x2e,\n\t0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f,\n\t0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77,\n\t0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22,\n\t0x00, 0x42, 0x69, 0x0a, 0x1b, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x65, 0x78, 0x61,\n\t0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64,\n\t0x42, 0x0f, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x50, 0x72, 0x6f, 0x74,\n\t0x6f, 0x50, 0x01, 0x5a, 0x37, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,\n\t0x6e, 0x61, 0x74, 0x73, 0x2d, 0x72, 0x70, 0x63, 0x2f, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x65, 0x78,\n\t0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c,\n\t0x64, 0x2f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72,\n\t0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_helloworld_proto_rawDescOnce sync.Once\n\tfile_helloworld_proto_rawDescData = file_helloworld_proto_rawDesc\n)\n\nfunc file_helloworld_proto_rawDescGZIP() []byte {\n\tfile_helloworld_proto_rawDescOnce.Do(func() {\n\t\tfile_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_proto_rawDescData)\n\t})\n\treturn file_helloworld_proto_rawDescData\n}\n\nvar file_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_helloworld_proto_goTypes = []interface{}{\n\t(*HelloRequest)(nil), // 0: helloworld.HelloRequest\n\t(*HelloReply)(nil),   // 1: helloworld.HelloReply\n}\nvar file_helloworld_proto_depIdxs = []int32{\n\t0, // 0: helloworld.Greeter.SayHello:input_type -> helloworld.HelloRequest\n\t1, // 1: helloworld.Greeter.SayHello:output_type -> helloworld.HelloReply\n\t1, // [1:2] is the sub-list for method output_type\n\t0, // [0:1] is the sub-list for method input_type\n\t0, // [0:0] is the sub-list for extension type_name\n\t0, // [0:0] is the sub-list for extension extendee\n\t0, // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_helloworld_proto_init() }\nfunc file_helloworld_proto_init() {\n\tif File_helloworld_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HelloRequest); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HelloReply); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_helloworld_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_helloworld_proto_goTypes,\n\t\tDependencyIndexes: file_helloworld_proto_depIdxs,\n\t\tMessageInfos:      file_helloworld_proto_msgTypes,\n\t}.Build()\n\tFile_helloworld_proto = out.File\n\tfile_helloworld_proto_rawDesc = nil\n\tfile_helloworld_proto_goTypes = nil\n\tfile_helloworld_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "examples/helloworld/helloworld/helloworld.proto",
    "content": "// Copyright 2015 gRPC authors.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto3\";\n\noption java_multiple_files = true;\noption java_package = \"io.grpc.examples.helloworld\";\noption java_outer_classname = \"HelloWorldProto\";\n\nimport \"nrpc.proto\";\n\npackage helloworld;\n\noption go_package = \"github.com/nats-rpc/nrpc/examples/helloworld/helloworld\";\n\n// The greeting service definition.\nservice Greeter {\n  // Sends a greeting\n  rpc SayHello (HelloRequest) returns (HelloReply) {}\n}\n\n// The request message containing the user's name.\nmessage HelloRequest {\n  string name = 1;\n}\n\n// The response message containing the greetings\nmessage HelloReply {\n  string message = 1;\n}\n"
  },
  {
    "path": "examples/metrics_helloworld/helloworld/helloworld.go",
    "content": "package helloworld\n\n//go:generate protoc --go_out . --go_opt=paths=source_relative --nrpc_out plugins=prometheus:. --nrpc_opt=paths=source_relative helloworld.proto\n"
  },
  {
    "path": "examples/metrics_helloworld/helloworld/helloworld.nrpc.go",
    "content": "// This code was autogenerated from helloworld.proto, do not edit.\npackage helloworld\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"google.golang.org/protobuf/proto\"\n\t\"github.com/nats-io/nats.go\"\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t\"github.com/nats-rpc/nrpc\"\n)\n\n// GreeterServer is the interface that providers of the service\n// Greeter should implement.\ntype GreeterServer interface {\n\tSayHello(ctx context.Context, req HelloRequest) (resp HelloReply, err error)\n}\n\nvar (\n\t// The request completion time, measured at client-side.\n\tclientRCTForGreeter = prometheus.NewSummaryVec(\n\t\tprometheus.SummaryOpts{\n\t\t\tName:       \"nrpc_client_request_completion_time_seconds\",\n\t\t\tHelp:       \"The request completion time for calls, measured client-side.\",\n\t\t\tObjectives: map[float64]float64{0.9: 0.01, 0.95: 0.01, 0.99: 0.001},\n\t\t\tConstLabels: map[string]string{\n\t\t\t\t\"service\": \"Greeter\",\n\t\t\t},\n\t\t},\n\t\t[]string{\"method\"})\n\n\t// The handler execution time, measured at server-side.\n\tserverHETForGreeter = prometheus.NewSummaryVec(\n\t\tprometheus.SummaryOpts{\n\t\t\tName:       \"nrpc_server_handler_execution_time_seconds\",\n\t\t\tHelp:       \"The handler execution time for calls, measured server-side.\",\n\t\t\tObjectives: map[float64]float64{0.9: 0.01, 0.95: 0.01, 0.99: 0.001},\n\t\t\tConstLabels: map[string]string{\n\t\t\t\t\"service\": \"Greeter\",\n\t\t\t},\n\t\t},\n\t\t[]string{\"method\"})\n\n\t// The counts of calls made by the client, classified by result type.\n\tclientCallsForGreeter = prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tName: \"nrpc_client_calls_count\",\n\t\t\tHelp: \"The count of calls made by the client.\",\n\t\t\tConstLabels: map[string]string{\n\t\t\t\t\"service\": \"Greeter\",\n\t\t\t},\n\t\t},\n\t\t[]string{\"method\", \"encoding\", \"result_type\"})\n\n\t// The counts of requests handled by the server, classified by result type.\n\tserverRequestsForGreeter = prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tName: \"nrpc_server_requests_count\",\n\t\t\tHelp: \"The count of requests handled by the server.\",\n\t\t\tConstLabels: map[string]string{\n\t\t\t\t\"service\": \"Greeter\",\n\t\t\t},\n\t\t},\n\t\t[]string{\"method\", \"encoding\", \"result_type\"})\n)\n\n// GreeterHandler provides a NATS subscription handler that can serve a\n// subscription using a given GreeterServer implementation.\ntype GreeterHandler struct {\n\tctx     context.Context\n\tworkers *nrpc.WorkerPool\n\tnc      nrpc.NatsConn\n\tserver  GreeterServer\n\n\tencodings []string\n}\n\nfunc NewGreeterHandler(ctx context.Context, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {\n\treturn &GreeterHandler{\n\t\tctx:    ctx,\n\t\tnc:     nc,\n\t\tserver: s,\n\n\t\tencodings: []string{\"protobuf\"},\n\t}\n}\n\nfunc NewGreeterConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {\n\treturn &GreeterHandler{\n\t\tworkers: workers,\n\t\tnc:      nc,\n\t\tserver:  s,\n\t}\n}\n\n// SetEncodings sets the output encodings when using a '*Publish' function\nfunc (h *GreeterHandler) SetEncodings(encodings []string) {\n\th.encodings = encodings\n}\n\nfunc (h *GreeterHandler) Subject() string {\n\treturn \"Greeter.>\"\n}\n\nfunc (h *GreeterHandler) Handler(msg *nats.Msg) {\n\tvar ctx context.Context\n\tif h.workers != nil {\n\t\tctx = h.workers.Context\n\t} else {\n\t\tctx = h.ctx\n\t}\n\trequest := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)\n\t// extract method name & encoding from subject\n\t_, _, name, tail, err := nrpc.ParseSubject(\n\t\t\"\", 0, \"Greeter\", 0, msg.Subject)\n\tif err != nil {\n\t\tlog.Printf(\"GreeterHanlder: Greeter subject parsing failed: %v\", err)\n\t\treturn\n\t}\n\n\trequest.MethodName = name\n\trequest.SubjectTail = tail\n\n\t// call handler and form response\n\tvar immediateError *nrpc.Error\n\tswitch name {\n\tcase \"SayHello\":\n\t\t_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"SayHelloHanlder: SayHello subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req HelloRequest\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"SayHelloHandler: SayHello request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n\t\t\tserverRequestsForGreeter.WithLabelValues(\n\t\t\t\t\"SayHello\", request.Encoding, \"unmarshal_fail\").Inc()\n\t\t} else {\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\tinnerResp, err := h.server.SayHello(ctx, req)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn &innerResp, err\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tlog.Printf(\"GreeterHandler: unknown name %q\", name)\n\t\timmediateError = &nrpc.Error{\n\t\t\tType: nrpc.Error_CLIENT,\n\t\t\tMessage: \"unknown name: \" + name,\n\t\t}\n\t\tserverRequestsForGreeter.WithLabelValues(\n\t\t\t\"Greeter\", request.Encoding, \"name_fail\").Inc()\n\t}\n\trequest.AfterReply = func(request *nrpc.Request, success, replySuccess bool) {\n\t\tif !replySuccess {\n\t\t\tserverRequestsForGreeter.WithLabelValues(\n\t\t\t\trequest.MethodName, request.Encoding, \"sendreply_fail\").Inc()\n\t\t}\n\t\tif success {\n\t\t\tserverRequestsForGreeter.WithLabelValues(\n\t\t\t\trequest.MethodName, request.Encoding, \"success\").Inc()\n\t\t} else {\n\t\t\tserverRequestsForGreeter.WithLabelValues(\n\t\t\t\trequest.MethodName, request.Encoding, \"handler_fail\").Inc()\n\t\t}\n\t\t// report metric to Prometheus\n\t\tserverHETForGreeter.WithLabelValues(request.MethodName).Observe(\n\t\t\trequest.Elapsed().Seconds())\n\t}\n\tif immediateError == nil {\n\t\tif h.workers != nil {\n\t\t\t// Try queuing the request\n\t\t\tif err := h.workers.QueueRequest(request); err != nil {\n\t\t\t\tlog.Printf(\"nrpc: Error queuing the request: %s\", err)\n\t\t\t}\n\t\t} else {\n\t\t\t// Run the handler synchronously\n\t\t\trequest.RunAndReply()\n\t\t}\n\t}\n\n\tif immediateError != nil {\n\t\tif err := request.SendReply(nil, immediateError); err != nil {\n\t\t\tlog.Printf(\"GreeterHandler: Greeter handler failed to publish the response: %s\", err)\n\t\t\tserverRequestsForGreeter.WithLabelValues(\n\t\t\t\trequest.MethodName, request.Encoding, \"handler_fail\").Inc()\n\t\t}\n\t\tserverHETForGreeter.WithLabelValues(request.MethodName).Observe(\n\t\t\trequest.Elapsed().Seconds())\n\t} else {\n\t}\n}\n\ntype GreeterClient struct {\n\tnc      nrpc.NatsConn\n\tSubject string\n\tEncoding string\n\tTimeout time.Duration\n}\n\nfunc NewGreeterClient(nc nrpc.NatsConn) *GreeterClient {\n\treturn &GreeterClient{\n\t\tnc:      nc,\n\t\tSubject: \"Greeter\",\n\t\tEncoding: \"protobuf\",\n\t\tTimeout: 5 * time.Second,\n\t}\n}\n\nfunc (c *GreeterClient) SayHello(req HelloRequest) (resp HelloReply, err error) {\n\tstart := time.Now()\n\n\tsubject := c.Subject + \".\" + \"SayHello\"\n\n\t// call\n\terr = nrpc.Call(&req, &resp, c.nc, subject, c.Encoding, c.Timeout)\n\tif err != nil {\n\t\tclientCallsForGreeter.WithLabelValues(\n\t\t\t\"SayHello\", c.Encoding, \"call_fail\").Inc()\n\t\treturn // already logged\n\t}\n\n\t// report total time taken to Prometheus\n\telapsed := time.Since(start).Seconds()\n\tclientRCTForGreeter.WithLabelValues(\"SayHello\").Observe(elapsed)\n\tclientCallsForGreeter.WithLabelValues(\n\t\t\"SayHello\", c.Encoding, \"success\").Inc()\n\n\treturn\n}\n\ntype Client struct {\n\tnc      nrpc.NatsConn\n\tdefaultEncoding string\n\tdefaultTimeout time.Duration\n\tGreeter *GreeterClient\n}\n\nfunc NewClient(nc nrpc.NatsConn) *Client {\n\tc := Client{\n\t\tnc: nc,\n\t\tdefaultEncoding: \"protobuf\",\n\t\tdefaultTimeout: 5*time.Second,\n\t}\n\tc.Greeter = NewGreeterClient(nc)\n\treturn &c\n}\n\nfunc (c *Client) SetEncoding(encoding string) {\n\tc.defaultEncoding = encoding\n\tif c.Greeter != nil {\n\t\tc.Greeter.Encoding = encoding\n\t}\n}\n\nfunc (c *Client) SetTimeout(t time.Duration) {\n\tc.defaultTimeout = t\n\tif c.Greeter != nil {\n\t\tc.Greeter.Timeout = t\n\t}\n}\n\nfunc init() {\n\t// register metrics for service Greeter\n\tprometheus.MustRegister(clientRCTForGreeter)\n\tprometheus.MustRegister(serverHETForGreeter)\n\tprometheus.MustRegister(clientCallsForGreeter)\n\tprometheus.MustRegister(serverRequestsForGreeter)\n}"
  },
  {
    "path": "examples/metrics_helloworld/helloworld/helloworld.pb.go",
    "content": "// Copyright 2015 gRPC authors.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.29.0\n// \tprotoc        v4.22.2\n// source: helloworld.proto\n\npackage helloworld\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\n// The request message containing the user's name.\ntype HelloRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n}\n\nfunc (x *HelloRequest) Reset() {\n\t*x = HelloRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_helloworld_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HelloRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HelloRequest) ProtoMessage() {}\n\nfunc (x *HelloRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_helloworld_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.\nfunc (*HelloRequest) Descriptor() ([]byte, []int) {\n\treturn file_helloworld_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *HelloRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\n// The response message containing the greetings\ntype HelloReply struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tMessage string `protobuf:\"bytes,1,opt,name=message,proto3\" json:\"message,omitempty\"`\n}\n\nfunc (x *HelloReply) Reset() {\n\t*x = HelloReply{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_helloworld_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HelloReply) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HelloReply) ProtoMessage() {}\n\nfunc (x *HelloReply) ProtoReflect() protoreflect.Message {\n\tmi := &file_helloworld_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use HelloReply.ProtoReflect.Descriptor instead.\nfunc (*HelloReply) Descriptor() ([]byte, []int) {\n\treturn file_helloworld_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *HelloReply) GetMessage() string {\n\tif x != nil {\n\t\treturn x.Message\n\t}\n\treturn \"\"\n}\n\nvar File_helloworld_proto protoreflect.FileDescriptor\n\nvar file_helloworld_proto_rawDesc = []byte{\n\t0x0a, 0x10, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x70, 0x72, 0x6f,\n\t0x74, 0x6f, 0x12, 0x0a, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x22, 0x22,\n\t0x0a, 0x0c, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12,\n\t0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,\n\t0x6d, 0x65, 0x22, 0x26, 0x0a, 0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79,\n\t0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x49, 0x0a, 0x07, 0x47, 0x72,\n\t0x65, 0x65, 0x74, 0x65, 0x72, 0x12, 0x3e, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c,\n\t0x6f, 0x12, 0x18, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48,\n\t0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x68, 0x65,\n\t0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65,\n\t0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x71, 0x0a, 0x1b, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63,\n\t0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2e, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77,\n\t0x6f, 0x72, 0x6c, 0x64, 0x42, 0x0f, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x57, 0x6f, 0x72, 0x6c, 0x64,\n\t0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,\n\t0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x61, 0x74, 0x73, 0x2d, 0x72, 0x70, 0x63, 0x2f, 0x6e, 0x72, 0x70,\n\t0x63, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x6d, 0x65, 0x74, 0x72, 0x69,\n\t0x63, 0x73, 0x5f, 0x68, 0x65, 0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x2f, 0x68, 0x65,\n\t0x6c, 0x6c, 0x6f, 0x77, 0x6f, 0x72, 0x6c, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_helloworld_proto_rawDescOnce sync.Once\n\tfile_helloworld_proto_rawDescData = file_helloworld_proto_rawDesc\n)\n\nfunc file_helloworld_proto_rawDescGZIP() []byte {\n\tfile_helloworld_proto_rawDescOnce.Do(func() {\n\t\tfile_helloworld_proto_rawDescData = protoimpl.X.CompressGZIP(file_helloworld_proto_rawDescData)\n\t})\n\treturn file_helloworld_proto_rawDescData\n}\n\nvar file_helloworld_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_helloworld_proto_goTypes = []interface{}{\n\t(*HelloRequest)(nil), // 0: helloworld.HelloRequest\n\t(*HelloReply)(nil),   // 1: helloworld.HelloReply\n}\nvar file_helloworld_proto_depIdxs = []int32{\n\t0, // 0: helloworld.Greeter.SayHello:input_type -> helloworld.HelloRequest\n\t1, // 1: helloworld.Greeter.SayHello:output_type -> helloworld.HelloReply\n\t1, // [1:2] is the sub-list for method output_type\n\t0, // [0:1] is the sub-list for method input_type\n\t0, // [0:0] is the sub-list for extension type_name\n\t0, // [0:0] is the sub-list for extension extendee\n\t0, // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_helloworld_proto_init() }\nfunc file_helloworld_proto_init() {\n\tif File_helloworld_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_helloworld_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HelloRequest); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_helloworld_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HelloReply); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_helloworld_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_helloworld_proto_goTypes,\n\t\tDependencyIndexes: file_helloworld_proto_depIdxs,\n\t\tMessageInfos:      file_helloworld_proto_msgTypes,\n\t}.Build()\n\tFile_helloworld_proto = out.File\n\tfile_helloworld_proto_rawDesc = nil\n\tfile_helloworld_proto_goTypes = nil\n\tfile_helloworld_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "examples/metrics_helloworld/helloworld/helloworld.proto",
    "content": "// Copyright 2015 gRPC authors.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\nsyntax = \"proto3\";\n\noption java_multiple_files = true;\noption java_package = \"io.grpc.examples.helloworld\";\noption java_outer_classname = \"HelloWorldProto\";\n\npackage helloworld;\n\noption go_package = \"github.com/nats-rpc/nrpc/examples/metrics_helloworld/helloworld\";\n\n// The greeting service definition.\nservice Greeter {\n  // Sends a greeting\n  rpc SayHello (HelloRequest) returns (HelloReply) {}\n}\n\n// The request message containing the user's name.\nmessage HelloRequest {\n  string name = 1;\n}\n\n// The response message containing the greetings\nmessage HelloReply {\n  string message = 1;\n}\n"
  },
  {
    "path": "examples/metrics_helloworld/metrics_greeter_client/main.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"log\"\n\t\"net/http\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\n\t// This is the package containing the generated *.pb.go and *.nrpc.go\n\t// files.\n\t\"github.com/nats-rpc/nrpc/examples/metrics_helloworld/helloworld\"\n\n\t// If you've used the prometheus plugin when generating the code, you\n\t// can import the HTTP handler of Prometheus to serve up the metrics.\n\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n)\n\nfunc main() {\n\t// Connect to the NATS server.\n\tnc, err := nats.Connect(nats.DefaultURL, nats.Timeout(5*time.Second))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer nc.Close()\n\n\t// This is our generated client.\n\tcli := helloworld.NewGreeterClient(nc)\n\n\t// Contact the server and print out its response.\n\tresp, err := cli.SayHello(helloworld.HelloRequest{Name: \"world\"})\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// print\n\tfmt.Printf(\"Greeting: %s\\n\", resp.Message)\n\n\t// Do this block only if you generated the code with the prometheus plugin.\n\tfmt.Println(\"Check metrics at http://localhost:6061/metrics. Hit ^C to exit.\")\n\thttp.Handle(\"/metrics\", promhttp.Handler())\n\thttp.ListenAndServe(\":6061\", nil)\n}\n"
  },
  {
    "path": "examples/metrics_helloworld/metrics_greeter_server/main.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"math/rand\"\n\t\"net/http\"\n\t\"os\"\n\t\"os/signal\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\n\t// This is the package containing the generated *.pb.go and *.nrpc.go\n\t// files.\n\t\"github.com/nats-rpc/nrpc/examples/metrics_helloworld/helloworld\"\n\n\t// If you've used the prometheus plugin when generating the code, you\n\t// can import the HTTP handler of Prometheus to serve up the metrics.\n\t\"github.com/prometheus/client_golang/prometheus/promhttp\"\n)\n\n// server implements the helloworld.GreeterServer interface.\ntype server struct{}\n\n// SayHello is an implementation of the SayHello method from the definition of\n// the Greeter service.\nfunc (s *server) SayHello(ctx context.Context, req helloworld.HelloRequest) (resp helloworld.HelloReply, err error) {\n\tresp.Message = \"Hello \" + req.Name\n\tif rand.Intn(10) < 7 { // will fail 70% of the time\n\t\terr = errors.New(\"random failure simulated\")\n\t}\n\ttime.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond) // random delay\n\treturn\n}\n\nfunc main() {\n\t// Connect to the NATS server.\n\tnc, err := nats.Connect(nats.DefaultURL, nats.Timeout(5*time.Second))\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer nc.Close()\n\n\t// Our server implementation.\n\ts := &server{}\n\trand.Seed(time.Now().UnixNano())\n\n\t// The NATS handler from the helloworld.nrpc.proto file.\n\th := helloworld.NewGreeterHandler(context.TODO(), nc, s)\n\n\t// Start a NATS subscription using the handler. You can also use the\n\t// QueueSubscribe() method for a load-balanced set of servers.\n\tsub, err := nc.Subscribe(h.Subject(), h.Handler)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\tdefer sub.Unsubscribe()\n\n\t// Do this block only if you generated the code with the prometheus plugin.\n\thttp.Handle(\"/metrics\", promhttp.Handler())\n\tgo http.ListenAndServe(\":6060\", nil)\n\n\t// Keep running until ^C.\n\tfmt.Println(\"server is running, ^C quits.\")\n\tc := make(chan os.Signal, 1)\n\tsignal.Notify(c, os.Interrupt)\n\t<-c\n\tclose(c)\n}\n"
  },
  {
    "path": "examples/nooption/nooption.go",
    "content": "package nooption\n\n//go:generate protoc --go_out . --go_opt=paths=source_relative --nrpc_out . --nrpc_opt=paths=source_relative nooption.proto\n"
  },
  {
    "path": "examples/nooption/nooption.nrpc.go",
    "content": "// This code was autogenerated from nooption.proto, do not edit.\npackage nooption\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"google.golang.org/protobuf/proto\"\n\t\"github.com/nats-io/nats.go\"\n\t\"github.com/nats-rpc/nrpc\"\n)\n\n// GreeterServer is the interface that providers of the service\n// Greeter should implement.\ntype GreeterServer interface {\n\tSayHello(ctx context.Context, req HelloRequest) (resp HelloReply, err error)\n}\n\n// GreeterHandler provides a NATS subscription handler that can serve a\n// subscription using a given GreeterServer implementation.\ntype GreeterHandler struct {\n\tctx     context.Context\n\tworkers *nrpc.WorkerPool\n\tnc      nrpc.NatsConn\n\tserver  GreeterServer\n\n\tencodings []string\n}\n\nfunc NewGreeterHandler(ctx context.Context, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {\n\treturn &GreeterHandler{\n\t\tctx:    ctx,\n\t\tnc:     nc,\n\t\tserver: s,\n\n\t\tencodings: []string{\"protobuf\"},\n\t}\n}\n\nfunc NewGreeterConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s GreeterServer) *GreeterHandler {\n\treturn &GreeterHandler{\n\t\tworkers: workers,\n\t\tnc:      nc,\n\t\tserver:  s,\n\t}\n}\n\n// SetEncodings sets the output encodings when using a '*Publish' function\nfunc (h *GreeterHandler) SetEncodings(encodings []string) {\n\th.encodings = encodings\n}\n\nfunc (h *GreeterHandler) Subject() string {\n\treturn \"Greeter.>\"\n}\n\nfunc (h *GreeterHandler) Handler(msg *nats.Msg) {\n\tvar ctx context.Context\n\tif h.workers != nil {\n\t\tctx = h.workers.Context\n\t} else {\n\t\tctx = h.ctx\n\t}\n\trequest := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)\n\t// extract method name & encoding from subject\n\t_, _, name, tail, err := nrpc.ParseSubject(\n\t\t\"\", 0, \"Greeter\", 0, msg.Subject)\n\tif err != nil {\n\t\tlog.Printf(\"GreeterHanlder: Greeter subject parsing failed: %v\", err)\n\t\treturn\n\t}\n\n\trequest.MethodName = name\n\trequest.SubjectTail = tail\n\n\t// call handler and form response\n\tvar immediateError *nrpc.Error\n\tswitch name {\n\tcase \"SayHello\":\n\t\t_, request.Encoding, err = nrpc.ParseSubjectTail(0, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"SayHelloHanlder: SayHello subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req HelloRequest\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"SayHelloHandler: SayHello request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n\t\t} else {\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\tinnerResp, err := h.server.SayHello(ctx, req)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn &innerResp, err\n\t\t\t}\n\t\t}\n\tdefault:\n\t\tlog.Printf(\"GreeterHandler: unknown name %q\", name)\n\t\timmediateError = &nrpc.Error{\n\t\t\tType: nrpc.Error_CLIENT,\n\t\t\tMessage: \"unknown name: \" + name,\n\t\t}\n\t}\n\tif immediateError == nil {\n\t\tif h.workers != nil {\n\t\t\t// Try queuing the request\n\t\t\tif err := h.workers.QueueRequest(request); err != nil {\n\t\t\t\tlog.Printf(\"nrpc: Error queuing the request: %s\", err)\n\t\t\t}\n\t\t} else {\n\t\t\t// Run the handler synchronously\n\t\t\trequest.RunAndReply()\n\t\t}\n\t}\n\n\tif immediateError != nil {\n\t\tif err := request.SendReply(nil, immediateError); err != nil {\n\t\t\tlog.Printf(\"GreeterHandler: Greeter handler failed to publish the response: %s\", err)\n\t\t}\n\t} else {\n\t}\n}\n\ntype GreeterClient struct {\n\tnc      nrpc.NatsConn\n\tSubject string\n\tEncoding string\n\tTimeout time.Duration\n}\n\nfunc NewGreeterClient(nc nrpc.NatsConn) *GreeterClient {\n\treturn &GreeterClient{\n\t\tnc:      nc,\n\t\tSubject: \"Greeter\",\n\t\tEncoding: \"protobuf\",\n\t\tTimeout: 5 * time.Second,\n\t}\n}\n\nfunc (c *GreeterClient) SayHello(req HelloRequest) (resp HelloReply, err error) {\n\n\tsubject := c.Subject + \".\" + \"SayHello\"\n\n\t// call\n\terr = nrpc.Call(&req, &resp, c.nc, subject, c.Encoding, c.Timeout)\n\tif err != nil {\n\t\treturn // already logged\n\t}\n\n\treturn\n}\n\ntype Client struct {\n\tnc      nrpc.NatsConn\n\tdefaultEncoding string\n\tdefaultTimeout time.Duration\n\tGreeter *GreeterClient\n}\n\nfunc NewClient(nc nrpc.NatsConn) *Client {\n\tc := Client{\n\t\tnc: nc,\n\t\tdefaultEncoding: \"protobuf\",\n\t\tdefaultTimeout: 5*time.Second,\n\t}\n\tc.Greeter = NewGreeterClient(nc)\n\treturn &c\n}\n\nfunc (c *Client) SetEncoding(encoding string) {\n\tc.defaultEncoding = encoding\n\tif c.Greeter != nil {\n\t\tc.Greeter.Encoding = encoding\n\t}\n}\n\nfunc (c *Client) SetTimeout(t time.Duration) {\n\tc.defaultTimeout = t\n\tif c.Greeter != nil {\n\t\tc.Greeter.Timeout = t\n\t}\n}"
  },
  {
    "path": "examples/nooption/nooption.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.29.0\n// \tprotoc        v4.22.2\n// source: nooption.proto\n\npackage nooption\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\n// The request message containing the user's name.\ntype HelloRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tName string `protobuf:\"bytes,1,opt,name=name,proto3\" json:\"name,omitempty\"`\n}\n\nfunc (x *HelloRequest) Reset() {\n\t*x = HelloRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_nooption_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HelloRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HelloRequest) ProtoMessage() {}\n\nfunc (x *HelloRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_nooption_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use HelloRequest.ProtoReflect.Descriptor instead.\nfunc (*HelloRequest) Descriptor() ([]byte, []int) {\n\treturn file_nooption_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *HelloRequest) GetName() string {\n\tif x != nil {\n\t\treturn x.Name\n\t}\n\treturn \"\"\n}\n\n// The response message containing the greetings\ntype HelloReply struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tMessage string `protobuf:\"bytes,1,opt,name=message,proto3\" json:\"message,omitempty\"`\n}\n\nfunc (x *HelloReply) Reset() {\n\t*x = HelloReply{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_nooption_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HelloReply) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HelloReply) ProtoMessage() {}\n\nfunc (x *HelloReply) ProtoReflect() protoreflect.Message {\n\tmi := &file_nooption_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use HelloReply.ProtoReflect.Descriptor instead.\nfunc (*HelloReply) Descriptor() ([]byte, []int) {\n\treturn file_nooption_proto_rawDescGZIP(), []int{1}\n}\n\nfunc (x *HelloReply) GetMessage() string {\n\tif x != nil {\n\t\treturn x.Message\n\t}\n\treturn \"\"\n}\n\nvar File_nooption_proto protoreflect.FileDescriptor\n\nvar file_nooption_proto_rawDesc = []byte{\n\t0x0a, 0x0e, 0x6e, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x12, 0x08, 0x6e, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x22, 0x0a, 0x0c, 0x48, 0x65,\n\t0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,\n\t0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x26,\n\t0x0a, 0x0a, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x18, 0x0a, 0x07,\n\t0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d,\n\t0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x32, 0x45, 0x0a, 0x07, 0x47, 0x72, 0x65, 0x65, 0x74, 0x65,\n\t0x72, 0x12, 0x3a, 0x0a, 0x08, 0x53, 0x61, 0x79, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x12, 0x16, 0x2e,\n\t0x6e, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65,\n\t0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x6e, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,\n\t0x2e, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x00, 0x42, 0x2c, 0x5a,\n\t0x2a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x61, 0x74, 0x73,\n\t0x2d, 0x72, 0x70, 0x63, 0x2f, 0x6e, 0x72, 0x70, 0x63, 0x2f, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c,\n\t0x65, 0x73, 0x2f, 0x6e, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x62, 0x06, 0x70, 0x72, 0x6f,\n\t0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_nooption_proto_rawDescOnce sync.Once\n\tfile_nooption_proto_rawDescData = file_nooption_proto_rawDesc\n)\n\nfunc file_nooption_proto_rawDescGZIP() []byte {\n\tfile_nooption_proto_rawDescOnce.Do(func() {\n\t\tfile_nooption_proto_rawDescData = protoimpl.X.CompressGZIP(file_nooption_proto_rawDescData)\n\t})\n\treturn file_nooption_proto_rawDescData\n}\n\nvar file_nooption_proto_msgTypes = make([]protoimpl.MessageInfo, 2)\nvar file_nooption_proto_goTypes = []interface{}{\n\t(*HelloRequest)(nil), // 0: nooption.HelloRequest\n\t(*HelloReply)(nil),   // 1: nooption.HelloReply\n}\nvar file_nooption_proto_depIdxs = []int32{\n\t0, // 0: nooption.Greeter.SayHello:input_type -> nooption.HelloRequest\n\t1, // 1: nooption.Greeter.SayHello:output_type -> nooption.HelloReply\n\t1, // [1:2] is the sub-list for method output_type\n\t0, // [0:1] is the sub-list for method input_type\n\t0, // [0:0] is the sub-list for extension type_name\n\t0, // [0:0] is the sub-list for extension extendee\n\t0, // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_nooption_proto_init() }\nfunc file_nooption_proto_init() {\n\tif File_nooption_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_nooption_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HelloRequest); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_nooption_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HelloReply); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_nooption_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   2,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   1,\n\t\t},\n\t\tGoTypes:           file_nooption_proto_goTypes,\n\t\tDependencyIndexes: file_nooption_proto_depIdxs,\n\t\tMessageInfos:      file_nooption_proto_msgTypes,\n\t}.Build()\n\tFile_nooption_proto = out.File\n\tfile_nooption_proto_rawDesc = nil\n\tfile_nooption_proto_goTypes = nil\n\tfile_nooption_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "examples/nooption/nooption.proto",
    "content": "syntax = \"proto3\";\n\npackage nooption;\n\noption go_package = \"github.com/nats-rpc/nrpc/examples/nooption\";\n\nservice Greeter {\n  // Sends a greeting\n  rpc SayHello (HelloRequest) returns (HelloReply) {}\n}\n\n// The request message containing the user's name.\nmessage HelloRequest {\n  string name = 1;\n}\n\n// The response message containing the greetings\nmessage HelloReply {\n  string message = 1;\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/nats-rpc/nrpc\n\ngo 1.11\n\nrequire (\n\tgithub.com/cespare/xxhash/v2 v2.2.0 // indirect\n\tgithub.com/golang/protobuf v1.5.3 // indirect\n\tgithub.com/nats-io/nats-server/v2 v2.9.23\n\tgithub.com/nats-io/nats.go v1.28.0\n\tgithub.com/prometheus/client_golang v1.14.0\n\tgithub.com/prometheus/common v0.42.0 // indirect\n\tgithub.com/prometheus/procfs v0.9.0 // indirect\n\tgithub.com/stretchr/testify v1.8.1\n\tgoogle.golang.org/protobuf v1.33.0\n)\n"
  },
  {
    "path": "go.sum",
    "content": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=\ncloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU=\ncloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY=\ncloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc=\ncloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0=\ncloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To=\ncloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4=\ncloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M=\ncloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc=\ncloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk=\ncloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs=\ncloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc=\ncloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY=\ncloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=\ncloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=\ncloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc=\ncloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg=\ncloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc=\ncloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=\ncloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=\ncloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=\ncloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk=\ncloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I=\ncloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw=\ncloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA=\ncloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU=\ncloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw=\ncloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos=\ncloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=\ncloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=\ncloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=\ndmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=\ngithub.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=\ngithub.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=\ngithub.com/alecthomas/kingpin/v2 v2.3.1/go.mod h1:oYL5vtsvEHZGHxU7DMp32Dvx+qL+ptGn6lWaot2vCNE=\ngithub.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=\ngithub.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=\ngithub.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=\ngithub.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=\ngithub.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=\ngithub.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=\ngithub.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=\ngithub.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=\ngithub.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=\ngithub.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=\ngithub.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=\ngithub.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=\ngithub.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=\ngithub.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=\ngithub.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=\ngithub.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=\ngithub.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=\ngithub.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=\ngithub.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=\ngithub.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=\ngithub.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY=\ngithub.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=\ngithub.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=\ngithub.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=\ngithub.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=\ngithub.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=\ngithub.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=\ngithub.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=\ngithub.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=\ngithub.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=\ngithub.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=\ngithub.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=\ngithub.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y=\ngithub.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw=\ngithub.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4=\ngithub.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=\ngithub.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk=\ngithub.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=\ngithub.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=\ngithub.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=\ngithub.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=\ngithub.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=\ngithub.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=\ngithub.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=\ngithub.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=\ngithub.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=\ngithub.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=\ngithub.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=\ngithub.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=\ngithub.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=\ngithub.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=\ngithub.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=\ngithub.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=\ngithub.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=\ngithub.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=\ngithub.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0=\ngithub.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=\ngithub.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=\ngithub.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=\ngithub.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=\ngithub.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=\ngithub.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=\ngithub.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=\ngithub.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=\ngithub.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=\ngithub.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=\ngithub.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=\ngithub.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=\ngithub.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=\ngithub.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=\ngithub.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=\ngithub.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=\ngithub.com/klauspost/compress v1.16.5/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=\ngithub.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=\ngithub.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=\ngithub.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=\ngithub.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=\ngithub.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=\ngithub.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=\ngithub.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=\ngithub.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=\ngithub.com/minio/highwayhash v1.0.2 h1:Aak5U0nElisjDCfPSG79Tgzkn2gl66NxOMspRrKnA/g=\ngithub.com/minio/highwayhash v1.0.2/go.mod h1:BQskDq+xkJ12lmlUUi7U0M5Swg3EWR+dLTk+kldvVxY=\ngithub.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=\ngithub.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=\ngithub.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=\ngithub.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=\ngithub.com/nats-io/jwt/v2 v2.5.0 h1:WQQ40AAlqqfx+f6ku+i0pOVm+ASirD4fUh+oQsiE9Ak=\ngithub.com/nats-io/jwt/v2 v2.5.0/go.mod h1:24BeQtRwxRV8ruvC4CojXlx/WQ/VjuwlYiH+vu/+ibI=\ngithub.com/nats-io/nats-server/v2 v2.9.23 h1:6Wj6H6QpP9FMlpCyWUaNu2yeZ/qGj+mdRkZ1wbikExU=\ngithub.com/nats-io/nats-server/v2 v2.9.23/go.mod h1:wEjrEy9vnqIGE4Pqz4/c75v9Pmaq7My2IgFmnykc4C0=\ngithub.com/nats-io/nats.go v1.28.0 h1:Th4G6zdsz2d0OqXdfzKLClo6bOfoI/b1kInhRtFIy5c=\ngithub.com/nats-io/nats.go v1.28.0/go.mod h1:XpbWUlOElGwTYbMR7imivs7jJj9GtK7ypv321Wp6pjc=\ngithub.com/nats-io/nkeys v0.4.4 h1:xvBJ8d69TznjcQl9t6//Q5xXuVhyYiSos6RPtvQNTwA=\ngithub.com/nats-io/nkeys v0.4.4/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64=\ngithub.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=\ngithub.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=\ngithub.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=\ngithub.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=\ngithub.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=\ngithub.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=\ngithub.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=\ngithub.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=\ngithub.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=\ngithub.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y=\ngithub.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=\ngithub.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=\ngithub.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=\ngithub.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w=\ngithub.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=\ngithub.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=\ngithub.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=\ngithub.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=\ngithub.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=\ngithub.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM=\ngithub.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc=\ngithub.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=\ngithub.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=\ngithub.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=\ngithub.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\ngithub.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=\ngithub.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=\ngithub.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI=\ngithub.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY=\ngithub.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=\ngithub.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=\ngithub.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=\ngithub.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=\ngithub.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngithub.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=\ngithub.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=\ngithub.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=\ngithub.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=\ngithub.com/xhit/go-str2duration v1.2.0/go.mod h1:3cPSlfZlUHVlneIVfePFWcJZsuwf+P1v2SRTV4cUmp4=\ngithub.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=\ngithub.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=\ngo.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=\ngo.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8=\ngo.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw=\ngo.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0=\ngolang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=\ngolang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=\ngolang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=\ngolang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=\ngolang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=\ngolang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=\ngolang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=\ngolang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=\ngolang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=\ngolang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek=\ngolang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY=\ngolang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=\ngolang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=\ngolang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=\ngolang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=\ngolang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=\ngolang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=\ngolang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=\ngolang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=\ngolang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs=\ngolang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=\ngolang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE=\ngolang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o=\ngolang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=\ngolang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=\ngolang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=\ngolang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=\ngolang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=\ngolang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=\ngolang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=\ngolang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=\ngolang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=\ngolang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=\ngolang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=\ngolang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=\ngolang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=\ngolang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=\ngolang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=\ngolang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=\ngolang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=\ngolang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=\ngolang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=\ngolang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=\ngolang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=\ngolang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=\ngolang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=\ngolang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=\ngolang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=\ngolang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=\ngolang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=\ngolang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=\ngolang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=\ngolang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=\ngolang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=\ngolang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=\ngolang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=\ngolang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=\ngolang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=\ngolang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=\ngolang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=\ngolang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=\ngolang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngolang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=\ngolang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=\ngolang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=\ngolang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=\ngolang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=\ngolang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=\ngolang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw=\ngolang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=\ngolang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=\ngolang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA=\ngolang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=\ngolang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=\ngolang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngolang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=\ngoogle.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=\ngoogle.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M=\ngoogle.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=\ngoogle.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI=\ngoogle.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=\ngoogle.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE=\ngoogle.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM=\ngoogle.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc=\ngoogle.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=\ngoogle.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=\ngoogle.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngoogle.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=\ngoogle.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=\ngoogle.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=\ngoogle.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8=\ngoogle.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc=\ngoogle.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA=\ngoogle.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c=\ngoogle.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U=\ngoogle.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=\ngoogle.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA=\ngoogle.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=\ngoogle.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=\ngoogle.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=\ngoogle.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM=\ngoogle.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=\ngoogle.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY=\ngoogle.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=\ngoogle.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60=\ngoogle.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk=\ngoogle.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=\ngoogle.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=\ngoogle.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=\ngoogle.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=\ngoogle.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=\ngoogle.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=\ngoogle.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=\ngoogle.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4=\ngoogle.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=\ngoogle.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=\ngoogle.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=\ngoogle.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=\ngoogle.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=\ngoogle.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=\ngopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=\ngopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=\ngopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=\ngopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\ngopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=\ngopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\nhonnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=\nhonnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=\nhonnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nhonnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=\nrsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=\nrsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=\nrsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=\n"
  },
  {
    "path": "helloworld_test.go",
    "content": "package nrpc\n\nimport (\n\t\"bytes\"\n\t\"os\"\n\t\"os/exec\"\n\t\"testing\"\n\t\"time\"\n)\n\nfunc TestHelloWorldExample(t *testing.T) {\n\t// make sure protoc-gen-nrpc is up to date\n\tinstallGenRPC := exec.Command(\"go\", \"install\", \"./protoc-gen-nrpc\")\n\tif out, err := installGenRPC.CombinedOutput(); err != nil {\n\t\tt.Fatal(\"Install protoc-gen-nrpc failed\", err, \":\\n\", string(out))\n\t}\n\t// generate the sources\n\tgenerate := exec.Command(\"go\", \"generate\", \"./examples/helloworld/helloworld\")\n\tif out, err := generate.CombinedOutput(); err != nil {\n\t\tt.Fatal(\"Generate failed\", err, \":\\n\", string(out))\n\t}\n\t// build\n\tbuildServer := exec.Command(\"go\", \"build\",\n\t\t\"-o\", \"./examples/helloworld/greeter_server/greeter_server\",\n\t\t\"./examples/helloworld/greeter_server\")\n\tif out, err := buildServer.CombinedOutput(); err != nil {\n\t\tt.Fatal(\"Buid server failed\", err, string(out))\n\t}\n\tbuildClient := exec.Command(\"go\", \"build\",\n\t\t\"-o\", \"./examples/helloworld/greeter_client/greeter_client\",\n\t\t\"./examples/helloworld/greeter_client\")\n\tif out, err := buildClient.CombinedOutput(); err != nil {\n\t\tt.Fatal(\"Buid client failed\", err, string(out))\n\t}\n\t// run the server\n\tserver := exec.Command(\"./examples/helloworld/greeter_server/greeter_server\", NatsURL)\n\tvar serverStdout bytes.Buffer\n\tserver.Stdout = &serverStdout\n\tserver.Start()\n\tdefer func() {\n\t\tif server.Process != nil {\n\t\t\tserver.Process.Signal(os.Interrupt)\n\t\t}\n\t\tif err := server.Wait(); err != nil {\n\t\t\tt.Error(\"Server run failed:\", err)\n\t\t\tt.Error(\"Server output:\", serverStdout.String())\n\t\t}\n\t}()\n\n\t// Give the server a little time to be ready to handle requests\n\ttime.Sleep(250 * time.Millisecond)\n\n\t// run the client and check its output\n\tclient := exec.Command(\"./examples/helloworld/greeter_client/greeter_client\", NatsURL)\n\ttimeout := time.AfterFunc(time.Second, func() { client.Process.Kill() })\n\tout, err := client.CombinedOutput()\n\ttimeout.Stop()\n\tif err != nil {\n\t\tt.Fatal(\"Run client failed with:\", err, \", output was:\\n\", string(out))\n\t}\n\texpectedOuput := \"Greeting: Hello world\\n\"\n\tif string(out) != expectedOuput {\n\t\tt.Errorf(\"Wrong client output. Expected '%s', got '%s'\",\n\t\t\texpectedOuput, string(out))\n\t}\n}\n"
  },
  {
    "path": "nrpc.go",
    "content": "package nrpc\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"fmt\"\n\t\"log\"\n\t\"runtime/debug\"\n\t\"strings\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\tjsonpb \"google.golang.org/protobuf/encoding/protojson\"\n\t\"google.golang.org/protobuf/proto\"\n)\n\nconst (\n\tstatusHeader      = \"Status\"\n\tnoResponderStatus = \"503\"\n)\n\n// ContextKey type for storing values into context.Context\ntype ContextKey int\n\n// ErrStreamInvalidMsgCount is when a stream reply gets a wrong number of messages\nvar ErrStreamInvalidMsgCount = errors.New(\"Stream reply received an incorrect number of messages\")\n\n//go:generate protoc --go_out=. --go_opt=paths=source_relative nrpc.proto\n\ntype NatsConn interface {\n\tPublish(subj string, data []byte) error\n\tPublishRequest(subj, reply string, data []byte) error\n\tRequest(subj string, data []byte, timeout time.Duration) (*nats.Msg, error)\n\n\tChanSubscribe(subj string, ch chan *nats.Msg) (*nats.Subscription, error)\n\tSubscribe(subj string, handler nats.MsgHandler) (*nats.Subscription, error)\n\tSubscribeSync(subj string) (*nats.Subscription, error)\n}\n\n// ReplyInboxMaker returns a new inbox subject for a given nats connection.\ntype ReplyInboxMaker func(NatsConn) string\n\n// GetReplyInbox is used by StreamCall to get a inbox subject\n// It can be changed by a client lib that needs custom inbox subjects\nvar GetReplyInbox ReplyInboxMaker = func(NatsConn) string {\n\treturn nats.NewInbox()\n}\n\nfunc (e *Error) Error() string {\n\treturn fmt.Sprintf(\"%s error: %s\", Error_Type_name[int32(e.Type)], e.Message)\n}\n\nfunc Unmarshal(encoding string, data []byte, msg proto.Message) error {\n\tswitch encoding {\n\tcase \"protobuf\":\n\t\treturn proto.Unmarshal(data, msg)\n\tcase \"json\":\n\t\treturn jsonpb.Unmarshal(data, msg)\n\tdefault:\n\t\treturn errors.New(\"Invalid encoding: \" + encoding)\n\t}\n}\n\nfunc UnmarshalResponse(encoding string, data []byte, msg proto.Message) error {\n\tswitch encoding {\n\tcase \"protobuf\":\n\t\tif len(data) > 0 && data[0] == 0 {\n\t\t\tvar repErr Error\n\t\t\tif err := proto.Unmarshal(data[1:], &repErr); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn &repErr\n\t\t}\n\t\treturn proto.Unmarshal(data, msg)\n\tcase \"json\":\n\t\tif len(data) > 13 && bytes.Equal(data[:13], []byte(\"{\\\"__error__\\\":\")) {\n\t\t\tvar rep map[string]json.RawMessage\n\t\t\tif err := json.Unmarshal(data, &rep); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\terrbuf, ok := rep[\"__error__\"]\n\t\t\tif !ok {\n\t\t\t\tpanic(\"invalid error message\")\n\t\t\t}\n\t\t\tvar nrpcErr Error\n\t\t\tif err := jsonpb.Unmarshal(errbuf, &nrpcErr); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\treturn &nrpcErr\n\t\t}\n\t\treturn jsonpb.Unmarshal(data, msg)\n\tdefault:\n\t\treturn errors.New(\"Invalid encoding: \" + encoding)\n\t}\n}\n\nfunc Marshal(encoding string, msg proto.Message) ([]byte, error) {\n\tswitch encoding {\n\tcase \"protobuf\":\n\t\treturn proto.Marshal(msg)\n\tcase \"json\":\n\t\treturn jsonpb.Marshal(msg)\n\tdefault:\n\t\treturn nil, errors.New(\"Invalid encoding: \" + encoding)\n\t}\n}\n\nfunc MarshalErrorResponse(encoding string, repErr *Error) ([]byte, error) {\n\tswitch encoding {\n\tcase \"protobuf\":\n\t\tb, err := proto.Marshal(repErr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn append([]byte{0}, b...), nil\n\tcase \"json\":\n\t\tb, err := jsonpb.Marshal(repErr)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\treturn json.Marshal(map[string]json.RawMessage{\n\t\t\t\"__error__\": json.RawMessage(b),\n\t\t})\n\tdefault:\n\t\treturn nil, errors.New(\"Invalid encoding: \" + encoding)\n\t}\n}\n\nfunc ParseSubject(\n\tpackageSubject string, packageParamsCount int,\n\tserviceSubject string, serviceParamsCount int,\n\tsubject string,\n) (packageParams []string, serviceParams []string,\n\tname string, tail []string, err error,\n) {\n\tpackageSubjectDepth := 0\n\tif packageSubject != \"\" {\n\t\tpackageSubjectDepth = strings.Count(packageSubject, \".\") + 1\n\t}\n\tserviceSubjectDepth := strings.Count(serviceSubject, \".\") + 1\n\tsubjectMinSize := packageSubjectDepth + packageParamsCount + serviceSubjectDepth + serviceParamsCount + 1\n\n\ttokens := strings.Split(subject, \".\")\n\tif len(tokens) < subjectMinSize {\n\t\terr = fmt.Errorf(\n\t\t\t\"Invalid subject len. Expects number of parts >= %d, got %d\",\n\t\t\tsubjectMinSize, len(tokens))\n\t\treturn\n\t}\n\tif packageSubject != \"\" {\n\t\tfor i, packageSubjectPart := range strings.Split(packageSubject, \".\") {\n\t\t\tif tokens[i] != packageSubjectPart {\n\t\t\t\terr = fmt.Errorf(\n\t\t\t\t\t\"Invalid subject prefix. Expected '%s', got '%s'\",\n\t\t\t\t\tpackageSubjectPart, tokens[i])\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\t\ttokens = tokens[packageSubjectDepth:]\n\t}\n\n\tpackageParams = tokens[0:packageParamsCount]\n\ttokens = tokens[packageParamsCount:]\n\n\tfor i, serviceSubjectPart := range strings.Split(serviceSubject, \".\") {\n\t\tif tokens[i] != serviceSubjectPart {\n\t\t\terr = fmt.Errorf(\n\t\t\t\t\"Invalid subject. Service should be '%s', got '%s'\",\n\t\t\t\tserviceSubjectPart, tokens[i])\n\t\t\treturn\n\t\t}\n\t}\n\ttokens = tokens[serviceSubjectDepth:]\n\n\tserviceParams = tokens[0:serviceParamsCount]\n\ttokens = tokens[serviceParamsCount:]\n\n\tname = tokens[0]\n\ttokens = tokens[1:]\n\n\ttail = tokens\n\treturn\n}\n\nfunc ParseSubjectTail(\n\tmethodParamsCount int,\n\ttail []string,\n) (\n\tmethodParams []string, encoding string, err error,\n) {\n\tif len(tail) < methodParamsCount || len(tail) > methodParamsCount+1 {\n\t\terr = fmt.Errorf(\n\t\t\t\"Invalid subject tail length. Expects %d or %d parts, got %d\",\n\t\t\tmethodParamsCount, methodParamsCount+1, len(tail),\n\t\t)\n\t\treturn\n\t}\n\tmethodParams = tail[:methodParamsCount]\n\ttail = tail[methodParamsCount:]\n\tswitch len(tail) {\n\tcase 0:\n\t\tencoding = \"protobuf\"\n\tcase 1:\n\t\tencoding = tail[0]\n\tdefault:\n\t\tpanic(\"Got extra tokens, which should be impossible at this point\")\n\t}\n\treturn\n}\n\nfunc Call(req proto.Message, rep proto.Message, nc NatsConn, subject string, encoding string, timeout time.Duration) error {\n\t// encode request\n\trawRequest, err := Marshal(encoding, req)\n\tif err != nil {\n\t\tlog.Printf(\"nrpc: inner request marshal failed: %v\", err)\n\t\treturn err\n\t}\n\n\tif encoding != \"protobuf\" {\n\t\tsubject += \".\" + encoding\n\t}\n\n\t// call\n\tif _, noreply := rep.(*NoReply); noreply {\n\t\terr := nc.Publish(subject, rawRequest)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"nrpc: nats publish failed: %v\", err)\n\t\t}\n\t\treturn err\n\t}\n\tmsg, err := nc.Request(subject, rawRequest, timeout)\n\tif err != nil {\n\t\tlog.Printf(\"nrpc: nats request failed: %v\", err)\n\t\treturn err\n\t}\n\n\tdata := msg.Data\n\n\tif err := UnmarshalResponse(encoding, data, rep); err != nil {\n\t\tif _, isError := err.(*Error); !isError {\n\t\t\tlog.Printf(\"nrpc: response unmarshal failed: %v\", err)\n\t\t}\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\nfunc Poll(\n\treq proto.Message, rep proto.Message,\n\tnc NatsConn, subject string, encoding string, timeout time.Duration,\n\tmaxreplies int, cb func() error,\n) error {\n\t// encode request\n\trawRequest, err := Marshal(encoding, req)\n\tif err != nil {\n\t\tlog.Printf(\"nrpc: inner request marshal failed: %v\", err)\n\t\treturn err\n\t}\n\n\tif encoding != \"protobuf\" {\n\t\tsubject += \".\" + encoding\n\t}\n\n\treply := GetReplyInbox(nc)\n\treplyC := make(chan *nats.Msg)\n\tdefer close(replyC)\n\n\tsub, err := nc.ChanSubscribe(reply, replyC)\n\tdefer func() {\n\t\tif err := sub.Unsubscribe(); err != nil {\n\t\t\tlog.Printf(\"nrpc: nats unsubscribe failed: %v\", err)\n\t\t}\n\t}()\n\n\tif err := nc.PublishRequest(subject, reply, rawRequest); err != nil {\n\t\tlog.Printf(\"nrpc: nats request failed: %v\", err)\n\t\treturn err\n\t}\n\n\ttimeoutC := time.After(timeout)\n\tvar replyCount int\n\n\tfor {\n\t\tselect {\n\t\tcase msg := <-replyC:\n\t\t\treplyCount++\n\n\t\t\tdata := msg.Data\n\n\t\t\tif err := UnmarshalResponse(encoding, data, rep); err != nil {\n\t\t\t\tif _, isError := err.(*Error); !isError {\n\t\t\t\t\tlog.Printf(\"nrpc: response unmarshal failed: %v\", err)\n\t\t\t\t}\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif err := cb(); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\tif replyCount == maxreplies {\n\t\t\t\treturn nil\n\t\t\t}\n\t\tcase <-timeoutC:\n\t\t\treturn nats.ErrTimeout\n\t\t}\n\t}\n}\n\nconst (\n\t// RequestContextKey is the key for string the request into the context\n\tRequestContextKey ContextKey = iota\n)\n\n// NewRequest creates a Request instance\nfunc NewRequest(ctx context.Context, conn NatsConn, subject string, replySubject string) *Request {\n\treturn &Request{\n\t\tContext:      ctx,\n\t\tConn:         conn,\n\t\tSubject:      subject,\n\t\tReplySubject: replySubject,\n\t\tCreatedAt:    time.Now(),\n\t}\n}\n\n// GetRequest returns the Request associated with a context, or nil if absent\nfunc GetRequest(ctx context.Context) *Request {\n\trequest, _ := ctx.Value(RequestContextKey).(*Request)\n\treturn request\n}\n\n// Request is a server-side incoming request\ntype Request struct {\n\tContext context.Context\n\tConn    NatsConn\n\n\tisStreamedReply bool\n\tKeepStreamAlive *KeepStreamAlive\n\tStreamContext   context.Context\n\tStreamCancel    func()\n\tStreamMsgCount  uint32\n\tstreamLock      sync.Mutex\n\n\tSubject     string\n\tMethodName  string\n\tSubjectTail []string\n\n\tCreatedAt time.Time\n\tStartedAt time.Time\n\n\tEncoding     string\n\tNoReply      bool\n\tReplySubject string\n\n\tPackageParams map[string]string\n\tServiceParams map[string]string\n\n\tAfterReply func(r *Request, success bool, replySuccess bool)\n\n\tHandler func(context.Context) (proto.Message, error)\n}\n\n// Elapsed duration since request was started\nfunc (r *Request) Elapsed() time.Duration {\n\treturn time.Since(r.CreatedAt)\n}\n\n// Run the handler and capture any error. Returns the response or the error\n// that should be returned to the caller\nfunc (r *Request) Run() (msg proto.Message, replyError *Error) {\n\tr.StartedAt = time.Now()\n\tctx := r.Context\n\tif r.StreamedReply() {\n\t\tctx = r.StreamContext\n\t}\n\tctx = context.WithValue(ctx, RequestContextKey, r)\n\tmsg, replyError = CaptureErrors(\n\t\tfunc() (proto.Message, error) {\n\t\t\treturn r.Handler(ctx)\n\t\t})\n\treturn\n}\n\n// RunAndReply calls Run() and send the reply back to the caller\nfunc (r *Request) RunAndReply() {\n\tvar failed, replyFailed bool\n\t// In case RunAndReply was called directly, we may need to initialize the\n\t// streamed reply\n\tr.setupStreamedReply()\n\tresp, replyError := r.Run()\n\tif replyError != nil {\n\t\tfailed = true\n\t\tlog.Printf(\"%s handler failed: %s\", r.MethodName, replyError)\n\t}\n\tif !r.NoReply {\n\t\tif err := r.SendReply(resp, replyError); err != nil {\n\t\t\treplyFailed = true\n\t\t\tlog.Printf(\"%s failed to publish the response: %s\", r.MethodName, err)\n\t\t}\n\t}\n\tif r.AfterReply != nil {\n\t\tr.AfterReply(r, !failed, !replyFailed)\n\t}\n}\n\n// PackageParam returns a package parameter value, or \"\" if absent\nfunc (r *Request) PackageParam(key string) string {\n\tif r == nil || r.PackageParams == nil {\n\t\treturn \"\"\n\t}\n\treturn r.PackageParams[key]\n}\n\n// ServiceParam returns a package parameter value, or \"\" if absent\nfunc (r *Request) ServiceParam(key string) string {\n\tif r == nil || r.ServiceParams == nil {\n\t\treturn \"\"\n\t}\n\treturn r.ServiceParams[key]\n}\n\n// SetPackageParam sets a package param value\nfunc (r *Request) SetPackageParam(key, value string) {\n\tif r.PackageParams == nil {\n\t\tr.PackageParams = make(map[string]string)\n\t}\n\tr.PackageParams[key] = value\n}\n\n// SetServiceParam sets a service param value\nfunc (r *Request) SetServiceParam(key, value string) {\n\tif r.ServiceParams == nil {\n\t\tr.ServiceParams = make(map[string]string)\n\t}\n\tr.ServiceParams[key] = value\n}\n\n// EnableStreamedReply enables the streamed reply mode\nfunc (r *Request) EnableStreamedReply() {\n\tr.isStreamedReply = true\n}\n\n// setupStreamedReply initializes the reply stream if needed.\nfunc (r *Request) setupStreamedReply() {\n\tr.streamLock.Lock()\n\tdefer r.streamLock.Unlock()\n\n\tif !r.StreamedReply() || r.KeepStreamAlive != nil {\n\t\treturn\n\t}\n\tr.StreamContext, r.StreamCancel = context.WithCancel(r.Context)\n\tr.KeepStreamAlive = NewKeepStreamAlive(\n\t\tr.Conn, r.ReplySubject, r.Encoding, r.StreamCancel)\n}\n\n// StreamedReply returns true if the request reply is streamed\nfunc (r *Request) StreamedReply() bool {\n\treturn r.isStreamedReply\n}\n\n// SendStreamReply send a reply a part of a stream\nfunc (r *Request) SendStreamReply(msg proto.Message) {\n\tif err := r.sendReply(msg, nil); err != nil {\n\t\tlog.Printf(\"nrpc: error publishing response: %s\", err)\n\t\tr.StreamCancel()\n\t\treturn\n\t}\n\tr.StreamMsgCount++\n}\n\n// SendReply sends a reply to the caller\nfunc (r *Request) SendReply(resp proto.Message, withError *Error) error {\n\tif r.StreamedReply() {\n\t\tr.KeepStreamAlive.Stop()\n\t\tif withError == nil {\n\t\t\treturn r.sendReply(\n\t\t\t\tnil, &Error{Type: Error_EOS, MsgCount: r.StreamMsgCount},\n\t\t\t)\n\t\t}\n\t}\n\treturn r.sendReply(resp, withError)\n}\n\n// sendReply sends a reply to the caller\nfunc (r *Request) sendReply(resp proto.Message, withError *Error) error {\n\treturn Publish(resp, withError, r.Conn, r.ReplySubject, r.Encoding)\n}\n\n// SendErrorTooBusy cancels the request with a 'SERVERTOOBUSY' error\nfunc (r *Request) SendErrorTooBusy(msg string) error {\n\treturn r.SendReply(nil, &Error{\n\t\tType:    Error_SERVERTOOBUSY,\n\t\tMessage: msg,\n\t})\n}\n\nvar ErrEOS = errors.New(\"End of stream\")\nvar ErrCanceled = errors.New(\"Call canceled\")\n\nfunc NewStreamCallSubscription(\n\tctx context.Context, nc NatsConn, encoding string, subject string,\n\ttimeout time.Duration,\n) (*StreamCallSubscription, error) {\n\tsub := StreamCallSubscription{\n\t\tctx:      ctx,\n\t\tnc:       nc,\n\t\tencoding: encoding,\n\t\tsubject:  subject,\n\t\ttimeout:  timeout,\n\t\ttimeoutT: time.NewTimer(timeout),\n\t\tclosed:   false,\n\t\tsubCh:    make(chan *nats.Msg, 256),\n\t\tnextCh:   make(chan *nats.Msg),\n\t\tquit:     make(chan struct{}),\n\t\terrCh:    make(chan error, 1),\n\t}\n\tssub, err := nc.ChanSubscribe(subject, sub.subCh)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tgo sub.loop(ssub)\n\treturn &sub, nil\n}\n\ntype StreamCallSubscription struct {\n\tctx      context.Context\n\tnc       NatsConn\n\tencoding string\n\tsubject  string\n\ttimeout  time.Duration\n\ttimeoutT *time.Timer\n\tclosed   bool\n\tsubCh    chan *nats.Msg\n\tnextCh   chan *nats.Msg\n\tquit     chan struct{}\n\terrCh    chan error\n\tmsgCount uint32\n}\n\nfunc (sub *StreamCallSubscription) stop() {\n\tclose(sub.quit)\n}\n\nfunc (sub *StreamCallSubscription) loop(ssub *nats.Subscription) {\n\thbSubject := sub.subject + \".heartbeat\"\n\tticker := time.NewTicker(time.Second)\n\tdefer ticker.Stop()\n\tdefer ssub.Unsubscribe()\n\tfor {\n\t\tselect {\n\t\tcase msg := <-sub.subCh:\n\t\t\tsub.timeoutT.Reset(sub.timeout)\n\n\t\t\tif len(msg.Data) == 1 && msg.Data[0] == 0 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\t// Check for no responder status.\n\t\t\tif len(msg.Data) == 0 && msg.Header.Get(statusHeader) == noResponderStatus {\n\t\t\t\tsub.errCh <- nats.ErrNoResponders\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tsub.nextCh <- msg\n\t\tcase <-sub.timeoutT.C:\n\t\t\tsub.errCh <- nats.ErrTimeout\n\t\t\treturn\n\t\tcase <-sub.ctx.Done():\n\t\t\t// send a 'lastbeat' and quit\n\t\t\tb, err := Marshal(sub.encoding, &HeartBeat{Lastbeat: true})\n\t\t\tif err != nil {\n\t\t\t\terr = fmt.Errorf(\"Error marshaling heartbeat: %s\", err)\n\t\t\t\tsub.errCh <- err\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err := sub.nc.Publish(hbSubject, b); err != nil {\n\t\t\t\terr = fmt.Errorf(\"Error sending heartbeat: %s\", err)\n\t\t\t\tsub.errCh <- err\n\t\t\t\treturn\n\t\t\t}\n\t\t\tsub.errCh <- ErrCanceled\n\t\t\treturn\n\t\tcase <-ticker.C:\n\t\t\tmsg, err := Marshal(sub.encoding, &HeartBeat{})\n\t\t\tif err != nil {\n\t\t\t\terr = fmt.Errorf(\"Error marshaling heartbeat: %s\", err)\n\t\t\t\tsub.errCh <- err\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err := sub.nc.Publish(hbSubject, msg); err != nil {\n\t\t\t\terr = fmt.Errorf(\"Error sending heartbeat: %s\", err)\n\t\t\t\tsub.errCh <- err\n\t\t\t\treturn\n\t\t\t}\n\t\tcase <-sub.quit:\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc (sub *StreamCallSubscription) Next(rep proto.Message) error {\n\tif sub.closed {\n\t\treturn nats.ErrBadSubscription\n\t}\n\tselect {\n\tcase err := <-sub.errCh:\n\t\tsub.closed = true\n\t\treturn err\n\tcase msg := <-sub.nextCh:\n\t\tif err := UnmarshalResponse(sub.encoding, msg.Data, rep); err != nil {\n\t\t\tsub.stop()\n\t\t\tsub.closed = true\n\t\t\tif nrpcErr, ok := err.(*Error); ok {\n\t\t\t\tif nrpcErr.GetMsgCount() != sub.msgCount {\n\t\t\t\t\tlog.Printf(\n\t\t\t\t\t\t\"nrpc: received invalid number of messages. Expected %d, got %d\",\n\t\t\t\t\t\tnrpcErr.GetMsgCount(), sub.msgCount)\n\t\t\t\t}\n\t\t\t\tif nrpcErr.GetType() == Error_EOS {\n\t\t\t\t\tif nrpcErr.GetMsgCount() != sub.msgCount {\n\t\t\t\t\t\treturn ErrStreamInvalidMsgCount\n\t\t\t\t\t}\n\t\t\t\t\treturn ErrEOS\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tlog.Printf(\"nrpc: response unmarshal failed: %v\", err)\n\t\t\t}\n\t\t\treturn err\n\t\t}\n\t\tsub.msgCount++\n\t}\n\n\treturn nil\n}\n\nfunc StreamCall(ctx context.Context, nc NatsConn, subject string, req proto.Message, encoding string, timeout time.Duration) (*StreamCallSubscription, error) {\n\trawRequest, err := Marshal(encoding, req)\n\tif err != nil {\n\t\tlog.Printf(\"nrpc: inner request marshal failed: %v\", err)\n\t\treturn nil, err\n\t}\n\n\tif encoding != \"protobuf\" {\n\t\tsubject += \".\" + encoding\n\t}\n\n\treply := GetReplyInbox(nc)\n\n\tstreamSub, err := NewStreamCallSubscription(ctx, nc, encoding, reply, timeout)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := nc.PublishRequest(subject, reply, rawRequest); err != nil {\n\t\tstreamSub.stop()\n\t\treturn nil, err\n\t}\n\treturn streamSub, nil\n}\n\nfunc Publish(resp proto.Message, withError *Error, nc NatsConn, subject string, encoding string) error {\n\tvar rawResponse []byte\n\tvar err error\n\n\tif withError != nil {\n\t\trawResponse, err = MarshalErrorResponse(encoding, withError)\n\t} else {\n\t\trawResponse, err = Marshal(encoding, resp)\n\t}\n\n\tif err != nil {\n\t\tlog.Printf(\"nrpc: rpc response marshal failed: %v\", err)\n\t\treturn err\n\t}\n\n\t// send response\n\tif err := nc.Publish(subject, rawResponse); err != nil {\n\t\tlog.Printf(\"nrpc: response publish failed: %v\", err)\n\t\treturn err\n\t}\n\n\treturn nil\n}\n\n// CaptureErrors runs a handler and convert error and panics into proper Error\nfunc CaptureErrors(fn func() (proto.Message, error)) (msg proto.Message, replyError *Error) {\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tlog.Printf(\"Caught panic: %s\\n%s\", r, debug.Stack())\n\t\t\treplyError = &Error{\n\t\t\t\tType:    Error_SERVER,\n\t\t\t\tMessage: fmt.Sprint(r),\n\t\t\t}\n\t\t}\n\t}()\n\tvar err error\n\tmsg, err = fn()\n\tif err != nil {\n\t\tvar ok bool\n\t\tif replyError, ok = err.(*Error); !ok {\n\t\t\treplyError = &Error{\n\t\t\t\tType:    Error_CLIENT,\n\t\t\t\tMessage: err.Error(),\n\t\t\t}\n\t\t}\n\t}\n\treturn\n}\n\nfunc NewKeepStreamAlive(nc NatsConn, subject string, encoding string, onError func()) *KeepStreamAlive {\n\tk := KeepStreamAlive{\n\t\tnc:       nc,\n\t\tsubject:  subject,\n\t\tencoding: encoding,\n\t\tc:        make(chan struct{}),\n\t\tonError:  onError,\n\t}\n\tgo k.loop()\n\treturn &k\n}\n\ntype KeepStreamAlive struct {\n\tnc       NatsConn\n\tsubject  string\n\tencoding string\n\tc        chan struct{}\n\tonError  func()\n}\n\nfunc (k *KeepStreamAlive) Stop() {\n\tclose(k.c)\n}\n\nfunc (k *KeepStreamAlive) loop() {\n\thbChan := make(chan *nats.Msg, 256)\n\thbSub, err := k.nc.ChanSubscribe(k.subject+\".heartbeat\", hbChan)\n\tif err != nil {\n\t\tlog.Printf(\"nrpc: could not subscribe to heartbeat: %s\", err)\n\t\tk.onError()\n\t}\n\tdefer func() {\n\t\tif err := hbSub.Unsubscribe(); err != nil {\n\t\t\tlog.Printf(\"nrpc: error unsubscribing from heartbeat: %s\", err)\n\t\t}\n\t}()\n\thbDelay := 0\n\tticker := time.NewTicker(time.Second)\n\tfor {\n\t\tselect {\n\t\tcase msg := <-hbChan:\n\t\t\tvar hb HeartBeat\n\t\t\tif err := Unmarshal(k.encoding, msg.Data, &hb); err != nil {\n\t\t\t\tlog.Printf(\"nrpc: error unmarshaling heartbeat: %s\", err)\n\t\t\t\tticker.Stop()\n\t\t\t\tk.onError()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif hb.Lastbeat {\n\t\t\t\tlog.Printf(\"nrpc: client canceled the streamed reply. (%s)\", k.subject)\n\t\t\t\tticker.Stop()\n\t\t\t\tk.onError()\n\t\t\t\treturn\n\t\t\t}\n\t\t\thbDelay = 0\n\t\tcase <-ticker.C:\n\t\t\thbDelay++\n\t\t\tif hbDelay >= 5 {\n\t\t\t\tlog.Printf(\"nrpc: No heartbeat received in 5 seconds. Canceling.\")\n\t\t\t\tticker.Stop()\n\t\t\t\tk.onError()\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif err := k.nc.Publish(k.subject, []byte{0}); err != nil {\n\t\t\t\tlog.Printf(\"nrpc: error publishing response: %s\", err)\n\t\t\t\tticker.Stop()\n\t\t\t\tk.onError()\n\t\t\t\treturn\n\t\t\t}\n\t\tcase <-k.c:\n\t\t\tticker.Stop()\n\t\t\treturn\n\t\t}\n\t}\n}\n\n// WorkerPool is a pool of workers\ntype WorkerPool struct {\n\tContext       context.Context\n\tcontextCancel context.CancelFunc\n\n\tqueue     chan *Request\n\tschedule  chan *Request\n\twaitGroup sync.WaitGroup\n\tm         sync.Mutex\n\n\tsize               uint\n\tmaxPending         uint\n\tmaxPendingDuration time.Duration\n}\n\n// NewWorkerPool creates a pool of workers\nfunc NewWorkerPool(\n\tctx context.Context,\n\tsize uint,\n\tmaxPending uint,\n\tmaxPendingDuration time.Duration,\n) *WorkerPool {\n\tnCtx, cancel := context.WithCancel(ctx)\n\tpool := WorkerPool{\n\t\tContext:            nCtx,\n\t\tcontextCancel:      cancel,\n\t\tqueue:              make(chan *Request, maxPending),\n\t\tschedule:           make(chan *Request),\n\t\tmaxPending:         maxPending,\n\t\tmaxPendingDuration: maxPendingDuration,\n\t}\n\tpool.waitGroup.Add(1)\n\tgo pool.scheduler()\n\tpool.SetSize(size)\n\treturn &pool\n}\n\nfunc (pool *WorkerPool) getQueue() (queue chan *Request) {\n\tpool.m.Lock()\n\tqueue = pool.queue\n\tpool.m.Unlock()\n\treturn\n}\n\nfunc (pool *WorkerPool) scheduler() {\n\tdefer pool.waitGroup.Done()\n\n\tfor {\n\t\tqueue := pool.getQueue()\n\t\tif queue == nil {\n\t\t\treturn\n\t\t}\n\tqueueLoop:\n\t\tfor request := range queue {\n\t\t\tnow := time.Now()\n\n\t\t\tpool.m.Lock()\n\t\t\tdeadline := request.CreatedAt.Add(pool.maxPendingDuration)\n\t\t\tpool.m.Unlock()\n\n\t\t\tif deadline.After(now) {\n\t\t\t\t// Safety call to setupStreamedReply in case QueueRequest had\n\t\t\t\t// to time to do it yet\n\t\t\t\trequest.setupStreamedReply()\n\t\t\t\tselect {\n\t\t\t\tcase pool.schedule <- request:\n\t\t\t\t\tcontinue queueLoop\n\t\t\t\tcase <-time.After(deadline.Sub(now)):\n\t\t\t\t\t// Too late\n\t\t\t\t}\n\t\t\t}\n\t\t\trequest.SendErrorTooBusy(\"No worker available\")\n\t\t}\n\t}\n}\n\nfunc (pool *WorkerPool) worker() {\n\tdefer pool.waitGroup.Done()\n\tfor request := range pool.schedule {\n\t\tif request == nil {\n\t\t\treturn\n\t\t}\n\t\trequest.RunAndReply()\n\t}\n}\n\n// SetMaxPending changes the queue size\nfunc (pool *WorkerPool) SetMaxPending(value uint) {\n\tif pool.maxPending == value {\n\t\treturn\n\t}\n\tpool.m.Lock()\n\tdefer pool.m.Unlock()\n\n\toldQueue := pool.queue\n\tpool.queue = make(chan *Request, value)\n\tpool.maxPending = value\n\n\tclose(oldQueue)\n\n\t// drain the old queue and cancel requests if there are too many\n\tfor request := range oldQueue {\n\t\tselect {\n\t\tcase pool.queue <- request:\n\t\tdefault:\n\t\t\trequest.SendErrorTooBusy(\"too many pending requests\")\n\t\t}\n\t}\n}\n\n// SetMaxPendingDuration changes the max pending delay\nfunc (pool *WorkerPool) SetMaxPendingDuration(value time.Duration) {\n\tpool.m.Lock()\n\tpool.maxPendingDuration = value\n\tpool.m.Unlock()\n}\n\n// SetSize changes the number of workers\nfunc (pool *WorkerPool) SetSize(size uint) {\n\tpool.m.Lock()\n\tdefer pool.m.Unlock()\n\n\tif size == pool.size {\n\t\treturn\n\t}\n\tfor size < pool.size {\n\t\tpool.schedule <- nil\n\t\tpool.size--\n\t}\n\tfor size > pool.size {\n\t\tpool.waitGroup.Add(1)\n\t\tgo pool.worker()\n\t\tpool.size++\n\t}\n}\n\n// QueueRequest adds a request to the queue\n// Send a SERVERTOOBUSY error to the client if the queue is full\nfunc (pool *WorkerPool) QueueRequest(request *Request) error {\n\tselect {\n\tcase pool.getQueue() <- request:\n\t\trequest.setupStreamedReply()\n\t\treturn nil\n\tdefault:\n\t\treturn request.SendErrorTooBusy(\"too many pending requests\")\n\t}\n}\n\n// Close stops all the workers and wait for their completion\n// If the workers do not stop before the timeout, their context is canceled\n// Will never return if a request ignores the context\nfunc (pool *WorkerPool) Close(timeout time.Duration) {\n\t// Stops all the workers so nothing more gets scheduled\n\tpool.SetSize(0)\n\n\tpool.m.Lock()\n\toldQueue := pool.queue\n\tpool.queue = nil\n\tpool.m.Unlock()\n\n\tclose(oldQueue)\n\tfor request := range oldQueue {\n\t\trequest.SendErrorTooBusy(\"Worker pool shutting down\")\n\t}\n\n\t// Now wait for the workers to stop and cancel the context if they don't\n\ttimer := time.AfterFunc(timeout, pool.contextCancel)\n\tpool.waitGroup.Wait()\n\ttimer.Stop()\n\tclose(pool.schedule)\n}\n"
  },
  {
    "path": "nrpc.pb.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.29.0\n// \tprotoc        v4.22.2\n// source: nrpc.proto\n\npackage nrpc\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\tdescriptorpb \"google.golang.org/protobuf/types/descriptorpb\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype SubjectRule int32\n\nconst (\n\tSubjectRule_COPY    SubjectRule = 0\n\tSubjectRule_TOLOWER SubjectRule = 1\n)\n\n// Enum value maps for SubjectRule.\nvar (\n\tSubjectRule_name = map[int32]string{\n\t\t0: \"COPY\",\n\t\t1: \"TOLOWER\",\n\t}\n\tSubjectRule_value = map[string]int32{\n\t\t\"COPY\":    0,\n\t\t\"TOLOWER\": 1,\n\t}\n)\n\nfunc (x SubjectRule) Enum() *SubjectRule {\n\tp := new(SubjectRule)\n\t*p = x\n\treturn p\n}\n\nfunc (x SubjectRule) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (SubjectRule) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_nrpc_proto_enumTypes[0].Descriptor()\n}\n\nfunc (SubjectRule) Type() protoreflect.EnumType {\n\treturn &file_nrpc_proto_enumTypes[0]\n}\n\nfunc (x SubjectRule) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use SubjectRule.Descriptor instead.\nfunc (SubjectRule) EnumDescriptor() ([]byte, []int) {\n\treturn file_nrpc_proto_rawDescGZIP(), []int{0}\n}\n\ntype Error_Type int32\n\nconst (\n\tError_CLIENT        Error_Type = 0\n\tError_SERVER        Error_Type = 1\n\tError_EOS           Error_Type = 3\n\tError_SERVERTOOBUSY Error_Type = 4\n)\n\n// Enum value maps for Error_Type.\nvar (\n\tError_Type_name = map[int32]string{\n\t\t0: \"CLIENT\",\n\t\t1: \"SERVER\",\n\t\t3: \"EOS\",\n\t\t4: \"SERVERTOOBUSY\",\n\t}\n\tError_Type_value = map[string]int32{\n\t\t\"CLIENT\":        0,\n\t\t\"SERVER\":        1,\n\t\t\"EOS\":           3,\n\t\t\"SERVERTOOBUSY\": 4,\n\t}\n)\n\nfunc (x Error_Type) Enum() *Error_Type {\n\tp := new(Error_Type)\n\t*p = x\n\treturn p\n}\n\nfunc (x Error_Type) String() string {\n\treturn protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x))\n}\n\nfunc (Error_Type) Descriptor() protoreflect.EnumDescriptor {\n\treturn file_nrpc_proto_enumTypes[1].Descriptor()\n}\n\nfunc (Error_Type) Type() protoreflect.EnumType {\n\treturn &file_nrpc_proto_enumTypes[1]\n}\n\nfunc (x Error_Type) Number() protoreflect.EnumNumber {\n\treturn protoreflect.EnumNumber(x)\n}\n\n// Deprecated: Use Error_Type.Descriptor instead.\nfunc (Error_Type) EnumDescriptor() ([]byte, []int) {\n\treturn file_nrpc_proto_rawDescGZIP(), []int{0, 0}\n}\n\ntype Error struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tType     Error_Type `protobuf:\"varint,1,opt,name=type,proto3,enum=nrpc.Error_Type\" json:\"type,omitempty\"`\n\tMessage  string     `protobuf:\"bytes,2,opt,name=message,proto3\" json:\"message,omitempty\"`\n\tMsgCount uint32     `protobuf:\"varint,3,opt,name=msgCount,proto3\" json:\"msgCount,omitempty\"`\n}\n\nfunc (x *Error) Reset() {\n\t*x = Error{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_nrpc_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Error) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Error) ProtoMessage() {}\n\nfunc (x *Error) ProtoReflect() protoreflect.Message {\n\tmi := &file_nrpc_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Error.ProtoReflect.Descriptor instead.\nfunc (*Error) Descriptor() ([]byte, []int) {\n\treturn file_nrpc_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *Error) GetType() Error_Type {\n\tif x != nil {\n\t\treturn x.Type\n\t}\n\treturn Error_CLIENT\n}\n\nfunc (x *Error) GetMessage() string {\n\tif x != nil {\n\t\treturn x.Message\n\t}\n\treturn \"\"\n}\n\nfunc (x *Error) GetMsgCount() uint32 {\n\tif x != nil {\n\t\treturn x.MsgCount\n\t}\n\treturn 0\n}\n\ntype Void struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n}\n\nfunc (x *Void) Reset() {\n\t*x = Void{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_nrpc_proto_msgTypes[1]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *Void) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*Void) ProtoMessage() {}\n\nfunc (x *Void) ProtoReflect() protoreflect.Message {\n\tmi := &file_nrpc_proto_msgTypes[1]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use Void.ProtoReflect.Descriptor instead.\nfunc (*Void) Descriptor() ([]byte, []int) {\n\treturn file_nrpc_proto_rawDescGZIP(), []int{1}\n}\n\ntype NoRequest struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n}\n\nfunc (x *NoRequest) Reset() {\n\t*x = NoRequest{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_nrpc_proto_msgTypes[2]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NoRequest) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NoRequest) ProtoMessage() {}\n\nfunc (x *NoRequest) ProtoReflect() protoreflect.Message {\n\tmi := &file_nrpc_proto_msgTypes[2]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use NoRequest.ProtoReflect.Descriptor instead.\nfunc (*NoRequest) Descriptor() ([]byte, []int) {\n\treturn file_nrpc_proto_rawDescGZIP(), []int{2}\n}\n\ntype NoReply struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n}\n\nfunc (x *NoReply) Reset() {\n\t*x = NoReply{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_nrpc_proto_msgTypes[3]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *NoReply) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*NoReply) ProtoMessage() {}\n\nfunc (x *NoReply) ProtoReflect() protoreflect.Message {\n\tmi := &file_nrpc_proto_msgTypes[3]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use NoReply.ProtoReflect.Descriptor instead.\nfunc (*NoReply) Descriptor() ([]byte, []int) {\n\treturn file_nrpc_proto_rawDescGZIP(), []int{3}\n}\n\ntype HeartBeat struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tLastbeat bool `protobuf:\"varint,1,opt,name=lastbeat,proto3\" json:\"lastbeat,omitempty\"`\n}\n\nfunc (x *HeartBeat) Reset() {\n\t*x = HeartBeat{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_nrpc_proto_msgTypes[4]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *HeartBeat) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*HeartBeat) ProtoMessage() {}\n\nfunc (x *HeartBeat) ProtoReflect() protoreflect.Message {\n\tmi := &file_nrpc_proto_msgTypes[4]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use HeartBeat.ProtoReflect.Descriptor instead.\nfunc (*HeartBeat) Descriptor() ([]byte, []int) {\n\treturn file_nrpc_proto_rawDescGZIP(), []int{4}\n}\n\nfunc (x *HeartBeat) GetLastbeat() bool {\n\tif x != nil {\n\t\treturn x.Lastbeat\n\t}\n\treturn false\n}\n\nvar file_nrpc_proto_extTypes = []protoimpl.ExtensionInfo{\n\t{\n\t\tExtendedType:  (*descriptorpb.FileOptions)(nil),\n\t\tExtensionType: (*string)(nil),\n\t\tField:         50000,\n\t\tName:          \"nrpc.packageSubject\",\n\t\tTag:           \"bytes,50000,opt,name=packageSubject\",\n\t\tFilename:      \"nrpc.proto\",\n\t},\n\t{\n\t\tExtendedType:  (*descriptorpb.FileOptions)(nil),\n\t\tExtensionType: ([]string)(nil),\n\t\tField:         50001,\n\t\tName:          \"nrpc.packageSubjectParams\",\n\t\tTag:           \"bytes,50001,rep,name=packageSubjectParams\",\n\t\tFilename:      \"nrpc.proto\",\n\t},\n\t{\n\t\tExtendedType:  (*descriptorpb.FileOptions)(nil),\n\t\tExtensionType: (*SubjectRule)(nil),\n\t\tField:         50002,\n\t\tName:          \"nrpc.serviceSubjectRule\",\n\t\tTag:           \"varint,50002,opt,name=serviceSubjectRule,enum=nrpc.SubjectRule\",\n\t\tFilename:      \"nrpc.proto\",\n\t},\n\t{\n\t\tExtendedType:  (*descriptorpb.FileOptions)(nil),\n\t\tExtensionType: (*SubjectRule)(nil),\n\t\tField:         50003,\n\t\tName:          \"nrpc.methodSubjectRule\",\n\t\tTag:           \"varint,50003,opt,name=methodSubjectRule,enum=nrpc.SubjectRule\",\n\t\tFilename:      \"nrpc.proto\",\n\t},\n\t{\n\t\tExtendedType:  (*descriptorpb.ServiceOptions)(nil),\n\t\tExtensionType: (*string)(nil),\n\t\tField:         51000,\n\t\tName:          \"nrpc.serviceSubject\",\n\t\tTag:           \"bytes,51000,opt,name=serviceSubject\",\n\t\tFilename:      \"nrpc.proto\",\n\t},\n\t{\n\t\tExtendedType:  (*descriptorpb.ServiceOptions)(nil),\n\t\tExtensionType: ([]string)(nil),\n\t\tField:         51001,\n\t\tName:          \"nrpc.serviceSubjectParams\",\n\t\tTag:           \"bytes,51001,rep,name=serviceSubjectParams\",\n\t\tFilename:      \"nrpc.proto\",\n\t},\n\t{\n\t\tExtendedType:  (*descriptorpb.MethodOptions)(nil),\n\t\tExtensionType: (*string)(nil),\n\t\tField:         52000,\n\t\tName:          \"nrpc.methodSubject\",\n\t\tTag:           \"bytes,52000,opt,name=methodSubject\",\n\t\tFilename:      \"nrpc.proto\",\n\t},\n\t{\n\t\tExtendedType:  (*descriptorpb.MethodOptions)(nil),\n\t\tExtensionType: ([]string)(nil),\n\t\tField:         52001,\n\t\tName:          \"nrpc.methodSubjectParams\",\n\t\tTag:           \"bytes,52001,rep,name=methodSubjectParams\",\n\t\tFilename:      \"nrpc.proto\",\n\t},\n\t{\n\t\tExtendedType:  (*descriptorpb.MethodOptions)(nil),\n\t\tExtensionType: (*bool)(nil),\n\t\tField:         52002,\n\t\tName:          \"nrpc.streamedReply\",\n\t\tTag:           \"varint,52002,opt,name=streamedReply\",\n\t\tFilename:      \"nrpc.proto\",\n\t},\n\t{\n\t\tExtendedType:  (*descriptorpb.MethodOptions)(nil),\n\t\tExtensionType: (*bool)(nil),\n\t\tField:         52003,\n\t\tName:          \"nrpc.pollingEnabled\",\n\t\tTag:           \"varint,52003,opt,name=pollingEnabled\",\n\t\tFilename:      \"nrpc.proto\",\n\t},\n}\n\n// Extension fields to descriptorpb.FileOptions.\nvar (\n\t// A custom subject prefix to use instead of the package name\n\t//\n\t// optional string packageSubject = 50000;\n\tE_PackageSubject = &file_nrpc_proto_extTypes[0]\n\t// Parameters included in the subject at the package level\n\t//\n\t// repeated string packageSubjectParams = 50001;\n\tE_PackageSubjectParams = &file_nrpc_proto_extTypes[1]\n\t// Default rule to build a service subject from the service name\n\t//\n\t// optional nrpc.SubjectRule serviceSubjectRule = 50002;\n\tE_ServiceSubjectRule = &file_nrpc_proto_extTypes[2]\n\t// Default rule to build a method subject from its name\n\t//\n\t// optional nrpc.SubjectRule methodSubjectRule = 50003;\n\tE_MethodSubjectRule = &file_nrpc_proto_extTypes[3]\n)\n\n// Extension fields to descriptorpb.ServiceOptions.\nvar (\n\t// A custom subject token to use instead of (service name + serviceSubjectRule)\n\t//\n\t// optional string serviceSubject = 51000;\n\tE_ServiceSubject = &file_nrpc_proto_extTypes[4]\n\t// Parameters included in the subject at the service level\n\t//\n\t// repeated string serviceSubjectParams = 51001;\n\tE_ServiceSubjectParams = &file_nrpc_proto_extTypes[5]\n)\n\n// Extension fields to descriptorpb.MethodOptions.\nvar (\n\t// A custom subject to use instead of (methor name + methodSubjectRule)\n\t//\n\t// optional string methodSubject = 52000;\n\tE_MethodSubject = &file_nrpc_proto_extTypes[6]\n\t// Parameters included in the subject at the method level\n\t//\n\t// repeated string methodSubjectParams = 52001;\n\tE_MethodSubjectParams = &file_nrpc_proto_extTypes[7]\n\t// If true, the method returns a stream of reply messages instead of just one\n\t//\n\t// optional bool streamedReply = 52002;\n\tE_StreamedReply = &file_nrpc_proto_extTypes[8]\n\t// If true, a 'Polling' version of the client method is generated\n\t//\n\t// optional bool pollingEnabled = 52003;\n\tE_PollingEnabled = &file_nrpc_proto_extTypes[9]\n)\n\nvar File_nrpc_proto protoreflect.FileDescriptor\n\nvar file_nrpc_proto_rawDesc = []byte{\n\t0x0a, 0x0a, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x04, 0x6e, 0x72,\n\t0x70, 0x63, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f,\n\t0x62, 0x75, 0x66, 0x2f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x6f, 0x72, 0x2e, 0x70,\n\t0x72, 0x6f, 0x74, 0x6f, 0x22, 0x9f, 0x01, 0x0a, 0x05, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x24,\n\t0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x6e,\n\t0x72, 0x70, 0x63, 0x2e, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04,\n\t0x74, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18,\n\t0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x1a,\n\t0x0a, 0x08, 0x6d, 0x73, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d,\n\t0x52, 0x08, 0x6d, 0x73, 0x67, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x3a, 0x0a, 0x04, 0x54, 0x79,\n\t0x70, 0x65, 0x12, 0x0a, 0x0a, 0x06, 0x43, 0x4c, 0x49, 0x45, 0x4e, 0x54, 0x10, 0x00, 0x12, 0x0a,\n\t0x0a, 0x06, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x45, 0x4f,\n\t0x53, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x45, 0x52, 0x56, 0x45, 0x52, 0x54, 0x4f, 0x4f,\n\t0x42, 0x55, 0x53, 0x59, 0x10, 0x04, 0x22, 0x06, 0x0a, 0x04, 0x56, 0x6f, 0x69, 0x64, 0x22, 0x0b,\n\t0x0a, 0x09, 0x4e, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x09, 0x0a, 0x07, 0x4e,\n\t0x6f, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x27, 0x0a, 0x09, 0x48, 0x65, 0x61, 0x72, 0x74, 0x42,\n\t0x65, 0x61, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x62, 0x65, 0x61, 0x74, 0x18,\n\t0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x08, 0x6c, 0x61, 0x73, 0x74, 0x62, 0x65, 0x61, 0x74, 0x2a,\n\t0x24, 0x0a, 0x0b, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x08,\n\t0x0a, 0x04, 0x43, 0x4f, 0x50, 0x59, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x54, 0x4f, 0x4c, 0x4f,\n\t0x57, 0x45, 0x52, 0x10, 0x01, 0x3a, 0x46, 0x0a, 0x0e, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65,\n\t0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,\n\t0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70,\n\t0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd0, 0x86, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x70,\n\t0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a, 0x52, 0x0a,\n\t0x14, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50,\n\t0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70,\n\t0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70, 0x74, 0x69,\n\t0x6f, 0x6e, 0x73, 0x18, 0xd1, 0x86, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x70, 0x61, 0x63,\n\t0x6b, 0x61, 0x67, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d,\n\t0x73, 0x3a, 0x61, 0x0a, 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x6a,\n\t0x65, 0x63, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,\n\t0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65, 0x4f, 0x70,\n\t0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd2, 0x86, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e,\n\t0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x75, 0x6c, 0x65,\n\t0x52, 0x12, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74,\n\t0x52, 0x75, 0x6c, 0x65, 0x3a, 0x5f, 0x0a, 0x11, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x75,\n\t0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67,\n\t0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x46, 0x69, 0x6c, 0x65,\n\t0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xd3, 0x86, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32,\n\t0x11, 0x2e, 0x6e, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x75,\n\t0x6c, 0x65, 0x52, 0x11, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,\n\t0x74, 0x52, 0x75, 0x6c, 0x65, 0x3a, 0x49, 0x0a, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65,\n\t0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65,\n\t0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63,\n\t0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb8, 0x8e, 0x03, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x0e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74,\n\t0x3a, 0x55, 0x0a, 0x14, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65,\n\t0x63, 0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1f, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,\n\t0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x69,\n\t0x63, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xb9, 0x8e, 0x03, 0x20, 0x03, 0x28,\n\t0x09, 0x52, 0x14, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63,\n\t0x74, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x3a, 0x46, 0x0a, 0x0d, 0x6d, 0x65, 0x74, 0x68, 0x6f,\n\t0x64, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,\n\t0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f,\n\t0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xa0, 0x96, 0x03, 0x20, 0x01, 0x28, 0x09,\n\t0x52, 0x0d, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x3a,\n\t0x52, 0x0a, 0x13, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74,\n\t0x50, 0x61, 0x72, 0x61, 0x6d, 0x73, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,\n\t0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f,\n\t0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xa1, 0x96, 0x03, 0x20, 0x03, 0x28, 0x09, 0x52, 0x13,\n\t0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x53, 0x75, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x50, 0x61, 0x72,\n\t0x61, 0x6d, 0x73, 0x3a, 0x46, 0x0a, 0x0d, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x65, 0x64, 0x52,\n\t0x65, 0x70, 0x6c, 0x79, 0x12, 0x1e, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,\n\t0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74,\n\t0x69, 0x6f, 0x6e, 0x73, 0x18, 0xa2, 0x96, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0d, 0x73, 0x74,\n\t0x72, 0x65, 0x61, 0x6d, 0x65, 0x64, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x3a, 0x48, 0x0a, 0x0e, 0x70,\n\t0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1e, 0x2e,\n\t0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,\n\t0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xa3, 0x96,\n\t0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0e, 0x70, 0x6f, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x45, 0x6e,\n\t0x61, 0x62, 0x6c, 0x65, 0x64, 0x42, 0x1a, 0x5a, 0x18, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,\n\t0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x61, 0x74, 0x73, 0x2d, 0x72, 0x70, 0x63, 0x2f, 0x6e, 0x72, 0x70,\n\t0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,\n}\n\nvar (\n\tfile_nrpc_proto_rawDescOnce sync.Once\n\tfile_nrpc_proto_rawDescData = file_nrpc_proto_rawDesc\n)\n\nfunc file_nrpc_proto_rawDescGZIP() []byte {\n\tfile_nrpc_proto_rawDescOnce.Do(func() {\n\t\tfile_nrpc_proto_rawDescData = protoimpl.X.CompressGZIP(file_nrpc_proto_rawDescData)\n\t})\n\treturn file_nrpc_proto_rawDescData\n}\n\nvar file_nrpc_proto_enumTypes = make([]protoimpl.EnumInfo, 2)\nvar file_nrpc_proto_msgTypes = make([]protoimpl.MessageInfo, 5)\nvar file_nrpc_proto_goTypes = []interface{}{\n\t(SubjectRule)(0),                    // 0: nrpc.SubjectRule\n\t(Error_Type)(0),                     // 1: nrpc.Error.Type\n\t(*Error)(nil),                       // 2: nrpc.Error\n\t(*Void)(nil),                        // 3: nrpc.Void\n\t(*NoRequest)(nil),                   // 4: nrpc.NoRequest\n\t(*NoReply)(nil),                     // 5: nrpc.NoReply\n\t(*HeartBeat)(nil),                   // 6: nrpc.HeartBeat\n\t(*descriptorpb.FileOptions)(nil),    // 7: google.protobuf.FileOptions\n\t(*descriptorpb.ServiceOptions)(nil), // 8: google.protobuf.ServiceOptions\n\t(*descriptorpb.MethodOptions)(nil),  // 9: google.protobuf.MethodOptions\n}\nvar file_nrpc_proto_depIdxs = []int32{\n\t1,  // 0: nrpc.Error.type:type_name -> nrpc.Error.Type\n\t7,  // 1: nrpc.packageSubject:extendee -> google.protobuf.FileOptions\n\t7,  // 2: nrpc.packageSubjectParams:extendee -> google.protobuf.FileOptions\n\t7,  // 3: nrpc.serviceSubjectRule:extendee -> google.protobuf.FileOptions\n\t7,  // 4: nrpc.methodSubjectRule:extendee -> google.protobuf.FileOptions\n\t8,  // 5: nrpc.serviceSubject:extendee -> google.protobuf.ServiceOptions\n\t8,  // 6: nrpc.serviceSubjectParams:extendee -> google.protobuf.ServiceOptions\n\t9,  // 7: nrpc.methodSubject:extendee -> google.protobuf.MethodOptions\n\t9,  // 8: nrpc.methodSubjectParams:extendee -> google.protobuf.MethodOptions\n\t9,  // 9: nrpc.streamedReply:extendee -> google.protobuf.MethodOptions\n\t9,  // 10: nrpc.pollingEnabled:extendee -> google.protobuf.MethodOptions\n\t0,  // 11: nrpc.serviceSubjectRule:type_name -> nrpc.SubjectRule\n\t0,  // 12: nrpc.methodSubjectRule:type_name -> nrpc.SubjectRule\n\t13, // [13:13] is the sub-list for method output_type\n\t13, // [13:13] is the sub-list for method input_type\n\t11, // [11:13] is the sub-list for extension type_name\n\t1,  // [1:11] is the sub-list for extension extendee\n\t0,  // [0:1] is the sub-list for field type_name\n}\n\nfunc init() { file_nrpc_proto_init() }\nfunc file_nrpc_proto_init() {\n\tif File_nrpc_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_nrpc_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Error); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_nrpc_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*Void); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_nrpc_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NoRequest); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_nrpc_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*NoReply); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t\tfile_nrpc_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*HeartBeat); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_nrpc_proto_rawDesc,\n\t\t\tNumEnums:      2,\n\t\t\tNumMessages:   5,\n\t\t\tNumExtensions: 10,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_nrpc_proto_goTypes,\n\t\tDependencyIndexes: file_nrpc_proto_depIdxs,\n\t\tEnumInfos:         file_nrpc_proto_enumTypes,\n\t\tMessageInfos:      file_nrpc_proto_msgTypes,\n\t\tExtensionInfos:    file_nrpc_proto_extTypes,\n\t}.Build()\n\tFile_nrpc_proto = out.File\n\tfile_nrpc_proto_rawDesc = nil\n\tfile_nrpc_proto_goTypes = nil\n\tfile_nrpc_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "nrpc.proto",
    "content": "syntax = \"proto3\";\n\npackage nrpc;\n\noption go_package = \"github.com/nats-rpc/nrpc\";\n\nimport \"google/protobuf/descriptor.proto\";\n\nenum SubjectRule {\n    COPY = 0;\n    TOLOWER = 1;\n}\n\nextend google.protobuf.FileOptions {\n    // A custom subject prefix to use instead of the package name\n    string packageSubject = 50000;\n    // Parameters included in the subject at the package level\n    repeated string packageSubjectParams = 50001;\n    // Default rule to build a service subject from the service name\n    SubjectRule serviceSubjectRule = 50002;\n    // Default rule to build a method subject from its name\n    SubjectRule methodSubjectRule = 50003;\n}\n\nextend google.protobuf.ServiceOptions {\n\t// A custom subject token to use instead of (service name + serviceSubjectRule)\n\tstring serviceSubject = 51000;\n\t// Parameters included in the subject at the service level\n\trepeated string serviceSubjectParams = 51001;\n}\n\nextend google.protobuf.MethodOptions {\n    // A custom subject to use instead of (methor name + methodSubjectRule)\n    string methodSubject = 52000;\n    // Parameters included in the subject at the method level\n    repeated string methodSubjectParams = 52001;\n    // If true, the method returns a stream of reply messages instead of just one\n    bool streamedReply = 52002;\n    // If true, a 'Polling' version of the client method is generated\n    bool pollingEnabled = 52003;\n}\n\nmessage Error {\n    enum Type {\n        CLIENT = 0;\n        SERVER = 1;\n        EOS = 3;\n        SERVERTOOBUSY = 4;\n    }\n    Type type = 1;\n    string message = 2;\n    uint32 msgCount = 3;\n}\n\nmessage Void {}\n\nmessage NoRequest {}\nmessage NoReply {}\n\nmessage HeartBeat {\n    bool lastbeat = 1;\n}\n"
  },
  {
    "path": "nrpc_test.go",
    "content": "package nrpc_test\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"fmt\"\n\t\"log\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats.go\"\n\t\"google.golang.org/protobuf/proto\"\n\n\t\"github.com/nats-rpc/nrpc\"\n)\n\n//go:generate protoc --go_out=. --go_opt=paths=source_relative nrpc_test.proto\n//go:generate mv nrpc_test.pb.go nrpcpb_test.go\n\nfunc TestBasic(t *testing.T) {\n\tnc, err := nats.Connect(nrpc.NatsURL, nats.Timeout(5*time.Second))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer nc.Close()\n\n\tsubn, err := nc.Subscribe(\"foo.*\", func(m *nats.Msg) {\n\t\tif err := nrpc.Publish(&DummyMessage{Foobar: \"world\"}, nil, nc, m.Reply, \"protobuf\"); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer subn.Unsubscribe()\n\n\tvar dm DummyMessage\n\tif err := nrpc.Call(\n\t\t&DummyMessage{Foobar: \"hello\"}, &dm, nc, \"foo.bar\", \"protobuf\", 5*time.Second,\n\t); err != nil {\n\t\tt.Fatal(err)\n\t}\n\tif dm.Foobar != \"world\" {\n\t\tt.Fatal(\"wrong response: \", string(dm.Foobar))\n\t}\n}\n\nfunc TestDecode(t *testing.T) {\n\tnc, err := nats.Connect(nrpc.NatsURL, nats.Timeout(5*time.Second))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer nc.Close()\n\n\tvar name string\n\tsubn, err := nc.Subscribe(\"foo.*\", func(m *nats.Msg) {\n\t\trname := strings.Split(m.Subject, \".\")[1]\n\t\tvar dm DummyMessage\n\t\tif rname != name {\n\t\t\tt.Fatal(\"unexpected name: \" + rname)\n\t\t} else if err := proto.Unmarshal(m.Data, &dm); err != nil {\n\t\t\tt.Fatal(err)\n\t\t} else if dm.Foobar != \"hello\" {\n\t\t\tt.Fatal(\"unexpected inner request: \" + dm.Foobar)\n\t\t} else if err := nrpc.Publish(&DummyMessage{Foobar: \"world\"}, nil, nc, m.Reply, \"protobuf\"); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer subn.Unsubscribe()\n\n\tvar names = []string{\"lorem\", \"ipsum\", \"dolor\"}\n\tfor _, n := range names {\n\t\tname = n\n\t\tvar dm DummyMessage\n\t\tif err := nrpc.Call(\n\t\t\t&DummyMessage{Foobar: \"hello\"}, &dm, nc, \"foo.\"+name, \"protobuf\", 5*time.Second,\n\t\t); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif dm.Foobar != \"world\" {\n\t\t\tt.Fatal(\"wrong response: \", string(dm.Foobar))\n\t\t}\n\t}\n}\n\nfunc TestStreamCall(t *testing.T) {\n\tnc, err := nats.Connect(nrpc.NatsURL, nats.Timeout(5*time.Second))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer nc.Close()\n\n\tt.Run(\"Simple stream\", func(t *testing.T) {\n\t\tsubn, err := nc.Subscribe(\"foo.*\", func(m *nats.Msg) {\n\t\t\ttime.Sleep(60 * time.Millisecond)\n\t\t\t// Send an empty message\n\t\t\tif err := nc.Publish(m.Reply, []byte{0}); err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\ttime.Sleep(60 * time.Millisecond)\n\t\t\t// Send a first message\n\t\t\tif err := nrpc.Publish(\n\t\t\t\t&DummyMessage{Foobar: \"hello\"},\n\t\t\t\tnil,\n\t\t\t\tnc, m.Reply, \"protobuf\",\n\t\t\t); err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\ttime.Sleep(60 * time.Millisecond)\n\t\t\tlog.Print(\"Sending 'world'\")\n\t\t\t// Send a second message\n\t\t\tif err := nrpc.Publish(\n\t\t\t\t&DummyMessage{Foobar: \"world\"},\n\t\t\t\tnil,\n\t\t\t\tnc, m.Reply, \"protobuf\",\n\t\t\t); err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tlog.Print(\"Sending EOF\")\n\t\t\t// Send the EOS marker\n\t\t\tif err := nrpc.Publish(\n\t\t\t\tnil,\n\t\t\t\t&nrpc.Error{Type: nrpc.Error_EOS, MsgCount: 2},\n\t\t\t\tnc, m.Reply, \"protobuf\",\n\t\t\t); err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tdefer subn.Unsubscribe()\n\n\t\tsub, err := nrpc.StreamCall(\n\t\t\tcontext.TODO(), nc, \"foo.*\", &DummyMessage{}, \"protobuf\", 100*time.Millisecond)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tvar dm DummyMessage\n\t\tvar cont bool\n\n\t\terr = sub.Next(&dm)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\terr = sub.Next(&dm)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\terr = sub.Next(&dm)\n\t\tif err != nrpc.ErrEOS {\n\t\t\tt.Fatalf(\"Expected EOS, got %s\", err)\n\t\t}\n\t\tif cont {\n\t\t\tt.Errorf(\"Expects cont=false\")\n\t\t}\n\t\terr = sub.Next(&dm)\n\t\tif err != nats.ErrBadSubscription {\n\t\t\tt.Errorf(\"Expected a ErrBadSubscription, got %s\", err)\n\t\t}\n\t})\n\n\tt.Run(\"Error\", func(t *testing.T) {\n\t\tsubn, err := nc.Subscribe(\"foo.*\", func(m *nats.Msg) {\n\t\t\tif err := nrpc.Publish(\n\t\t\t\tnil,\n\t\t\t\t&nrpc.Error{Type: nrpc.Error_CLIENT, Message: \"error\"},\n\t\t\t\tnc, m.Reply, \"protobuf\",\n\t\t\t); err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tdefer subn.Unsubscribe()\n\n\t\tsub, err := nrpc.StreamCall(\n\t\t\tcontext.TODO(), nc, \"foo.*\", &DummyMessage{}, \"protobuf\", 100*time.Millisecond)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\terr = sub.Next(&DummyMessage{})\n\t\tif err == nil {\n\t\t\tt.Fatalf(\"Expected an error, got %s\", err)\n\t\t}\n\t\tif nErr, ok := err.(*nrpc.Error); ok {\n\t\t\tif nErr.Message != \"error\" {\n\t\t\t\tt.Errorf(\"Expected message='error', got %s\", nErr.Message)\n\t\t\t}\n\t\t} else {\n\t\t\tt.Errorf(\"Expected a nrpc.Error, got %s\", err)\n\t\t}\n\t\terr = sub.Next(&DummyMessage{})\n\t\tif err != nats.ErrBadSubscription {\n\t\t\tt.Errorf(\"Expected a ErrBadSubscription, got %s\", err)\n\t\t}\n\t})\n}\n\nfunc TestError(t *testing.T) {\n\tnc, err := nats.Connect(nrpc.NatsURL, nats.Timeout(5*time.Second))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer nc.Close()\n\n\tsubn, err := nc.Subscribe(\"foo.*\", func(m *nats.Msg) {\n\t\tif err := nrpc.Publish(\n\t\t\t&DummyMessage{Foobar: \"world\"},\n\t\t\t&nrpc.Error{Type: nrpc.Error_CLIENT, Message: \"anerror\"},\n\t\t\tnc, m.Reply, \"protobuf\",\n\t\t); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer subn.Unsubscribe()\n\n\terr = nrpc.Call(&DummyMessage{Foobar: \"hello\"}, &DummyMessage{}, nc, \"foo.bar\", \"protobuf\", 5*time.Second)\n\tif err == nil {\n\t\tt.Fatal(\"error expected\")\n\t}\n\tif err.Error() != \"CLIENT error: anerror\" {\n\t\tt.Fatal(\"wrong error: \", err.Error())\n\t}\n}\n\nfunc TestTimeout(t *testing.T) {\n\tnc, err := nats.Connect(nrpc.NatsURL, nats.Timeout(5*time.Second))\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer nc.Close()\n\n\tsubn, err := nc.Subscribe(\"foo.*\", func(m *nats.Msg) {\n\t\ttime.Sleep(time.Second)\n\t\tif err := nrpc.Publish(&DummyMessage{Foobar: \"world\"}, nil, nc, m.Reply, \"protobuf\"); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t})\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\tdefer subn.Unsubscribe()\n\n\terr = nrpc.Call(&DummyMessage{Foobar: \"hello\"}, &DummyMessage{}, nc, \"foo.bar\", \"protobuf\", 500*time.Millisecond)\n\tif err == nil {\n\t\tt.Fatal(\"error expected\")\n\t} else if err.Error() != \"nats: timeout\" {\n\t\tt.Fatal(\"unexpected error: \" + err.Error())\n\t}\n}\n\nvar (\n\tencodingTestMsg = DummyMessage{Foobar: \"hello\"}\n\tencodingTests   = []struct {\n\t\tencoding string\n\t\tdata     []byte\n\t}{\n\t\t{\"protobuf\", []byte{10, 5, 104, 101, 108, 108, 111}},\n\t\t{\"json\", []byte(`{\"foobar\":\"hello\"}`)},\n\t}\n)\n\nfunc TestMarshal(t *testing.T) {\n\tfor _, tt := range encodingTests {\n\t\tt.Run(\"Marshal\"+tt.encoding, func(t *testing.T) {\n\t\t\tb, err := nrpc.Marshal(tt.encoding, &encodingTestMsg)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif !bytes.Equal(b, tt.data) {\n\t\t\t\tt.Errorf(\"Marshal %s failed\", tt.encoding)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestUnmarshal(t *testing.T) {\n\tfor _, tt := range encodingTests {\n\t\tt.Run(\"Unmarshal\"+tt.encoding, func(t *testing.T) {\n\t\t\tvar msg DummyMessage\n\t\t\terr := nrpc.Unmarshal(tt.encoding, tt.data, &msg)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif msg.Foobar != encodingTestMsg.Foobar {\n\t\t\t\tt.Errorf(\n\t\t\t\t\t\"%s decode failed. Expected %#v, got %#v\",\n\t\t\t\t\ttt.encoding, encodingTestMsg, msg)\n\t\t\t}\n\t\t})\n\t}\n}\n\nfunc TestMarshalUnmarshalResponse(t *testing.T) {\n\tfor _, tt := range encodingTests {\n\t\tt.Run(\"UnmarshalResponse\"+tt.encoding, func(t *testing.T) {\n\t\t\tvar msg DummyMessage\n\t\t\terr := nrpc.UnmarshalResponse(tt.encoding, tt.data, &msg)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif msg.Foobar != encodingTestMsg.Foobar {\n\t\t\t\tt.Errorf(\n\t\t\t\t\t\"%s decode failed. Expected %#v, got %#v\",\n\t\t\t\t\ttt.encoding, encodingTestMsg, msg)\n\t\t\t}\n\t\t})\n\t\tt.Run(\"MarshalErrorResponse\"+tt.encoding, func(t *testing.T) {\n\t\t\tdata, err := nrpc.MarshalErrorResponse(tt.encoding, &nrpc.Error{\n\t\t\t\tType: nrpc.Error_SERVER, Message: \"Some error\",\n\t\t\t})\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(\"Unexpected error:\", err)\n\t\t\t}\n\t\t\tswitch tt.encoding {\n\t\t\tcase \"protobuf\":\n\t\t\t\tif data[0] != 0 {\n\t\t\t\t\tt.Error(\"Expects payload to start with a '0', got\", data[0])\n\t\t\t\t}\n\t\t\tcase \"json\":\n\t\t\t\tvar expected = `{\"__error__\":{\"type\":\"SERVER\",\"message\":\"Some error\"}}`\n\t\t\t\tif string(data) != expected {\n\t\t\t\t\tt.Errorf(\"Invalid json-encoded error. Expects %s, got %s\", expected, string(data))\n\t\t\t\t}\n\t\t\t}\n\t\t\tvar msg DummyMessage\n\t\t\terr = nrpc.UnmarshalResponse(tt.encoding, data, &msg)\n\t\t\tif err == nil {\n\t\t\t\tt.Errorf(\"Expected an error, got nil\")\n\t\t\t\treturn\n\t\t\t}\n\t\t\trepErr, ok := err.(*nrpc.Error)\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"Expected a nrpc.Error, got %#v\", err)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tif repErr.Type != nrpc.Error_SERVER || repErr.Message != \"Some error\" {\n\t\t\t\tt.Errorf(\"Unexpected err: %#v\", *repErr)\n\t\t\t}\n\t\t})\n\t}\n}\n\n// MSG Greeter.SayHello-json 1 _INBOX.test 16\\r\\n{\"foobar\":\"hello\"}\\r\\n\n\nfunc compareStringSlices(t *testing.T, expected, actual []string) {\n\tif len(expected) != len(expected) {\n\t\tt.Errorf(\"String slices are different. Expected [%s], got [%s]\",\n\t\t\tstrings.Join(expected, \",\"), strings.Join(actual, \",\"))\n\t\treturn\n\t}\n\tfor i, expectedValue := range expected {\n\t\tif actual[i] != expectedValue {\n\t\t\tt.Errorf(\"String slices are different. Expected [%s], got [%s]\",\n\t\t\t\tstrings.Join(expected, \",\"), strings.Join(actual, \",\"))\n\t\t\treturn\n\t\t}\n\t}\n}\n\nfunc TestParseSubject(t *testing.T) {\n\tfor i, tt := range []struct {\n\t\tpkgSubject     string\n\t\tpkgParamsCount int\n\t\tsvcSubject     string\n\t\tsvcParamsCount int\n\t\tmtParamsCount  int\n\t\tsubject        string\n\t\tpkgParams      []string\n\t\tsvcParams      []string\n\t\tmtParams       []string\n\t\tname           string\n\t\tencoding       string\n\t\terr            string\n\t}{\n\t\t{\"\", 0, \"foo\", 0, 0, \"foo.bar\", nil, nil, nil, \"bar\", \"protobuf\", \"\"},\n\t\t{\"\", 0, \"foo\", 0, 0, \"foo.bar.protobuf\", nil, nil, nil, \"bar\", \"protobuf\", \"\"},\n\t\t{\"\", 0, \"foo\", 0, 0, \"foo.bar.json\", nil, nil, nil, \"bar\", \"json\", \"\"},\n\t\t{\"\", 0, \"foo\", 0, 0, \"foo.bar.json.protobuf\", nil, nil, nil, \"bar\", \"\",\n\t\t\t\"Invalid subject tail length. Expects 0 or 1 parts, got 2\"},\n\t\t{\"demo\", 0, \"foo\", 0, 0, \"demo.foo.bar\", nil, nil, nil, \"bar\", \"protobuf\", \"\"},\n\t\t{\"demo\", 0, \"foo\", 0, 0, \"demo.foo.bar.json\", nil, nil, nil, \"bar\", \"json\", \"\"},\n\t\t{\"demo\", 0, \"foo\", 0, 0, \"foo.bar.json\", nil, nil, nil, \"\", \"\",\n\t\t\t\"Invalid subject prefix. Expected 'demo', got 'foo'\"},\n\t\t{\"demo\", 2, \"foo\", 0, 0, \"demo.p1.p2.foo.bar.json\", []string{\"p1\", \"p2\"}, nil, nil, \"bar\", \"json\", \"\"},\n\t\t{\"demo\", 2, \"foo\", 1, 0, \"demo.p1.p2.foo.sp1.bar.json\", []string{\"p1\", \"p2\"}, []string{\"sp1\"}, nil, \"bar\", \"json\", \"\"},\n\t\t{\"demo.pkg\", 1, \"nested.svc\", 1, 0, \"demo.pkg.p1.nested.svc.sp1.bar\",\n\t\t\t[]string{\"p1\"}, []string{\"sp1\"}, nil, \"bar\", \"protobuf\", \"\"},\n\t} {\n\t\tpkgParams, svcParams, name, tail, err := nrpc.ParseSubject(\n\t\t\ttt.pkgSubject, tt.pkgParamsCount,\n\t\t\ttt.svcSubject, tt.svcParamsCount,\n\t\t\ttt.subject)\n\t\tvar mtParams []string\n\t\tvar encoding string\n\t\tif err == nil {\n\t\t\tmtParams, encoding, err = nrpc.ParseSubjectTail(tt.mtParamsCount, tail)\n\t\t}\n\t\tcompareStringSlices(t, tt.pkgParams, pkgParams)\n\t\tcompareStringSlices(t, tt.svcParams, svcParams)\n\t\tcompareStringSlices(t, tt.mtParams, mtParams)\n\t\tif name != tt.name {\n\t\t\tt.Errorf(\"test %d: Expected name=%s, got %s\", i, tt.name, name)\n\t\t}\n\t\tif encoding != tt.encoding {\n\t\t\tt.Errorf(\"text %d: Expected encoding=%s, got %s\", i, tt.encoding, encoding)\n\t\t}\n\t\tif tt.err == \"\" && err != nil {\n\t\t\tt.Errorf(\"text %d: Unexpected error %s\", i, err)\n\t\t} else if tt.err != \"\" && err == nil {\n\t\t\tt.Errorf(\"text %d: Expected error, got nothing\", i)\n\t\t} else if tt.err != \"\" && tt.err != err.Error() {\n\t\t\tt.Errorf(\"text %d: Expected error '%s', got '%s'\", i, tt.err, err)\n\t\t}\n\t}\n}\n\nfunc TestCaptureErrors(t *testing.T) {\n\tt.Run(\"NoError\", func(t *testing.T) {\n\t\tmsg, err := nrpc.CaptureErrors(func() (proto.Message, error) {\n\t\t\treturn &DummyMessage{Foobar: \"Hi\"}, nil\n\t\t})\n\t\tif err != nil {\n\t\t\tt.Error(\"Unexpected error:\", err)\n\t\t}\n\t\tdm, ok := msg.(*DummyMessage)\n\t\tif !ok {\n\t\t\tt.Error(\"Expected a DummyMessage, got\", msg)\n\t\t}\n\t\tif dm.Foobar != \"Hi\" {\n\t\t\tt.Error(\"Message was not passed properly\")\n\t\t}\n\t})\n\tt.Run(\"ClientError\", func(t *testing.T) {\n\t\tmsg, err := nrpc.CaptureErrors(func() (proto.Message, error) {\n\t\t\treturn nil, fmt.Errorf(\"anerror\")\n\t\t})\n\t\tif err == nil {\n\t\t\tt.Fatal(\"Expected an error, got nothing\")\n\t\t}\n\t\tif err.Type != nrpc.Error_CLIENT {\n\t\t\tt.Errorf(\"Invalid error type. Expected 'CLIENT' (0), got %s\", err.Type)\n\t\t}\n\t\tif err.Message != \"anerror\" {\n\t\t\tt.Error(\"Unexpected error message. Expected 'anerror', got\", err.Message)\n\t\t}\n\t\tif msg != nil {\n\t\t\tt.Error(\"Expected a nil msg, got\", msg)\n\t\t}\n\t})\n\tt.Run(\"DirectError\", func(t *testing.T) {\n\t\tmsg, err := nrpc.CaptureErrors(func() (proto.Message, error) {\n\t\t\treturn nil, &nrpc.Error{Type: nrpc.Error_SERVER, Message: \"anerror\"}\n\t\t})\n\t\tif err == nil {\n\t\t\tt.Fatal(\"Expected an error, got nothing\")\n\t\t}\n\t\tif err.Type != nrpc.Error_SERVER {\n\t\t\tt.Errorf(\"Invalid error type. Expected 'SERVER' (1), got %s\", err.Type)\n\t\t}\n\t\tif err.Message != \"anerror\" {\n\t\t\tt.Error(\"Unexpected error message. Expected 'anerror', got\", err.Message)\n\t\t}\n\t\tif msg != nil {\n\t\t\tt.Error(\"Expected a nil msg, got\", msg)\n\t\t}\n\t})\n\tt.Run(\"ServerError\", func(t *testing.T) {\n\t\tmsg, err := nrpc.CaptureErrors(func() (proto.Message, error) {\n\t\t\tpanic(\"panicking\")\n\t\t})\n\t\tif err == nil {\n\t\t\tt.Fatal(\"Expected an error, got nothing\")\n\t\t}\n\t\tif err.Type != nrpc.Error_SERVER {\n\t\t\tt.Errorf(\"Invalid error type. Expected 'SERVER' (1), got %s\", err.Type)\n\t\t}\n\t\tif err.Message != \"panicking\" {\n\t\t\tt.Error(\"Unexpected error message. Expected 'panicking', got\", err.Message)\n\t\t}\n\t\tif msg != nil {\n\t\t\tt.Error(\"Expected a nil msg, got\", msg)\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "nrpc_test.proto",
    "content": "syntax = \"proto3\";\n\noption go_package = \"github.com/nats-rpc/nrpc_test\";\n\nmessage DummyMessage {\n    string foobar = 1;\n}\n"
  },
  {
    "path": "nrpcpb_test.go",
    "content": "// Code generated by protoc-gen-go. DO NOT EDIT.\n// versions:\n// \tprotoc-gen-go v1.29.0\n// \tprotoc        v4.22.2\n// source: nrpc_test.proto\n\npackage nrpc_test\n\nimport (\n\tprotoreflect \"google.golang.org/protobuf/reflect/protoreflect\"\n\tprotoimpl \"google.golang.org/protobuf/runtime/protoimpl\"\n\treflect \"reflect\"\n\tsync \"sync\"\n)\n\nconst (\n\t// Verify that this generated code is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)\n\t// Verify that runtime/protoimpl is sufficiently up-to-date.\n\t_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)\n)\n\ntype DummyMessage struct {\n\tstate         protoimpl.MessageState\n\tsizeCache     protoimpl.SizeCache\n\tunknownFields protoimpl.UnknownFields\n\n\tFoobar string `protobuf:\"bytes,1,opt,name=foobar,proto3\" json:\"foobar,omitempty\"`\n}\n\nfunc (x *DummyMessage) Reset() {\n\t*x = DummyMessage{}\n\tif protoimpl.UnsafeEnabled {\n\t\tmi := &file_nrpc_test_proto_msgTypes[0]\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tms.StoreMessageInfo(mi)\n\t}\n}\n\nfunc (x *DummyMessage) String() string {\n\treturn protoimpl.X.MessageStringOf(x)\n}\n\nfunc (*DummyMessage) ProtoMessage() {}\n\nfunc (x *DummyMessage) ProtoReflect() protoreflect.Message {\n\tmi := &file_nrpc_test_proto_msgTypes[0]\n\tif protoimpl.UnsafeEnabled && x != nil {\n\t\tms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))\n\t\tif ms.LoadMessageInfo() == nil {\n\t\t\tms.StoreMessageInfo(mi)\n\t\t}\n\t\treturn ms\n\t}\n\treturn mi.MessageOf(x)\n}\n\n// Deprecated: Use DummyMessage.ProtoReflect.Descriptor instead.\nfunc (*DummyMessage) Descriptor() ([]byte, []int) {\n\treturn file_nrpc_test_proto_rawDescGZIP(), []int{0}\n}\n\nfunc (x *DummyMessage) GetFoobar() string {\n\tif x != nil {\n\t\treturn x.Foobar\n\t}\n\treturn \"\"\n}\n\nvar File_nrpc_test_proto protoreflect.FileDescriptor\n\nvar file_nrpc_test_proto_rawDesc = []byte{\n\t0x0a, 0x0f, 0x6e, 0x72, 0x70, 0x63, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x2e, 0x70, 0x72, 0x6f, 0x74,\n\t0x6f, 0x22, 0x26, 0x0a, 0x0c, 0x44, 0x75, 0x6d, 0x6d, 0x79, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67,\n\t0x65, 0x12, 0x16, 0x0a, 0x06, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,\n\t0x09, 0x52, 0x06, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x42, 0x1f, 0x5a, 0x1d, 0x67, 0x69, 0x74,\n\t0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6e, 0x61, 0x74, 0x73, 0x2d, 0x72, 0x70, 0x63,\n\t0x2f, 0x6e, 0x72, 0x70, 0x63, 0x5f, 0x74, 0x65, 0x73, 0x74, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,\n\t0x6f, 0x33,\n}\n\nvar (\n\tfile_nrpc_test_proto_rawDescOnce sync.Once\n\tfile_nrpc_test_proto_rawDescData = file_nrpc_test_proto_rawDesc\n)\n\nfunc file_nrpc_test_proto_rawDescGZIP() []byte {\n\tfile_nrpc_test_proto_rawDescOnce.Do(func() {\n\t\tfile_nrpc_test_proto_rawDescData = protoimpl.X.CompressGZIP(file_nrpc_test_proto_rawDescData)\n\t})\n\treturn file_nrpc_test_proto_rawDescData\n}\n\nvar file_nrpc_test_proto_msgTypes = make([]protoimpl.MessageInfo, 1)\nvar file_nrpc_test_proto_goTypes = []interface{}{\n\t(*DummyMessage)(nil), // 0: DummyMessage\n}\nvar file_nrpc_test_proto_depIdxs = []int32{\n\t0, // [0:0] is the sub-list for method output_type\n\t0, // [0:0] is the sub-list for method input_type\n\t0, // [0:0] is the sub-list for extension type_name\n\t0, // [0:0] is the sub-list for extension extendee\n\t0, // [0:0] is the sub-list for field type_name\n}\n\nfunc init() { file_nrpc_test_proto_init() }\nfunc file_nrpc_test_proto_init() {\n\tif File_nrpc_test_proto != nil {\n\t\treturn\n\t}\n\tif !protoimpl.UnsafeEnabled {\n\t\tfile_nrpc_test_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {\n\t\t\tswitch v := v.(*DummyMessage); i {\n\t\t\tcase 0:\n\t\t\t\treturn &v.state\n\t\t\tcase 1:\n\t\t\t\treturn &v.sizeCache\n\t\t\tcase 2:\n\t\t\t\treturn &v.unknownFields\n\t\t\tdefault:\n\t\t\t\treturn nil\n\t\t\t}\n\t\t}\n\t}\n\ttype x struct{}\n\tout := protoimpl.TypeBuilder{\n\t\tFile: protoimpl.DescBuilder{\n\t\t\tGoPackagePath: reflect.TypeOf(x{}).PkgPath(),\n\t\t\tRawDescriptor: file_nrpc_test_proto_rawDesc,\n\t\t\tNumEnums:      0,\n\t\t\tNumMessages:   1,\n\t\t\tNumExtensions: 0,\n\t\t\tNumServices:   0,\n\t\t},\n\t\tGoTypes:           file_nrpc_test_proto_goTypes,\n\t\tDependencyIndexes: file_nrpc_test_proto_depIdxs,\n\t\tMessageInfos:      file_nrpc_test_proto_msgTypes,\n\t}.Build()\n\tFile_nrpc_test_proto = out.File\n\tfile_nrpc_test_proto_rawDesc = nil\n\tfile_nrpc_test_proto_goTypes = nil\n\tfile_nrpc_test_proto_depIdxs = nil\n}\n"
  },
  {
    "path": "protoc-gen-nrpc/main.go",
    "content": "package main\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"log\"\n\t\"os\"\n\t\"path\"\n\t\"strings\"\n\t\"text/template\"\n\n\t\"github.com/nats-rpc/nrpc\"\n\n\t\"google.golang.org/protobuf/proto\"\n\tdescriptor \"google.golang.org/protobuf/types/descriptorpb\"\n\tplugin \"google.golang.org/protobuf/types/pluginpb\"\n)\n\n// baseName returns the last path element of the name, with the last dotted suffix removed.\nfunc baseName(name string) string {\n\t// First, find the last element\n\tif i := strings.LastIndex(name, \"/\"); i >= 0 {\n\t\tname = name[i+1:]\n\t}\n\t// Now drop the suffix\n\tif i := strings.LastIndex(name, \".\"); i >= 0 {\n\t\tname = name[0:i]\n\t}\n\treturn name\n}\n\n// getGoPackage returns the file's go_package option.\n// If it containts a semicolon, only the part before it is returned.\nfunc getGoPackage(fd *descriptor.FileDescriptorProto) string {\n\tpkg := fd.GetOptions().GetGoPackage()\n\tif strings.Contains(pkg, \";\") {\n\t\tparts := strings.Split(pkg, \";\")\n\t\tif len(parts) > 2 {\n\t\t\tlog.Fatalf(\n\t\t\t\t\"protoc-gen-nrpc: go_package '%s' contains more than 1 ';'\",\n\t\t\t\tpkg)\n\t\t}\n\t\tpkg = parts[1]\n\t}\n\n\treturn pkg\n}\n\n// goPackageOption interprets the file's go_package option.\n// If there is no go_package, it returns (\"\", \"\", false).\n// If there's a simple name, it returns (\"\", pkg, true).\n// If the option implies an import path, it returns (impPath, pkg, true).\nfunc goPackageOption(d *descriptor.FileDescriptorProto) (impPath, pkg string, ok bool) {\n\tpkg = getGoPackage(d)\n\tif pkg == \"\" {\n\t\treturn\n\t}\n\tok = true\n\t// The presence of a slash implies there's an import path.\n\tslash := strings.LastIndex(pkg, \"/\")\n\tif slash < 0 {\n\t\treturn\n\t}\n\timpPath, pkg = pkg, pkg[slash+1:]\n\t// A semicolon-delimited suffix overrides the package name.\n\tsc := strings.IndexByte(impPath, ';')\n\tif sc < 0 {\n\t\treturn\n\t}\n\timpPath, pkg = impPath[:sc], impPath[sc+1:]\n\treturn\n}\n\n// goPackageName returns the Go package name to use in the\n// generated Go file.  The result explicit reports whether the name\n// came from an option go_package statement.  If explicit is false,\n// the name was derived from the protocol buffer's package statement\n// or the input file name.\nfunc goPackageName(d *descriptor.FileDescriptorProto) (name string, explicit bool) {\n\t// Does the file have a \"go_package\" option?\n\tif _, pkg, ok := goPackageOption(d); ok {\n\t\treturn pkg, true\n\t}\n\n\t// Does the file have a package clause?\n\tif pkg := d.GetPackage(); pkg != \"\" {\n\t\treturn pkg, false\n\t}\n\t// Use the file base name.\n\treturn baseName(d.GetName()), false\n}\n\n// goFileName returns the output name for the generated Go file.\nfunc goFileName(d *descriptor.FileDescriptorProto) string {\n\tname := *d.Name\n\tif ext := path.Ext(name); ext == \".proto\" || ext == \".protodevel\" {\n\t\tname = name[:len(name)-len(ext)]\n\t}\n\tname += \".nrpc.go\"\n\n\tif pathsSourceRelative {\n\t\treturn name\n\t}\n\n\t// Does the file have a \"go_package\" option?\n\t// If it does, it may override the filename.\n\tif impPath, _, ok := goPackageOption(d); ok && impPath != \"\" {\n\t\t// Replace the existing dirname with the declared import path.\n\t\t_, name = path.Split(name)\n\t\tname = path.Join(impPath, name)\n\t\treturn name\n\t}\n\n\treturn name\n}\n\n// splitMessageTypeName split a message type into (package name, type name)\nfunc splitMessageTypeName(name string) (string, string) {\n\tif len(name) == 0 {\n\t\tlog.Fatal(\"Empty message type\")\n\t}\n\tif name[0] != '.' {\n\t\tlog.Fatalf(\"Expect message type name to start with '.', but it is '%s'\", name)\n\t}\n\tlastDot := strings.LastIndex(name, \".\")\n\treturn name[1:lastDot], name[lastDot+1:]\n}\n\nfunc splitTypePath(name string) []string {\n\tif len(name) == 0 {\n\t\tlog.Fatal(\"Empty message type\")\n\t}\n\tif name[0] != '.' {\n\t\tlog.Fatalf(\"Expect message type name to start with '.', but it is '%s'\", name)\n\t}\n\treturn strings.Split(name[1:], \".\")\n}\n\nfunc lookupFileDescriptor(name string) *descriptor.FileDescriptorProto {\n\tfor _, fd := range request.GetProtoFile() {\n\t\tif fd.GetPackage() == name {\n\t\t\treturn fd\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc lookupMessageType(name string) (*descriptor.FileDescriptorProto, *descriptor.DescriptorProto) {\n\tpath := splitTypePath(name)\n\n\tpkgpath := path[:len(path)-1]\n\n\tvar fd *descriptor.FileDescriptorProto\n\tfor {\n\t\tpkgname := strings.Join(pkgpath, \".\")\n\t\tfd = lookupFileDescriptor(pkgname)\n\t\tif fd != nil {\n\t\t\tbreak\n\t\t}\n\t\tif len(pkgpath) == 1 {\n\t\t\tlog.Fatalf(\"Could not find the .proto file for package '%s' (from message %s)\", pkgname, name)\n\t\t}\n\t\tpkgpath = pkgpath[:len(pkgpath)-1]\n\t}\n\n\tpath = path[len(pkgpath):]\n\n\tvar d *descriptor.DescriptorProto\n\tfor _, mt := range fd.GetMessageType() {\n\t\tif mt.GetName() == path[0] {\n\t\t\td = mt\n\t\t\tbreak\n\t\t}\n\t}\n\tif d == nil {\n\t\tlog.Fatalf(\"No such type '%s' in package '%s'\", path[0], strings.Join(pkgpath, \".\"))\n\t}\n\tfor i, token := range path[1:] {\n\t\tvar found bool\n\t\tfor _, nd := range d.GetNestedType() {\n\t\t\tif nd.GetName() == token {\n\t\t\t\td = nd\n\t\t\t\tfound = true\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif !found {\n\t\t\tlog.Fatalf(\"No such nested type '%s' in '%s.%s'\",\n\t\t\t\ttoken, strings.Join(pkgpath, \".\"), strings.Join(path[:i+1], \".\"))\n\t\t}\n\t}\n\treturn fd, d\n}\n\nfunc getField(d *descriptor.DescriptorProto, name string) *descriptor.FieldDescriptorProto {\n\tfor _, f := range d.GetField() {\n\t\tif f.GetName() == name {\n\t\t\treturn f\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc getOneofDecl(d *descriptor.DescriptorProto, name string) *descriptor.OneofDescriptorProto {\n\tfor _, of := range d.GetOneofDecl() {\n\t\tif of.GetName() == name {\n\t\t\treturn of\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc pkgSubject(fd *descriptor.FileDescriptorProto) string {\n\tif options := fd.GetOptions(); options != nil {\n\t\te := proto.GetExtension(options, nrpc.E_PackageSubject)\n\t\tif value, ok := e.(string); ok {\n\t\t\treturn value\n\t\t}\n\t}\n\treturn fd.GetPackage()\n}\n\nfunc getResultType(\n\tmd *descriptor.MethodDescriptorProto,\n) string {\n\treturn md.GetOutputType()\n}\n\nfunc getGoType(pbType string) (string, string) {\n\tif !strings.Contains(pbType, \".\") {\n\t\treturn \"\", pbType\n\t}\n\tfd, _ := lookupMessageType(pbType)\n\tname := strings.TrimPrefix(pbType, \".\"+fd.GetPackage()+\".\")\n\tname = strings.Replace(name, \".\", \"_\", -1)\n\treturn getGoPackage(fd), name\n}\n\nfunc getPkgImportName(goPkg string) string {\n\tif goPkg == getGoPackage(currentFile) {\n\t\treturn \"\"\n\t}\n\treplacer := strings.NewReplacer(\".\", \"_\", \"/\", \"_\", \"-\", \"_\")\n\treturn replacer.Replace(goPkg)\n}\n\nvar pluginPrometheus bool\nvar pathsSourceRelative bool\n\nvar funcMap = template.FuncMap{\n\t\"GoPackageName\": func(fd *descriptor.FileDescriptorProto) string {\n\t\tp, _ := goPackageName(fd)\n\t\treturn p\n\t},\n\t\"GetPkg\": func(pkg, s string) string {\n\t\ts = strings.TrimPrefix(s, \".\")\n\t\ts = strings.TrimPrefix(s, pkg)\n\t\ts = strings.TrimPrefix(s, \".\")\n\t\treturn s\n\t},\n\t\"GetExtraImports\": func(fd *descriptor.FileDescriptorProto) []string {\n\t\t// check all the types used and imports packages from where they come\n\t\tvar imports = make(map[string]string)\n\t\tfor _, sd := range fd.GetService() {\n\t\t\tfor _, md := range sd.GetMethod() {\n\t\t\t\tgoPkg, _ := getGoType(md.GetInputType())\n\t\t\t\tpkgImportName := getPkgImportName(goPkg)\n\t\t\t\tif pkgImportName != \"\" {\n\t\t\t\t\timports[pkgImportName] = goPkg\n\t\t\t\t}\n\t\t\t\tgoPkg, _ = getGoType(getResultType(md))\n\t\t\t\tpkgImportName = getPkgImportName(goPkg)\n\t\t\t\tif pkgImportName != \"\" {\n\t\t\t\t\timports[pkgImportName] = goPkg\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvar result []string\n\t\tfor importName, goPkg := range imports {\n\t\t\tresult = append(result,\n\t\t\t\tfmt.Sprintf(\"%s \\\"%s\\\"\",\n\t\t\t\t\timportName,\n\t\t\t\t\tgoPkg,\n\t\t\t\t),\n\t\t\t)\n\t\t}\n\t\treturn result\n\t},\n\t\"GetPkgSubjectPrefix\": func(fd *descriptor.FileDescriptorProto) string {\n\t\tif s := pkgSubject(fd); s != \"\" {\n\t\t\treturn s + \".\"\n\t\t}\n\t\treturn \"\"\n\t},\n\t\"GetPkgSubject\": pkgSubject,\n\t\"GetPkgSubjectParams\": func(fd *descriptor.FileDescriptorProto) []string {\n\t\tif opts := fd.GetOptions(); opts != nil {\n\t\t\te := proto.GetExtension(opts, nrpc.E_PackageSubjectParams)\n\t\t\tvalue := e.([]string)\n\t\t\treturn value\n\t\t}\n\t\treturn nil\n\t},\n\t\"GetServiceSubject\": func(sd *descriptor.ServiceDescriptorProto) string {\n\t\tif opts := sd.GetOptions(); opts != nil {\n\t\t\ts := proto.GetExtension(opts, nrpc.E_ServiceSubject)\n\t\t\tif value, ok := s.(string); ok && s != \"\" {\n\t\t\t\treturn value\n\t\t\t}\n\t\t}\n\t\tif opts := currentFile.GetOptions(); opts != nil {\n\t\t\ts := proto.GetExtension(opts, nrpc.E_ServiceSubjectRule)\n\t\t\tswitch s.(nrpc.SubjectRule) {\n\t\t\tcase nrpc.SubjectRule_COPY:\n\t\t\t\treturn sd.GetName()\n\t\t\tcase nrpc.SubjectRule_TOLOWER:\n\t\t\t\treturn strings.ToLower(sd.GetName())\n\t\t\t}\n\t\t}\n\t\treturn sd.GetName()\n\t},\n\t\"ServiceNeedsHandler\": func(sd *descriptor.ServiceDescriptorProto) bool {\n\t\tfor _, md := range sd.GetMethod() {\n\t\t\tif md.GetInputType() != \".nrpc.NoRequest\" {\n\t\t\t\treturn true\n\t\t\t}\n\t\t}\n\t\treturn false\n\t},\n\t\"GetMethodSubject\": func(md *descriptor.MethodDescriptorProto) string {\n\t\tif opts := md.GetOptions(); opts != nil {\n\t\t\ts := proto.GetExtension(opts, nrpc.E_MethodSubject)\n\t\t\tif value, ok := s.(string); ok && value != \"\" {\n\t\t\t\treturn value\n\t\t\t}\n\t\t}\n\t\tif opts := currentFile.GetOptions(); opts != nil {\n\t\t\ts := proto.GetExtension(opts, nrpc.E_MethodSubjectRule)\n\t\t\tswitch s.(nrpc.SubjectRule) {\n\t\t\tcase nrpc.SubjectRule_COPY:\n\t\t\t\treturn md.GetName()\n\t\t\tcase nrpc.SubjectRule_TOLOWER:\n\t\t\t\treturn strings.ToLower(md.GetName())\n\t\t\t}\n\t\t}\n\t\treturn md.GetName()\n\t},\n\t\"GetMethodSubjectParams\": func(md *descriptor.MethodDescriptorProto) []string {\n\t\tif opts := md.GetOptions(); opts != nil {\n\t\t\te := proto.GetExtension(opts, nrpc.E_MethodSubjectParams)\n\t\t\tif s, ok := e.([]string); ok {\n\t\t\t\treturn s\n\t\t\t}\n\t\t}\n\t\treturn []string{}\n\t},\n\t\"GetServiceSubjectParams\": func(sd *descriptor.ServiceDescriptorProto) []string {\n\t\tif opts := sd.GetOptions(); opts != nil {\n\t\t\te := proto.GetExtension(opts, nrpc.E_ServiceSubjectParams)\n\t\t\tif s, ok := e.([]string); ok {\n\t\t\t\treturn s\n\t\t\t}\n\t\t}\n\t\treturn []string{}\n\t},\n\t\"HasStreamedReply\": func(md *descriptor.MethodDescriptorProto) bool {\n\t\tif opts := md.GetOptions(); opts != nil {\n\t\t\te := proto.GetExtension(opts, nrpc.E_StreamedReply)\n\t\t\tif s, ok := e.(bool); ok {\n\t\t\t\treturn s\n\t\t\t}\n\t\t}\n\t\treturn false\n\t},\n\t\"HasPollEnabled\": func(md *descriptor.MethodDescriptorProto) bool {\n\t\tif opts := md.GetOptions(); opts != nil {\n\t\t\te := proto.GetExtension(opts, nrpc.E_PollingEnabled)\n\t\t\tif s, ok := e.(bool); ok {\n\t\t\t\treturn s\n\t\t\t}\n\t\t}\n\t\treturn false\n\t},\n\t\"Prometheus\": func() bool {\n\t\treturn pluginPrometheus\n\t},\n\t\"GetResultType\": getResultType,\n\t\"GoType\": func(pbType string) string {\n\t\tgoPkg, goType := getGoType(pbType)\n\t\tif goPkg != \"\" {\n\t\t\timportName := getPkgImportName(goPkg)\n\t\t\tif importName != \"\" {\n\t\t\t\tgoType = importName + \".\" + goType\n\t\t\t}\n\t\t}\n\t\treturn goType\n\t},\n}\n\nvar request plugin.CodeGeneratorRequest\nvar currentFile *descriptor.FileDescriptorProto\n\nfunc main() {\n\n\tlog.SetPrefix(\"protoc-gen-nrpc: \")\n\tdata, err := ioutil.ReadAll(os.Stdin)\n\tif err != nil {\n\t\tlog.Fatalf(\"error: reading input: %v\", err)\n\t}\n\n\tvar response plugin.CodeGeneratorResponse\n\tif err := proto.Unmarshal(data, &request); err != nil {\n\t\tlog.Fatalf(\"error: parsing input proto: %v\", err)\n\t}\n\n\tif len(request.GetFileToGenerate()) == 0 {\n\t\tlog.Fatal(\"error: no files to generate\")\n\t}\n\n\tfor _, param := range strings.Split(request.GetParameter(), \",\") {\n\t\tvar value string\n\t\tif i := strings.Index(param, \"=\"); i >= 0 {\n\t\t\tvalue = param[i+1:]\n\t\t\tparam = param[0:i]\n\t\t}\n\t\tswitch param {\n\t\tcase \"\":\n\t\t\t// Ignore.\n\t\tcase \"plugins\":\n\t\t\tfor _, plugin := range strings.Split(value, \";\") {\n\t\t\t\tswitch plugin {\n\t\t\t\tcase \"prometheus\":\n\t\t\t\t\tpluginPrometheus = true\n\t\t\t\tdefault:\n\t\t\t\t\tlog.Fatalf(\"invalid plugin: %s\", plugin)\n\t\t\t\t}\n\t\t\t}\n\t\tcase \"paths\":\n\t\t\tif value == \"source_relative\" {\n\t\t\t\tpathsSourceRelative = true\n\t\t\t} else if value == \"import\" {\n\t\t\t\tpathsSourceRelative = false\n\t\t\t} else {\n\t\t\t\tlog.Fatalf(`unknown path type %q: want \"import\" or \"source_relative\"`, value)\n\t\t\t}\n\t\t}\n\t}\n\n\ttmpl, err := template.New(\".\").Funcs(funcMap).Parse(tFile)\n\tif err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\tfor _, name := range request.GetFileToGenerate() {\n\t\tvar fd *descriptor.FileDescriptorProto\n\t\tfor _, fd = range request.GetProtoFile() {\n\t\t\tif name == fd.GetName() {\n\t\t\t\tbreak\n\t\t\t}\n\t\t}\n\t\tif fd == nil {\n\t\t\tlog.Fatalf(\"could not find the .proto file for %s\", name)\n\t\t}\n\n\t\tcurrentFile = fd\n\n\t\tvar buf bytes.Buffer\n\t\tif err := tmpl.Execute(&buf, fd); err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tcurrentFile = nil\n\n\t\tresponse.File = append(response.File, &plugin.CodeGeneratorResponse_File{\n\t\t\tName:    proto.String(goFileName(fd)),\n\t\t\tContent: proto.String(buf.String()),\n\t\t})\n\t}\n\n\tif data, err = proto.Marshal(&response); err != nil {\n\t\tlog.Fatalf(\"error: failed to marshal output proto: %v\", err)\n\t}\n\tif _, err := os.Stdout.Write(data); err != nil {\n\t\tlog.Fatalf(\"error: failed to write output proto: %v\", err)\n\t}\n}\n"
  },
  {
    "path": "protoc-gen-nrpc/tmpl.go",
    "content": "package main\n\nconst tFile = `// This code was autogenerated from {{.GetName}}, do not edit.\n\n{{- $pkgName := GoPackageName .}}\n{{- $pkgSubject := GetPkgSubject .}}\n{{- $pkgSubjectPrefix := GetPkgSubjectPrefix .}}\n{{- $pkgSubjectParams := GetPkgSubjectParams .}}\npackage {{$pkgName}}\n\nimport (\n\t\"context\"\n\t\"log\"\n\t\"time\"\n\n\t\"google.golang.org/protobuf/proto\"\n\t\"github.com/nats-io/nats.go\"\n\t{{- range  GetExtraImports .}}\n\t{{.}}\n\t{{- end}}\n\t{{- if Prometheus}}\n\t\"github.com/prometheus/client_golang/prometheus\"\n\t{{- end}}\n\t\"github.com/nats-rpc/nrpc\"\n)\n\n{{- range .Service}}\n\n// {{.GetName}}Server is the interface that providers of the service\n// {{.GetName}} should implement.\ntype {{.GetName}}Server interface {\n\t{{- range .Method}}\n\t{{- if ne .GetInputType \".nrpc.NoRequest\"}}\n\t{{- $resultType := GetResultType .}}\n\t{{.GetName}}(ctx context.Context\n\t\t{{- range GetMethodSubjectParams . -}}\n\t\t, {{ . }} string\n\t\t{{- end -}}\n\t\t{{- if ne .GetInputType \".nrpc.Void\" -}}\n\t\t, req *{{GoType .GetInputType}}\n\t\t{{- end -}}\n\t\t{{- if HasStreamedReply . -}}\n\t\t, pushRep func(*{{GoType .GetOutputType}})\n\t\t{{- end -}}\n\t)\n\t\t{{- if ne $resultType \".nrpc.NoReply\" }} (\n\t\t{{- if and (ne $resultType \".nrpc.Void\") (not (HasStreamedReply .)) -}}\n\t\t*{{GoType $resultType}}, {{end -}}\n\t\terror)\n\t\t{{- end -}}\n\t{{- end}}\n\t{{- end}}\n}\n\n{{- if Prometheus}}\n\nvar (\n\t// The request completion time, measured at client-side.\n\tclientRCTFor{{.GetName}} = prometheus.NewSummaryVec(\n\t\tprometheus.SummaryOpts{\n\t\t\tName:       \"nrpc_client_request_completion_time_seconds\",\n\t\t\tHelp:       \"The request completion time for calls, measured client-side.\",\n\t\t\tObjectives: map[float64]float64{0.9: 0.01, 0.95: 0.01, 0.99: 0.001},\n\t\t\tConstLabels: map[string]string{\n\t\t\t\t\"service\": \"{{.GetName}}\",\n\t\t\t},\n\t\t},\n\t\t[]string{\"method\"})\n\n\t// The handler execution time, measured at server-side.\n\tserverHETFor{{.GetName}} = prometheus.NewSummaryVec(\n\t\tprometheus.SummaryOpts{\n\t\t\tName:       \"nrpc_server_handler_execution_time_seconds\",\n\t\t\tHelp:       \"The handler execution time for calls, measured server-side.\",\n\t\t\tObjectives: map[float64]float64{0.9: 0.01, 0.95: 0.01, 0.99: 0.001},\n\t\t\tConstLabels: map[string]string{\n\t\t\t\t\"service\": \"{{.GetName}}\",\n\t\t\t},\n\t\t},\n\t\t[]string{\"method\"})\n\n\t// The counts of calls made by the client, classified by result type.\n\tclientCallsFor{{.GetName}} = prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tName: \"nrpc_client_calls_count\",\n\t\t\tHelp: \"The count of calls made by the client.\",\n\t\t\tConstLabels: map[string]string{\n\t\t\t\t\"service\": \"{{.GetName}}\",\n\t\t\t},\n\t\t},\n\t\t[]string{\"method\", \"encoding\", \"result_type\"})\n\n\t// The counts of requests handled by the server, classified by result type.\n\tserverRequestsFor{{.GetName}} = prometheus.NewCounterVec(\n\t\tprometheus.CounterOpts{\n\t\t\tName: \"nrpc_server_requests_count\",\n\t\t\tHelp: \"The count of requests handled by the server.\",\n\t\t\tConstLabels: map[string]string{\n\t\t\t\t\"service\": \"{{.GetName}}\",\n\t\t\t},\n\t\t},\n\t\t[]string{\"method\", \"encoding\", \"result_type\"})\n)\n{{- end}}\n\n// {{.GetName}}Handler provides a NATS subscription handler that can serve a\n// subscription using a given {{.GetName}}Server implementation.\ntype {{.GetName}}Handler struct {\n\tctx     context.Context\n\tworkers *nrpc.WorkerPool\n\tnc      nrpc.NatsConn\n\tserver  {{.GetName}}Server\n\n\tencodings []string\n}\n\nfunc New{{.GetName}}Handler(ctx context.Context, nc nrpc.NatsConn, s {{.GetName}}Server) *{{.GetName}}Handler {\n\treturn &{{.GetName}}Handler{\n\t\tctx:    ctx,\n\t\tnc:     nc,\n\t\tserver: s,\n\n\t\tencodings: []string{\"protobuf\"},\n\t}\n}\n\nfunc New{{.GetName}}ConcurrentHandler(workers *nrpc.WorkerPool, nc nrpc.NatsConn, s {{.GetName}}Server) *{{.GetName}}Handler {\n\treturn &{{.GetName}}Handler{\n\t\tworkers: workers,\n\t\tnc:      nc,\n\t\tserver:  s,\n\t}\n}\n\n// SetEncodings sets the output encodings when using a '*Publish' function\nfunc (h *{{.GetName}}Handler) SetEncodings(encodings []string) {\n\th.encodings = encodings\n}\n\nfunc (h *{{.GetName}}Handler) Subject() string {\n\treturn \"{{$pkgSubjectPrefix}}\n\t{{- range $pkgSubjectParams -}}\n\t\t*.\n\t{{- end -}}\n\t{{GetServiceSubject .}}\n\t{{- range GetServiceSubjectParams . -}}\n\t\t.*\n\t{{- end -}}\n\t.>\"\n}\n{{- $serviceName := .GetName}}\n{{- $serviceSubject := GetServiceSubject .}}\n{{- $serviceSubjectParams := GetServiceSubjectParams .}}\n{{- range .Method}}\n{{- if eq .GetInputType \".nrpc.NoRequest\"}}\n\nfunc (h *{{$serviceName}}Handler) {{.GetName}}Publish(\n\t{{- range $pkgSubjectParams}}pkg{{.}} string, {{end -}}\n\t{{- range $serviceSubjectParams}}svc{{.}} string, {{end -}}\n\t{{- range GetMethodSubjectParams .}}mt{{.}} string, {{end -}}\n\tmsg *{{GoType .GetOutputType}}) error {\n\tfor _, encoding := range h.encodings {\n\t\trawMsg, err := nrpc.Marshal(encoding, msg)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"{{$serviceName}}Handler.{{.GetName}}Publish: error marshaling the message: %s\", err)\n\t\t\treturn err\n\t\t}\n\t\tsubject := \"{{$pkgSubject}}.\"\n\t\t{{- range $pkgSubjectParams}} + pkg{{.}} + \".\"{{end -}}\n\t\t+ \"{{$serviceSubject}}.\"\n\t\t{{- range $serviceSubjectParams}} + svc{{.}} + \".\"{{end -}}\n\t\t+ \"{{GetMethodSubject .}}\"\n\t\t{{- range GetMethodSubjectParams .}} + \".\" + mt{{.}}{{end}}\n\t\tif encoding != \"protobuf\" {\n\t\t\tsubject += \".\" + encoding\n\t\t}\n\t\tif err := h.nc.Publish(subject, rawMsg); err != nil {\n\t\t\treturn err\n\t\t}\n\t}\n\treturn nil\n}\n{{- end}}\n{{- end}}\n\n{{- if ServiceNeedsHandler .}}\n\nfunc (h *{{.GetName}}Handler) Handler(msg *nats.Msg) {\n\tvar ctx context.Context\n\tif h.workers != nil {\n\t\tctx = h.workers.Context\n\t} else {\n\t\tctx = h.ctx\n\t}\n\trequest := nrpc.NewRequest(ctx, h.nc, msg.Subject, msg.Reply)\n\t// extract method name & encoding from subject\n\t{{ if ne 0 (len $pkgSubjectParams)}}pkgParams{{else}}_{{end -}},\n\t{{- if ne 0 (len (GetServiceSubjectParams .))}} svcParams{{else}} _{{end -}}\n\t, name, tail, err := nrpc.ParseSubject(\n\t\t\"{{$pkgSubject}}\", {{len $pkgSubjectParams}}, \"{{GetServiceSubject .}}\", {{len (GetServiceSubjectParams .)}}, msg.Subject)\n\tif err != nil {\n\t\tlog.Printf(\"{{.GetName}}Hanlder: {{.GetName}} subject parsing failed: %v\", err)\n\t\treturn\n\t}\n\n\trequest.MethodName = name\n\trequest.SubjectTail = tail\n\n\t{{- range $i, $name := $pkgSubjectParams }}\n\trequest.SetPackageParam(\"{{$name}}\", pkgParams[{{$i}}])\n\t{{- end }}\n\t{{- range $i, $name := GetServiceSubjectParams . }}\n\trequest.SetServiceParam(\"{{$name}}\", svcParams[{{$i}}])\n\t{{- end }}\n\n\t// call handler and form response\n\tvar immediateError *nrpc.Error\n\tswitch name {\n\t{{- range .Method}}\n\tcase \"{{GetMethodSubject .}}\":\n\t\t{{- if eq .GetInputType \".nrpc.NoRequest\"}}\n\t\t// {{.GetName}} is a no-request method. Ignore it.\n\t\treturn\n\t\t{{- else}}{{/* !NoRequest */}}\n\t\t{{- if ne 0 (len (GetMethodSubjectParams .))}}\n\t\tvar mtParams []string\n\t\t{{- end}}\n\t\t{{- if eq .GetOutputType \".nrpc.NoReply\"}}\n\t\trequest.NoReply = true\n\t\t{{- end}}\n\t\t{{if eq 0 (len (GetMethodSubjectParams .))}}_{{else}}mtParams{{end}}, request.Encoding, err = nrpc.ParseSubjectTail({{len (GetMethodSubjectParams .)}}, request.SubjectTail)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"{{.GetName}}Hanlder: {{.GetName}} subject parsing failed: %v\", err)\n\t\t\tbreak\n\t\t}\n\t\tvar req {{GoType .GetInputType}}\n\t\tif err := nrpc.Unmarshal(request.Encoding, msg.Data, &req); err != nil {\n\t\t\tlog.Printf(\"{{.GetName}}Handler: {{.GetName}} request unmarshal failed: %v\", err)\n\t\t\timmediateError = &nrpc.Error{\n\t\t\t\tType: nrpc.Error_CLIENT,\n\t\t\t\tMessage: \"bad request received: \" + err.Error(),\n\t\t\t}\n{{- if Prometheus}}\n\t\t\tserverRequestsFor{{$serviceName}}.WithLabelValues(\n\t\t\t\t\"{{.GetName}}\", request.Encoding, \"unmarshal_fail\").Inc()\n{{- end}}\n\t\t} else {\n\t\t\t{{- if HasStreamedReply .}}\n\t\t\trequest.EnableStreamedReply()\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\terr := h.server.{{.GetName}}(ctx\n\t\t\t\t{{- range $i, $p := GetMethodSubjectParams . -}}\n\t\t\t\t, mtParams[{{ $i }}]\n\t\t\t\t{{- end -}}\n\t\t\t\t{{- if ne .GetInputType \".nrpc.Void\" -}}\n\t\t\t\t, &req\n\t\t\t\t{{- end -}}\n\t\t\t\t, func(rep *{{GoType .GetOutputType}}){\n\t\t\t\t\trequest.SendStreamReply(rep)\n\t\t\t\t})\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t\t{{- else }}\n\t\t\trequest.Handler = func(ctx context.Context)(proto.Message, error){\n\t\t\t\t{{- if eq .GetOutputType \".nrpc.NoReply\" -}}\n\t\t\t\tvar innerResp = &nrpc.NoReply{}\n\t\t\t\t{{else}}\n\t\t\t\t{{if eq .GetOutputType \".nrpc.Void\" -}}\n\t\t\t\tvar innerResp = &nrpc.Void{}\n\t\t\t\t{{else}}innerResp, {{end -}}\n\t\t\t\terr := {{end -}}\n\t\t\t\th.server.{{.GetName}}(ctx\n\t\t\t\t{{- range $i, $p := GetMethodSubjectParams . -}}\n\t\t\t\t, mtParams[{{ $i }}]\n\t\t\t\t{{- end -}}\n\t\t\t\t{{- if ne .GetInputType \".nrpc.Void\" -}}\n\t\t\t\t, &req\n\t\t\t\t{{- end -}}\n\t\t\t\t)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\treturn innerResp, err\n\t\t\t}\n\t\t\t{{- end }}\n\t\t}\n\t\t{{- end}}{{/* not HasStreamedReply */}}\n{{- end}}{{/* range .Method */}}\n\tdefault:\n\t\tlog.Printf(\"{{.GetName}}Handler: unknown name %q\", name)\n\t\timmediateError = &nrpc.Error{\n\t\t\tType: nrpc.Error_CLIENT,\n\t\t\tMessage: \"unknown name: \" + name,\n\t\t}\n{{- if Prometheus}}\n\t\tserverRequestsFor{{.GetName}}.WithLabelValues(\n\t\t\t\"{{.GetName}}\", request.Encoding, \"name_fail\").Inc()\n{{- end}}\n\t}\n\n{{- if Prometheus}}\n\trequest.AfterReply = func(request *nrpc.Request, success, replySuccess bool) {\n\t\tif !replySuccess {\n\t\t\tserverRequestsFor{{$serviceName}}.WithLabelValues(\n\t\t\t\trequest.MethodName, request.Encoding, \"sendreply_fail\").Inc()\n\t\t}\n\t\tif success {\n\t\t\tserverRequestsFor{{$serviceName}}.WithLabelValues(\n\t\t\t\trequest.MethodName, request.Encoding, \"success\").Inc()\n\t\t} else {\n\t\t\tserverRequestsFor{{$serviceName}}.WithLabelValues(\n\t\t\t\trequest.MethodName, request.Encoding, \"handler_fail\").Inc()\n\t\t}\n\t\t// report metric to Prometheus\n\t\tserverHETFor{{$serviceName}}.WithLabelValues(request.MethodName).Observe(\n\t\t\trequest.Elapsed().Seconds())\n\t}\n\n{{- end}}\n\tif immediateError == nil {\n\t\tif h.workers != nil {\n\t\t\t// Try queuing the request\n\t\t\tif err := h.workers.QueueRequest(request); err != nil {\n\t\t\t\tlog.Printf(\"nrpc: Error queuing the request: %s\", err)\n\t\t\t}\n\t\t} else {\n\t\t\t// Run the handler synchronously\n\t\t\trequest.RunAndReply()\n\t\t}\n\t}\n\n\tif immediateError != nil {\n\t\tif err := request.SendReply(nil, immediateError); err != nil {\n\t\t\tlog.Printf(\"{{.GetName}}Handler: {{.GetName}} handler failed to publish the response: %s\", err)\n{{- if Prometheus}}\n\t\t\tserverRequestsFor{{$serviceName}}.WithLabelValues(\n\t\t\t\trequest.MethodName, request.Encoding, \"handler_fail\").Inc()\n{{- end}}\n\t\t}\n{{- if Prometheus}}\n\t\tserverHETFor{{$serviceName}}.WithLabelValues(request.MethodName).Observe(\n\t\t\trequest.Elapsed().Seconds())\n{{- end}}\n\t} else {\n\t}\n}\n{{- end}}\n\ntype {{.GetName}}Client struct {\n\tnc      nrpc.NatsConn\n\t{{- if ne 0 (len $pkgSubject)}}\n\tPkgSubject string\n\t{{- end}}\n\t{{- range $pkgSubjectParams}}\n\tPkgParam{{ . }} string\n\t{{- end}}\n\tSubject string\n\t{{- range GetServiceSubjectParams .}}\n\tSvcParam{{ . }} string\n\t{{- end}}\n\tEncoding string\n\tTimeout time.Duration\n}\n\nfunc New{{.GetName}}Client(nc nrpc.NatsConn\n\t{{- range $pkgSubjectParams -}}\n\t, pkgParam{{.}} string\n\t{{- end -}}\n\t{{- range GetServiceSubjectParams . -}}\n\t, svcParam{{ . }} string\n\t{{- end -}}\n\t) *{{.GetName}}Client {\n\treturn &{{.GetName}}Client{\n\t\tnc:      nc,\n\t\t{{- if ne 0 (len $pkgSubject)}}\n\t\tPkgSubject: \"{{$pkgSubject}}\",\n\t\t{{- end}}\n\t\t{{- range $pkgSubjectParams}}\n\t\tPkgParam{{.}}: pkgParam{{.}},\n\t\t{{- end}}\n\t\tSubject: \"{{GetServiceSubject .}}\",\n\t\t{{- range GetServiceSubjectParams .}}\n\t\tSvcParam{{.}}: svcParam{{.}},\n\t\t{{- end}}\n\t\tEncoding: \"protobuf\",\n\t\tTimeout: 5 * time.Second,\n\t}\n}\n{{- $serviceName := .GetName}}\n{{- $serviceSubjectParams := GetServiceSubjectParams .}}\n{{- range .Method}}\n{{- $resultType := GetResultType .}}\n{{- if eq .GetInputType \".nrpc.NoRequest\"}}\n\nfunc (c *{{$serviceName}}Client) {{.GetName}}Subject(\n\t{{range GetMethodSubjectParams .}}mt{{.}} string,{{end}}\n) string {\n\tsubject := {{ if ne 0 (len $pkgSubject) -}}\n\t\tc.PkgSubject + \".\" + {{end}}\n\t{{- range $pkgSubjectParams -}}\n\t\tc.PkgParam{{.}} + \".\" + {{end -}}\n\tc.Subject + \".\" + {{range $serviceSubjectParams -}}\n\t\tc.SvcParam{{.}} + \".\" + {{end -}}\n\t\"{{GetMethodSubject .}}\"\n\t{{- range GetMethodSubjectParams .}} + \".\" + mt{{.}}{{end}}\n\tif c.Encoding != \"protobuf\" {\n\t\tsubject += \".\" + c.Encoding\n\t}\n\treturn subject\n}\n\ntype {{$serviceName}}{{.GetName}}Subscription struct {\n\t*nats.Subscription\n\t\n\tencoding string\n}\n\nfunc (s *{{$serviceName}}{{.GetName}}Subscription) Next(timeout time.Duration) (next {{GoType .GetOutputType}}, err error) {\n\tmsg, err := s.Subscription.NextMsg(timeout)\n\tif err != nil {\n\t\treturn\n\t}\n\terr = nrpc.Unmarshal(s.encoding, msg.Data, &next)\n\treturn\n}\n\nfunc (c *{{$serviceName}}Client) {{.GetName}}SubscribeSync(\n\t{{range GetMethodSubjectParams .}}mt{{.}} string,{{end}}\n) (sub *{{$serviceName}}{{.GetName}}Subscription, err error) {\n\tsubject := c.{{.GetName}}Subject(\n\t\t{{range GetMethodSubjectParams .}}mt{{.}},{{end}}\n\t)\n\tnatsSub, err := c.nc.SubscribeSync(subject)\n\tif err != nil {\n\t\treturn\n\t}\n\tsub = &{{$serviceName}}{{.GetName}}Subscription{natsSub, c.Encoding}\n\treturn\n}\n\nfunc (c *{{$serviceName}}Client) {{.GetName}}Subscribe(\n\t{{range GetMethodSubjectParams .}}mt{{.}} string,{{end}}\n\thandler func (*{{GoType .GetOutputType}}),\n) (sub *nats.Subscription, err error) {\n\tsubject := c.{{.GetName}}Subject(\n\t\t{{range GetMethodSubjectParams .}}mt{{.}},{{end}}\n\t)\n\tsub, err = c.nc.Subscribe(subject, func(msg *nats.Msg){\n\t\tvar pmsg {{GoType .GetOutputType}}\n\t\terr := nrpc.Unmarshal(c.Encoding, msg.Data, &pmsg)\n\t\tif err != nil {\n\t\t\tlog.Printf(\"{{$serviceName}}Client.{{.GetName}}Subscribe: Error decoding, %s\", err)\n\t\t\treturn\n\t\t}\n\t\thandler(&pmsg)\n\t})\n\treturn\n}\n\nfunc (c *{{$serviceName}}Client) {{.GetName}}SubscribeChan(\n\t{{range GetMethodSubjectParams .}}mt{{.}} string,{{end}}\n) (<-chan *{{GoType .GetOutputType}}, *nats.Subscription, error) {\n\tch := make(chan *{{GoType .GetOutputType}})\n\tsub, err := c.{{.GetName}}Subscribe(\n\t\t{{- range GetMethodSubjectParams .}}mt{{.}}, {{end -}}\n\t\tfunc (msg *{{GoType .GetOutputType}}) {\n\t\tch <- msg\n\t})\n\treturn ch, sub, err\n}\n\n{{- else if HasStreamedReply .}}\n\nfunc (c *{{$serviceName}}Client) {{.GetName}}(\n\tctx context.Context,\n\t{{- range GetMethodSubjectParams . -}}\n\t{{ . }} string,\n\t{{- end}}\n\t{{- if ne .GetInputType \".nrpc.Void\"}}\n\treq *{{GoType .GetInputType}},\n\t{{- end}}\n\tcb func (context.Context, *{{GoType .GetOutputType}}),\n) error {\n{{- if Prometheus}}\n\tstart := time.Now()\n{{- end}}\n\tsubject := {{ if ne 0 (len $pkgSubject) -}}\n\t\tc.PkgSubject + \".\" + {{end}}\n\t{{- range $pkgSubjectParams -}}\n\t\tc.PkgParam{{.}} + \".\" + {{end -}}\n\tc.Subject + \".\" + {{range $serviceSubjectParams -}}\n\t\tc.SvcParam{{.}} + \".\" + {{end -}}\n\t\"{{GetMethodSubject .}}\"\n\t{{- range GetMethodSubjectParams . }} + \".\" + {{ . }}{{ end }}\n\n\tsub, err := nrpc.StreamCall(ctx, c.nc, subject\n\t\t{{- if ne .GetInputType \".nrpc.Void\" -}}\n\t\t, req\n\t\t{{- else -}}\n\t\t, &nrpc.Void{}\n\t\t{{- end -}}\n\t\t, c.Encoding, c.Timeout)\n\tif err != nil {\n\t\t{{- if Prometheus}}\n\t\tclientCallsFor{{$serviceName}}.WithLabelValues(\n\t\t\t\"{{.GetName}}\", c.Encoding, \"error\").Inc()\n\t\t{{- end}}\n\t\treturn err\n\t}\n\n\tvar res {{GoType .GetOutputType}}\n\tfor {\n\t\terr = sub.Next(&res)\n\t\tif err != nil {\n\t\t\tbreak\n\t\t}\n\t\tcb(ctx, &res)\n\t}\n\tif err == nrpc.ErrEOS {\n\t\terr = nil\n\t}\n{{- if Prometheus}}\n\t// report total time taken to Prometheus\n\telapsed := time.Since(start).Seconds()\n\tclientRCTFor{{$serviceName}}.WithLabelValues(\"{{.GetName}}\").Observe(elapsed)\n\tclientCallsFor{{$serviceName}}.WithLabelValues(\n\t\t\"{{.GetName}}\", c.Encoding, \"success\").Inc()\n{{- end}}\n\treturn err\n}\n{{- else}}\n\nfunc (c *{{$serviceName}}Client) {{.GetName}}(\n\t{{- range GetMethodSubjectParams . -}}\n\t{{ . }} string, {{ end -}}\n\t{{- if ne .GetInputType \".nrpc.Void\" -}}\n\treq *{{GoType .GetInputType}}\n\t{{- end -}}) (\n\t\t{{- if not (eq $resultType \".nrpc.Void\" \".nrpc.NoReply\") -}}\n\t\t*{{GoType $resultType}}, {{end -}}\n\t\terror) {\n{{- if Prometheus}}\n\tstart := time.Now()\n{{- end}}\n\n\tsubject := {{ if ne 0 (len $pkgSubject) -}}\n\t\tc.PkgSubject + \".\" + {{end}}\n\t{{- range $pkgSubjectParams -}}\n\t\tc.PkgParam{{.}} + \".\" + {{end -}}\n\tc.Subject + \".\" + {{range $serviceSubjectParams -}}\n\t\tc.SvcParam{{.}} + \".\" + {{end -}}\n\t\"{{GetMethodSubject .}}\"\n\t{{- range GetMethodSubjectParams . }} + \".\" + {{ . }}{{ end }}\n\n\t// call\n\t{{- if eq .GetInputType \".nrpc.Void\"}}\n\tvar req = &{{GoType .GetInputType}}{}\n\t{{- end}}\n\tvar resp = {{GoType $resultType}}{}\n\tif err := nrpc.Call(req, &resp, c.nc, subject, c.Encoding, c.Timeout); err != nil {\n{{- if Prometheus}}\n\t\tclientCallsFor{{$serviceName}}.WithLabelValues(\n\t\t\t\"{{.GetName}}\", c.Encoding, \"call_fail\").Inc()\n{{- end}}\n\t\treturn {{ if not (eq $resultType \".nrpc.Void\" \".nrpc.NoReply\") }}nil, {{ end }}err\n\t}\n\n{{- if Prometheus}}\n\n\t// report total time taken to Prometheus\n\telapsed := time.Since(start).Seconds()\n\tclientRCTFor{{$serviceName}}.WithLabelValues(\"{{.GetName}}\").Observe(elapsed)\n\tclientCallsFor{{$serviceName}}.WithLabelValues(\n\t\t\"{{.GetName}}\", c.Encoding, \"success\").Inc()\n{{- end}}\n\n\treturn {{ if not (eq $resultType \".nrpc.Void\" \".nrpc.NoReply\") }}&resp, {{ end }}nil\n}\n\n{{- if HasPollEnabled .}}\n\nfunc (c *{{$serviceName}}Client) {{.GetName}}Poll(\n\t{{- range GetMethodSubjectParams . -}}\n\t{{ . }} string, {{ end -}}\n\t{{- if ne .GetInputType \".nrpc.Void\" -}}\n\treq *{{GoType .GetInputType}},\n\t{{- end -}}\n\tmaxreplies int, cb func (*{{GoType .GetOutputType}}) error,\n) (error) {\n{{- if Prometheus}}\n\tstart := time.Now()\n{{- end}}\n\n\tsubject := {{ if ne 0 (len $pkgSubject) -}}\n\t\tc.PkgSubject + \".\" + {{end}}\n\t{{- range $pkgSubjectParams -}}\n\t\tc.PkgParam{{.}} + \".\" + {{end -}}\n\tc.Subject + \".\" + {{range $serviceSubjectParams -}}\n\t\tc.SvcParam{{.}} + \".\" + {{end -}}\n\t\"{{GetMethodSubject .}}\"\n\t{{- range GetMethodSubjectParams . }} + \".\" + {{ . }}{{ end }}\n\n\t{{- if eq .GetInputType \".nrpc.Void\"}}\n\tvar req = &{{GoType .GetInputType}}{}\n\t{{- end}}\n\n\tvar resp {{GoType .GetOutputType}}\n\n\terr := nrpc.Poll(req, &resp, c.nc, subject, c.Encoding, c.Timeout, maxreplies,\n\t\tfunc() error {\n\t\t\treturn cb(&resp)\n\t\t},\n\t)\n\tif err != nil {\n{{- if Prometheus}}\n\t\tclientCallsFor{{$serviceName}}.WithLabelValues(\n\t\t\t\"{{.GetName}}\", c.Encoding, \"poll_fail\").Inc()\n{{- end}}\n\t\treturn err\n\t}\n\n{{- if Prometheus}}\n\n\t// report total time taken to Prometheus\n\telapsed := time.Since(start).Seconds()\n\tclientRCTFor{{$serviceName}}.WithLabelValues(\"{{.GetName}}\").Observe(elapsed)\n\tclientCallsFor{{$serviceName}}.WithLabelValues(\n\t\t\"{{.GetName}}\", c.Encoding, \"poll_success\").Inc()\n{{- end}}\n\n\treturn nil\n}\n{{- end}}\n\n{{- end}}\n{{- end}}\n{{- end}}\n\ntype Client struct {\n\tnc      nrpc.NatsConn\n\tdefaultEncoding string\n\tdefaultTimeout time.Duration\n\t{{- if ne 0 (len $pkgSubject)}}\n\tpkgSubject string\n\t{{- end}}\n\t{{- range $pkgSubjectParams}}\n\tpkgParam{{ . }} string\n\t{{- end}}\n\n\t{{- range .Service}}\n\t{{.GetName}} *{{.GetName}}Client\n\t{{- end}}\n}\n\nfunc NewClient(nc nrpc.NatsConn\n\t{{- range $pkgSubjectParams -}}\n\t, pkgParam{{.}} string\n\t{{- end -}}) *Client {\n\tc := Client{\n\t\tnc: nc,\n\t\tdefaultEncoding: \"protobuf\",\n\t\tdefaultTimeout: 5*time.Second,\n\t\t{{- if ne 0 (len $pkgSubject)}}\n\t\tpkgSubject: \"{{$pkgSubject}}\",\n\t\t{{- end}}\n\t\t{{- range $pkgSubjectParams}}\n\t\tpkgParam{{.}}: pkgParam{{.}},\n\t\t{{- end}}\n\t}\n\t{{- range .Service}}\n\t{{- if eq 0 (len (GetServiceSubjectParams .))}}\n\tc.{{.GetName}} = New{{.GetName}}Client(nc\n\t{{- range $pkgSubjectParams -}}\n\t\t, c.pkgParam{{ . }}\n\t{{- end}})\n\t{{- end}}\n\t{{- end}}\n\treturn &c\n}\n\nfunc (c *Client) SetEncoding(encoding string) {\n\tc.defaultEncoding = encoding\n\t{{- range .Service}}\n\tif c.{{.GetName}} != nil {\n\t\tc.{{.GetName}}.Encoding = encoding\n\t}\n\t{{- end}}\n}\n\nfunc (c *Client) SetTimeout(t time.Duration) {\n\tc.defaultTimeout = t\n\t{{- range .Service}}\n\tif c.{{.GetName}} != nil {\n\t\tc.{{.GetName}}.Timeout = t\n\t}\n\t{{- end}}\n}\n\n{{- range .Service}}\n{{- if ne 0 (len (GetServiceSubjectParams .))}}\n\nfunc (c *Client) Set{{.GetName}}Params(\n\t{{- range GetServiceSubjectParams .}}\n\t{{ . }} string,\n\t{{- end}}\n) {\n\tc.{{.GetName}} = New{{.GetName}}Client(\n\t\tc.nc,\n\t{{- range $pkgSubjectParams}}\n\t\tc.pkgParam{{ . }},\n\t{{- end}}\n\t{{- range GetServiceSubjectParams .}}\n\t\t{{ . }},\n\t{{- end}}\n\t)\n\tc.{{.GetName}}.Encoding = c.defaultEncoding\n\tc.{{.GetName}}.Timeout = c.defaultTimeout\n}\n\nfunc (c *Client) New{{.GetName}}(\n\t{{- range GetServiceSubjectParams .}}\n\t{{ . }} string,\n\t{{- end}}\n) *{{.GetName}}Client {\n\tclient := New{{.GetName}}Client(\n\t\tc.nc,\n\t{{- range $pkgSubjectParams}}\n\t\tc.pkgParam{{ . }},\n\t{{- end}}\n\t{{- range GetServiceSubjectParams .}}\n\t\t{{ . }},\n\t{{- end}}\n\t)\n\tclient.Encoding = c.defaultEncoding\n\tclient.Timeout = c.defaultTimeout\n\treturn client\n}\n{{- end}}\n{{- end}}\n\n{{- if Prometheus}}\n\nfunc init() {\n{{- range .Service}}\n\t// register metrics for service {{.GetName}}\n\tprometheus.MustRegister(clientRCTFor{{.GetName}})\n\tprometheus.MustRegister(serverHETFor{{.GetName}})\n\tprometheus.MustRegister(clientCallsFor{{.GetName}})\n\tprometheus.MustRegister(serverRequestsFor{{.GetName}})\n{{- end}}\n}\n{{- end}}`\n"
  },
  {
    "path": "testrunner_test.go",
    "content": "package nrpc\n\nimport (\n\t\"log\"\n\t\"os\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/nats-io/nats-server/v2/logger\"\n\t\"github.com/nats-io/nats-server/v2/server\"\n)\n\nvar NatsURL string\n\nfunc TestMain(m *testing.M) {\n\tgnatsd := server.New(&server.Options{Port: server.RANDOM_PORT})\n\tgnatsd.SetLogger(\n\t\tlogger.NewStdLogger(false, false, false, false, false),\n\t\tfalse, false)\n\tgo gnatsd.Start()\n\tdefer gnatsd.Shutdown()\n\n\tif !gnatsd.ReadyForConnections(time.Second) {\n\t\tlog.Fatal(\"Cannot start the gnatsd server\")\n\t}\n\tNatsURL = \"nats://\" + gnatsd.Addr().String()\n\n\tos.Exit(m.Run())\n}\n"
  }
]