-- |
-- Module:      Data.ProtoBuf.WireFormat
-- Copyright:   (c) 2015-2016 Martijn Rijkeboer <mrr@sru-systems.com>
-- License:     MIT
-- Maintainer:  Martijn Rijkeboer <mrr@sru-systems.com>
--
-- Functions for converting Haskell to wire format and back.

module Data.ProtoBuf.WireFormat
    ( module Data.ProtoBuf.Default
    , module Data.ProtoBuf.FieldNumber
    , module Data.ProtoBuf.Mergeable
    , module Data.ProtoBuf.Required
    , module Data.ProtoBuf.WireEnum
    , module Data.ProtoBuf.WireMessage
    , module Data.ProtoBuf.WireTag
    , module Data.ProtoBuf.WireType
    , decode
    , encode

    , getBool
    , getBoolOpt
    , getBoolPacked
    , getBytes
    , getBytesOpt
    , getDouble
    , getDoubleOpt
    , getDoublePacked
    , getEnum
    , getEnumOpt
    , getEnumPacked
    , getFixed32
    , getFixed32Opt
    , getFixed32Packed
    , getFixed64
    , getFixed64Opt
    , getFixed64Packed
    , getFloat
    , getFloatOpt
    , getFloatPacked
    , getGroup
    , getGroupOpt
    , getInt32
    , getInt32Opt
    , getInt32Packed
    , getInt64
    , getInt64Opt
    , getInt64Packed
    , getMessage
    , getMessageOpt
    , getSFixed32
    , getSFixed32Opt
    , getSFixed32Packed
    , getSFixed64
    , getSFixed64Opt
    , getSFixed64Packed
    , getSInt32
    , getSInt32Opt
    , getSInt32Packed
    , getSInt64
    , getSInt64Opt
    , getSInt64Packed
    , getString
    , getStringOpt
    , getUInt32
    , getUInt32Opt
    , getUInt32Packed
    , getUInt64
    , getUInt64Opt
    , getUInt64Packed
    , getUnknown
    , getWireTag

    , putBool
    , putBoolList
    , putBoolOpt
    , putBoolPacked
    , putBytes
    , putBytesList
    , putBytesOpt
    , putDouble
    , putDoubleList
    , putDoubleOpt
    , putDoublePacked
    , putEnum
    , putEnumList
    , putEnumOpt
    , putEnumPacked
    , putFixed32
    , putFixed32List
    , putFixed32Opt
    , putFixed32Packed
    , putFixed64
    , putFixed64List
    , putFixed64Opt
    , putFixed64Packed
    , putFloat
    , putFloatList
    , putFloatOpt
    , putFloatPacked
    , putGroup
    , putGroupOpt
    , putInt32
    , putInt32List
    , putInt32Opt
    , putInt32Packed
    , putInt64
    , putInt64List
    , putInt64Opt
    , putInt64Packed
    , putSFixed32
    , putSFixed32List
    , putSFixed32Opt
    , putSFixed32Packed
    , putSFixed64
    , putSFixed64List
    , putSFixed64Opt
    , putSFixed64Packed
    , putSInt32
    , putSInt32List
    , putSInt32Opt
    , putSInt32Packed
    , putSInt64
    , putSInt64List
    , putSInt64Opt
    , putSInt64Packed
    , putMessage
    , putMessageList
    , putMessageOpt
    , putString
    , putStringList
    , putStringOpt
    , putUInt32
    , putUInt32List
    , putUInt32Opt
    , putUInt32Packed
    , putUInt64
    , putUInt64List
    , putUInt64Opt
    , putUInt64Packed
    , putWireTag
    ) where


