{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE ViewPatterns #-}

{-# OPTIONS_GHC -Wno-orphans #-}

-- | Encodes to protobuf directly from application-specific source data without
-- an intermediate value of a type generated from protobuf message definitions.
--
-- Use @compile-proto-file --typeLevelFormat ...@ to generate supporting code.
--
-- Importantly, code generation does not make use of this module,
-- instead using only "Proto3.Suite.Form".  Therefore one can replace
-- this module with another that makes use of the same generated code.
--
-- /WARNING/: This module is experimental and breaking changes may occur much more
-- frequently than in the other modules of this package, perhaps even in patch releases.
--
-- Example @.proto@ file:
--
-- > syntax = "proto3";
-- > package Example;
-- >
-- > message Submessage {
-- > };
-- >
-- > message Message {
-- >   sint32 implicitField = 1;
-- >   optional sint32 optionalField = 2;
-- >   repeated sint32 repeatedField = 3;
-- >   Submessage submessageField = 4;
-- >   map<sint32, string> mapField = 5;
-- > }
--
-- Example Haskell program:
--
-- > {-# LANGUAGE DataKinds #-}
-- > {-# LANGUAGE OverloadedStrings #-}
-- > {-# LANGUAGE PolyKinds #-}
-- > {-# LANGUAGE TypeApplications #-}
-- >
-- > import Control.Category ((.), id)
-- > import Data.ByteString.Lazy (writeFile)
-- > import Data.Text.Short (ShortText)
-- > import Data.Word (Word8)
-- > import Example (Message, Submessage)
-- > import Prelude hiding ((.), id)
-- > import Proto3.Suite.Form (Association, ProtoType(SInt32, String))
-- > import Proto3.Suite.Form.Encode
-- >          (Auto(..), MessageEncoder, associations, field,
-- >           fieldsToMessage, messageEncoderToLazyByteString)
-- > import Proto3.Wire.Encode.Repeated (mapRepeated)
-- >
-- > main :: IO ()
-- > main = do
-- >   let assoc :: (Word8, ShortText) -> MessageEncoder (Association 'SInt32 'String)
-- >       assoc (k, v) = fieldsToMessage (field @"key" k . field @"value" v)
-- >   Data.ByteString.Lazy.writeFile "example.data" $
-- >     messageEncoderToLazyByteString $
-- >       fieldsToMessage @Message $
-- >         field @"implicitField" @Word8 123 .
-- >         field @"optionalField" (Just (Auto 456)) .
-- >         field @"repeatedField" (mapRepeated Auto [789, 321]) .
-- >         field @"submessageField" (Just (fieldsToMessage @Submessage id)) .
-- >         associations @"mapField" (mapRepeated assoc [(3, "abc"), (5, "xyz")])
--
module Proto3.Suite.Form.Encode
  ( MessageEncoder(..)
  , messageEncoderToLazyByteString
  , messageEncoderToByteString
  , etaMessageEncoder
  , unsafeByteStringToMessageEncoder
  , MessageEncoding
  , messageCache
  , cacheMessageEncoding
  , cachedMessageEncoding
  , messageEncodingToByteString
  , unsafeByteStringToMessageEncoding
  , FieldsEncoder(..)
  , etaFieldsEncoder
  , FieldsEncoding
  , cacheFieldsEncoding
  , cachedFieldsEncoding
  , Distinct
  , DistinctCheck
  , RepeatedNames
  , RepeatedNames1
  , Omits
  , Strip
  , OccupiedOnly
  , OccupiedOnly1
  , fieldsToMessage
  , Occupy
  , Occupy1
  , NameSublist
  , omitted
  , SFieldNumberI
  , KnownFieldNumber
  , Field(..)
  , FieldForm(..)
  , Wrap(..)
  , Auto(..)
  , foldFieldsEncoders
  , message
  , associations
  , Reflection(..)
  , messageReflection
  ) where

import Control.Applicative ((<|>))
import Control.Category (Category(..))
import Control.DeepSeq (NFData)
import Data.Aeson qualified as Aeson (FromJSON(..), ToJSON(..))
import Data.Coerce (coerce)
import Data.Int (Int8, Int16, Int32, Int64)
import Data.Kind (Type)
import Data.ByteString qualified as B
import Data.ByteString.Lazy qualified as BL
import Data.ByteString.Short qualified as BS
import Data.Functor.Identity (Identity(..))
import Data.Text qualified as T
import Data.Text.Lazy qualified as TL
import Data.Text.Short qualified as TS
import Data.Word (Word8, Word16, Word32, Word64)
import GHC.Exts (Proxy#, proxy#)
import GHC.Generics (Generic)
import GHC.TypeLits (Symbol)
import Prelude hiding (String, (.), id)
import Proto3.Suite.Form.Encode.Core
import Proto3.Suite.Class
         (Message, MessageField, encodeMessage, encodeMessageField, fromByteString)
import Proto3.Suite.Form
         (Association, MessageFieldType,  Packing(..), Cardinality(..),
          CardinalityOf, ProtoType(..), ProtoTypeOf)
import Proto3.Suite.JSONPB.Class qualified as JSONPB
         (FromJSONPB(..), ToJSONPB(..), toAesonEncoding, toAesonValue)
import Proto3.Suite.Types (Enumerated, codeFromEnumerated)
import Proto3.Wire.Class (ProtoEnum(..))
import Proto3.Wire.Encode qualified as Encode
import Proto3.Wire.Encode.Repeated (ToRepeated, mapRepeated)
import Proto3.Wire.Reverse qualified as RB
import Proto3.Wire.Types (FieldNumber, fieldNumber)

-- | The unsafe but fast inverse of 'messageEncoderToByteString'.
unsafeByteStringToMessageEncoder :: B.ByteString -> MessageEncoder message
unsafeByteStringToMessageEncoder :: forall message. ByteString -> MessageEncoder message
unsafeByteStringToMessageEncoder = MessageBuilder -> MessageEncoder message
forall message. MessageBuilder -> MessageEncoder message
UnsafeMessageEncoder (MessageBuilder -> MessageEncoder message)
-> (ByteString -> MessageBuilder)
-> ByteString
-> MessageEncoder message
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ByteString -> MessageBuilder
Encode.unsafeFromByteString

-- | The octet sequence that would be emitted by some
-- 'MessageEncoder' having the same type parameter.
--
-- (This type is not a 'Semigroup' because combining encodings that both
-- have the same non-repeated field is arguably incorrect, even though the
-- standard asks parsers to to try to work around such improper repetition.)
--
-- See also: 'cacheMessageEncoding'
newtype MessageEncoding (message :: Type) = UnsafeMessageEncoding B.ByteString
  deriving stock ((forall x.
 MessageEncoding message -> Rep (MessageEncoding message) x)
-> (forall x.
    Rep (MessageEncoding message) x -> MessageEncoding message)
-> Generic (MessageEncoding message)
forall x.
Rep (MessageEncoding message) x -> MessageEncoding message
forall x.
MessageEncoding message -> Rep (MessageEncoding message) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall message x.
Rep (MessageEncoding message) x -> MessageEncoding message
forall message x.
MessageEncoding message -> Rep (MessageEncoding message) x
$cfrom :: forall message x.
MessageEncoding message -> Rep (MessageEncoding message) x
from :: forall x.
MessageEncoding message -> Rep (MessageEncoding message) x
$cto :: forall message x.
Rep (MessageEncoding message) x -> MessageEncoding message
to :: forall x.
Rep (MessageEncoding message) x -> MessageEncoding message
Generic)
  deriving newtype (MessageEncoding message -> ()
(MessageEncoding message -> ()) -> NFData (MessageEncoding message)
forall message. MessageEncoding message -> ()
forall a. (a -> ()) -> NFData a
$crnf :: forall message. MessageEncoding message -> ()
rnf :: MessageEncoding message -> ()
NFData)

type role MessageEncoding nominal

instance FieldForm 'Optional ('Message inner) (Identity (MessageEncoding inner))
  where
    fieldForm :: Proxy# 'Optional
-> Proxy# ('Message inner)
-> FieldNumber
-> Identity (MessageEncoding inner)
-> MessageBuilder
fieldForm Proxy# 'Optional
rep Proxy# ('Message inner)
ty !FieldNumber
fn (Identity MessageEncoding inner
e) = Proxy# 'Optional
-> Proxy# ('Message inner)
-> FieldNumber
-> Identity (MessageEncoder inner)
-> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm Proxy# 'Optional
rep Proxy# ('Message inner)
ty FieldNumber
fn (MessageEncoder inner -> Identity (MessageEncoder inner)
forall a. a -> Identity a
Identity (MessageEncoding inner -> MessageEncoder inner
forall message. MessageEncoding message -> MessageEncoder message
cachedMessageEncoding MessageEncoding inner
e))
    {-# INLINE fieldForm #-}

-- | This instance is rather artificial because maps are automatically
-- repeated and unpacked, with no option to specify a single key-value pair
-- as an @optional@ field or a field of a @oneof@.  Hence the code generator
-- should never directly make use of this instance, but it will do so
-- indirectly via the general instance for repeated unpacked fields,
-- which will then delegate to this instance.
instance FieldForm 'Optional ('Map key value) (Identity (MessageEncoding (Association key value)))
  where
    fieldForm :: Proxy# 'Optional
-> Proxy# ('Map key value)
-> FieldNumber
-> Identity (MessageEncoding (Association key value))
-> MessageBuilder
fieldForm Proxy# 'Optional
rep Proxy# ('Map key value)
ty !FieldNumber
fn (Identity MessageEncoding (Association key value)
a) = Proxy# 'Optional
-> Proxy# ('Map key value)
-> FieldNumber
-> Identity (MessageEncoder (Association key value))
-> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm Proxy# 'Optional
rep Proxy# ('Map key value)
ty FieldNumber
fn (MessageEncoder (Association key value)
-> Identity (MessageEncoder (Association key value))
forall a. a -> Identity a
Identity (MessageEncoding (Association key value)
-> MessageEncoder (Association key value)
forall message. MessageEncoding message -> MessageEncoder message
cachedMessageEncoding MessageEncoding (Association key value)
a))
    {-# INLINE fieldForm #-}

-- | Precomputes the octet sequence that would be written by the given 'MessageEncoder'.
-- Do this only if you expect to reuse that specific octet sequence repeatedly.
--
-- @'cachedMessageEncoding' . 'cacheMessageEncoding'@ is functionally equivalent
-- to 'id' but has different performance characteristics.
--
-- See also: 'cacheFieldsEncoding'.
cacheMessageEncoding :: MessageEncoder message -> MessageEncoding message
cacheMessageEncoding :: forall message. MessageEncoder message -> MessageEncoding message
cacheMessageEncoding = ByteString -> MessageEncoding message
forall message. ByteString -> MessageEncoding message
UnsafeMessageEncoding (ByteString -> MessageEncoding message)
-> (MessageEncoder message -> ByteString)
-> MessageEncoder message
-> MessageEncoding message
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. MessageEncoder message -> ByteString
forall message. MessageEncoder message -> ByteString
messageEncoderToByteString

-- | Encodes a precomputed 'MessageEncoder' by copying octets from a memory buffer.
-- See 'cacheMessageEncoding'.
--
-- See also: 'cachedFieldsEncoding'
cachedMessageEncoding :: MessageEncoding message -> MessageEncoder message
cachedMessageEncoding :: forall message. MessageEncoding message -> MessageEncoder message
cachedMessageEncoding = ByteString -> MessageEncoder message
forall message. ByteString -> MessageEncoder message
unsafeByteStringToMessageEncoder (ByteString -> MessageEncoder message)
-> (MessageEncoding message -> ByteString)
-> MessageEncoding message
-> MessageEncoder message
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. MessageEncoding message -> ByteString
forall message. MessageEncoding message -> ByteString
messageEncodingToByteString

-- | Strips type information from the message encoding, leaving only its octets.
messageEncodingToByteString :: MessageEncoding message -> B.ByteString
messageEncodingToByteString :: forall message. MessageEncoding message -> ByteString
messageEncodingToByteString (UnsafeMessageEncoding ByteString
octets) = ByteString
octets

-- | Unsafe because the caller must ensure that the given octets
-- are in the correct format for a message of the specified type.
unsafeByteStringToMessageEncoding :: B.ByteString -> MessageEncoding message
unsafeByteStringToMessageEncoding :: forall message. ByteString -> MessageEncoding message
unsafeByteStringToMessageEncoding = ByteString -> MessageEncoding message
forall message. ByteString -> MessageEncoding message
UnsafeMessageEncoding

-- | The octet sequence that would be prefixed by some
-- 'FieldsEncoder' having the same type parameters.
newtype FieldsEncoding (message :: Type) (possible :: [Symbol]) (following :: [Symbol]) =
  UnsafeFieldsEncoding { forall message (possible :: [Symbol]) (following :: [Symbol]).
FieldsEncoding message possible following -> ByteString
untypedFieldsEncoding :: B.ByteString }

type role FieldsEncoding nominal nominal nominal

-- | Precomputes the octet sequence that would be written by the given 'FieldsEncoder'.
-- Do this only if you expect to reuse that specific octet sequence repeatedly.
--
-- @'cachedFieldsEncoding' . 'cacheFieldsEncoding'@ is functionally equivalent
-- to 'id' but has different performance characteristics.
--
-- See also: 'cacheMessageEncoding'
cacheFieldsEncoding ::
  FieldsEncoder message possible following -> FieldsEncoding message possible following
cacheFieldsEncoding :: forall message (possible :: [Symbol]) (following :: [Symbol]).
FieldsEncoder message possible following
-> FieldsEncoding message possible following
cacheFieldsEncoding =
  ByteString -> FieldsEncoding message possible following
forall message (possible :: [Symbol]) (following :: [Symbol]).
ByteString -> FieldsEncoding message possible following
UnsafeFieldsEncoding (ByteString -> FieldsEncoding message possible following)
-> (FieldsEncoder message possible following -> ByteString)
-> FieldsEncoder message possible following
-> FieldsEncoding message possible following
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. LazyByteString -> ByteString
BL.toStrict (LazyByteString -> ByteString)
-> (FieldsEncoder message possible following -> LazyByteString)
-> FieldsEncoder message possible following
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. MessageBuilder -> LazyByteString
Encode.toLazyByteString (MessageBuilder -> LazyByteString)
-> (FieldsEncoder message possible following -> MessageBuilder)
-> FieldsEncoder message possible following
-> LazyByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. FieldsEncoder message possible following -> MessageBuilder
forall message (possible :: [Symbol]) (following :: [Symbol]).
FieldsEncoder message possible following -> MessageBuilder
untypedFieldsEncoder

-- | Encodes a precomputed 'FieldsEncoder' by copying octets from a memory buffer.
-- See 'cacheFieldsEncoding'.
--
-- See also: 'cachedMessageEncoding'.
cachedFieldsEncoding ::
  FieldsEncoding message possible following -> FieldsEncoder message possible following
cachedFieldsEncoding :: forall message (possible :: [Symbol]) (following :: [Symbol]).
FieldsEncoding message possible following
-> FieldsEncoder message possible following
cachedFieldsEncoding = MessageBuilder -> FieldsEncoder message possible following
forall message (possible :: [Symbol]) (following :: [Symbol]).
MessageBuilder -> FieldsEncoder message possible following
UnsafeFieldsEncoder (MessageBuilder -> FieldsEncoder message possible following)
-> (FieldsEncoding message possible following -> MessageBuilder)
-> FieldsEncoding message possible following
-> FieldsEncoder message possible following
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. ByteString -> MessageBuilder
Encode.unsafeFromByteString (ByteString -> MessageBuilder)
-> (FieldsEncoding message possible following -> ByteString)
-> FieldsEncoding message possible following
-> MessageBuilder
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. FieldsEncoding message possible following -> ByteString
forall message (possible :: [Symbol]) (following :: [Symbol]).
FieldsEncoding message possible following -> ByteString
untypedFieldsEncoding
{-# INLINE cachedFieldsEncoding #-}

$(instantiatePackableField
  [t| 'UInt32 |] [t| Word32 |] [| Encode.uint32 |] [| Encode.packedUInt32R |]
  [ ([t| Word16 |], [| fromIntegral @Word16 @Word32 |], [t| 'UInt32 |])
  , ([t|  Word8 |], [| fromIntegral  @Word8 @Word32 |], [t| 'UInt32 |])
  ] True)

$(instantiatePackableField
  [t| 'UInt64 |] [t| Word64 |] [| Encode.uint64 |] [| Encode.packedUInt64R |]
  [ ([t| Word32 |], [|                           id |], [t| 'UInt32 |])
  , ([t| Word16 |], [| fromIntegral @Word16 @Word32 |], [t| 'UInt32 |])
  , ([t|  Word8 |], [| fromIntegral  @Word8 @Word32 |], [t| 'UInt32 |])
  ] True)

$(instantiatePackableField
  [t| 'Int32 |] [t| Int32 |] [| Encode.int32 |] [| Encode.packedInt32R |]
  [ ([t|  Int16 |], [| fromIntegral   @Int16 @Int32 |], [t|  'Int32 |])
  , ([t|   Int8 |], [| fromIntegral    @Int8 @Int32 |], [t|  'Int32 |])
  -- Because the encoding for @int32@ is just a conversion to the 64-bit unsigned
  -- integer that is equal to the original value modulo @2^64@ followed by @uint64@
  -- encoding, the encoding of unsigned values can be accomplished with the @uint32@
  -- encoder, which generates less code because it need not support values @>= 2^32@.
  , ([t| Word16 |], [|                           id |], [t| 'UInt32 |])
  , ([t|  Word8 |], [|                           id |], [t| 'UInt32 |])
  ] True)

$(instantiatePackableField
  [t| 'Int64 |] [t| Int64 |] [| Encode.int64 |] [| Encode.packedInt64R |]
  [ ([t|  Int32 |], [| fromIntegral  @Int32 @Int64 |], [t| 'Int64 |])
  , ([t|  Int16 |], [| fromIntegral  @Int16 @Int64 |], [t| 'Int64 |])
  , ([t|   Int8 |], [| fromIntegral   @Int8 @Int64 |], [t| 'Int64 |])
  -- Because the encoding for @int32@ is just a conversion to the 64-bit unsigned
  -- integer that is equal to the original value modulo @2^64@ followed by @uint64@
  -- encoding, the encoding of unsigned values can be accomplished with the @uint32@
  -- encoder, which generates less code because it need not support values @>= 2^32@.
  , ([t| Word32 |], [|                           id |], [t| 'UInt32 |])
  , ([t| Word16 |], [|                           id |], [t| 'UInt32 |])
  , ([t|  Word8 |], [|                           id |], [t| 'UInt32 |])
  ] True)

$(instantiatePackableField
  [t| 'SInt32 |] [t| Int32 |] [| Encode.sint32 |] [| Encode.packedSInt32R |]
  [ ([t|  Int16 |], [| fromIntegral  @Int16 @Int32 |], [t| 'SInt32 |])
  , ([t|   Int8 |], [| fromIntegral   @Int8 @Int32 |], [t| 'SInt32 |])
  , ([t| Word16 |], [| fromIntegral @Word16 @Int32 |], [t| 'SInt32 |])
  , ([t|  Word8 |], [| fromIntegral  @Word8 @Int32 |], [t| 'SInt32 |])
  ] False)

$(instantiatePackableField
  [t| 'SInt64 |] [t| Int64 |] [| Encode.sint64 |] [| Encode.packedSInt64R |]
  [ ([t|  Int32 |], [|                          id |], [t| 'SInt32 |])
  , ([t|  Int16 |], [|                          id |], [t| 'SInt32 |])
  , ([t|   Int8 |], [|                          id |], [t| 'SInt32 |])
  , ([t| Word32 |], [| fromIntegral @Word32 @Int64 |], [t| 'SInt64 |])
  , ([t| Word16 |], [|                          id |], [t| 'SInt32 |])
  , ([t|  Word8 |], [|                          id |], [t| 'SInt32 |])
  ] False)

$(instantiatePackableField
  [t| 'Fixed32 |] [t| Word32 |] [| Encode.fixed32 |] [| Encode.packedFixed32R |]
  [ ([t| Word16 |], [| fromIntegral @Word16 @Word32 |], [t| 'Fixed32 |])
  , ([t|  Word8 |], [| fromIntegral  @Word8 @Word32 |], [t| 'Fixed32 |])
  ] False)

$(instantiatePackableField
  [t| 'Fixed64 |] [t| Word64 |] [| Encode.fixed64 |] [| Encode.packedFixed64R |]
  [ ([t| Word32 |], [| fromIntegral @Word32 @Word64 |], [t| 'Fixed64 |])
  , ([t| Word16 |], [| fromIntegral @Word16 @Word64 |], [t| 'Fixed64 |])
  , ([t|  Word8 |], [| fromIntegral  @Word8 @Word64 |], [t| 'Fixed64 |])
  ] False)

$(instantiatePackableField
  [t| 'SFixed32 |] [t| Int32 |] [| Encode.sfixed32 |] [| Encode.packedSFixed32R |]
  [ ([t|  Int16 |], [| fromIntegral  @Int16 @Int32 |], [t| 'SFixed32 |])
  , ([t|   Int8 |], [| fromIntegral   @Int8 @Int32 |], [t| 'SFixed32 |])
  , ([t| Word16 |], [| fromIntegral @Word16 @Int32 |], [t| 'SFixed32 |])
  , ([t|  Word8 |], [| fromIntegral  @Word8 @Int32 |], [t| 'SFixed32 |])
  ] False)

$(instantiatePackableField
  [t| 'SFixed64 |] [t| Int64 |] [| Encode.sfixed64 |] [| Encode.packedSFixed64R |]
  [ ([t|  Int32 |], [| fromIntegral  @Int32 @Int64 |], [t| 'SFixed64 |])
  , ([t|  Int16 |], [| fromIntegral  @Int16 @Int64 |], [t| 'SFixed64 |])
  , ([t|   Int8 |], [| fromIntegral   @Int8 @Int64 |], [t| 'SFixed64 |])
  , ([t| Word32 |], [| fromIntegral @Word32 @Int64 |], [t| 'SFixed64 |])
  , ([t| Word16 |], [| fromIntegral @Word16 @Int64 |], [t| 'SFixed64 |])
  , ([t|  Word8 |], [| fromIntegral  @Word8 @Int64 |], [t| 'SFixed64 |])
  ] False)

$(instantiatePackableField
  [t| 'Bool |] [t| Bool |] [| Encode.bool |] [| Encode.packedBoolsR |]
  [] True)

$(instantiatePackableField
  [t| 'Float |] [t| Float |] [| Encode.float |] [| Encode.packedFloatsR |]
  [] True)

$(instantiatePackableField
  [t| 'Double |] [t| Double |] [| Encode.double |] [| Encode.packedDoublesR |]
  [ ([t| Float |], [| realToFrac @Float @Double |], [t| 'Double |])
  ] True)

$(instantiateStringOrBytesField
   [t| 'String |] [t| TS.ShortText |] [| Encode.shortText |]
   [ ([t| T.Text |], [| \(!fn) x -> Encode.text fn (TL.fromStrict x) |])
   , ([t| TL.Text |], [| Encode.text |])
   ])

$(instantiateStringOrBytesField
   [t| 'Bytes |] [t| BS.ShortByteString |] [| Encode.shortByteString |]
   [ ([t| B.ByteString |], [| Encode.byteString |])
   , ([t| BL.ByteString |], [| Encode.lazyByteString |])
   ])

instance ( ProtoEnum e
         , FieldForm 'Implicit 'Int32 Int32
         ) =>
         FieldForm 'Implicit ('Enumeration e) e
  where
    fieldForm :: Proxy# 'Implicit
-> Proxy# ('Enumeration e) -> FieldNumber -> e -> MessageBuilder
fieldForm Proxy# 'Implicit
rep Proxy# ('Enumeration e)
_ !FieldNumber
fn e
x = Proxy# 'Implicit
-> Proxy# 'Int32 -> FieldNumber -> Int32 -> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm Proxy# 'Implicit
rep (Proxy# 'Int32
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# 'Int32) FieldNumber
fn (e -> Int32
forall a. ProtoEnum a => a -> Int32
fromProtoEnum e
x)
    {-# INLINE fieldForm #-}

instance ( ProtoEnum e
         , FieldForm 'Optional 'Int32 (Identity Int32)
         ) =>
         FieldForm 'Optional ('Enumeration e) (Identity e)
  where
    fieldForm :: Proxy# 'Optional
-> Proxy# ('Enumeration e)
-> FieldNumber
-> Identity e
-> MessageBuilder
fieldForm Proxy# 'Optional
rep Proxy# ('Enumeration e)
_ !FieldNumber
fn (Identity e
x) =
      Proxy# 'Optional
-> Proxy# 'Int32 -> FieldNumber -> Identity Int32 -> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm Proxy# 'Optional
rep (Proxy# 'Int32
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# 'Int32) FieldNumber
fn (Int32 -> Identity Int32
forall a. a -> Identity a
Identity (e -> Int32
forall a. ProtoEnum a => a -> Int32
fromProtoEnum e
x))
    {-# INLINE fieldForm #-}

instance ( ProtoEnum e
         , FieldForm 'Implicit 'Int32 Int32
         ) =>
         FieldForm 'Implicit ('Enumeration e) (Enumerated e)
  where
    fieldForm :: Proxy# 'Implicit
-> Proxy# ('Enumeration e)
-> FieldNumber
-> Enumerated e
-> MessageBuilder
fieldForm Proxy# 'Implicit
rep Proxy# ('Enumeration e)
_ !FieldNumber
fn Enumerated e
x = Proxy# 'Implicit
-> Proxy# 'Int32 -> FieldNumber -> Int32 -> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm Proxy# 'Implicit
rep (Proxy# 'Int32
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# 'Int32) FieldNumber
fn (Enumerated e -> Int32
forall e. ProtoEnum e => Enumerated e -> Int32
codeFromEnumerated Enumerated e
x)
    {-# INLINE fieldForm #-}

instance ( ProtoEnum e
         , FieldForm 'Optional 'Int32 (Identity Int32)
         ) =>
         FieldForm 'Optional ('Enumeration e) (Identity (Enumerated e))
  where
    fieldForm :: Proxy# 'Optional
-> Proxy# ('Enumeration e)
-> FieldNumber
-> Identity (Enumerated e)
-> MessageBuilder
fieldForm Proxy# 'Optional
rep Proxy# ('Enumeration e)
_ !FieldNumber
fn (Identity Enumerated e
x) =
      Proxy# 'Optional
-> Proxy# 'Int32 -> FieldNumber -> Identity Int32 -> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm Proxy# 'Optional
rep (Proxy# 'Int32
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# 'Int32) FieldNumber
fn (Int32 -> Identity Int32
forall a. a -> Identity a
Identity (Enumerated e -> Int32
forall e. ProtoEnum e => Enumerated e -> Int32
codeFromEnumerated Enumerated e
x))
    {-# INLINE fieldForm #-}

instance ProtoEnum e =>
         PackedFieldForm ('Enumeration e) e
  where
    packedFieldForm :: Proxy# ('Enumeration e)
-> FieldNumber -> Repeated e -> MessageBuilder
packedFieldForm Proxy# ('Enumeration e)
_ !FieldNumber
fn Repeated e
xs =
      Proxy# 'Int32 -> FieldNumber -> Repeated Int32 -> MessageBuilder
forall (protoType :: ProtoType) a.
PackedFieldForm protoType a =>
Proxy# protoType -> FieldNumber -> Repeated a -> MessageBuilder
packedFieldForm (Proxy# 'Int32
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# 'Int32) FieldNumber
fn ((e -> Int32) -> Repeated e -> Repeated Int32
forall a b. (a -> b) -> Repeated a -> Repeated b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap e -> Int32
forall a. ProtoEnum a => a -> Int32
fromProtoEnum Repeated e
xs)
    {-# INLINE packedFieldForm #-}

instance ProtoEnum e =>
         PackedFieldForm ('Enumeration e) (Enumerated e)
  where
    packedFieldForm :: Proxy# ('Enumeration e)
-> FieldNumber -> Repeated (Enumerated e) -> MessageBuilder
packedFieldForm Proxy# ('Enumeration e)
_ !FieldNumber
fn Repeated (Enumerated e)
xs =
      Proxy# 'Int32 -> FieldNumber -> Repeated Int32 -> MessageBuilder
forall (protoType :: ProtoType) a.
PackedFieldForm protoType a =>
Proxy# protoType -> FieldNumber -> Repeated a -> MessageBuilder
packedFieldForm (Proxy# 'Int32
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# 'Int32) FieldNumber
fn ((Enumerated e -> Int32)
-> Repeated (Enumerated e) -> Repeated Int32
forall a b. (a -> b) -> Repeated a -> Repeated b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Enumerated e -> Int32
forall e. ProtoEnum e => Enumerated e -> Int32
codeFromEnumerated Repeated (Enumerated e)
xs)
    {-# INLINE packedFieldForm #-}

instance FieldForm 'Optional 'Bytes (Identity RB.BuildR)
  where
    fieldForm :: Proxy# 'Optional
-> Proxy# 'Bytes
-> FieldNumber
-> Identity BuildR
-> MessageBuilder
fieldForm Proxy# 'Optional
_ Proxy# 'Bytes
_ = forall a b. Coercible a b => a -> b
forall a b. Coercible a b => a -> b
coerce
      @(FieldNumber -> RB.BuildR -> Encode.MessageBuilder)
      @(FieldNumber -> Identity RB.BuildR -> Encode.MessageBuilder)
      FieldNumber -> BuildR -> MessageBuilder
Encode.bytes
    {-# INLINE fieldForm #-}

instance FieldForm 'Implicit 'Bytes RB.BuildR
  where
    fieldForm :: Proxy# 'Implicit
-> Proxy# 'Bytes -> FieldNumber -> BuildR -> MessageBuilder
fieldForm Proxy# 'Implicit
_ Proxy# 'Bytes
_ = FieldNumber -> BuildR -> MessageBuilder
Encode.bytesIfNonempty
    {-# INLINE fieldForm #-}

-- | Combines 'FieldsEncoder' builders for zero or more repeated fields.
foldFieldsEncoders ::
  forall c message names .
  ToRepeated c (FieldsEncoder message names names) =>
  c ->
  FieldsEncoder message names names
foldFieldsEncoders :: forall c message (names :: [Symbol]).
ToRepeated c (FieldsEncoder message names names) =>
c -> FieldsEncoder message names names
foldFieldsEncoders c
prefixes =
  MessageBuilder -> FieldsEncoder message names names
forall message (possible :: [Symbol]) (following :: [Symbol]).
MessageBuilder -> FieldsEncoder message possible following
UnsafeFieldsEncoder (Repeated MessageBuilder -> MessageBuilder
forall c. ToRepeated c MessageBuilder => c -> MessageBuilder
Encode.repeatedMessageBuilder ((FieldsEncoder message names names -> MessageBuilder)
-> c -> Repeated MessageBuilder
forall c e a. ToRepeated c e => (e -> a) -> c -> Repeated a
mapRepeated FieldsEncoder message names names -> MessageBuilder
forall message (possible :: [Symbol]) (following :: [Symbol]).
FieldsEncoder message possible following -> MessageBuilder
untypedFieldsEncoder c
prefixes))
{-# INLINE foldFieldsEncoders #-}

-- | Specializes the argument type of 'field' to the encoding of a submessage type,
-- which can help to avoid ambiguity when the argument expression is polymorphic.
message ::
  forall (name :: Symbol) (inner :: Type) (outer :: Type) (names :: [Symbol]) .
  ( ProtoTypeOf outer name ~ 'Message inner
  , Field name (MessageEncoder inner) outer
  , KnownFieldNumber outer name
  ) =>
  MessageEncoder inner ->
  FieldsEncoder outer names (Occupy outer name names)
message :: forall (name :: Symbol) inner outer (names :: [Symbol]).
(ProtoTypeOf outer name ~ 'Message inner,
 Field name (MessageEncoder inner) outer,
 KnownFieldNumber outer name) =>
MessageEncoder inner
-> FieldsEncoder outer names (Occupy outer name names)
message = forall (name :: Symbol) a message (names :: [Symbol]).
Field name a message =>
a -> FieldsEncoder message names (Occupy message name names)
field @name @(MessageEncoder inner)

-- | Specializes the argument type of 'field' to be a sequence of key-value pair encodings,
-- which can help to avoid ambiguity when the argument expression is polymorphic.
associations ::
  forall (name :: Symbol) (t :: Type -> Type) (key :: ProtoType) (value :: ProtoType)
         (message :: Type) (names :: [Symbol]) .
  ( ProtoTypeOf message name ~ 'Map key value
  , CardinalityOf message name ~ 'Repeated 'Unpacked
  , Field name (t (MessageEncoder (Association key value))) message
  , KnownFieldNumber message name
  ) =>
  t (MessageEncoder (Association key value)) ->
  FieldsEncoder message names names
associations :: forall (name :: Symbol) (t :: * -> *) (key :: ProtoType)
       (value :: ProtoType) message (names :: [Symbol]).
(ProtoTypeOf message name ~ 'Map key value,
 CardinalityOf message name ~ 'Repeated 'Unpacked,
 Field name (t (MessageEncoder (Association key value))) message,
 KnownFieldNumber message name) =>
t (MessageEncoder (Association key value))
-> FieldsEncoder message names names
associations = forall (name :: Symbol) a message (names :: [Symbol]).
Field name a message =>
a -> FieldsEncoder message names (Occupy message name names)
field @name @(t (MessageEncoder (Association key value)))

-- | Signals that the argument to 'field' should be treated
-- as a reflection in Haskell of a protobuf construct, both
-- in its type and in its value.
--
-- For example, if the type argument is generated from a protobuf
-- message definition, then 'field' will encode the message whose
-- fields are given by the Haskell data type inside of this @newtype@.
--
-- Repeated fields must be supplied as an appropriately-typed sequence.
--
-- For this @newtype@, 'Field' delegates to `Proto3.Suite.Class.MessageField`
-- and has its performance characteristics.  The creation of temporary
-- reflections of protobuf messages may decrease efficiency
-- in some cases.  However, you may find this @newtype@ useful
-- where a mix of techniques is needed, either for compatibility
-- or during a gradual transition to use of 'Field'.
--
-- Note that for optional submessages you must use `Proto3.Suite.Types.Nested`,
-- and for repeated submessages you must use `Proto3.Suite.Types.NestedVec`.
-- (For submessages within a @oneof@ you can use the reflection type directly.)
--
-- To encode a top-level message instead of a field, use 'messageReflection'.
newtype Reflection a = Reflection a

instance ( MessageFieldType cardinality protoType a
         , MessageField a
         ) =>
         FieldForm cardinality protoType (Reflection a)
  where
    fieldForm :: Proxy# cardinality
-> Proxy# protoType
-> FieldNumber
-> Reflection a
-> MessageBuilder
fieldForm Proxy# cardinality
_ Proxy# protoType
_ = (FieldNumber -> a -> MessageBuilder)
-> FieldNumber -> Reflection a -> MessageBuilder
forall a b. Coercible a b => a -> b
coerce (forall a. MessageField a => FieldNumber -> a -> MessageBuilder
encodeMessageField @a)
    {-# INLINE fieldForm #-}

-- | Creates a message encoder by means of type class `Proto3.Suite.Class.Message`.
--
-- To encode a field instead of a top-level message, use 'Reflection'.
messageReflection :: forall message . Message message => message -> MessageEncoder message
messageReflection :: forall message.
Message message =>
message -> MessageEncoder message
messageReflection message
m = MessageBuilder -> MessageEncoder message
forall a b. Coercible a b => a -> b
coerce (forall a. Message a => FieldNumber -> a -> MessageBuilder
encodeMessage @message (Word64 -> FieldNumber
fieldNumber Word64
1) message
m)
{-# INLINABLE messageReflection #-}

-- | Creates a message encoding by means of type class `Proto3.Suite.Class.Message`.
--
-- Equivalent to @'cacheMessageEncoding' . 'messageReflection'@.
messageCache :: forall message . Message message => message -> MessageEncoding message
messageCache :: forall message.
Message message =>
message -> MessageEncoding message
messageCache message
m = MessageEncoder message -> MessageEncoding message
forall message. MessageEncoder message -> MessageEncoding message
cacheMessageEncoding (message -> MessageEncoder message
forall message.
Message message =>
message -> MessageEncoder message
messageReflection message
m)
{-# INLINABLE messageCache #-}

instance (Message message, Show message) =>
         Show (MessageEncoding message)
  where
    showsPrec :: Int -> MessageEncoding message -> ShowS
showsPrec Int
d (MessageEncoding message -> ByteString
forall message. MessageEncoding message -> ByteString
messageEncodingToByteString -> ByteString
bs) = Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
11) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
      case ByteString -> Either ParseError message
forall a. Message a => ByteString -> Either ParseError a
fromByteString ByteString
bs of
        Left ParseError
_ -> Name -> ShowS
forall a. Show a => a -> ShowS
shows 'unsafeByteStringToMessageEncoding ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Char -> ShowS
showChar Char
' ' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> ByteString -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 ByteString
bs
        Right (message
msg :: message) -> Name -> ShowS
forall a. Show a => a -> ShowS
shows 'messageCache ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Char -> ShowS
showChar Char
' ' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> message -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 message
msg

instance (Message message, Show message) =>
         Show (MessageEncoder message)
  where
    showsPrec :: Int -> MessageEncoder message -> ShowS
showsPrec Int
d (MessageEncoder message -> ByteString
forall message. MessageEncoder message -> ByteString
messageEncoderToByteString -> ByteString
bs) = Bool -> ShowS -> ShowS
showParen (Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
11) (ShowS -> ShowS) -> ShowS -> ShowS
forall a b. (a -> b) -> a -> b
$
      case ByteString -> Either ParseError message
forall a. Message a => ByteString -> Either ParseError a
fromByteString ByteString
bs of
        Left ParseError
_ -> Name -> ShowS
forall a. Show a => a -> ShowS
shows 'unsafeByteStringToMessageEncoder ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Char -> ShowS
showChar Char
' ' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> ByteString -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 ByteString
bs
        Right (message
msg :: message) -> Name -> ShowS
forall a. Show a => a -> ShowS
shows 'messageReflection ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Char -> ShowS
showChar Char
' ' ShowS -> ShowS -> ShowS
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Int -> message -> ShowS
forall a. Show a => Int -> a -> ShowS
showsPrec Int
11 message
msg

instance (Message message, JSONPB.ToJSONPB message) =>
         JSONPB.ToJSONPB (MessageEncoding message)
  where
    toJSONPB :: MessageEncoding message -> Options -> Value
toJSONPB (MessageEncoding message -> ByteString
forall message. MessageEncoding message -> ByteString
messageEncodingToByteString -> ByteString
bs) Options
opts =
      case ByteString -> Either ParseError message
forall a. Message a => ByteString -> Either ParseError a
fromByteString ByteString
bs of
        Left ParseError
_ -> forall a. ToJSONPB a => a -> Options -> Value
JSONPB.toJSONPB @B.ByteString ByteString
bs Options
opts
        Right (message
msg :: message) -> forall a. ToJSONPB a => a -> Options -> Value
JSONPB.toJSONPB @message message
msg Options
opts

    toEncodingPB :: MessageEncoding message -> Options -> Encoding
toEncodingPB (MessageEncoding message -> ByteString
forall message. MessageEncoding message -> ByteString
messageEncodingToByteString -> ByteString
bs) Options
opts =
      case ByteString -> Either ParseError message
forall a. Message a => ByteString -> Either ParseError a
fromByteString ByteString
bs of
        Left ParseError
_ -> forall a. ToJSONPB a => a -> Options -> Encoding
JSONPB.toEncodingPB @B.ByteString ByteString
bs Options
opts
        Right (message
msg :: message) -> forall a. ToJSONPB a => a -> Options -> Encoding
JSONPB.toEncodingPB @message message
msg Options
opts

instance (Message message, JSONPB.ToJSONPB message) =>
         JSONPB.ToJSONPB (MessageEncoder message)
  where
    toJSONPB :: MessageEncoder message -> Options -> Value
toJSONPB = forall a. ToJSONPB a => a -> Options -> Value
JSONPB.toJSONPB @(MessageEncoding message) (MessageEncoding message -> Options -> Value)
-> (MessageEncoder message -> MessageEncoding message)
-> MessageEncoder message
-> Options
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. MessageEncoder message -> MessageEncoding message
forall message. MessageEncoder message -> MessageEncoding message
cacheMessageEncoding
    toEncodingPB :: MessageEncoder message -> Options -> Encoding
toEncodingPB = forall a. ToJSONPB a => a -> Options -> Encoding
JSONPB.toEncodingPB @(MessageEncoding message) (MessageEncoding message -> Options -> Encoding)
-> (MessageEncoder message -> MessageEncoding message)
-> MessageEncoder message
-> Options
-> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. MessageEncoder message -> MessageEncoding message
forall message. MessageEncoder message -> MessageEncoding message
cacheMessageEncoding

instance (Message message, JSONPB.FromJSONPB message) =>
         JSONPB.FromJSONPB (MessageEncoding message)
  where
    parseJSONPB :: Value -> Parser (MessageEncoding message)
parseJSONPB Value
v =
      message -> MessageEncoding message
forall message.
Message message =>
message -> MessageEncoding message
messageCache (message -> MessageEncoding message)
-> Parser message -> Parser (MessageEncoding message)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSONPB a => Value -> Parser a
JSONPB.parseJSONPB @message Value
v Parser (MessageEncoding message)
-> Parser (MessageEncoding message)
-> Parser (MessageEncoding message)
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
      ByteString -> MessageEncoding message
forall message. ByteString -> MessageEncoding message
unsafeByteStringToMessageEncoding (ByteString -> MessageEncoding message)
-> Parser ByteString -> Parser (MessageEncoding message)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSONPB a => Value -> Parser a
JSONPB.parseJSONPB @B.ByteString Value
v

instance (Message message, JSONPB.FromJSONPB message) =>
         JSONPB.FromJSONPB (MessageEncoder message)
  where
    parseJSONPB :: Value -> Parser (MessageEncoder message)
parseJSONPB Value
v =
      message -> MessageEncoder message
forall message.
Message message =>
message -> MessageEncoder message
messageReflection (message -> MessageEncoder message)
-> Parser message -> Parser (MessageEncoder message)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSONPB a => Value -> Parser a
JSONPB.parseJSONPB @message Value
v Parser (MessageEncoder message)
-> Parser (MessageEncoder message)
-> Parser (MessageEncoder message)
forall a. Parser a -> Parser a -> Parser a
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|>
      ByteString -> MessageEncoder message
forall message. ByteString -> MessageEncoder message
unsafeByteStringToMessageEncoder (ByteString -> MessageEncoder message)
-> Parser ByteString -> Parser (MessageEncoder message)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FromJSONPB a => Value -> Parser a
JSONPB.parseJSONPB @B.ByteString Value
v

instance (Message message, JSONPB.ToJSONPB message) =>
         Aeson.ToJSON (MessageEncoding message)
  where
    toJSON :: MessageEncoding message -> Value
toJSON = MessageEncoding message -> Value
forall a. ToJSONPB a => a -> Value
JSONPB.toAesonValue
    toEncoding :: MessageEncoding message -> Encoding
toEncoding = MessageEncoding message -> Encoding
forall a. ToJSONPB a => a -> Encoding
JSONPB.toAesonEncoding

instance (Message message, JSONPB.ToJSONPB message) =>
         Aeson.ToJSON (MessageEncoder message)
  where
    toJSON :: MessageEncoder message -> Value
toJSON = MessageEncoder message -> Value
forall a. ToJSONPB a => a -> Value
JSONPB.toAesonValue
    toEncoding :: MessageEncoder message -> Encoding
toEncoding = MessageEncoder message -> Encoding
forall a. ToJSONPB a => a -> Encoding
JSONPB.toAesonEncoding

instance (Message message, JSONPB.FromJSONPB message) =>
         Aeson.FromJSON (MessageEncoding message)
  where
    parseJSON :: Value -> Parser (MessageEncoding message)
parseJSON = Value -> Parser (MessageEncoding message)
forall a. FromJSONPB a => Value -> Parser a
JSONPB.parseJSONPB

instance (Message message, JSONPB.FromJSONPB message) =>
         Aeson.FromJSON (MessageEncoder message)
  where
    parseJSON :: Value -> Parser (MessageEncoder message)
parseJSON = Value -> Parser (MessageEncoder message)
forall a. FromJSONPB a => Value -> Parser a
JSONPB.parseJSONPB