{-# LANGUAGE GADTs #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternGuards #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TypeApplications #-}
module Data.ProtoLens.Message (
Message(..),
Tag(..),
allFields,
FieldDescriptor(..),
fieldDescriptorName,
isRequired,
FieldAccessor(..),
WireDefault(..),
Packing(..),
FieldTypeDescriptor(..),
ScalarField(..),
MessageOrGroup(..),
FieldDefault(..),
MessageEnum(..),
build,
Registry,
register,
lookupRegistered,
SomeMessageType(..),
matchAnyMessage,
AnyMessageDescriptor(..),
maybeLens,
reverseRepeatedFields,
FieldSet,
TaggedValue(..),
discardUnknownFields,
) where
import qualified Data.ByteString as B
import Data.Int
import qualified Data.Map as Map
import Data.Map (Map)
import Data.Maybe (fromMaybe)
import Data.Proxy (Proxy(..))
import qualified Data.Text as T
import Data.Word
import Lens.Family2 (Lens', over, set)
import Lens.Family2.Unchecked (lens)
import qualified Data.Semigroup as Semigroup
import Data.ProtoLens.Encoding.Bytes (Builder, Parser)
import Data.ProtoLens.Encoding.Wire
( Tag(..)
, TaggedValue(..)
)
class Message msg where
messageName :: Proxy msg -> T.Text
packedMessageDescriptor :: Proxy msg -> B.ByteString
packedFileDescriptor :: Proxy msg -> B.ByteString
defMessage :: msg
fieldsByTag :: Map Tag (FieldDescriptor msg)
fieldsByTextFormatName :: Map String (FieldDescriptor msg)
fieldsByTextFormatName =
forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList [(String
n, FieldDescriptor msg
f) | f :: FieldDescriptor msg
f@(FieldDescriptor String
n FieldTypeDescriptor value
_ FieldAccessor msg value
_) <- forall msg. Message msg => [FieldDescriptor msg]
allFields]
unknownFields :: Lens' msg FieldSet
parseMessage :: Parser msg
buildMessage :: msg -> Builder
allFields :: Message msg => [FieldDescriptor msg]
allFields :: forall msg. Message msg => [FieldDescriptor msg]
allFields = forall k a. Map k a -> [a]
Map.elems forall msg. Message msg => Map Tag (FieldDescriptor msg)
fieldsByTag
type FieldSet = [TaggedValue]
data FieldDescriptor msg where
FieldDescriptor :: String
-> FieldTypeDescriptor value -> FieldAccessor msg value
-> FieldDescriptor msg
fieldDescriptorName :: FieldDescriptor msg -> String
fieldDescriptorName :: forall msg. FieldDescriptor msg -> String
fieldDescriptorName (FieldDescriptor String
name FieldTypeDescriptor value
_ FieldAccessor msg value
_) = String
name
isRequired :: FieldDescriptor msg -> Bool
isRequired :: forall msg. FieldDescriptor msg -> Bool
isRequired (FieldDescriptor String
_ FieldTypeDescriptor value
_ (PlainField WireDefault value
Required Lens' msg value
_)) = Bool
True
isRequired FieldDescriptor msg
_ = Bool
False
data FieldAccessor msg value where
PlainField :: WireDefault value -> Lens' msg value
-> FieldAccessor msg value
OptionalField :: Lens' msg (Maybe value) -> FieldAccessor msg value
RepeatedField :: Packing -> Lens' msg [value] -> FieldAccessor msg value
MapField :: (Ord key, Message entry) => Lens' entry key -> Lens' entry value
-> Lens' msg (Map key value) -> FieldAccessor msg entry
data WireDefault value where
Required :: WireDefault value
Optional :: (FieldDefault value, Eq value) => WireDefault value
class FieldDefault value where
fieldDefault :: value
instance FieldDefault Bool where
fieldDefault :: Bool
fieldDefault = Bool
False
instance FieldDefault Int32 where
fieldDefault :: Int32
fieldDefault = Int32
0
instance FieldDefault Int64 where
fieldDefault :: Int64
fieldDefault = Int64
0
instance FieldDefault Word32 where
fieldDefault :: Word32
fieldDefault = Word32
0
instance FieldDefault Word64 where
fieldDefault :: Word64
fieldDefault = Word64
0
instance FieldDefault Float where
fieldDefault :: Float
fieldDefault = Float
0
instance FieldDefault Double where
fieldDefault :: Double
fieldDefault = Double
0
instance FieldDefault B.ByteString where
fieldDefault :: ByteString
fieldDefault = ByteString
B.empty
instance FieldDefault T.Text where
fieldDefault :: Text
fieldDefault = Text
T.empty
data Packing = Packed | Unpacked
data FieldTypeDescriptor value where
MessageField :: Message value => MessageOrGroup -> FieldTypeDescriptor value
ScalarField :: ScalarField value -> FieldTypeDescriptor value
deriving instance Show (FieldTypeDescriptor value)
data MessageOrGroup = MessageType | GroupType
deriving Int -> MessageOrGroup -> ShowS
[MessageOrGroup] -> ShowS
MessageOrGroup -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [MessageOrGroup] -> ShowS
$cshowList :: [MessageOrGroup] -> ShowS
show :: MessageOrGroup -> String
$cshow :: MessageOrGroup -> String
showsPrec :: Int -> MessageOrGroup -> ShowS
$cshowsPrec :: Int -> MessageOrGroup -> ShowS
Show
data ScalarField t where
EnumField :: MessageEnum value => ScalarField value
Int32Field :: ScalarField Int32
Int64Field :: ScalarField Int64
UInt32Field :: ScalarField Word32
UInt64Field :: ScalarField Word64
SInt32Field :: ScalarField Int32
SInt64Field :: ScalarField Int64
Fixed32Field :: ScalarField Word32
Fixed64Field :: ScalarField Word64
SFixed32Field :: ScalarField Int32
SFixed64Field :: ScalarField Int64
FloatField :: ScalarField Float
DoubleField :: ScalarField Double
BoolField :: ScalarField Bool
StringField :: ScalarField T.Text
BytesField :: ScalarField B.ByteString
deriving instance Show (ScalarField value)
matchAnyMessage :: forall value . FieldTypeDescriptor value -> Maybe (AnyMessageDescriptor value)
matchAnyMessage :: forall value.
FieldTypeDescriptor value -> Maybe (AnyMessageDescriptor value)
matchAnyMessage (MessageField MessageOrGroup
_)
| forall msg. Message msg => Proxy msg -> Text
messageName (forall {k} (t :: k). Proxy t
Proxy @value) forall a. Eq a => a -> a -> Bool
== Text
"google.protobuf.Any"
, Just (FieldDescriptor String
_ (ScalarField ScalarField value
StringField) (PlainField WireDefault value
Optional Lens' value value
typeUrlLens))
<- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Tag
1 (forall msg. Message msg => Map Tag (FieldDescriptor msg)
fieldsByTag @value)
, Just (FieldDescriptor String
_ (ScalarField ScalarField value
BytesField) (PlainField WireDefault value
Optional Lens' value value
valueLens))
<- forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Tag
2 (forall msg. Message msg => Map Tag (FieldDescriptor msg)
fieldsByTag @value)
= forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall msg.
Lens' msg Text -> Lens' msg ByteString -> AnyMessageDescriptor msg
AnyMessageDescriptor Lens' value value
typeUrlLens Lens' value value
valueLens
matchAnyMessage FieldTypeDescriptor value
_ = forall a. Maybe a
Nothing
data AnyMessageDescriptor msg
= AnyMessageDescriptor
{ forall msg. AnyMessageDescriptor msg -> Lens' msg Text
anyTypeUrlLens :: Lens' msg T.Text
, forall msg. AnyMessageDescriptor msg -> Lens' msg ByteString
anyValueLens :: Lens' msg B.ByteString
}
class (Enum a, Bounded a) => MessageEnum a where
maybeToEnum :: Int -> Maybe a
showEnum :: a -> String
readEnum :: String -> Maybe a
build :: Message a => (a -> a) -> a
build :: forall a. Message a => (a -> a) -> a
build = (forall a b. (a -> b) -> a -> b
$ forall msg. Message msg => msg
defMessage)
maybeLens :: b -> Lens' (Maybe b) b
maybeLens :: forall b. b -> Lens' (Maybe b) b
maybeLens b
x = forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens (forall a. a -> Maybe a -> a
fromMaybe b
x) forall a b. (a -> b) -> a -> b
$ forall a b. a -> b -> a
const forall a. a -> Maybe a
Just
reverseRepeatedFields :: Map k (FieldDescriptor msg) -> msg -> msg
reverseRepeatedFields :: forall k msg. Map k (FieldDescriptor msg) -> msg -> msg
reverseRepeatedFields Map k (FieldDescriptor msg)
fields msg
x0
= forall a b k. (a -> b -> a) -> a -> Map k b -> a
Map.foldl' forall a. a -> FieldDescriptor a -> a
reverseListField msg
x0 Map k (FieldDescriptor msg)
fields
where
reverseListField :: a -> FieldDescriptor a -> a
reverseListField :: forall a. a -> FieldDescriptor a -> a
reverseListField a
x (FieldDescriptor String
_ FieldTypeDescriptor value
_ (RepeatedField Packing
_ Lens' a [value]
f))
= forall s t a b. Setter s t a b -> (a -> b) -> s -> t
over Lens' a [value]
f forall a. [a] -> [a]
reverse a
x
reverseListField a
x FieldDescriptor a
_ = a
x
newtype Registry = Registry (Map.Map T.Text SomeMessageType)
deriving (NonEmpty Registry -> Registry
Registry -> Registry -> Registry
forall b. Integral b => b -> Registry -> Registry
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> Registry -> Registry
$cstimes :: forall b. Integral b => b -> Registry -> Registry
sconcat :: NonEmpty Registry -> Registry
$csconcat :: NonEmpty Registry -> Registry
<> :: Registry -> Registry -> Registry
$c<> :: Registry -> Registry -> Registry
Semigroup.Semigroup, Semigroup Registry
Registry
[Registry] -> Registry
Registry -> Registry -> Registry
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [Registry] -> Registry
$cmconcat :: [Registry] -> Registry
mappend :: Registry -> Registry -> Registry
$cmappend :: Registry -> Registry -> Registry
mempty :: Registry
$cmempty :: Registry
Monoid)
register :: forall msg . Message msg => Proxy msg -> Registry
register :: forall msg. Message msg => Proxy msg -> Registry
register Proxy msg
p = Map Text SomeMessageType -> Registry
Registry forall a b. (a -> b) -> a -> b
$ forall k a. k -> a -> Map k a
Map.singleton (forall msg. Message msg => Proxy msg -> Text
messageName (forall {k} (t :: k). Proxy t
Proxy @msg)) (forall msg. Message msg => Proxy msg -> SomeMessageType
SomeMessageType Proxy msg
p)
lookupRegistered :: T.Text -> Registry -> Maybe SomeMessageType
lookupRegistered :: Text -> Registry -> Maybe SomeMessageType
lookupRegistered Text
n (Registry Map Text SomeMessageType
m) = forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup (forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ Text -> Text -> (Text, Text)
T.breakOnEnd Text
"/" Text
n) Map Text SomeMessageType
m
data SomeMessageType where
SomeMessageType :: Message msg => Proxy msg -> SomeMessageType
discardUnknownFields :: Message msg => msg -> msg
discardUnknownFields :: forall msg. Message msg => msg -> msg
discardUnknownFields = forall s t a b. Setter s t a b -> b -> s -> t
set forall msg. Message msg => Lens' msg FieldSet
unknownFields []