import Data.Binary.Get (Get, getLazyByteString, getWord8, getWord32le, getWord64le, isEmpty, runGetOrFail)
import Data.Binary.IEEE754 (getFloat32le, getFloat64le, putFloat32le, putFloat64le)
import Data.Binary.Put ( Put, putLazyByteString, putWord8, putWord32le, putWord64le, runPut)
import Data.Bits (Bits, (.|.), (.&.), shiftL, shiftR, setBit, testBit)
import Data.ByteString.Lazy (ByteString)
import Data.Foldable (forM_)
import Data.Int (Int32, Int64)
import Data.ProtoBuf.Default (Default(..))
import Data.ProtoBuf.FieldNumber (fromFieldNumber, toFieldNumber, FieldNumber(..))
import Data.ProtoBuf.Mergeable (Mergeable(..))
import Data.ProtoBuf.Required (Required(..))
import Data.ProtoBuf.WireEnum (WireEnum(..))
import Data.ProtoBuf.WireMessage (WireMessage(..))
import Data.ProtoBuf.WireTag (fromWireTag, toWireTag, WireTag(..))
import Data.ProtoBuf.WireType (fromWireType, toWireType, WireType(..))
import Data.Sequence (Seq, (|>))
import Data.Text.Lazy (Text)
import Data.Text.Lazy.Encoding (decodeUtf8', encodeUtf8)
import Data.Word (Word8, Word32, Word64)

import qualified Data.ByteString.Lazy as BSL
import qualified Data.ProtoBuf.ZigZag as ZZ
import qualified Data.Sequence        as Seq
import qualified Data.Set             as Set


-- | Decode a ByteString into either the data-type or an error message.
--
-- Decode CustomType:
--
-- > decCustomType :: ByteString -> Either String CustomType
-- > decCustomType = decode
decode :: (Default a, Required a, WireMessage a) => ByteString -> Either String a
decode :: ByteString -> Either String a
decode ByteString
bytes = case Get a
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
forall a.
Get a
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
runGetOrFail Get a
forall a. (Default a, Required a, WireMessage a) => Get a
getGroup ByteString
bytes of
    Left  (ByteString
_, ByteOffset
_, String
err) -> String -> Either String a
forall a b. a -> Either a b
Left String
err
    Right (ByteString
_, ByteOffset
_, a
obj) -> a -> Either String a
forall a b. b -> Either a b
Right a
obj


-- | Encode a data-type into a ByteString.
--
-- Encode CustomType:
--
-- > encCustomType :: CustomType -> ByteString
-- > encCustomType = encode
encode :: (WireMessage a) => a -> ByteString
encode :: a -> ByteString
encode a
obj = Put -> ByteString
runPut (a -> Put
forall a. WireMessage a => a -> Put
putGroup a
obj)


-- | Decode a required bool field.
getBool :: Get Bool
getBool :: Get Bool
getBool = do
    Word8
val <- Get Word8
forall a. (Bits a, Integral a) => Get a
getVarInt :: Get Word8
    if Word8
val Word8 -> Word8 -> Bool
forall a. Eq a => a -> a -> Bool
== Word8
0
    then Bool -> Get Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
    else Bool -> Get Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
True


-- | Decode an optional bool field.
getBoolOpt :: Get (Maybe Bool)
getBoolOpt :: Get (Maybe Bool)
getBoolOpt = Get Bool -> Get (Maybe Bool)
forall a. Get a -> Get (Maybe a)
getOpt Get Bool
getBool


-- | Decode a packed repeated bool field.
getBoolPacked :: Get (Seq Bool)
getBoolPacked :: Get (Seq Bool)
getBoolPacked = Get Bool -> Get (Seq Bool)
forall a. Get a -> Get (Seq a)
getPacked Get Bool
getBool


-- | Decode a required bytes field.
getBytes :: Get ByteString
getBytes :: Get ByteString
getBytes = do
    ByteOffset
len <- Get ByteOffset
forall a. (Bits a, Integral a) => Get a
getVarInt
    ByteOffset -> Get ByteString
getLazyByteString ByteOffset
len


-- | Decode an optional bytes field.
getBytesOpt :: Get (Maybe ByteString)
getBytesOpt :: Get (Maybe ByteString)
getBytesOpt = Get ByteString -> Get (Maybe ByteString)
forall a. Get a -> Get (Maybe a)
getOpt Get ByteString
getBytes


-- | Decode a required double field.
getDouble :: Get Double
getDouble :: Get Double
getDouble = Get Double
getFloat64le


-- | Decode an optional double field.
getDoubleOpt :: Get (Maybe Double)
getDoubleOpt :: Get (Maybe Double)
getDoubleOpt = Get Double -> Get (Maybe Double)
forall a. Get a -> Get (Maybe a)
getOpt Get Double
getDouble


-- | Decode a packed repeated double field.
getDoublePacked :: Get (Seq Double)
getDoublePacked :: Get (Seq Double)
getDoublePacked = Get Double -> Get (Seq Double)
forall a. Get a -> Get (Seq a)
getPacked Get Double
getDouble


-- | Decode a required enum field.
getEnum :: (WireEnum a) => Get a
getEnum :: Get a
getEnum = Int32 -> a
forall a. WireEnum a => Int32 -> a
intToEnum (Int32 -> a) -> Get Int32 -> Get a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Int32
getInt32


-- | Decode an optional enum field.
getEnumOpt :: (WireEnum a) => Get (Maybe a)
getEnumOpt :: Get (Maybe a)
getEnumOpt = Get a -> Get (Maybe a)
forall a. Get a -> Get (Maybe a)
getOpt Get a
forall a. WireEnum a => Get a
getEnum


-- | Decode a packed repeated enum field.
getEnumPacked :: (WireEnum a) => Get (Seq a)
getEnumPacked :: Get (Seq a)
getEnumPacked = Get a -> Get (Seq a)
forall a. Get a -> Get (Seq a)
getPacked Get a
forall a. WireEnum a => Get a
getEnum


-- | Decode a required fixed32 field.
getFixed32 :: Get Word32
getFixed32 :: Get Word32
getFixed32 = Get Word32
getWord32le


-- | Decode an optional fixed32 field.
getFixed32Opt :: Get (Maybe Word32)
getFixed32Opt :: Get (Maybe Word32)
getFixed32Opt = Get Word32 -> Get (Maybe Word32)
forall a. Get a -> Get (Maybe a)
getOpt Get Word32
getFixed32


-- | Decode a packed repeated fixed32 field.
getFixed32Packed :: Get (Seq Word32)
getFixed32Packed :: Get (Seq Word32)
getFixed32Packed = Get Word32 -> Get (Seq Word32)
forall a. Get a -> Get (Seq a)
getPacked Get Word32
getFixed32


-- | Decode a required fixed64 field.
getFixed64 :: Get Word64
getFixed64 :: Get Word64
getFixed64 = Get Word64
getWord64le


-- | Decode an optional fixed64 field.
getFixed64Opt :: Get (Maybe Word64)
getFixed64Opt :: Get (Maybe Word64)
getFixed64Opt = Get Word64 -> Get (Maybe Word64)
forall a. Get a -> Get (Maybe a)
getOpt Get Word64
getFixed64


-- | Decode a packed repeated fixed64 field.
getFixed64Packed :: Get (Seq Word64)
getFixed64Packed :: Get (Seq Word64)
getFixed64Packed = Get Word64 -> Get (Seq Word64)
forall a. Get a -> Get (Seq a)
getPacked Get Word64
getFixed64


-- | Decode a required float field.
getFloat :: Get Float
getFloat :: Get Float
getFloat = Get Float
getFloat32le


-- | Decode an optional float field.
getFloatOpt :: Get (Maybe Float)
getFloatOpt :: Get (Maybe Float)
getFloatOpt = Get Float -> Get (Maybe Float)
forall a. Get a -> Get (Maybe a)
getOpt Get Float
getFloat


-- | Decode a packed repeated float field.
getFloatPacked :: Get (Seq Float)
getFloatPacked :: Get (Seq Float)
getFloatPacked = Get Float -> Get (Seq Float)
forall a. Get a -> Get (Seq a)
getPacked Get Float
getFloat


-- | Decode a required group field.
getGroup :: (Default a, Required a, WireMessage a) => Get a
getGroup :: Get a
getGroup = a -> Set WireTag -> Get a
forall a. WireMessage a => a -> Set WireTag -> Get a
loop a
defaultMsg Set WireTag
reqTagSet
    where
        loop :: a -> Set WireTag -> Get a
loop a
msg Set WireTag
reqs | Set WireTag -> Bool
forall a. Set a -> Bool
Set.null Set WireTag
reqs = do
            Bool
done <- Get Bool
isEmpty
            if Bool
done
            then a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return a
msg
            else do
                WireTag
tag <- Get WireTag
getWireTag
                a
msg' <- WireTag -> a -> Get a
forall a. WireMessage a => WireTag -> a -> Get a
fieldToValue WireTag
tag a
msg
                a -> Set WireTag -> Get a
loop a
msg' Set WireTag
reqs
        loop a
msg Set WireTag
reqs = do
            Bool
done <- Get Bool
isEmpty
            if Bool
done
            then String -> Get a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Missing required field(s)"
            else do
                WireTag
tag <- Get WireTag
getWireTag
                a
msg' <- WireTag -> a -> Get a
forall a. WireMessage a => WireTag -> a -> Get a
fieldToValue WireTag
tag a
msg
                a -> Set WireTag -> Get a
loop a
msg' (WireTag -> Set WireTag -> Set WireTag
forall a. Ord a => a -> Set a -> Set a
Set.delete WireTag
tag Set WireTag
reqs)
        defaultMsg :: a
defaultMsg = a
forall a. Default a => a
defaultVal
        reqTagSet :: Set WireTag
reqTagSet = a -> Set WireTag
forall a. Required a => a -> Set WireTag
reqTags a
defaultMsg


-- | Decode an optional group field.
getGroupOpt :: (Default a, Required a, WireMessage a) => Get (Maybe a)
getGroupOpt :: Get (Maybe a)
getGroupOpt = Get a -> Get (Maybe a)
forall a. Get a -> Get (Maybe a)
getOpt Get a
forall a. (Default a, Required a, WireMessage a) => Get a
getGroup


