{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveTraversable #-}
{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ImportQualifiedPost #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE PackageImports #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneKindSignatures #-}
{-# LANGUAGE TemplateHaskellQuotes #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE ViewPatterns #-}

-- | Implementation details of "Proto3.Suite.Form.Encode" that
-- must be kept separate for the sake of @TemplateHaskell@.
module Proto3.Suite.Form.Encode.Core
  ( MessageEncoder(..)
  , messageEncoderToLazyByteString
  , messageEncoderToByteString
  , etaMessageEncoder
  , FieldsEncoder(..)
  , etaFieldsEncoder
  , Distinct
  , DistinctCheck
  , RepeatedNames
  , RepeatedNames1
  , Omits
  , Strip
  , OccupiedName
  , OccupiedOnly
  , OccupiedOnly1
  , fieldsToMessage
  , Occupy
  , Occupy1
  , NameSublist
  , omitted
  , SFieldNumberI
  , KnownFieldNumber
  , fieldNumberVal
  , Field(..)
  , FieldForm(..)
  , PackedFieldForm(..)
  , Wrap(..)
  , Auto(..)
  , instantiatePackableField
  , instantiateStringOrBytesField
  ) where

import Control.Category (Category(..))
import Data.ByteString qualified as B
import Data.ByteString.Lazy qualified as BL
import Data.Coerce (coerce)
import Data.Functor.Identity (Identity(..))
import Data.Kind (Type)
import Data.Traversable (for)
import GHC.Exts (Constraint, Proxy#, TYPE, proxy#)
import GHC.Generics (Generic)
import GHC.TypeLits (ErrorMessage(..), KnownNat, Nat, Symbol, TypeError, natVal')
import "template-haskell" Language.Haskell.TH qualified as TH
import Prelude hiding ((.), id)
import Proto3.Suite.Class (isDefault)
import Proto3.Suite.Form
         (Association, NumberOf, OneOfOf, Packing(..), Cardinality(..),
          CardinalityOf, ProtoType(..), ProtoTypeOf, Wrapper)
import Proto3.Wire.Encode qualified as Encode
import Proto3.Wire.Encode.Repeated (Repeated(..), ToRepeated(..), mapRepeated)
import Proto3.Wire.Types (FieldNumber, fieldNumber)

-- | Annotates 'Encode.MessageBuilder' with the type of protobuf message it encodes.
-- Prefix a tag and length to turn the message into a submessage of a larger message.
newtype MessageEncoder (message :: Type) = UnsafeMessageEncoder
  { forall message. MessageEncoder message -> MessageBuilder
untypedMessageEncoder :: Encode.MessageBuilder }

type role MessageEncoder nominal

-- | Serialize a message (or portion thereof) as a lazy 'BL.ByteString'.
messageEncoderToLazyByteString :: forall message . MessageEncoder message -> BL.ByteString
messageEncoderToLazyByteString :: forall message. MessageEncoder message -> ByteString
messageEncoderToLazyByteString = MessageBuilder -> ByteString
Encode.toLazyByteString (MessageBuilder -> ByteString)
-> (MessageEncoder message -> MessageBuilder)
-> MessageEncoder message
-> 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
. MessageEncoder message -> MessageBuilder
forall message. MessageEncoder message -> MessageBuilder
untypedMessageEncoder

-- | Serialize a message (or portion thereof) as a strict 'B.ByteString'.
--
-- Functionally equivalent to @'BL.toStrict' . 'messageEncoderToLazyByteString'@,
-- and currently even the performance is the same.
messageEncoderToByteString :: forall message . MessageEncoder message -> B.ByteString
messageEncoderToByteString :: forall message. MessageEncoder message -> ByteString
messageEncoderToByteString = ByteString -> ByteString
BL.toStrict (ByteString -> ByteString)
-> (MessageEncoder message -> ByteString)
-> MessageEncoder message
-> 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
. MessageEncoder message -> ByteString
forall message. MessageEncoder message -> ByteString
messageEncoderToLazyByteString

-- | Like 'Encode.etaMessageBuilder' but for 'MessageEncoder'.
etaMessageEncoder :: forall a message . (a -> MessageEncoder message) -> a -> MessageEncoder message
etaMessageEncoder :: forall a message.
(a -> MessageEncoder message) -> a -> MessageEncoder message
etaMessageEncoder = ((a -> MessageBuilder) -> a -> MessageBuilder)
-> (a -> MessageEncoder message) -> a -> MessageEncoder message
forall a b. Coercible a b => a -> b
coerce (forall a. (a -> MessageBuilder) -> a -> MessageBuilder
Encode.etaMessageBuilder @a)

-- | A 'Category' on builders that prefix zero or more fields to a message.
-- Use '.' to accumulate prefixes to create an 'MessageEncoder' for a whole message.
--
-- The first type parameter specifies the type of message being built.
--
-- The second and third type parameters list the names of some subset
-- of the oneofs and non-repeatable non-oneof fields possible within
-- the type of message specified by the first type parameter.  The
-- third type parameter must be a suffix of the second, and limits
-- the oneofs and non-repeatable non-oneof fields that may occur in
-- any builder which follows the contained builder.  The first parameter
-- prefixes the names of the oneofs and non-repeatable non-oneof
-- fields that /might/ be written by the contained builder.
--
-- If a name ends up listed more than once, that will eventually
-- be detected as a compilation error; see type family 'Distinct'.
--
-- Note that this type system permits multiple blocks of the same
-- packed repeated field.  Though that would be less compact than
-- a single block, it is allowed by the protobuf standard.
--
-- See also: 'cacheFieldsEncoder'
newtype FieldsEncoder (message :: Type) (possible :: [Symbol]) (following :: [Symbol]) =
  UnsafeFieldsEncoder { forall message (possible :: [Symbol]) (following :: [Symbol]).
FieldsEncoder message possible following -> MessageBuilder
untypedFieldsEncoder :: Encode.MessageBuilder }

type role FieldsEncoder nominal nominal nominal

-- | The 'Category' on encoders of zero or more fields of a particular
-- type of message whose '.' is '<>' on the contained builders.
--
-- Note that '.' preserves the requirements
-- on the type parameters of 'FieldsEncoder'.
instance Category (FieldsEncoder message)
  where
    id :: forall (a :: [Symbol]). FieldsEncoder message a a
id = MessageBuilder -> FieldsEncoder message a a
forall message (possible :: [Symbol]) (following :: [Symbol]).
MessageBuilder -> FieldsEncoder message possible following
UnsafeFieldsEncoder MessageBuilder
forall a. Monoid a => a
mempty
    FieldsEncoder message b c
f . :: forall (b :: [Symbol]) (c :: [Symbol]) (a :: [Symbol]).
FieldsEncoder message b c
-> FieldsEncoder message a b -> FieldsEncoder message a c
. FieldsEncoder message a b
g = MessageBuilder -> FieldsEncoder message a c
forall message (possible :: [Symbol]) (following :: [Symbol]).
MessageBuilder -> FieldsEncoder message possible following
UnsafeFieldsEncoder (FieldsEncoder message b c -> MessageBuilder
forall message (possible :: [Symbol]) (following :: [Symbol]).
FieldsEncoder message possible following -> MessageBuilder
untypedFieldsEncoder FieldsEncoder message b c
f MessageBuilder -> MessageBuilder -> MessageBuilder
forall a. Semigroup a => a -> a -> a
<> FieldsEncoder message a b -> MessageBuilder
forall message (possible :: [Symbol]) (following :: [Symbol]).
FieldsEncoder message possible following -> MessageBuilder
untypedFieldsEncoder FieldsEncoder message a b
g)

-- | Like 'Encode.etaMessageBuilder' but for 'FieldsEncoder'.
etaFieldsEncoder ::
  forall a message possible following .
  (a -> FieldsEncoder message possible following) ->
  a -> FieldsEncoder message possible following
etaFieldsEncoder :: forall a message (possible :: [Symbol]) (following :: [Symbol]).
(a -> FieldsEncoder message possible following)
-> a -> FieldsEncoder message possible following
etaFieldsEncoder = ((a -> MessageBuilder) -> a -> MessageBuilder)
-> (a -> FieldsEncoder message possible following)
-> a
-> FieldsEncoder message possible following
forall a b. Coercible a b => a -> b
coerce (forall a. (a -> MessageBuilder) -> a -> MessageBuilder
Encode.etaMessageBuilder @a)

-- | Yields a satisfied constraint if the given list of names contains
-- no duplicates after first filtering out the names of repeated fields
-- and replacing the names of @oneof@ fields with their @oneof@ names.
-- Otherwise raises a compilation error mentioning the repeated names.
type Distinct (message :: Type) (names :: [Symbol]) =
  DistinctCheck message (RepeatedNames (OccupiedOnly message names))

-- | Reports nonempty output of 'RepeatedNames' as applied to the result of 'OccupiedOnly'.
--
-- This type family is an implementation detail of 'Distinct'
-- that is subject to change, and is exported only to assist
-- in understanding of compilation errors.
type family DistinctCheck (message :: Type) (repeated :: [k]) :: Constraint
  where
    DistinctCheck _ '[] = ()
    DistinctCheck message repeated = TypeError
      ( 'ShowType message ':<>: 'Text " forbids repetition of:"
        ':$$: 'ShowType repeated )

-- | Given a list of names, returns the non-repeating list
-- of names that occur more than once in the given list.
--
-- This type family is an implementation detail of 'Distinct'
-- that is subject to change, and is exported only to assist
-- in understanding of compilation errors.
type family RepeatedNames (names :: [k]) :: [k]
  where
    RepeatedNames (name ': names) = RepeatedNames1 name names (Omits name names)
    RepeatedNames '[] = '[]

-- | Helps to implement 'RepeatedNames'.
--
-- This type family is an implementation detail of 'Distinct'
-- that is subject to change, and is exported only to assist
-- in understanding of compilation errors.
type family RepeatedNames1 (name :: k) (names :: [k]) (omits :: Bool) :: [k]
  where
    RepeatedNames1 _ names 'True = RepeatedNames names
    RepeatedNames1 name names 'False = name ': RepeatedNames (Strip name names)

-- | Is the given name absent from the given list of names?
--
-- This type family is an implementation detail of 'RepeatedNames'
-- that is subject to change, and is exported only to assist
-- in understanding of compilation errors.
type family Omits (name :: k) (names :: [k]) :: Bool
  where
    Omits name (name ': names) = 'False
    Omits name (_ ': names) = Omits name names
    Omits name '[] = 'True

-- | Strips all occurrences of the given name, leaving behind all other name occurrences.
--
-- This type family is an implementation detail of 'RepeatedNames'
-- that is subject to change, and is exported only to assist
-- in understanding of compilation errors.
type family Strip (name :: k) (names :: [k]) :: [k]
  where
    Strip name (name ': names) = Strip name names
    Strip name (other ': names) = other ': Strip name names
    Strip name '[] = '[]

-- | Yields the name of the containing @oneof@ if there is one,
-- and otherwise returns the field name as is.  This type family can
-- help prevent two fields of the same @oneof@ from being emitted.
--
-- This type family is an implementation detail of other type families
-- that is subject to change, and is exported only to assist
-- in understanding of compilation errors.
type OccupiedName (message :: Type) (name :: Symbol) = OccupiedName1 name (OneOfOf message name)

-- | This type family is an implementation detail of 'OccupiedName'
-- that is subject to change, and is exported only to assist
-- in understanding of compilation errors.
type family OccupiedName1 (name :: Symbol) (oneof :: Symbol) :: Symbol
  where
    OccupiedName1 name "" = name
    OccupiedName1 _ oneof = oneof

-- | Filters out the repeated field names and replaces @oneof@ fields with their @oneof@ names.
--
-- We do this in case 'omitted' is used to introduce the names of repeated fields
-- or fields that are contained within @oneof@s; see the explanatory comments there.
--
-- This type family is an implementation detail of 'Distinct'
-- that is subject to change, and is exported only to assist
-- in understanding of compilation errors.
type family OccupiedOnly (message :: Type) (names :: [Symbol]) :: [Symbol]
  where
    OccupiedOnly message (name ': names) =
      OccupiedOnly1 message name names (CardinalityOf message name)
    OccupiedOnly _ '[] =
      '[]

-- | Helps to implement 'OccupiedOnly'.
--
-- This type family is an implementation detail of 'Distinct'
-- that is subject to change, and is exported only to assist
-- in understanding of compilation errors.
type family OccupiedOnly1 (message :: Type) (name :: Symbol) (names :: [Symbol])
                          (cardinality :: Cardinality) :: [Symbol]
  where
    OccupiedOnly1 message name names 'Implicit =
      name ': OccupiedOnly message names
    OccupiedOnly1 message name names 'Optional =
      OccupiedName message name ': OccupiedOnly message names
    OccupiedOnly1 message name names ('Repeated _) =
      OccupiedOnly message names

-- | Relabels a prefix of fields of a message as an encoding for
-- the message as a whole (though without any tag or length that
-- would make it a submessage).
fieldsToMessage ::
  forall (message :: Type) (names :: [Symbol]) .
  Distinct message names =>
  FieldsEncoder message '[] names ->
  MessageEncoder message
fieldsToMessage :: forall message (names :: [Symbol]).
Distinct message names =>
FieldsEncoder message '[] names -> MessageEncoder message
fieldsToMessage = MessageBuilder -> MessageEncoder message
forall message. MessageBuilder -> MessageEncoder message
UnsafeMessageEncoder (MessageBuilder -> MessageEncoder message)
-> (FieldsEncoder message '[] names -> MessageBuilder)
-> FieldsEncoder message '[] names
-> 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
. FieldsEncoder message '[] names -> MessageBuilder
forall message (possible :: [Symbol]) (following :: [Symbol]).
FieldsEncoder message possible following -> MessageBuilder
untypedFieldsEncoder

-- | Among the names of the given message, prefixes
-- the given name with the following exceptions:
--
-- * Names of repeatable fields are not prefixed;
--   there is no need to avoid their repetition.
--
-- * When a field of a @oneof@ is named, the name
--   of the entire @oneof@ is prefixed in order to
--   prevent further emission of any of its fields.
--
type Occupy (message :: Type) (name :: Symbol) (names :: [Symbol]) =
  Occupy1 message name names (CardinalityOf message name)

-- | Helps to implement 'Occupy'.
--
-- This type family is an implementation detail of 'Occupy'
-- that is subject to change, and is exported only to assist
-- in understanding of compilation errors.
type family Occupy1 (message :: Type) (name :: Symbol) (names :: [Symbol])
                    (cardinality :: Cardinality) :: [Symbol]
  where
    Occupy1 message name names 'Implicit = name ': names
    Occupy1 message name names 'Optional = OccupiedName message name ': names
    Occupy1 message name names ('Repeated _) = names

-- | The constraint that 'moreNames' is 'names', but possibly with additional
-- names inserted.  For simplicity, reordering is not currently allowed.
type family NameSublist (names :: [Symbol]) (moreNames :: [Symbol]) :: Constraint
  where
    NameSublist '[] _ = (() :: Constraint)
    NameSublist (n ': ns) (n ': ms) = NameSublist ns ms
    NameSublist ns (_ ': ms) = NameSublist ns ms
    NameSublist (n ': _) '[] = TypeError
      ( 'Text "NameSublist: name disappeared: " ':<>: 'ShowType n )

-- | Uses an empty encoding for the @oneof@s and non-@oneof@ message fields
-- that appear in the final type parameter of 'FieldsEncoder' but not the
-- previous type parameter, thereby implicitly emitting their default values.
--
-- This function is not always required, but becomes necessary when
-- there are two code paths, one of which may write non-repeatable
-- fields and one of which leaves some implicitly defaulted.  This
-- function reconciles the types of the two code paths.
--
-- This function should not be used to introduce the name of a field
-- that is repeated or belongs to @oneof@, because doing so could
-- confuse the reader.  But such misuse is unlikely to be accidental,
-- and the 'Distinct' constraint compensates by ignoring repeated
-- fields and replacing @oneof@ fields with their @oneof@ names.
omitted ::
  forall (message :: Type) (names :: [Symbol]) (moreNames :: [Symbol]) .
  NameSublist names moreNames =>
  FieldsEncoder message names moreNames
omitted :: forall message (names :: [Symbol]) (moreNames :: [Symbol]).
NameSublist names moreNames =>
FieldsEncoder message names moreNames
omitted = MessageBuilder -> FieldsEncoder message names moreNames
forall message (possible :: [Symbol]) (following :: [Symbol]).
MessageBuilder -> FieldsEncoder message possible following
UnsafeFieldsEncoder MessageBuilder
forall a. Monoid a => a
mempty

-- | Singleton field number type.
newtype SFieldNumber (fieldNumber :: Nat)
  = UnsafeSFieldNumber { forall (fieldNumber :: Nat).
SFieldNumber fieldNumber -> FieldNumber
untypedSFieldNumber :: FieldNumber }

-- | Provides the term-level value of the given field number type.
class SFieldNumberI (fieldNumber :: Nat)
  where
    -- | Provides the term-level value in the form of a value of the associated singleton type.
    sFieldNumber :: SFieldNumber fieldNumber

instance KnownNat fieldNumber =>
         SFieldNumberI fieldNumber
  where
    sFieldNumber :: SFieldNumber fieldNumber
sFieldNumber =
      FieldNumber -> SFieldNumber fieldNumber
forall (fieldNumber :: Nat).
FieldNumber -> SFieldNumber fieldNumber
UnsafeSFieldNumber (Word64 -> FieldNumber
fieldNumber (Integer -> Word64
forall a. Num a => Integer -> a
fromInteger (Proxy# fieldNumber -> Integer
forall (n :: Nat). KnownNat n => Proxy# n -> Integer
natVal' (Proxy# fieldNumber
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# fieldNumber))))
    {-# INLINABLE sFieldNumber #-}  -- So that it can specialize to particular field number types.

-- | Provides the (term-level) field number of the field
-- having the specified message type and field name.
type KnownFieldNumber message name = SFieldNumberI (NumberOf message name)

-- | Provides the (term-level) field number of the field having
-- the message type and field name specified by the type arguments.
fieldNumberVal :: forall message name . KnownFieldNumber message name => FieldNumber
fieldNumberVal :: forall message (name :: Symbol).
KnownFieldNumber message name =>
FieldNumber
fieldNumberVal = SFieldNumber (NumberOf message name) -> FieldNumber
forall (fieldNumber :: Nat).
SFieldNumber fieldNumber -> FieldNumber
untypedSFieldNumber (forall (fieldNumber :: Nat).
SFieldNumberI fieldNumber =>
SFieldNumber fieldNumber
sFieldNumber @(NumberOf message name))
{-# INLINE fieldNumberVal #-}

-- | Provides a way to encode a field with the given name from a given type.
-- That name is interpreted in the context of a given type of message.
--
-- More than one argument type may be supported for any given field;
-- see further discussion in the comments for 'FieldForm', to which
-- this type class delegates after determining the cardinality and
-- protobuf type of the field in question.
type Field :: Symbol -> forall {r} . TYPE r -> Type -> Constraint
class Field name a message
  where
    -- | Encodes the named field from the given value.
    --
    -- If the field is neither @optional@, nor @repeated@, nor part of a @oneof@, then
    -- its default value is represented implicitly--that is, it encodes to zero octets.
    --
    -- In other cases the argument is often a container.  In particular, when using
    -- this method with @optional@ fields and fields within a @oneof@, the argument
    -- type typically involves 'Maybe' or (if the field is always "set") 'Identity'.
    --
    -- Use @TypeApplications@ to specify the field name as the first type parameter.
    --
    -- The second type parameter may also be ambiguous.  For example, the argument
    -- expression may be an integer literal or (when using @OverloadedStrings@)
    -- a string literal.  @TypeApplications@ would resolve the ambiguity, but you
    -- may prefer the 'Auto' wrapper or special-case helper functions such as:
    -- `Proto3.Suite.Form.Encode.message`,
    -- `Proto3.Suite.Form.Encode.associations`.
    --
    -- See also 'fieldForm'.
    field :: forall names . a -> FieldsEncoder message names (Occupy message name names)

instance forall (name :: Symbol)
#if defined(__GLASGOW_HASKELL__) && 904 <= __GLASGOW_HASKELL__
                r (a :: TYPE r)
#else
                (a :: Type)
                  -- Regarding the call to @coerce@, GHC 9.2.8 would say:
                  -- "Cannot use function with levity-polymorphic arguments".
                  -- So we just drop support for unlifted arguments until GHC 9.4.
#endif
                (message :: Type) .
         ( KnownFieldNumber message name
         , FieldForm (CardinalityOf message name) (ProtoTypeOf message name) a
         ) =>
         Field name a message
  where
    field :: forall names . a -> FieldsEncoder message names (Occupy message name names)
    field :: forall (names :: [Symbol]).
a -> FieldsEncoder message names (Occupy message name names)
field = forall a b. Coercible a b => a -> b
forall a b. Coercible a b => a -> b
coerce
      @(a -> Encode.MessageBuilder)
      @(a -> FieldsEncoder message names (Occupy message name names))
      (forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm @(CardinalityOf message name) @(ProtoTypeOf message name) @a
                 Proxy# (CardinalityOf message name)
forall {k} (a :: k). Proxy# a
proxy# Proxy# (ProtoTypeOf message name)
forall {k} (a :: k). Proxy# a
proxy# (forall message (name :: Symbol).
KnownFieldNumber message name =>
FieldNumber
fieldNumberVal @message @name))
      -- Implementation Note: Using the newtype constructor would require us
      -- to bind a variable of kind @TYPE r@, which is runtime-polymorphic.
      -- By using a coercion we avoid runtime polymorphism restrictions.
    {-# INLINE field #-}

-- | Implements 'Field' for all fields having the specified cardinality,
-- protobuf type, and type of argument to be encoded within that field.
--
-- Argument Type:
--
-- For any given cardinality and protobuf type there may be multiple
-- instances of this class for different types of argument.  For example,
-- a field of protobuf type @sint64@ may be encoded from any of the Haskell
-- types `Data.Int.Int8`, `Data.Int.Word8`, `Data.Int.Int16`, `Data.Int.Word16`,
-- `Data.Int.Int32`, `Data.Int.Word32`, or `Data.Int.Int64`.  Note that this
-- library does /not/ provide an instance for `Data.Int.Word64` because its
-- values greater than or equal to @2 ^ 63@ cannot be represented by @sint64@.
--
-- As another example, for fields of submessage type @m@ there
-- are type class instances for both @'MessageEncoder' m@
-- and @`Proto3.Suite.Form.Encode.MessageEncoding` m@
-- (wrapped in a suitable container if repeated or outside of a @oneof@).
--
-- Arguments for optional fields are often expressed using 'Maybe',
-- and arguments for repeated fields are often expressed in using
-- 'Forward', 'Reverse', and 'Reverse'--the choice is up to the user.
--
-- Of course, if you add instances of this type class then please be
-- sure to consider how they might overlap with existing instances,
-- and try to avoid overly broad instances that might cause ambiguity.
--
-- However, this library does provide some general instances:
--
--   * An instance for 'Optional' with 'Maybe' that delegates to
--     the corresponding instance for 'Optional' with 'Identity'.
--
--   * An instance for @'Repeated' 'Unpacked'@ that delegates to
--     the corresponding instance for 'Optional' with 'Identity'.
--
--   * An instance for @'Repeated' 'Packed'@ that delegates to 'PackedFieldForm'.
--
-- Design Note:
--
-- Importantly, the type parameters of this type class do not mention
-- the containing message type, field name, or field number, thus
-- allowing it to be broadly applicable to all containing message types.
--
-- Furthermore, type class 'Field' has a general-purpose definition
-- that need not be specialized for particular message types: one that
-- makes use of 'KnownFieldNumber', 'ProtoTypeOf', and this type class
-- (though in order to simplify usage, 'Field' is a full type class,
-- not a mere constraint alias with a related function).
--
-- In this way the only message-specific instances are of type classes
-- defined in "Proto3.Suite.Form", which declare message format without
-- specifying any policy regarding how to efficiently encode or which
-- Haskell types may be encoded.
type FieldForm :: Cardinality -> ProtoType -> forall {r} . TYPE r -> Constraint
class FieldForm cardinality protoType a
  where
    -- | Encodes a message field with the
    -- given number from the given value.
    --
    -- If the field is neither @repeated@, nor @optional@, nor
    -- part of a @oneof@, then its default value is represented
    -- implicitly--that is, it encodes to zero octets.
    --
    -- If you apply this method to a polymorphic expression,
    -- such as a literal value, then you may need to choose
    -- a particular type with @TypeApplications@ or @::@.
    fieldForm :: Proxy# cardinality -> Proxy# protoType -> FieldNumber -> a -> Encode.MessageBuilder

instance FieldForm 'Optional protoType (Identity a) =>
         FieldForm 'Optional protoType (Maybe a)
  where
    fieldForm :: Proxy# 'Optional
-> Proxy# protoType -> FieldNumber -> Maybe a -> MessageBuilder
fieldForm Proxy# 'Optional
rep Proxy# protoType
ty !FieldNumber
fn = (Maybe a -> MessageBuilder) -> Maybe a -> MessageBuilder
forall a. (a -> MessageBuilder) -> a -> MessageBuilder
Encode.etaMessageBuilder ((Maybe a -> MessageBuilder) -> Maybe a -> MessageBuilder)
-> (Maybe a -> MessageBuilder) -> Maybe a -> MessageBuilder
forall a b. (a -> b) -> a -> b
$
      forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap @Maybe (Proxy# 'Optional
-> Proxy# protoType -> FieldNumber -> Identity a -> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm Proxy# 'Optional
rep Proxy# protoType
ty FieldNumber
fn (Identity a -> MessageBuilder)
-> (a -> Identity a) -> a -> 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
. a -> Identity a
forall a. a -> Identity a
Identity)
    {-# INLINE fieldForm #-}

instance ( ToRepeated c e
         , FieldForm 'Optional protoType (Identity e)
         ) =>
         FieldForm ('Repeated 'Unpacked) protoType c
  where
    fieldForm :: Proxy# ('Repeated 'Unpacked)
-> Proxy# protoType -> FieldNumber -> c -> MessageBuilder
fieldForm Proxy# ('Repeated 'Unpacked)
_ Proxy# protoType
ty !FieldNumber
fn = (c -> MessageBuilder) -> c -> MessageBuilder
forall a. (a -> MessageBuilder) -> a -> MessageBuilder
Encode.etaMessageBuilder ((c -> MessageBuilder) -> c -> MessageBuilder)
-> (c -> MessageBuilder) -> c -> MessageBuilder
forall a b. (a -> b) -> a -> b
$
      Repeated MessageBuilder -> MessageBuilder
forall c. ToRepeated c MessageBuilder => c -> MessageBuilder
Encode.repeatedMessageBuilder (Repeated MessageBuilder -> MessageBuilder)
-> (c -> Repeated MessageBuilder) -> c -> 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
.
      (e -> MessageBuilder) -> c -> Repeated MessageBuilder
forall c e a. ToRepeated c e => (e -> a) -> c -> Repeated a
mapRepeated (Proxy# 'Optional
-> Proxy# protoType -> FieldNumber -> Identity e -> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm (Proxy# 'Optional
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# 'Optional) Proxy# protoType
ty FieldNumber
fn (Identity e -> MessageBuilder)
-> (e -> Identity e) -> e -> 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
. e -> Identity e
forall a. a -> Identity a
Identity)
    {-# INLINE fieldForm #-}

-- | Ignores the preference for packed format when there is exactly one element,
-- and therefore packed format would be more verbose.  (Conforming parsers must
-- accept both packed and unpacked primitives regardless of packing preference.)
instance ( ToRepeated c e
         , PackedFieldForm protoType e
         , FieldForm 'Optional protoType (Identity e)
         ) =>
         FieldForm ('Repeated 'Packed) protoType c
  where
    fieldForm :: Proxy# ('Repeated 'Packed)
-> Proxy# protoType -> FieldNumber -> c -> MessageBuilder
fieldForm Proxy# ('Repeated 'Packed)
_ Proxy# protoType
ty !FieldNumber
fn (c -> Repeated e
forall c e. ToRepeated c e => c -> Repeated e
toRepeated -> !xs :: Repeated e
xs@(ReverseRepeated Maybe Int
prediction FoldR e
reversed)) =
        case Maybe Int
prediction of
          Just Int
count
            | Int
2 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
count -> Proxy# protoType -> FieldNumber -> Repeated e -> MessageBuilder
forall (protoType :: ProtoType) a.
PackedFieldForm protoType a =>
Proxy# protoType -> FieldNumber -> Repeated a -> MessageBuilder
packedFieldForm Proxy# protoType
ty FieldNumber
fn Repeated e
xs  -- multiple packed elements
            | Bool
otherwise -> Proxy# ('Repeated 'Unpacked)
-> Proxy# protoType -> FieldNumber -> Repeated e -> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm (Proxy# ('Repeated 'Unpacked)
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# ('Repeated 'Unpacked)) Proxy# protoType
ty FieldNumber
fn Repeated e
xs  -- 0 or 1
          Maybe Int
Nothing -> case (e -> Singleton e -> Singleton e)
-> Singleton e -> FoldR e -> Singleton e
forall a b. (a -> b -> b) -> b -> FoldR a -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr e -> Singleton e -> Singleton e
forall a. a -> Singleton a -> Singleton a
singletonOp Singleton e
forall a. Singleton a
Empty FoldR e
reversed of
            Singleton e
Empty -> MessageBuilder
forall a. Monoid a => a
mempty  -- 0 elements can be expressed implicitly
            Singleton e
x -> Proxy# 'Optional
-> Proxy# protoType -> FieldNumber -> Identity e -> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm (Proxy# 'Optional
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# 'Optional) Proxy# protoType
ty FieldNumber
fn (e -> Identity e
forall a. a -> Identity a
Identity e
x) -- unpacked
            Singleton e
Multiple -> Proxy# protoType -> FieldNumber -> Repeated e -> MessageBuilder
forall (protoType :: ProtoType) a.
PackedFieldForm protoType a =>
Proxy# protoType -> FieldNumber -> Repeated a -> MessageBuilder
packedFieldForm Proxy# protoType
ty FieldNumber
fn Repeated e
xs  -- multiple packed elements
      where
        singletonOp :: a -> Singleton a -> Singleton a
        singletonOp :: forall a. a -> Singleton a -> Singleton a
singletonOp a
x Singleton a
Empty = a -> Singleton a
forall a. a -> Singleton a
Singleton a
x
        singletonOp a
_ Singleton a
_ = Singleton a
forall a. Singleton a
Multiple
    {-# INLINE fieldForm #-}

data Singleton a = Empty | Singleton a | Multiple

instance FieldForm 'Optional ('Message inner) (Identity (MessageEncoder inner))
  where
    fieldForm :: Proxy# 'Optional
-> Proxy# ('Message inner)
-> FieldNumber
-> Identity (MessageEncoder inner)
-> MessageBuilder
fieldForm Proxy# 'Optional
_ Proxy# ('Message inner)
_ !FieldNumber
fn (Identity MessageEncoder inner
e) = FieldNumber -> MessageBuilder -> MessageBuilder
Encode.embedded FieldNumber
fn (MessageEncoder inner -> MessageBuilder
forall message. MessageEncoder message -> MessageBuilder
untypedMessageEncoder MessageEncoder 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 (MessageEncoder (Association key value)))
  where
    fieldForm :: Proxy# 'Optional
-> Proxy# ('Map key value)
-> FieldNumber
-> Identity (MessageEncoder (Association key value))
-> MessageBuilder
fieldForm Proxy# 'Optional
_ Proxy# ('Map key value)
_ !FieldNumber
fn (Identity MessageEncoder (Association key value)
a) = FieldNumber -> MessageBuilder -> MessageBuilder
Encode.embedded FieldNumber
fn (MessageEncoder (Association key value) -> MessageBuilder
forall message. MessageEncoder message -> MessageBuilder
untypedMessageEncoder MessageEncoder (Association key value)
a)
    {-# INLINE fieldForm #-}

-- | 'FieldForm' delegates to this type class when encoding
-- packed repeated fields containing two or more elements.
type PackedFieldForm :: ProtoType -> forall {r} . TYPE r -> Constraint
class PackedFieldForm protoType a
  where
    -- | 'fieldForm' delegates to this method when encoding
    -- packed repeated fields containing two or more elements.
    packedFieldForm :: Proxy# protoType -> FieldNumber -> Repeated a -> Encode.MessageBuilder

-- | Indicates that a wrapper type should be emitted by encoding its field,
-- as opposed to by supplying 'MessageEncoder' for the wrapper as a whole.
--
-- We also provide specific instances of 'FieldForm' that avoid the need
-- to 'Wrap' certain commonly-used argument types, such as 'Int32'.
--
-- See also 'Wrapper'.
newtype Wrap (a :: Type) = Wrap { forall a. Wrap a -> a
unwrap :: a }
  deriving stock ((forall m. Monoid m => Wrap m -> m)
-> (forall m a. Monoid m => (a -> m) -> Wrap a -> m)
-> (forall m a. Monoid m => (a -> m) -> Wrap a -> m)
-> (forall a b. (a -> b -> b) -> b -> Wrap a -> b)
-> (forall a b. (a -> b -> b) -> b -> Wrap a -> b)
-> (forall b a. (b -> a -> b) -> b -> Wrap a -> b)
-> (forall b a. (b -> a -> b) -> b -> Wrap a -> b)
-> (forall a. (a -> a -> a) -> Wrap a -> a)
-> (forall a. (a -> a -> a) -> Wrap a -> a)
-> (forall a. Wrap a -> [a])
-> (forall a. Wrap a -> Bool)
-> (forall a. Wrap a -> Int)
-> (forall a. Eq a => a -> Wrap a -> Bool)
-> (forall a. Ord a => Wrap a -> a)
-> (forall a. Ord a => Wrap a -> a)
-> (forall a. Num a => Wrap a -> a)
-> (forall a. Num a => Wrap a -> a)
-> Foldable Wrap
forall a. Eq a => a -> Wrap a -> Bool
forall a. Num a => Wrap a -> a
forall a. Ord a => Wrap a -> a
forall m. Monoid m => Wrap m -> m
forall a. Wrap a -> Bool
forall a. Wrap a -> Int
forall a. Wrap a -> [a]
forall a. (a -> a -> a) -> Wrap a -> a
forall m a. Monoid m => (a -> m) -> Wrap a -> m
forall b a. (b -> a -> b) -> b -> Wrap a -> b
forall a b. (a -> b -> b) -> b -> Wrap a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => Wrap m -> m
fold :: forall m. Monoid m => Wrap m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Wrap a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Wrap a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Wrap a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Wrap a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> Wrap a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Wrap a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Wrap a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Wrap a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Wrap a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Wrap a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Wrap a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Wrap a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> Wrap a -> a
foldr1 :: forall a. (a -> a -> a) -> Wrap a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Wrap a -> a
foldl1 :: forall a. (a -> a -> a) -> Wrap a -> a
$ctoList :: forall a. Wrap a -> [a]
toList :: forall a. Wrap a -> [a]
$cnull :: forall a. Wrap a -> Bool
null :: forall a. Wrap a -> Bool
$clength :: forall a. Wrap a -> Int
length :: forall a. Wrap a -> Int
$celem :: forall a. Eq a => a -> Wrap a -> Bool
elem :: forall a. Eq a => a -> Wrap a -> Bool
$cmaximum :: forall a. Ord a => Wrap a -> a
maximum :: forall a. Ord a => Wrap a -> a
$cminimum :: forall a. Ord a => Wrap a -> a
minimum :: forall a. Ord a => Wrap a -> a
$csum :: forall a. Num a => Wrap a -> a
sum :: forall a. Num a => Wrap a -> a
$cproduct :: forall a. Num a => Wrap a -> a
product :: forall a. Num a => Wrap a -> a
Foldable, (forall a b. (a -> b) -> Wrap a -> Wrap b)
-> (forall a b. a -> Wrap b -> Wrap a) -> Functor Wrap
forall a b. a -> Wrap b -> Wrap a
forall a b. (a -> b) -> Wrap a -> Wrap b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Wrap a -> Wrap b
fmap :: forall a b. (a -> b) -> Wrap a -> Wrap b
$c<$ :: forall a b. a -> Wrap b -> Wrap a
<$ :: forall a b. a -> Wrap b -> Wrap a
Functor, (forall x. Wrap a -> Rep (Wrap a) x)
-> (forall x. Rep (Wrap a) x -> Wrap a) -> Generic (Wrap a)
forall x. Rep (Wrap a) x -> Wrap a
forall x. Wrap a -> Rep (Wrap a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Wrap a) x -> Wrap a
forall a x. Wrap a -> Rep (Wrap a) x
$cfrom :: forall a x. Wrap a -> Rep (Wrap a) x
from :: forall x. Wrap a -> Rep (Wrap a) x
$cto :: forall a x. Rep (Wrap a) x -> Wrap a
to :: forall x. Rep (Wrap a) x -> Wrap a
Generic, Functor Wrap
Foldable Wrap
(Functor Wrap, Foldable Wrap) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Wrap a -> f (Wrap b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Wrap (f a) -> f (Wrap a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Wrap a -> m (Wrap b))
-> (forall (m :: * -> *) a. Monad m => Wrap (m a) -> m (Wrap a))
-> Traversable Wrap
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Wrap (m a) -> m (Wrap a)
forall (f :: * -> *) a. Applicative f => Wrap (f a) -> f (Wrap a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Wrap a -> m (Wrap b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Wrap a -> f (Wrap b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Wrap a -> f (Wrap b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Wrap a -> f (Wrap b)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Wrap (f a) -> f (Wrap a)
sequenceA :: forall (f :: * -> *) a. Applicative f => Wrap (f a) -> f (Wrap a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Wrap a -> m (Wrap b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Wrap a -> m (Wrap b)
$csequence :: forall (m :: * -> *) a. Monad m => Wrap (m a) -> m (Wrap a)
sequence :: forall (m :: * -> *) a. Monad m => Wrap (m a) -> m (Wrap a)
Traversable)
  deriving newtype (Wrap a
Wrap a -> Wrap a -> Bounded (Wrap a)
forall a. a -> a -> Bounded a
forall a. Bounded a => Wrap a
$cminBound :: forall a. Bounded a => Wrap a
minBound :: Wrap a
$cmaxBound :: forall a. Bounded a => Wrap a
maxBound :: Wrap a
Bounded, Int -> Wrap a
Wrap a -> Int
Wrap a -> [Wrap a]
Wrap a -> Wrap a
Wrap a -> Wrap a -> [Wrap a]
Wrap a -> Wrap a -> Wrap a -> [Wrap a]
(Wrap a -> Wrap a)
-> (Wrap a -> Wrap a)
-> (Int -> Wrap a)
-> (Wrap a -> Int)
-> (Wrap a -> [Wrap a])
-> (Wrap a -> Wrap a -> [Wrap a])
-> (Wrap a -> Wrap a -> [Wrap a])
-> (Wrap a -> Wrap a -> Wrap a -> [Wrap a])
-> Enum (Wrap a)
forall a. Enum a => Int -> Wrap a
forall a. Enum a => Wrap a -> Int
forall a. Enum a => Wrap a -> [Wrap a]
forall a. Enum a => Wrap a -> Wrap a
forall a. Enum a => Wrap a -> Wrap a -> [Wrap a]
forall a. Enum a => Wrap a -> Wrap a -> Wrap a -> [Wrap a]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: forall a. Enum a => Wrap a -> Wrap a
succ :: Wrap a -> Wrap a
$cpred :: forall a. Enum a => Wrap a -> Wrap a
pred :: Wrap a -> Wrap a
$ctoEnum :: forall a. Enum a => Int -> Wrap a
toEnum :: Int -> Wrap a
$cfromEnum :: forall a. Enum a => Wrap a -> Int
fromEnum :: Wrap a -> Int
$cenumFrom :: forall a. Enum a => Wrap a -> [Wrap a]
enumFrom :: Wrap a -> [Wrap a]
$cenumFromThen :: forall a. Enum a => Wrap a -> Wrap a -> [Wrap a]
enumFromThen :: Wrap a -> Wrap a -> [Wrap a]
$cenumFromTo :: forall a. Enum a => Wrap a -> Wrap a -> [Wrap a]
enumFromTo :: Wrap a -> Wrap a -> [Wrap a]
$cenumFromThenTo :: forall a. Enum a => Wrap a -> Wrap a -> Wrap a -> [Wrap a]
enumFromThenTo :: Wrap a -> Wrap a -> Wrap a -> [Wrap a]
Enum, Wrap a -> Wrap a -> Bool
(Wrap a -> Wrap a -> Bool)
-> (Wrap a -> Wrap a -> Bool) -> Eq (Wrap a)
forall a. Eq a => Wrap a -> Wrap a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Wrap a -> Wrap a -> Bool
== :: Wrap a -> Wrap a -> Bool
$c/= :: forall a. Eq a => Wrap a -> Wrap a -> Bool
/= :: Wrap a -> Wrap a -> Bool
Eq, Num (Wrap a)
Num (Wrap a) =>
(Wrap a -> Wrap a -> Wrap a)
-> (Wrap a -> Wrap a)
-> (Rational -> Wrap a)
-> Fractional (Wrap a)
Rational -> Wrap a
Wrap a -> Wrap a
Wrap a -> Wrap a -> Wrap a
forall a. Fractional a => Num (Wrap a)
forall a. Fractional a => Rational -> Wrap a
forall a. Fractional a => Wrap a -> Wrap a
forall a. Fractional a => Wrap a -> Wrap a -> Wrap a
forall a.
Num a =>
(a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
$c/ :: forall a. Fractional a => Wrap a -> Wrap a -> Wrap a
/ :: Wrap a -> Wrap a -> Wrap a
$crecip :: forall a. Fractional a => Wrap a -> Wrap a
recip :: Wrap a -> Wrap a
$cfromRational :: forall a. Fractional a => Rational -> Wrap a
fromRational :: Rational -> Wrap a
Fractional, Enum (Wrap a)
Real (Wrap a)
(Real (Wrap a), Enum (Wrap a)) =>
(Wrap a -> Wrap a -> Wrap a)
-> (Wrap a -> Wrap a -> Wrap a)
-> (Wrap a -> Wrap a -> Wrap a)
-> (Wrap a -> Wrap a -> Wrap a)
-> (Wrap a -> Wrap a -> (Wrap a, Wrap a))
-> (Wrap a -> Wrap a -> (Wrap a, Wrap a))
-> (Wrap a -> Integer)
-> Integral (Wrap a)
Wrap a -> Integer
Wrap a -> Wrap a -> (Wrap a, Wrap a)
Wrap a -> Wrap a -> Wrap a
forall a. Integral a => Enum (Wrap a)
forall a. Integral a => Real (Wrap a)
forall a. Integral a => Wrap a -> Integer
forall a. Integral a => Wrap a -> Wrap a -> (Wrap a, Wrap a)
forall a. Integral a => Wrap a -> Wrap a -> Wrap a
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: forall a. Integral a => Wrap a -> Wrap a -> Wrap a
quot :: Wrap a -> Wrap a -> Wrap a
$crem :: forall a. Integral a => Wrap a -> Wrap a -> Wrap a
rem :: Wrap a -> Wrap a -> Wrap a
$cdiv :: forall a. Integral a => Wrap a -> Wrap a -> Wrap a
div :: Wrap a -> Wrap a -> Wrap a
$cmod :: forall a. Integral a => Wrap a -> Wrap a -> Wrap a
mod :: Wrap a -> Wrap a -> Wrap a
$cquotRem :: forall a. Integral a => Wrap a -> Wrap a -> (Wrap a, Wrap a)
quotRem :: Wrap a -> Wrap a -> (Wrap a, Wrap a)
$cdivMod :: forall a. Integral a => Wrap a -> Wrap a -> (Wrap a, Wrap a)
divMod :: Wrap a -> Wrap a -> (Wrap a, Wrap a)
$ctoInteger :: forall a. Integral a => Wrap a -> Integer
toInteger :: Wrap a -> Integer
Integral, Eq (Wrap a)
Eq (Wrap a) =>
(Wrap a -> Wrap a -> Ordering)
-> (Wrap a -> Wrap a -> Bool)
-> (Wrap a -> Wrap a -> Bool)
-> (Wrap a -> Wrap a -> Bool)
-> (Wrap a -> Wrap a -> Bool)
-> (Wrap a -> Wrap a -> Wrap a)
-> (Wrap a -> Wrap a -> Wrap a)
-> Ord (Wrap a)
Wrap a -> Wrap a -> Bool
Wrap a -> Wrap a -> Ordering
Wrap a -> Wrap a -> Wrap a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Wrap a)
forall a. Ord a => Wrap a -> Wrap a -> Bool
forall a. Ord a => Wrap a -> Wrap a -> Ordering
forall a. Ord a => Wrap a -> Wrap a -> Wrap a
$ccompare :: forall a. Ord a => Wrap a -> Wrap a -> Ordering
compare :: Wrap a -> Wrap a -> Ordering
$c< :: forall a. Ord a => Wrap a -> Wrap a -> Bool
< :: Wrap a -> Wrap a -> Bool
$c<= :: forall a. Ord a => Wrap a -> Wrap a -> Bool
<= :: Wrap a -> Wrap a -> Bool
$c> :: forall a. Ord a => Wrap a -> Wrap a -> Bool
> :: Wrap a -> Wrap a -> Bool
$c>= :: forall a. Ord a => Wrap a -> Wrap a -> Bool
>= :: Wrap a -> Wrap a -> Bool
$cmax :: forall a. Ord a => Wrap a -> Wrap a -> Wrap a
max :: Wrap a -> Wrap a -> Wrap a
$cmin :: forall a. Ord a => Wrap a -> Wrap a -> Wrap a
min :: Wrap a -> Wrap a -> Wrap a
Ord, Integer -> Wrap a
Wrap a -> Wrap a
Wrap a -> Wrap a -> Wrap a
(Wrap a -> Wrap a -> Wrap a)
-> (Wrap a -> Wrap a -> Wrap a)
-> (Wrap a -> Wrap a -> Wrap a)
-> (Wrap a -> Wrap a)
-> (Wrap a -> Wrap a)
-> (Wrap a -> Wrap a)
-> (Integer -> Wrap a)
-> Num (Wrap a)
forall a. Num a => Integer -> Wrap a
forall a. Num a => Wrap a -> Wrap a
forall a. Num a => Wrap a -> Wrap a -> Wrap a
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: forall a. Num a => Wrap a -> Wrap a -> Wrap a
+ :: Wrap a -> Wrap a -> Wrap a
$c- :: forall a. Num a => Wrap a -> Wrap a -> Wrap a
- :: Wrap a -> Wrap a -> Wrap a
$c* :: forall a. Num a => Wrap a -> Wrap a -> Wrap a
* :: Wrap a -> Wrap a -> Wrap a
$cnegate :: forall a. Num a => Wrap a -> Wrap a
negate :: Wrap a -> Wrap a
$cabs :: forall a. Num a => Wrap a -> Wrap a
abs :: Wrap a -> Wrap a
$csignum :: forall a. Num a => Wrap a -> Wrap a
signum :: Wrap a -> Wrap a
$cfromInteger :: forall a. Num a => Integer -> Wrap a
fromInteger :: Integer -> Wrap a
Num, ReadPrec [Wrap a]
ReadPrec (Wrap a)
Int -> ReadS (Wrap a)
ReadS [Wrap a]
(Int -> ReadS (Wrap a))
-> ReadS [Wrap a]
-> ReadPrec (Wrap a)
-> ReadPrec [Wrap a]
-> Read (Wrap a)
forall a. Read a => ReadPrec [Wrap a]
forall a. Read a => ReadPrec (Wrap a)
forall a. Read a => Int -> ReadS (Wrap a)
forall a. Read a => ReadS [Wrap a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (Wrap a)
readsPrec :: Int -> ReadS (Wrap a)
$creadList :: forall a. Read a => ReadS [Wrap a]
readList :: ReadS [Wrap a]
$creadPrec :: forall a. Read a => ReadPrec (Wrap a)
readPrec :: ReadPrec (Wrap a)
$creadListPrec :: forall a. Read a => ReadPrec [Wrap a]
readListPrec :: ReadPrec [Wrap a]
Read, Num (Wrap a)
Ord (Wrap a)
(Num (Wrap a), Ord (Wrap a)) =>
(Wrap a -> Rational) -> Real (Wrap a)
Wrap a -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
forall a. Real a => Num (Wrap a)
forall a. Real a => Ord (Wrap a)
forall a. Real a => Wrap a -> Rational
$ctoRational :: forall a. Real a => Wrap a -> Rational
toRational :: Wrap a -> Rational
Real, Int -> Wrap a -> ShowS
[Wrap a] -> ShowS
Wrap a -> String
(Int -> Wrap a -> ShowS)
-> (Wrap a -> String) -> ([Wrap a] -> ShowS) -> Show (Wrap a)
forall a. Show a => Int -> Wrap a -> ShowS
forall a. Show a => [Wrap a] -> ShowS
forall a. Show a => Wrap a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Wrap a -> ShowS
showsPrec :: Int -> Wrap a -> ShowS
$cshow :: forall a. Show a => Wrap a -> String
show :: Wrap a -> String
$cshowList :: forall a. Show a => [Wrap a] -> ShowS
showList :: [Wrap a] -> ShowS
Show)

instance FieldForm 'Implicit protoType a =>
         FieldForm 'Optional ('Message (Wrapper protoType)) (Identity (Wrap a))
  where
    fieldForm :: Proxy# 'Optional
-> Proxy# ('Message (Wrapper protoType))
-> FieldNumber
-> Identity (Wrap a)
-> MessageBuilder
fieldForm Proxy# 'Optional
_ Proxy# ('Message (Wrapper protoType))
ty !FieldNumber
fn (Identity (Wrap a
x)) =
      Proxy# 'Optional
-> Proxy# ('Message (Wrapper protoType))
-> FieldNumber
-> Identity (MessageEncoder (Wrapper protoType))
-> MessageBuilder
forall (cardinality :: Cardinality) (protoType :: ProtoType) a.
FieldForm cardinality protoType a =>
Proxy# cardinality
-> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
fieldForm (Proxy# 'Optional
forall {k} (a :: k). Proxy# a
proxy# :: Proxy# 'Optional) Proxy# ('Message (Wrapper protoType))
ty FieldNumber
fn
                (MessageEncoder (Wrapper protoType)
-> Identity (MessageEncoder (Wrapper protoType))
forall a. a -> Identity a
Identity (forall message (names :: [Symbol]).
Distinct message names =>
FieldsEncoder message '[] names -> MessageEncoder message
fieldsToMessage @(Wrapper protoType) (forall (name :: Symbol) a message (names :: [Symbol]).
Field name a message =>
a -> FieldsEncoder message names (Occupy message name names)
field @"value" a
x)))
    {-# INLINE fieldForm #-}

-- | Asks that its type parameter be chosen to be the most efficient Haskell type
-- that expresses the full range of possible values of the relevant protobuf field.
--
-- This choice can be used to resolve ambiguity around polymorphic
-- literal values, or when performing a polymorphic conversion
-- from a type that is not directly encodable, such as 'Int'.
newtype Auto (a :: Type) = Auto { forall a. Auto a -> a
unauto :: a }
  deriving stock ((forall m. Monoid m => Auto m -> m)
-> (forall m a. Monoid m => (a -> m) -> Auto a -> m)
-> (forall m a. Monoid m => (a -> m) -> Auto a -> m)
-> (forall a b. (a -> b -> b) -> b -> Auto a -> b)
-> (forall a b. (a -> b -> b) -> b -> Auto a -> b)
-> (forall b a. (b -> a -> b) -> b -> Auto a -> b)
-> (forall b a. (b -> a -> b) -> b -> Auto a -> b)
-> (forall a. (a -> a -> a) -> Auto a -> a)
-> (forall a. (a -> a -> a) -> Auto a -> a)
-> (forall a. Auto a -> [a])
-> (forall a. Auto a -> Bool)
-> (forall a. Auto a -> Int)
-> (forall a. Eq a => a -> Auto a -> Bool)
-> (forall a. Ord a => Auto a -> a)
-> (forall a. Ord a => Auto a -> a)
-> (forall a. Num a => Auto a -> a)
-> (forall a. Num a => Auto a -> a)
-> Foldable Auto
forall a. Eq a => a -> Auto a -> Bool
forall a. Num a => Auto a -> a
forall a. Ord a => Auto a -> a
forall m. Monoid m => Auto m -> m
forall a. Auto a -> Bool
forall a. Auto a -> Int
forall a. Auto a -> [a]
forall a. (a -> a -> a) -> Auto a -> a
forall m a. Monoid m => (a -> m) -> Auto a -> m
forall b a. (b -> a -> b) -> b -> Auto a -> b
forall a b. (a -> b -> b) -> b -> Auto a -> b
forall (t :: * -> *).
(forall m. Monoid m => t m -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall m a. Monoid m => (a -> m) -> t a -> m)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall a b. (a -> b -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall b a. (b -> a -> b) -> b -> t a -> b)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. (a -> a -> a) -> t a -> a)
-> (forall a. t a -> [a])
-> (forall a. t a -> Bool)
-> (forall a. t a -> Int)
-> (forall a. Eq a => a -> t a -> Bool)
-> (forall a. Ord a => t a -> a)
-> (forall a. Ord a => t a -> a)
-> (forall a. Num a => t a -> a)
-> (forall a. Num a => t a -> a)
-> Foldable t
$cfold :: forall m. Monoid m => Auto m -> m
fold :: forall m. Monoid m => Auto m -> m
$cfoldMap :: forall m a. Monoid m => (a -> m) -> Auto a -> m
foldMap :: forall m a. Monoid m => (a -> m) -> Auto a -> m
$cfoldMap' :: forall m a. Monoid m => (a -> m) -> Auto a -> m
foldMap' :: forall m a. Monoid m => (a -> m) -> Auto a -> m
$cfoldr :: forall a b. (a -> b -> b) -> b -> Auto a -> b
foldr :: forall a b. (a -> b -> b) -> b -> Auto a -> b
$cfoldr' :: forall a b. (a -> b -> b) -> b -> Auto a -> b
foldr' :: forall a b. (a -> b -> b) -> b -> Auto a -> b
$cfoldl :: forall b a. (b -> a -> b) -> b -> Auto a -> b
foldl :: forall b a. (b -> a -> b) -> b -> Auto a -> b
$cfoldl' :: forall b a. (b -> a -> b) -> b -> Auto a -> b
foldl' :: forall b a. (b -> a -> b) -> b -> Auto a -> b
$cfoldr1 :: forall a. (a -> a -> a) -> Auto a -> a
foldr1 :: forall a. (a -> a -> a) -> Auto a -> a
$cfoldl1 :: forall a. (a -> a -> a) -> Auto a -> a
foldl1 :: forall a. (a -> a -> a) -> Auto a -> a
$ctoList :: forall a. Auto a -> [a]
toList :: forall a. Auto a -> [a]
$cnull :: forall a. Auto a -> Bool
null :: forall a. Auto a -> Bool
$clength :: forall a. Auto a -> Int
length :: forall a. Auto a -> Int
$celem :: forall a. Eq a => a -> Auto a -> Bool
elem :: forall a. Eq a => a -> Auto a -> Bool
$cmaximum :: forall a. Ord a => Auto a -> a
maximum :: forall a. Ord a => Auto a -> a
$cminimum :: forall a. Ord a => Auto a -> a
minimum :: forall a. Ord a => Auto a -> a
$csum :: forall a. Num a => Auto a -> a
sum :: forall a. Num a => Auto a -> a
$cproduct :: forall a. Num a => Auto a -> a
product :: forall a. Num a => Auto a -> a
Foldable, (forall a b. (a -> b) -> Auto a -> Auto b)
-> (forall a b. a -> Auto b -> Auto a) -> Functor Auto
forall a b. a -> Auto b -> Auto a
forall a b. (a -> b) -> Auto a -> Auto b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> Auto a -> Auto b
fmap :: forall a b. (a -> b) -> Auto a -> Auto b
$c<$ :: forall a b. a -> Auto b -> Auto a
<$ :: forall a b. a -> Auto b -> Auto a
Functor, (forall x. Auto a -> Rep (Auto a) x)
-> (forall x. Rep (Auto a) x -> Auto a) -> Generic (Auto a)
forall x. Rep (Auto a) x -> Auto a
forall x. Auto a -> Rep (Auto a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Auto a) x -> Auto a
forall a x. Auto a -> Rep (Auto a) x
$cfrom :: forall a x. Auto a -> Rep (Auto a) x
from :: forall x. Auto a -> Rep (Auto a) x
$cto :: forall a x. Rep (Auto a) x -> Auto a
to :: forall x. Rep (Auto a) x -> Auto a
Generic, Functor Auto
Foldable Auto
(Functor Auto, Foldable Auto) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> Auto a -> f (Auto b))
-> (forall (f :: * -> *) a.
    Applicative f =>
    Auto (f a) -> f (Auto a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> Auto a -> m (Auto b))
-> (forall (m :: * -> *) a. Monad m => Auto (m a) -> m (Auto a))
-> Traversable Auto
forall (t :: * -> *).
(Functor t, Foldable t) =>
(forall (f :: * -> *) a b.
 Applicative f =>
 (a -> f b) -> t a -> f (t b))
-> (forall (f :: * -> *) a. Applicative f => t (f a) -> f (t a))
-> (forall (m :: * -> *) a b.
    Monad m =>
    (a -> m b) -> t a -> m (t b))
-> (forall (m :: * -> *) a. Monad m => t (m a) -> m (t a))
-> Traversable t
forall (m :: * -> *) a. Monad m => Auto (m a) -> m (Auto a)
forall (f :: * -> *) a. Applicative f => Auto (f a) -> f (Auto a)
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Auto a -> m (Auto b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Auto a -> f (Auto b)
$ctraverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Auto a -> f (Auto b)
traverse :: forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> Auto a -> f (Auto b)
$csequenceA :: forall (f :: * -> *) a. Applicative f => Auto (f a) -> f (Auto a)
sequenceA :: forall (f :: * -> *) a. Applicative f => Auto (f a) -> f (Auto a)
$cmapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Auto a -> m (Auto b)
mapM :: forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Auto a -> m (Auto b)
$csequence :: forall (m :: * -> *) a. Monad m => Auto (m a) -> m (Auto a)
sequence :: forall (m :: * -> *) a. Monad m => Auto (m a) -> m (Auto a)
Traversable)
  deriving newtype (Auto a
Auto a -> Auto a -> Bounded (Auto a)
forall a. a -> a -> Bounded a
forall a. Bounded a => Auto a
$cminBound :: forall a. Bounded a => Auto a
minBound :: Auto a
$cmaxBound :: forall a. Bounded a => Auto a
maxBound :: Auto a
Bounded, Int -> Auto a
Auto a -> Int
Auto a -> [Auto a]
Auto a -> Auto a
Auto a -> Auto a -> [Auto a]
Auto a -> Auto a -> Auto a -> [Auto a]
(Auto a -> Auto a)
-> (Auto a -> Auto a)
-> (Int -> Auto a)
-> (Auto a -> Int)
-> (Auto a -> [Auto a])
-> (Auto a -> Auto a -> [Auto a])
-> (Auto a -> Auto a -> [Auto a])
-> (Auto a -> Auto a -> Auto a -> [Auto a])
-> Enum (Auto a)
forall a. Enum a => Int -> Auto a
forall a. Enum a => Auto a -> Int
forall a. Enum a => Auto a -> [Auto a]
forall a. Enum a => Auto a -> Auto a
forall a. Enum a => Auto a -> Auto a -> [Auto a]
forall a. Enum a => Auto a -> Auto a -> Auto a -> [Auto a]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: forall a. Enum a => Auto a -> Auto a
succ :: Auto a -> Auto a
$cpred :: forall a. Enum a => Auto a -> Auto a
pred :: Auto a -> Auto a
$ctoEnum :: forall a. Enum a => Int -> Auto a
toEnum :: Int -> Auto a
$cfromEnum :: forall a. Enum a => Auto a -> Int
fromEnum :: Auto a -> Int
$cenumFrom :: forall a. Enum a => Auto a -> [Auto a]
enumFrom :: Auto a -> [Auto a]
$cenumFromThen :: forall a. Enum a => Auto a -> Auto a -> [Auto a]
enumFromThen :: Auto a -> Auto a -> [Auto a]
$cenumFromTo :: forall a. Enum a => Auto a -> Auto a -> [Auto a]
enumFromTo :: Auto a -> Auto a -> [Auto a]
$cenumFromThenTo :: forall a. Enum a => Auto a -> Auto a -> Auto a -> [Auto a]
enumFromThenTo :: Auto a -> Auto a -> Auto a -> [Auto a]
Enum, Auto a -> Auto a -> Bool
(Auto a -> Auto a -> Bool)
-> (Auto a -> Auto a -> Bool) -> Eq (Auto a)
forall a. Eq a => Auto a -> Auto a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Eq a => Auto a -> Auto a -> Bool
== :: Auto a -> Auto a -> Bool
$c/= :: forall a. Eq a => Auto a -> Auto a -> Bool
/= :: Auto a -> Auto a -> Bool
Eq, Num (Auto a)
Num (Auto a) =>
(Auto a -> Auto a -> Auto a)
-> (Auto a -> Auto a)
-> (Rational -> Auto a)
-> Fractional (Auto a)
Rational -> Auto a
Auto a -> Auto a
Auto a -> Auto a -> Auto a
forall a. Fractional a => Num (Auto a)
forall a. Fractional a => Rational -> Auto a
forall a. Fractional a => Auto a -> Auto a
forall a. Fractional a => Auto a -> Auto a -> Auto a
forall a.
Num a =>
(a -> a -> a) -> (a -> a) -> (Rational -> a) -> Fractional a
$c/ :: forall a. Fractional a => Auto a -> Auto a -> Auto a
/ :: Auto a -> Auto a -> Auto a
$crecip :: forall a. Fractional a => Auto a -> Auto a
recip :: Auto a -> Auto a
$cfromRational :: forall a. Fractional a => Rational -> Auto a
fromRational :: Rational -> Auto a
Fractional, Enum (Auto a)
Real (Auto a)
(Real (Auto a), Enum (Auto a)) =>
(Auto a -> Auto a -> Auto a)
-> (Auto a -> Auto a -> Auto a)
-> (Auto a -> Auto a -> Auto a)
-> (Auto a -> Auto a -> Auto a)
-> (Auto a -> Auto a -> (Auto a, Auto a))
-> (Auto a -> Auto a -> (Auto a, Auto a))
-> (Auto a -> Integer)
-> Integral (Auto a)
Auto a -> Integer
Auto a -> Auto a -> (Auto a, Auto a)
Auto a -> Auto a -> Auto a
forall a. Integral a => Enum (Auto a)
forall a. Integral a => Real (Auto a)
forall a. Integral a => Auto a -> Integer
forall a. Integral a => Auto a -> Auto a -> (Auto a, Auto a)
forall a. Integral a => Auto a -> Auto a -> Auto a
forall a.
(Real a, Enum a) =>
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> (a, a))
-> (a -> a -> (a, a))
-> (a -> Integer)
-> Integral a
$cquot :: forall a. Integral a => Auto a -> Auto a -> Auto a
quot :: Auto a -> Auto a -> Auto a
$crem :: forall a. Integral a => Auto a -> Auto a -> Auto a
rem :: Auto a -> Auto a -> Auto a
$cdiv :: forall a. Integral a => Auto a -> Auto a -> Auto a
div :: Auto a -> Auto a -> Auto a
$cmod :: forall a. Integral a => Auto a -> Auto a -> Auto a
mod :: Auto a -> Auto a -> Auto a
$cquotRem :: forall a. Integral a => Auto a -> Auto a -> (Auto a, Auto a)
quotRem :: Auto a -> Auto a -> (Auto a, Auto a)
$cdivMod :: forall a. Integral a => Auto a -> Auto a -> (Auto a, Auto a)
divMod :: Auto a -> Auto a -> (Auto a, Auto a)
$ctoInteger :: forall a. Integral a => Auto a -> Integer
toInteger :: Auto a -> Integer
Integral, Eq (Auto a)
Eq (Auto a) =>
(Auto a -> Auto a -> Ordering)
-> (Auto a -> Auto a -> Bool)
-> (Auto a -> Auto a -> Bool)
-> (Auto a -> Auto a -> Bool)
-> (Auto a -> Auto a -> Bool)
-> (Auto a -> Auto a -> Auto a)
-> (Auto a -> Auto a -> Auto a)
-> Ord (Auto a)
Auto a -> Auto a -> Bool
Auto a -> Auto a -> Ordering
Auto a -> Auto a -> Auto a
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
forall a. Ord a => Eq (Auto a)
forall a. Ord a => Auto a -> Auto a -> Bool
forall a. Ord a => Auto a -> Auto a -> Ordering
forall a. Ord a => Auto a -> Auto a -> Auto a
$ccompare :: forall a. Ord a => Auto a -> Auto a -> Ordering
compare :: Auto a -> Auto a -> Ordering
$c< :: forall a. Ord a => Auto a -> Auto a -> Bool
< :: Auto a -> Auto a -> Bool
$c<= :: forall a. Ord a => Auto a -> Auto a -> Bool
<= :: Auto a -> Auto a -> Bool
$c> :: forall a. Ord a => Auto a -> Auto a -> Bool
> :: Auto a -> Auto a -> Bool
$c>= :: forall a. Ord a => Auto a -> Auto a -> Bool
>= :: Auto a -> Auto a -> Bool
$cmax :: forall a. Ord a => Auto a -> Auto a -> Auto a
max :: Auto a -> Auto a -> Auto a
$cmin :: forall a. Ord a => Auto a -> Auto a -> Auto a
min :: Auto a -> Auto a -> Auto a
Ord, Integer -> Auto a
Auto a -> Auto a
Auto a -> Auto a -> Auto a
(Auto a -> Auto a -> Auto a)
-> (Auto a -> Auto a -> Auto a)
-> (Auto a -> Auto a -> Auto a)
-> (Auto a -> Auto a)
-> (Auto a -> Auto a)
-> (Auto a -> Auto a)
-> (Integer -> Auto a)
-> Num (Auto a)
forall a. Num a => Integer -> Auto a
forall a. Num a => Auto a -> Auto a
forall a. Num a => Auto a -> Auto a -> Auto a
forall a.
(a -> a -> a)
-> (a -> a -> a)
-> (a -> a -> a)
-> (a -> a)
-> (a -> a)
-> (a -> a)
-> (Integer -> a)
-> Num a
$c+ :: forall a. Num a => Auto a -> Auto a -> Auto a
+ :: Auto a -> Auto a -> Auto a
$c- :: forall a. Num a => Auto a -> Auto a -> Auto a
- :: Auto a -> Auto a -> Auto a
$c* :: forall a. Num a => Auto a -> Auto a -> Auto a
* :: Auto a -> Auto a -> Auto a
$cnegate :: forall a. Num a => Auto a -> Auto a
negate :: Auto a -> Auto a
$cabs :: forall a. Num a => Auto a -> Auto a
abs :: Auto a -> Auto a
$csignum :: forall a. Num a => Auto a -> Auto a
signum :: Auto a -> Auto a
$cfromInteger :: forall a. Num a => Integer -> Auto a
fromInteger :: Integer -> Auto a
Num, ReadPrec [Auto a]
ReadPrec (Auto a)
Int -> ReadS (Auto a)
ReadS [Auto a]
(Int -> ReadS (Auto a))
-> ReadS [Auto a]
-> ReadPrec (Auto a)
-> ReadPrec [Auto a]
-> Read (Auto a)
forall a. Read a => ReadPrec [Auto a]
forall a. Read a => ReadPrec (Auto a)
forall a. Read a => Int -> ReadS (Auto a)
forall a. Read a => ReadS [Auto a]
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
$creadsPrec :: forall a. Read a => Int -> ReadS (Auto a)
readsPrec :: Int -> ReadS (Auto a)
$creadList :: forall a. Read a => ReadS [Auto a]
readList :: ReadS [Auto a]
$creadPrec :: forall a. Read a => ReadPrec (Auto a)
readPrec :: ReadPrec (Auto a)
$creadListPrec :: forall a. Read a => ReadPrec [Auto a]
readListPrec :: ReadPrec [Auto a]
Read, Num (Auto a)
Ord (Auto a)
(Num (Auto a), Ord (Auto a)) =>
(Auto a -> Rational) -> Real (Auto a)
Auto a -> Rational
forall a. (Num a, Ord a) => (a -> Rational) -> Real a
forall a. Real a => Num (Auto a)
forall a. Real a => Ord (Auto a)
forall a. Real a => Auto a -> Rational
$ctoRational :: forall a. Real a => Auto a -> Rational
toRational :: Auto a -> Rational
Real, Int -> Auto a -> ShowS
[Auto a] -> ShowS
Auto a -> String
(Int -> Auto a -> ShowS)
-> (Auto a -> String) -> ([Auto a] -> ShowS) -> Show (Auto a)
forall a. Show a => Int -> Auto a -> ShowS
forall a. Show a => [Auto a] -> ShowS
forall a. Show a => Auto a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Show a => Int -> Auto a -> ShowS
showsPrec :: Int -> Auto a -> ShowS
$cshow :: forall a. Show a => Auto a -> String
show :: Auto a -> String
$cshowList :: forall a. Show a => [Auto a] -> ShowS
showList :: [Auto a] -> ShowS
Show)

instantiatePackableField ::
  -- | Protobuf type of kind 'ProtoType'.
  TH.Q TH.Type ->
  -- | 'fieldForm' argument type.
  TH.Q TH.Type ->
  -- | The encoder for non-repeated or unpacked fields
  -- of the specified protobuf type and argument type.
  TH.Q TH.Exp ->
  -- | The encoder for packed fields of the specified protobuf type and argument type.
  TH.Q TH.Exp ->
  -- | For every promotion to this type of field:
  --  1. The argument type to before promotion.
  --  2. The conversion from that type to an argument type.
  --  3. The compatible protobuf type whose encoder we should use;
  --     it must support the post-conversion type of the argument.
  --
  -- NOTE: Do not convert when some source values have no semantically-equivalent
  -- value to which to convert.  Specifically, do not convert from signed integers
  -- to unsigned integers (because negative values become positive ones), and only
  -- convert from unsigned to signed when widening (because otherwise some positive
  -- values become will negative ones).
  --
  -- These are /not/ selected by 'Auto'.
  [(TH.Q TH.Type, TH.Q TH.Exp, TH.Q TH.Type)] ->
  -- | Is there a standard wrapper type?
  Bool ->
  TH.Q [TH.Dec]
instantiatePackableField :: Q Type
-> Q Type
-> Q Exp
-> Q Exp
-> [(Q Type, Q Exp, Q Type)]
-> Bool
-> Q [Dec]
instantiatePackableField Q Type
protoType Q Type
elementType Q Exp
encoder Q Exp
packedEncoder [(Q Type, Q Exp, Q Type)]
promotions Bool
hasWrapper = do
  [Dec]
direct <-
    [d|

      instance FieldForm 'Optional $Q Type
protoType (Identity $Q Type
elementType)
        where
          fieldForm _ _ = coerce
            @(FieldNumber -> $Q Type
elementType -> Encode.MessageBuilder)
            @(FieldNumber -> Identity $Q Type
elementType -> Encode.MessageBuilder)
            $Q Exp
encoder
          {-# INLINE fieldForm #-}

      instance FieldForm 'Implicit $Q Type
protoType $Q Type
elementType
        where
          fieldForm _ ty !fn x
            | isDefault x = mempty
            | otherwise = fieldForm (proxy# :: Proxy# 'Optional) ty fn (Identity x)
          {-# INLINE fieldForm #-}

      instance (a ~ $Q Type
elementType) =>
               FieldForm 'Optional $Q Type
protoType (Identity (Auto a))
        where
          fieldForm = coerce (fieldForm @'Optional @($Q Type
protoType) @(Identity a))
          {-# INLINE fieldForm #-}

      instance (a ~ $Q Type
elementType) =>
               FieldForm 'Implicit $Q Type
protoType (Auto a)
        where
          fieldForm = coerce (fieldForm @'Implicit @($Q Type
protoType) @a)
          {-# INLINE fieldForm #-}

      instance PackedFieldForm $Q Type
protoType $Q Type
elementType
        where
          packedFieldForm _ = $Q Exp
packedEncoder
          {-# INLINE packedFieldForm #-}

      instance (a ~ $Q Type
elementType) =>
               PackedFieldForm $Q Type
protoType (Auto a)
        where
          packedFieldForm = coerce (packedFieldForm @($Q Type
protoType) @a)
          {-# INLINE packedFieldForm #-}

      |]

  [[Dec]]
promoted <- [(Q Type, Q Exp, Q Type)]
-> ((Q Type, Q Exp, Q Type) -> Q [Dec]) -> Q [[Dec]]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [(Q Type, Q Exp, Q Type)]
promotions (((Q Type, Q Exp, Q Type) -> Q [Dec]) -> Q [[Dec]])
-> ((Q Type, Q Exp, Q Type) -> Q [Dec]) -> Q [[Dec]]
forall a b. (a -> b) -> a -> b
$ \(Q Type
supportedType, Q Exp
conversion, Q Type
compatibleProtoType) ->
    [d|

      instance FieldForm 'Optional $Q Type
protoType (Identity $Q Type
supportedType)
        where
          fieldForm rep _ !fn (Identity x) =
            fieldForm rep (proxy# :: Proxy# $Q Type
compatibleProtoType) fn (Identity ($Q Exp
conversion x))
          {-# INLINE fieldForm #-}

      instance FieldForm 'Implicit $Q Type
protoType $Q Type
supportedType
        where
          fieldForm rep _ !fn x =
            fieldForm rep (proxy# :: Proxy# $Q Type
compatibleProtoType) fn ($Q Exp
conversion x)
          {-# INLINE fieldForm #-}

      instance PackedFieldForm $Q Type
protoType $Q Type
supportedType
        where
          packedFieldForm _ !fn xs =
            packedFieldForm (proxy# :: Proxy# $Q Type
compatibleProtoType) fn (fmap $Q Exp
conversion xs)
          {-# INLINE packedFieldForm #-}

      |]

  [Dec]
wrapped <- if Bool -> Bool
not Bool
hasWrapper then [Dec] -> Q [Dec]
forall a. a -> Q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [] else
    [d|

      instance FieldForm 'Optional ('Message (Wrapper $Q Type
protoType)) (Identity $Q Type
elementType)
        where
          fieldForm = coerce
            (fieldForm @'Optional @('Message (Wrapper $Q Type
protoType)) @(Identity (Wrap $Q Type
elementType)))
          {-# INLINE fieldForm #-}

      instance (a ~ $Q Type
elementType) =>
               FieldForm 'Optional ('Message (Wrapper $Q Type
protoType)) (Identity (Auto a))
        where
          fieldForm = coerce
            (fieldForm @'Optional @('Message (Wrapper $Q Type
protoType)) @(Identity (Wrap a)))
          {-# INLINE fieldForm #-}

      |]

  [[Dec]]
wrappedPromoted <- if Bool -> Bool
not Bool
hasWrapper then [[Dec]] -> Q [[Dec]]
forall a. a -> Q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure [] else
    [(Q Type, Q Exp, Q Type)]
-> ((Q Type, Q Exp, Q Type) -> Q [Dec]) -> Q [[Dec]]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [(Q Type, Q Exp, Q Type)]
promotions (((Q Type, Q Exp, Q Type) -> Q [Dec]) -> Q [[Dec]])
-> ((Q Type, Q Exp, Q Type) -> Q [Dec]) -> Q [[Dec]]
forall a b. (a -> b) -> a -> b
$ \(Q Type
supportedType, Q Exp
_, Q Type
_) -> do
      [d|

        instance FieldForm 'Optional ('Message (Wrapper $Q Type
protoType)) (Identity $Q Type
supportedType)
          where
            fieldForm = coerce
              (fieldForm @'Optional @('Message (Wrapper $Q Type
protoType)) @(Identity (Wrap $Q Type
supportedType)))
            {-# INLINE fieldForm #-}

        |]

  [Dec] -> Q [Dec]
forall a. a -> Q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Dec] -> Q [Dec]) -> [Dec] -> Q [Dec]
forall a b. (a -> b) -> a -> b
$ [Dec]
direct [Dec] -> [Dec] -> [Dec]
forall a. [a] -> [a] -> [a]
++ [[Dec]] -> [Dec]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Dec]]
promoted [Dec] -> [Dec] -> [Dec]
forall a. [a] -> [a] -> [a]
++ [Dec]
wrapped [Dec] -> [Dec] -> [Dec]
forall a. [a] -> [a] -> [a]
++ [[Dec]] -> [Dec]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Dec]]
wrappedPromoted

instantiateStringOrBytesField ::
  -- | Protobuf type of kind 'ProtoType'.
  TH.Q TH.Type ->
  -- | 'fieldForm' argument type.
  TH.Q TH.Type ->
  -- | The encoder for fields of the specified protobuf type and argument type.
  TH.Q TH.Exp ->
  -- | Additional argument types and their associated encoders.
  -- These are /not/ selected by 'Auto'.
  [(TH.Q TH.Type, TH.Q TH.Exp)] ->
  TH.Q [TH.Dec]
instantiateStringOrBytesField :: Q Type -> Q Type -> Q Exp -> [(Q Type, Q Exp)] -> Q [Dec]
instantiateStringOrBytesField Q Type
protoType Q Type
argumentType Q Exp
encoder [(Q Type, Q Exp)]
additional = do
  [Dec]
preferred <- [d|

    instance FieldForm 'Optional $Q Type
protoType (Identity $Q Type
argumentType)
      where
        fieldForm _ _ = coerce
          @(FieldNumber -> $Q Type
argumentType -> Encode.MessageBuilder)
          @(FieldNumber -> Identity $Q Type
argumentType -> Encode.MessageBuilder)
          $Q Exp
encoder
        {-# INLINE fieldForm #-}

    instance FieldForm 'Implicit $Q Type
protoType $Q Type
argumentType
      where
        fieldForm _ ty !fn x
          | isDefault x = mempty
          | otherwise = fieldForm (proxy# :: Proxy# 'Optional) ty fn (Identity x)
        {-# INLINE fieldForm #-}

    instance (a ~ $Q Type
argumentType) =>
             FieldForm 'Optional $Q Type
protoType (Identity (Auto a))
      where
        fieldForm = coerce (fieldForm @'Optional @($Q Type
protoType) @(Identity a))
        {-# INLINE fieldForm #-}

    instance (a ~ $Q Type
argumentType) =>
             FieldForm 'Implicit $Q Type
protoType (Auto a)
      where
        fieldForm = coerce (fieldForm @'Implicit @($Q Type
protoType) @a)
        {-# INLINE fieldForm #-}

    instance FieldForm 'Optional ('Message (Wrapper $Q Type
protoType)) (Identity $Q Type
argumentType)
      where
        fieldForm = coerce
          (fieldForm @'Optional @('Message (Wrapper $Q Type
protoType)) @(Identity (Wrap $Q Type
argumentType)))
        {-# INLINE fieldForm #-}

    instance (a ~ $Q Type
argumentType) =>
             FieldForm 'Optional ('Message (Wrapper $Q Type
protoType)) (Identity (Auto a))
      where
        fieldForm = coerce
          (fieldForm @'Optional @('Message (Wrapper $Q Type
protoType)) @(Identity (Wrap a)))
        {-# INLINE fieldForm #-}

    |]

  [[Dec]]
supported <- [(Q Type, Q Exp)] -> ((Q Type, Q Exp) -> Q [Dec]) -> Q [[Dec]]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [(Q Type, Q Exp)]
additional (((Q Type, Q Exp) -> Q [Dec]) -> Q [[Dec]])
-> ((Q Type, Q Exp) -> Q [Dec]) -> Q [[Dec]]
forall a b. (a -> b) -> a -> b
$ \(Q Type
supportedType, Q Exp
additionalEncoder) -> [d|

    instance FieldForm 'Optional $Q Type
protoType (Identity $Q Type
supportedType)
      where
        fieldForm _ _ = coerce
          @(FieldNumber -> $Q Type
supportedType -> Encode.MessageBuilder)
          @(FieldNumber -> Identity $Q Type
supportedType -> Encode.MessageBuilder)
          $Q Exp
additionalEncoder
        {-# INLINE fieldForm #-}

    instance FieldForm 'Implicit $Q Type
protoType $Q Type
supportedType
      where
        fieldForm _ ty !fn x
          | isDefault x = mempty
          | otherwise = fieldForm (proxy# :: Proxy# 'Optional) ty fn (Identity x)
        {-# INLINE fieldForm #-}

    instance FieldForm 'Optional ('Message (Wrapper $Q Type
protoType)) (Identity $Q Type
supportedType)
      where
        fieldForm = coerce
          (fieldForm @'Optional @('Message (Wrapper $Q Type
protoType)) @(Identity (Wrap $Q Type
supportedType)))
        {-# INLINE fieldForm #-}

    |]

  [Dec] -> Q [Dec]
forall a. a -> Q a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Dec] -> Q [Dec]) -> [Dec] -> Q [Dec]
forall a b. (a -> b) -> a -> b
$ [Dec]
preferred [Dec] -> [Dec] -> [Dec]
forall a. [a] -> [a] -> [a]
++ [[Dec]] -> [Dec]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat [[Dec]]
supported