warp-grpc (empty) → 0.1.0.0
raw patch · 13 files changed
+1829/−0 lines, 13 filesdep +basedep +binarydep +bytestringsetup-changed
Dependencies added: base, binary, bytestring, case-insensitive, http-types, http2-grpc-types, proto-lens, proto-lens-protoc, wai, warp, warp-grpc, warp-tls
Files
- ChangeLog.md +3/−0
- LICENSE +30/−0
- README.md +82/−0
- Setup.hs +2/−0
- app/Main.hs +69/−0
- gen/Proto/Protos/Grpcbin.hs +986/−0
- gen/Proto/Protos/Grpcbin_Fields.hs +196/−0
- src/Network/GRPC/Server.hs +55/−0
- src/Network/GRPC/Server/Handlers.hs +162/−0
- src/Network/GRPC/Server/Helpers.hs +21/−0
- src/Network/GRPC/Server/Wai.hs +125/−0
- test/Spec.hs +2/−0
- warp-grpc.cabal +96/−0
+ ChangeLog.md view
@@ -0,0 +1,3 @@+# Changelog for warp-grpc++## Unreleased changes
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Lucas DiCioccio (c) 2018++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++ * Redistributions of source code must retain the above copyright+ notice, this list of conditions and the following disclaimer.++ * Redistributions in binary form must reproduce the above+ copyright notice, this list of conditions and the following+ disclaimer in the documentation and/or other materials provided+ with the distribution.++ * Neither the name of Author name here nor the names of other+ contributors may be used to endorse or promote products derived+ from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,82 @@+# warp-grpc++A gRPC server implementation on top of Warp's HTTP2 handler. The lib also+contains a demo sever using the awesome `grpcb.in` Proto. The current release+is an advanced technical demo, expect a few breaking changes.++## Usage++### Prerequisites++In addition to a working Haskell dev environment, you need to:+- build the `proto-lens-protoc` executable (`proto-lens`)+- install the `protoc` executable++### Adding .proto files to a Haskell package++In order to run gRPC:++- generate the `Proto` stubs in some `gen` directory++A single `protoc` invocation may be enough for both Proto and GRPC outputs:++```bash+protoc "--plugin=protoc-gen-haskell-protolens=${protolens}" \+ --haskell-protolens_out=./gen \+ -I "${protodir1} \+ -I "${protodir2} \+ ${first.proto} \+ ${second.proto}+```++- add the `gen` sourcedir for the generated to your .cabal/package.yaml file (cf. 'hs-source-dirs').+- add the generated Proto modules to the 'exposed-modules' (or 'other-modules') keys++A reliable way to list the module names is the following bash invocation:++```bash+find gen -name "*.hs" | sed -e 's/gen\///' | sed -e 's/\.hs$//' | tr '/' '.'+```++Unlike `proto-lens`, this project does not yet provide a modified `Setup.hs`.+As a result, we cannot automate these steps from within Cabal/Stack. Hence,+you'll have to automate these steps outside your Haskell toolchain.+++### Build a certificate++In shell,++```shell+openssl genrsa -out key.pem 2048+openssl req -new -key key.pem -out certificate.csr+openssl x509 -req -in certificate.csr -signkey key.pem -out certificate.pem+```++### Build and run the example binary++- stack build+- stack exec -- warp-grpc-exe++Note that you'll need a patched Warp using https://github.com/yesodweb/wai/pull/711 .++## Design++The library implements gRPC using a WAI middleware for a set of gRPC endpoints.+Endpoint handlers differ depending of the streaming/unary-ty of individual+RPCs. Bidirectional streams will be supported next.++There is little specification around the expected allowed observable states in+gRPC, hence the types this library presents make conservative choices: unary+RPCs expect an input before providing an output. Client stream allows to return+an output only when the client has stopped streaming. Server streams wait for+an input before starting to iterate sending outputs.++## Next steps++* Split the `grpcb.in` example from the lib.+* Handler type for bidirectional streams.++## Limitations++* Only supports "h2" with TLS (I'd argue it's a feature, not a bug. Don't @-me)
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ app/Main.hs view
@@ -0,0 +1,69 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE DataKinds #-}+module Main where++import Network.GRPC.Server++import Control.Concurrent (threadDelay)+import Data.ProtoLens.Message (def)+import Network.Wai.Handler.WarpTLS (defaultTlsSettings)+import Network.Wai.Handler.Warp (defaultSettings)+import Network.GRPC.HTTP2.Types (RPC(..))+import Network.GRPC.HTTP2.Encoding (gzip)+import Proto.Protos.Grpcbin (GRPCBin, EmptyMessage(..), IndexReply(..), IndexReply'Endpoint(..))++main :: IO ()+main = runGrpc defaultTlsSettings defaultSettings handlers [gzip]++handlers :: [ServiceHandler]+handlers =+ [ unary (RPC :: RPC GRPCBin "empty") handleEmpty+ , unary (RPC :: RPC GRPCBin "index") handleIndex+ , unary (RPC :: RPC GRPCBin "specificError") handleSpecificError+ , unary (RPC :: RPC GRPCBin "randomError") handleRandomError+ , unary (RPC :: RPC GRPCBin "dummyUnary") handleDummyUnary+ , serverStream (RPC :: RPC GRPCBin "dummyServerStream") handleDummyServerStream+ , clientStream (RPC :: RPC GRPCBin "dummyClientStream") handleDummyClientStream+ ]++handleIndex :: UnaryHandler GRPCBin "index"+handleIndex _ input = do+ print ("index"::[Char], input)+ return $ IndexReply "desc" [IndexReply'Endpoint "/path1" "ill-supported" def] def++handleEmpty :: UnaryHandler GRPCBin "empty"+handleEmpty _ input = do+ print ("empty"::[Char], input)+ return $ EmptyMessage def++handleSpecificError :: UnaryHandler GRPCBin "specificError"+handleSpecificError _ input = do+ print ("specificError"::[Char], input)+ _ <- throwIO $ GRPCStatus INTERNAL "noo"+ return $ EmptyMessage def++handleRandomError :: UnaryHandler GRPCBin "randomError"+handleRandomError _ input = do+ print ("randomError"::[Char], input)+ return $ EmptyMessage def++handleDummyUnary :: UnaryHandler GRPCBin "dummyUnary"+handleDummyUnary _ input = pure input++handleDummyServerStream :: ServerStreamHandler GRPCBin "dummyServerStream" Int+handleDummyServerStream _ input = do+ print ("sstream-start"::[Char], input)+ return $ (10, ServerStream $ \n -> do+ threadDelay 1000000+ if n == 0+ then print ("sstream-end"::[Char]) >> return Nothing+ else do+ print ("sstream-msg"::[Char], n)+ return $ Just (n-1, def))++handleDummyClientStream :: ClientStreamHandler GRPCBin "dummyClientStream" Int+handleDummyClientStream _ = do+ print ("cstream-start"::[Char])+ return $ (0, ClientStream+ (\n input -> print ("cstream-msg"::[Char], n, input) >> return (n+1))+ (\n -> print ("cstream-end"::[Char], n) >> return def))
+ gen/Proto/Protos/Grpcbin.hs view
@@ -0,0 +1,986 @@+{- This file was auto-generated from protos/grpcbin.proto by the proto-lens-protoc program. -}+{-# LANGUAGE ScopedTypeVariables, DataKinds, TypeFamilies,+ UndecidableInstances, GeneralizedNewtypeDeriving,+ MultiParamTypeClasses, FlexibleContexts, FlexibleInstances,+ PatternSynonyms, MagicHash, NoImplicitPrelude, DataKinds #-}+{-# OPTIONS_GHC -fno-warn-unused-imports#-}+{-# OPTIONS_GHC -fno-warn-duplicate-exports#-}+module Proto.Protos.Grpcbin+ (GRPCBin(..), DummyMessage(..), DummyMessage'Enum(..),+ DummyMessage'Enum(), DummyMessage'Enum'UnrecognizedValue,+ DummyMessage'Sub(..), EmptyMessage(..), HeadersMessage(..),+ HeadersMessage'MetadataEntry(..), HeadersMessage'Values(..),+ IndexReply(..), IndexReply'Endpoint(..), SpecificErrorRequest(..))+ where+import qualified Data.ProtoLens.Reexport.Lens.Labels.Prism+ as Lens.Labels.Prism+import qualified Data.ProtoLens.Reexport.Prelude as Prelude+import qualified Data.ProtoLens.Reexport.Data.Int as Data.Int+import qualified Data.ProtoLens.Reexport.Data.Word as Data.Word+import qualified Data.ProtoLens.Reexport.Data.ProtoLens+ as Data.ProtoLens+import qualified+ Data.ProtoLens.Reexport.Data.ProtoLens.Message.Enum+ as Data.ProtoLens.Message.Enum+import qualified+ Data.ProtoLens.Reexport.Data.ProtoLens.Service.Types+ as Data.ProtoLens.Service.Types+import qualified Data.ProtoLens.Reexport.Lens.Family2+ as Lens.Family2+import qualified Data.ProtoLens.Reexport.Lens.Family2.Unchecked+ as Lens.Family2.Unchecked+import qualified Data.ProtoLens.Reexport.Data.Default.Class+ as Data.Default.Class+import qualified Data.ProtoLens.Reexport.Data.Text as Data.Text+import qualified Data.ProtoLens.Reexport.Data.Map as Data.Map+import qualified Data.ProtoLens.Reexport.Data.ByteString+ as Data.ByteString+import qualified Data.ProtoLens.Reexport.Data.ByteString.Char8+ as Data.ByteString.Char8+import qualified Data.ProtoLens.Reexport.Lens.Labels as Lens.Labels+import qualified Data.ProtoLens.Reexport.Text.Read as Text.Read++{- | Fields :++ * 'Proto.Protos.Grpcbin_Fields.fString' @:: Lens' DummyMessage Data.Text.Text@+ * 'Proto.Protos.Grpcbin_Fields.fStrings' @:: Lens' DummyMessage [Data.Text.Text]@+ * 'Proto.Protos.Grpcbin_Fields.fInt32' @:: Lens' DummyMessage Data.Int.Int32@+ * 'Proto.Protos.Grpcbin_Fields.fInt32s' @:: Lens' DummyMessage [Data.Int.Int32]@+ * 'Proto.Protos.Grpcbin_Fields.fEnum' @:: Lens' DummyMessage DummyMessage'Enum@+ * 'Proto.Protos.Grpcbin_Fields.fEnums' @:: Lens' DummyMessage [DummyMessage'Enum]@+ * 'Proto.Protos.Grpcbin_Fields.fSub' @:: Lens' DummyMessage DummyMessage'Sub@+ * 'Proto.Protos.Grpcbin_Fields.maybe'fSub' @:: Lens' DummyMessage (Prelude.Maybe DummyMessage'Sub)@+ * 'Proto.Protos.Grpcbin_Fields.fSubs' @:: Lens' DummyMessage [DummyMessage'Sub]@+ * 'Proto.Protos.Grpcbin_Fields.fBool' @:: Lens' DummyMessage Prelude.Bool@+ * 'Proto.Protos.Grpcbin_Fields.fBools' @:: Lens' DummyMessage [Prelude.Bool]@+ * 'Proto.Protos.Grpcbin_Fields.fInt64' @:: Lens' DummyMessage Data.Int.Int64@+ * 'Proto.Protos.Grpcbin_Fields.fInt64s' @:: Lens' DummyMessage [Data.Int.Int64]@+ * 'Proto.Protos.Grpcbin_Fields.fBytes' @:: Lens' DummyMessage Data.ByteString.ByteString@+ * 'Proto.Protos.Grpcbin_Fields.fBytess' @:: Lens' DummyMessage [Data.ByteString.ByteString]@+ * 'Proto.Protos.Grpcbin_Fields.fFloat' @:: Lens' DummyMessage Prelude.Float@+ * 'Proto.Protos.Grpcbin_Fields.fFloats' @:: Lens' DummyMessage [Prelude.Float]@+ -}+data DummyMessage = DummyMessage{_DummyMessage'fString ::+ !Data.Text.Text,+ _DummyMessage'fStrings :: ![Data.Text.Text],+ _DummyMessage'fInt32 :: !Data.Int.Int32,+ _DummyMessage'fInt32s :: ![Data.Int.Int32],+ _DummyMessage'fEnum :: !DummyMessage'Enum,+ _DummyMessage'fEnums :: ![DummyMessage'Enum],+ _DummyMessage'fSub :: !(Prelude.Maybe DummyMessage'Sub),+ _DummyMessage'fSubs :: ![DummyMessage'Sub],+ _DummyMessage'fBool :: !Prelude.Bool,+ _DummyMessage'fBools :: ![Prelude.Bool],+ _DummyMessage'fInt64 :: !Data.Int.Int64,+ _DummyMessage'fInt64s :: ![Data.Int.Int64],+ _DummyMessage'fBytes :: !Data.ByteString.ByteString,+ _DummyMessage'fBytess :: ![Data.ByteString.ByteString],+ _DummyMessage'fFloat :: !Prelude.Float,+ _DummyMessage'fFloats :: ![Prelude.Float],+ _DummyMessage'_unknownFields :: !Data.ProtoLens.FieldSet}+ deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)+instance (Lens.Labels.HasLens' f DummyMessage x a, a ~ b) =>+ Lens.Labels.HasLens f DummyMessage DummyMessage x a b+ where+ lensOf = Lens.Labels.lensOf'+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fString" (Data.Text.Text)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fString+ (\ x__ y__ -> x__{_DummyMessage'fString = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fStrings" ([Data.Text.Text])+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fStrings+ (\ x__ y__ -> x__{_DummyMessage'fStrings = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fInt32" (Data.Int.Int32)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fInt32+ (\ x__ y__ -> x__{_DummyMessage'fInt32 = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fInt32s" ([Data.Int.Int32])+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fInt32s+ (\ x__ y__ -> x__{_DummyMessage'fInt32s = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fEnum" (DummyMessage'Enum)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fEnum+ (\ x__ y__ -> x__{_DummyMessage'fEnum = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fEnums" ([DummyMessage'Enum])+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fEnums+ (\ x__ y__ -> x__{_DummyMessage'fEnums = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fSub" (DummyMessage'Sub)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fSub+ (\ x__ y__ -> x__{_DummyMessage'fSub = y__}))+ (Data.ProtoLens.maybeLens Data.Default.Class.def)+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "maybe'fSub"+ (Prelude.Maybe DummyMessage'Sub)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fSub+ (\ x__ y__ -> x__{_DummyMessage'fSub = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fSubs" ([DummyMessage'Sub])+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fSubs+ (\ x__ y__ -> x__{_DummyMessage'fSubs = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fBool" (Prelude.Bool)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fBool+ (\ x__ y__ -> x__{_DummyMessage'fBool = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fBools" ([Prelude.Bool])+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fBools+ (\ x__ y__ -> x__{_DummyMessage'fBools = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fInt64" (Data.Int.Int64)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fInt64+ (\ x__ y__ -> x__{_DummyMessage'fInt64 = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fInt64s" ([Data.Int.Int64])+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fInt64s+ (\ x__ y__ -> x__{_DummyMessage'fInt64s = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fBytes"+ (Data.ByteString.ByteString)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fBytes+ (\ x__ y__ -> x__{_DummyMessage'fBytes = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fBytess"+ ([Data.ByteString.ByteString])+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fBytess+ (\ x__ y__ -> x__{_DummyMessage'fBytess = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fFloat" (Prelude.Float)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fFloat+ (\ x__ y__ -> x__{_DummyMessage'fFloat = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage "fFloats" ([Prelude.Float])+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'fFloats+ (\ x__ y__ -> x__{_DummyMessage'fFloats = y__}))+ Prelude.id+instance Data.Default.Class.Default DummyMessage where+ def+ = DummyMessage{_DummyMessage'fString = Data.ProtoLens.fieldDefault,+ _DummyMessage'fStrings = [],+ _DummyMessage'fInt32 = Data.ProtoLens.fieldDefault,+ _DummyMessage'fInt32s = [],+ _DummyMessage'fEnum = Data.Default.Class.def,+ _DummyMessage'fEnums = [], _DummyMessage'fSub = Prelude.Nothing,+ _DummyMessage'fSubs = [],+ _DummyMessage'fBool = Data.ProtoLens.fieldDefault,+ _DummyMessage'fBools = [],+ _DummyMessage'fInt64 = Data.ProtoLens.fieldDefault,+ _DummyMessage'fInt64s = [],+ _DummyMessage'fBytes = Data.ProtoLens.fieldDefault,+ _DummyMessage'fBytess = [],+ _DummyMessage'fFloat = Data.ProtoLens.fieldDefault,+ _DummyMessage'fFloats = [], _DummyMessage'_unknownFields = ([])}+instance Data.ProtoLens.Message DummyMessage where+ messageName _ = Data.Text.pack "grpcbin.DummyMessage"+ fieldsByTag+ = let fString__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_string"+ (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::+ Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fString")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fStrings__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_strings"+ (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::+ Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)+ (Data.ProtoLens.RepeatedField Data.ProtoLens.Unpacked+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fStrings")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fInt32__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_int32"+ (Data.ProtoLens.ScalarField Data.ProtoLens.Int32Field ::+ Data.ProtoLens.FieldTypeDescriptor Data.Int.Int32)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fInt32")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fInt32s__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_int32s"+ (Data.ProtoLens.ScalarField Data.ProtoLens.Int32Field ::+ Data.ProtoLens.FieldTypeDescriptor Data.Int.Int32)+ (Data.ProtoLens.RepeatedField Data.ProtoLens.Packed+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fInt32s")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fEnum__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_enum"+ (Data.ProtoLens.ScalarField Data.ProtoLens.EnumField ::+ Data.ProtoLens.FieldTypeDescriptor DummyMessage'Enum)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fEnum")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fEnums__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_enums"+ (Data.ProtoLens.ScalarField Data.ProtoLens.EnumField ::+ Data.ProtoLens.FieldTypeDescriptor DummyMessage'Enum)+ (Data.ProtoLens.RepeatedField Data.ProtoLens.Packed+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fEnums")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fSub__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_sub"+ (Data.ProtoLens.MessageField Data.ProtoLens.MessageType ::+ Data.ProtoLens.FieldTypeDescriptor DummyMessage'Sub)+ (Data.ProtoLens.OptionalField+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "maybe'fSub")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fSubs__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_subs"+ (Data.ProtoLens.MessageField Data.ProtoLens.MessageType ::+ Data.ProtoLens.FieldTypeDescriptor DummyMessage'Sub)+ (Data.ProtoLens.RepeatedField Data.ProtoLens.Unpacked+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fSubs")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fBool__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_bool"+ (Data.ProtoLens.ScalarField Data.ProtoLens.BoolField ::+ Data.ProtoLens.FieldTypeDescriptor Prelude.Bool)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fBool")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fBools__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_bools"+ (Data.ProtoLens.ScalarField Data.ProtoLens.BoolField ::+ Data.ProtoLens.FieldTypeDescriptor Prelude.Bool)+ (Data.ProtoLens.RepeatedField Data.ProtoLens.Packed+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fBools")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fInt64__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_int64"+ (Data.ProtoLens.ScalarField Data.ProtoLens.Int64Field ::+ Data.ProtoLens.FieldTypeDescriptor Data.Int.Int64)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fInt64")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fInt64s__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_int64s"+ (Data.ProtoLens.ScalarField Data.ProtoLens.Int64Field ::+ Data.ProtoLens.FieldTypeDescriptor Data.Int.Int64)+ (Data.ProtoLens.RepeatedField Data.ProtoLens.Packed+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fInt64s")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fBytes__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_bytes"+ (Data.ProtoLens.ScalarField Data.ProtoLens.BytesField ::+ Data.ProtoLens.FieldTypeDescriptor Data.ByteString.ByteString)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fBytes")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fBytess__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_bytess"+ (Data.ProtoLens.ScalarField Data.ProtoLens.BytesField ::+ Data.ProtoLens.FieldTypeDescriptor Data.ByteString.ByteString)+ (Data.ProtoLens.RepeatedField Data.ProtoLens.Unpacked+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fBytess")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fFloat__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_float"+ (Data.ProtoLens.ScalarField Data.ProtoLens.FloatField ::+ Data.ProtoLens.FieldTypeDescriptor Prelude.Float)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fFloat")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ fFloats__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_floats"+ (Data.ProtoLens.ScalarField Data.ProtoLens.FloatField ::+ Data.ProtoLens.FieldTypeDescriptor Prelude.Float)+ (Data.ProtoLens.RepeatedField Data.ProtoLens.Packed+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fFloats")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage+ in+ Data.Map.fromList+ [(Data.ProtoLens.Tag 1, fString__field_descriptor),+ (Data.ProtoLens.Tag 2, fStrings__field_descriptor),+ (Data.ProtoLens.Tag 3, fInt32__field_descriptor),+ (Data.ProtoLens.Tag 4, fInt32s__field_descriptor),+ (Data.ProtoLens.Tag 5, fEnum__field_descriptor),+ (Data.ProtoLens.Tag 6, fEnums__field_descriptor),+ (Data.ProtoLens.Tag 7, fSub__field_descriptor),+ (Data.ProtoLens.Tag 8, fSubs__field_descriptor),+ (Data.ProtoLens.Tag 9, fBool__field_descriptor),+ (Data.ProtoLens.Tag 10, fBools__field_descriptor),+ (Data.ProtoLens.Tag 11, fInt64__field_descriptor),+ (Data.ProtoLens.Tag 12, fInt64s__field_descriptor),+ (Data.ProtoLens.Tag 13, fBytes__field_descriptor),+ (Data.ProtoLens.Tag 14, fBytess__field_descriptor),+ (Data.ProtoLens.Tag 15, fFloat__field_descriptor),+ (Data.ProtoLens.Tag 16, fFloats__field_descriptor)]+ unknownFields+ = Lens.Family2.Unchecked.lens _DummyMessage'_unknownFields+ (\ x__ y__ -> x__{_DummyMessage'_unknownFields = y__})+data DummyMessage'Enum = DummyMessage'ENUM_0+ | DummyMessage'ENUM_1+ | DummyMessage'ENUM_2+ | DummyMessage'Enum'Unrecognized !DummyMessage'Enum'UnrecognizedValue+ deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)+newtype DummyMessage'Enum'UnrecognizedValue = DummyMessage'Enum'UnrecognizedValue Data.Int.Int32+ deriving (Prelude.Eq, Prelude.Ord, Prelude.Show)+instance Data.ProtoLens.MessageEnum DummyMessage'Enum where+ maybeToEnum 0 = Prelude.Just DummyMessage'ENUM_0+ maybeToEnum 1 = Prelude.Just DummyMessage'ENUM_1+ maybeToEnum 2 = Prelude.Just DummyMessage'ENUM_2+ maybeToEnum k+ = Prelude.Just+ (DummyMessage'Enum'Unrecognized+ (DummyMessage'Enum'UnrecognizedValue (Prelude.fromIntegral k)))+ showEnum DummyMessage'ENUM_0 = "ENUM_0"+ showEnum DummyMessage'ENUM_1 = "ENUM_1"+ showEnum DummyMessage'ENUM_2 = "ENUM_2"+ showEnum+ (DummyMessage'Enum'Unrecognized+ (DummyMessage'Enum'UnrecognizedValue k))+ = Prelude.show k+ readEnum "ENUM_0" = Prelude.Just DummyMessage'ENUM_0+ readEnum "ENUM_1" = Prelude.Just DummyMessage'ENUM_1+ readEnum "ENUM_2" = Prelude.Just DummyMessage'ENUM_2+ readEnum k+ = (Prelude.>>=) (Text.Read.readMaybe k) Data.ProtoLens.maybeToEnum+instance Prelude.Bounded DummyMessage'Enum where+ minBound = DummyMessage'ENUM_0+ maxBound = DummyMessage'ENUM_2+instance Prelude.Enum DummyMessage'Enum where+ toEnum k__+ = Prelude.maybe+ (Prelude.error+ ((Prelude.++) "toEnum: unknown value for enum Enum: "+ (Prelude.show k__)))+ Prelude.id+ (Data.ProtoLens.maybeToEnum k__)+ fromEnum DummyMessage'ENUM_0 = 0+ fromEnum DummyMessage'ENUM_1 = 1+ fromEnum DummyMessage'ENUM_2 = 2+ fromEnum+ (DummyMessage'Enum'Unrecognized+ (DummyMessage'Enum'UnrecognizedValue k))+ = Prelude.fromIntegral k+ succ DummyMessage'ENUM_2+ = Prelude.error+ "DummyMessage'Enum.succ: bad argument DummyMessage'ENUM_2. This value would be out of bounds."+ succ DummyMessage'ENUM_0 = DummyMessage'ENUM_1+ succ DummyMessage'ENUM_1 = DummyMessage'ENUM_2+ succ _+ = Prelude.error+ "DummyMessage'Enum.succ: bad argument: unrecognized value"+ pred DummyMessage'ENUM_0+ = Prelude.error+ "DummyMessage'Enum.pred: bad argument DummyMessage'ENUM_0. This value would be out of bounds."+ pred DummyMessage'ENUM_1 = DummyMessage'ENUM_0+ pred DummyMessage'ENUM_2 = DummyMessage'ENUM_1+ pred _+ = Prelude.error+ "DummyMessage'Enum.pred: bad argument: unrecognized value"+ enumFrom = Data.ProtoLens.Message.Enum.messageEnumFrom+ enumFromTo = Data.ProtoLens.Message.Enum.messageEnumFromTo+ enumFromThen = Data.ProtoLens.Message.Enum.messageEnumFromThen+ enumFromThenTo = Data.ProtoLens.Message.Enum.messageEnumFromThenTo+instance Data.Default.Class.Default DummyMessage'Enum where+ def = DummyMessage'ENUM_0+instance Data.ProtoLens.FieldDefault DummyMessage'Enum where+ fieldDefault = DummyMessage'ENUM_0+{- | Fields :++ * 'Proto.Protos.Grpcbin_Fields.fString' @:: Lens' DummyMessage'Sub Data.Text.Text@+ -}+data DummyMessage'Sub = DummyMessage'Sub{_DummyMessage'Sub'fString+ :: !Data.Text.Text,+ _DummyMessage'Sub'_unknownFields ::+ !Data.ProtoLens.FieldSet}+ deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)+instance (Lens.Labels.HasLens' f DummyMessage'Sub x a, a ~ b) =>+ Lens.Labels.HasLens f DummyMessage'Sub DummyMessage'Sub x a b+ where+ lensOf = Lens.Labels.lensOf'+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f DummyMessage'Sub "fString" (Data.Text.Text)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _DummyMessage'Sub'fString+ (\ x__ y__ -> x__{_DummyMessage'Sub'fString = y__}))+ Prelude.id+instance Data.Default.Class.Default DummyMessage'Sub where+ def+ = DummyMessage'Sub{_DummyMessage'Sub'fString =+ Data.ProtoLens.fieldDefault,+ _DummyMessage'Sub'_unknownFields = ([])}+instance Data.ProtoLens.Message DummyMessage'Sub where+ messageName _ = Data.Text.pack "grpcbin.DummyMessage.Sub"+ fieldsByTag+ = let fString__field_descriptor+ = Data.ProtoLens.FieldDescriptor "f_string"+ (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::+ Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fString")))+ :: Data.ProtoLens.FieldDescriptor DummyMessage'Sub+ in+ Data.Map.fromList+ [(Data.ProtoLens.Tag 1, fString__field_descriptor)]+ unknownFields+ = Lens.Family2.Unchecked.lens _DummyMessage'Sub'_unknownFields+ (\ x__ y__ -> x__{_DummyMessage'Sub'_unknownFields = y__})+{- | Fields :++ -}+data EmptyMessage = EmptyMessage{_EmptyMessage'_unknownFields ::+ !Data.ProtoLens.FieldSet}+ deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)+instance (Lens.Labels.HasLens' f EmptyMessage x a, a ~ b) =>+ Lens.Labels.HasLens f EmptyMessage EmptyMessage x a b+ where+ lensOf = Lens.Labels.lensOf'+instance Data.Default.Class.Default EmptyMessage where+ def = EmptyMessage{_EmptyMessage'_unknownFields = ([])}+instance Data.ProtoLens.Message EmptyMessage where+ messageName _ = Data.Text.pack "grpcbin.EmptyMessage"+ fieldsByTag = let in Data.Map.fromList []+ unknownFields+ = Lens.Family2.Unchecked.lens _EmptyMessage'_unknownFields+ (\ x__ y__ -> x__{_EmptyMessage'_unknownFields = y__})+{- | Fields :++ * 'Proto.Protos.Grpcbin_Fields.metadata' @:: Lens' HeadersMessage+ (Data.Map.Map Data.Text.Text HeadersMessage'Values)@+ -}+data HeadersMessage = HeadersMessage{_HeadersMessage'metadata ::+ !(Data.Map.Map Data.Text.Text HeadersMessage'Values),+ _HeadersMessage'_unknownFields :: !Data.ProtoLens.FieldSet}+ deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)+instance (Lens.Labels.HasLens' f HeadersMessage x a, a ~ b) =>+ Lens.Labels.HasLens f HeadersMessage HeadersMessage x a b+ where+ lensOf = Lens.Labels.lensOf'+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f HeadersMessage "metadata"+ (Data.Map.Map Data.Text.Text HeadersMessage'Values)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _HeadersMessage'metadata+ (\ x__ y__ -> x__{_HeadersMessage'metadata = y__}))+ Prelude.id+instance Data.Default.Class.Default HeadersMessage where+ def+ = HeadersMessage{_HeadersMessage'metadata = Data.Map.empty,+ _HeadersMessage'_unknownFields = ([])}+instance Data.ProtoLens.Message HeadersMessage where+ messageName _ = Data.Text.pack "grpcbin.HeadersMessage"+ fieldsByTag+ = let metadata__field_descriptor+ = Data.ProtoLens.FieldDescriptor "Metadata"+ (Data.ProtoLens.MessageField Data.ProtoLens.MessageType ::+ Data.ProtoLens.FieldTypeDescriptor HeadersMessage'MetadataEntry)+ (Data.ProtoLens.MapField+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "key"))+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "value"))+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "metadata")))+ :: Data.ProtoLens.FieldDescriptor HeadersMessage+ in+ Data.Map.fromList+ [(Data.ProtoLens.Tag 1, metadata__field_descriptor)]+ unknownFields+ = Lens.Family2.Unchecked.lens _HeadersMessage'_unknownFields+ (\ x__ y__ -> x__{_HeadersMessage'_unknownFields = y__})+{- | Fields :++ * 'Proto.Protos.Grpcbin_Fields.key' @:: Lens' HeadersMessage'MetadataEntry Data.Text.Text@+ * 'Proto.Protos.Grpcbin_Fields.value' @:: Lens' HeadersMessage'MetadataEntry HeadersMessage'Values@+ * 'Proto.Protos.Grpcbin_Fields.maybe'value' @:: Lens' HeadersMessage'MetadataEntry+ (Prelude.Maybe HeadersMessage'Values)@+ -}+data HeadersMessage'MetadataEntry = HeadersMessage'MetadataEntry{_HeadersMessage'MetadataEntry'key+ :: !Data.Text.Text,+ _HeadersMessage'MetadataEntry'value+ ::+ !(Prelude.Maybe+ HeadersMessage'Values),+ _HeadersMessage'MetadataEntry'_unknownFields+ :: !Data.ProtoLens.FieldSet}+ deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)+instance (Lens.Labels.HasLens' f HeadersMessage'MetadataEntry x a,+ a ~ b) =>+ Lens.Labels.HasLens f HeadersMessage'MetadataEntry+ HeadersMessage'MetadataEntry+ x+ a+ b+ where+ lensOf = Lens.Labels.lensOf'+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f HeadersMessage'MetadataEntry "key"+ (Data.Text.Text)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _HeadersMessage'MetadataEntry'key+ (\ x__ y__ -> x__{_HeadersMessage'MetadataEntry'key = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f HeadersMessage'MetadataEntry "value"+ (HeadersMessage'Values)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _HeadersMessage'MetadataEntry'value+ (\ x__ y__ -> x__{_HeadersMessage'MetadataEntry'value = y__}))+ (Data.ProtoLens.maybeLens Data.Default.Class.def)+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f HeadersMessage'MetadataEntry "maybe'value"+ (Prelude.Maybe HeadersMessage'Values)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _HeadersMessage'MetadataEntry'value+ (\ x__ y__ -> x__{_HeadersMessage'MetadataEntry'value = y__}))+ Prelude.id+instance Data.Default.Class.Default HeadersMessage'MetadataEntry+ where+ def+ = HeadersMessage'MetadataEntry{_HeadersMessage'MetadataEntry'key =+ Data.ProtoLens.fieldDefault,+ _HeadersMessage'MetadataEntry'value = Prelude.Nothing,+ _HeadersMessage'MetadataEntry'_unknownFields = ([])}+instance Data.ProtoLens.Message HeadersMessage'MetadataEntry where+ messageName _+ = Data.Text.pack "grpcbin.HeadersMessage.MetadataEntry"+ fieldsByTag+ = let key__field_descriptor+ = Data.ProtoLens.FieldDescriptor "key"+ (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::+ Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "key")))+ :: Data.ProtoLens.FieldDescriptor HeadersMessage'MetadataEntry+ value__field_descriptor+ = Data.ProtoLens.FieldDescriptor "value"+ (Data.ProtoLens.MessageField Data.ProtoLens.MessageType ::+ Data.ProtoLens.FieldTypeDescriptor HeadersMessage'Values)+ (Data.ProtoLens.OptionalField+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "maybe'value")))+ :: Data.ProtoLens.FieldDescriptor HeadersMessage'MetadataEntry+ in+ Data.Map.fromList+ [(Data.ProtoLens.Tag 1, key__field_descriptor),+ (Data.ProtoLens.Tag 2, value__field_descriptor)]+ unknownFields+ = Lens.Family2.Unchecked.lens+ _HeadersMessage'MetadataEntry'_unknownFields+ (\ x__ y__ ->+ x__{_HeadersMessage'MetadataEntry'_unknownFields = y__})+{- | Fields :++ * 'Proto.Protos.Grpcbin_Fields.values' @:: Lens' HeadersMessage'Values [Data.Text.Text]@+ -}+data HeadersMessage'Values = HeadersMessage'Values{_HeadersMessage'Values'values+ :: ![Data.Text.Text],+ _HeadersMessage'Values'_unknownFields ::+ !Data.ProtoLens.FieldSet}+ deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)+instance (Lens.Labels.HasLens' f HeadersMessage'Values x a,+ a ~ b) =>+ Lens.Labels.HasLens f HeadersMessage'Values HeadersMessage'Values x+ a+ b+ where+ lensOf = Lens.Labels.lensOf'+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f HeadersMessage'Values "values"+ ([Data.Text.Text])+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _HeadersMessage'Values'values+ (\ x__ y__ -> x__{_HeadersMessage'Values'values = y__}))+ Prelude.id+instance Data.Default.Class.Default HeadersMessage'Values where+ def+ = HeadersMessage'Values{_HeadersMessage'Values'values = [],+ _HeadersMessage'Values'_unknownFields = ([])}+instance Data.ProtoLens.Message HeadersMessage'Values where+ messageName _ = Data.Text.pack "grpcbin.HeadersMessage.Values"+ fieldsByTag+ = let values__field_descriptor+ = Data.ProtoLens.FieldDescriptor "values"+ (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::+ Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)+ (Data.ProtoLens.RepeatedField Data.ProtoLens.Unpacked+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "values")))+ :: Data.ProtoLens.FieldDescriptor HeadersMessage'Values+ in+ Data.Map.fromList+ [(Data.ProtoLens.Tag 1, values__field_descriptor)]+ unknownFields+ = Lens.Family2.Unchecked.lens _HeadersMessage'Values'_unknownFields+ (\ x__ y__ -> x__{_HeadersMessage'Values'_unknownFields = y__})+{- | Fields :++ * 'Proto.Protos.Grpcbin_Fields.description' @:: Lens' IndexReply Data.Text.Text@+ * 'Proto.Protos.Grpcbin_Fields.endpoints' @:: Lens' IndexReply [IndexReply'Endpoint]@+ -}+data IndexReply = IndexReply{_IndexReply'description ::+ !Data.Text.Text,+ _IndexReply'endpoints :: ![IndexReply'Endpoint],+ _IndexReply'_unknownFields :: !Data.ProtoLens.FieldSet}+ deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)+instance (Lens.Labels.HasLens' f IndexReply x a, a ~ b) =>+ Lens.Labels.HasLens f IndexReply IndexReply x a b+ where+ lensOf = Lens.Labels.lensOf'+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f IndexReply "description" (Data.Text.Text)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _IndexReply'description+ (\ x__ y__ -> x__{_IndexReply'description = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f IndexReply "endpoints"+ ([IndexReply'Endpoint])+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _IndexReply'endpoints+ (\ x__ y__ -> x__{_IndexReply'endpoints = y__}))+ Prelude.id+instance Data.Default.Class.Default IndexReply where+ def+ = IndexReply{_IndexReply'description = Data.ProtoLens.fieldDefault,+ _IndexReply'endpoints = [], _IndexReply'_unknownFields = ([])}+instance Data.ProtoLens.Message IndexReply where+ messageName _ = Data.Text.pack "grpcbin.IndexReply"+ fieldsByTag+ = let description__field_descriptor+ = Data.ProtoLens.FieldDescriptor "description"+ (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::+ Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "description")))+ :: Data.ProtoLens.FieldDescriptor IndexReply+ endpoints__field_descriptor+ = Data.ProtoLens.FieldDescriptor "endpoints"+ (Data.ProtoLens.MessageField Data.ProtoLens.MessageType ::+ Data.ProtoLens.FieldTypeDescriptor IndexReply'Endpoint)+ (Data.ProtoLens.RepeatedField Data.ProtoLens.Unpacked+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "endpoints")))+ :: Data.ProtoLens.FieldDescriptor IndexReply+ in+ Data.Map.fromList+ [(Data.ProtoLens.Tag 1, description__field_descriptor),+ (Data.ProtoLens.Tag 2, endpoints__field_descriptor)]+ unknownFields+ = Lens.Family2.Unchecked.lens _IndexReply'_unknownFields+ (\ x__ y__ -> x__{_IndexReply'_unknownFields = y__})+{- | Fields :++ * 'Proto.Protos.Grpcbin_Fields.path' @:: Lens' IndexReply'Endpoint Data.Text.Text@+ * 'Proto.Protos.Grpcbin_Fields.description' @:: Lens' IndexReply'Endpoint Data.Text.Text@+ -}+data IndexReply'Endpoint = IndexReply'Endpoint{_IndexReply'Endpoint'path+ :: !Data.Text.Text,+ _IndexReply'Endpoint'description :: !Data.Text.Text,+ _IndexReply'Endpoint'_unknownFields ::+ !Data.ProtoLens.FieldSet}+ deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)+instance (Lens.Labels.HasLens' f IndexReply'Endpoint x a, a ~ b) =>+ Lens.Labels.HasLens f IndexReply'Endpoint IndexReply'Endpoint x a b+ where+ lensOf = Lens.Labels.lensOf'+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f IndexReply'Endpoint "path" (Data.Text.Text)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _IndexReply'Endpoint'path+ (\ x__ y__ -> x__{_IndexReply'Endpoint'path = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f IndexReply'Endpoint "description"+ (Data.Text.Text)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _IndexReply'Endpoint'description+ (\ x__ y__ -> x__{_IndexReply'Endpoint'description = y__}))+ Prelude.id+instance Data.Default.Class.Default IndexReply'Endpoint where+ def+ = IndexReply'Endpoint{_IndexReply'Endpoint'path =+ Data.ProtoLens.fieldDefault,+ _IndexReply'Endpoint'description = Data.ProtoLens.fieldDefault,+ _IndexReply'Endpoint'_unknownFields = ([])}+instance Data.ProtoLens.Message IndexReply'Endpoint where+ messageName _ = Data.Text.pack "grpcbin.IndexReply.Endpoint"+ fieldsByTag+ = let path__field_descriptor+ = Data.ProtoLens.FieldDescriptor "path"+ (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::+ Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "path")))+ :: Data.ProtoLens.FieldDescriptor IndexReply'Endpoint+ description__field_descriptor+ = Data.ProtoLens.FieldDescriptor "description"+ (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::+ Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "description")))+ :: Data.ProtoLens.FieldDescriptor IndexReply'Endpoint+ in+ Data.Map.fromList+ [(Data.ProtoLens.Tag 1, path__field_descriptor),+ (Data.ProtoLens.Tag 2, description__field_descriptor)]+ unknownFields+ = Lens.Family2.Unchecked.lens _IndexReply'Endpoint'_unknownFields+ (\ x__ y__ -> x__{_IndexReply'Endpoint'_unknownFields = y__})+{- | Fields :++ * 'Proto.Protos.Grpcbin_Fields.code' @:: Lens' SpecificErrorRequest Data.Word.Word32@+ * 'Proto.Protos.Grpcbin_Fields.reason' @:: Lens' SpecificErrorRequest Data.Text.Text@+ -}+data SpecificErrorRequest = SpecificErrorRequest{_SpecificErrorRequest'code+ :: !Data.Word.Word32,+ _SpecificErrorRequest'reason :: !Data.Text.Text,+ _SpecificErrorRequest'_unknownFields ::+ !Data.ProtoLens.FieldSet}+ deriving (Prelude.Show, Prelude.Eq, Prelude.Ord)+instance (Lens.Labels.HasLens' f SpecificErrorRequest x a,+ a ~ b) =>+ Lens.Labels.HasLens f SpecificErrorRequest SpecificErrorRequest x a+ b+ where+ lensOf = Lens.Labels.lensOf'+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f SpecificErrorRequest "code"+ (Data.Word.Word32)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _SpecificErrorRequest'code+ (\ x__ y__ -> x__{_SpecificErrorRequest'code = y__}))+ Prelude.id+instance Prelude.Functor f =>+ Lens.Labels.HasLens' f SpecificErrorRequest "reason"+ (Data.Text.Text)+ where+ lensOf' _+ = (Prelude..)+ (Lens.Family2.Unchecked.lens _SpecificErrorRequest'reason+ (\ x__ y__ -> x__{_SpecificErrorRequest'reason = y__}))+ Prelude.id+instance Data.Default.Class.Default SpecificErrorRequest where+ def+ = SpecificErrorRequest{_SpecificErrorRequest'code =+ Data.ProtoLens.fieldDefault,+ _SpecificErrorRequest'reason = Data.ProtoLens.fieldDefault,+ _SpecificErrorRequest'_unknownFields = ([])}+instance Data.ProtoLens.Message SpecificErrorRequest where+ messageName _ = Data.Text.pack "grpcbin.SpecificErrorRequest"+ fieldsByTag+ = let code__field_descriptor+ = Data.ProtoLens.FieldDescriptor "code"+ (Data.ProtoLens.ScalarField Data.ProtoLens.UInt32Field ::+ Data.ProtoLens.FieldTypeDescriptor Data.Word.Word32)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "code")))+ :: Data.ProtoLens.FieldDescriptor SpecificErrorRequest+ reason__field_descriptor+ = Data.ProtoLens.FieldDescriptor "reason"+ (Data.ProtoLens.ScalarField Data.ProtoLens.StringField ::+ Data.ProtoLens.FieldTypeDescriptor Data.Text.Text)+ (Data.ProtoLens.PlainField Data.ProtoLens.Optional+ (Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "reason")))+ :: Data.ProtoLens.FieldDescriptor SpecificErrorRequest+ in+ Data.Map.fromList+ [(Data.ProtoLens.Tag 1, code__field_descriptor),+ (Data.ProtoLens.Tag 2, reason__field_descriptor)]+ unknownFields+ = Lens.Family2.Unchecked.lens _SpecificErrorRequest'_unknownFields+ (\ x__ y__ -> x__{_SpecificErrorRequest'_unknownFields = y__})+data GRPCBin = GRPCBin{}+ deriving ()+instance Data.ProtoLens.Service.Types.Service GRPCBin where+ type ServiceName GRPCBin = "GRPCBin"+ type ServicePackage GRPCBin = "grpcbin"+ type ServiceMethods GRPCBin =+ '["dummyBidirectionalStreamStream", "dummyClientStream",+ "dummyServerStream", "dummyUnary", "empty", "headersUnary",+ "index", "noResponseUnary", "randomError", "specificError"]+instance Data.ProtoLens.Service.Types.HasMethodImpl GRPCBin "index"+ where+ type MethodName GRPCBin "index" = "Index"+ type MethodInput GRPCBin "index" = EmptyMessage+ type MethodOutput GRPCBin "index" = IndexReply+ type MethodStreamingType GRPCBin "index" =+ 'Data.ProtoLens.Service.Types.NonStreaming+instance Data.ProtoLens.Service.Types.HasMethodImpl GRPCBin "empty"+ where+ type MethodName GRPCBin "empty" = "Empty"+ type MethodInput GRPCBin "empty" = EmptyMessage+ type MethodOutput GRPCBin "empty" = EmptyMessage+ type MethodStreamingType GRPCBin "empty" =+ 'Data.ProtoLens.Service.Types.NonStreaming+instance Data.ProtoLens.Service.Types.HasMethodImpl GRPCBin+ "dummyUnary"+ where+ type MethodName GRPCBin "dummyUnary" = "DummyUnary"+ type MethodInput GRPCBin "dummyUnary" = DummyMessage+ type MethodOutput GRPCBin "dummyUnary" = DummyMessage+ type MethodStreamingType GRPCBin "dummyUnary" =+ 'Data.ProtoLens.Service.Types.NonStreaming+instance Data.ProtoLens.Service.Types.HasMethodImpl GRPCBin+ "dummyServerStream"+ where+ type MethodName GRPCBin "dummyServerStream" = "DummyServerStream"+ type MethodInput GRPCBin "dummyServerStream" = DummyMessage+ type MethodOutput GRPCBin "dummyServerStream" = DummyMessage+ type MethodStreamingType GRPCBin "dummyServerStream" =+ 'Data.ProtoLens.Service.Types.ServerStreaming+instance Data.ProtoLens.Service.Types.HasMethodImpl GRPCBin+ "dummyClientStream"+ where+ type MethodName GRPCBin "dummyClientStream" = "DummyClientStream"+ type MethodInput GRPCBin "dummyClientStream" = DummyMessage+ type MethodOutput GRPCBin "dummyClientStream" = DummyMessage+ type MethodStreamingType GRPCBin "dummyClientStream" =+ 'Data.ProtoLens.Service.Types.ClientStreaming+instance Data.ProtoLens.Service.Types.HasMethodImpl GRPCBin+ "dummyBidirectionalStreamStream"+ where+ type MethodName GRPCBin "dummyBidirectionalStreamStream" =+ "DummyBidirectionalStreamStream"+ type MethodInput GRPCBin "dummyBidirectionalStreamStream" =+ DummyMessage+ type MethodOutput GRPCBin "dummyBidirectionalStreamStream" =+ DummyMessage+ type MethodStreamingType GRPCBin "dummyBidirectionalStreamStream" =+ 'Data.ProtoLens.Service.Types.BiDiStreaming+instance Data.ProtoLens.Service.Types.HasMethodImpl GRPCBin+ "specificError"+ where+ type MethodName GRPCBin "specificError" = "SpecificError"+ type MethodInput GRPCBin "specificError" = SpecificErrorRequest+ type MethodOutput GRPCBin "specificError" = EmptyMessage+ type MethodStreamingType GRPCBin "specificError" =+ 'Data.ProtoLens.Service.Types.NonStreaming+instance Data.ProtoLens.Service.Types.HasMethodImpl GRPCBin+ "randomError"+ where+ type MethodName GRPCBin "randomError" = "RandomError"+ type MethodInput GRPCBin "randomError" = EmptyMessage+ type MethodOutput GRPCBin "randomError" = EmptyMessage+ type MethodStreamingType GRPCBin "randomError" =+ 'Data.ProtoLens.Service.Types.NonStreaming+instance Data.ProtoLens.Service.Types.HasMethodImpl GRPCBin+ "headersUnary"+ where+ type MethodName GRPCBin "headersUnary" = "HeadersUnary"+ type MethodInput GRPCBin "headersUnary" = EmptyMessage+ type MethodOutput GRPCBin "headersUnary" = HeadersMessage+ type MethodStreamingType GRPCBin "headersUnary" =+ 'Data.ProtoLens.Service.Types.NonStreaming+instance Data.ProtoLens.Service.Types.HasMethodImpl GRPCBin+ "noResponseUnary"+ where+ type MethodName GRPCBin "noResponseUnary" = "NoResponseUnary"+ type MethodInput GRPCBin "noResponseUnary" = EmptyMessage+ type MethodOutput GRPCBin "noResponseUnary" = EmptyMessage+ type MethodStreamingType GRPCBin "noResponseUnary" =+ 'Data.ProtoLens.Service.Types.NonStreaming
+ gen/Proto/Protos/Grpcbin_Fields.hs view
@@ -0,0 +1,196 @@+{- This file was auto-generated from protos/grpcbin.proto by the proto-lens-protoc program. -}+{-# LANGUAGE ScopedTypeVariables, DataKinds, TypeFamilies,+ UndecidableInstances, GeneralizedNewtypeDeriving,+ MultiParamTypeClasses, FlexibleContexts, FlexibleInstances,+ PatternSynonyms, MagicHash, NoImplicitPrelude, DataKinds #-}+{-# OPTIONS_GHC -fno-warn-unused-imports#-}+{-# OPTIONS_GHC -fno-warn-duplicate-exports#-}+module Proto.Protos.Grpcbin_Fields where+import qualified Data.ProtoLens.Reexport.Prelude as Prelude+import qualified Data.ProtoLens.Reexport.Data.Int as Data.Int+import qualified Data.ProtoLens.Reexport.Data.Word as Data.Word+import qualified Data.ProtoLens.Reexport.Data.ProtoLens+ as Data.ProtoLens+import qualified+ Data.ProtoLens.Reexport.Data.ProtoLens.Message.Enum+ as Data.ProtoLens.Message.Enum+import qualified+ Data.ProtoLens.Reexport.Data.ProtoLens.Service.Types+ as Data.ProtoLens.Service.Types+import qualified Data.ProtoLens.Reexport.Lens.Family2+ as Lens.Family2+import qualified Data.ProtoLens.Reexport.Lens.Family2.Unchecked+ as Lens.Family2.Unchecked+import qualified Data.ProtoLens.Reexport.Data.Default.Class+ as Data.Default.Class+import qualified Data.ProtoLens.Reexport.Data.Text as Data.Text+import qualified Data.ProtoLens.Reexport.Data.Map as Data.Map+import qualified Data.ProtoLens.Reexport.Data.ByteString+ as Data.ByteString+import qualified Data.ProtoLens.Reexport.Data.ByteString.Char8+ as Data.ByteString.Char8+import qualified Data.ProtoLens.Reexport.Lens.Labels as Lens.Labels+import qualified Data.ProtoLens.Reexport.Text.Read as Text.Read++code ::+ forall f s t a b . (Lens.Labels.HasLens f s t "code" a b) =>+ Lens.Family2.LensLike f s t a b+code+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "code")+description ::+ forall f s t a b . (Lens.Labels.HasLens f s t "description" a b) =>+ Lens.Family2.LensLike f s t a b+description+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "description")+endpoints ::+ forall f s t a b . (Lens.Labels.HasLens f s t "endpoints" a b) =>+ Lens.Family2.LensLike f s t a b+endpoints+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "endpoints")+fBool ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fBool" a b) =>+ Lens.Family2.LensLike f s t a b+fBool+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fBool")+fBools ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fBools" a b) =>+ Lens.Family2.LensLike f s t a b+fBools+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fBools")+fBytes ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fBytes" a b) =>+ Lens.Family2.LensLike f s t a b+fBytes+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fBytes")+fBytess ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fBytess" a b) =>+ Lens.Family2.LensLike f s t a b+fBytess+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fBytess")+fEnum ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fEnum" a b) =>+ Lens.Family2.LensLike f s t a b+fEnum+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fEnum")+fEnums ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fEnums" a b) =>+ Lens.Family2.LensLike f s t a b+fEnums+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fEnums")+fFloat ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fFloat" a b) =>+ Lens.Family2.LensLike f s t a b+fFloat+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fFloat")+fFloats ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fFloats" a b) =>+ Lens.Family2.LensLike f s t a b+fFloats+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fFloats")+fInt32 ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fInt32" a b) =>+ Lens.Family2.LensLike f s t a b+fInt32+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fInt32")+fInt32s ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fInt32s" a b) =>+ Lens.Family2.LensLike f s t a b+fInt32s+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fInt32s")+fInt64 ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fInt64" a b) =>+ Lens.Family2.LensLike f s t a b+fInt64+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fInt64")+fInt64s ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fInt64s" a b) =>+ Lens.Family2.LensLike f s t a b+fInt64s+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fInt64s")+fString ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fString" a b) =>+ Lens.Family2.LensLike f s t a b+fString+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fString")+fStrings ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fStrings" a b) =>+ Lens.Family2.LensLike f s t a b+fStrings+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fStrings")+fSub ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fSub" a b) =>+ Lens.Family2.LensLike f s t a b+fSub+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fSub")+fSubs ::+ forall f s t a b . (Lens.Labels.HasLens f s t "fSubs" a b) =>+ Lens.Family2.LensLike f s t a b+fSubs+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "fSubs")+key ::+ forall f s t a b . (Lens.Labels.HasLens f s t "key" a b) =>+ Lens.Family2.LensLike f s t a b+key+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "key")+maybe'fSub ::+ forall f s t a b . (Lens.Labels.HasLens f s t "maybe'fSub" a b) =>+ Lens.Family2.LensLike f s t a b+maybe'fSub+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "maybe'fSub")+maybe'value ::+ forall f s t a b . (Lens.Labels.HasLens f s t "maybe'value" a b) =>+ Lens.Family2.LensLike f s t a b+maybe'value+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "maybe'value")+metadata ::+ forall f s t a b . (Lens.Labels.HasLens f s t "metadata" a b) =>+ Lens.Family2.LensLike f s t a b+metadata+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "metadata")+path ::+ forall f s t a b . (Lens.Labels.HasLens f s t "path" a b) =>+ Lens.Family2.LensLike f s t a b+path+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "path")+reason ::+ forall f s t a b . (Lens.Labels.HasLens f s t "reason" a b) =>+ Lens.Family2.LensLike f s t a b+reason+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "reason")+value ::+ forall f s t a b . (Lens.Labels.HasLens f s t "value" a b) =>+ Lens.Family2.LensLike f s t a b+value+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "value")+values ::+ forall f s t a b . (Lens.Labels.HasLens f s t "values" a b) =>+ Lens.Family2.LensLike f s t a b+values+ = Lens.Labels.lensOf+ ((Lens.Labels.proxy#) :: (Lens.Labels.Proxy#) "values")
+ src/Network/GRPC/Server.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}+-- TODO:+-- * read timeout+-- * proper primitives for streaming+module Network.GRPC.Server+ ( runGrpc+ , UnaryHandler+ , ServerStreamHandler+ , ServerStream(..)+ , ClientStreamHandler+ , ClientStream(..)+ -- * registration+ , ServiceHandler+ , unary+ , serverStream+ , clientStream+ -- * registration+ , GRPCStatus (..)+ , throwIO+ , GRPCStatusMessage+ , GRPCStatusCode (..)+ -- * to work directly with WAI+ , grpcApp+ , grpcService+ ) where++import Control.Exception (throwIO)+import Network.GRPC.HTTP2.Encoding (Compression)+import Network.GRPC.HTTP2.Types (GRPCStatus(..), GRPCStatusCode(..), GRPCStatusMessage)+import Network.Wai.Handler.WarpTLS (TLSSettings, runTLS)+import Network.Wai.Handler.Warp (Settings)++import Network.GRPC.Server.Handlers (UnaryHandler, unary, ServerStreamHandler, ServerStream(..), serverStream, ClientStreamHandler, ClientStream(..), clientStream)+import Network.GRPC.Server.Wai (ServiceHandler(..), grpcApp, grpcService)++-- | Helper to constructs and serve a gRPC over HTTP2 application.+--+-- You may want to use 'grpcApp' for adding middlewares to your gRPC server.+runGrpc+ :: TLSSettings+ -- ^ TLS settings for the HTTP2 server.+ -> Settings+ -- ^ Warp settings.+ -> [ServiceHandler]+ -- ^ List of ServiceHandler. Refer to 'grcpApp'+ -> [Compression]+ -- ^ Compression methods used.+ -> IO ()+runGrpc tlsSettings settings handlers compressions =+ runTLS tlsSettings settings (grpcApp compressions handlers)
+ src/Network/GRPC/Server/Handlers.hs view
@@ -0,0 +1,162 @@+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedStrings #-}+module Network.GRPC.Server.Handlers where++import Data.Binary.Get (pushChunk, Decoder(..))+import qualified Data.ByteString.Char8 as ByteString+import Data.ByteString.Char8 (ByteString)+import Data.ByteString.Lazy (toStrict)+import Data.ProtoLens.Message (Message)+import Data.ProtoLens.Service.Types (Service(..), HasMethod, HasMethodImpl(..))+import Network.GRPC.HTTP2.Encoding (decodeInput, encodeOutput, Encoding(..), Decoding(..))+import Network.GRPC.HTTP2.Types (RPC(..), GRPCStatus(..), GRPCStatusCode(..), path)+import Network.Wai (Request, requestBody, strictRequestBody)++import Network.GRPC.Server.Wai (WaiHandler, ServiceHandler(..), closeEarly)++-- | Handy type to refer to Handler for 'unary' RPCs handler.+type UnaryHandler s m = Request -> MethodInput s m -> IO (MethodOutput s m)++-- | Handy type for 'server-streaming' RPCs.+--+-- We expect an implementation to:+-- - read the input request+-- - return an initial state and an state-passing action that the server code will call to fetch the output to send to the client (or close an a Nothing)+-- See 'ServerStream' for the type which embodies these requirements.+type ServerStreamHandler s m a = Request -> MethodInput s m -> IO (a, ServerStream s m a)++newtype ServerStream s m a = ServerStream {+ serverStreamNext :: a -> IO (Maybe (a, MethodOutput s m))+ }++-- | Handy type for 'client-streaming' RPCs.+--+-- We expect an implementation to:+-- - acknowledge a the new client stream by returning an initial state and two functions:+-- - a state-passing handler for new client message+-- - a state-aware handler for answering the client when it is ending its stream+-- See 'ClientStream' for the type which embodies these requirements.+type ClientStreamHandler s m a = Request -> IO (a, ClientStream s m a)++data ClientStream s m a = ClientStream {+ clientStreamHandler :: a -> MethodInput s m -> IO a+ , clientStreamFinalizer :: a -> IO (MethodOutput s m)+ }++-- | Construct a handler for handling a unary RPC.+unary+ :: (Service s, HasMethod s m)+ => RPC s m+ -> UnaryHandler s m+ -> ServiceHandler+unary rpc handler =+ ServiceHandler (path rpc) (handleUnary rpc handler)++-- | Construct a handler for handling a server-streaming RPC.+serverStream+ :: (Service s, HasMethod s m)+ => RPC s m+ -> ServerStreamHandler s m a+ -> ServiceHandler+serverStream rpc handler =+ ServiceHandler (path rpc) (handleServerStream rpc handler)++-- | Construct a handler for handling a client-streaming RPC.+clientStream+ :: (Service s, HasMethod s m)+ => RPC s m+ -> ClientStreamHandler s m a+ -> ServiceHandler+clientStream rpc handler =+ ServiceHandler (path rpc) (handleClientStream rpc handler)++-- | Handle unary RPCs.+handleUnary ::+ (Service s, HasMethod s m)+ => RPC s m+ -> UnaryHandler s m+ -> WaiHandler+handleUnary rpc handler decoding encoding req write flush = do+ handleRequestChunksLoop (decodeInput rpc $ _getDecodingCompression decoding) handleMsg handleEof nextChunk+ where+ nextChunk = toStrict <$> strictRequestBody req+ handleMsg = errorOnLeftOver (\i -> handler req i >>= reply)+ handleEof = closeEarly (GRPCStatus INVALID_ARGUMENT "early end of request body")+ reply msg = write (encodeOutput rpc (_getEncodingCompression encoding) msg) >> flush++-- | Handle Server-Streaming RPCs.+handleServerStream ::+ (Service s, HasMethod s m)+ => RPC s m+ -> ServerStreamHandler s m a+ -> WaiHandler+handleServerStream rpc handler decoding encoding req write flush = do+ handleRequestChunksLoop (decodeInput rpc $ _getDecodingCompression decoding) handleMsg handleEof nextChunk+ where+ nextChunk = toStrict <$> strictRequestBody req+ handleMsg = errorOnLeftOver (\i -> handler req i >>= replyN)+ handleEof = closeEarly (GRPCStatus INVALID_ARGUMENT "early end of request body")+ replyN (v, sStream) = do+ let go v1 = serverStreamNext sStream v1 >>= \case+ Just (v2, msg) -> do+ write (encodeOutput rpc (_getEncodingCompression encoding) msg) >> flush+ go v2+ Nothing -> pure ()+ go v++-- | Handle Client-Streaming RPCs.+handleClientStream ::+ (Service s, HasMethod s m)+ => RPC s m+ -> ClientStreamHandler s m a+ -> WaiHandler+handleClientStream rpc handler0 decoding encoding req write flush = do+ handler0 req >>= go+ where+ go (v, cStream) = handleRequestChunksLoop (decodeInput rpc $ _getDecodingCompression decoding) (handleMsg v) (handleEof v) nextChunk+ where+ nextChunk = requestBody req+ handleMsg v0 dat msg = clientStreamHandler cStream v0 msg >>= \v1 -> loop dat v1+ handleEof v0 = clientStreamFinalizer cStream v0 >>= reply+ reply msg = write (encodeOutput rpc (_getEncodingCompression encoding) msg) >> flush+ loop chunk v1 = handleRequestChunksLoop (flip pushChunk chunk $ decodeInput rpc (_getDecodingCompression decoding)) (handleMsg v1) (handleEof v1) nextChunk++-- | Helpers to consume input in chunks.+handleRequestChunksLoop+ :: (Message a)+ => Decoder (Either String a)+ -- ^ Message decoder.+ -> (ByteString -> a -> IO ())+ -- ^ Handler for a single message.+ -- The ByteString corresponds to leftover data.+ -> IO ()+ -- ^ Handler for handling end-of-streams.+ -> IO ByteString+ -- ^ Action to retrieve the next chunk.+ -> IO ()+{-# INLINEABLE handleRequestChunksLoop #-}+handleRequestChunksLoop decoder handleMsg handleEof nextChunk =+ case decoder of+ (Done unusedDat _ (Right val)) -> do+ handleMsg unusedDat val+ (Done _ _ (Left err)) -> do+ closeEarly (GRPCStatus INVALID_ARGUMENT (ByteString.pack $ "done-error: " ++ err))+ (Fail _ _ err) ->+ closeEarly (GRPCStatus INVALID_ARGUMENT (ByteString.pack $ "fail-error: " ++ err))+ partial@(Partial _) -> do+ chunk <- nextChunk+ if ByteString.null chunk+ then+ handleEof+ else+ handleRequestChunksLoop (pushChunk partial chunk) handleMsg handleEof nextChunk++-- | Combinator around message handler to error on left overs.+--+-- This combinator ensures that, unless for client stream, an unparsed piece of+-- data with a correctly-read message is treated as an error.+errorOnLeftOver :: (a -> IO b) -> ByteString -> a -> IO b+errorOnLeftOver f rest+ | ByteString.null rest = f+ | otherwise = const $ closeEarly $ GRPCStatus INVALID_ARGUMENT ("left-overs: " <> rest)
+ src/Network/GRPC/Server/Helpers.hs view
@@ -0,0 +1,21 @@+++module Network.GRPC.Server.Helpers where++import qualified Data.ByteString.Char8 as ByteString+import Data.Maybe (fromMaybe)+import Network.GRPC.HTTP2.Types (GRPCStatus(..), trailerForStatusCode, grpcStatusH, grpcMessageH)+import Network.Wai (Request)+import Network.Wai.Handler.Warp (http2dataTrailers, defaultHTTP2Data, modifyHTTP2Data, HTTP2Data)++-- | Helper to set the GRPCStatus on the trailers reply.+modifyGRPCStatus :: Request -> GRPCStatus -> IO ()+modifyGRPCStatus req = modifyHTTP2Data req . makeGRPCTrailers++makeGRPCTrailers :: GRPCStatus -> (Maybe HTTP2Data -> Maybe HTTP2Data)+makeGRPCTrailers (GRPCStatus s msg) h2data =+ Just $! (fromMaybe defaultHTTP2Data h2data) { http2dataTrailers = trailers }+ where+ trailers = if ByteString.null msg then [status] else [status, message]+ status = (grpcStatusH, trailerForStatusCode s)+ message = (grpcMessageH, msg)
+ src/Network/GRPC/Server/Wai.hs view
@@ -0,0 +1,125 @@+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Network.GRPC.Server.Wai where++import Control.Exception (Handler(..), catches, SomeException, throwIO)+import Data.ByteString.Char8 (ByteString)+import qualified Data.ByteString.Char8 as ByteString+import Data.ByteString.Lazy (fromStrict)+import Data.Binary.Builder (Builder)+import Data.Maybe (fromMaybe)+import qualified Data.CaseInsensitive as CI+import qualified Data.List as List+import Network.GRPC.HTTP2.Encoding (Compression, Encoding(..), Decoding(..), grpcCompressionHV, uncompressed)+import Network.GRPC.HTTP2.Types (GRPCStatus(..), GRPCStatusCode(..), grpcStatusH, grpcMessageH, grpcContentTypeHV, grpcEncodingH, grpcAcceptEncodingH)+import Network.HTTP.Types (status200, status404)+import Network.Wai (Application, Request(..), rawPathInfo, responseLBS, responseStream, requestHeaders)++import Network.GRPC.Server.Helpers (modifyGRPCStatus)++-- | A Wai Handler for a request.+type WaiHandler =+ Decoding+ -- ^ Compression for the request inputs.+ -> Encoding+ -- ^ Compression for the request outputs.+ -> Request+ -- ^ Request object.+ -> (Builder -> IO ())+ -- ^ Write a data chunk in the reply.+ -> IO ()+ -- ^ Flush the output.+ -> IO ()++-- | Untyped gRPC Service handler.+data ServiceHandler = ServiceHandler {+ grpcHandlerPath :: ByteString+ -- ^ Path to the Service to be handled.+ , grpcWaiHandler :: WaiHandler+ -- ^ Actual request handler.+ }++-- | Build a WAI 'Application' from a list of ServiceHandler.+--+-- Currently, gRPC calls are lookuped up by traversing the list of ServiceHandler.+-- This lookup may be inefficient for large amount of servics.+grpcApp :: [Compression] -> [ServiceHandler] -> Application+grpcApp compressions services =+ grpcService compressions services err404app+ where+ err404app :: Application+ err404app req rep =+ rep $ responseLBS status404 [] $ fromStrict ("not found: " <> rawPathInfo req)++-- | Aborts a GRPC handler with a given GRPCStatus.+closeEarly :: GRPCStatus -> IO a+closeEarly = throwIO++-- | Build a WAI 'Middleware' from a list of ServiceHandler.+--+-- Currently, gRPC calls are lookuped up by traversing the list of ServiceHandler.+-- This lookup may be inefficient for large amount of services.+grpcService :: [Compression] -> [ServiceHandler] -> (Application -> Application)+grpcService compressions services app = \req rep -> do+ case lookupHandler (rawPathInfo req) services of+ Just handler ->+ -- Handler that catches early GRPC termination and other exceptions.+ --+ -- Other exceptions are turned into GRPC status INTERNAL (rather+ -- than returning a 500).+ --+ -- These exceptions are swallowed from the WAI "onException"+ -- handler, so we'll need a better way to handle this case.+ let grpcHandler write flush =+ (doHandle handler req write flush)+ `catches` [ Handler $ \(e::GRPCStatus) -> modifyGRPCStatus req e+ , Handler $ \(e::SomeException) -> modifyGRPCStatus req (GRPCStatus INTERNAL $ ByteString.pack $ show e )+ ]+ in (rep $ responseStream status200 hdrs200 grpcHandler)+ Nothing ->+ app req rep+ where+ hdrs200 = [+ ("content-type", grpcContentTypeHV)+ , ("trailer", CI.original grpcStatusH)+ , ("trailer", CI.original grpcMessageH)+ ]+ lookupHandler :: ByteString -> [ServiceHandler] -> Maybe WaiHandler+ lookupHandler p plainHandlers = grpcWaiHandler <$>+ List.find (\(ServiceHandler rpcPath _) -> rpcPath == p) plainHandlers+ doHandle handler req write flush = do+ let bestCompression = lookupEncoding req compressions+ let pickedCompression = fromMaybe (Encoding uncompressed) bestCompression++ let hopefulDecompression = lookupDecoding req compressions+ let pickedDecompression = fromMaybe (Decoding uncompressed) hopefulDecompression++ _ <- handler pickedDecompression pickedCompression req write flush+ modifyGRPCStatus req (GRPCStatus OK "WAI handler ended.")++-- | Looks-up header for encoding outgoing messages.+requestAcceptEncodingNames :: Request -> [ByteString]+requestAcceptEncodingNames req = fromMaybe [] $+ ByteString.split ',' <$> lookup grpcAcceptEncodingH (requestHeaders req)++-- | Looks-up the compression to use from a set of known algorithms.+lookupEncoding :: Request -> [Compression] -> Maybe Encoding+lookupEncoding req compressions = fmap Encoding $+ safeHead [ c | c <- compressions+ , n <- requestAcceptEncodingNames req+ , n == grpcCompressionHV c+ ]+ where+ safeHead [] = Nothing+ safeHead (x:_) = Just x++-- | Looks-up header for decoding incoming messages.+requestDecodingName :: Request -> Maybe ByteString+requestDecodingName req = lookup grpcEncodingH (requestHeaders req)++-- | Looks-up the compression to use for decoding messages.+lookupDecoding :: Request -> [Compression] -> Maybe Decoding+lookupDecoding req compressions = fmap Decoding $ do+ d <- requestDecodingName req+ lookup d [(grpcCompressionHV c, c) | c <- compressions]
+ test/Spec.hs view
@@ -0,0 +1,2 @@+main :: IO ()+main = putStrLn "Test suite not yet implemented"
+ warp-grpc.cabal view
@@ -0,0 +1,96 @@+-- This file has been generated from package.yaml by hpack version 0.28.2.+--+-- see: https://github.com/sol/hpack+--+-- hash: d116fcb32e265f228bd3deb1c4665cd8477e5dd7fa46ea0b2af4d678c06c0fc6++name: warp-grpc+version: 0.1.0.0+synopsis: A minimal gRPC server on top of Warp.+description: Please see the README on Github at <https://github.com/githubuser/warp-grpc#readme>+category: Networking+homepage: https://github.com/lucasdicioccio/warp-grpc#readme+bug-reports: https://github.com/lucasdicioccio/warp-grpc/issues+author: Lucas DiCioccio+maintainer: lucas@dicioccio.fr+copyright: 2017 Lucas DiCioccio+license: BSD3+license-file: LICENSE+build-type: Simple+cabal-version: >= 1.10+extra-source-files:+ ChangeLog.md+ README.md++source-repository head+ type: git+ location: https://github.com/lucasdicioccio/warp-grpc++library+ exposed-modules:+ Network.GRPC.Server+ Network.GRPC.Server.Handlers+ Network.GRPC.Server.Helpers+ Network.GRPC.Server.Wai+ other-modules:+ Paths_warp_grpc+ hs-source-dirs:+ src+ build-depends:+ base >=4.7 && <5+ , binary+ , bytestring+ , case-insensitive+ , http-types+ , http2-grpc-types >=0.2+ , proto-lens+ , wai+ , warp >=3.2.24 && <3.3+ , warp-tls+ default-language: Haskell2010++executable warp-grpc-exe+ main-is: Main.hs+ other-modules:+ Proto.Protos.Grpcbin+ Proto.Protos.Grpcbin_Fields+ hs-source-dirs:+ app+ gen+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ base >=4.7 && <5+ , binary+ , bytestring+ , case-insensitive+ , http-types+ , http2-grpc-types >=0.2+ , proto-lens+ , proto-lens-protoc+ , wai+ , warp >=3.2.24 && <3.3+ , warp-grpc+ , warp-tls+ default-language: Haskell2010++test-suite warp-grpc-test+ type: exitcode-stdio-1.0+ main-is: Spec.hs+ other-modules:+ Paths_warp_grpc+ hs-source-dirs:+ test+ ghc-options: -threaded -rtsopts -with-rtsopts=-N+ build-depends:+ base >=4.7 && <5+ , binary+ , bytestring+ , case-insensitive+ , http-types+ , http2-grpc-types >=0.2+ , proto-lens+ , wai+ , warp >=3.2.24 && <3.3+ , warp-grpc+ , warp-tls+ default-language: Haskell2010