-- | Decode a required int32 field.
getInt32 :: Get Int32
getInt32 :: Get Int32
getInt32 = Get Int32
forall a. (Bits a, Integral a) => Get a
getVarInt


-- | Decode an optional int32 field.
getInt32Opt :: Get (Maybe Int32)
getInt32Opt :: Get (Maybe Int32)
getInt32Opt = Get Int32 -> Get (Maybe Int32)
forall a. Get a -> Get (Maybe a)
getOpt Get Int32
getInt32


-- | Decode a packed repeated int32 field.
getInt32Packed :: Get (Seq Int32)
getInt32Packed :: Get (Seq Int32)
getInt32Packed = Get Int32 -> Get (Seq Int32)
forall a. Get a -> Get (Seq a)
getPacked Get Int32
getInt32


-- | Decode a required int64 field.
getInt64 :: Get Int64
getInt64 :: Get ByteOffset
getInt64 = Get ByteOffset
forall a. (Bits a, Integral a) => Get a
getVarInt


-- | Decode an optional int64 field.
getInt64Opt :: Get (Maybe Int64)
getInt64Opt :: Get (Maybe ByteOffset)
getInt64Opt = Get ByteOffset -> Get (Maybe ByteOffset)
forall a. Get a -> Get (Maybe a)
getOpt Get ByteOffset
getInt64


-- | Decode a packed repeated int64 field.
getInt64Packed :: Get (Seq Int64)
getInt64Packed :: Get (Seq ByteOffset)
getInt64Packed = Get ByteOffset -> Get (Seq ByteOffset)
forall a. Get a -> Get (Seq a)
getPacked Get ByteOffset
getInt64


-- | Decode a required message field.
getMessage :: (Default a, Required a, WireMessage a) => Get a
getMessage :: Get a
getMessage = do
    ByteString
bytes <- Get ByteString
getBytes
    case Get a
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
forall a.
Get a
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
runGetOrFail Get a
forall a. (Default a, Required a, WireMessage a) => Get a
getGroup ByteString
bytes of
        Left  (ByteString
_, ByteOffset
_, String
err) -> String -> Get a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
err
        Right (ByteString
_, ByteOffset
_, a
obj) -> a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return a
obj


-- | Decode an optional message field.
getMessageOpt :: (Default a, Required a, WireMessage a) => Get (Maybe a)
getMessageOpt :: Get (Maybe a)
getMessageOpt = Get a -> Get (Maybe a)
forall a. Get a -> Get (Maybe a)
getOpt Get a
forall a. (Default a, Required a, WireMessage a) => Get a
getMessage


-- | Decode a required sfixed32 field.
getSFixed32 :: Get Int32
getSFixed32 :: Get Int32
getSFixed32 = Word32 -> Int32
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word32 -> Int32) -> Get Word32 -> Get Int32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
getWord32le


-- | Decode an optional sfixed32 field.
getSFixed32Opt :: Get (Maybe Int32)
getSFixed32Opt :: Get (Maybe Int32)
getSFixed32Opt = Get Int32 -> Get (Maybe Int32)
forall a. Get a -> Get (Maybe a)
getOpt Get Int32
getSFixed32


-- | Decode a packed repeated sfixed32 field.
getSFixed32Packed :: Get (Seq Int32)
getSFixed32Packed :: Get (Seq Int32)
getSFixed32Packed = Get Int32 -> Get (Seq Int32)
forall a. Get a -> Get (Seq a)
getPacked Get Int32
getSFixed32


-- | Decode a required sfixed64 field.
getSFixed64 :: Get Int64
getSFixed64 :: Get ByteOffset
getSFixed64 = Word64 -> ByteOffset
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word64 -> ByteOffset) -> Get Word64 -> Get ByteOffset
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
getWord64le


-- | Decode an optional sfixed64 field.
getSFixed64Opt :: Get (Maybe Int64)
getSFixed64Opt :: Get (Maybe ByteOffset)
getSFixed64Opt = Get ByteOffset -> Get (Maybe ByteOffset)
forall a. Get a -> Get (Maybe a)
getOpt Get ByteOffset
getSFixed64


-- | Decode a packed repeated sfixed64 field.
getSFixed64Packed :: Get (Seq Int64)
getSFixed64Packed :: Get (Seq ByteOffset)
getSFixed64Packed = Get ByteOffset -> Get (Seq ByteOffset)
forall a. Get a -> Get (Seq a)
getPacked Get ByteOffset
getSFixed64


-- | Decode a required sint32 field.
getSInt32 :: Get Int32
getSInt32 :: Get Int32
getSInt32 = Word32 -> Int32
ZZ.decode32 (Word32 -> Int32) -> Get Word32 -> Get Int32
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word32
forall a. (Bits a, Integral a) => Get a
getVarInt


-- | Decode an optional sint32 field.
getSInt32Opt :: Get (Maybe Int32)
getSInt32Opt :: Get (Maybe Int32)
getSInt32Opt = Get Int32 -> Get (Maybe Int32)
forall a. Get a -> Get (Maybe a)
getOpt Get Int32
getSInt32


-- | Decode a packed repeated sint32 field.
getSInt32Packed :: Get (Seq Int32)
getSInt32Packed :: Get (Seq Int32)
getSInt32Packed = Get Int32 -> Get (Seq Int32)
forall a. Get a -> Get (Seq a)
getPacked Get Int32
getSInt32


-- | Decode a required sint64 field.
getSInt64 :: Get Int64
getSInt64 :: Get ByteOffset
getSInt64 = Word64 -> ByteOffset
ZZ.decode64 (Word64 -> ByteOffset) -> Get Word64 -> Get ByteOffset
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get Word64
forall a. (Bits a, Integral a) => Get a
getVarInt


-- | Decode an optional sint64 field.
getSInt64Opt :: Get (Maybe Int64)
getSInt64Opt :: Get (Maybe ByteOffset)
getSInt64Opt = Get ByteOffset -> Get (Maybe ByteOffset)
forall a. Get a -> Get (Maybe a)
getOpt Get ByteOffset
getSInt64


-- | Decode a packed repeated sint64 field.
getSInt64Packed :: Get (Seq Int64)
getSInt64Packed :: Get (Seq ByteOffset)
getSInt64Packed = Get ByteOffset -> Get (Seq ByteOffset)
forall a. Get a -> Get (Seq a)
getPacked Get ByteOffset
getSInt64


-- | Decode a required string.
getString :: Get Text
getString :: Get Text
getString = do
    ByteString
bytes <- Get ByteString
getBytes
    case ByteString -> Either UnicodeException Text
decodeUtf8' ByteString
bytes of
        Right Text
text -> Text -> Get Text
forall (m :: * -> *) a. Monad m => a -> m a
return Text
text
        Left  UnicodeException
err  -> String -> Get Text
forall (m :: * -> *) a. MonadFail m => String -> m a
fail  (String -> Get Text) -> String -> Get Text
forall a b. (a -> b) -> a -> b
$ String
"Invalid UTF8: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ UnicodeException -> String
forall a. Show a => a -> String
show UnicodeException
err


-- | Decode an optional string.
getStringOpt :: Get (Maybe Text)
getStringOpt :: Get (Maybe Text)
getStringOpt = Get Text -> Get (Maybe Text)
forall a. Get a -> Get (Maybe a)
getOpt Get Text
getString


-- | Decode a required uint32 field.
getUInt32 :: Get Word32
getUInt32 :: Get Word32
getUInt32 = Get Word32
forall a. (Bits a, Integral a) => Get a
getVarInt


-- | Decode an optional uint32 field.
getUInt32Opt :: Get (Maybe Word32)
getUInt32Opt :: Get (Maybe Word32)
getUInt32Opt = Get Word32 -> Get (Maybe Word32)
forall a. Get a -> Get (Maybe a)
getOpt Get Word32
getUInt32


-- | Decode a packed repeated uint32 field.
getUInt32Packed :: Get (Seq Word32)
getUInt32Packed :: Get (Seq Word32)
getUInt32Packed = Get Word32 -> Get (Seq Word32)
forall a. Get a -> Get (Seq a)
getPacked Get Word32
getUInt32


-- | Decode a required uint64 field.
getUInt64 :: Get Word64
getUInt64 :: Get Word64
getUInt64 = Get Word64
forall a. (Bits a, Integral a) => Get a
getVarInt


-- | Decode an optional uint64 field.
getUInt64Opt :: Get (Maybe Word64)
getUInt64Opt :: Get (Maybe Word64)
getUInt64Opt = Get Word64 -> Get (Maybe Word64)
forall a. Get a -> Get (Maybe a)
getOpt Get Word64
getUInt64


-- | Decode a packed repeated uint64 field.
getUInt64Packed :: Get (Seq Word64)
getUInt64Packed :: Get (Seq Word64)
getUInt64Packed = Get Word64 -> Get (Seq Word64)
forall a. Get a -> Get (Seq a)
getPacked Get Word64
getUInt64


-- | Skip an unknown field.
getUnknown :: WireTag -> a -> Get a
getUnknown :: WireTag -> a -> Get a
getUnknown (WireTag FieldNumber
_ WireType
VarInt)   a
a = (Get ByteOffset
forall a. (Bits a, Integral a) => Get a
getVarInt :: Get Int64) Get ByteOffset -> Get a -> Get a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
getUnknown (WireTag FieldNumber
_ WireType
Bit64)    a
a = Get Word64
getWord64le Get Word64 -> Get a -> Get a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
getUnknown (WireTag FieldNumber
_ WireType
LenDelim) a
a = Get ByteString
getBytes    Get ByteString -> Get a -> Get a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a
getUnknown (WireTag FieldNumber
_ WireType
Bit32)    a
a = Get Word32
getWord32le Get Word32 -> Get a -> Get a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return a
a


-- | Decode a wire tag.
getWireTag :: Get WireTag
getWireTag :: Get WireTag
getWireTag = do
    Word32
int <- Get Word32
forall a. (Bits a, Integral a) => Get a
getVarInt
    case Word32 -> Either String WireTag
toWireTag Word32
int of
        Right WireTag
tag -> WireTag -> Get WireTag
forall (m :: * -> *) a. Monad m => a -> m a
return WireTag
tag
        Left  String
err -> String -> Get WireTag
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
err


-- | Encode a required bool field.
putBool :: WireTag -> Bool -> Put
putBool :: WireTag -> Bool -> Put
putBool WireTag
tag Bool
val = do
    WireTag -> Put
putWireTag WireTag
tag
    Word8 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt (Word8 -> Put) -> Word8 -> Put
forall a b. (a -> b) -> a -> b
$ Bool -> Word8
boolToWord8 Bool
val


-- | Encode a repeated bool field.
putBoolList :: WireTag -> Seq Bool -> Put
putBoolList :: WireTag -> Seq Bool -> Put
putBoolList = (WireTag -> Bool -> Put) -> WireTag -> Seq Bool -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Bool -> Put
putBool


-- | Encode an optional bool field.
putBoolOpt :: WireTag -> Maybe Bool -> Put
putBoolOpt :: WireTag -> Maybe Bool -> Put
putBoolOpt = (WireTag -> Bool -> Put) -> WireTag -> Maybe Bool -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Bool -> Put
putBool


-- | Encode a packed repeated bool field.
putBoolPacked :: WireTag -> Seq Bool -> Put
putBoolPacked :: WireTag -> Seq Bool -> Put
putBoolPacked = (Bool -> Put) -> WireTag -> Seq Bool -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked (Word8 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt (Word8 -> Put) -> (Bool -> Word8) -> Bool -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Bool -> Word8
boolToWord8)


-- | Encode a required bytes field.
putBytes :: WireTag -> ByteString -> Put
putBytes :: WireTag -> ByteString -> Put
putBytes WireTag
tag ByteString
bs = do
    WireTag -> Put
putWireTag WireTag
tag
    ByteOffset -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt (ByteOffset -> Put) -> ByteOffset -> Put
forall a b. (a -> b) -> a -> b
$ ByteString -> ByteOffset
BSL.length ByteString
bs
    ByteString -> Put
putLazyByteString ByteString
bs


-- | Encode a repeated bytes field.
putBytesList :: WireTag -> Seq ByteString -> Put
putBytesList :: WireTag -> Seq ByteString -> Put
putBytesList = (WireTag -> ByteString -> Put) -> WireTag -> Seq ByteString -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> ByteString -> Put
putBytes


-- | Encode an optional bytes field.
putBytesOpt :: WireTag -> Maybe ByteString -> Put
putBytesOpt :: WireTag -> Maybe ByteString -> Put
putBytesOpt = (WireTag -> ByteString -> Put)
-> WireTag -> Maybe ByteString -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> ByteString -> Put
putBytes


-- | Encode a required double field.
putDouble :: WireTag -> Double -> Put
putDouble :: WireTag -> Double -> Put
putDouble WireTag
tag Double
d = do
    WireTag -> Put
putWireTag WireTag
tag
    Double -> Put
putFloat64le Double
d


-- | Encode a repeated double field.
putDoubleList :: WireTag -> Seq Double -> Put
putDoubleList :: WireTag -> Seq Double -> Put
putDoubleList = (WireTag -> Double -> Put) -> WireTag -> Seq Double -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Double -> Put
putDouble


-- | Encode an optional double field.
putDoubleOpt :: WireTag -> Maybe Double -> Put
putDoubleOpt :: WireTag -> Maybe Double -> Put
putDoubleOpt = (WireTag -> Double -> Put) -> WireTag -> Maybe Double -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Double -> Put
putDouble


-- | Encode a packed repeated double field.
putDoublePacked :: WireTag -> Seq Double -> Put
putDoublePacked :: WireTag -> Seq Double -> Put
putDoublePacked = (Double -> Put) -> WireTag -> Seq Double -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked Double -> Put
putFloat64le


-- | Encode a required enum field.
putEnum :: WireEnum a => WireTag -> a -> Put
putEnum :: WireTag -> a -> Put
putEnum WireTag
tag a
a = WireTag -> Int32 -> Put
putInt32 WireTag
tag (Int32 -> Put) -> Int32 -> Put
forall a b. (a -> b) -> a -> b
$ a -> Int32
forall a. WireEnum a => a -> Int32
enumToInt a
a


-- | Encode a repeated enum field.
putEnumList :: WireEnum a => WireTag -> Seq a -> Put
putEnumList :: WireTag -> Seq a -> Put
putEnumList = (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> a -> Put
forall a. WireEnum a => WireTag -> a -> Put
putEnum


-- | Encode an optional enum field.
putEnumOpt :: WireEnum a => WireTag -> Maybe a -> Put
putEnumOpt :: WireTag -> Maybe a -> Put
putEnumOpt = (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> a -> Put
forall a. WireEnum a => WireTag -> a -> Put
putEnum


-- | Encode a packed repeated enum field.
putEnumPacked :: WireEnum a => WireTag -> Seq a -> Put
putEnumPacked :: WireTag -> Seq a -> Put
putEnumPacked = (a -> Put) -> WireTag -> Seq a -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked (Int32 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt (Int32 -> Put) -> (a -> Int32) -> a -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Int32
forall a. WireEnum a => a -> Int32
enumToInt)


-- | Encode a required fixed32 field.
putFixed32 :: WireTag -> Word32 -> Put
putFixed32 :: WireTag -> Word32 -> Put
putFixed32 WireTag
tag Word32
f = do
    WireTag -> Put
putWireTag WireTag
tag
    Word32 -> Put
putWord32le Word32
f


-- | Encode a repeated fixed32 field.
putFixed32List :: WireTag -> Seq Word32 -> Put
putFixed32List :: WireTag -> Seq Word32 -> Put
putFixed32List = (WireTag -> Word32 -> Put) -> WireTag -> Seq Word32 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Word32 -> Put
putFixed32


-- | Encode an optional fixed32 field.
putFixed32Opt :: WireTag -> Maybe Word32 -> Put
putFixed32Opt :: WireTag -> Maybe Word32 -> Put
putFixed32Opt = (WireTag -> Word32 -> Put) -> WireTag -> Maybe Word32 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Word32 -> Put
putFixed32


-- | Encode a packed repeated fixed32 field.
putFixed32Packed :: WireTag -> Seq Word32 -> Put
putFixed32Packed :: WireTag -> Seq Word32 -> Put
putFixed32Packed = (Word32 -> Put) -> WireTag -> Seq Word32 -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked Word32 -> Put
putWord32le


-- | Encode a required fixed64 field.
putFixed64 :: WireTag -> Word64 -> Put
putFixed64 :: WireTag -> Word64 -> Put
putFixed64 WireTag
tag Word64
f = do
    WireTag -> Put
putWireTag WireTag
tag
    Word64 -> Put
putWord64le Word64
f


-- | Encode a repeated fixed64 field.
putFixed64List :: WireTag -> Seq Word64 -> Put
putFixed64List :: WireTag -> Seq Word64 -> Put
putFixed64List = (WireTag -> Word64 -> Put) -> WireTag -> Seq Word64 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Word64 -> Put
putFixed64


-- | Encode an optional fixed64 field.
putFixed64Opt :: WireTag -> Maybe Word64 -> Put
putFixed64Opt :: WireTag -> Maybe Word64 -> Put
putFixed64Opt = (WireTag -> Word64 -> Put) -> WireTag -> Maybe Word64 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Word64 -> Put
putFixed64


-- | Encode a packed repeated fixed64 field.
putFixed64Packed :: WireTag -> Seq Word64 -> Put
putFixed64Packed :: WireTag -> Seq Word64 -> Put
putFixed64Packed = (Word64 -> Put) -> WireTag -> Seq Word64 -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked Word64 -> Put
putWord64le


-- | Encode a required float field.
putFloat :: WireTag -> Float -> Put
putFloat :: WireTag -> Float -> Put
putFloat WireTag
tag Float
f = do
    WireTag -> Put
putWireTag WireTag
tag
    Float -> Put
putFloat32le Float
f


-- | Encode a repeated float field.
putFloatList :: WireTag -> Seq Float -> Put
putFloatList :: WireTag -> Seq Float -> Put
putFloatList = (WireTag -> Float -> Put) -> WireTag -> Seq Float -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Float -> Put
putFloat


-- | Encode an optional float field.
putFloatOpt :: WireTag -> Maybe Float -> Put
putFloatOpt :: WireTag -> Maybe Float -> Put
putFloatOpt = (WireTag -> Float -> Put) -> WireTag -> Maybe Float -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Float -> Put
putFloat


-- | Encode a packed repeated float field.
putFloatPacked :: WireTag -> Seq Float -> Put
putFloatPacked :: WireTag -> Seq Float -> Put
putFloatPacked = (Float -> Put) -> WireTag -> Seq Float -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked Float -> Put
putFloat32le


-- | Encode a required group field.
putGroup :: WireMessage a => a -> Put
putGroup :: a -> Put
putGroup = a -> Put
forall a. WireMessage a => a -> Put
messageToFields


-- | Encode an optional group field.
putGroupOpt :: WireMessage a => Maybe a -> Put
putGroupOpt :: Maybe a -> Put
putGroupOpt (Just a
val) = a -> Put
forall a. WireMessage a => a -> Put
putGroup a
val
putGroupOpt Maybe a
Nothing    = () -> Put
forall (m :: * -> *) a. Monad m => a -> m a
return ()


-- | Encode a required int32 field.
putInt32 :: WireTag -> Int32 -> Put
putInt32 :: WireTag -> Int32 -> Put
putInt32 WireTag
tag Int32
i = do
    WireTag -> Put
putWireTag WireTag
tag
    Int32 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt Int32
i


-- | Encode a repeated int32 field.
putInt32List :: WireTag -> Seq Int32 -> Put
putInt32List :: WireTag -> Seq Int32 -> Put
putInt32List = (WireTag -> Int32 -> Put) -> WireTag -> Seq Int32 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Int32 -> Put
putInt32


-- | Encode an optional int32 field.
putInt32Opt :: WireTag -> Maybe Int32 -> Put
putInt32Opt :: WireTag -> Maybe Int32 -> Put
putInt32Opt = (WireTag -> Int32 -> Put) -> WireTag -> Maybe Int32 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Int32 -> Put
putInt32


-- | Encode a packed repeated int32 field.
putInt32Packed :: WireTag -> Seq Int32 -> Put
putInt32Packed :: WireTag -> Seq Int32 -> Put
putInt32Packed = (Int32 -> Put) -> WireTag -> Seq Int32 -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked Int32 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt


-- | Encode a required int64 field.
putInt64 :: WireTag -> Int64 -> Put
putInt64 :: WireTag -> ByteOffset -> Put
putInt64 WireTag
tag ByteOffset
i = do
    WireTag -> Put
putWireTag WireTag
tag
    ByteOffset -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt ByteOffset
i


-- | Encode a repeated int64 field.
putInt64List :: WireTag -> Seq Int64 -> Put
putInt64List :: WireTag -> Seq ByteOffset -> Put
putInt64List = (WireTag -> ByteOffset -> Put) -> WireTag -> Seq ByteOffset -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> ByteOffset -> Put
putInt64


-- | Encode an optional int64 field.
putInt64Opt :: WireTag -> Maybe Int64 -> Put
putInt64Opt :: WireTag -> Maybe ByteOffset -> Put
putInt64Opt = (WireTag -> ByteOffset -> Put)
-> WireTag -> Maybe ByteOffset -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> ByteOffset -> Put
putInt64


-- | Encode a packed repeated int64 field.
putInt64Packed :: WireTag -> Seq Int64 -> Put
putInt64Packed :: WireTag -> Seq ByteOffset -> Put
putInt64Packed = (ByteOffset -> Put) -> WireTag -> Seq ByteOffset -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked ByteOffset -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt


-- | Encode a required sfixed32 field.
putSFixed32 :: WireTag -> Int32 -> Put
putSFixed32 :: WireTag -> Int32 -> Put
putSFixed32 WireTag
tag Int32
f = do
    WireTag -> Put
putWireTag WireTag
tag
    Word32 -> Put
putWord32le (Word32 -> Put) -> Word32 -> Put
forall a b. (a -> b) -> a -> b
$ Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int32
f


-- | Encode a repeated sfixed32 field.
putSFixed32List :: WireTag -> Seq Int32 -> Put
putSFixed32List :: WireTag -> Seq Int32 -> Put
putSFixed32List = (WireTag -> Int32 -> Put) -> WireTag -> Seq Int32 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Int32 -> Put
putSFixed32


-- | Encode an optional sfixed32 field.
putSFixed32Opt :: WireTag -> Maybe Int32 -> Put
putSFixed32Opt :: WireTag -> Maybe Int32 -> Put
putSFixed32Opt = (WireTag -> Int32 -> Put) -> WireTag -> Maybe Int32 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Int32 -> Put
putSFixed32


-- | Encode a packed repeated sfixed32 field.
putSFixed32Packed :: WireTag -> Seq Int32 -> Put
putSFixed32Packed :: WireTag -> Seq Int32 -> Put
putSFixed32Packed = (Int32 -> Put) -> WireTag -> Seq Int32 -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked (Word32 -> Put
putWord32le (Word32 -> Put) -> (Int32 -> Word32) -> Int32 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Word32
forall a b. (Integral a, Num b) => a -> b
fromIntegral)


-- | Encode a required sfixed64 field.
putSFixed64 :: WireTag -> Int64 -> Put
putSFixed64 :: WireTag -> ByteOffset -> Put
putSFixed64 WireTag
tag ByteOffset
f = do
    WireTag -> Put
putWireTag WireTag
tag
    Word64 -> Put
putWord64le (Word64 -> Put) -> Word64 -> Put
forall a b. (a -> b) -> a -> b
$ ByteOffset -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral ByteOffset
f


-- | Encode a repeated sfixed64 field.
putSFixed64List :: WireTag -> Seq Int64 -> Put
putSFixed64List :: WireTag -> Seq ByteOffset -> Put
putSFixed64List = (WireTag -> ByteOffset -> Put) -> WireTag -> Seq ByteOffset -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> ByteOffset -> Put
putSFixed64


-- | Encode an optional sfixed64 field.
putSFixed64Opt :: WireTag -> Maybe Int64 -> Put
putSFixed64Opt :: WireTag -> Maybe ByteOffset -> Put
putSFixed64Opt = (WireTag -> ByteOffset -> Put)
-> WireTag -> Maybe ByteOffset -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> ByteOffset -> Put
putSFixed64


-- | Encode a packed repeated sfixed64 field.
putSFixed64Packed :: WireTag -> Seq Int64 -> Put
putSFixed64Packed :: WireTag -> Seq ByteOffset -> Put
putSFixed64Packed = (ByteOffset -> Put) -> WireTag -> Seq ByteOffset -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked (Word64 -> Put
putWord64le (Word64 -> Put) -> (ByteOffset -> Word64) -> ByteOffset -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteOffset -> Word64
forall a b. (Integral a, Num b) => a -> b
fromIntegral)


-- | Encode a required sint32 field.
putSInt32 :: WireTag -> Int32 -> Put
putSInt32 :: WireTag -> Int32 -> Put
putSInt32 WireTag
tag Int32
i = do
    WireTag -> Put
putWireTag WireTag
tag
    Word32 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt (Word32 -> Put) -> Word32 -> Put
forall a b. (a -> b) -> a -> b
$ Int32 -> Word32
ZZ.encode32 Int32
i


-- | Encode a repeated sint32 field.
putSInt32List :: WireTag -> Seq Int32 -> Put
putSInt32List :: WireTag -> Seq Int32 -> Put
putSInt32List = (WireTag -> Int32 -> Put) -> WireTag -> Seq Int32 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Int32 -> Put
putSInt32


-- | Encode an optional sint32 field.
putSInt32Opt :: WireTag -> Maybe Int32 -> Put
putSInt32Opt :: WireTag -> Maybe Int32 -> Put
putSInt32Opt = (WireTag -> Int32 -> Put) -> WireTag -> Maybe Int32 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Int32 -> Put
putSInt32


-- | Encode a packed repeated sint32 field.
putSInt32Packed :: WireTag -> Seq Int32 -> Put
putSInt32Packed :: WireTag -> Seq Int32 -> Put
putSInt32Packed = (Int32 -> Put) -> WireTag -> Seq Int32 -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked (Word32 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt (Word32 -> Put) -> (Int32 -> Word32) -> Int32 -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int32 -> Word32
ZZ.encode32)


-- | Encode a required sint64 field.
putSInt64 :: WireTag -> Int64 -> Put
putSInt64 :: WireTag -> ByteOffset -> Put
putSInt64 WireTag
tag ByteOffset
i = do
    WireTag -> Put
putWireTag WireTag
tag
    Word64 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt (Word64 -> Put) -> Word64 -> Put
forall a b. (a -> b) -> a -> b
$ ByteOffset -> Word64
ZZ.encode64 ByteOffset
i


-- | Encode a repeated sint64 field.
putSInt64List :: WireTag -> Seq Int64 -> Put
putSInt64List :: WireTag -> Seq ByteOffset -> Put
putSInt64List = (WireTag -> ByteOffset -> Put) -> WireTag -> Seq ByteOffset -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> ByteOffset -> Put
putSInt64


-- | Encode an optional sint64 field.
putSInt64Opt :: WireTag -> Maybe Int64 -> Put
putSInt64Opt :: WireTag -> Maybe ByteOffset -> Put
putSInt64Opt = (WireTag -> ByteOffset -> Put)
-> WireTag -> Maybe ByteOffset -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> ByteOffset -> Put
putSInt64


-- | Encode a packed repeated sint64 field.
putSInt64Packed :: WireTag -> Seq Int64 -> Put
putSInt64Packed :: WireTag -> Seq ByteOffset -> Put
putSInt64Packed = (ByteOffset -> Put) -> WireTag -> Seq ByteOffset -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked (Word64 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt (Word64 -> Put) -> (ByteOffset -> Word64) -> ByteOffset -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteOffset -> Word64
ZZ.encode64)


-- | Encode a required message field.
putMessage :: WireMessage a => WireTag -> a -> Put
putMessage :: WireTag -> a -> Put
putMessage WireTag
tag a
a = WireTag -> ByteString -> Put
putBytes WireTag
tag (ByteString -> Put) -> ByteString -> Put
forall a b. (a -> b) -> a -> b
$ Put -> ByteString
runPut (a -> Put
forall a. WireMessage a => a -> Put
putGroup a
a)


-- | Encode a repeated message field.
putMessageList :: WireMessage a => WireTag -> Seq a -> Put
putMessageList :: WireTag -> Seq a -> Put
putMessageList = (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> a -> Put
forall a. WireMessage a => WireTag -> a -> Put
putMessage


-- | Encode an optional message field.
putMessageOpt :: WireMessage a => WireTag -> Maybe a -> Put
putMessageOpt :: WireTag -> Maybe a -> Put
putMessageOpt = (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> a -> Put
forall a. WireMessage a => WireTag -> a -> Put
putMessage


-- | Encode a required string field.
putString :: WireTag -> Text -> Put
putString :: WireTag -> Text -> Put
putString WireTag
tag Text
txt = WireTag -> ByteString -> Put
putBytes WireTag
tag (ByteString -> Put) -> ByteString -> Put
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
encodeUtf8 Text
txt


-- | Encode a repeated string field.
putStringList :: WireTag -> Seq Text -> Put
putStringList :: WireTag -> Seq Text -> Put
putStringList = (WireTag -> Text -> Put) -> WireTag -> Seq Text -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Text -> Put
putString


-- | Encode an optional string field.
putStringOpt :: WireTag -> Maybe Text -> Put
putStringOpt :: WireTag -> Maybe Text -> Put
putStringOpt = (WireTag -> Text -> Put) -> WireTag -> Maybe Text -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Text -> Put
putString


-- | Encode a required uint32 field.
putUInt32 :: WireTag -> Word32 -> Put
putUInt32 :: WireTag -> Word32 -> Put
putUInt32 WireTag
tag Word32
i = do
    WireTag -> Put
putWireTag WireTag
tag
    Word32 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt Word32
i


-- | Encode a repeated uint32 field.
putUInt32List :: WireTag -> Seq Word32 -> Put
putUInt32List :: WireTag -> Seq Word32 -> Put
putUInt32List = (WireTag -> Word32 -> Put) -> WireTag -> Seq Word32 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Word32 -> Put
putUInt32


-- | Encode an optional uint32 field.
putUInt32Opt :: WireTag -> Maybe Word32 -> Put
putUInt32Opt :: WireTag -> Maybe Word32 -> Put
putUInt32Opt = (WireTag -> Word32 -> Put) -> WireTag -> Maybe Word32 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Word32 -> Put
putUInt32


-- | Encode a packed repeated uint32 field.
putUInt32Packed :: WireTag -> Seq Word32 -> Put
putUInt32Packed :: WireTag -> Seq Word32 -> Put
putUInt32Packed = (Word32 -> Put) -> WireTag -> Seq Word32 -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked Word32 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt


-- | Encode a required uint64 field.
putUInt64 :: WireTag -> Word64 -> Put
putUInt64 :: WireTag -> Word64 -> Put
putUInt64 WireTag
tag Word64
i = do
    WireTag -> Put
putWireTag WireTag
tag
    Word64 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt Word64
i


-- | Encode a repeated uint64 field.
putUInt64List :: WireTag -> Seq Word64 -> Put
putUInt64List :: WireTag -> Seq Word64 -> Put
putUInt64List = (WireTag -> Word64 -> Put) -> WireTag -> Seq Word64 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> Word64 -> Put
putUInt64


-- | Encode an optional uint64 field.
putUInt64Opt :: WireTag -> Maybe Word64 -> Put
putUInt64Opt :: WireTag -> Maybe Word64 -> Put
putUInt64Opt = (WireTag -> Word64 -> Put) -> WireTag -> Maybe Word64 -> Put
forall a. (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> Word64 -> Put
putUInt64


-- | Encode a packed repeated uint64 field.
putUInt64Packed :: WireTag -> Seq Word64 -> Put
putUInt64Packed :: WireTag -> Seq Word64 -> Put
putUInt64Packed = (Word64 -> Put) -> WireTag -> Seq Word64 -> Put
forall a. (a -> Put) -> WireTag -> Seq a -> Put
putPacked Word64 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt


-- | Encode a wire tag.
putWireTag :: WireTag -> Put
putWireTag :: WireTag -> Put
putWireTag = Word32 -> Put
forall a. (Bits a, Integral a) => a -> Put
putVarInt (Word32 -> Put) -> (WireTag -> Word32) -> WireTag -> Put
forall b c a. (b -> c) -> (a -> b) -> a -> c
. WireTag -> Word32
fromWireTag



{- Internal -}


getOpt :: Get a -> Get (Maybe a)
getOpt :: Get a -> Get (Maybe a)
getOpt = (a -> Maybe a) -> Get a -> Get (Maybe a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap a -> Maybe a
forall a. a -> Maybe a
Just


getPacked :: Get a -> Get (Seq a)
getPacked :: Get a -> Get (Seq a)
getPacked Get a
f = do
    ByteString
bytes <- Get ByteString
getBytes
    case Get (Seq a)
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, Seq a)
forall a.
Get a
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
runGetOrFail (Seq a -> Get (Seq a)
loop Seq a
forall a. Seq a
Seq.empty) ByteString
bytes of
      Left  (ByteString
_, ByteOffset
_, String
err) -> String -> Get (Seq a)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
err
      Right (ByteString
_, ByteOffset
_, Seq a
obj) -> Seq a -> Get (Seq a)
forall (m :: * -> *) a. Monad m => a -> m a
return Seq a
obj
    where
      loop :: Seq a -> Get (Seq a)
loop Seq a
xs = do
        Bool
done <- Get Bool
isEmpty
        if Bool
done
          then Seq a -> Get (Seq a)
forall (m :: * -> *) a. Monad m => a -> m a
return Seq a
xs
          else do
            a
val <- Get a
f
            Seq a -> Get (Seq a)
loop (Seq a
xs Seq a -> a -> Seq a
forall a. Seq a -> a -> Seq a
|> a
val)


getVarInt :: (Bits a, Integral a) => Get a
getVarInt :: Get a
getVarInt = a -> Shift -> Get a
forall a. (Bits a, Integral a) => a -> Shift -> Get a
getVarIntBytes a
0 Shift
0


type Shift = Int


getVarIntBytes :: (Bits a, Integral a) => a -> Shift -> Get a
getVarIntBytes :: a -> Shift -> Get a
getVarIntBytes a
prev Shift
shift = do
    (Bool
isLast, a
newVal, Shift
newShift) <- a -> Shift -> Get (Bool, a, Shift)
forall a.
(Bits a, Integral a) =>
a -> Shift -> Get (Bool, a, Shift)
getVarIntByte a
prev Shift
shift
    if Bool
isLast
      then a -> Get a
forall (m :: * -> *) a. Monad m => a -> m a
return a
newVal
      else a -> Shift -> Get a
forall a. (Bits a, Integral a) => a -> Shift -> Get a
getVarIntBytes a
newVal Shift
newShift


getVarIntByte :: (Bits a, Integral a) => a -> Shift -> Get (Bool, a, Shift)
getVarIntByte :: a -> Shift -> Get (Bool, a, Shift)
getVarIntByte a
prev Shift
shift = do
    Word8
byte  <- Get Word8
getWord8
    let isLast :: Bool
isLast = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ Word8 -> Shift -> Bool
forall a. Bits a => a -> Shift -> Bool
testBit Word8
byte Shift
7
    let newVal :: a
newVal = a
prev a -> a -> a
forall a. Bits a => a -> a -> a
.|. (Word8 -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word8
byte Word8 -> Word8 -> Word8
forall a. Bits a => a -> a -> a
.&. Word8
0x7F) a -> Shift -> a
forall a. Bits a => a -> Shift -> a
`shiftL` Shift
shift)
    let newShift :: Shift
newShift = Shift
shift Shift -> Shift -> Shift
forall a. Num a => a -> a -> a
+ Shift
7
    (Bool, a, Shift) -> Get (Bool, a, Shift)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
isLast, a
newVal, Shift
newShift)


putVarInt :: (Bits a, Integral a) => a -> Put
putVarInt :: a -> Put
putVarInt a
i
    | a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
0     = a -> Put
forall a. (Bits a, Integral a) => a -> Put
putNegVarInt a
i
    | Bool
otherwise = a -> Put
forall a. (Bits a, Integral a) => a -> Put
putPosVarInt a
i


putNegVarInt :: (Bits a, Integral a) => a -> Put
putNegVarInt :: a -> Put
putNegVarInt a
i = a -> Shift -> Put
forall a. (Bits a, Integral a) => a -> Shift -> Put
putNegVarInt' a
i Shift
10


putNegVarInt' :: (Bits a, Integral a) => a -> Int -> Put
putNegVarInt' :: a -> Shift -> Put
putNegVarInt' a
i Shift
1 = Word8 -> Put
putWord8 (Word8 -> Put) -> Word8 -> Put
forall a b. (a -> b) -> a -> b
$ a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word8) -> a -> Word8
forall a b. (a -> b) -> a -> b
$ a
i a -> a -> a
forall a. Bits a => a -> a -> a
.&. a
1
putNegVarInt' a
i Shift
n = do
    Word8 -> Put
putWord8 (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word8) -> a -> Word8
forall a b. (a -> b) -> a -> b
$ a -> Shift -> a
forall a. Bits a => a -> Shift -> a
setBit (a
i a -> a -> a
forall a. Bits a => a -> a -> a
.&. a
0x7F) Shift
7)
    a -> Shift -> Put
forall a. (Bits a, Integral a) => a -> Shift -> Put
putNegVarInt' (a -> Shift -> a
forall a. Bits a => a -> Shift -> a
shiftR a
i Shift
7) (Shift
n Shift -> Shift -> Shift
forall a. Num a => a -> a -> a
- Shift
1)


putPosVarInt :: (Bits a, Integral a) => a -> Put
putPosVarInt :: a -> Put
putPosVarInt a
i
    | a
i a -> a -> Bool
forall a. Ord a => a -> a -> Bool
< a
128   = Word8 -> Put
putWord8 (Word8 -> Put) -> Word8 -> Put
forall a b. (a -> b) -> a -> b
$ a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral a
i
    | Bool
otherwise = do
        Word8 -> Put
putWord8 (a -> Word8
forall a b. (Integral a, Num b) => a -> b
fromIntegral (a -> Word8) -> a -> Word8
forall a b. (a -> b) -> a -> b
$ a -> Shift -> a
forall a. Bits a => a -> Shift -> a
setBit (a
i a -> a -> a
forall a. Bits a => a -> a -> a
.&. a
0x7F) Shift
7)
        a -> Put
forall a. (Bits a, Integral a) => a -> Put
putPosVarInt (a -> Shift -> a
forall a. Bits a => a -> Shift -> a
shiftR a
i Shift
7)


putList :: (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList :: (WireTag -> a -> Put) -> WireTag -> Seq a -> Put
putList WireTag -> a -> Put
f WireTag
tag = (a -> Put) -> Seq a -> Put
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (WireTag -> a -> Put
f WireTag
tag)


putPacked :: (a -> Put) -> WireTag -> Seq a -> Put
putPacked :: (a -> Put) -> WireTag -> Seq a -> Put
putPacked a -> Put
f WireTag
tag Seq a
xs
    | Shift
len Shift -> Shift -> Bool
forall a. Eq a => a -> a -> Bool
== Shift
0  = () -> Put
forall (m :: * -> *) a. Monad m => a -> m a
return ()
    | Bool
otherwise = WireTag -> ByteString -> Put
putBytes WireTag
tag (ByteString -> Put) -> ByteString -> Put
forall a b. (a -> b) -> a -> b
$ Put -> ByteString
runPut (Seq a -> (a -> Put) -> Put
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ Seq a
xs a -> Put
f)
    where len :: Shift
len = Seq a -> Shift
forall a. Seq a -> Shift
Seq.length Seq a
xs


putOpt :: (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt :: (WireTag -> a -> Put) -> WireTag -> Maybe a -> Put
putOpt WireTag -> a -> Put
f WireTag
tag (Just a
val) = WireTag -> a -> Put
f WireTag
tag a
val
putOpt WireTag -> a -> Put
_ WireTag
_   Maybe a
Nothing    = () -> Put
forall (m :: * -> *) a. Monad m => a -> m a
return ()


boolToWord8 :: Bool -> Word8
boolToWord8 :: Bool -> Word8
boolToWord8 Bool
True  = Word8
1
boolToWord8 Bool
False = Word8
0