packages feed

proto3-suite 0.7.0 → 0.9.4

raw patch · 34 files changed

+8100/−2787 lines, 34 filesdep +attoparsec-aesondep +ghc-lib-parserdep +template-haskelldep −haskell-srcdep −large-genericsdep −large-recordsdep ~QuickCheckdep ~aesondep ~aeson-prettyPVP ok

version bump matches the API change (PVP)

Dependencies added: attoparsec-aeson, ghc-lib-parser, template-haskell

Dependencies removed: haskell-src, large-generics, large-records, range-set-list, semigroups

Dependency ranges changed: QuickCheck, aeson, aeson-pretty, attoparsec, base, binary, bytestring, containers, deepseq, dhall, filepath, foldl, hashable, insert-ordered-containers, lens, mtl, neat-interpolation, optparse-applicative, optparse-generic, parsec, pretty-show, proto3-wire, split, system-filepath, tasty, tasty-quickcheck, text, time, transformers, turtle, vector

API changes (from Hackage documentation)

- Proto3.Suite.Class: instance (Data.Record.Generic.Generic a, Data.Record.Generic.Constraints a Proto3.Suite.Class.HasDefault) => Proto3.Suite.Class.GenericHasDefault (Data.Record.Generic.GHC.ThroughLRGenerics a)
- Proto3.Suite.Class: instance Proto3.Suite.Class.HasDefault (Proto3.Suite.Types.Bytes Data.ByteString.Internal.ByteString)
- Proto3.Suite.Class: instance Proto3.Suite.Class.HasDefault Data.ByteString.Internal.ByteString
- Proto3.Suite.Class: instance Proto3.Suite.Class.HasDefault GHC.Integer.Type.Integer
- Proto3.Suite.Class: instance Proto3.Suite.Class.Message Data.ByteString.Internal.ByteString
- Proto3.Suite.Class: instance Proto3.Suite.Class.MessageField (Proto3.Suite.Types.Bytes Data.ByteString.Internal.ByteString)
- Proto3.Suite.Class: instance Proto3.Suite.Class.MessageField Data.ByteString.Internal.ByteString
- Proto3.Suite.Class: instance Proto3.Suite.Class.Primitive (Proto3.Suite.Types.Bytes Data.ByteString.Internal.ByteString)
- Proto3.Suite.Class: instance Proto3.Suite.Class.Primitive Data.ByteString.Internal.ByteString
- Proto3.Suite.Class: type family GenericFieldCount f :: Nat;
- Proto3.Suite.DotProto: Anonymous :: DotProtoIdentifier
- Proto3.Suite.DotProto: Bool :: DotProtoPrimType
- Proto3.Suite.DotProto: BoolLit :: Bool -> DotProtoValue
- Proto3.Suite.DotProto: Bytes :: DotProtoPrimType
- Proto3.Suite.DotProto: DotProto :: [DotProtoImport] -> [DotProtoOption] -> DotProtoPackageSpec -> [DotProtoDefinition] -> DotProtoMeta -> DotProto
- Proto3.Suite.DotProto: DotProtoEmptyField :: DotProtoField
- Proto3.Suite.DotProto: DotProtoEnum :: String -> DotProtoIdentifier -> [DotProtoEnumPart] -> DotProtoDefinition
- Proto3.Suite.DotProto: DotProtoEnumEmpty :: DotProtoEnumPart
- Proto3.Suite.DotProto: DotProtoEnumField :: DotProtoIdentifier -> DotProtoEnumValue -> [DotProtoOption] -> DotProtoEnumPart
- Proto3.Suite.DotProto: DotProtoEnumOption :: DotProtoOption -> DotProtoEnumPart
- Proto3.Suite.DotProto: DotProtoField :: FieldNumber -> DotProtoType -> DotProtoIdentifier -> [DotProtoOption] -> String -> DotProtoField
- Proto3.Suite.DotProto: DotProtoImport :: DotProtoImportQualifier -> FilePath -> DotProtoImport
- Proto3.Suite.DotProto: DotProtoImportDefault :: DotProtoImportQualifier
- Proto3.Suite.DotProto: DotProtoImportPublic :: DotProtoImportQualifier
- Proto3.Suite.DotProto: DotProtoImportWeak :: DotProtoImportQualifier
- Proto3.Suite.DotProto: DotProtoMessage :: String -> DotProtoIdentifier -> [DotProtoMessagePart] -> DotProtoDefinition
- Proto3.Suite.DotProto: DotProtoMessageDefinition :: DotProtoDefinition -> DotProtoMessagePart
- Proto3.Suite.DotProto: DotProtoMessageField :: DotProtoField -> DotProtoMessagePart
- Proto3.Suite.DotProto: DotProtoMessageOneOf :: DotProtoIdentifier -> [DotProtoField] -> DotProtoMessagePart
- Proto3.Suite.DotProto: DotProtoMessageOption :: DotProtoOption -> DotProtoMessagePart
- Proto3.Suite.DotProto: DotProtoMessageReserved :: [DotProtoReservedField] -> DotProtoMessagePart
- Proto3.Suite.DotProto: DotProtoMeta :: Path -> DotProtoMeta
- Proto3.Suite.DotProto: DotProtoNoPackage :: DotProtoPackageSpec
- Proto3.Suite.DotProto: DotProtoOption :: DotProtoIdentifier -> DotProtoValue -> DotProtoOption
- Proto3.Suite.DotProto: DotProtoPackageSpec :: DotProtoIdentifier -> DotProtoPackageSpec
- Proto3.Suite.DotProto: DotProtoService :: String -> DotProtoIdentifier -> [DotProtoServicePart] -> DotProtoDefinition
- Proto3.Suite.DotProto: DotProtoServiceEmpty :: DotProtoServicePart
- Proto3.Suite.DotProto: DotProtoServiceOption :: DotProtoOption -> DotProtoServicePart
- Proto3.Suite.DotProto: DotProtoServiceRPCMethod :: RPCMethod -> DotProtoServicePart
- Proto3.Suite.DotProto: Dots :: Path -> DotProtoIdentifier
- Proto3.Suite.DotProto: Double :: DotProtoPrimType
- Proto3.Suite.DotProto: FieldName :: String -> FieldName
- Proto3.Suite.DotProto: FieldRange :: Int -> Int -> DotProtoReservedField
- Proto3.Suite.DotProto: Fixed32 :: DotProtoPrimType
- Proto3.Suite.DotProto: Fixed64 :: DotProtoPrimType
- Proto3.Suite.DotProto: Float :: DotProtoPrimType
- Proto3.Suite.DotProto: FloatLit :: Double -> DotProtoValue
- Proto3.Suite.DotProto: Identifier :: DotProtoIdentifier -> DotProtoValue
- Proto3.Suite.DotProto: Int32 :: DotProtoPrimType
- Proto3.Suite.DotProto: Int64 :: DotProtoPrimType
- Proto3.Suite.DotProto: IntLit :: Int -> DotProtoValue
- Proto3.Suite.DotProto: Map :: DotProtoPrimType -> DotProtoPrimType -> DotProtoType
- Proto3.Suite.DotProto: MessageName :: String -> MessageName
- Proto3.Suite.DotProto: Named :: DotProtoIdentifier -> DotProtoPrimType
- Proto3.Suite.DotProto: NestedRepeated :: DotProtoPrimType -> DotProtoType
- Proto3.Suite.DotProto: NonStreaming :: Streaming
- Proto3.Suite.DotProto: PackageName :: String -> PackageName
- Proto3.Suite.DotProto: PackedField :: Packing
- Proto3.Suite.DotProto: Path :: NonEmpty String -> Path
- Proto3.Suite.DotProto: Prim :: DotProtoPrimType -> DotProtoType
- Proto3.Suite.DotProto: Qualified :: DotProtoIdentifier -> DotProtoIdentifier -> DotProtoIdentifier
- Proto3.Suite.DotProto: RPCMethod :: DotProtoIdentifier -> DotProtoIdentifier -> Streaming -> DotProtoIdentifier -> Streaming -> [DotProtoOption] -> RPCMethod
- Proto3.Suite.DotProto: RenderingOptions :: (DotProtoIdentifier -> DotProtoIdentifier -> FieldNumber -> Doc) -> (DotProtoIdentifier -> DotProtoIdentifier -> Doc) -> RenderingOptions
- Proto3.Suite.DotProto: Repeated :: DotProtoPrimType -> DotProtoType
- Proto3.Suite.DotProto: ReservedIdentifier :: String -> DotProtoReservedField
- Proto3.Suite.DotProto: SFixed32 :: DotProtoPrimType
- Proto3.Suite.DotProto: SFixed64 :: DotProtoPrimType
- Proto3.Suite.DotProto: SInt32 :: DotProtoPrimType
- Proto3.Suite.DotProto: SInt64 :: DotProtoPrimType
- Proto3.Suite.DotProto: Single :: String -> DotProtoIdentifier
- Proto3.Suite.DotProto: SingleField :: Int -> DotProtoReservedField
- Proto3.Suite.DotProto: Streaming :: Streaming
- Proto3.Suite.DotProto: String :: DotProtoPrimType
- Proto3.Suite.DotProto: StringLit :: String -> DotProtoValue
- Proto3.Suite.DotProto: UInt32 :: DotProtoPrimType
- Proto3.Suite.DotProto: UInt64 :: DotProtoPrimType
- Proto3.Suite.DotProto: UnpackedField :: Packing
- Proto3.Suite.DotProto: [components] :: Path -> NonEmpty String
- Proto3.Suite.DotProto: [dotProtoFieldComment] :: DotProtoField -> String
- Proto3.Suite.DotProto: [dotProtoFieldName] :: DotProtoField -> DotProtoIdentifier
- Proto3.Suite.DotProto: [dotProtoFieldNumber] :: DotProtoField -> FieldNumber
- Proto3.Suite.DotProto: [dotProtoFieldOptions] :: DotProtoField -> [DotProtoOption]
- Proto3.Suite.DotProto: [dotProtoFieldType] :: DotProtoField -> DotProtoType
- Proto3.Suite.DotProto: [dotProtoImportPath] :: DotProtoImport -> FilePath
- Proto3.Suite.DotProto: [dotProtoImportQualifier] :: DotProtoImport -> DotProtoImportQualifier
- Proto3.Suite.DotProto: [dotProtoOptionIdentifier] :: DotProtoOption -> DotProtoIdentifier
- Proto3.Suite.DotProto: [dotProtoOptionValue] :: DotProtoOption -> DotProtoValue
- Proto3.Suite.DotProto: [getFieldName] :: FieldName -> String
- Proto3.Suite.DotProto: [getMessageName] :: MessageName -> String
- Proto3.Suite.DotProto: [getPackageName] :: PackageName -> String
- Proto3.Suite.DotProto: [metaModulePath] :: DotProtoMeta -> Path
- Proto3.Suite.DotProto: [protoDefinitions] :: DotProto -> [DotProtoDefinition]
- Proto3.Suite.DotProto: [protoImports] :: DotProto -> [DotProtoImport]
- Proto3.Suite.DotProto: [protoMeta] :: DotProto -> DotProtoMeta
- Proto3.Suite.DotProto: [protoOptions] :: DotProto -> [DotProtoOption]
- Proto3.Suite.DotProto: [protoPackage] :: DotProto -> DotProtoPackageSpec
- Proto3.Suite.DotProto: [roEnumMemberName] :: RenderingOptions -> DotProtoIdentifier -> DotProtoIdentifier -> Doc
- Proto3.Suite.DotProto: [roSelectorName] :: RenderingOptions -> DotProtoIdentifier -> DotProtoIdentifier -> FieldNumber -> Doc
- Proto3.Suite.DotProto: [rpcMethodName] :: RPCMethod -> DotProtoIdentifier
- Proto3.Suite.DotProto: [rpcMethodOptions] :: RPCMethod -> [DotProtoOption]
- Proto3.Suite.DotProto: [rpcMethodRequestStreaming] :: RPCMethod -> Streaming
- Proto3.Suite.DotProto: [rpcMethodRequestType] :: RPCMethod -> DotProtoIdentifier
- Proto3.Suite.DotProto: [rpcMethodResponseStreaming] :: RPCMethod -> Streaming
- Proto3.Suite.DotProto: [rpcMethodResponseType] :: RPCMethod -> DotProtoIdentifier
- Proto3.Suite.DotProto: class Pretty a
- Proto3.Suite.DotProto: data DotProto
- Proto3.Suite.DotProto: data DotProtoDefinition
- Proto3.Suite.DotProto: data DotProtoEnumPart
- Proto3.Suite.DotProto: data DotProtoField
- Proto3.Suite.DotProto: data DotProtoIdentifier
- Proto3.Suite.DotProto: data DotProtoImport
- Proto3.Suite.DotProto: data DotProtoImportQualifier
- Proto3.Suite.DotProto: data DotProtoMessagePart
- Proto3.Suite.DotProto: data DotProtoMeta
- Proto3.Suite.DotProto: data DotProtoOption
- Proto3.Suite.DotProto: data DotProtoPackageSpec
- Proto3.Suite.DotProto: data DotProtoPrimType
- Proto3.Suite.DotProto: data DotProtoReservedField
- Proto3.Suite.DotProto: data DotProtoServicePart
- Proto3.Suite.DotProto: data DotProtoType
- Proto3.Suite.DotProto: data DotProtoValue
- Proto3.Suite.DotProto: data Packing
- Proto3.Suite.DotProto: data ProtoParser a
- Proto3.Suite.DotProto: data RPCMethod
- Proto3.Suite.DotProto: data RenderingOptions
- Proto3.Suite.DotProto: data Streaming
- Proto3.Suite.DotProto: defEnumMemberName :: DotProtoIdentifier -> DotProtoIdentifier -> Doc
- Proto3.Suite.DotProto: defRenderingOptions :: RenderingOptions
- Proto3.Suite.DotProto: defSelectorName :: DotProtoIdentifier -> DotProtoIdentifier -> FieldNumber -> Doc
- Proto3.Suite.DotProto: fakePath :: Path
- Proto3.Suite.DotProto: newtype FieldName
- Proto3.Suite.DotProto: newtype MessageName
- Proto3.Suite.DotProto: newtype PackageName
- Proto3.Suite.DotProto: newtype Path
- Proto3.Suite.DotProto: pExtendKw :: ProtoParser ()
- Proto3.Suite.DotProto: pExtendStmt :: ProtoParser (DotProtoIdentifier, [DotProtoMessagePart])
- Proto3.Suite.DotProto: pFieldOptionStmt :: ProtoParser DotProtoOption
- Proto3.Suite.DotProto: pFieldOptions :: ProtoParser [DotProtoOption]
- Proto3.Suite.DotProto: pOptionId :: ProtoParser DotProtoIdentifier
- Proto3.Suite.DotProto: pOptionKw :: ProtoParser ()
- Proto3.Suite.DotProto: pOptionStmt :: ProtoParser DotProtoOption
- Proto3.Suite.DotProto: pPrint :: Pretty a => a -> Doc
- Proto3.Suite.DotProto: pPrintList :: Pretty a => PrettyLevel -> [a] -> Doc
- Proto3.Suite.DotProto: pPrintPrec :: Pretty a => PrettyLevel -> Rational -> a -> Doc
- Proto3.Suite.DotProto: packageFromDefs :: String -> [DotProtoDefinition] -> DotProto
- Proto3.Suite.DotProto: parseProto :: Path -> String -> Either ParseError DotProto
- Proto3.Suite.DotProto: parseProtoFile :: MonadIO m => Path -> FilePath -> m (Either ParseError DotProto)
- Proto3.Suite.DotProto: renderDotProto :: RenderingOptions -> DotProto -> Doc
- Proto3.Suite.DotProto: toProtoFile :: RenderingOptions -> DotProto -> String
- Proto3.Suite.DotProto: toProtoFileDef :: DotProto -> String
- Proto3.Suite.DotProto: type DotProtoEnumValue = Int32
- Proto3.Suite.DotProto.AST: DotProtoEmptyField :: DotProtoField
- Proto3.Suite.DotProto.AST: DotProtoEnumEmpty :: DotProtoEnumPart
- Proto3.Suite.DotProto.AST: DotProtoServiceEmpty :: DotProtoServicePart
- Proto3.Suite.DotProto.Generate: LargeRecords :: RecordStyle
- Proto3.Suite.DotProto.Generate: RegularRecords :: RecordStyle
- Proto3.Suite.DotProto.Generate: [recordStyle] :: CompileArgs -> RecordStyle
- Proto3.Suite.DotProto.Generate: data RecordStyle
- Proto3.Suite.DotProto.Generate: instance GHC.Classes.Eq Proto3.Suite.DotProto.Generate.RecordStyle
- Proto3.Suite.DotProto.Generate: instance GHC.Read.Read Proto3.Suite.DotProto.Generate.RecordStyle
- Proto3.Suite.DotProto.Generate: instance GHC.Show.Show Proto3.Suite.DotProto.Generate.RecordStyle
- Proto3.Suite.DotProto.Generate.LargeRecord: isLargeRecord :: HsDecl -> Bool
- Proto3.Suite.DotProto.Generate.LargeRecord: nfDataInstD :: HsDecl -> String -> HsDecl
- Proto3.Suite.DotProto.Generate.Syntax: defaultSrcLoc :: SrcLoc
- Proto3.Suite.DotProto.Generate.Syntax: match_ :: HsName -> [HsPat] -> HsRhs -> [HsDecl] -> HsMatch
- Proto3.Suite.DotProto.Internal: type GettingM r s a = forall m. Applicative m => (a -> Compose m (Const r) a) -> s -> Compose m (Const r) s
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoIdentifier
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoImport
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoImportQualifier
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoOption
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoPackageSpec
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoPrimType
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoReservedField
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoServicePart
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoType
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoValue
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.Streaming
- Proto3.Suite.DotProto.Rendering: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Wire.Types.FieldNumber
- Proto3.Suite.JSONPB.Class: instance Proto3.Suite.JSONPB.Class.FromJSONPB Data.ByteString.Internal.ByteString
- Proto3.Suite.JSONPB.Class: instance Proto3.Suite.JSONPB.Class.ToJSONPB Data.ByteString.Internal.ByteString
- Proto3.Suite.Types: instance GHC.Exts.IsList (Proto3.Suite.Types.NestedVec a)
- Proto3.Suite.Types: instance GHC.Exts.IsList (Proto3.Suite.Types.PackedVec a)
- Proto3.Suite.Types: instance GHC.Exts.IsList (Proto3.Suite.Types.UnpackedVec a)
+ Proto3.Suite: ($dmdecodeMessage) :: (Message a, Generic a, GenericMessage (Rep a)) => FieldNumber -> Parser RawMessage a
+ Proto3.Suite: ($dmdecodeMessageField) :: (MessageField a, HasDefault a, Primitive a) => Parser RawField a
+ Proto3.Suite: ($dmdef) :: (HasDefault a, Generic a, GenericHasDefault (Rep a)) => a
+ Proto3.Suite: ($dmdotProto) :: (Message a, GenericMessage (Rep a)) => Proxy# a -> [DotProtoField]
+ Proto3.Suite: ($dmencodeMessage) :: (Message a, Generic a, GenericMessage (Rep a)) => FieldNumber -> a -> MessageBuilder
+ Proto3.Suite: ($dmencodeMessageField) :: (MessageField a, HasDefault a, Primitive a) => FieldNumber -> a -> MessageBuilder
+ Proto3.Suite: ($dmenumerate) :: (Finite a, IsString string, Generic a, GenericFinite (Rep a)) => Proxy# a -> [(string, Int32)]
+ Proto3.Suite: ($dmisDefault) :: (HasDefault a, Eq a) => a -> Bool
+ Proto3.Suite: ($dmnameOf) :: (Named a, IsString string, GenericNamed (Rep a)) => Proxy# a -> string
+ Proto3.Suite: ($dmprimType) :: (Primitive a, Named a) => Proxy# a -> DotProtoPrimType
+ Proto3.Suite: ($dmprotoType) :: (MessageField a, Primitive a) => Proxy# a -> DotProtoField
+ Proto3.Suite.Class: ($dmdecodeMessage) :: (Message a, Generic a, GenericMessage (Rep a)) => FieldNumber -> Parser RawMessage a
+ Proto3.Suite.Class: ($dmdecodeMessageField) :: (MessageField a, HasDefault a, Primitive a) => Parser RawField a
+ Proto3.Suite.Class: ($dmdef) :: (HasDefault a, Generic a, GenericHasDefault (Rep a)) => a
+ Proto3.Suite.Class: ($dmdotProto) :: (Message a, GenericMessage (Rep a)) => Proxy# a -> [DotProtoField]
+ Proto3.Suite.Class: ($dmencodeMessage) :: (Message a, Generic a, GenericMessage (Rep a)) => FieldNumber -> a -> MessageBuilder
+ Proto3.Suite.Class: ($dmencodeMessageField) :: (MessageField a, HasDefault a, Primitive a) => FieldNumber -> a -> MessageBuilder
+ Proto3.Suite.Class: ($dmenumerate) :: (Finite a, IsString string, Generic a, GenericFinite (Rep a)) => Proxy# a -> [(string, Int32)]
+ Proto3.Suite.Class: ($dmisDefault) :: (HasDefault a, Eq a) => a -> Bool
+ Proto3.Suite.Class: ($dmnameOf) :: (Named a, IsString string, GenericNamed (Rep a)) => Proxy# a -> string
+ Proto3.Suite.Class: ($dmprimType) :: (Primitive a, Named a) => Proxy# a -> DotProtoPrimType
+ Proto3.Suite.Class: ($dmprotoType) :: (MessageField a, Primitive a) => Proxy# a -> DotProtoField
+ Proto3.Suite.Class: ($dmzigZagDecode) :: (ZigZag a, Num (ZigZagEncoded a), Bits (ZigZagEncoded a), Integral (ZigZagEncoded a), Num a) => ZigZagEncoded a -> Signed a
+ Proto3.Suite.Class: ($dmzigZagEncode) :: (ZigZag a, Num a, FiniteBits a, Integral a, Num (ZigZagEncoded a)) => Signed a -> ZigZagEncoded a
+ Proto3.Suite.Class: --
+ Proto3.Suite.Class: -- NOTE: The two integral types must have the same width both to
+ Proto3.Suite.Class: -- ZigZag-encoded <tt>sint32</tt> values in packed fields.
+ Proto3.Suite.Class: -- before v0.8.2. Those older versions incorrectly sign-extended
+ Proto3.Suite.Class: -- compensate for overlong encodings emitted by versions of this library
+ Proto3.Suite.Class: -- correctly encode large <tt>sint32</tt> values and, during decoding, to
+ Proto3.Suite.Class: -- encoding but before varint encoding, and after varint decoding but
+ Proto3.Suite.Class: -- | The unsigned integral type used to hold the value after ZigZag
+ Proto3.Suite.Class: class ZigZag a where {
+ Proto3.Suite.Class: instance Proto3.Suite.Class.HasDefault (Proto3.Suite.Types.Bytes Data.ByteString.Internal.Type.ByteString)
+ Proto3.Suite.Class: instance Proto3.Suite.Class.HasDefault (Proto3.Suite.Types.Bytes Data.ByteString.Short.Internal.ShortByteString)
+ Proto3.Suite.Class: instance Proto3.Suite.Class.HasDefault Data.ByteString.Internal.Type.ByteString
+ Proto3.Suite.Class: instance Proto3.Suite.Class.HasDefault Data.ByteString.Short.Internal.ShortByteString
+ Proto3.Suite.Class: instance Proto3.Suite.Class.HasDefault GHC.Num.Integer.Integer
+ Proto3.Suite.Class: instance Proto3.Suite.Class.Message Data.ByteString.Internal.Type.ByteString
+ Proto3.Suite.Class: instance Proto3.Suite.Class.Message Data.ByteString.Short.Internal.ShortByteString
+ Proto3.Suite.Class: instance Proto3.Suite.Class.MessageField (Proto3.Suite.Types.Bytes Data.ByteString.Internal.Type.ByteString)
+ Proto3.Suite.Class: instance Proto3.Suite.Class.MessageField (Proto3.Suite.Types.Bytes Data.ByteString.Short.Internal.ShortByteString)
+ Proto3.Suite.Class: instance Proto3.Suite.Class.MessageField Data.ByteString.Internal.Type.ByteString
+ Proto3.Suite.Class: instance Proto3.Suite.Class.MessageField Data.ByteString.Short.Internal.ShortByteString
+ Proto3.Suite.Class: instance Proto3.Suite.Class.Primitive (Proto3.Suite.Types.Bytes Data.ByteString.Internal.Type.ByteString)
+ Proto3.Suite.Class: instance Proto3.Suite.Class.Primitive (Proto3.Suite.Types.Bytes Data.ByteString.Short.Internal.ShortByteString)
+ Proto3.Suite.Class: instance Proto3.Suite.Class.Primitive Data.ByteString.Internal.Type.ByteString
+ Proto3.Suite.Class: instance Proto3.Suite.Class.Primitive Data.ByteString.Short.Internal.ShortByteString
+ Proto3.Suite.Class: instance Proto3.Suite.Class.Primitive a => Proto3.Suite.Class.MessageField (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit a))
+ Proto3.Suite.Class: instance Proto3.Suite.Class.ZigZag GHC.Int.Int32
+ Proto3.Suite.Class: instance Proto3.Suite.Class.ZigZag GHC.Int.Int64
+ Proto3.Suite.Class: type GenericFieldCount (f :: Type -> Type) :: Nat;
+ Proto3.Suite.Class: type ZigZagEncoded a;
+ Proto3.Suite.Class: zigZagDecode :: ZigZag a => ZigZagEncoded a -> Signed a
+ Proto3.Suite.Class: zigZagEncode :: ZigZag a => Signed a -> ZigZagEncoded a
+ Proto3.Suite.DotProto.AST: DotProtoEnumReserved :: [DotProtoReservedField] -> DotProtoEnumPart
+ Proto3.Suite.DotProto.AST: Optional :: DotProtoPrimType -> DotProtoType
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoIdentifier
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoImport
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoImportQualifier
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoOption
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoPackageSpec
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoPrimType
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoReservedField
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoServicePart
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoType
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.DotProtoValue
+ Proto3.Suite.DotProto.AST: instance Text.PrettyPrint.HughesPJClass.Pretty Proto3.Suite.DotProto.AST.Streaming
+ Proto3.Suite.DotProto.Generate: RedefinedFields :: Histogram FieldName -> Histogram FieldNumber -> CompileError
+ Proto3.Suite.DotProto.Generate: [typeLevelFormat] :: CompileArgs -> Bool
+ Proto3.Suite.DotProto.Generate: instance GHC.Classes.Eq Proto3.Suite.DotProto.Generate.SimpleTypeName
+ Proto3.Suite.DotProto.Generate.Swagger: instance Data.Swagger.Internal.Schema.ToSchema a => Data.Swagger.Internal.Schema.ToSchema (Proto3.Suite.Types.ForceEmit a)
+ Proto3.Suite.DotProto.Generate.Syntax: app :: HsExp -> HsExp -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: appAt :: HsExp -> HsType -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: applyAt :: HsExp -> [HsType] -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: bindStmt_ :: HsPat -> HsExp -> ExprLStmt GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: bodyStmt_ :: HsExp -> ExprLStmt GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: case_ :: HsExp -> [HsAlt] -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: class SyntaxDefault a
+ Proto3.Suite.DotProto.Generate.Syntax: closedTyFamDecl_ :: HsQName -> [HsTyVarBndrV] -> HsType -> [(Maybe [HsTyVarBndrU], [HsType], HsType)] -> HsDecl
+ Proto3.Suite.DotProto.Generate.Syntax: conPat :: HsQName -> [HsPat] -> HsPat
+ Proto3.Suite.DotProto.Generate.Syntax: derivingClause_ :: Maybe HsDerivStrategy -> [(HsOuterSigTyVarBndrs, HsType)] -> Maybe HsDerivingClause
+ Proto3.Suite.DotProto.Generate.Syntax: do_ :: [ExprLStmt GhcPs] -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: fieldBind_ :: HsName -> HsExp -> LHsRecField GhcPs HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: fieldPunPat :: HsName -> LHsRecField GhcPs HsPat
+ Proto3.Suite.DotProto.Generate.Syntax: fieldUpd_ :: HsName -> HsExp -> LHsRecUpdField GhcPs GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: floatE :: RealFloat f => f -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: forceEmitT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formBoolT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formBytesT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formCardinalityOf :: HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: formCardinalityT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formDoubleT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formEnumerationT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formFieldNotFound :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formFieldOrOneOfNotFound :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formFixed32T :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formFixed64T :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formFloatT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formImplicitT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formInt32T :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formInt64T :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formMapT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formMessageT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formNamesOf :: HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: formNumberOf :: HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: formOneOfOf :: HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: formOptionalT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formPackedT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formProtoTypeOf :: HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: formProtoTypeT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formRepeatedT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formSFixed32T :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formSFixed64T :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formSInt32T :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formSInt64T :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formStringT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formUInt32T :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formUInt64T :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formUnpackedT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: formWrapperT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: fractionOp :: HsQOp
+ Proto3.Suite.DotProto.Generate.Syntax: funTy :: HsType -> HsType -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: functionLike_ :: SrcStrictness -> HsName -> [([HsPat], HsExp)] -> HsBind
+ Proto3.Suite.DotProto.Generate.Syntax: functionS_ :: String -> [([HsPat], HsExp)] -> HsBind
+ Proto3.Suite.DotProto.Generate.Syntax: function_ :: HsName -> [([HsPat], HsExp)] -> HsBind
+ Proto3.Suite.DotProto.Generate.Syntax: ieNameAll_ :: HsName -> HsImportSpec
+ Proto3.Suite.DotProto.Generate.Syntax: ieName_ :: HsName -> HsImportSpec
+ Proto3.Suite.DotProto.Generate.Syntax: if_ :: HsExp -> HsExp -> HsExp -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: implicitOuterFamEqnTyVarBinders_ :: HsOuterFamEqnTyVarBndrs
+ Proto3.Suite.DotProto.Generate.Syntax: implicitOuterSigTyVarBinders_ :: HsOuterSigTyVarBndrs
+ Proto3.Suite.DotProto.Generate.Syntax: instance (Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault a, Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault b) => Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault (a, b)
+ Proto3.Suite.DotProto.Generate.Syntax: instance (Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault a, Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault b, Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault c) => Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault (a, b, c)
+ Proto3.Suite.DotProto.Generate.Syntax: instance GHC.Parser.Annotation.NoAnn a => Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault (GHC.Parser.Annotation.EpAnn a)
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault ()
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault (GHC.Maybe.Maybe a)
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault (GHC.Parser.Annotation.AnnSortKey tag)
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault (GHC.Parser.Annotation.EpToken token)
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault (GHC.Parser.Annotation.EpUniToken token utoken)
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault (Language.Haskell.Syntax.Type.HsBndrVis GHC.Hs.Extension.GhcPs)
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault GHC.Hs.Binds.AnnSig
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault GHC.Hs.Expr.AnnsIf
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault GHC.Hs.Expr.EpAnnHsCase
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault GHC.Parser.Annotation.AnnParen
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault GHC.Parser.Annotation.AnnPragma
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault GHC.Parser.Annotation.IsUnicodeSyntax
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault GHC.Types.SourceText.SourceText
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault GHC.Types.SrcLoc.SrcSpan
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault Language.Haskell.Syntax.Extension.NoExtField
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault [a]
+ Proto3.Suite.DotProto.Generate.Syntax: instance Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault a => Proto3.Suite.DotProto.Generate.Syntax.SyntaxDefault (GHC.Types.SrcLoc.GenLocated GHC.Parser.Annotation.TokenLocation a)
+ Proto3.Suite.DotProto.Generate.Syntax: justN :: HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: justT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: kindSig_ :: HsType -> HsType -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: kindedTyVar_ :: flag -> HsName -> HsType -> LHsTyVarBndr flag GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: lambda_ :: [HsPat] -> HsExp -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: lastStmt_ :: HsExp -> ExprLStmt GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: letStmt_ :: [HsBind] -> ExprLStmt GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: let_ :: [HsBind] -> HsExp -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: listT_ :: [HsType] -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: list_ :: [HsExp] -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: maybeT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: natT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: natTLit :: Integral a => a -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: nothingN :: HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: nothingT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: opApp :: HsExp -> HsQOp -> HsExp -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: optionalC :: HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: parenPat :: HsPat -> HsPat
+ Proto3.Suite.DotProto.Generate.Syntax: parenTy :: HsType -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: patBind_ :: HsPat -> HsExp -> HsBind
+ Proto3.Suite.DotProto.Generate.Syntax: pattern PfxCon :: [arg] -> HsConDetails Void arg r
+ Proto3.Suite.DotProto.Generate.Syntax: pattern VirtualBraces :: Int -> EpLayout
+ Proto3.Suite.DotProto.Generate.Syntax: protobufFormNS :: ModuleName
+ Proto3.Suite.DotProto.Generate.Syntax: protobufFormName :: NameSpace -> String -> HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: protobufFormType :: NameSpace -> String -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: qual_ :: ModuleName -> NameSpace -> String -> HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: recPat :: HsQName -> [LHsRecField GhcPs HsPat] -> HsPat
+ Proto3.Suite.DotProto.Generate.Syntax: recordCtor_ :: HsName -> [LHsRecField GhcPs HsExp] -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: recordUpd_ :: HsExp -> [LHsRecUpdField GhcPs GhcPs] -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: splitDerivingClause :: HsDerivingClause -> (Maybe HsDerivStrategy, [(HsOuterSigTyVarBndrs, HsType)])
+ Proto3.Suite.DotProto.Generate.Syntax: splitTyApp :: HsType -> (HsType, [HsType])
+ Proto3.Suite.DotProto.Generate.Syntax: splitTyConApp :: HsType -> Maybe (HsName, [HsType])
+ Proto3.Suite.DotProto.Generate.Syntax: strPat :: String -> HsPat
+ Proto3.Suite.DotProto.Generate.Syntax: symT :: String -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: symbolT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: synDef :: SyntaxDefault a => a
+ Proto3.Suite.DotProto.Generate.Syntax: tupleT_ :: [HsType] -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: tupleType_ :: [HsType] -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: tuple_ :: [HsExp] -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: tvar_ :: String -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: tvarn_ :: String -> HsName
+ Proto3.Suite.DotProto.Generate.Syntax: tyApply :: HsType -> [HsType] -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: tyConApp :: HsName -> HsType -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: tyConApply :: HsName -> [HsType] -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: tyFamInstDecl_ :: HsQName -> Maybe [HsTyVarBndrU] -> [HsType] -> HsType -> HsDecl
+ Proto3.Suite.DotProto.Generate.Syntax: type HsAlt = LMatch GhcPs HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: type HsBangType = LBangType GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsBind = LHsBind GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsConDecl = LConDecl GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsDecl = LHsDecl GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsDerivStrategy = LDerivStrategy GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsDerivingClause = LHsDerivingClause GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsExp = LHsExpr GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsExportSpec = LIE GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsGrhs = LGRHS GhcPs HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: type HsGuardedAlts = GRHSs GhcPs HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: type HsImportDecl = LImportDecl GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsImportSpec = LIE GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsMatch = LMatch GhcPs HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: type HsName = LIdP GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsOuterFamEqnTyVarBndrs = HsOuterFamEqnTyVarBndrs GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsOuterSigTyVarBndrs = HsOuterSigTyVarBndrs GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsPat = LPat GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsQName = LIdP GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsQOp = LHsExpr GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsSig = LSig GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsTyVarBndrU = LHsTyVarBndr () GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsTyVarBndrV = LHsTyVarBndr HsBndrVis GhcPs GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type HsType = LHsType GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: type Module = ModuleName
+ Proto3.Suite.DotProto.Generate.Syntax: typeErrorT :: HsType
+ Proto3.Suite.DotProto.Generate.Syntax: typeNamed_ :: HsName -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: typeOfInstDecl :: HsDecl -> Maybe (HsOuterSigTyVarBndrs, HsType)
+ Proto3.Suite.DotProto.Generate.Syntax: typeSig_ :: [HsName] -> HsOuterSigTyVarBndrs -> HsType -> HsDecl
+ Proto3.Suite.DotProto.Generate.Syntax: unbangedTy_ :: HsType -> HsBangType
+ Proto3.Suite.DotProto.Generate.Syntax: unrestrictedArrow_ :: HsArrow GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: userTyVar_ :: flag -> HsName -> LHsTyVarBndr flag GhcPs
+ Proto3.Suite.DotProto.Generate.Syntax: valDecl_ :: HsBind -> HsDecl
+ Proto3.Suite.DotProto.Generate.Syntax: var_ :: HsQName -> HsExp
+ Proto3.Suite.DotProto.Generate.Syntax: wild_ :: HsPat
+ Proto3.Suite.DotProto.Internal: Histogram :: Map a Int -> Histogram a
+ Proto3.Suite.DotProto.Internal: RedefinedFields :: Histogram FieldName -> Histogram FieldNumber -> CompileError
+ Proto3.Suite.DotProto.Internal: instance GHC.Classes.Eq a => GHC.Classes.Eq (Proto3.Suite.DotProto.Internal.Histogram a)
+ Proto3.Suite.DotProto.Internal: instance GHC.Classes.Ord a => GHC.Base.Monoid (Proto3.Suite.DotProto.Internal.Histogram a)
+ Proto3.Suite.DotProto.Internal: instance GHC.Classes.Ord a => GHC.Base.Semigroup (Proto3.Suite.DotProto.Internal.Histogram a)
+ Proto3.Suite.DotProto.Internal: instance GHC.Classes.Ord a => GHC.Classes.Ord (Proto3.Suite.DotProto.Internal.Histogram a)
+ Proto3.Suite.DotProto.Internal: instance GHC.Show.Show a => GHC.Show.Show (Proto3.Suite.DotProto.Internal.Histogram a)
+ Proto3.Suite.DotProto.Internal: joinIntervals :: (Enum a, Ord a) => (a, a) -> (a, a) -> Maybe (a, a)
+ Proto3.Suite.DotProto.Internal: mergeIntervals :: (Enum a, Ord a) => [(a, a)] -> [(a, a)]
+ Proto3.Suite.DotProto.Internal: mulipleOccurrencesOnly :: Histogram a -> Histogram a
+ Proto3.Suite.DotProto.Internal: newtype Histogram a
+ Proto3.Suite.DotProto.Internal: nonconsecutive :: (Enum a, Ord a) => a -> a -> Bool
+ Proto3.Suite.DotProto.Internal: normalizeIntervals :: (Enum a, Ord a) => [(a, a)] -> [(a, a)]
+ Proto3.Suite.DotProto.Internal: oneOccurrence :: a -> Histogram a
+ Proto3.Suite.DotProto.Internal: type GettingM r s a = forall (m :: Type -> Type). Applicative m => a -> Compose m Const r :: Type -> Type a -> s -> Compose m Const r :: Type -> Type s
+ Proto3.Suite.DotProto.Parsing: pEmptyStmt :: ProtoParser ()
+ Proto3.Suite.Form: Bool :: ProtoType
+ Proto3.Suite.Form: Bytes :: ProtoType
+ Proto3.Suite.Form: Double :: ProtoType
+ Proto3.Suite.Form: Enumeration :: Type -> ProtoType
+ Proto3.Suite.Form: Fixed32 :: ProtoType
+ Proto3.Suite.Form: Fixed64 :: ProtoType
+ Proto3.Suite.Form: Float :: ProtoType
+ Proto3.Suite.Form: Implicit :: Cardinality
+ Proto3.Suite.Form: Int32 :: ProtoType
+ Proto3.Suite.Form: Int64 :: ProtoType
+ Proto3.Suite.Form: Map :: ProtoType -> ProtoType -> ProtoType
+ Proto3.Suite.Form: Message :: Type -> ProtoType
+ Proto3.Suite.Form: Optional :: Cardinality
+ Proto3.Suite.Form: Packed :: Packing
+ Proto3.Suite.Form: Repeated :: Packing -> Cardinality
+ Proto3.Suite.Form: SFixed32 :: ProtoType
+ Proto3.Suite.Form: SFixed64 :: ProtoType
+ Proto3.Suite.Form: SInt32 :: ProtoType
+ Proto3.Suite.Form: SInt64 :: ProtoType
+ Proto3.Suite.Form: String :: ProtoType
+ Proto3.Suite.Form: UInt32 :: ProtoType
+ Proto3.Suite.Form: UInt64 :: ProtoType
+ Proto3.Suite.Form: Unpacked :: Packing
+ Proto3.Suite.Form: class (RecoverCardinality haskellType ~ cardinality, RecoverProtoType haskellType ~ protoType) => MessageFieldType (cardinality :: Cardinality) (protoType :: ProtoType) haskellType
+ Proto3.Suite.Form: data Association (key :: ProtoType) (value :: ProtoType)
+ Proto3.Suite.Form: data Cardinality
+ Proto3.Suite.Form: data Packing
+ Proto3.Suite.Form: data ProtoType
+ Proto3.Suite.Form: data Wrapper (protoType :: ProtoType)
+ Proto3.Suite.Form: instance (Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit k kh, Proto3.Suite.Form.MessageFieldType (Proto3.Suite.Form.CardinalityOfMapped v) v vh) => Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) ('Proto3.Suite.Form.Map k v) (Data.Map.Internal.Map kh vh)
+ Proto3.Suite.Form: instance (Proto3.Suite.Form.OptionalMessageFieldType m haskellType, Proto3.Suite.Form.RecoverCardinality haskellType GHC.Types.~ 'Proto3.Suite.Form.Optional, Proto3.Suite.Form.RecoverProtoType haskellType GHC.Types.~ 'Proto3.Suite.Form.Message m) => Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message m) haskellType
+ Proto3.Suite.Form: instance (Proto3.Suite.Form.RepeatedMessageFieldType m haskellType, Proto3.Suite.Form.RecoverCardinality haskellType GHC.Types.~ 'Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked, Proto3.Suite.Form.RecoverProtoType haskellType GHC.Types.~ 'Proto3.Suite.Form.Message m) => Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) ('Proto3.Suite.Form.Message m) haskellType
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Bool GHC.Types.Bool
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Bytes (Proto3.Suite.Types.Bytes a)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Double GHC.Types.Double
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed32 (Proto3.Suite.Types.Fixed GHC.Word.Word32)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed64 (Proto3.Suite.Types.Fixed GHC.Word.Word64)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Float GHC.Types.Float
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int32 GHC.Int.Int32
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int64 GHC.Int.Int64
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed32 (Proto3.Suite.Types.Signed (Proto3.Suite.Types.Fixed GHC.Int.Int32))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed64 (Proto3.Suite.Types.Signed (Proto3.Suite.Types.Fixed GHC.Int.Int64))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt32 (Proto3.Suite.Types.Signed GHC.Int.Int32)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt64 (Proto3.Suite.Types.Signed GHC.Int.Int64)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.String (Proto3.Suite.Types.String a)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt32 GHC.Word.Word32
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt64 GHC.Word.Word64
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Implicit ('Proto3.Suite.Form.Enumeration e) (Proto3.Suite.Types.Enumerated e)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Bool (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit GHC.Types.Bool))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Bytes (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit (Proto3.Suite.Types.Bytes a)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Double (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit GHC.Types.Double))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed32 (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit (Proto3.Suite.Types.Fixed GHC.Word.Word32)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed64 (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit (Proto3.Suite.Types.Fixed GHC.Word.Word64)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Float (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit GHC.Types.Float))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int32 (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit GHC.Int.Int32))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int64 (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit GHC.Int.Int64))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed32 (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit (Proto3.Suite.Types.Signed (Proto3.Suite.Types.Fixed GHC.Int.Int32))))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed64 (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit (Proto3.Suite.Types.Signed (Proto3.Suite.Types.Fixed GHC.Int.Int64))))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt32 (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit (Proto3.Suite.Types.Signed GHC.Int.Int32)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt64 (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit (Proto3.Suite.Types.Signed GHC.Int.Int64)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.String (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit (Proto3.Suite.Types.String a)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt32 (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit GHC.Word.Word32))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt64 (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit GHC.Word.Word64))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Enumeration e) (GHC.Maybe.Maybe (Proto3.Suite.Types.ForceEmit (Proto3.Suite.Types.Enumerated e)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.Bool (Proto3.Suite.Types.PackedVec GHC.Types.Bool)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.Double (Proto3.Suite.Types.PackedVec GHC.Types.Double)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.Fixed32 (Proto3.Suite.Types.PackedVec (Proto3.Suite.Types.Fixed GHC.Word.Word32))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.Fixed64 (Proto3.Suite.Types.PackedVec (Proto3.Suite.Types.Fixed GHC.Word.Word64))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.Float (Proto3.Suite.Types.PackedVec GHC.Types.Float)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.Int32 (Proto3.Suite.Types.PackedVec GHC.Int.Int32)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.Int64 (Proto3.Suite.Types.PackedVec GHC.Int.Int64)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.SFixed32 (Proto3.Suite.Types.PackedVec (Proto3.Suite.Types.Signed (Proto3.Suite.Types.Fixed GHC.Int.Int32)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.SFixed64 (Proto3.Suite.Types.PackedVec (Proto3.Suite.Types.Signed (Proto3.Suite.Types.Fixed GHC.Int.Int64)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.SInt32 (Proto3.Suite.Types.PackedVec (Proto3.Suite.Types.Signed GHC.Int.Int32))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.SInt64 (Proto3.Suite.Types.PackedVec (Proto3.Suite.Types.Signed GHC.Int.Int64))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.UInt32 (Proto3.Suite.Types.PackedVec GHC.Word.Word32)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) 'Proto3.Suite.Form.UInt64 (Proto3.Suite.Types.PackedVec GHC.Word.Word64)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Packed) ('Proto3.Suite.Form.Enumeration e) (Proto3.Suite.Types.PackedVec (Proto3.Suite.Types.Enumerated e))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.Bool (Proto3.Suite.Types.UnpackedVec GHC.Types.Bool)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.Bytes (Proto3.Suite.Types.UnpackedVec (Proto3.Suite.Types.Bytes a))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.Double (Proto3.Suite.Types.UnpackedVec GHC.Types.Double)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.Fixed32 (Proto3.Suite.Types.UnpackedVec (Proto3.Suite.Types.Fixed GHC.Word.Word32))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.Fixed64 (Proto3.Suite.Types.UnpackedVec (Proto3.Suite.Types.Fixed GHC.Word.Word64))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.Float (Proto3.Suite.Types.UnpackedVec GHC.Types.Float)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.Int32 (Proto3.Suite.Types.UnpackedVec GHC.Int.Int32)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.Int64 (Proto3.Suite.Types.UnpackedVec GHC.Int.Int64)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.SFixed32 (Proto3.Suite.Types.UnpackedVec (Proto3.Suite.Types.Signed (Proto3.Suite.Types.Fixed GHC.Int.Int32)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.SFixed64 (Proto3.Suite.Types.UnpackedVec (Proto3.Suite.Types.Signed (Proto3.Suite.Types.Fixed GHC.Int.Int64)))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.SInt32 (Proto3.Suite.Types.UnpackedVec (Proto3.Suite.Types.Signed GHC.Int.Int32))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.SInt64 (Proto3.Suite.Types.UnpackedVec (Proto3.Suite.Types.Signed GHC.Int.Int64))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.String (Proto3.Suite.Types.UnpackedVec (Proto3.Suite.Types.String a))
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.UInt32 (Proto3.Suite.Types.UnpackedVec GHC.Word.Word32)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) 'Proto3.Suite.Form.UInt64 (Proto3.Suite.Types.UnpackedVec GHC.Word.Word64)
+ Proto3.Suite.Form: instance Proto3.Suite.Form.MessageFieldType ('Proto3.Suite.Form.Repeated 'Proto3.Suite.Form.Unpacked) ('Proto3.Suite.Form.Enumeration e) (Proto3.Suite.Types.UnpackedVec (Proto3.Suite.Types.Enumerated e))
+ Proto3.Suite.Form: type FieldNotFound message (name :: Symbol) = 'Text "Field " ':<>: 'ShowType name ':<>: 'Text " not found in message:" ':$$: 'ShowType message
+ Proto3.Suite.Form: type FieldOrOneOfNotFound message (name :: Symbol) = 'Text "Field or oneof " ':<>: 'ShowType name ':<>: 'Text " not found in message:" ':$$: 'ShowType message
+ Proto3.Suite.Form: type family RepeatedMessageFieldType m haskellType
+ Proto3.Suite.Form.Encode: Auto :: a -> Auto a
+ Proto3.Suite.Form.Encode: Reflection :: a -> Reflection a
+ Proto3.Suite.Form.Encode: UnsafeFieldsEncoder :: MessageBuilder -> FieldsEncoder message (possible :: [Symbol]) (following :: [Symbol])
+ Proto3.Suite.Form.Encode: UnsafeMessageEncoder :: MessageBuilder -> MessageEncoder message
+ Proto3.Suite.Form.Encode: Wrap :: a -> Wrap a
+ Proto3.Suite.Form.Encode: [unauto] :: Auto a -> a
+ Proto3.Suite.Form.Encode: [untypedFieldsEncoder] :: FieldsEncoder message (possible :: [Symbol]) (following :: [Symbol]) -> MessageBuilder
+ Proto3.Suite.Form.Encode: [untypedMessageEncoder] :: MessageEncoder message -> MessageBuilder
+ Proto3.Suite.Form.Encode: [unwrap] :: Wrap a -> a
+ Proto3.Suite.Form.Encode: 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
+ Proto3.Suite.Form.Encode: cacheFieldsEncoding :: forall message (possible :: [Symbol]) (following :: [Symbol]). FieldsEncoder message possible following -> FieldsEncoding message possible following
+ Proto3.Suite.Form.Encode: cacheMessageEncoding :: MessageEncoder message -> MessageEncoding message
+ Proto3.Suite.Form.Encode: cachedFieldsEncoding :: forall message (possible :: [Symbol]) (following :: [Symbol]). FieldsEncoding message possible following -> FieldsEncoder message possible following
+ Proto3.Suite.Form.Encode: cachedMessageEncoding :: MessageEncoding message -> MessageEncoder message
+ Proto3.Suite.Form.Encode: class Field (name :: Symbol) (a :: TYPE r) message
+ Proto3.Suite.Form.Encode: class FieldForm (cardinality :: Cardinality) (protoType :: ProtoType) (a :: TYPE r)
+ Proto3.Suite.Form.Encode: class SFieldNumberI (fieldNumber :: Nat)
+ Proto3.Suite.Form.Encode: data FieldsEncoding message (possible :: [Symbol]) (following :: [Symbol])
+ Proto3.Suite.Form.Encode: data MessageEncoding message
+ Proto3.Suite.Form.Encode: etaFieldsEncoder :: forall a message (possible :: [Symbol]) (following :: [Symbol]). (a -> FieldsEncoder message possible following) -> a -> FieldsEncoder message possible following
+ Proto3.Suite.Form.Encode: etaMessageEncoder :: (a -> MessageEncoder message) -> a -> MessageEncoder message
+ Proto3.Suite.Form.Encode: field :: forall (names :: [Symbol]). Field name a message => a -> FieldsEncoder message names (Occupy message name names)
+ Proto3.Suite.Form.Encode: fieldForm :: FieldForm cardinality protoType a => Proxy# cardinality -> Proxy# protoType -> FieldNumber -> a -> MessageBuilder
+ Proto3.Suite.Form.Encode: fieldsToMessage :: forall message (names :: [Symbol]). Distinct message names => FieldsEncoder message ('[] :: [Symbol]) names -> MessageEncoder message
+ Proto3.Suite.Form.Encode: foldFieldsEncoders :: forall c message (names :: [Symbol]). ToRepeated c (FieldsEncoder message names names) => c -> FieldsEncoder message names names
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Class.Message message, GHC.Show.Show message) => GHC.Show.Show (Proto3.Suite.Form.Encode.Core.MessageEncoder message)
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Class.Message message, GHC.Show.Show message) => GHC.Show.Show (Proto3.Suite.Form.Encode.MessageEncoding message)
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Class.Message message, Proto3.Suite.JSONPB.Class.FromJSONPB message) => Data.Aeson.Types.FromJSON.FromJSON (Proto3.Suite.Form.Encode.Core.MessageEncoder message)
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Class.Message message, Proto3.Suite.JSONPB.Class.FromJSONPB message) => Data.Aeson.Types.FromJSON.FromJSON (Proto3.Suite.Form.Encode.MessageEncoding message)
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Class.Message message, Proto3.Suite.JSONPB.Class.FromJSONPB message) => Proto3.Suite.JSONPB.Class.FromJSONPB (Proto3.Suite.Form.Encode.Core.MessageEncoder message)
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Class.Message message, Proto3.Suite.JSONPB.Class.FromJSONPB message) => Proto3.Suite.JSONPB.Class.FromJSONPB (Proto3.Suite.Form.Encode.MessageEncoding message)
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Class.Message message, Proto3.Suite.JSONPB.Class.ToJSONPB message) => Data.Aeson.Types.ToJSON.ToJSON (Proto3.Suite.Form.Encode.Core.MessageEncoder message)
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Class.Message message, Proto3.Suite.JSONPB.Class.ToJSONPB message) => Data.Aeson.Types.ToJSON.ToJSON (Proto3.Suite.Form.Encode.MessageEncoding message)
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Class.Message message, Proto3.Suite.JSONPB.Class.ToJSONPB message) => Proto3.Suite.JSONPB.Class.ToJSONPB (Proto3.Suite.Form.Encode.Core.MessageEncoder message)
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Class.Message message, Proto3.Suite.JSONPB.Class.ToJSONPB message) => Proto3.Suite.JSONPB.Class.ToJSONPB (Proto3.Suite.Form.Encode.MessageEncoding message)
+ Proto3.Suite.Form.Encode: instance (Proto3.Suite.Form.MessageFieldType cardinality protoType a, Proto3.Suite.Class.MessageField a) => Proto3.Suite.Form.Encode.Core.FieldForm cardinality protoType (Proto3.Suite.Form.Encode.Reflection a)
+ Proto3.Suite.Form.Encode: instance (Proto3.Wire.Class.ProtoEnum e, Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int32 GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit ('Proto3.Suite.Form.Enumeration e) (Proto3.Suite.Types.Enumerated e)
+ Proto3.Suite.Form.Encode: instance (Proto3.Wire.Class.ProtoEnum e, Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int32 GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit ('Proto3.Suite.Form.Enumeration e) e
+ Proto3.Suite.Form.Encode: instance (Proto3.Wire.Class.ProtoEnum e, Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int32 (Data.Functor.Identity.Identity GHC.Int.Int32)) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Enumeration e) (Data.Functor.Identity.Identity (Proto3.Suite.Types.Enumerated e))
+ Proto3.Suite.Form.Encode: instance (Proto3.Wire.Class.ProtoEnum e, Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int32 (Data.Functor.Identity.Identity GHC.Int.Int32)) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Enumeration e) (Data.Functor.Identity.Identity e)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ Data.ByteString.Short.Internal.ShortByteString) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Bytes (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ Data.ByteString.Short.Internal.ShortByteString) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Bytes (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ Data.ByteString.Short.Internal.ShortByteString) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Bytes)) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ Data.Text.Short.Internal.ShortText) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.String (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ Data.Text.Short.Internal.ShortText) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.String (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ Data.Text.Short.Internal.ShortText) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.String)) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int32 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed32 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt32 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int32 (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed32 (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt32 (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int32)) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int32 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed32 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int32) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt32 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int64 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed64 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt64 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int64 (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed64 (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt64 (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int64)) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int64) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int64 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int64) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed64 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Int.Int64) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt64 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Bool) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Bool (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Bool) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Bool (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Bool) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Bool)) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Bool) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Bool (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Double) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Double (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Double) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Double (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Double) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Double)) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Double) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Double (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Float) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Float (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Float) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Float (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Float) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Float)) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Types.Float) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Float (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed32 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt32 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed32 (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt32 (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word32) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.UInt32)) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word32) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Fixed32 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word32) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.UInt32 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed64 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt64 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed64 (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt64 (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word64) => Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.UInt64)) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.Core.Auto a))
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word64) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Fixed64 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance (a GHC.Types.~ GHC.Word.Word64) => Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.UInt64 (Proto3.Suite.Form.Encode.Core.Auto a)
+ Proto3.Suite.Form.Encode: instance Control.DeepSeq.NFData (Proto3.Suite.Form.Encode.MessageEncoding message)
+ Proto3.Suite.Form.Encode: instance GHC.Generics.Generic (Proto3.Suite.Form.Encode.MessageEncoding message)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Bool GHC.Types.Bool
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Bytes Data.ByteString.Internal.Type.ByteString
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Bytes Data.ByteString.Lazy.Internal.ByteString
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Bytes Data.ByteString.Short.Internal.ShortByteString
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Bytes Proto3.Wire.Reverse.Internal.BuildR
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Double GHC.Types.Double
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Double GHC.Types.Float
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed32 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed32 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed32 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed64 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed64 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed64 GHC.Word.Word64
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Fixed64 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Float GHC.Types.Float
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int32 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int32 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int32 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int32 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int32 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int64 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int64 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int64 GHC.Int.Int64
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int64 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int64 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int64 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.Int64 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed32 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed32 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed32 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed32 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed32 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed64 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed64 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed64 GHC.Int.Int64
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed64 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed64 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed64 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SFixed64 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt32 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt32 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt32 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt32 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt32 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt64 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt64 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt64 GHC.Int.Int64
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt64 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt64 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt64 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.SInt64 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.String Data.Text.Internal.Lazy.Text
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.String Data.Text.Internal.Text
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.String Data.Text.Short.Internal.ShortText
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt32 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt32 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt32 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt64 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt64 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt64 GHC.Word.Word64
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Implicit 'Proto3.Suite.Form.UInt64 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Bool (Data.Functor.Identity.Identity GHC.Types.Bool)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Bytes (Data.Functor.Identity.Identity Data.ByteString.Internal.Type.ByteString)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Bytes (Data.Functor.Identity.Identity Data.ByteString.Lazy.Internal.ByteString)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Bytes (Data.Functor.Identity.Identity Data.ByteString.Short.Internal.ShortByteString)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Bytes (Data.Functor.Identity.Identity Proto3.Wire.Reverse.Internal.BuildR)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Double (Data.Functor.Identity.Identity GHC.Types.Double)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Double (Data.Functor.Identity.Identity GHC.Types.Float)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed32 (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed32 (Data.Functor.Identity.Identity GHC.Word.Word32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed32 (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed64 (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed64 (Data.Functor.Identity.Identity GHC.Word.Word32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed64 (Data.Functor.Identity.Identity GHC.Word.Word64)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Fixed64 (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Float (Data.Functor.Identity.Identity GHC.Types.Float)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int32 (Data.Functor.Identity.Identity GHC.Int.Int16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int32 (Data.Functor.Identity.Identity GHC.Int.Int32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int32 (Data.Functor.Identity.Identity GHC.Int.Int8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int32 (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int32 (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int64 (Data.Functor.Identity.Identity GHC.Int.Int16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int64 (Data.Functor.Identity.Identity GHC.Int.Int32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int64 (Data.Functor.Identity.Identity GHC.Int.Int64)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int64 (Data.Functor.Identity.Identity GHC.Int.Int8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int64 (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int64 (Data.Functor.Identity.Identity GHC.Word.Word32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.Int64 (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed32 (Data.Functor.Identity.Identity GHC.Int.Int16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed32 (Data.Functor.Identity.Identity GHC.Int.Int32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed32 (Data.Functor.Identity.Identity GHC.Int.Int8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed32 (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed32 (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed64 (Data.Functor.Identity.Identity GHC.Int.Int16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed64 (Data.Functor.Identity.Identity GHC.Int.Int32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed64 (Data.Functor.Identity.Identity GHC.Int.Int64)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed64 (Data.Functor.Identity.Identity GHC.Int.Int8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed64 (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed64 (Data.Functor.Identity.Identity GHC.Word.Word32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SFixed64 (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt32 (Data.Functor.Identity.Identity GHC.Int.Int16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt32 (Data.Functor.Identity.Identity GHC.Int.Int32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt32 (Data.Functor.Identity.Identity GHC.Int.Int8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt32 (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt32 (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt64 (Data.Functor.Identity.Identity GHC.Int.Int16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt64 (Data.Functor.Identity.Identity GHC.Int.Int32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt64 (Data.Functor.Identity.Identity GHC.Int.Int64)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt64 (Data.Functor.Identity.Identity GHC.Int.Int8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt64 (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt64 (Data.Functor.Identity.Identity GHC.Word.Word32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.SInt64 (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.String (Data.Functor.Identity.Identity Data.Text.Internal.Lazy.Text)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.String (Data.Functor.Identity.Identity Data.Text.Internal.Text)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.String (Data.Functor.Identity.Identity Data.Text.Short.Internal.ShortText)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt32 (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt32 (Data.Functor.Identity.Identity GHC.Word.Word32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt32 (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt64 (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt64 (Data.Functor.Identity.Identity GHC.Word.Word32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt64 (Data.Functor.Identity.Identity GHC.Word.Word64)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional 'Proto3.Suite.Form.UInt64 (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Map key value) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.MessageEncoding (Proto3.Suite.Form.Association key value)))
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Bool)) (Data.Functor.Identity.Identity GHC.Types.Bool)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Bytes)) (Data.Functor.Identity.Identity Data.ByteString.Internal.Type.ByteString)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Bytes)) (Data.Functor.Identity.Identity Data.ByteString.Lazy.Internal.ByteString)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Bytes)) (Data.Functor.Identity.Identity Data.ByteString.Short.Internal.ShortByteString)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Double)) (Data.Functor.Identity.Identity GHC.Types.Double)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Double)) (Data.Functor.Identity.Identity GHC.Types.Float)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Float)) (Data.Functor.Identity.Identity GHC.Types.Float)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int32)) (Data.Functor.Identity.Identity GHC.Int.Int16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int32)) (Data.Functor.Identity.Identity GHC.Int.Int32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int32)) (Data.Functor.Identity.Identity GHC.Int.Int8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int32)) (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int32)) (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int64)) (Data.Functor.Identity.Identity GHC.Int.Int16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int64)) (Data.Functor.Identity.Identity GHC.Int.Int32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int64)) (Data.Functor.Identity.Identity GHC.Int.Int64)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int64)) (Data.Functor.Identity.Identity GHC.Int.Int8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int64)) (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int64)) (Data.Functor.Identity.Identity GHC.Word.Word32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.Int64)) (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.String)) (Data.Functor.Identity.Identity Data.Text.Internal.Lazy.Text)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.String)) (Data.Functor.Identity.Identity Data.Text.Internal.Text)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.String)) (Data.Functor.Identity.Identity Data.Text.Short.Internal.ShortText)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.UInt32)) (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.UInt32)) (Data.Functor.Identity.Identity GHC.Word.Word32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.UInt32)) (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.UInt64)) (Data.Functor.Identity.Identity GHC.Word.Word16)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.UInt64)) (Data.Functor.Identity.Identity GHC.Word.Word32)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.UInt64)) (Data.Functor.Identity.Identity GHC.Word.Word64)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message (Proto3.Suite.Form.Wrapper 'Proto3.Suite.Form.UInt64)) (Data.Functor.Identity.Identity GHC.Word.Word8)
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.FieldForm 'Proto3.Suite.Form.Optional ('Proto3.Suite.Form.Message inner) (Data.Functor.Identity.Identity (Proto3.Suite.Form.Encode.MessageEncoding inner))
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Bool GHC.Types.Bool
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Double GHC.Types.Double
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Double GHC.Types.Float
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Fixed32 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Fixed32 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Fixed32 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Fixed64 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Fixed64 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Fixed64 GHC.Word.Word64
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Fixed64 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Float GHC.Types.Float
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int32 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int32 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int32 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int32 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int32 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int64 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int64 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int64 GHC.Int.Int64
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int64 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int64 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int64 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.Int64 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed32 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed32 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed32 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed32 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed32 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed64 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed64 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed64 GHC.Int.Int64
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed64 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed64 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed64 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SFixed64 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt32 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt32 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt32 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt32 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt32 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt64 GHC.Int.Int16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt64 GHC.Int.Int32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt64 GHC.Int.Int64
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt64 GHC.Int.Int8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt64 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt64 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.SInt64 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.UInt32 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.UInt32 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.UInt32 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.UInt64 GHC.Word.Word16
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.UInt64 GHC.Word.Word32
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.UInt64 GHC.Word.Word64
+ Proto3.Suite.Form.Encode: instance Proto3.Suite.Form.Encode.Core.PackedFieldForm 'Proto3.Suite.Form.UInt64 GHC.Word.Word8
+ Proto3.Suite.Form.Encode: instance Proto3.Wire.Class.ProtoEnum e => Proto3.Suite.Form.Encode.Core.PackedFieldForm ('Proto3.Suite.Form.Enumeration e) (Proto3.Suite.Types.Enumerated e)
+ Proto3.Suite.Form.Encode: instance Proto3.Wire.Class.ProtoEnum e => Proto3.Suite.Form.Encode.Core.PackedFieldForm ('Proto3.Suite.Form.Enumeration e) e
+ Proto3.Suite.Form.Encode: 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)
+ Proto3.Suite.Form.Encode: messageCache :: Message message => message -> MessageEncoding message
+ Proto3.Suite.Form.Encode: messageEncoderToByteString :: MessageEncoder message -> ByteString
+ Proto3.Suite.Form.Encode: messageEncoderToLazyByteString :: MessageEncoder message -> ByteString
+ Proto3.Suite.Form.Encode: messageEncodingToByteString :: MessageEncoding message -> ByteString
+ Proto3.Suite.Form.Encode: messageReflection :: Message message => message -> MessageEncoder message
+ Proto3.Suite.Form.Encode: newtype Auto a
+ Proto3.Suite.Form.Encode: newtype FieldsEncoder message (possible :: [Symbol]) (following :: [Symbol])
+ Proto3.Suite.Form.Encode: newtype MessageEncoder message
+ Proto3.Suite.Form.Encode: newtype Reflection a
+ Proto3.Suite.Form.Encode: newtype Wrap a
+ Proto3.Suite.Form.Encode: omitted :: forall message (names :: [Symbol]) (moreNames :: [Symbol]). NameSublist names moreNames => FieldsEncoder message names moreNames
+ Proto3.Suite.Form.Encode: type Distinct message (names :: [Symbol]) = DistinctCheck message RepeatedNames OccupiedOnly message names
+ Proto3.Suite.Form.Encode: type KnownFieldNumber message (name :: Symbol) = SFieldNumberI NumberOf message name
+ Proto3.Suite.Form.Encode: type Occupy message (name :: Symbol) (names :: [Symbol]) = Occupy1 message name names CardinalityOf message name
+ Proto3.Suite.Form.Encode: type family NameSublist (names :: [Symbol]) (moreNames :: [Symbol])
+ Proto3.Suite.Form.Encode: unsafeByteStringToMessageEncoder :: ByteString -> MessageEncoder message
+ Proto3.Suite.Form.Encode: unsafeByteStringToMessageEncoding :: ByteString -> MessageEncoding message
+ Proto3.Suite.Haskell.Parser: data Logger
+ Proto3.Suite.Haskell.Parser: initLogger :: IO Logger
+ Proto3.Suite.Haskell.Parser: parseModule :: Logger -> RealSrcLoc -> StringBuffer -> IO (Maybe (Located (HsModule GhcPs)))
+ Proto3.Suite.Haskell.Parser: renderSDoc :: SDoc -> String
+ Proto3.Suite.JSONPB: ($dmdeclareNamedSchema) :: (ToSchema a, Generic a, GToSchema (Rep a), TypeHasSimpleShape a "genericDeclareNamedSchemaUnrestricted") => Proxy a -> Declare (Definitions Schema) NamedSchema
+ Proto3.Suite.JSONPB: ($dmparseJSON) :: (FromJSON a, Generic a, GFromJSON Zero (Rep a)) => Value -> Parser a
+ Proto3.Suite.JSONPB: ($dmtoJSON) :: (ToJSON a, Generic a, GToJSON' Value Zero (Rep a)) => a -> Value
+ Proto3.Suite.JSONPB: omitField :: ToJSON a => a -> Bool
+ Proto3.Suite.JSONPB: omittedField :: FromJSON a => Maybe a
+ Proto3.Suite.JSONPB.Class: instance Proto3.Suite.JSONPB.Class.FromJSONPB Data.ByteString.Internal.Type.ByteString
+ Proto3.Suite.JSONPB.Class: instance Proto3.Suite.JSONPB.Class.FromJSONPB a => Proto3.Suite.JSONPB.Class.FromJSONPB (Proto3.Suite.Types.ForceEmit a)
+ Proto3.Suite.JSONPB.Class: instance Proto3.Suite.JSONPB.Class.ToJSONPB Data.ByteString.Internal.Type.ByteString
+ Proto3.Suite.JSONPB.Class: instance Proto3.Suite.JSONPB.Class.ToJSONPB a => Proto3.Suite.JSONPB.Class.ToJSONPB (Proto3.Suite.Types.ForceEmit a)
+ Proto3.Suite.Types: codeFromEnumerated :: ProtoEnum e => Enumerated e -> Int32
+ Proto3.Suite.Types: codeToEnumerated :: ProtoEnum e => Int32 -> Enumerated e
+ Proto3.Suite.Types: instance GHC.IsList.IsList (Proto3.Suite.Types.NestedVec a)
+ Proto3.Suite.Types: instance GHC.IsList.IsList (Proto3.Suite.Types.PackedVec a)
+ Proto3.Suite.Types: instance GHC.IsList.IsList (Proto3.Suite.Types.UnpackedVec a)
- Proto3.Suite: decodeMessage :: (Message a, Generic a, GenericMessage (Rep a)) => FieldNumber -> Parser RawMessage a
+ Proto3.Suite: decodeMessage :: Message a => FieldNumber -> Parser RawMessage a
- Proto3.Suite: decodeMessageField :: (MessageField a, HasDefault a, Primitive a) => Parser RawField a
+ Proto3.Suite: decodeMessageField :: MessageField a => Parser RawField a
- Proto3.Suite: def :: (HasDefault a, Generic a, GenericHasDefault (Rep a)) => a
+ Proto3.Suite: def :: HasDefault a => a
- Proto3.Suite: dotProto :: (Message a, GenericMessage (Rep a)) => Proxy# a -> [DotProtoField]
+ Proto3.Suite: dotProto :: Message a => Proxy# a -> [DotProtoField]
- Proto3.Suite: encodeMessage :: (Message a, Generic a, GenericMessage (Rep a)) => FieldNumber -> a -> MessageBuilder
+ Proto3.Suite: encodeMessage :: Message a => FieldNumber -> a -> MessageBuilder
- Proto3.Suite: encodeMessageField :: (MessageField a, HasDefault a, Primitive a) => FieldNumber -> a -> MessageBuilder
+ Proto3.Suite: encodeMessageField :: MessageField a => FieldNumber -> a -> MessageBuilder
- Proto3.Suite: enumerate :: (Finite a, IsString string, Generic a, GenericFinite (Rep a)) => Proxy# a -> [(string, Int32)]
+ Proto3.Suite: enumerate :: (Finite a, IsString string) => Proxy# a -> [(string, Int32)]
- Proto3.Suite: isDefault :: (HasDefault a, Eq a) => a -> Bool
+ Proto3.Suite: isDefault :: HasDefault a => a -> Bool
- Proto3.Suite: nameOf :: (Named a, IsString string, GenericNamed (Rep a)) => Proxy# a -> string
+ Proto3.Suite: nameOf :: (Named a, IsString string) => Proxy# a -> string
- Proto3.Suite: primType :: (Primitive a, Named a) => Proxy# a -> DotProtoPrimType
+ Proto3.Suite: primType :: Primitive a => Proxy# a -> DotProtoPrimType
- Proto3.Suite: protoType :: (MessageField a, Primitive a) => Proxy# a -> DotProtoField
+ Proto3.Suite: protoType :: MessageField a => Proxy# a -> DotProtoField
- Proto3.Suite.Class: coerceOver :: forall a b f. Coercible (f a) (f b) => f a -> f b
+ Proto3.Suite.Class: coerceOver :: forall {k} (a :: k) (b :: k) f. Coercible (f a) (f b) => f a -> f b
- Proto3.Suite.Class: decodeMessage :: (Message a, Generic a, GenericMessage (Rep a)) => FieldNumber -> Parser RawMessage a
+ Proto3.Suite.Class: decodeMessage :: Message a => FieldNumber -> Parser RawMessage a
- Proto3.Suite.Class: decodeMessageField :: (MessageField a, HasDefault a, Primitive a) => Parser RawField a
+ Proto3.Suite.Class: decodeMessageField :: MessageField a => Parser RawField a
- Proto3.Suite.Class: def :: (HasDefault a, Generic a, GenericHasDefault (Rep a)) => a
+ Proto3.Suite.Class: def :: HasDefault a => a
- Proto3.Suite.Class: dotProto :: (Message a, GenericMessage (Rep a)) => Proxy# a -> [DotProtoField]
+ Proto3.Suite.Class: dotProto :: Message a => Proxy# a -> [DotProtoField]
- Proto3.Suite.Class: encodeMessage :: (Message a, Generic a, GenericMessage (Rep a)) => FieldNumber -> a -> MessageBuilder
+ Proto3.Suite.Class: encodeMessage :: Message a => FieldNumber -> a -> MessageBuilder
- Proto3.Suite.Class: encodeMessageField :: (MessageField a, HasDefault a, Primitive a) => FieldNumber -> a -> MessageBuilder
+ Proto3.Suite.Class: encodeMessageField :: MessageField a => FieldNumber -> a -> MessageBuilder
- Proto3.Suite.Class: enumerate :: (Finite a, IsString string, Generic a, GenericFinite (Rep a)) => Proxy# a -> [(string, Int32)]
+ Proto3.Suite.Class: enumerate :: (Finite a, IsString string) => Proxy# a -> [(string, Int32)]
- Proto3.Suite.Class: isDefault :: (HasDefault a, Eq a) => a -> Bool
+ Proto3.Suite.Class: isDefault :: HasDefault a => a -> Bool
- Proto3.Suite.Class: nameOf :: (Named a, IsString string, GenericNamed (Rep a)) => Proxy# a -> string
+ Proto3.Suite.Class: nameOf :: (Named a, IsString string) => Proxy# a -> string
- Proto3.Suite.Class: primType :: (Primitive a, Named a) => Proxy# a -> DotProtoPrimType
+ Proto3.Suite.Class: primType :: Primitive a => Proxy# a -> DotProtoPrimType
- Proto3.Suite.Class: protoType :: (MessageField a, Primitive a) => Proxy# a -> DotProtoField
+ Proto3.Suite.Class: protoType :: MessageField a => Proxy# a -> DotProtoField
- Proto3.Suite.Class: unsafeCoerceOver :: forall a b f. f a -> f b
+ Proto3.Suite.Class: unsafeCoerceOver :: forall {k} (a :: k) (b :: k) f. f a -> f b
- Proto3.Suite.DotProto.Generate: CompileArgs :: [FilePath] -> [FilePath] -> FilePath -> FilePath -> StringType -> RecordStyle -> CompileArgs
+ Proto3.Suite.DotProto.Generate: CompileArgs :: [FilePath] -> [FilePath] -> FilePath -> FilePath -> StringType -> Bool -> CompileArgs
- Proto3.Suite.DotProto.Generate: compileDotProtoFile :: CompileArgs -> IO (Either CompileError ())
+ Proto3.Suite.DotProto.Generate: compileDotProtoFile :: Logger -> CompileArgs -> IO (Either CompileError ())
- Proto3.Suite.DotProto.Generate: compileDotProtoFileOrDie :: CompileArgs -> IO ()
+ Proto3.Suite.DotProto.Generate: compileDotProtoFileOrDie :: Logger -> CompileArgs -> IO ()
- Proto3.Suite.DotProto.Generate: hsModuleForDotProto :: MonadError CompileError m => StringType -> RecordStyle -> ([HsImportDecl], [HsDecl]) -> DotProto -> TypeContext -> m HsModule
+ Proto3.Suite.DotProto.Generate: hsModuleForDotProto :: (MonadError CompileError m, ?stringType :: StringType, ?typeLevelFormat :: Bool) => ([HsImportDecl], [HsDecl]) -> DotProto -> TypeContext -> m (HsModule GhcPs)
- Proto3.Suite.DotProto.Generate: renderHsModuleForDotProto :: MonadError CompileError m => StringType -> RecordStyle -> ([HsImportDecl], [HsDecl]) -> DotProto -> TypeContext -> m String
+ Proto3.Suite.DotProto.Generate: renderHsModuleForDotProto :: (MonadError CompileError m, ?stringType :: StringType, ?typeLevelFormat :: Bool) => ([HsImportDecl], [HsDecl]) -> DotProto -> TypeContext -> m String
- Proto3.Suite.DotProto.Generate.Syntax: alt_ :: HsPat -> HsGuardedAlts -> [HsDecl] -> HsAlt
+ Proto3.Suite.DotProto.Generate.Syntax: alt_ :: HsPat -> HsExp -> HsAlt
- Proto3.Suite.DotProto.Generate.Syntax: dataDecl_ :: String -> [HsConDecl] -> [HsQName] -> HsDecl
+ Proto3.Suite.DotProto.Generate.Syntax: dataDecl_ :: String -> [HsTyVarBndrV] -> [HsConDecl] -> [HsQName] -> HsDecl
- Proto3.Suite.DotProto.Generate.Syntax: grpcName :: String -> HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: grpcName :: NameSpace -> String -> HsQName
- Proto3.Suite.DotProto.Generate.Syntax: haskellNS :: Module
+ Proto3.Suite.DotProto.Generate.Syntax: haskellNS :: ModuleName
- Proto3.Suite.DotProto.Generate.Syntax: haskellName :: String -> HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: haskellName :: NameSpace -> String -> HsQName
- Proto3.Suite.DotProto.Generate.Syntax: importDecl_ :: Module -> Bool -> Maybe Module -> Maybe (Bool, [HsImportSpec]) -> HsImportDecl
+ Proto3.Suite.DotProto.Generate.Syntax: importDecl_ :: ModuleName -> Bool -> Maybe ModuleName -> Maybe (Bool, [HsImportSpec]) -> HsImportDecl
- Proto3.Suite.DotProto.Generate.Syntax: instDecl_ :: HsQName -> [HsType] -> [HsDecl] -> HsDecl
+ Proto3.Suite.DotProto.Generate.Syntax: instDecl_ :: HsQName -> [HsType] -> [HsBind] -> HsDecl
- Proto3.Suite.DotProto.Generate.Syntax: jsonpbName :: String -> HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: jsonpbName :: NameSpace -> String -> HsQName
- Proto3.Suite.DotProto.Generate.Syntax: lrName :: String -> HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: lrName :: NameSpace -> String -> HsQName
- Proto3.Suite.DotProto.Generate.Syntax: module_ :: Module -> Maybe [HsExportSpec] -> [HsImportDecl] -> [HsDecl] -> HsModule
+ Proto3.Suite.DotProto.Generate.Syntax: module_ :: ModuleName -> Maybe [HsExportSpec] -> [HsImportDecl] -> [HsDecl] -> HsModule GhcPs
- Proto3.Suite.DotProto.Generate.Syntax: protobufASTName :: String -> HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: protobufASTName :: NameSpace -> String -> HsQName
- Proto3.Suite.DotProto.Generate.Syntax: protobufName :: String -> HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: protobufName :: NameSpace -> String -> HsQName
- Proto3.Suite.DotProto.Generate.Syntax: proxyName :: String -> HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: proxyName :: NameSpace -> String -> HsQName
- Proto3.Suite.DotProto.Generate.Syntax: tyApp :: HsType -> [HsType] -> HsType
+ Proto3.Suite.DotProto.Generate.Syntax: tyApp :: HsType -> HsType -> HsType
- Proto3.Suite.DotProto.Generate.Syntax: unqual_ :: String -> HsQName
+ Proto3.Suite.DotProto.Generate.Syntax: unqual_ :: NameSpace -> String -> HsName
- Proto3.Suite.DotProto.Internal: FieldOneOf :: OneofField -> FieldInfo
+ Proto3.Suite.DotProto.Internal: FieldOneOf :: FieldName -> OneofField -> FieldInfo
- Proto3.Suite.DotProto.Internal: suffixBy :: forall a. (a -> Bool) -> [a] -> Either [a] ([a], [a])
+ Proto3.Suite.DotProto.Internal: suffixBy :: (a -> Bool) -> [a] -> Either [a] ([a], [a])
- Proto3.Suite.DotProto.Internal: type FindProtoResult = Either String (Maybe (Path, FilePath))
+ Proto3.Suite.DotProto.Internal: type FindProtoResult = Either String Maybe (Path, FilePath)
- Proto3.Suite.JSONPB: enumFieldEncoding :: forall a. (Named a, Show a) => a -> Encoding
+ Proto3.Suite.JSONPB: enumFieldEncoding :: (Named a, Show a) => a -> Encoding
- Proto3.Suite.JSONPB: enumFieldString :: forall a. (Named a, Show a) => a -> Value
+ Proto3.Suite.JSONPB: enumFieldString :: (Named a, Show a) => a -> Value
- Proto3.Suite.JSONPB.Class: enumFieldEncoding :: forall a. (Named a, Show a) => a -> Encoding
+ Proto3.Suite.JSONPB.Class: enumFieldEncoding :: (Named a, Show a) => a -> Encoding
- Proto3.Suite.JSONPB.Class: enumFieldString :: forall a. (Named a, Show a) => a -> Value
+ Proto3.Suite.JSONPB.Class: enumFieldString :: (Named a, Show a) => a -> Value

Files

CHANGELOG.md view
@@ -1,3 +1,94 @@+# 0.9.4+* [#289](https://github.com/awakesecurity/proto3-suite/pull/289) Support optional fields+  * Support optional fields (outside of a `oneof`).  Such fields are allowed+    by newer versions of the proto3 specification (and even recommended by it).+  * Correctly prohibit `map` and `repeated` fields within a `oneof`+    (and continue to prohibit `optional` fields within a `oneof`).+  * [BREAKING CHANGE in experimental module: When encoding a `oneof` field, the `field`+     method now expects `Maybe a` or `Identity a` where it used to expect plain `a`.+     Similarly, any instantiation of `FieldForm` for `Singular Alternative` should be+     changed to specify `Optional` instead, and must wrap the argument type in `Identity`.+     The type-level descriptions of cardinality have been reorganized to better reflect+     standard terminology and encoding: `...Repetition...` -> `...Cardinality...`,+     `Singular Implicit` -> `Implicit`, `Singular Alternative` -> `Optional`.+     The `Omission` type is no longer needed and has been removed.]+  * When using `field` to encode an `optional` or `oneof` field that in practice+    is always present, you may now replace the `Just` data constructor with+    the `Identity` newtype constructor in order to express that fact.  When+    extending `FieldForm` at type `Optional`, define the instance for `Identity`+    because the general `Maybe` instance delegates to `Identity` in the `Just` case.++# 0.9.3+* [#284](https://github.com/awakesecurity/proto3-suite/pull/284) Delete Repeated.hs+  * [BREAKING CHANGE in experimental module: Rename `Prefix` to `FieldsEncoder`, along with related functions.]+  * [BREAKING CHANGE in experimental module: Rename `Fields` to `FieldsEncoding`, along with related functions.]+  * Add instances of `FromJSON`, `FromJSONPB`, `ToJSON`, `ToJSONPB`+    for `MessageEncoding` and `MessageEncoder`.+* [#290](https://github.com/awakesecurity/proto3-suite/pull/290)+  * Support tasty-1.5+  * Drop support for GHC 9.2+* [#291](https://github.com/awakesecurity/proto3-suite/pull/291) Optimize isDefault instances++# 0.9.2+* [#282](https://github.com/awakesecurity/proto3-suite/pull/282) Show MessageEncoder+  * [BREAKING CHANGE in experimental module: Rename `toLazyByteString` to `messageEncoderToLazyByteString`.]+  * [BREAKING CHANGE in experimental module: Rename `cacheMessage` to `messageCache`.]+  * [BREAKING CHANGE in experimental module: Delete `Eq` instance for `MessageEncoding` because it is application-defined whether we should ignore field order during comparison.]+  * Add `Show` instance for `MessageEncoder`.+  * Add `messageEncoderToByteString` and `unsafeByteStringToMessageEncoder`.+* [#283](https://github.com/awakesecurity/proto3-suite/pull/283) Delete Repeated.hs+  * Delete unused experimental source file `src/Proto3/Suite/Form/Encode/Repeated.hs`;+    proto3-wire provides the relevant functionality in `Proto3.Wire.Encode.Repeated`.++# 0.9.1+* [#275](https://github.com/awakesecurity/proto3-suite/pull/275) the `canonicalize-proto-file` executable no longer depends on the [`range-set-list](https://github.com/phadej/range-set-list#readme) package for normalizing reserved field ranges.+* Relocated orphaned [`Pretty`](https://hackage.haskell.org/package/pretty-1.1.3.6/docs/Text-PrettyPrint-HughesPJClass.html#t:Pretty) instances for AST types to [`Proto3.Suite.DotProto.AST`].++# 0.9.0+* [#272](https://github.com/awakesecurity/proto3-suite/pull/272) removed support for `large-records` and `large-generics`.+* [#274](https://github.com/awakesecurity/proto3-suite/pull/274) Support aeson-2.2.+* [#276](https://github.com/awakesecurity/proto3-suite/pull/276)+  * Switch dependency from `ghc` to `ghc-lib-parser`+  * Drop support for GHC 9.0.++# 0.8.3+* Fix overlong encoding of packed "sint32" fields containing elements in+  [-0x80000000, -0x40000001] or [0x40000000, 0x7FFFFFFF], which increased+  message size and hindered forward compatibility of "sint32" with "sint64".+* Add "--stringType" as a preferred spelling of "--string-type"+  because its style matches that of other options.+* Add compiler error "RedefinedFields".+* Export codeFromEnumerated and codeToEnumerated.+* Add an experimental feature to encode without using+  intermediate data structures; see Proto3.Suite.Form and+  the new compile-proto-file option --typeLevelFormat++# 0.8.2+* Support GHC 9.10.+* Test with nixpkgs-24.11.++# 0.8.1+* Fix support for dhall-1.42.+* Support dhall on GHC 9.8.+* Fix aeson upper bound in library target (was correct in test target).+* Fix default compiler version in shell.nix.+* Test with GHC 9.8.2 instead of GHC 9.8.1 and GHC 9.6.5 instead of GHC 9.6.2.+* Test with nixpkgs-24.05 but always using aeson-2.1.2.1.++# 0.8.0+* [BREAKING CHANGE: Use "ghc" library in place of "haskell-src".]+  The "ghc" library is now used to parse and print Haskell source code.+  Switching to "ghc" adds support for language features beyond Haskell 98+  and should improve diagnostic messages for sources specified with+  "--extraInstanceFile".  Breakage should be limited to users of:+  * Proto3.Suite.DotProto.Generate+  * Proto3.Suite.DotProto.Generate.LargeRecord+  * Proto3.Suite.DotProto.Generate.Syntax+* Drop support for GHC 8.10.+* On Darwin, drop support for GHC 9.0.+* Add support for GHC 9.6 (without large-records).+* Add support for GHC 9.8 (without large-records, dhall).+ # 0.7.0 * Support GHC 9.2, 9.4. * Support proto files without a package declaration.
proto3-suite.cabal view
@@ -1,6 +1,6 @@ cabal-version:       2.2 name:                proto3-suite-version:             0.7.0+version:             0.9.4 synopsis:            A higher-level API to the proto3-wire library description:   This library provides a higher-level API to <https://github.com/awakesecurity/proto3-wire the `proto3-wire` library>@@ -17,12 +17,19 @@ license:             Apache-2.0 author:              Arista Networks <opensource@awakesecurity.com> maintainer:          Arista Networks <opensource@awakesecurity.com>-copyright:           2017-2020 Awake Security, 2021-2022 Arista Networks+copyright:           2017-2020 Awake Security, 2021-2025 Arista Networks category:            Codec build-type:          Simple-data-files:          test-files/*.bin tests/encode.sh tests/decode.sh-extra-source-files:  CHANGELOG.md, gen/.gitignore +data-files:+  test-files/*.bin +  tests/encode.sh +  tests/decode.sh++extra-source-files:+  CHANGELOG.md, +  gen/.gitignore+ flag dhall   Description:   Turn on Dhall interpret and inject codegen   Default:       False@@ -38,21 +45,42 @@   Default:       False   Manual:        True -flag large-records-  Description:   Generate records with smaller core code size using the large-records library+flag attoparsec-aeson+  Description:   Depend upon the Haskell package "attoparsec-aeson".   Default:       True-  Manual:        True+  Manual:        False+    -- "Manual: False" to automatically skip "attoparsec-aeson" if it is not available +flag development+  Description: Enable development-specific options.+  Default:     False +  Manual:      True+ source-repository head   type:     git   location: https://github.com/awakesecurity/proto3-suite  common common+  default-language: Haskell2010   default-extensions:-    DeriveDataTypeable DeriveGeneric+    BlockArguments ExplicitNamespaces DeriveDataTypeable DeriveGeneric+    ImportQualifiedPost ViewPatterns +  if flag(development)+    ghc-options:+      -Werror++  build-depends:+      base >=4.15 && <5.0+    , proto3-wire >= 1.4.6 && < 1.5++  ghc-options:+    -O2 +    -Wall+ library-  import: common+  import:           common+  hs-source-dirs:   src    if flag(dhall)     exposed-modules:   Proto3.Suite.DhallPB@@ -60,89 +88,91 @@     cpp-options:       -DDHALL    if flag(swagger)-    exposed-modules:   Proto3.Suite.DotProto.Generate.Swagger-                       Proto3.Suite.DotProto.Generate.Swagger.Wrappers-    build-depends:     swagger2 >=2.1.6 && <2.9-    cpp-options:       -DSWAGGER+    build-depends:+      swagger2 >=2.1.6 && <2.9++    cpp-options:       +      -DSWAGGER++    exposed-modules:+      Proto3.Suite.DotProto.Generate.Swagger+      Proto3.Suite.DotProto.Generate.Swagger.Wrappers+     if flag(swagger-wrapper-format)-      hs-source-dirs:  src/swagger-wrapper-format+      hs-source-dirs: src/swagger-wrapper-format     else-      hs-source-dirs:  src/no-swagger-wrapper-format+      hs-source-dirs: src/no-swagger-wrapper-format -  if flag(large-records)-    -- large-records support uses newer Dhall APIs. So we need at least 1.34.-    build-depends:     dhall >=1.34 && < 1.43,-                       large-generics,-                       large-records-    cpp-options:       -DLARGE_RECORDS+  exposed-modules:     +    Proto3.Suite+    Proto3.Suite.Class+    Proto3.Suite.DotProto+    Proto3.Suite.DotProto.AST+    Proto3.Suite.DotProto.AST.Lens+    Proto3.Suite.DotProto.Generate+    Proto3.Suite.DotProto.Generate.Record+    Proto3.Suite.DotProto.Generate.Syntax+    Proto3.Suite.DotProto.Parsing+    Proto3.Suite.DotProto.Rendering+    Proto3.Suite.Form+    Proto3.Suite.Form.Encode+    Proto3.Suite.JSONPB+    Proto3.Suite.Tutorial+    Proto3.Suite.Types -  exposed-modules:     Proto3.Suite-                       Proto3.Suite.Class-                       Proto3.Suite.DotProto-                       Proto3.Suite.DotProto.Generate-                       Proto3.Suite.DotProto.Generate.LargeRecord-                       Proto3.Suite.DotProto.Generate.Record-                       Proto3.Suite.DotProto.Generate.Syntax-                       Proto3.Suite.DotProto.AST-                       Proto3.Suite.DotProto.AST.Lens-                       Proto3.Suite.DotProto.Parsing-                       Proto3.Suite.DotProto.Rendering-                       Proto3.Suite.JSONPB-                       Proto3.Suite.Tutorial-                       Proto3.Suite.Types+    Google.Protobuf.Timestamp+    Google.Protobuf.Wrappers.Polymorphic -                       Google.Protobuf.Timestamp-                       Google.Protobuf.Wrappers.Polymorphic+    Proto3.Suite.DotProto.Internal+    Proto3.Suite.Haskell.Parser+    Proto3.Suite.JSONPB.Class -                       Proto3.Suite.DotProto.Internal-                       Proto3.Suite.JSONPB.Class+  other-modules:+    Proto3.Suite.Form.Encode.Core+    Turtle.Compat -  other-modules:       Turtle.Compat+  build-depends:       +      aeson >= 1.1.1.0 && < 2.3+    , aeson-pretty >= 0.8.10 && < 0.9+    , attoparsec >= 0.13.0.1 && < 0.15+    , base64-bytestring >= 1.0.0.1 && < 1.3+    , binary >=0.8.3 && <= 0.9+    , bytestring >=0.10.6.0 && <0.13+    , deepseq >=1.4 && <1.6+    , cereal >= 0.5.1 && <0.6+    , containers >=0.5 && <0.8+    , contravariant >=1.4 && <1.6+    , filepath >= 1.5.2 && < 1.6+    , foldl >= 1.4.18 && < 1.5+    , ghc-lib-parser >=9.2.8 && <9.13+    , hashable >= 1.4.7 && < 1.5+    , insert-ordered-containers >= 0.2.7 && < 0.3+    , lens >= 5.3.5 && < 5.4+    , mtl >=2.2 && <2.4+    , neat-interpolation >= 0.5.1 && < 0.6+    , parsec >= 3.1.9 && <3.2+    , parsers >= 0.12 && <0.13+    , pretty ==1.1.*+    , pretty-show >= 1.6.12 && < 2+    , QuickCheck >=2.10 && <2.17+    , quickcheck-instances >=0.3.26 && < 0.4+    , safe ==0.3.*+    , split >= 0.2.5 && < 0.3+    , system-filepath >= 0.4.14 && < 0.5+    , template-haskell >=2.17 && <2.24+    , text >= 0.2 && <2.2+    , text-short >=0.1.3 && <0.2+    , time >= 1.12.2 && < 1.13+    , transformers >=0.4 && <0.7+    , turtle < 1.6.0 || >= 1.6.1 && < 1.7+    , vector >=0.11 && <0.14 -  build-depends:       aeson >= 1.1.1.0 && < 2.2,-                       aeson-pretty,-                       attoparsec >= 0.13.0.1,-                       base >=4.8 && <5.0,-                       base64-bytestring >= 1.0.0.1 && < 1.3,-                       binary >=0.8.3,-                       bytestring >=0.10.6.0 && <0.12.0,-                       deepseq ==1.4.*,-                       cereal >= 0.5.1 && <0.6,-                       containers >=0.5 && < 0.7,-                       contravariant >=1.4 && <1.6,-                       filepath,-                       foldl,-                       hashable,-                       haskell-src ==1.0.*,-                       insert-ordered-containers,-                       lens,-                       mtl ==2.2.*,-                       neat-interpolation,-                       parsec >= 3.1.9 && <3.2.0,-                       parsers >= 0.12 && <0.13,-                       pretty ==1.1.*,-                       pretty-show >= 1.6.12 && < 2.0,-                       proto3-wire >= 1.2.2 && < 1.5,-                       QuickCheck >=2.10 && <2.15,-                       quickcheck-instances >=0.3.26 && < 0.4,-                       safe ==0.3.*,-                       split,-                       system-filepath,-                       time,-                       text >= 0.2 && <2.1,-                       text-short >=0.1.3 && <0.2,-                       transformers >=0.4 && <0.6,-                       turtle < 1.6.0 || >= 1.6.1 && < 1.7.0,-                       vector >=0.11 && < 0.13-  if !impl(ghc >= 8.0)-    build-depends:     semigroups >= 0.18 && < 0.20-  hs-source-dirs:      src-  default-language:    Haskell2010-  ghc-options:         -O2 -Wall+  if flag(attoparsec-aeson)+    build-depends:+      attoparsec-aeson >= 2.2.0.0 && < 2.3  test-suite tests   import:           common-  default-language: Haskell2010   type:             exitcode-stdio-1.0   main-is:          Main.hs @@ -150,6 +180,8 @@     gen     tests +  cpp-options:         -DTYPE_LEVEL_FORMAT+   if flag(dhall)     other-modules:     TestDhall     build-depends:     dhall >=1.13 && < 1.43@@ -161,92 +193,94 @@     if flag(swagger-wrapper-format)       cpp-options:       -DSWAGGER_WRAPPER_FORMAT -  if flag(large-records)-    build-depends:     large-generics,-                       large-records-    cpp-options:       -DLARGE_RECORDS-   autogen-modules:     TestProto     TestProtoImport+    TestProtoNegativeEnum+    TestProtoNestedMessage     TestProtoOneof     TestProtoOneofImport+    TestProtoOptional     TestProtoWrappers-    TestProtoNestedMessage    other-modules:     ArbitraryGeneratedTestTypes     TestCodeGen     TestProto     TestProtoImport-    TestProtoOneof-    TestProtoOneofImport-    TestProtoWrappers     --TestProtoLeadingDot+    TestProtoNegativeEnum     TestProtoNestedMessage+    TestProtoOneof+    TestProtoOneofImport+    TestProtoOptional     --TestProtoProtocPlugin+    TestProtoWrappers     Test.Proto.Generate.Name     Test.Proto.Generate.Name.Gen+    Test.Proto.Parse+    Test.Proto.Parse.Core+    Test.Proto.Interval     Test.Proto.Parse.Gen     Test.Proto.Parse.Option+    Test.Proto.ToEncoder    build-depends:-      aeson >= 1.1.1.0 && < 2.2+      aeson     , attoparsec >= 0.13.0.1-    , base >=4.8 && <5.0     , base64-bytestring >= 1.0.0.1 && < 1.3-    , bytestring >=0.10.6.0 && <0.12.0+    , bytestring >=0.10.6.0 && <0.13     , cereal >= 0.5.1 && <0.6-    , containers >=0.5 && < 0.7-    , deepseq ==1.4.*+    , containers >=0.5 && <0.8+    , deepseq >=1.4 && <1.6     , doctest     , generic-arbitrary+    , ghc-lib-parser >= 9.10.2 && < 9.11     , hedgehog-    , mtl ==2.2.*+    , mtl >=2.2 && <2.4     , parsec >= 3.1.9 && <3.2.0     , pretty ==1.1.*     , pretty-show >= 1.6.12 && < 2.0     , proto3-suite-    , proto3-wire >= 1.2 && < 1.5-    , QuickCheck >=2.10 && <2.15+    , QuickCheck >=2.10 && <2.17     , record-hasfield-    , tasty >= 0.11 && <1.5+    , tasty >= 0.11 && <1.6     , tasty-hedgehog     , tasty-hunit >= 0.9 && <0.11-    , tasty-quickcheck >= 0.8.4 && <0.11-    , text >= 0.2 && <2.1+    , tasty-quickcheck >= 0.8.4 && <0.12+    , text >= 0.2 && <2.2     , text-short >=0.1.3 && <0.2-    , transformers >=0.4 && <0.6-    , turtle-    , vector >=0.11 && < 0.13--  if !impl(ghc >= 8.0)-    build-depends:     semigroups >= 0.18 && < 0.20-  ghc-options:         -O2 -Wall+    , transformers >=0.4 && <0.7+    , turtle < 1.6.0 || >= 1.6.1 && < 1.7+    , vector >=0.11 && <0.14  executable compile-proto-file-  main-is:             Main.hs-  hs-source-dirs:      tools/compile-proto-file-  default-language:    Haskell2010-  build-depends:       base >=4.12 && <5.0-                       , optparse-applicative-                       , proto3-suite-                       , system-filepath-                       , text-                       , turtle-  ghc-options:         -O2 -Wall+  main-is:          Main.hs+  hs-source-dirs:   tools/compile-proto-file+  default-language: Haskell2010 +  build-depends: +      base >=4.15 && <5.0+    , ghc-lib-parser >= 9.10.2 && < 9.11+    , optparse-applicative >= 0.18.1 && < 0.19+    , proto3-suite+    , system-filepath >= 0.4.14 && < 0.5+    , text >= 2.1.1 && < 2.2+    , turtle < 1.6.0 || >= 1.6.1 && < 1.7++  ghc-options:+    -O2+    -Wall+ executable canonicalize-proto-file-  main-is:             Main.hs-  hs-source-dirs:      tools/canonicalize-proto-file-  default-language:    Haskell2010-  build-depends:       base >=4.11.0.0 && <5.0-                       , containers >=0.5 && <0.7-                       , mtl ==2.2.*-                       , optparse-generic-                       , proto3-suite-                       , proto3-wire >= 1.2 && <1.5-                       , range-set-list >=0.1.2 && <0.2-                       , system-filepath-                       , turtle-  ghc-options:         -O2 -Wall+  import:           common+  main-is:          Main.hs+  hs-source-dirs:   tools/canonicalize-proto-file++  build-depends:       +      containers >=0.5 && <0.8+    , mtl >=2.2 && <2.4+    , optparse-generic >= 1.5.2 && < 1.6+    , proto3-suite+    , system-filepath >= 0.4.14 && < 0.5+    , turtle < 1.6.0 || >= 1.6.1 && < 1.7
src/Google/Protobuf/Wrappers/Polymorphic.hs view
@@ -5,6 +5,7 @@ {-# LANGUAGE DerivingStrategies         #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} +-- | Haskell types used to express standard protobuf wrapper message types. module Google.Protobuf.Wrappers.Polymorphic   ( Wrapped(..)   ) where
src/Proto3/Suite/Class.hs view
@@ -34,7 +34,7 @@ -- -- = Strings ----- Use 'TL.Text' instead of 'String' for string types inside messages.+-- Use 'TL.Text' instead of `Prelude.String` for string types inside messages. -- -- = Example --@@ -88,6 +88,7 @@   , fromB64   , coerceOver   , unsafeCoerceOver+  , ZigZag(..)    -- * Documentation   , Named(..)@@ -99,11 +100,15 @@   , GenericMessage(..)   ) where +#if !MIN_VERSION_base(4,18,0) import           Control.Applicative+#endif import           Control.Monad+import           Data.Bits              (Bits, FiniteBits) import qualified Data.ByteString        as B import qualified Data.ByteString.Base64 as B64 import qualified Data.ByteString.Lazy   as BL+import qualified Data.ByteString.Short  as BS import           Data.Coerce            (Coercible, coerce) import qualified Data.Foldable          as Foldable import           Data.Functor           (($>))@@ -118,6 +123,7 @@ import qualified Data.Text.Short        as TS import qualified Data.Traversable       as TR import           Data.Vector            (Vector)+import qualified Data.Vector            as V import           Data.Word              (Word32, Word64) import           GHC.Exts               (fromList, Proxy#, proxy#) import           GHC.Generics@@ -139,19 +145,6 @@ import qualified Data.Record.Generic.Rep as LG #endif --- | Pass through those values that are outside the enum range;--- this is for forward compatibility as enumerations are extended.-codeFromEnumerated :: ProtoEnum e => Enumerated e -> Int32-codeFromEnumerated = either id fromProtoEnum . enumerated-{-# INLINE codeFromEnumerated #-}---- | Values inside the enum range are in Right, the rest in Left;--- this is for forward compatibility as enumerations are extended.-codeToEnumerated :: ProtoEnum e => Int32 -> Enumerated e-codeToEnumerated code =-  Enumerated $ maybe (Left code) Right (toProtoEnumMay code)-{-# INLINE codeToEnumerated #-}- -- | A class for types with default values per the protocol buffers spec. class HasDefault a where   -- | The default value for this type.@@ -203,29 +196,40 @@  instance HasDefault T.Text where   def = mempty+  isDefault = T.null  deriving via T.Text instance HasDefault (Proto3.Suite.Types.String T.Text)  instance HasDefault TL.Text where   def = mempty+  isDefault = TL.null  deriving via TL.Text instance HasDefault (Proto3.Suite.Types.String TL.Text)  instance HasDefault TS.ShortText where   def = mempty+  isDefault = TS.null  deriving via TS.ShortText instance HasDefault (Proto3.Suite.Types.String TS.ShortText)  instance HasDefault B.ByteString where   def = mempty+  isDefault = B.null  deriving via B.ByteString instance HasDefault (Proto3.Suite.Types.Bytes B.ByteString)  instance HasDefault BL.ByteString where   def = mempty+  isDefault = BL.null  deriving via BL.ByteString instance HasDefault (Proto3.Suite.Types.Bytes BL.ByteString) +instance HasDefault BS.ShortByteString where+  def = mempty+  isDefault = BS.null++deriving via BS.ShortByteString instance HasDefault (Proto3.Suite.Types.Bytes BS.ShortByteString)+ instance ProtoEnum e => HasDefault (Enumerated e) where   def = codeToEnumerated 0   isDefault = (== 0) . codeFromEnumerated@@ -234,15 +238,15 @@  instance HasDefault (UnpackedVec a) where   def = mempty-  isDefault = null . unpackedvec+  isDefault = V.null . unpackedvec  instance HasDefault (PackedVec a) where   def = mempty-  isDefault = null . packedvec+  isDefault = V.null . packedvec  instance HasDefault (NestedVec a) where   def = mempty-  isDefault = null . nestedvec+  isDefault = V.null . nestedvec  instance HasDefault (Nested a) where   def = Nested Nothing@@ -256,7 +260,7 @@ -- 'PackedVec'/'UnpackedVec' instance HasDefault (Vector a) where   def       = mempty-  isDefault = null+  isDefault = V.null  -- | Used in generated records to represent an unwrapped 'Nested' instance HasDefault (Maybe a) where@@ -544,6 +548,14 @@  deriving via BL.ByteString instance Primitive (Proto3.Suite.Types.Bytes BL.ByteString) +instance Primitive BS.ShortByteString where+  encodePrimitive !num = Encode.shortByteString num+  {-# INLINE encodePrimitive #-}+  decodePrimitive = Decode.shortByteString+  primType _ = Bytes++deriving via BS.ShortByteString instance Primitive (Proto3.Suite.Types.Bytes BS.ShortByteString)+ instance forall e. (Named e, ProtoEnum e) => Primitive (Enumerated e) where   encodePrimitive !num = either (Encode.int32 num) (Encode.enum num) . enumerated   {-# INLINE encodePrimitive #-}@@ -553,7 +565,7 @@     Decode.enum   primType _ = Named (Single (nameOf (proxy# :: Proxy# e))) -instance (Primitive a) => Primitive (ForceEmit a) where+instance Primitive a => Primitive (ForceEmit a) where   encodePrimitive !num = encodePrimitive num . forceEmit   {-# INLINE encodePrimitive #-}   decodePrimitive     = coerce @(Parser RawPrimitive a) @(Parser RawPrimitive (ForceEmit a)) decodePrimitive@@ -622,6 +634,8 @@ deriving via B.ByteString instance MessageField (Proto3.Suite.Types.Bytes B.ByteString) instance MessageField BL.ByteString deriving via BL.ByteString instance MessageField (Proto3.Suite.Types.Bytes BL.ByteString)+instance MessageField BS.ShortByteString+deriving via BS.ShortByteString instance MessageField (Proto3.Suite.Types.Bytes BS.ShortByteString) instance (Named e, ProtoEnum e) => MessageField (Enumerated e)  instance (Ord k, Primitive k, MessageField k, Primitive v, MessageField v) => MessageField (M.Map k v) where@@ -660,6 +674,12 @@   encodeMessageField !num = encodePrimitive num   {-# INLINE encodeMessageField #-} +instance Primitive a => MessageField (Maybe (ForceEmit a)) where+  encodeMessageField !num = foldMap (encodePrimitive num)+  {-# INLINE encodeMessageField #-}+  decodeMessageField = Decode.optional decodePrimitive+  protoType _ = messageField (Optional $ primType (proxy# :: Proxy# (ForceEmit a))) Nothing+ instance (Named a, Message a) => MessageField (Nested a) where   encodeMessageField !num = go op     where@@ -741,39 +761,26 @@  instance MessageField (PackedVec (Signed Int32)) where   encodeMessageField !fn =-      omittingDefault (Encode.packedVarintsV zigZag fn) . coerce @_ @(Vector Int32)+      omittingDefault (Encode.packedVarintsV zigZag fn) . packedvec     where-      zigZag = fromIntegral . Encode.zigZagEncode+      zigZag = fromIntegral @Word32 @Word64 . zigZagEncode @Int32   {-# INLINE encodeMessageField #-}  -- Let 'Encode.packedVarintsV' figure out how much to inline. -  decodeMessageField = decodePacked (fmap (fmap zagZig) Decode.packedVarints)-    where-      -- This type signature is important: `Decode.zigZagDecode` will not undo-      -- `Encode.zigZagEncode` if given a signed value with the high order bit-      -- set. So we don't allow GHC to infer a signed input type.-      zagZig :: Word32 -> Signed Int32-      zagZig = Signed . fromIntegral . Decode.zigZagDecode+  decodeMessageField = decodePacked (fmap (fmap zigZagDecode) Decode.packedVarints)    protoType _ = messageField (Repeated SInt32) (Just PackedField)  instance MessageField (PackedVec (Signed Int64)) where   encodeMessageField !fn =-      omittingDefault (Encode.packedVarintsV zigZag fn) . coerce @_ @(Vector Int64)+      omittingDefault (Encode.packedVarintsV zigZag fn) . packedvec     where-      zigZag = fromIntegral . Encode.zigZagEncode+      zigZag = zigZagEncode @Int64   {-# INLINE encodeMessageField #-}  -- Let 'Encode.packedVarintsV' figure out how much to inline. -  decodeMessageField = decodePacked (fmap (fmap zagZig) Decode.packedVarints)-    where-      -- This type signature is important: `Decode.zigZagDecode` will not undo-      -- `Encode.zigZagEncode` if given a signed value with the high order bit-      -- set. So we don't allow GHC to infer a signed input type.-      zagZig :: Word64 -> Signed Int64-      zagZig = Signed . fromIntegral . Decode.zigZagDecode+  decodeMessageField = decodePacked (fmap (fmap zigZagDecode) Decode.packedVarints)    protoType _ = messageField (Repeated SInt64) (Just PackedField) - instance MessageField (PackedVec (Fixed Word32)) where   encodeMessageField !fn =     omittingDefault (Encode.packedFixed32V id fn) . coerce @_ @(Vector Word32)@@ -825,12 +832,16 @@ instance (MessageField e, KnownSymbol comments) => MessageField (e // comments) where   encodeMessageField !fn = encodeMessageField fn . unCommented   {-# INLINE encodeMessageField #-}+   decodeMessageField = coerce @(Parser RawField e)                               @(Parser RawField (Commented comments e))                               decodeMessageField-  protoType p = (protoType (lowerProxy1 p))-                  { dotProtoFieldComment = symbolVal (lowerProxy2 p) }++  protoType p = field { dotProtoFieldComment = symbolVal (lowerProxy2 p) }     where+      field :: DotProtoField+      field = protoType (lowerProxy1 p)+       lowerProxy1 :: forall k f (a :: k). Proxy# (f a) -> Proxy# a       lowerProxy1 _ = proxy# @@ -983,6 +994,11 @@   decodeMessage = decodeWrapperMessage   dotProto = dotProtoWrapper +instance Message BS.ShortByteString where+  encodeMessage = encodeWrapperMessage+  decodeMessage = decodeWrapperMessage+  dotProto = dotProtoWrapper+ -- * Generic Instances  class GenericMessage (f :: Type -> Type) where@@ -1020,7 +1036,9 @@         adjust (genericDotProto (proxy# :: Proxy# g))       where         offset = fromIntegral $ natVal (Proxy @(GenericFieldCount f))+         adjust = map adjustPart+         adjustPart part = part           { dotProtoFieldNumber = FieldNumber . (offset +)                                   . getFieldNumber . dotProtoFieldNumber@@ -1059,3 +1077,63 @@   genericEncodeMessage num (M1 x)   = genericEncodeMessage num x   genericDecodeMessage num          = M1 <$> genericDecodeMessage num   genericDotProto _                 = genericDotProto (proxy# :: Proxy# f)++class ZigZag a+  where+    -- | The unsigned integral type used to hold the value+    -- after ZigZag encoding but before varint encoding, and+    -- after varint decoding but before ZigZag decoding.+    --+    -- NOTE: The two integral types must have the same width both to+    -- correctly encode large @sint32@ values and, during decoding,+    -- to compensate for overlong encodings emitted by versions of+    -- this library before v0.8.2.  Those older versions incorrectly+    -- sign-extended ZigZag-encoded @sint32@ values in packed fields.+    type ZigZagEncoded a :: Type++    -- | Importantly, the resulting unsigned integer has the same+    -- width as the input type, so that any integral promotion before+    -- or during varint encoding will zero-pad instead of sign-extend.+    --+    -- Sign extension would result in a more bulky encoding+    -- and would violate the compatibility guarantee in+    -- <https://protobuf.dev/programming-guides/proto3/#updating> that+    -- an @sint32@ value can be decoded as if it had type @sint64@.+    zigZagEncode :: Signed a -> ZigZagEncoded a+    default zigZagEncode ::+      (Num a, FiniteBits a, Integral a, Num (ZigZagEncoded a)) =>+      Signed a -> ZigZagEncoded a+    zigZagEncode = fromIntegral . Encode.zigZagEncode . signed+    {-# INLINE zigZagEncode #-}++    -- | Importantly, the given unsigned integer has the same width as the result type.+    -- If the encoder was a version of this library before v0.8.2, and the field was+    -- packed, it would have incorrectly sign-extended between the ZigZag encoding step+    -- and the varint encoding step, rather than zero-padding.  By narrowing before we+    -- ZigZag decode, we exclude the incorrect bits.+    --+    -- Maintaining compatibility with versions of this library before v0.8.2+    -- does have a curious side effect.  When an @sint64@ value outside the+    -- range of @sint32@ is decoded as type @sint32@, the sign will be+    -- preserved and the magnitude decreased, rather than the more typical+    -- conversion that outputs the remainder after division by @2^32@, as+    -- would happen with 'fromIntegral @Int64 @Int32'.  One could argue that+    -- our behavior is surprising and unusual.  However, both narrowings+    -- lose information, and neither is supported by protobuf:+    -- <https://protobuf.dev/programming-guides/dos-donts/> says,+    -- "However, changing a field's message type will break+    -- unless the new message is a superset of the old one."+    zigZagDecode :: ZigZagEncoded a -> Signed a+    default zigZagDecode ::+      (Num (ZigZagEncoded a), Bits (ZigZagEncoded a), Integral (ZigZagEncoded a), Num a) =>+      ZigZagEncoded a -> Signed a+    zigZagDecode = Signed . fromIntegral . Decode.zigZagDecode+    {-# INLINE zigZagDecode #-}++instance ZigZag Int32+  where+    type ZigZagEncoded Int32 = Word32++instance ZigZag Int64+  where+    type ZigZagEncoded Int64 = Word64
src/Proto3/Suite/DhallPB.hs view
@@ -30,12 +30,14 @@ import           GHC.Float                   (double2Float, float2Double) import           Proto3.Suite.Types          (Enumerated (..), Fixed (..)) +#if !(MIN_VERSION_dhall(1,42,0)) import qualified Data.ByteString import qualified Data.ByteString.Base64 import qualified Data.ByteString.Base64.Lazy import qualified Data.ByteString.Lazy import qualified Data.Text.Encoding import qualified Data.Text.Lazy.Encoding+#endif import qualified Dhall  #if !(MIN_VERSION_dhall(1,27,0))@@ -63,6 +65,8 @@  instance Dhall.FromDhall a => Dhall.FromDhall (Either Int32 a) +#if !(MIN_VERSION_dhall(1,42,0))+ -------------------------------------------------------------------------------- -- Interpret the strict and lazy ByteString types --@@ -80,6 +84,8 @@     where       b64Decode =  Data.ByteString.Base64.decodeLenient . Data.Text.Encoding.encodeUtf8 +#endif+ -------------------------------------------------------------------------------- -- Interpret integer scalar types @@ -182,6 +188,8 @@ instance Dhall.ToDhall Float where   injectWith = fmap (contramap float2Double) Dhall.injectWith +#if !(MIN_VERSION_dhall(1,42,0))+ -------------------------------------------------------------------------------- -- Inject strict and lazy ByteStrings --@@ -204,6 +212,8 @@       -- but we should never encounter that case with this usage       -- because we Base64 encode the ByteString first       b64Encode = Data.Text.Encoding.decodeUtf8 . Data.ByteString.Base64.encode++#endif  #if !(MIN_VERSION_dhall(1,27,0)) --------------------------------------------------------------------------------
src/Proto3/Suite/DotProto/AST.hs view
@@ -35,6 +35,7 @@   ) where  import           Control.Applicative+import           Data.Char                 (toLower) import           Control.Monad import           Data.Data                 (Data) import           Data.Int                  (Int32)@@ -46,7 +47,11 @@ import           Proto3.Wire.Types         (FieldNumber (..)) import           Test.QuickCheck import           Test.QuickCheck.Instances ()+import           Text.PrettyPrint          ((<+>))+import qualified Text.PrettyPrint          as PP+import           Text.PrettyPrint.HughesPJClass (Pretty(..)) import           Turtle                    (FilePath)+import           Turtle.Compat             (encodeString)  -- | The name of a message newtype MessageName = MessageName@@ -58,7 +63,7 @@  -- | The name of some field newtype FieldName = FieldName-  { getFieldName :: String } +  { getFieldName :: String }   deriving (Data, Eq, Generic, IsString, Ord)  instance Show FieldName where@@ -66,14 +71,14 @@  -- | The name of the package newtype PackageName = PackageName-  { getPackageName :: String } +  { getPackageName :: String }   deriving (Data, Eq, Generic, IsString, Ord)  instance Show PackageName where   show = show . getPackageName -newtype Path = Path -  { components :: NE.NonEmpty String } +newtype Path = Path+  { components :: NE.NonEmpty String }   deriving (Data, Eq, Generic, Ord, Show)  -- Used for testing@@ -87,13 +92,25 @@   | Anonymous -- [recheck] is there a better way to represent unnamed things   deriving (Data, Eq, Generic, Ord, Show) +instance Pretty DotProtoIdentifier where+  pPrint (Single name)                    = PP.text name+  pPrint (Dots (Path names))              = PP.hcat . PP.punctuate (PP.text ".") $ PP.text <$> NE.toList names+  pPrint (Qualified qualifier identifier) = PP.parens (pPrint qualifier) <> PP.text "." <> pPrint identifier+  pPrint Anonymous                        = PP.empty+ -- | Top-level import declaration data DotProtoImport = DotProtoImport   { dotProtoImportQualifier :: DotProtoImportQualifier   , dotProtoImportPath      :: FilePath-  } +  }   deriving (Data, Eq, Generic, Ord, Show) +instance Pretty DotProtoImport where+  pPrint (DotProtoImport q i) =+    PP.text "import" <+> pPrint q <+> strLit fp PP.<> PP.text ";"+    where+      fp = encodeString i+ instance Arbitrary DotProtoImport where   arbitrary = do     dotProtoImportQualifier <- arbitrary@@ -106,6 +123,11 @@   | DotProtoImportDefault   deriving (Bounded, Data, Enum, Eq, Generic, Ord, Show) +instance Pretty DotProtoImportQualifier where+  pPrint DotProtoImportDefault = PP.empty+  pPrint DotProtoImportPublic  = PP.text "public"+  pPrint DotProtoImportWeak    = PP.text "weak"+ instance Arbitrary DotProtoImportQualifier where   arbitrary = elements     [ DotProtoImportDefault@@ -119,6 +141,10 @@   | DotProtoNoPackage   deriving (Data, Eq, Generic, Ord, Show) +instance Pretty DotProtoPackageSpec where+  pPrint (DotProtoPackageSpec p) = PP.text "package" <+> pPrint p PP.<> PP.text ";"+  pPrint (DotProtoNoPackage)     = PP.empty+ instance Arbitrary DotProtoPackageSpec where   arbitrary = oneof     [ return DotProtoNoPackage@@ -132,6 +158,9 @@   , dotProtoOptionValue      :: DotProtoValue   } deriving (Data, Eq, Generic, Ord, Show) +instance Pretty DotProtoOption where+  pPrint (DotProtoOption key value) = pPrint key <+> PP.text "=" <+> pPrint value+ instance Arbitrary DotProtoOption where     arbitrary = do       dotProtoOptionIdentifier <- oneof@@ -168,7 +197,7 @@   { metaModulePath :: Path     -- ^ The "module path" associated with the .proto file from which this AST     -- was parsed. The "module path" is derived from the `--includeDir`-relative-    -- .proto filename passed to 'parseProtoFile'. See+    -- .proto filename passed to `Proto3.Suite.DotProto.Parsing.parseProtoFile`. See     -- 'Proto3.Suite.DotProto.Internal.toModulePath' for details on how module     -- path values are constructed. See     -- 'Proto3.Suite.DotProto.Generate.modulePathModName' to see how it is used@@ -199,7 +228,7 @@     protoMeta        <- arbitrary     return (DotProto {..}) --- | Matches the definition of `constant` in the proto3 language spec+-- | Matches the definition of @constant@ in the proto3 language spec --   These are only used as rvalues data DotProtoValue   = Identifier DotProtoIdentifier@@ -209,6 +238,13 @@   | BoolLit    Bool   deriving (Data, Eq, Generic, Ord, Show) +instance Pretty DotProtoValue where+  pPrint (Identifier value) = pPrint value+  pPrint (StringLit  value) = strLit value+  pPrint (IntLit     value) = PP.text $ show value+  pPrint (FloatLit   value) = PP.text $ show value+  pPrint (BoolLit    value) = PP.text $ toLower <$> show value+ instance Arbitrary DotProtoValue where   arbitrary = oneof     [ fmap Identifier  arbitrarySingleIdentifier@@ -238,6 +274,24 @@   -- ^ A named type, referring to another message or enum defined in the same file   deriving (Data, Eq, Generic, Ord, Show) +instance Pretty DotProtoPrimType where+  pPrint (Named i)  = pPrint i+  pPrint Int32      = PP.text "int32"+  pPrint Int64      = PP.text "int64"+  pPrint SInt32     = PP.text "sint32"+  pPrint SInt64     = PP.text "sint64"+  pPrint UInt32     = PP.text "uint32"+  pPrint UInt64     = PP.text "uint64"+  pPrint Fixed32    = PP.text "fixed32"+  pPrint Fixed64    = PP.text "fixed64"+  pPrint SFixed32   = PP.text "sfixed32"+  pPrint SFixed64   = PP.text "sfixed64"+  pPrint String     = PP.text "string"+  pPrint Bytes      = PP.text "bytes"+  pPrint Bool       = PP.text "bool"+  pPrint Float      = PP.text "float"+  pPrint Double     = PP.text "double"+ instance Arbitrary DotProtoPrimType where   arbitrary = oneof     [ elements@@ -273,11 +327,19 @@ --   are meaningful in every type context. data DotProtoType   = Prim           DotProtoPrimType+  | Optional       DotProtoPrimType   | Repeated       DotProtoPrimType   | NestedRepeated DotProtoPrimType   | Map            DotProtoPrimType DotProtoPrimType   deriving (Data, Eq, Generic, Ord, Show) +instance Pretty DotProtoType where+  pPrint (Prim           ty) = pPrint ty+  pPrint (Optional       ty) = PP.text "optional" <+> pPrint ty+  pPrint (Repeated       ty) = PP.text "repeated" <+> pPrint ty+  pPrint (NestedRepeated ty) = PP.text "repeated" <+> pPrint ty+  pPrint (Map keyty valuety) = PP.text "map<" <> pPrint keyty <> PP.text ", " <> pPrint valuety <> PP.text ">"+ instance Arbitrary DotProtoType where   arbitrary = oneof [fmap Prim arbitrary] @@ -286,7 +348,7 @@ data DotProtoEnumPart   = DotProtoEnumField DotProtoIdentifier DotProtoEnumValue [DotProtoOption]   | DotProtoEnumOption DotProtoOption-  | DotProtoEnumEmpty+  | DotProtoEnumReserved   [DotProtoReservedField]   deriving (Data, Eq, Generic, Ord, Show)  instance Arbitrary DotProtoEnumPart where@@ -307,15 +369,30 @@   | NonStreaming   deriving (Bounded, Data, Enum, Eq, Generic, Ord, Show) +instance Pretty Streaming where+  pPrint Streaming    = PP.text "stream"+  pPrint NonStreaming = PP.empty+ instance Arbitrary Streaming where   arbitrary = elements [Streaming, NonStreaming]  data DotProtoServicePart   = DotProtoServiceRPCMethod RPCMethod   | DotProtoServiceOption DotProtoOption-  | DotProtoServiceEmpty   deriving (Data, Eq, Generic, Ord, Show) +instance Pretty DotProtoServicePart where+  pPrint (DotProtoServiceRPCMethod RPCMethod{..})+    =   PP.text "rpc"+    <+> pPrint rpcMethodName+    <+> PP.parens (pPrint rpcMethodRequestStreaming <+> pPrint rpcMethodRequestType)+    <+> PP.text "returns"+    <+> PP.parens (pPrint rpcMethodResponseStreaming <+> pPrint rpcMethodResponseType)+    <+> case rpcMethodOptions of+          [] -> PP.text ";"+          _  -> PP.braces . PP.vcat $ serviceOption <$> rpcMethodOptions+  pPrint (DotProtoServiceOption option) = serviceOption option+ instance Arbitrary DotProtoServicePart where   arbitrary = oneof     [ DotProtoServiceRPCMethod <$> arbitrary@@ -329,7 +406,7 @@   , rpcMethodResponseType :: DotProtoIdentifier   , rpcMethodResponseStreaming :: Streaming   , rpcMethodOptions :: [DotProtoOption]-  } +  }   deriving (Data, Eq, Generic, Ord, Show)  instance Arbitrary RPCMethod where@@ -386,7 +463,6 @@   , dotProtoFieldOptions :: [DotProtoOption]   , dotProtoFieldComment :: String   }-  | DotProtoEmptyField   deriving (Data, Eq, Generic, Ord, Show)  instance Arbitrary DotProtoField where@@ -405,6 +481,11 @@   | ReservedIdentifier String   deriving (Data, Eq, Generic, Ord, Show) +instance Pretty DotProtoReservedField where+  pPrint (SingleField num)      = PP.text $ show num+  pPrint (FieldRange start end) = (PP.text $ show start) <+> PP.text "to" <+> (PP.text $ show end)+  pPrint (ReservedIdentifier i) = PP.text $ show i+ instance Arbitrary DotProtoReservedField where   arbitrary =     oneof [arbitrarySingleField, arbitraryFieldRange]@@ -464,3 +545,15 @@  smallListOf1 :: Gen a -> Gen [a] smallListOf1 x = choose (1, 5) >>= \n -> vectorOf n x++strLit :: String -> PP.Doc+strLit string = PP.text "\"" <> foldMap escape string <> PP.text "\""+  where+    escape '\n' = PP.text "\\n"+    escape '\\' = PP.text "\\\\"+    escape '\0' = PP.text "\\x00"+    escape '"'  = PP.text "\\\""+    escape  c   = PP.text [ c ]++serviceOption :: DotProtoOption -> PP.Doc+serviceOption o = PP.text "option" <+> pPrint o PP.<> PP.text ";"
src/Proto3/Suite/DotProto/Generate.hs view
@@ -4,2054 +4,2322 @@ {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleContexts          #-} {-# LANGUAGE FlexibleInstances         #-}-{-# LANGUAGE LambdaCase                #-}-{-# LANGUAGE MultiWayIf                #-}-{-# LANGUAGE NamedFieldPuns            #-}-{-# LANGUAGE OverloadedStrings         #-}-{-# LANGUAGE QuasiQuotes               #-}-{-# LANGUAGE RecordWildCards           #-}-{-# LANGUAGE ScopedTypeVariables       #-}-{-# LANGUAGE StandaloneDeriving        #-}-{-# LANGUAGE TupleSections             #-}-{-# LANGUAGE TypeApplications          #-}-{-# LANGUAGE TypeOperators             #-}-{-# LANGUAGE ViewPatterns              #-}--{-| This module provides functions to generate Haskell declarations for protobuf-    messages--}--module Proto3.Suite.DotProto.Generate-  ( CompileError(..)-  , StringType(..)-  , RecordStyle (..)-  , parseStringType-  , TypeContext-  , CompileArgs(..)-  , compileDotProtoFile-  , compileDotProtoFileOrDie-  , renameProtoFile-  , hsModuleForDotProto-  , renderHsModuleForDotProto-  , readDotProtoWithContext-  ) where--import           Control.Applicative-import           Control.Lens                   ((&), ix, over, has, filtered)-import           Control.Monad.Except           (MonadError(..), runExceptT)-import           Control.Monad.IO.Class         (MonadIO(..))-import           Data.Char-import           Data.Coerce-import           Data.Either                    (partitionEithers)-import           Data.List                      (find, intercalate, nub, sort, sortBy, stripPrefix)-import qualified Data.List.NonEmpty             as NE-import           Data.List.Split                (splitOn)-import           Data.List.NonEmpty (NonEmpty (..))-import qualified Data.Map                       as M-import           Data.Maybe-import           Data.Monoid-import           Data.Ord                       (comparing)-import qualified Data.Set                       as S-import           Data.String                    (fromString)-import qualified Data.Text                      as T-import           Language.Haskell.Parser        (ParseResult(..), parseModule)-import           Language.Haskell.Pretty-import           Language.Haskell.Syntax-import qualified NeatInterpolation              as Neat-import           Prelude                        hiding (FilePath)-import           Proto3.Suite.DotProto-import           Proto3.Suite.DotProto.AST.Lens-import qualified Proto3.Suite.DotProto.Generate.LargeRecord as LargeRecord-import qualified Proto3.Suite.DotProto.Generate.Record as RegularRecord-import           Proto3.Suite.DotProto.Generate.Syntax-import           Proto3.Suite.DotProto.Internal-import           Proto3.Wire.Types              (FieldNumber (..))-import Text.Parsec (Parsec, alphaNum, eof, parse, satisfy, try)-import qualified Text.Parsec as Parsec-import qualified Turtle hiding (encodeString)-import qualified Turtle.Compat as Turtle (encodeString)-import           Turtle                         (FilePath, (</>), (<.>))---- $setup--- >>> :set -XTypeApplications----------------------------------------------------------------------------------------- * Public interface----data CompileArgs = CompileArgs-  { includeDir         :: [FilePath]-  , extraInstanceFiles :: [FilePath]-  , inputProto         :: FilePath-  , outputDir          :: FilePath-  , stringType         :: StringType-  , recordStyle        :: RecordStyle-  }--data StringType = StringType String String-  -- ^ Qualified module name, then unqualified type name.--data RecordStyle = RegularRecords | LargeRecords-  deriving stock (Eq, Show, Read)--parseStringType :: String -> Either String StringType-parseStringType str = case splitOn "." str of-  xs@(_ : _ : _) -> Right $ StringType (intercalate "." $ init xs) (last xs)-  _ -> Left "must be in the form Module.Type"---- | Generate a Haskell module corresponding to a @.proto@ file-compileDotProtoFile :: CompileArgs -> IO (Either CompileError ())-compileDotProtoFile CompileArgs{..} = runExceptT $ do-  (dotProto, importTypeContext) <- readDotProtoWithContext includeDir inputProto-  modulePathPieces <- traverse renameProtoFile (toModuleComponents dotProto)--  let relativePath = foldr combine mempty (map fromString $ NE.toList modulePathPieces) <.> "hs"-      combine p1 p2 | p2 == mempty = p1-      combine p1 p2 = p1 </> p2-  let modulePath = outputDir </> relativePath--  Turtle.mktree (Turtle.directory modulePath)--  extraInstances <- foldMapM getExtraInstances extraInstanceFiles-  haskellModule <- renderHsModuleForDotProto stringType recordStyle extraInstances dotProto importTypeContext--  liftIO (writeFile (Turtle.encodeString modulePath) haskellModule)-  where-    toModuleComponents :: DotProto -> NonEmpty String-    toModuleComponents = components . metaModulePath . protoMeta---- | Same as 'compileDotProtoFile', except terminates the program with an error--- message on failure.-compileDotProtoFileOrDie :: CompileArgs -> IO ()-compileDotProtoFileOrDie args = compileDotProtoFile args >>= \case-  Left e -> do-    -- TODO: pretty print the error messages-    let errText          = Turtle.format Turtle.w  e-    let dotProtoPathText = Turtle.format Turtle.fp (inputProto args)-    dieLines [Neat.text|-      Error: failed to compile "${dotProtoPathText}":--      ${errText}-    |]-  _ -> pure ()---- | Renaming protobuf file names to valid Haskell module names.------ By convention, protobuf filenames are snake case. 'rnProtoFile' renames--- snake-cased protobuf filenames by:------ * Replacing occurrences of one or more underscores followed by an--- alphabetical character with one less underscore.------ * Capitalizing the first character following the string of underscores.------ ==== __Examples__------ >>> renameProtoFile @(Either CompileError) "abc_xyz"--- Right "AbcXyz"------ >>> renameProtoFile @(Either CompileError) "abc_1bc"--- Left (InvalidModuleName "abc_1bc")------ >>> renameProtoFile @(Either CompileError) "_"--- Left (InvalidModuleName "_")-renameProtoFile :: MonadError CompileError m => String -> m String-renameProtoFile filename =-  case parse parser "" filename of-    Left {} -> throwError (InvalidModuleName filename)-    Right (nm, ps, sn) -> pure (toUpperFirst nm ++ rename ps ++ sn)-  where-    rename :: [(String, String)] -> String-    rename = foldMap $ \(us, nm) ->-      drop 1 us ++ toUpperFirst nm--    parser :: Parsec String () (String, [(String, String)], String)-    parser = do-      nm <- pName-      ps <- Parsec.many (try pNamePart)-      sn <- Parsec.many (satisfy (== '_'))-      pure (nm, ps, sn) <* eof--    pNamePart :: Parsec String () (String, String)-    pNamePart = liftA2 (,) (Parsec.many1 (satisfy (== '_'))) pName--    pName :: Parsec String () String-    pName = liftA2 (:) (satisfy isAlpha) (Parsec.many alphaNum)---- | Compile a 'DotProto' AST into a 'String' representing the Haskell---   source of a module implementing types and instances for the .proto---   messages and enums.-renderHsModuleForDotProto-    :: MonadError CompileError m-    => StringType-    -> RecordStyle-    -> ([HsImportDecl],[HsDecl]) -> DotProto -> TypeContext -> m String-renderHsModuleForDotProto stringType recordStyle extraInstanceFiles dotProto importCtxt = do-    haskellModule <- hsModuleForDotProto stringType recordStyle extraInstanceFiles dotProto importCtxt--    let languagePragmas = textUnlines $ map (\extn -> "{-# LANGUAGE " <> extn <> " #-}") $ sort extensions-        ghcOptionPragmas = textUnlines $ map (\opt -> "{-# OPTIONS_GHC " <> opt <> " #-}") $ sort options--        extensions :: [T.Text]-        extensions =-          [ "DataKinds"-          , "DeriveAnyClass"-          , "DeriveGeneric"-          , "GADTs"-          , "OverloadedStrings"-          , "TypeApplications"-          ] ++-          case recordStyle of-            RegularRecords -> []-            LargeRecords -> [ "ConstraintKinds"-                           , "FlexibleInstances"-                           , "MultiParamTypeClasses"-                           , "ScopedTypeVariables"-                           , "TypeFamilies"-                           , "UndecidableInstances"-                           ]--        options :: [T.Text]-        options = [ "-fno-warn-unused-imports"-                  , "-fno-warn-name-shadowing"-                  , "-fno-warn-unused-matches"-                  , "-fno-warn-missing-export-lists"-                  ] ++-                  case recordStyle of-                    RegularRecords -> []-                    LargeRecords -> [ "-fplugin=Data.Record.Plugin" ]--        mkLRAnnotation :: HsDecl -> Maybe T.Text-        mkLRAnnotation (HsDataDecl _ _ (HsIdent recName) _ [HsRecDecl _ _ (_fld1:_fld2:_)] _) =-          Just ("{-# ANN type " <> T.pack recName <> " largeRecord #-}")-        mkLRAnnotation _ = Nothing--        lrAnnotations :: T.Text-        lrAnnotations =-          case (recordStyle, haskellModule) of-            (RegularRecords, _) -> ""-            (LargeRecords, HsModule _ _ _ _ moduleDecls) ->-              textUnlines (mapMaybe mkLRAnnotation moduleDecls)--        moduleContent :: T.Text-        moduleContent = T.pack (prettyPrint haskellModule)--        textUnlines :: [T.Text] -> T.Text-        textUnlines = T.intercalate "\n"--    pure $ T.unpack $ [Neat.text|-      $languagePragmas-      $ghcOptionPragmas--      -- | Generated by Haskell protocol buffer compiler. DO NOT EDIT!-      $moduleContent--      $lrAnnotations-    |]---- | Compile a Haskell module AST given a 'DotProto' package AST.--- Instances given in @eis@ override those otherwise generated.-hsModuleForDotProto-    :: MonadError CompileError m-    => StringType-    -- ^ the module and the type for string-    -> RecordStyle-    -- ^ kind of records to generate-    -> ([HsImportDecl], [HsDecl])-    -- ^ Extra user-define instances that override default generated instances-    -> DotProto-    -- ^-    -> TypeContext-    -- ^-    -> m HsModule-hsModuleForDotProto-    stringType-    recordStyle-    (extraImports, extraInstances)-    dotProto@DotProto{ protoMeta = DotProtoMeta { metaModulePath = modulePath }-                     , protoPackage-                     , protoDefinitions-                     }-    importTypeContext-  = do-       moduleName <- modulePathModName modulePath--       typeContextImports <- ctxtImports importTypeContext--       let hasService = has (traverse._DotProtoService) protoDefinitions--       let importDeclarations = concat-              [ defaultImports recordStyle-                               ImportCustomisation-                               { icUsesGrpc = hasService-                               , icStringType = stringType-                               }-              , extraImports-              , typeContextImports ]--       typeContext <- dotProtoTypeContext dotProto--       let toDotProtoDeclaration =-             dotProtoDefinitionD stringType recordStyle protoPackage (typeContext <> importTypeContext)--       let extraInstances' = instancesForModule moduleName extraInstances--       decls <- replaceHsInstDecls extraInstances' <$>-                foldMapM toDotProtoDeclaration protoDefinitions--       return (module_ moduleName Nothing importDeclarations decls)--getExtraInstances-    :: (MonadIO m, MonadError CompileError m)-    => FilePath -> m ([HsImportDecl], [HsDecl])-getExtraInstances extraInstanceFile = do--  contents <- liftIO (readFile (Turtle.encodeString extraInstanceFile))--  case parseModule contents of-    ParseOk (HsModule _srcloc _mod _es idecls decls) -> do-      let isInstDecl HsInstDecl{} = True-          isInstDecl _            = False--      return (idecls, filter isInstDecl decls) --TODO give compile result--    ParseFailed srcLoc err -> do-      let srcLocText = Turtle.format Turtle.w srcLoc--      let errText = T.pack err--      let message = [Neat.text|-            Error: Failed to parse instance file--            ${srcLocText}: ${errText}-          |]--      internalError (T.unpack message)---- | This very specific function will only work for the qualification on the very first type--- in the object of an instance declaration. Those are the only sort of instance declarations--- generated within this code, so it suffices.-instancesForModule :: Module -> [HsDecl] -> [HsDecl]-instancesForModule m = foldr go []-   where go x xs = case x of-             HsInstDecl a b c (HsTyCon (Qual tm  i):ts) d ->-                        if m == tm then HsInstDecl a b c (HsTyCon (UnQual i):ts) d:xs else xs-             _ -> xs---- | For each thing in @base@ replaces it if it finds a matching @override@-replaceHsInstDecls :: [HsDecl] -> [HsDecl] -> [HsDecl]-replaceHsInstDecls overrides base = concatMap mbReplace base-  where-    -- instances defined separately from data type definition:-    mbReplace hid@(HsInstDecl _ _ qn tys _) =-        (: []) . fromMaybe hid $ search qn tys--    -- instances listed in "deriving" clause of data type definition:-    mbReplace (HsDataDecl loc ctx tyn names def insts) =-        let (uncustomized, customized) = partitionEithers (map (deriv tyn) insts)-        in HsDataDecl loc ctx tyn names def uncustomized : customized--    -- instances listed in "deriving" clause of newtype definition:-    mbReplace (HsNewTypeDecl loc ctx tyn names def insts) =-        let (uncustomized, customized) = partitionEithers (map (deriv tyn) insts)-        in HsNewTypeDecl loc ctx tyn names def uncustomized : customized--    -- irrelevant declarations remain unchanged:-    mbReplace hid = [hid]--    deriv tyn qn = maybe (Left qn) Right $ search qn [HsTyCon (UnQual tyn)]--    search qn tys = find (\x -> Just (unQual qn,tys) == getSig x) overrides--    getSig (HsInstDecl _ _ qn tys _) = Just (unQual qn,tys)-    getSig _ = Nothing--    unQual (Qual _ n) = Just n-    unQual (UnQual n) = Just n-    unQual (Special _) = Nothing---- | Parses the file at the given path and produces an AST along with a--- 'TypeContext' representing all types from imported @.proto@ files, using the--- first parameter as a list of paths to search for imported files. Terminates--- with exit code 1 when an included file cannot be found in the search path.-readDotProtoWithContext-    :: (MonadError CompileError m, MonadIO m)-    => [FilePath]-    -> FilePath-    -> m (DotProto, TypeContext)-readDotProtoWithContext [] toplevelProto = do-  -- If we're not given a search path, default to using the current working-  -- directory, as `protoc` does-  cwd <- Turtle.pwd-  readDotProtoWithContext [cwd] toplevelProto--readDotProtoWithContext searchPaths toplevelProto = do-  dp <- importProto searchPaths toplevelProto toplevelProto-  let importIt = readImportTypeContext searchPaths toplevelProto (S.singleton toplevelProto)-  tc <- foldMapM importIt (protoImports dp)-  pure (dp, tc)---- | Build the type context for an import, resolving transitive imports.-readImportTypeContext-    :: (MonadError CompileError m, MonadIO m)-    => [FilePath]-    -> FilePath-    -> S.Set FilePath-    -> DotProtoImport-    -> m TypeContext-readImportTypeContext searchPaths toplevelFP alreadyRead (DotProtoImport _ path)-  | path `S.member` alreadyRead = throwError (CircularImport path)-  | otherwise = do-      import_ <- importProto searchPaths toplevelFP path-      let importPkgSpec = protoPackage import_--      let fixImportTyInfo tyInfo =-             tyInfo { dotProtoTypeInfoPackage    = importPkgSpec-                    , dotProtoTypeInfoModulePath = metaModulePath . protoMeta $ import_-                    }-      importTypeContext <- fmap fixImportTyInfo <$> dotProtoTypeContext import_--      let prefixWithPackageName =-            case importPkgSpec of-              DotProtoPackageSpec packageName -> concatDotProtoIdentifier packageName-              DotProtoNoPackage -> pure--      qualifiedTypeContext <- mapKeysM prefixWithPackageName importTypeContext--      let isPublic (DotProtoImport q _) = q == DotProtoImportPublic-      transitiveImportsTC <--        foldMapOfM (traverse . filtered isPublic)-                   (readImportTypeContext searchPaths toplevelFP (S.insert path alreadyRead))-                   (protoImports import_)--      pure $ importTypeContext <> qualifiedTypeContext <> transitiveImportsTC---- | Given a type context, generates the Haskell import statements necessary to---   import all the required types.  Excludes module "Google.Protobuf.Wrappers"---   because the generated code does not actually make use of wrapper types---   as such; instead it uses @Maybe a@, where @a@ is the wrapped type.-ctxtImports :: MonadError CompileError m => TypeContext -> m [HsImportDecl]-ctxtImports =-    fmap (map mkImport . nub . filter (Module "Google.Protobuf.Wrappers" /=))-    . traverse (modulePathModName . dotProtoTypeInfoModulePath)-    . M.elems-  where-    mkImport modName = importDecl_ modName True Nothing Nothing---------------------------------------------------------------------------------------- * Helper functions for Haskell code generation------- ** Names---- | Generate the Haskell type name for a 'DotProtoTypeInfo' for a message /---   enumeration being compiled. NB: We ignore the 'dotProtoTypeInfoPackage'---   field of the 'DotProtoTypeInfo' parameter, instead demanding that we have---   been provided with a valid module path in its 'dotProtoTypeInfoModulePath'---   field. The latter describes the name of the Haskell module being generated.-msgTypeFromDpTypeInfo :: MonadError CompileError m-                      => TypeContext -> DotProtoTypeInfo -> DotProtoIdentifier -> m HsType-msgTypeFromDpTypeInfo ctxt DotProtoTypeInfo{..} ident = do-    modName   <- modulePathModName dotProtoTypeInfoModulePath-    identName <- qualifiedMessageTypeName ctxt dotProtoTypeInfoParent ident-    pure $ HsTyCon (Qual modName (HsIdent identName))--modulePathModName :: MonadError CompileError m => Path -> m Module-modulePathModName (Path comps) = Module . intercalate "." <$> traverse typeLikeName (NE.toList comps)--_pkgIdentModName :: MonadError CompileError m => DotProtoIdentifier -> m Module-_pkgIdentModName (Single s)  = Module <$> typeLikeName s-_pkgIdentModName (Dots path) = modulePathModName path-_pkgIdentModName x           = throwError (InvalidPackageName x)----- ** Dhall--#ifdef DHALL-hsDhallPB :: String-hsDhallPB = "HsDhallPb"--dhallPBName :: String -> HsQName-dhallPBName name = Qual (Module hsDhallPB) (HsIdent name)---- *** Generate Dhall Interpret and Inject generic instances--fromDhall, toDhall :: String-(fromDhall, toDhall) =-#if MIN_VERSION_dhall(1,27,0)-  ("FromDhall", "ToDhall")-#else-  ("Interpret", "Inject")-#endif--dhallInterpretInstDecl :: String -> HsDecl-dhallInterpretInstDecl typeName =-  instDecl_ (dhallPBName fromDhall)-            [ type_ typeName ]-            [ ]--dhallInjectInstDecl :: String -> HsDecl-dhallInjectInstDecl typeName =-  instDecl_ (dhallPBName toDhall)-            [ type_ typeName ]-            [ ]-#endif---- ** Helpers to wrap/unwrap types for protobuf (de-)serialization--data FieldContext = WithinMessage | WithinOneOf-  deriving (Eq, Show)--typeApp :: HsType -> HsExp-typeApp ty = uvar_ ("@("++ pp ty ++ ")")-  where-    -- Do not add linebreaks to typeapps as that causes parse errors-    pp = prettyPrintStyleMode style{mode=OneLineMode} defaultMode--coerceE :: Bool -> Bool -> HsType -> HsType -> Maybe HsExp-coerceE _ _ from to | from == to = Nothing-coerceE overTyCon unsafe from to =-    Just $ HsApp (HsApp coerceF (typeApp from)) (typeApp to)-  where-    coerceF | unsafe = HsVar (name "unsafeCoerce")-            | otherwise  = HsVar (name "coerce")-    name | overTyCon = protobufName . (<> "Over")-         | otherwise = haskellName--wrapFunE :: MonadError CompileError m => Bool -> FieldContext -> StringType -> TypeContext -> [DotProtoOption] -> DotProtoType -> m (Maybe HsExp)-wrapFunE overTyCon fc stringType ctxt opts dpt =-  coerceE overTyCon (isMap dpt)-    <$> dptToHsType fc stringType ctxt dpt-    <*> dptToHsTypeWrapped fc stringType opts ctxt dpt--wrapE :: MonadError CompileError m => FieldContext -> StringType -> TypeContext -> [DotProtoOption] -> DotProtoType -> HsExp -> m HsExp-wrapE fc stringType ctxt opts dpt e =-  maybeModify e <$> wrapFunE False fc stringType ctxt opts dpt--unwrapFunE :: MonadError CompileError m => Bool -> FieldContext -> StringType -> TypeContext -> [DotProtoOption] -> DotProtoType -> m (Maybe HsExp)-unwrapFunE overTyCon fc stringType ctxt opts dpt =-  coerceE overTyCon (isMap dpt)-    <$> dptToHsTypeWrapped fc stringType opts ctxt dpt-    <*> dptToHsType fc stringType ctxt dpt--unwrapE :: MonadError CompileError m => FieldContext -> StringType -> TypeContext -> [DotProtoOption] -> DotProtoType -> HsExp -> m HsExp-unwrapE fc stringType ctxt opts dpt e = do-  maybeModify e <$> unwrapFunE True fc stringType ctxt opts dpt---------------------------------------------------------------------------------------- * Functions to convert 'DotProtoType' into Haskell types------- | Convert a dot proto type to a Haskell type-dptToHsType :: MonadError CompileError m => FieldContext -> StringType -> TypeContext -> DotProtoType -> m HsType-dptToHsType fc = foldDPT (dptToHsContType fc) . dpptToHsType---- | Convert a dot proto type to a wrapped Haskell type-dptToHsTypeWrapped-  :: MonadError CompileError m-  => FieldContext-  -> StringType-  -> [DotProtoOption]-  -> TypeContext-  -> DotProtoType-  -> m HsType-dptToHsTypeWrapped fc stringType opts =-  foldDPT-    -- The wrapper for the collection type replaces the native haskell-    -- collection type, so try that first.-    (\ctxt ty -> maybe (dptToHsContType fc ctxt ty) id (dptToHsWrappedContType fc ctxt opts ty))-    -- Always wrap the primitive type.-    (dpptToHsTypeWrapped stringType)---- | Like 'dptToHsTypeWrapped' but without use of--- 'dptToHsContType' or 'dptToHsWrappedContType'.-dpptToHsTypeWrapped-  :: MonadError CompileError m-  => StringType-  -> TypeContext-  -> DotProtoPrimType-  -> m HsType-dpptToHsTypeWrapped (StringType _ stringType) ctxt =  \case-  Int32 ->-    pure $ primType_ "Int32"-  Int64 ->-    pure $ primType_ "Int64"-  SInt32 ->-    pure $ protobufSignedType_ $ primType_ "Int32"-  SInt64 ->-    pure $ protobufSignedType_ $ primType_ "Int64"-  UInt32 ->-    pure $ primType_ "Word32"-  UInt64 ->-    pure $ primType_ "Word64"-  Fixed32 ->-    pure $ protobufFixedType_ $ primType_ "Word32"-  Fixed64 ->-    pure $ protobufFixedType_ $ primType_ "Word64"-  SFixed32 ->-    pure $ protobufSignedType_ $ protobufFixedType_ $ primType_ "Int32"-  SFixed64 ->-    pure $ protobufSignedType_ $ protobufFixedType_ $ primType_ "Int64"-  String ->-    pure $ protobufStringType_ stringType-  Bytes  ->-    pure $ protobufBytesType_ "ByteString"-  Bool ->-    pure $ primType_ "Bool"-  Float ->-    pure $ primType_ "Float"-  Double ->-    pure $ primType_ "Double"-  Named (Dots (Path ("google" :| ["protobuf", x])))-    | x == "Int32Value" ->-        pure $ protobufWrappedType_ $ primType_ "Int32"-    | x == "Int64Value" ->-        pure $ protobufWrappedType_ $ primType_ "Int64"-    | x == "UInt32Value" ->-        pure $ protobufWrappedType_ $ primType_ "Word32"-    | x == "UInt64Value" ->-        pure $ protobufWrappedType_ $ primType_ "Word64"-    | x == "StringValue" ->-        pure $ protobufWrappedType_ $ protobufStringType_ stringType-    | x == "BytesValue" ->-        pure $ protobufWrappedType_ $ protobufBytesType_ "ByteString"-    | x == "BoolValue" ->-        pure $ protobufWrappedType_ $ primType_ "Bool"-    | x == "FloatValue" ->-        pure $ protobufWrappedType_ $ primType_ "Float"-    | x == "DoubleValue" ->-        pure $ protobufWrappedType_ $ primType_ "Double"-  Named msgName ->-    case M.lookup msgName ctxt of-      Just ty@(DotProtoTypeInfo { dotProtoTypeInfoKind = DotProtoKindEnum }) ->-          HsTyApp (protobufType_ "Enumerated") <$> msgTypeFromDpTypeInfo ctxt ty msgName-      Just ty -> msgTypeFromDpTypeInfo ctxt ty msgName-      Nothing -> noSuchTypeError msgName--foldDPT :: MonadError CompileError m-        => (TypeContext -> DotProtoType -> HsType -> HsType)-        -> (TypeContext -> DotProtoPrimType -> m HsType)-        -> TypeContext-        -> DotProtoType-        -> m HsType-foldDPT dptToHsCont foldPrim ctxt dpt =-  let-      prim = foldPrim ctxt-      go = foldDPT dptToHsCont foldPrim ctxt-      cont = dptToHsCont ctxt dpt-  in-    case dpt of-      Prim pType           -> cont <$> prim pType-      Repeated pType       -> cont <$> prim pType-      NestedRepeated pType -> cont <$> prim pType-      Map k v  | validMapKey k -> HsTyApp . cont <$> prim k <*> go (Prim v) -- need to 'Nest' message types-               | otherwise -> throwError $ InvalidMapKeyType (show $ pPrint k)---- | Translate DotProtoType constructors to wrapped Haskell container types--- (for Message serde instances).------ When the given 'FieldContext' is 'WithinOneOf' we do not wrap submessages--- in "Maybe" because the entire oneof is already wrapped in a "Maybe".-dptToHsWrappedContType :: FieldContext -> TypeContext -> [DotProtoOption] -> DotProtoType -> Maybe (HsType -> HsType)-dptToHsWrappedContType fc ctxt opts = \case-  Prim (Named tyName)-    | WithinMessage <- fc, isMessage ctxt tyName-                            -> Just $ HsTyApp (protobufType_ "Nested")-  Repeated (Named tyName)-    | isMessage ctxt tyName -> Just $ HsTyApp (protobufType_ "NestedVec")-  Repeated ty-    | isUnpacked opts       -> Just $ HsTyApp (protobufType_ "UnpackedVec")-    | isPacked opts         -> Just $ HsTyApp (protobufType_ "PackedVec")-    | isPackable ctxt ty    -> Just $ HsTyApp (protobufType_ "PackedVec")-    | otherwise             -> Just $ HsTyApp (protobufType_ "UnpackedVec")-  _ -> Nothing---- | Translate DotProtoType to Haskell container types.------ When the given 'FieldContext' is 'WithinOneOf' we do not wrap submessages--- in "Maybe" because the entire oneof is already wrapped in a "Maybe".-dptToHsContType :: FieldContext -> TypeContext -> DotProtoType -> HsType -> HsType-dptToHsContType fc ctxt = \case-  Prim (Named tyName) | WithinMessage <- fc, isMessage ctxt tyName-                     -> HsTyApp $ primType_ "Maybe"-  Repeated _         -> HsTyApp $ primType_ "Vector"-  NestedRepeated _   -> HsTyApp $ primType_ "Vector"-  Map _ _            -> HsTyApp $ primType_ "Map"-  _                  -> id---- | Convert a dot proto prim type to an unwrapped Haskell type-dpptToHsType :: MonadError CompileError m-             => StringType-             -> TypeContext-             -> DotProtoPrimType-             -> m HsType-dpptToHsType (StringType _ stringType) ctxt = \case-  Int32    -> pure $ primType_ "Int32"-  Int64    -> pure $ primType_ "Int64"-  SInt32   -> pure $ primType_ "Int32"-  SInt64   -> pure $ primType_ "Int64"-  UInt32   -> pure $ primType_ "Word32"-  UInt64   -> pure $ primType_ "Word64"-  Fixed32  -> pure $ primType_ "Word32"-  Fixed64  -> pure $ primType_ "Word64"-  SFixed32 -> pure $ primType_ "Int32"-  SFixed64 -> pure $ primType_ "Int64"-  String   -> pure $ primType_ stringType-  Bytes    -> pure $ primType_ "ByteString"-  Bool     -> pure $ primType_ "Bool"-  Float    -> pure $ primType_ "Float"-  Double   -> pure $ primType_ "Double"-  Named (Dots (Path ("google" :| ["protobuf", x])))-    | x == "Int32Value" -> pure $ primType_ "Int32"-    | x == "Int64Value" -> pure $ primType_ "Int64"-    | x == "UInt32Value" -> pure $ primType_ "Word32"-    | x == "UInt64Value" -> pure $ primType_ "Word64"-    | x == "StringValue" -> pure $ primType_ stringType-    | x == "BytesValue" -> pure $ primType_ "ByteString"-    | x == "BoolValue" -> pure $ primType_ "Bool"-    | x == "FloatValue" -> pure $ primType_ "Float"-    | x == "DoubleValue" -> pure $ primType_ "Double"-  Named msgName ->-    case M.lookup msgName ctxt of-      Just ty@(DotProtoTypeInfo { dotProtoTypeInfoKind = DotProtoKindEnum }) ->-          HsTyApp (protobufType_ "Enumerated") <$> msgTypeFromDpTypeInfo ctxt ty msgName-      Just ty -> msgTypeFromDpTypeInfo ctxt ty msgName-      Nothing -> noSuchTypeError msgName--validMapKey :: DotProtoPrimType -> Bool-validMapKey = (`elem` [ Int32, Int64, SInt32, SInt64, UInt32, UInt64-                      , Fixed32, Fixed64, SFixed32, SFixed64-                      , String, Bool])----------------------------------------------------------------------------------------- * Code generation------- ** Generate instances for a 'DotProto' package--dotProtoDefinitionD :: MonadError CompileError m-                    => StringType-                    -> RecordStyle-                    -> DotProtoPackageSpec-                    -> TypeContext-                    -> DotProtoDefinition-                    -> m [HsDecl]-dotProtoDefinitionD stringType recordStyle pkgSpec ctxt = \case-  DotProtoMessage _ messageName messageParts ->-    dotProtoMessageD stringType recordStyle ctxt Anonymous messageName messageParts--  DotProtoEnum _ enumName enumParts ->-    dotProtoEnumD Anonymous enumName enumParts--  DotProtoService _ serviceName serviceParts ->-    dotProtoServiceD stringType pkgSpec ctxt serviceName serviceParts---- | Generate 'Named' instance for a type in this package-namedInstD :: String -> HsDecl-namedInstD messageName =-  instDecl_ (protobufName "Named")-      [ type_ messageName ]-      [ HsFunBind [nameOfDecl] ]-  where-    nameOfDecl = match_ (HsIdent "nameOf") [HsPWildCard]-                        (HsUnGuardedRhs (apply fromStringE-                                               [ str_ messageName ]))-                        []--hasDefaultInstD :: String -> HsDecl-hasDefaultInstD messageName =-  instDecl_ (protobufName "HasDefault")-      [ type_ messageName ]-      [ ]---- ** Generate types and instances for .proto messages---- | Generate data types, 'Bounded', 'Enum', 'FromJSONPB', 'Named', 'Message',---   'ToJSONPB' instances as appropriate for the given 'DotProtoMessagePart's-dotProtoMessageD-    :: forall m-     . MonadError CompileError m-    => StringType-    -> RecordStyle-    -> TypeContext-    -> DotProtoIdentifier-    -> DotProtoIdentifier-    -> [DotProtoMessagePart]-    -> m [HsDecl]-dotProtoMessageD stringType recordStyle ctxt parentIdent messageIdent messageParts = do-    messageName <- qualifiedMessageName parentIdent messageIdent--    let mkDataDecl flds =-          dataDecl_ messageName-            [ recDecl_ (HsIdent messageName) flds ]-            defaultMessageDeriving--#ifdef SWAGGER-    let getName = \case-          DotProtoMessageField fld -> (: []) <$> getFieldNameForSchemaInstanceDeclaration fld-          DotProtoMessageOneOf ident _ -> (: []) . (Nothing, ) <$> dpIdentUnqualName ident-          _ -> pure []-#endif--    messageDataDecl <- mkDataDecl <$> foldMapM (messagePartFieldD messageName) messageParts--    foldMapM id-      [ sequence-          [ pure messageDataDecl-          , pure (nfDataInstD messageDataDecl messageName)-          , pure (namedInstD messageName)-          , pure (hasDefaultInstD messageName)-          , messageInstD stringType ctxt' parentIdent messageIdent messageParts--          , toJSONPBMessageInstD stringType ctxt' parentIdent messageIdent messageParts-          , fromJSONPBMessageInstD stringType ctxt' parentIdent messageIdent messageParts--            -- Generate Aeson instances in terms of JSONPB instances-          , pure (toJSONInstDecl messageName)-          , pure (fromJSONInstDecl messageName)--#ifdef SWAGGER-          -- And the Swagger ToSchema instance corresponding to JSONPB encodings-          , toSchemaInstanceDeclaration stringType ctxt' messageName Nothing-              =<< foldMapM getName messageParts-#endif--#ifdef DHALL-          -- Generate Dhall instances-          , pure (dhallInterpretInstDecl messageName)-          , pure (dhallInjectInstDecl messageName)-#endif-          ]--      -- Nested regular and oneof message decls-      , foldMapOfM (traverse . _DotProtoMessageDefinition)-                   nestedDecls-                   messageParts--      , foldMapOfM (traverse . _DotProtoMessageOneOf)-                   (uncurry $ nestedOneOfDecls messageName)-                   messageParts-      ]--  where-    ctxt' :: TypeContext-    ctxt' = maybe mempty dotProtoTypeChildContext (M.lookup messageIdent ctxt)-                <> ctxt--    nfDataInstD = case recordStyle of-                    RegularRecords -> RegularRecord.nfDataInstD-                    LargeRecords -> LargeRecord.nfDataInstD--    messagePartFieldD :: String -> DotProtoMessagePart -> m [([HsName], HsBangType)]-    messagePartFieldD messageName (DotProtoMessageField DotProtoField{..}) = do-      fullName <- prefixedFieldName messageName =<< dpIdentUnqualName dotProtoFieldName-      fullTy <- dptToHsType WithinMessage stringType ctxt' dotProtoFieldType-      pure [ ([HsIdent fullName], HsUnBangedTy fullTy ) ]--    messagePartFieldD messageName (DotProtoMessageOneOf fieldName _) = do-      fullName <- prefixedFieldName messageName =<< dpIdentUnqualName fieldName-      qualTyName <- prefixedConName messageName =<< dpIdentUnqualName fieldName-      let fullTy = HsTyApp (HsTyCon (haskellName "Maybe")) . type_ $ qualTyName-      pure [ ([HsIdent fullName], HsUnBangedTy fullTy) ]--    messagePartFieldD _ _ = pure []--    nestedDecls :: DotProtoDefinition -> m [HsDecl]-    nestedDecls (DotProtoMessage _ subMsgName subMessageDef) = do-      parentIdent' <- concatDotProtoIdentifier parentIdent messageIdent-      dotProtoMessageD stringType recordStyle ctxt' parentIdent' subMsgName subMessageDef--    nestedDecls (DotProtoEnum _ subEnumName subEnumDef) = do-      parentIdent' <- concatDotProtoIdentifier parentIdent messageIdent-      dotProtoEnumD parentIdent' subEnumName subEnumDef--    nestedDecls _ = pure []--    nestedOneOfDecls :: String -> DotProtoIdentifier -> [DotProtoField] -> m [HsDecl]-    nestedOneOfDecls messageName identifier fields = do-      fullName <- prefixedConName messageName =<< dpIdentUnqualName identifier--      (cons, idents) <- fmap unzip (mapM (oneOfCons fullName) fields)--#ifdef SWAGGER-      toSchemaInstance <- toSchemaInstanceDeclaration stringType ctxt' fullName (Just idents)-                            =<< mapM getFieldNameForSchemaInstanceDeclaration fields-#endif--      let nestedDecl = dataDecl_ fullName cons defaultMessageDeriving-      pure [ nestedDecl-           , nfDataInstD nestedDecl fullName-           , namedInstD fullName-#ifdef SWAGGER-           , toSchemaInstance-#endif--#ifdef DHALL-           , dhallInterpretInstDecl fullName-           , dhallInjectInstDecl fullName-#endif-           ]--    oneOfCons :: String -> DotProtoField -> m (HsConDecl, HsName)-    oneOfCons fullName DotProtoField{..} = do-       consTy <- dptToHsType WithinOneOf stringType ctxt' dotProtoFieldType-       consName <- prefixedConName fullName =<< dpIdentUnqualName dotProtoFieldName-       let ident = HsIdent consName-       pure (conDecl_ ident [HsUnBangedTy consTy], ident)--    oneOfCons _ DotProtoEmptyField = internalError "field type : empty field"---- *** Generate Protobuf 'Message' instances--messageInstD-    :: forall m-     . MonadError CompileError m-    => StringType-    -> TypeContext-    -> DotProtoIdentifier-    -> DotProtoIdentifier-    -> [DotProtoMessagePart]-    -> m HsDecl-messageInstD stringType ctxt parentIdent msgIdent messageParts = do-     msgName         <- qualifiedMessageName parentIdent msgIdent-     qualifiedFields <- getQualifiedFields msgName messageParts--     encodedFields   <- mapM encodeMessageField qualifiedFields-     decodedFields   <- mapM decodeMessageField qualifiedFields--     let encodeMessageDecl = match_ (HsIdent "encodeMessage")-                                    [HsPWildCard, HsPRec (unqual_ msgName) punnedFieldsP]-                                    (HsUnGuardedRhs encodeMessageE) []--         encodeMessageE = case encodedFields of-           [] -> memptyE-           (field : fields) -> foldl op (paren field) fields-             where op fs f = apply (apply mappendE [fs]) [paren f]-             -- NOTE: We use a left fold because this way the leftmost field-             -- is the most nested and the rightmost field--the one to be written-             -- first by the right-to-left builder--is the one that is least nested.--         punnedFieldsP = map (fp . coerce . recordFieldName) qualifiedFields-           where fp nm = HsPFieldPat (unqual_ nm) (HsPVar (HsIdent nm))---     let decodeMessageDecl = match_ (HsIdent "decodeMessage") [ HsPWildCard ]-                                    (HsUnGuardedRhs decodeMessageE) []--         decodeMessageE = foldl (\f -> HsInfixApp f apOp)-                                (apply pureE [ uvar_ msgName ])-                                decodedFields--     let dotProtoDecl = match_ (HsIdent "dotProto") [HsPWildCard]-                               (HsUnGuardedRhs dotProtoE) []--         dotProtoE = HsList $ do-           DotProtoMessageField DotProtoField{..} <- messageParts-           pure $ apply dotProtoFieldC-                        [ fieldNumberE dotProtoFieldNumber-                        , dpTypeE dotProtoFieldType-                        , dpIdentE dotProtoFieldName-                        , HsList (map optionE dotProtoFieldOptions)-                        , str_ dotProtoFieldComment-                        ]---     pure $ instDecl_ (protobufName "Message")-                      [ type_ msgName ]-                      [ HsFunBind [ encodeMessageDecl ]-                      , HsFunBind [ decodeMessageDecl ]-                      , HsFunBind [ dotProtoDecl ]-                      ]-  where-    encodeMessageField :: QualifiedField -> m HsExp-    encodeMessageField QualifiedField{recordFieldName, fieldInfo} =-      let recordFieldName' = uvar_ (coerce recordFieldName) in-      case fieldInfo of-        FieldNormal _fieldName fieldNum dpType options -> do-            fieldE <- wrapE WithinMessage stringType ctxt options dpType recordFieldName'-            pure $ apply encodeMessageFieldE [ fieldNumberE fieldNum, fieldE ]--        FieldOneOf OneofField{subfields} -> do-            alts <- mapM mkAlt subfields-            pure $ HsCase recordFieldName'-                    [ alt_ (HsPApp (haskellName "Nothing") [])-                           (HsUnGuardedAlt memptyE)-                           []-                    , alt_ (HsPApp (haskellName "Just") [patVar "x"])-                           (HsUnGuardedAlt (HsCase (uvar_ "x") alts))-                           []-                    ]-          where-            -- Create all pattern match & expr for each constructor:-            --    Constructor y -> encodeMessageField num (Nested (Just y)) -- for embedded messages-            --    Constructor y -> encodeMessageField num (ForceEmit y)     -- for everything else-            mkAlt (OneofSubfield fieldNum conName _ dpType options) = do-              let isMaybe-                     | Prim (Named tyName) <- dpType-                     = isMessage ctxt tyName-                     | otherwise-                     = False--              let wrapJust = HsParen . HsApp (HsVar (haskellName "Just"))--              xE <- (if isMaybe then id else fmap forceEmitE)-                     . wrapE WithinMessage stringType ctxt options dpType-                         -- For now we use 'WithinMessage' to preserve-                         -- the historical approach of treating this field-                         -- as if it were an ordinary non-oneof field that-                         -- just happens to be present.-                     . (if isMaybe then wrapJust else id)-                     $ uvar_ "y"--              pure $ alt_ (HsPApp (unqual_ conName) [patVar "y"])-                          (HsUnGuardedAlt (apply encodeMessageFieldE [fieldNumberE fieldNum, xE]))-                          []---    decodeMessageField :: QualifiedField -> m HsExp-    decodeMessageField QualifiedField{fieldInfo} =-      case fieldInfo of-        FieldNormal _fieldName fieldNum dpType options ->-            unwrapE WithinMessage stringType ctxt options dpType $-              apply atE [ decodeMessageFieldE, fieldNumberE fieldNum ]--        FieldOneOf OneofField{subfields} -> do-            parsers <- mapM subfieldParserE subfields-            pure $  apply oneofE [ HsVar (haskellName "Nothing")-                                 , HsList parsers-                                 ]-          where-            -- create a list of (fieldNumber, Cons <$> parser)-            subfieldParserE (OneofSubfield fieldNumber consName _ dpType options) = do-              let fE | Prim (Named tyName) <- dpType, isMessage ctxt tyName-                     = HsParen (HsApp fmapE (uvar_ consName))-                     | otherwise-                     = HsParen (HsInfixApp (HsVar (haskellName "Just"))-                                           composeOp-                                           (uvar_ consName))--              -- For now we continue the historical practice of parsing-              -- submessages within oneofs as if were outside of oneofs,-              -- and replacing the "Just . Ctor" with "fmap . Ctor".-              -- That is why we do not pass WithinOneOf.-              alts <- unwrapE WithinMessage stringType ctxt options dpType decodeMessageFieldE--              pure $ HsTuple-                   [ fieldNumberE fieldNumber-                   , HsInfixApp (apply pureE [ fE ]) apOp alts-                   ]----- *** Generate ToJSONPB/FromJSONPB instances--toJSONPBMessageInstD-    :: forall m-     . MonadError CompileError m-    => StringType-    -> TypeContext-    -> DotProtoIdentifier-    -> DotProtoIdentifier-    -> [DotProtoMessagePart]-    -> m HsDecl-toJSONPBMessageInstD stringType ctxt parentIdent msgIdent messageParts = do-    msgName    <- qualifiedMessageName parentIdent msgIdent-    qualFields <- getQualifiedFields msgName messageParts--    let applyE nm oneofNm = do-          fs <- traverse (encodeMessageField oneofNm) qualFields-          pure $ apply (HsVar (jsonpbName nm)) [HsList fs]--    let patBinder = foldQF (const fieldBinder) (oneofSubDisjunctBinder . subfields)-    let matchE nm appNm oneofAppNm = do-          rhs <- applyE appNm oneofAppNm-          pure $ match_-            (HsIdent nm)-            [ HsPApp (unqual_ msgName)-                     (patVar . patBinder <$> qualFields) ]-            (HsUnGuardedRhs rhs)-            []--    toJSONPB <- matchE "toJSONPB" "object" "objectOrNull"-    toEncoding <- matchE "toEncodingPB" "pairs" "pairsOrNull"--    pure $ instDecl_ (jsonpbName "ToJSONPB")-                     [ type_ msgName ]-                     [ HsFunBind [toJSONPB]-                     , HsFunBind [toEncoding]-                     ]--  where-    encodeMessageField :: String -> QualifiedField -> m HsExp-    encodeMessageField oneofNm (QualifiedField _ fieldInfo) =-      case fieldInfo of-        FieldNormal fldName fldNum dpType options ->-          defPairE fldName fldNum dpType options-        FieldOneOf oo ->-          oneofCaseE oneofNm oo--    -- E.g.-    -- "another" .= f2 -- always succeeds (produces default value on missing field)-    defPairE fldName fldNum dpType options = do-      w <- wrapE WithinMessage stringType ctxt options dpType (uvar_ (fieldBinder fldNum))-      pure $ HsInfixApp (str_ (coerce fldName)) toJSONPBOp w--    -- E.g.-    -- HsJSONPB.pair "name" f4 -- fails on missing field-    oneOfPairE fldNm varNm options dpType = do-      w <- wrapE WithinOneOf stringType ctxt options dpType (uvar_ varNm)-      pure $ apply (HsVar (jsonpbName "pair")) [str_ (coerce fldNm), w]--    -- Suppose we have a sum type Foo, nested inside a message Bar.-    -- We want to generate the following:-    ---    -- > toJSONPB (Bar foo more stuff) =-    -- >   HsJSONPB.object-    -- >     [ (let encodeFoo = (<case expr scrutinising foo> :: Options -> Value)-    -- >        in \option -> if optEmitNamedOneof option-    -- >                      then ("Foo" .= (PB.objectOrNull [encodeFoo] option)) option-    -- >                      else encodeFoo option-    -- >       )-    -- >     , <encode more>-    -- >     , <encode stuff>-    -- >     ]-    oneofCaseE :: String -> OneofField -> m HsExp-    oneofCaseE retJsonCtor (OneofField typeName subfields) = do-        altEs <- traverse altE subfields-        pure $ HsParen-          $ HsLet [ HsFunBind [ match_ (HsIdent caseName) [] (HsUnGuardedRhs (caseExpr altEs)) [] ] ]-          $ HsLambda defaultSrcLoc [patVar optsStr] (HsIf dontInline noInline yesInline)-      where-        optsStr = "options"-        opts    = uvar_ optsStr--        caseName = "encode" <> over (ix 0) toUpper typeName-        caseBnd = uvar_ caseName--        dontInline = HsApp (HsVar (jsonpbName "optEmitNamedOneof")) opts--        noInline = HsApp (HsParen (HsInfixApp (str_ typeName)-                                              toJSONPBOp-                                              (apply (HsVar (jsonpbName retJsonCtor))-                                                     [ HsList [caseBnd], opts ])))-                         opts--        yesInline = HsApp caseBnd opts--        altE sub@(OneofSubfield _ conName pbFldNm dpType options) = do-          let patVarNm = oneofSubBinder sub-          p <- oneOfPairE pbFldNm patVarNm options dpType-          pure $ alt_ (HsPApp (haskellName "Just")-                              [ HsPParen-                                (HsPApp (unqual_ conName) [patVar patVarNm])-                              ]-                      )-                      (HsUnGuardedAlt p)-                      []--        -- E.g.-        -- case f4_or_f9 of-        --   Just (SomethingPickOneName f4)-        --     -> HsJSONPB.pair "name" f4-        --   Just (SomethingPickOneSomeid f9)-        --     -> HsJSONPB.pair "someid" f9-        --   Nothing-        --     -> mempty-        caseExpr altEs = HsParen $-            HsCase disjunctName (altEs <> [fallthroughE])-          where-            disjunctName = uvar_ (oneofSubDisjunctBinder subfields)-            fallthroughE =-              alt_ (HsPApp (haskellName "Nothing") [])-                   (HsUnGuardedAlt memptyE)-                   []--fromJSONPBMessageInstD-    :: forall m-     . MonadError CompileError m-    => StringType-    -> TypeContext-    -> DotProtoIdentifier-    -> DotProtoIdentifier-    -> [DotProtoMessagePart]-    -> m HsDecl-fromJSONPBMessageInstD stringType ctxt parentIdent msgIdent messageParts = do-    msgName    <- qualifiedMessageName parentIdent msgIdent-    qualFields <- getQualifiedFields msgName messageParts--    fieldParsers <- traverse parseField qualFields--    let parseJSONPBE =-          apply (HsVar (jsonpbName "withObject"))-                [ str_ msgName-                , HsParen (HsLambda defaultSrcLoc [lambdaPVar] fieldAps)-                ]-          where-            fieldAps = foldl (\f -> HsInfixApp f apOp)-                             (apply pureE [ uvar_ msgName ])-                             fieldParsers--    let parseJSONPBDecl =-          match_ (HsIdent "parseJSONPB") [] (HsUnGuardedRhs parseJSONPBE) []--    pure (instDecl_ (jsonpbName "FromJSONPB")-                   [ type_ msgName ]-                   [ HsFunBind [ parseJSONPBDecl ] ])-  where-    lambdaPVar = patVar "obj"-    lambdaVar  = uvar_ "obj"--    parseField (QualifiedField _ (FieldNormal fldName _ dpType options)) =-      normalParserE fldName dpType options-    parseField (QualifiedField _ (FieldOneOf fld)) =-      oneofParserE fld--    -- E.g., for message-    --   message Something { oneof name_or_id { string name = _; int32 someid = _; } }-    ---    -- ==>-    ---    -- (let parseSomethingNameOrId parseObj = <FUNCTION, see tryParseDisjunctsE>-    --  in ((obj .: "nameOrId") Hs.>>=-    --      (HsJSONPB.withObject "nameOrId" parseSomethingNameOrId))-    --     <|>-    --     (parseSomethingNameOrId obj)-    -- )-    oneofParserE :: OneofField -> m HsExp-    oneofParserE (OneofField oneofType fields) = do-        ds <- tryParseDisjunctsE-        pure $ HsParen $-          HsLet [ HsFunBind [ match_ (HsIdent letBndStr) [patVar letArgStr ]-                                     (HsUnGuardedRhs ds) []-                            ]-                ]-                (HsInfixApp parseWrapped altOp parseUnwrapped)-      where-        oneofTyLit = str_ oneofType -- FIXME--        letBndStr  = "parse" <> over (ix 0) toUpper oneofType-        letBndName = uvar_ letBndStr-        letArgStr  = "parseObj"-        letArgName = uvar_ letArgStr--        parseWrapped = HsParen $-          HsInfixApp (HsParen (HsInfixApp lambdaVar parseJSONPBOp oneofTyLit))-                     bindOp-                     (apply (HsVar (jsonpbName "withObject")) [ oneofTyLit , letBndName ])--        parseUnwrapped = HsParen (HsApp letBndName lambdaVar)--        -- parseSomethingNameOrId parseObj =-        --   Hs.msum-        --     [ (Just . SomethingPickOneName) <$> (HsJSONPB.parseField parseObj "name")-        --     , (Just . SomethingPickOneSomeid) <$> (HsJSONPB.parseField parseObj "someid")-        --     , pure Nothing-        --     ]-        tryParseDisjunctsE = do-          fs <- traverse subParserE fields-          pure $ HsApp msumE (HsList (fs <> fallThruE))--        fallThruE = [ HsApp pureE (HsVar (haskellName "Nothing")) ]--        subParserE OneofSubfield{subfieldConsName, subfieldName,-                                 subfieldType, subfieldOptions} = do-          maybeCoercion <--            unwrapFunE False WithinOneOf stringType ctxt subfieldOptions subfieldType-          let inject = (HsInfixApp (HsVar (haskellName "Just"))-                                   composeOp-                                   (uvar_ subfieldConsName))-          pure $ HsInfixApp-              (maybe inject (HsInfixApp inject composeOp) maybeCoercion)-              fmapOp-              (apply (HsVar (jsonpbName "parseField"))-                     [ letArgName-                     , str_ (coerce subfieldName)])--    -- E.g. obj .: "someid"-    normalParserE :: FieldName -> DotProtoType -> [DotProtoOption] -> m HsExp-    normalParserE fldName dpType options =-      unwrapE WithinMessage stringType ctxt options dpType $-        HsInfixApp lambdaVar-                   parseJSONPBOp-                   (str_(coerce fldName))---- *** Generate default Aeson To/FromJSON and Swagger ToSchema instances--- (These are defined in terms of ToJSONPB)--toJSONInstDecl :: String -> HsDecl-toJSONInstDecl typeName =-  instDecl_ (jsonpbName "ToJSON")-            [ type_ typeName ]-            [ HsFunBind [ match_ (HsIdent "toJSON") []-                                 (HsUnGuardedRhs (HsVar (jsonpbName "toAesonValue"))) []-                        ]-            , HsFunBind [ match_ (HsIdent "toEncoding") []-                                 (HsUnGuardedRhs (HsVar (jsonpbName "toAesonEncoding"))) []-                        ]-            ]--fromJSONInstDecl :: String -> HsDecl-fromJSONInstDecl typeName =-  instDecl_ (jsonpbName "FromJSON")-            [ type_ typeName ]-            [ HsFunBind [match_ (HsIdent "parseJSON") []-                                (HsUnGuardedRhs (HsVar (jsonpbName "parseJSONPB"))) []-                        ]-            ]----- *** Generate `ToSchema` instance--getFieldNameForSchemaInstanceDeclaration-  :: MonadError CompileError m-  => DotProtoField-  -> m (Maybe ([DotProtoOption], DotProtoType), String)-getFieldNameForSchemaInstanceDeclaration fld = do-  unqual <- dpIdentUnqualName (dotProtoFieldName fld)-  let optsType = (dotProtoFieldOptions fld, dotProtoFieldType fld)-  pure (Just optsType, unqual)--toSchemaInstanceDeclaration-    :: MonadError CompileError m-    => StringType-    -> TypeContext-    -> String-    -- ^ Name of the message type to create an instance for-    -> Maybe [HsName]-    -- ^ Oneof constructors-    -> [(Maybe ([DotProtoOption], DotProtoType), String)]-    -- ^ Field names, with every field that is not actually a oneof-    -- combining fields paired with its options and protobuf type-    -> m HsDecl-toSchemaInstanceDeclaration stringType ctxt messageName maybeConstructors fieldNamesEtc = do-  let fieldNames = map snd fieldNamesEtc--  qualifiedFieldNames <- mapM (prefixedFieldName messageName) fieldNames--  let messageConstructor = HsCon (UnQual (HsIdent messageName))--  let _namedSchemaNameExpression = HsApp justC (str_ messageName)--#ifdef SWAGGER-      -- { _paramSchemaType = HsJSONPB.SwaggerObject-      -- }-  let paramSchemaUpdates =-        [ HsFieldUpdate _paramSchemaType _paramSchemaTypeExpression-        ]-        where-          _paramSchemaType = jsonpbName "_paramSchemaType"--#if MIN_VERSION_swagger2(2,4,0)-          _paramSchemaTypeExpression = HsApp justC (HsVar (jsonpbName "SwaggerObject"))-#else-          _paramSchemaTypeExpression = HsVar (jsonpbName "SwaggerObject")-#endif-#else-  let paramSchemaUpdates = []-#endif--  let _schemaParamSchemaExpression = HsRecUpdate memptyE paramSchemaUpdates--      -- [ ("fieldName0", qualifiedFieldName0)-      -- , ("fieldName1", qualifiedFieldName1)-      -- ...-      -- ]-  let properties = HsList $ do-        (fieldName, qualifiedFieldName) <- zip fieldNames qualifiedFieldNames-        return (HsTuple [ str_  fieldName, uvar_ qualifiedFieldName ])--  let _schemaPropertiesExpression =-        HsApp (HsVar (jsonpbName "insOrdFromList")) properties--      -- { _schemaParamSchema = ...-      -- , _schemaProperties  = ...-      -- , ...-      -- }-  let schemaUpdates = normalUpdates ++ extraUpdates-        where-          normalUpdates =-            [ HsFieldUpdate _schemaParamSchema _schemaParamSchemaExpression-            , HsFieldUpdate _schemaProperties  _schemaPropertiesExpression-            ]--          extraUpdates =-            case maybeConstructors of-                Just _ ->-                  [ HsFieldUpdate _schemaMinProperties justOne-                  , HsFieldUpdate _schemaMaxProperties justOne-                  ]-                Nothing ->-                  []--          _schemaParamSchema    = jsonpbName "_schemaParamSchema"-          _schemaProperties     = jsonpbName "_schemaProperties"-          _schemaMinProperties  = jsonpbName "_schemaMinProperties"-          _schemaMaxProperties  = jsonpbName "_schemaMaxProperties"--          justOne = HsApp justC (HsLit (HsInt 1))--  let _namedSchemaSchemaExpression = HsRecUpdate memptyE schemaUpdates--      -- { _namedSchemaName   = ...-      -- , _namedSchemaSchema = ...-      -- }-  let namedSchemaUpdates =-        [ HsFieldUpdate _namedSchemaName   _namedSchemaNameExpression-        , HsFieldUpdate _namedSchemaSchema _namedSchemaSchemaExpression-        ]-        where-          _namedSchemaName   = jsonpbName "_namedSchemaName"-          _namedSchemaSchema = jsonpbName "_namedSchemaSchema"--  let namedSchema = HsRecConstr (jsonpbName "NamedSchema") namedSchemaUpdates--  let toDeclareName fieldName = "declare_" ++ fieldName--  let toArgument fc (maybeOptsType, fieldName) =-          maybe pure (uncurry (unwrapE fc stringType ctxt)) maybeOptsType $-            HsApp asProxy declare-        where-          declare = uvar_ (toDeclareName fieldName)-          asProxy = HsVar (jsonpbName "asProxy")--      -- do let declare_fieldName0 = HsJSONPB.declareSchemaRef-      --    qualifiedFieldName0 <- declare_fieldName0 Proxy.Proxy-      --    let declare_fieldName1 = HsJSONPB.declareSchemaRef-      --    qualifiedFieldName1 <- declare_fieldName1 Proxy.Proxy-      --    ...-      --    let _ = pure MessageName <*> HsJSONPB.asProxy declare_fieldName0 <*> HsJSONPB.asProxy declare_fieldName1 <*> ...-      --    return (...)-  let expressionForMessage = do-        let bindingStatements = do-              (fieldName, qualifiedFieldName) <- zip fieldNames qualifiedFieldNames--              let declareIdentifier = HsIdent (toDeclareName fieldName)--              let stmt0 = HsLetStmt [ HsFunBind-                                      [ HsMatch defaultSrcLoc declareIdentifier []-                                                 (HsUnGuardedRhs (HsVar (jsonpbName "declareSchemaRef"))) []-                                      ]-                                    ]--              let stmt1 = HsGenerator defaultSrcLoc (HsPVar (HsIdent qualifiedFieldName))-                                        (HsApp (HsVar (UnQual declareIdentifier))-                                               (HsCon (proxyName "Proxy")))-              [ stmt0, stmt1]--        inferenceStatement <- do-          arguments <- traverse (toArgument WithinMessage) fieldNamesEtc-          let patternBind = HsPatBind defaultSrcLoc HsPWildCard-                (HsUnGuardedRhs (applicativeApply messageConstructor arguments)) []-          pure $ if null fieldNames then [] else [ HsLetStmt [ patternBind ] ]--        let returnStatement = HsQualifier (HsApp returnE (HsParen namedSchema))--        pure $ HsDo (bindingStatements ++ inferenceStatement ++ [ returnStatement ])--      -- do let declare_fieldName0 = HsJSONPB.declareSchemaRef-      --    let _ = pure ConstructorName0 <*> HsJSONPB.asProxy declare_fieldName0-      --    qualifiedFieldName0 <- declare_fieldName0 Proxy.Proxy-      --    let declare_fieldName1 = HsJSONPB.declareSchemaRef-      --    let _ = pure ConstructorName1 <*> HsJSONPB.asProxy declare_fieldName1-      --    qualifiedFieldName1 <- declare_fieldName1 Proxy.Proxy-      --    ...-      --    return (...)-  let expressionForOneOf constructors = do-        let bindingStatement (fieldNameEtc, qualifiedFieldName, constructor) = do-              let declareIdentifier = HsIdent (toDeclareName (snd fieldNameEtc))--              let stmt0 = HsLetStmt [ HsFunBind-                                        [ HsMatch defaultSrcLoc declareIdentifier []-                                                   (HsUnGuardedRhs (HsVar (jsonpbName "declareSchemaRef"))) []-                                        ]-                                    ]-              let stmt1 = HsGenerator defaultSrcLoc (HsPVar (HsIdent qualifiedFieldName))-                                        (HsApp (HsVar (UnQual declareIdentifier))-                                               (HsCon (proxyName "Proxy")))-              inferenceStatement <- do-                argument <- toArgument WithinOneOf fieldNameEtc-                let patternBind = HsPatBind defaultSrcLoc HsPWildCard-                      (HsUnGuardedRhs (applicativeApply (HsCon (UnQual constructor)) [ argument ])) []-                pure $ if null fieldNames then [] else [ HsLetStmt [ patternBind ] ]--              pure $ [stmt0, stmt1] ++ inferenceStatement--        bindingStatements <- foldMapM bindingStatement $-          zip3 fieldNamesEtc qualifiedFieldNames constructors--        let returnStatement = HsQualifier (HsApp returnE (HsParen namedSchema))--        pure $ HsDo (bindingStatements ++ [ returnStatement ])--  expression <- case maybeConstructors of-    Nothing           -> expressionForMessage-    Just constructors -> expressionForOneOf constructors--  let instanceDeclaration =-          instDecl_ className [ classArgument ] [ classDeclaration ]-        where-          className = jsonpbName "ToSchema"--          classArgument = HsTyCon (UnQual (HsIdent messageName))--          classDeclaration = HsFunBind [ match ]-            where-              match = match_ matchName [ HsPWildCard ] rightHandSide []-                where-                  rightHandSide = HsUnGuardedRhs expression--                  matchName = HsIdent "declareNamedSchema"--  return instanceDeclaration----- ** Generate types and instances for .proto enums--dotProtoEnumD-    :: MonadError CompileError m-    => DotProtoIdentifier-    -> DotProtoIdentifier-    -> [DotProtoEnumPart]-    -> m [HsDecl]-dotProtoEnumD parentIdent enumIdent enumParts = do-  enumName <- qualifiedMessageName parentIdent enumIdent--  let enumeratorDecls =-        [ (i, conIdent) | DotProtoEnumField conIdent i _options <- enumParts ]--  case enumeratorDecls of-    [] -> throwError $ EmptyEnumeration enumName-    (i, conIdent) : _-      | i == 0 -> return ()-      | otherwise -> throwError $ NonzeroFirstEnumeration enumName conIdent i--  enumCons <- sortBy (comparing fst) <$> traverse (traverse (fmap (prefixedEnumFieldName enumName) . dpIdentUnqualName)) enumeratorDecls--  let enumConNames = map snd enumCons--      minBoundD =-          [ match_ (HsIdent "minBound")-                   []-                   (HsUnGuardedRhs (uvar_ (head enumConNames)))-                   []-          ]--      maxBoundD =-          [ match_ (HsIdent "maxBound")-                   []-                   (HsUnGuardedRhs (uvar_ (last enumConNames)))-                   []-          ]--      compareD =-          [ match_ (HsIdent "compare")-                   [ patVar "x", patVar "y" ]-                   (HsUnGuardedRhs-                       (HsApp-                           (HsApp-                               (HsVar (haskellName "compare"))-                               (HsParen-                                   (HsApp (HsVar(protobufName "fromProtoEnum"))-                                          (uvar_ "x")-                                   )-                               )-                           )-                           (HsParen-                               (HsApp (HsVar (protobufName "fromProtoEnum"))-                                      (uvar_ "y")-                               )-                           )-                       )-                   )-                   []-          ]--      fromProtoEnumD =-          [ match_ (HsIdent "fromProtoEnum") [ HsPApp (unqual_ conName) [] ]-                   (HsUnGuardedRhs (intE conIdx))-                   []-          | (conIdx, conName) <- enumCons-          ]--      toProtoEnumMayD =-          [ match_ (HsIdent "toProtoEnumMay")-                   [ intP conIdx ]-                   (HsUnGuardedRhs (HsApp justC (uvar_ conName)))-                   []-          | (conIdx, conName) <- enumCons ] ++-          [ match_ (HsIdent "toProtoEnumMay")-                   [ HsPWildCard ]-                   (HsUnGuardedRhs nothingC)-                   []-          ]--      parseJSONPBDecls :: [HsMatch]-      parseJSONPBDecls = foldr ((:) . matchConName) [mismatch] enumConNames-        where-          matchConName conName = match_ (HsIdent "parseJSONPB") [pat conName]-                                        (HsUnGuardedRhs-                                           (HsApp pureE (uvar_ conName)))-                                        []--          pat nm = HsPApp (jsonpbName "String") [ HsPLit (HsString (tryStripEnumName nm)) ]--          tryStripEnumName = fromMaybe <*> stripPrefix enumName--          mismatch = match_ (HsIdent "parseJSONPB") [patVar "v"]-                            (HsUnGuardedRhs-                                  (apply (HsVar (jsonpbName "typeMismatch"))-                                    [ str_ enumName, uvar_ "v" ]))-                            []---      toJSONPBDecl =-        match_ (HsIdent "toJSONPB") [ patVar "x", HsPWildCard ]-          (HsUnGuardedRhs-             (HsApp (HsVar (jsonpbName "enumFieldString"))-                    (uvar_ "x")))-          []--      toEncodingPBDecl =-        match_ (HsIdent "toEncodingPB") [ patVar "x", HsPWildCard ]-          (HsUnGuardedRhs-             (HsApp (HsVar (jsonpbName "enumFieldEncoding"))-                    (uvar_ "x")))-          []--  pure [ dataDecl_ enumName-                   [ conDecl_ (HsIdent con) [] | con <- enumConNames ]-                   defaultEnumDeriving-       , namedInstD enumName-       , hasDefaultInstD enumName-       , instDecl_ (haskellName "Bounded") [ type_ enumName ]-                   [ HsFunBind minBoundD-                   , HsFunBind maxBoundD-                   ]-       , instDecl_ (haskellName "Ord") [ type_ enumName ]-                   [ HsFunBind compareD ]-       , instDecl_ (protobufName "ProtoEnum") [ type_ enumName ]-                   [ HsFunBind toProtoEnumMayD-                   , HsFunBind fromProtoEnumD-                   ]-       , instDecl_ (jsonpbName "ToJSONPB") [ type_ enumName ]-                   [ HsFunBind [toJSONPBDecl]-                   , HsFunBind [toEncodingPBDecl]-                   ]-       , instDecl_ (jsonpbName "FromJSONPB") [ type_ enumName ]-                   [ HsFunBind parseJSONPBDecls ]-       -- Generate Aeson instances in terms of JSONPB instances-       , toJSONInstDecl enumName-       , fromJSONInstDecl enumName--#ifdef DHALL-       -- Generate Dhall instances-       , dhallInterpretInstDecl enumName-       , dhallInjectInstDecl enumName-#endif--       -- And the Finite instance, used to infer a Swagger ToSchema instance-       -- for this enumerated type.-       , instDecl_ (protobufName "Finite") [ type_ enumName ] []-       ]---- ** Generate code for dot proto services--dotProtoServiceD-    :: MonadError CompileError m-    => StringType-    -> DotProtoPackageSpec-    -> TypeContext-    -> DotProtoIdentifier-    -> [DotProtoServicePart]-    -> m [HsDecl]-dotProtoServiceD stringType pkgSpec ctxt serviceIdent service = do-     serviceName <- typeLikeName =<< dpIdentUnqualName serviceIdent--     endpointPrefix <--       case pkgSpec of-         DotProtoPackageSpec pkgIdent -> do-           packageName <- dpIdentQualName pkgIdent-           pure $ "/" ++ packageName ++ "." ++ serviceName ++ "/"-         DotProtoNoPackage -> pure $ "/" ++ serviceName ++ "/"--     let serviceFieldD (DotProtoServiceRPCMethod RPCMethod{..}) = do-           fullName <- prefixedMethodName serviceName =<< dpIdentUnqualName rpcMethodName--           methodName <- case rpcMethodName of-                           Single nm -> pure nm-                           _ -> invalidMethodNameError rpcMethodName--           requestTy  <- dpptToHsType stringType ctxt (Named rpcMethodRequestType)--           responseTy <- dpptToHsType stringType ctxt (Named rpcMethodResponseType)--           let streamingType =-                 case (rpcMethodRequestStreaming, rpcMethodResponseStreaming) of-                   (Streaming, Streaming)       -> biDiStreamingC-                   (Streaming, NonStreaming)    -> clientStreamingC-                   (NonStreaming, Streaming)    -> serverStreamingC-                   (NonStreaming, NonStreaming) -> normalC--           pure [ ( endpointPrefix ++ methodName-                  , fullName, rpcMethodRequestStreaming, rpcMethodResponseStreaming-                  , HsUnBangedTy $-                    HsTyFun (tyApp (HsTyVar (HsIdent "request"))-                                   [streamingType, requestTy, responseTy])-                            (tyApp ioT-                                   [tyApp (HsTyVar (HsIdent "response"))-                                          [streamingType, responseTy]-                                   ]-                            )-                  )-                ]--         serviceFieldD _ = pure []--     fieldsD <- foldMapM serviceFieldD service--     serverFuncName <- prefixedFieldName serviceName "server"-     clientFuncName <- prefixedFieldName serviceName "client"--     let conDecl = recDecl_ (HsIdent serviceName)-                            [ ([HsIdent hsName], ty) | (_, hsName, _, _, ty) <- fieldsD ]--     let serverT = tyApp (HsTyCon (unqual_ serviceName))-                         [ serverRequestT, serverResponseT ]--     let serviceServerTypeD =-            HsTypeSig defaultSrcLoc [ HsIdent serverFuncName ]-                        (HsQualType [] (HsTyFun serverT (HsTyFun serviceOptionsC ioActionT)))--     let serviceServerD = HsFunBind [serverFuncD]-           where-             serverFuncD =-               match_ (HsIdent serverFuncName)-                      [ HsPRec (unqual_ serviceName)-                               [ HsPFieldPat (unqual_ methodName) (HsPVar (HsIdent methodName))-                               | (_, methodName, _, _, _) <- fieldsD-                               ]-                      , HsPApp (unqual_ "ServiceOptions")-                               [ patVar "serverHost"-                               , patVar "serverPort"-                               , patVar "useCompression"-                               , patVar "userAgentPrefix"-                               , patVar "userAgentSuffix"-                               , patVar "initialMetadata"-                               , patVar "sslConfig"-                               , patVar "logger"-                               , patVar "serverMaxReceiveMessageLength"-                               , patVar "serverMaxMetadataSize"-                               ]-                      ]-                      (HsUnGuardedRhs (apply serverLoopE [ serverOptsE ]))-                      []--             handlerE handlerC adapterE methodName hsName =-                 apply handlerC [ apply methodNameC [ str_ methodName ]-                                , apply adapterE [ uvar_ hsName ]-                                ]--             update u v = HsFieldUpdate (unqual_ u) (uvar_ v)--             serverOptsE = HsRecUpdate defaultOptionsE-                 [ HsFieldUpdate (grpcName "optNormalHandlers") $-                       HsList [ handlerE unaryHandlerC convertServerHandlerE endpointName hsName-                              | (endpointName, hsName, NonStreaming, NonStreaming, _) <- fieldsD-                              ]--                 , HsFieldUpdate (grpcName "optClientStreamHandlers") $-                       HsList [ handlerE clientStreamHandlerC convertServerReaderHandlerE endpointName hsName-                              | (endpointName, hsName, Streaming, NonStreaming, _) <- fieldsD-                              ]---                 , HsFieldUpdate (grpcName "optServerStreamHandlers") $-                       HsList [ handlerE serverStreamHandlerC convertServerWriterHandlerE endpointName hsName-                              | (endpointName, hsName, NonStreaming, Streaming, _) <- fieldsD-                              ]---                 , HsFieldUpdate (grpcName "optBiDiStreamHandlers") $-                       HsList [ handlerE biDiStreamHandlerC convertServerRWHandlerE endpointName hsName-                              | (endpointName, hsName, Streaming, Streaming, _) <- fieldsD-                              ]--                 , update "optServerHost" "serverHost"-                 , update "optServerPort" "serverPort"-                 , update "optUseCompression" "useCompression"-                 , update "optUserAgentPrefix" "userAgentPrefix"-                 , update "optUserAgentSuffix" "userAgentSuffix"-                 , update "optInitialMetadata" "initialMetadata"-                 , update "optSSLConfig" "sslConfig"-                 , update "optLogger" "logger"-                 , update "optMaxReceiveMessageLength" "serverMaxReceiveMessageLength"-                 , update "optMaxMetadataSize" "serverMaxMetadataSize"-                 ]--     let clientT = tyApp (HsTyCon (unqual_ serviceName)) [ clientRequestT, clientResultT ]--     let serviceClientTypeD =-             HsTypeSig defaultSrcLoc [ HsIdent clientFuncName ]-                       (HsQualType [] (HsTyFun grpcClientT (HsTyApp ioT clientT)))--     let serviceClientD = HsFunBind [ clientFuncD ]-            where-              clientFuncD = match_ (HsIdent clientFuncName)-                                   [ HsPVar (HsIdent "client") ]-                                   ( HsUnGuardedRhs clientRecE ) []--              clientRecE = foldl (\f -> HsInfixApp f apOp)-                                 (apply pureE [ uvar_ serviceName ])-                                 [ HsParen $ HsInfixApp clientRequestE' apOp (registerClientMethodE endpointName)-                                 | (endpointName, _, _, _, _) <- fieldsD-                                 ]--              clientRequestE' = apply pureE [ apply clientRequestE [ uvar_ "client" ] ]--              registerClientMethodE endpoint =-                apply clientRegisterMethodE [ uvar_ "client"-                                            , apply methodNameC [ str_ endpoint ]-                                            ]--     pure [ HsDataDecl defaultSrcLoc  [] (HsIdent serviceName)-                [ HsIdent "request", HsIdent "response" ]-                [ conDecl ] defaultServiceDeriving--          , serviceServerTypeD-          , serviceServerD--          , serviceClientTypeD-          , serviceClientD-          ]----------------------------------------------------------------------------------------- * Common Haskell expressions, constructors, and operators-----unaryHandlerC, clientStreamHandlerC, serverStreamHandlerC, biDiStreamHandlerC,-  methodNameC, defaultOptionsE, serverLoopE, convertServerHandlerE,-  convertServerReaderHandlerE, convertServerWriterHandlerE,-  convertServerRWHandlerE, clientRegisterMethodE, clientRequestE :: HsExp--unaryHandlerC               = HsVar (grpcName "UnaryHandler")-clientStreamHandlerC        = HsVar (grpcName "ClientStreamHandler")-serverStreamHandlerC        = HsVar (grpcName "ServerStreamHandler")-biDiStreamHandlerC          = HsVar (grpcName "BiDiStreamHandler")-methodNameC                 = HsVar (grpcName "MethodName")-defaultOptionsE             = HsVar (grpcName "defaultOptions")-serverLoopE                 = HsVar (grpcName "serverLoop")-convertServerHandlerE       = HsVar (grpcName "convertGeneratedServerHandler")-convertServerReaderHandlerE = HsVar (grpcName "convertGeneratedServerReaderHandler")-convertServerWriterHandlerE = HsVar (grpcName "convertGeneratedServerWriterHandler")-convertServerRWHandlerE     = HsVar (grpcName "convertGeneratedServerRWHandler")-clientRegisterMethodE       = HsVar (grpcName "clientRegisterMethod")-clientRequestE              = HsVar (grpcName "clientRequest")--biDiStreamingC, serverStreamingC, clientStreamingC, normalC, serviceOptionsC,-  ioActionT, serverRequestT, serverResponseT, clientRequestT, clientResultT,-  ioT, grpcClientT :: HsType-biDiStreamingC   = HsTyCon (Qual (Module "'HsGRPC") (HsIdent "BiDiStreaming"))-serverStreamingC = HsTyCon (Qual (Module "'HsGRPC") (HsIdent "ServerStreaming"))-clientStreamingC = HsTyCon (Qual (Module "'HsGRPC") (HsIdent "ClientStreaming"))-normalC          = HsTyCon (Qual (Module "'HsGRPC") (HsIdent "Normal"))-serviceOptionsC  = HsTyCon (Qual (Module "HsGRPC") (HsIdent "ServiceOptions"))-serverRequestT   = HsTyCon (grpcName "ServerRequest")-serverResponseT  = HsTyCon (grpcName "ServerResponse")-clientRequestT   = HsTyCon (grpcName "ClientRequest")-clientResultT    = HsTyCon (grpcName "ClientResult")-grpcClientT      = HsTyCon (grpcName "Client")-ioActionT        = tyApp ioT [ HsTyTuple [] ]-ioT              = HsTyCon (haskellName "IO")---- ** Expressions for protobuf-wire types--forceEmitE :: HsExp -> HsExp-forceEmitE = HsParen . HsApp forceEmitC--fieldNumberE :: FieldNumber -> HsExp-fieldNumberE = HsParen . HsApp fieldNumberC . intE . getFieldNumber--dpIdentE :: DotProtoIdentifier -> HsExp-dpIdentE (Single n)       = apply singleC [ str_ n ]-dpIdentE (Dots (Path (n NE.:| ns)))-  = apply dotsC [ apply pathC [ HsParen (HsInfixApp (str_ n) neConsOp (HsList (map str_ ns))) ] ]-dpIdentE (Qualified a b)  = apply qualifiedC [ dpIdentE a, dpIdentE b ]-dpIdentE Anonymous        = anonymousC--dpValueE :: DotProtoValue -> HsExp-dpValueE (Identifier nm) = apply identifierC [ dpIdentE nm ]-dpValueE (StringLit s)   = apply stringLitC  [ str_ s ]-dpValueE (IntLit i)      = apply intLitC     [ HsLit (HsInt (fromIntegral i)) ]-dpValueE (FloatLit f)    = apply floatLitC   [ HsLit (HsFrac (toRational f)) ]-dpValueE (BoolLit True)  = apply boolLitC    [ trueC ]-dpValueE (BoolLit False) = apply boolLitC    [ falseC ]--optionE :: DotProtoOption -> HsExp-optionE (DotProtoOption name value) =-  apply dotProtoOptionC [ dpIdentE name, dpValueE value ]---- | Translate a dot proto type to its Haskell AST type-dpTypeE :: DotProtoType -> HsExp-dpTypeE (Prim p)           = apply primC           [ dpPrimTypeE p ]-dpTypeE (Repeated p)       = apply repeatedC       [ dpPrimTypeE p ]-dpTypeE (NestedRepeated p) = apply nestedRepeatedC [ dpPrimTypeE p ]-dpTypeE (Map k v)          = apply mapC            [ dpPrimTypeE k, dpPrimTypeE v]----- | Translate a dot proto primitive type to a Haskell AST primitive type.-dpPrimTypeE :: DotProtoPrimType -> HsExp-dpPrimTypeE ty =-    let wrap = HsVar . protobufASTName in-    case ty of-        Named n  -> apply namedC [ dpIdentE n ]-        Int32    -> wrap "Int32"-        Int64    -> wrap "Int64"-        SInt32   -> wrap "SInt32"-        SInt64   -> wrap "SInt64"-        UInt32   -> wrap "UInt32"-        UInt64   -> wrap "UInt64"-        Fixed32  -> wrap "Fixed32"-        Fixed64  -> wrap "Fixed64"-        SFixed32 -> wrap "SFixed32"-        SFixed64 -> wrap "SFixed64"-        String   -> wrap "String"-        Bytes    -> wrap "Bytes"-        Bool     -> wrap "Bool"-        Float    -> wrap "Float"-        Double   -> wrap "Double"--data ImportCustomisation = ImportCustomisation-  { icStringType :: StringType-  , icUsesGrpc :: Bool-  }--defaultImports :: RecordStyle -> ImportCustomisation -> [HsImportDecl]-defaultImports recordStyle ImportCustomisation{ icUsesGrpc, icStringType = StringType stringModule stringType} =-    [ importDecl_ (m "Prelude")               & qualified haskellNS  & everything-    , importDecl_ (m "Proto3.Suite.Class")    & qualified protobufNS & everything-#ifdef DHALL-    , importDecl_ (m "Proto3.Suite.DhallPB")  & qualified (m hsDhallPB) & everything-#endif-    , importDecl_ (m "Proto3.Suite.DotProto") & qualified protobufASTNS & everything-    , importDecl_ (m "Proto3.Suite.JSONPB")   & qualified jsonpbNS   & everything-    , importDecl_ (m "Proto3.Suite.JSONPB")   & unqualified          & selecting  [s".=", s".:"]-    , importDecl_ (m "Proto3.Suite.Types")    & qualified protobufNS & everything-    , importDecl_ (m "Proto3.Wire")           & qualified protobufNS & everything-    , importDecl_ (m "Proto3.Wire.Decode")    & qualified protobufNS & selecting  [i"Parser", i"RawField"]-    , importDecl_ (m "Control.Applicative")   & qualified haskellNS  & everything-    , importDecl_ (m "Control.Applicative")   & unqualified          & selecting  [s"<*>", s"<|>", s"<$>"]-    , importDecl_ (m "Control.DeepSeq")       & qualified haskellNS  & everything-    , importDecl_ (m "Control.Monad")         & qualified haskellNS  & everything-    , importDecl_ (m "Data.ByteString")       & qualified haskellNS  & everything-    , importDecl_ (m "Data.Coerce")           & qualified haskellNS  & everything-    , importDecl_ (m "Data.Int")              & qualified haskellNS  & selecting  [i"Int16", i"Int32", i"Int64"]-    , importDecl_ (m "Data.List.NonEmpty")    & qualified haskellNS  & selecting  [HsIThingAll (HsIdent "NonEmpty")]-    , importDecl_ (m "Data.Map")              & qualified haskellNS  & selecting  [i"Map", i"mapKeysMonotonic"]-    , importDecl_ (m "Data.Proxy")            & qualified proxyNS    & everything-    , importDecl_ (m "Data.String")           & qualified haskellNS  & selecting  [i"fromString"]-    , importDecl_ (m stringModule)            & qualified haskellNS  & selecting  [i stringType]-    , importDecl_ (m "Data.Vector")           & qualified haskellNS  & selecting  [i"Vector"]-    , importDecl_ (m "Data.Word")             & qualified haskellNS  & selecting  [i"Word16", i"Word32", i"Word64"]-    , importDecl_ (m "GHC.Enum")              & qualified haskellNS  & everything-    , importDecl_ (m "GHC.Generics")          & qualified haskellNS  & everything-    , importDecl_ (m "Google.Protobuf.Wrappers.Polymorphic") & qualified protobufNS & selecting [HsIThingAll (HsIdent "Wrapped")]-    , importDecl_ (m "Unsafe.Coerce")         & qualified haskellNS  & everything-    ]-    <>-    (if not icUsesGrpc then [] else-    [ importDecl_ (m "Network.GRPC.HighLevel.Generated")           & alias grpcNS & everything-    , importDecl_ (m "Network.GRPC.HighLevel.Client")              & alias grpcNS & everything-    , importDecl_ (m "Network.GRPC.HighLevel.Server")              & alias grpcNS & hiding    [i"serverLoop"]-    , importDecl_ (m "Network.GRPC.HighLevel.Server.Unregistered") & alias grpcNS & selecting [i"serverLoop"]-    ])-    <>-    case recordStyle of-      RegularRecords -> []-      LargeRecords ->-        [ importDecl_ (m "Data.Record.Generic")              & qualified lrNS  & everything-        -- "large-records" stopped exporting "grnf"; we try-        -- to get it directly from "large-generics" if we can.-        ---        -- Ideally we would generate CPP conditionals so that-        -- the version check happens when the generated code-        -- is built, but as yet it is unclear how to do that.-        ---        -- As a result, we have to enable the version check-        -- based on the package version available when building-        -- compile-proto-file, and only if large record support-        -- is enabled in the library code.-#ifdef LARGE_RECORDS-#if MIN_VERSION_large_generics(0,2,1)-        , importDecl_ (m "Data.Record.Generic.NFData")       & qualified lrNS  & everything-#endif-#endif-        , importDecl_ (m "Data.Record.Generic.Rep")          & qualified lrNS  & everything-        , importDecl_ (m "Data.Record.Generic.Rep.Internal") & qualified lrNS  & everything-        , importDecl_ (m "Data.Record.Plugin.Runtime")       & qualified lrNS  & everything-        -- <https://hackage.haskell.org/package/large-records-0.4/changelog>-        -- says that as of large-records-0.4 the plugin does not generate-        -- imports, and that "code must now import Data.Record.Plugin to-        -- bring largeRecord into scope (necessary for ANN annotations)."-        -- We also seem to need to import some Prelude identifiers.-        ---        -- Ideally we would generate CPP conditionals so that-        -- the version check happens when the generated code-        -- is built, but as yet it is unclear how to do that.-        ---        -- As a result, we have to enable the version check-        -- based on the package version available when building-        -- compile-proto-file, and only if large record support-        -- is enabled in the library code.-#ifdef LARGE_RECORDS-#if MIN_VERSION_large_records(0,4,0)-        , importDecl_ (m "Data.Record.Plugin")               & unqualified     & selecting [i"largeRecord"]-        , importDecl_ (m "Prelude")                          & unqualified     & selecting [i"Eq", i"Int", i"Ord", i"Show", i"error"]-#endif-#endif-        ]-  where-    m = Module-    i = HsIVar . HsIdent-    s = HsIVar . HsSymbol--    grpcNS                    = m "HsGRPC"-    jsonpbNS                  = m "HsJSONPB"-    lrNS                      = m "LR"-    protobufNS                = m "HsProtobuf"-    protobufASTNS             = m "HsProtobufAST"-    proxyNS                   = m "Proxy"--    -- staged constructors for importDecl-    qualified :: Module -> (Bool -> Maybe Module -> a)  -> a-    qualified m' f = f True (Just m')--    unqualified :: (Bool -> Maybe Module -> a) -> a-    unqualified f = f False Nothing--    -- import unqualified AND also under a namespace-    alias :: Module -> (Bool -> Maybe Module -> a) -> a-    alias m' f = f False (Just m')--    selecting :: [HsImportSpec] -> (Maybe (Bool, [HsImportSpec]) -> a) -> a-    selecting is f = f (Just (False, is))--    hiding :: [HsImportSpec] -> (Maybe (Bool, [HsImportSpec]) -> a) -> a-    hiding is f =  f (Just (True, is))--    everything :: (Maybe (Bool, [HsImportSpec]) -> a) -> a-    everything f = f Nothing--defaultMessageDeriving :: [HsQName]-defaultMessageDeriving = map haskellName [ "Show", "Eq", "Ord", "Generic" ]--defaultEnumDeriving :: [HsQName]-defaultEnumDeriving = map haskellName [ "Show", "Eq", "Generic", "NFData" ]--defaultServiceDeriving :: [HsQName]-defaultServiceDeriving = map haskellName [ "Generic" ]+{-# LANGUAGE ImplicitParams            #-}+{-# LANGUAGE LambdaCase                #-}+{-# LANGUAGE MultiWayIf                #-}+{-# LANGUAGE NamedFieldPuns            #-}+{-# LANGUAGE OverloadedStrings         #-}+{-# LANGUAGE QuasiQuotes               #-}+{-# LANGUAGE RecordWildCards           #-}+{-# LANGUAGE ScopedTypeVariables       #-}+{-# LANGUAGE StandaloneDeriving        #-}+{-# LANGUAGE TupleSections             #-}+{-# LANGUAGE TypeApplications          #-}+{-# LANGUAGE TypeOperators             #-}+{-# LANGUAGE ViewPatterns              #-}++{-| This module provides functions to generate Haskell declarations for protobuf+    messages+-}++module Proto3.Suite.DotProto.Generate+  ( CompileError(..)+  , StringType(..)+  , parseStringType+  , TypeContext+  , CompileArgs(..)+  , compileDotProtoFile+  , compileDotProtoFileOrDie+  , renameProtoFile+  , hsModuleForDotProto+  , renderHsModuleForDotProto+  , readDotProtoWithContext+  ) where++import           Control.Applicative+import           Control.Lens                   ((&), ix, over, has, filtered)+import           Control.Monad                  (when)+import           Control.Monad.Except           (MonadError(..), runExceptT)+import           Control.Monad.IO.Class         (MonadIO(..))+import           Control.Monad.Writer           (WriterT, runWriterT, tell)+import           Data.Char+import           Data.Coerce+import           Data.Either                    (partitionEithers)+import           Data.Foldable                  (fold)+import           Data.Function                  (on)+import           Data.Functor                   ((<&>))+import           Data.List                      (find, intercalate, nub, sort, sortBy, stripPrefix)+import qualified Data.List.NonEmpty             as NE+import           Data.List.Split                (splitOn)+import           Data.List.NonEmpty             (NonEmpty (..))+import qualified Data.Map                       as M+import           Data.Maybe+import           Data.Monoid+import           Data.Ord                       (comparing)+import qualified Data.Set                       as S+import           Data.String                    (fromString)+import           GHC.Hs                         (HsSigType(..))+import           GHC.Parser.Annotation          (noLocA)+import           GHC.Types.Name.Occurrence      (dataName, tcName, varName)+import qualified Data.Text                      as T+import qualified GHC.Data.FastString            as GHC+import qualified GHC.Data.StringBuffer          as GHC+import qualified GHC.Hs                         as GHC+import qualified GHC.Types.Name                 as GHC+import qualified GHC.Types.Name.Reader          as GHC+import qualified GHC.Types.SrcLoc               as GHC+import qualified GHC.Utils.Outputable           as GHC+import qualified NeatInterpolation              as Neat+import           Prelude                        hiding (FilePath)+import           Proto3.Suite.DotProto+import           Proto3.Suite.DotProto.AST.Lens+import qualified Proto3.Suite.DotProto.Generate.Record as Record+import           Proto3.Suite.DotProto.Generate.Syntax+import           Proto3.Suite.Haskell.Parser    (Logger, parseModule, renderSDoc)+import           Proto3.Suite.DotProto.Internal+import           Proto3.Wire.Types              (FieldNumber (..))+import Text.Parsec (Parsec, alphaNum, eof, parse, satisfy, try)+import qualified Text.Parsec as Parsec+import qualified Turtle hiding (encodeString)+import qualified Turtle.Compat as Turtle (encodeString)+import           Turtle                         (FilePath, (</>), (<.>))++#if !MIN_VERSION_ghc_lib_parser(9,6,0)+import qualified GHC.Unit.Module.Name           as GHC+import qualified GHC.Types.Basic                as GHC (PromotionFlag(..))+#endif+++-- $setup+-- >>> :set -XTypeApplications++--------------------------------------------------------------------------------++--+-- * Public interface+--+data CompileArgs = CompileArgs+  { includeDir         :: [FilePath]+  , extraInstanceFiles :: [FilePath]+  , inputProto         :: FilePath+  , outputDir          :: FilePath+  , stringType         :: StringType+  , typeLevelFormat    :: Bool+  }++data StringType = StringType String String+  -- ^ Qualified module name, then unqualified type name.++parseStringType :: String -> Either String StringType+parseStringType str = case splitOn "." str of+  xs@(_ : _ : _) -> Right $ StringType (intercalate "." $ init xs) (last xs)+  _ -> Left "must be in the form Module.Type"++-- | Generate a Haskell module corresponding to a @.proto@ file+compileDotProtoFile :: Logger -> CompileArgs -> IO (Either CompileError ())+compileDotProtoFile logger CompileArgs{..} = runExceptT $ do+  (dotProto, importTypeContext) <- readDotProtoWithContext includeDir inputProto+  modulePathPieces <- traverse renameProtoFile (toModuleComponents dotProto)++  let relativePath = foldr combine mempty (map fromString $ NE.toList modulePathPieces) <.> "hs"+      combine p1 p2 | p2 == mempty = p1+      combine p1 p2 = p1 </> p2+  let modulePath = outputDir </> relativePath++  Turtle.mktree (Turtle.directory modulePath)++  extraInstances <- foldMapM (getExtraInstances logger) extraInstanceFiles+  haskellModule <-+    let ?stringType = stringType+        ?typeLevelFormat = typeLevelFormat+    in renderHsModuleForDotProto extraInstances dotProto importTypeContext++  liftIO (writeFile (Turtle.encodeString modulePath) haskellModule)+  where+    toModuleComponents :: DotProto -> NonEmpty String+    toModuleComponents = components . metaModulePath . protoMeta++-- | Same as 'compileDotProtoFile', except terminates the program with an error+-- message on failure.+compileDotProtoFileOrDie :: Logger -> CompileArgs -> IO ()+compileDotProtoFileOrDie logger args = compileDotProtoFile logger args >>= \case+  Left e -> do+    -- TODO: pretty print the error messages+    let errText          = Turtle.format Turtle.w  e+    let dotProtoPathText = Turtle.format Turtle.fp (inputProto args)+    dieLines [Neat.text|+      Error: failed to compile "${dotProtoPathText}":++      ${errText}+    |]+  _ -> pure ()++-- | Renaming protobuf file names to valid Haskell module names.+--+-- By convention, protobuf filenames are snake case. 'rnProtoFile' renames+-- snake-cased protobuf filenames by:+--+-- * Replacing occurrences of one or more underscores followed by an+-- alphabetical character with one less underscore.+--+-- * Capitalizing the first character following the string of underscores.+--+-- ==== __Examples__+--+-- >>> renameProtoFile @(Either CompileError) "abc_xyz"+-- Right "AbcXyz"+--+-- >>> renameProtoFile @(Either CompileError) "abc_1bc"+-- Left (InvalidModuleName "abc_1bc")+--+-- >>> renameProtoFile @(Either CompileError) "_"+-- Left (InvalidModuleName "_")+renameProtoFile :: MonadError CompileError m => String -> m String+renameProtoFile filename =+  case parse parser "" filename of+    Left {} -> throwError (InvalidModuleName filename)+    Right (nm, ps, sn) -> pure (toUpperFirst nm ++ rename ps ++ sn)+  where+    rename :: [(String, String)] -> String+    rename = foldMap $ \(us, nm) ->+      drop 1 us ++ toUpperFirst nm++    parser :: Parsec String () (String, [(String, String)], String)+    parser = do+      nm <- pName+      ps <- Parsec.many (try pNamePart)+      sn <- Parsec.many (satisfy (== '_'))+      pure (nm, ps, sn) <* eof++    pNamePart :: Parsec String () (String, String)+    pNamePart = liftA2 (,) (Parsec.many1 (satisfy (== '_'))) pName++    pName :: Parsec String () String+    pName = liftA2 (:) (satisfy isAlpha) (Parsec.many alphaNum)++-- | Compile a 'DotProto' AST into a 'String' representing the Haskell+--   source of a module implementing types and instances for the .proto+--   messages and enums.+renderHsModuleForDotProto ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  , (?typeLevelFormat :: Bool)+  ) =>+  ([HsImportDecl],[HsDecl]) ->+  DotProto ->+  TypeContext ->+  m String+renderHsModuleForDotProto extraInstanceFiles dotProto importCtxt = do+    haskellModule <- hsModuleForDotProto extraInstanceFiles dotProto importCtxt++    let languagePragmas = textUnlines $ map (\extn -> "{-# LANGUAGE " <> extn <> " #-}") $ sort extensions+        ghcOptionPragmas = textUnlines $ map (\opt -> "{-# OPTIONS_GHC " <> opt <> " #-}") $ sort options++        extensions :: [T.Text]+        extensions = nub $+          [ "DataKinds"+          , "DeriveAnyClass"+          , "DeriveGeneric"+          , "GADTs"+          , "NamedFieldPuns"+          , "NegativeLiterals"+          , "OverloadedStrings"+          , "TypeApplications"+          , "TypeOperators"+          ] +++          (if ?typeLevelFormat then [ "TypeFamilies", "UndecidableInstances" ] else [])+        options :: [T.Text]+        options = [ "-fno-warn-unused-imports"+                  , "-fno-warn-name-shadowing"+                  , "-fno-warn-unused-matches"+                  , "-fno-warn-missing-export-lists"+                  ]++        moduleContent :: T.Text+        moduleContent = T.pack $ renderSDoc $ GHC.ppr haskellModule++        textUnlines :: [T.Text] -> T.Text+        textUnlines = T.intercalate "\n"++    pure $ T.unpack $ [Neat.text|+      $languagePragmas+      $ghcOptionPragmas++      -- | Generated by Haskell protocol buffer compiler. DO NOT EDIT!+      $moduleContent+    |]++-- | Compile a Haskell module AST given a 'DotProto' package AST.+-- Instances given in @eis@ override those otherwise generated.+hsModuleForDotProto ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  , (?typeLevelFormat :: Bool)+  ) =>+  -- | Extra user-define instances that override default generated instances+  ([HsImportDecl], [HsDecl]) ->+  -- |+  DotProto ->+  -- |+  TypeContext ->+  m (GHC.HsModule+#if MIN_VERSION_ghc_lib_parser(9,6,0)+                  GHC.GhcPs+#endif+                           )+hsModuleForDotProto+    (extraImports, extraInstances)+    dotProto@DotProto{ protoMeta = DotProtoMeta { metaModulePath = modulePath }+                     , protoPackage+                     , protoDefinitions+                     }+    importTypeContext+  = do+       moduleName <- modulePathModName modulePath++       typeContextImports <- ctxtImports importTypeContext++       let icUsesGrpc = has (traverse._DotProtoService) protoDefinitions++       let importDeclarations = concat+              [ defaultImports icUsesGrpc+              , extraImports+              , typeContextImports ]++       typeContext <- dotProtoTypeContext dotProto++       let toDotProtoDeclaration =+             dotProtoDefinitionD protoPackage (typeContext <> importTypeContext)++       let extraInstances' = instancesForModule moduleName extraInstances++       decls <- replaceHsInstDecls extraInstances' <$>+                foldMapM toDotProtoDeclaration protoDefinitions++       pure (module_ moduleName Nothing importDeclarations decls)++getExtraInstances+    :: (MonadIO m, MonadError CompileError m)+    => Logger -> FilePath -> m ([HsImportDecl], [HsDecl])+getExtraInstances logger (Turtle.encodeString -> extraInstanceFile) = do+  contents <- liftIO $ GHC.hGetStringBuffer extraInstanceFile+  let location = GHC.mkRealSrcLoc (GHC.mkFastString extraInstanceFile) 1 1+  maybeModule <- liftIO $ parseModule logger location contents+  case maybeModule of+    Nothing ->+      internalError (T.unpack "Error: Failed to parse instance file")+    Just (GHC.L _ m) -> do+      let isInstDecl (GHC.L _ GHC.InstD{}) = True+          isInstDecl _                     = False+      pure (GHC.hsmodImports m, filter isInstDecl (GHC.hsmodDecls m))++-- | This very specific function will only work for the qualification on the very first type+-- in the object of an instance declaration. Those are the only sort of instance declarations+-- generated within this code, so it suffices.+instancesForModule :: Module -> [HsDecl] -> [HsDecl]+instancesForModule m = mapMaybe go+  where+    go ( GHC.L instX+         ( GHC.InstD clsInstX+           ( GHC.ClsInstD clsInstDeclX clsInstDecl@GHC.ClsInstDecl+             { cid_poly_ty = GHC.L tyX (HsSig ext bndrs ty) } ) ) )+      | Just (tc, GHC.L _ (GHC.HsTyVar _ GHC.NotPromoted (GHC.L _ (GHC.Qual tm i))) : ts) <-+          splitTyConApp ty, m == tm =+        Just ( GHC.L instX+               ( GHC.InstD clsInstX+                 ( GHC.ClsInstD clsInstDeclX clsInstDecl+                   { GHC.cid_poly_ty = GHC.L tyX (HsSig ext bndrs (tyConApply tc (typeNamed_ (noLocA (GHC.Unqual i)) : ts)))+                   } ) ) )+    go _ = Nothing++-- | For each thing in @base@ replaces it if it finds a matching @override@.+--+-- Current Limitations: The type of the type class instance and the corresponding+-- override must both be monomorphic; otherwise they will not match each other.+-- Furthermore, comparison is based on unqualified names, so please ensure that+-- those unqualified names are unambiguous or false matches may occur.+replaceHsInstDecls :: [HsDecl] -> [HsDecl] -> [HsDecl]+replaceHsInstDecls overrides base = concatMap (mbReplace) base+  where+    -- instances defined separately from data type definition:+    mbReplace :: HsDecl -> [HsDecl]+    mbReplace hid@(typeOfInstDecl -> Just classSig) =+        [fromMaybe hid (search classSig)]++    -- instances listed in "deriving" clause of data type or newtype definition:+    mbReplace ( GHC.L tyClDX+                ( GHC.TyClD dataDeclX+                  ( dataDecl@GHC.DataDecl+                    { tcdLName = tyn+                    , tcdDataDefn = dd@GHC.HsDataDefn+                      { dd_derivs = clauses+                      }+                    } ) ) ) =+        let ty = typeNamed_ tyn+            (uncustomized, customized) = partitionEithers (concatMap (clause ty) clauses)+        in ( GHC.L tyClDX+             ( GHC.TyClD dataDeclX+               ( dataDecl { GHC.tcdDataDefn = dd+                            { GHC.dd_derivs = uncustomized+                            } } ) ) )+           : customized++    -- irrelevant declarations remain unchanged:+    mbReplace hid = [hid]++    clause :: HsType -> HsDerivingClause -> [Either HsDerivingClause HsDecl]+    clause ty (splitDerivingClause -> (strategy, classSigs)) =+      let (uncustomized, customized) = partitionEithers (map (deriv ty) classSigs)+      in maybe id ((:) . Left) (derivingClause_ strategy uncustomized) (map Right customized)++    deriv ::+      HsType ->+      (HsOuterSigTyVarBndrs, HsType) ->+      Either (HsOuterSigTyVarBndrs, HsType) HsDecl+    deriv ty classSig@(bindings, classType) =+        maybe (Left classSig) Right (search (bindings, tyApp classType ty))++    -- | NOTE: 'getSig' must return 'Just' for *both* the goal and the override+    -- in order for there to be a match: 'Nothing' for both means no match.+    search :: (HsOuterSigTyVarBndrs, HsType) -> Maybe HsDecl+    search y = do+      desired <- getSig y+      find (\x -> Just desired == (getSig =<< typeOfInstDecl x)) overrides++    getSig :: (HsOuterSigTyVarBndrs, HsType) -> Maybe SimpleTypeName+    getSig (GHC.HsOuterImplicit _, x) = simpleType x+    getSig _ = empty++-- | A simplified representation of certain Haskell types.+data SimpleTypeName = SimpleTypeName GHC.OccName [SimpleTypeName]+  deriving Eq++-- | Types are difficult to compare in general, but for many+-- of the simpler types we can find a corresponding simple+-- description that is practical for us to compare.+--+-- WARNING: As legacy behavior we remove all qualifiers, rather than+-- normalizing them in some way that considers equivalence of module+-- qualifiers.  This behavior could potentially cause incorrect+-- results if two modules provide the same type name.+simpleType :: HsType -> Maybe SimpleTypeName+simpleType (GHC.L _ (GHC.HsParTy _ x)) = simpleType x+simpleType x = do+    (tc, as) <- splitTyConApp x+    sas <- traverse simpleType as+    pure (SimpleTypeName (unQual tc) sas)+  where+    unQual :: HsName -> GHC.OccName+    unQual (GHC.L _ (GHC.Unqual n)) = n+    unQual (GHC.L _ (GHC.Qual _ n)) = n+    unQual (GHC.L _ (GHC.Orig _ n)) = n+    unQual (GHC.L _ (GHC.Exact n)) = GHC.nameOccName n++-- | If both types are sufficiently simple,+-- then return the result of an equality test.+--+-- WARNING: As legacy behavior we remove all qualifiers, rather than+-- normalizing them in some way that considers equivalence of module+-- qualifiers.  This behavior could potentially cause incorrect+-- results if two modules provide the same type name.+simpleTypeEq :: HsType -> HsType -> Maybe Bool+simpleTypeEq a b = (==) <$> simpleType a <*> simpleType b++-- | Parses the file at the given path and produces an AST along with a+-- 'TypeContext' representing all types from imported @.proto@ files, using the+-- first parameter as a list of paths to search for imported files. Terminates+-- with exit code 1 when an included file cannot be found in the search path.+readDotProtoWithContext+    :: (MonadError CompileError m, MonadIO m)+    => [FilePath]+    -> FilePath+    -> m (DotProto, TypeContext)+readDotProtoWithContext [] toplevelProto = do+  -- If we're not given a search path, default to using the current working+  -- directory, as `protoc` does+  cwd <- Turtle.pwd+  readDotProtoWithContext [cwd] toplevelProto++readDotProtoWithContext searchPaths toplevelProto = do+  dp <- importProto searchPaths toplevelProto toplevelProto+  let importIt = readImportTypeContext searchPaths toplevelProto (S.singleton toplevelProto)+  tc <- foldMapM importIt (protoImports dp)+  pure (dp, tc)++-- | Build the type context for an import, resolving transitive imports.+readImportTypeContext+    :: (MonadError CompileError m, MonadIO m)+    => [FilePath]+    -> FilePath+    -> S.Set FilePath+    -> DotProtoImport+    -> m TypeContext+readImportTypeContext searchPaths toplevelFP alreadyRead (DotProtoImport _ path)+  | path `S.member` alreadyRead = throwError (CircularImport path)+  | otherwise = do+      import_ <- importProto searchPaths toplevelFP path+      let importPkgSpec = protoPackage import_++      let fixImportTyInfo tyInfo =+             tyInfo { dotProtoTypeInfoPackage    = importPkgSpec+                    , dotProtoTypeInfoModulePath = metaModulePath . protoMeta $ import_+                    }+      importTypeContext <- fmap fixImportTyInfo <$> dotProtoTypeContext import_++      let prefixWithPackageName =+            case importPkgSpec of+              DotProtoPackageSpec packageName -> concatDotProtoIdentifier packageName+              DotProtoNoPackage -> pure++      qualifiedTypeContext <- mapKeysM prefixWithPackageName importTypeContext++      let isPublic (DotProtoImport q _) = q == DotProtoImportPublic+      transitiveImportsTC <-+        foldMapOfM (traverse . filtered isPublic)+                   (readImportTypeContext searchPaths toplevelFP (S.insert path alreadyRead))+                   (protoImports import_)++      pure $ importTypeContext <> qualifiedTypeContext <> transitiveImportsTC++-- | Given a type context, generates the Haskell import statements necessary to+--   import all the required types.  Excludes module "Google.Protobuf.Wrappers"+--   because the generated code does not actually make use of wrapper types+--   as such; instead it uses @Maybe a@, where @a@ is the wrapped type.+ctxtImports :: MonadError CompileError m => TypeContext -> m [HsImportDecl]+ctxtImports =+    fmap (map mkImport . nub . filter (GHC.mkModuleName "Google.Protobuf.Wrappers" /=))+    . traverse (modulePathModName . dotProtoTypeInfoModulePath)+    . M.elems+  where+    mkImport modName = importDecl_ modName True Nothing Nothing++--------------------------------------------------------------------------------+--+-- * Helper functions for Haskell code generation+--++-- ** Names++-- | Generate the Haskell type name for a 'DotProtoTypeInfo' for a message /+--   enumeration being compiled. NB: We ignore the 'dotProtoTypeInfoPackage'+--   field of the 'DotProtoTypeInfo' parameter, instead demanding that we have+--   been provided with a valid module path in its 'dotProtoTypeInfoModulePath'+--   field. The latter describes the name of the Haskell module being generated.+msgTypeFromDpTypeInfo :: MonadError CompileError m+                      => TypeContext -> DotProtoTypeInfo -> DotProtoIdentifier -> m HsType+msgTypeFromDpTypeInfo ctxt DotProtoTypeInfo{..} ident = do+    modName   <- modulePathModName dotProtoTypeInfoModulePath+    identName <- qualifiedMessageTypeName ctxt dotProtoTypeInfoParent ident+    pure $ typeNamed_ $ qual_ modName tcName identName++modulePathModName :: MonadError CompileError m => Path -> m Module+modulePathModName (Path comps) =+  GHC.mkModuleName . intercalate "." <$> traverse typeLikeName (NE.toList comps)++_pkgIdentModName :: MonadError CompileError m => DotProtoIdentifier -> m Module+_pkgIdentModName (Single s)  = GHC.mkModuleName <$> typeLikeName s+_pkgIdentModName (Dots path) = modulePathModName path+_pkgIdentModName x           = throwError (InvalidPackageName x)+++-- ** Dhall++#ifdef DHALL+hsDhallPB :: String+hsDhallPB = "HsDhallPb"++dhallPBName :: GHC.NameSpace -> String -> HsQName+dhallPBName = qual_ (GHC.mkModuleName hsDhallPB)++-- *** Generate Dhall Interpret and Inject generic instances++fromDhall, toDhall :: String+(fromDhall, toDhall) =+#if MIN_VERSION_dhall(1,27,0)+  ("FromDhall", "ToDhall")+#else+  ("Interpret", "Inject")+#endif++dhallInterpretInstDecl :: String -> HsDecl+dhallInterpretInstDecl typeName =+  instDecl_ (dhallPBName tcName fromDhall)+            [ type_ typeName ]+            [ ]++dhallInjectInstDecl :: String -> HsDecl+dhallInjectInstDecl typeName =+  instDecl_ (dhallPBName tcName toDhall)+            [ type_ typeName ]+            [ ]+#endif++-- ** Helpers to wrap/unwrap types for protobuf (de-)serialization++data FieldContext = WithinMessage | WithinOneOf+  deriving (Eq, Show)++coerceE :: Bool -> Bool -> HsType -> HsType -> Maybe HsExp+coerceE _ _ from to | Just True <- simpleTypeEq from to = Nothing+coerceE overTyCon unsafe from to =+    Just $ applyAt coerceF [from, to]+  where+    coerceF | unsafe = var_ (name "unsafeCoerce")+            | otherwise  = var_ (name "coerce")+    name | overTyCon = protobufName varName . (<> "Over")+         | otherwise = haskellName varName++wrapFunE ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  Bool ->+  FieldContext ->+  TypeContext ->+  [DotProtoOption] ->+  DotProtoType ->+  m (Maybe HsExp)+wrapFunE overTyCon fc ctxt opts dpt =+  coerceE overTyCon (isMap dpt)+    <$> dptToHsType fc ctxt dpt+    <*> dptToHsTypeWrapped fc opts ctxt dpt++wrapE ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  FieldContext ->+  TypeContext ->+  [DotProtoOption] ->+  DotProtoType ->+  HsExp ->+  m HsExp+wrapE fc ctxt opts dpt e =+  maybeModify e <$> wrapFunE False fc ctxt opts dpt++unwrapFunE ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  Bool ->+  FieldContext ->+  TypeContext ->+  [DotProtoOption] ->+  DotProtoType ->+  m (Maybe HsExp)+unwrapFunE overTyCon fc ctxt opts dpt =+  coerceE overTyCon (isMap dpt)+    <$> dptToHsTypeWrapped fc opts ctxt dpt+    <*> dptToHsType fc ctxt dpt++unwrapE ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  FieldContext ->+  TypeContext ->+  [DotProtoOption] ->+  DotProtoType ->+  HsExp ->+  m HsExp+unwrapE fc ctxt opts dpt e = do+  maybeModify e <$> unwrapFunE True fc ctxt opts dpt++--------------------------------------------------------------------------------+--+-- * Functions to convert 'DotProtoType' into Haskell types+--++-- | Convert a dot proto type to a Haskell type+dptToHsType ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  FieldContext ->+  TypeContext ->+  DotProtoType ->+  m HsType+dptToHsType fc = foldDPT (dptToHsContType fc) dpptToHsType++-- | Convert a dot proto type to a wrapped Haskell type+dptToHsTypeWrapped ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  FieldContext ->+  [DotProtoOption] ->+  TypeContext ->+  DotProtoType ->+  m HsType+dptToHsTypeWrapped fc opts =+  foldDPT+    -- The wrapper for the collection type replaces the native haskell+    -- collection type, so try that first.+    (\ctxt ty -> maybe (dptToHsContType fc ctxt ty) id (dptToHsWrappedContType fc ctxt opts ty))+    -- Always wrap the primitive type.+    dpptToHsTypeWrapped++-- | Like 'dptToHsTypeWrapped' but without use of+-- 'dptToHsContType' or 'dptToHsWrappedContType'.+dpptToHsTypeWrapped ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  TypeContext ->+  DotProtoPrimType ->+  m HsType+dpptToHsTypeWrapped ctxt | StringType _ stringType <- ?stringType = \case+  Int32 ->+    pure $ primType_ "Int32"+  Int64 ->+    pure $ primType_ "Int64"+  SInt32 ->+    pure $ protobufSignedType_ $ primType_ "Int32"+  SInt64 ->+    pure $ protobufSignedType_ $ primType_ "Int64"+  UInt32 ->+    pure $ primType_ "Word32"+  UInt64 ->+    pure $ primType_ "Word64"+  Fixed32 ->+    pure $ protobufFixedType_ $ primType_ "Word32"+  Fixed64 ->+    pure $ protobufFixedType_ $ primType_ "Word64"+  SFixed32 ->+    pure $ protobufSignedType_ $ protobufFixedType_ $ primType_ "Int32"+  SFixed64 ->+    pure $ protobufSignedType_ $ protobufFixedType_ $ primType_ "Int64"+  String ->+    pure $ protobufStringType_ stringType+  Bytes  ->+    pure $ protobufBytesType_ "ByteString"+  Bool ->+    pure $ primType_ "Bool"+  Float ->+    pure $ primType_ "Float"+  Double ->+    pure $ primType_ "Double"+  Named (Dots (Path ("google" :| ["protobuf", x])))+    | x == "Int32Value" ->+        pure $ protobufWrappedType_ $ primType_ "Int32"+    | x == "Int64Value" ->+        pure $ protobufWrappedType_ $ primType_ "Int64"+    | x == "UInt32Value" ->+        pure $ protobufWrappedType_ $ primType_ "Word32"+    | x == "UInt64Value" ->+        pure $ protobufWrappedType_ $ primType_ "Word64"+    | x == "StringValue" ->+        pure $ protobufWrappedType_ $ protobufStringType_ stringType+    | x == "BytesValue" ->+        pure $ protobufWrappedType_ $ protobufBytesType_ "ByteString"+    | x == "BoolValue" ->+        pure $ protobufWrappedType_ $ primType_ "Bool"+    | x == "FloatValue" ->+        pure $ protobufWrappedType_ $ primType_ "Float"+    | x == "DoubleValue" ->+        pure $ protobufWrappedType_ $ primType_ "Double"+  Named msgName ->+    case M.lookup msgName ctxt of+      Just ty@(DotProtoTypeInfo { dotProtoTypeInfoKind = DotProtoKindEnum }) ->+        tyApp (protobufType_ "Enumerated") <$> msgTypeFromDpTypeInfo ctxt ty msgName+      Just ty -> msgTypeFromDpTypeInfo ctxt ty msgName+      Nothing -> noSuchTypeError msgName++foldDPT :: MonadError CompileError m+        => (TypeContext -> DotProtoType -> HsType -> HsType)+        -> (TypeContext -> DotProtoPrimType -> m HsType)+        -> TypeContext+        -> DotProtoType+        -> m HsType+foldDPT dptToHsCont foldPrim ctxt dpt =+  let+      prim = foldPrim ctxt+      go = foldDPT dptToHsCont foldPrim ctxt+      cont = dptToHsCont ctxt dpt+  in+    case dpt of+      Prim pType           -> cont <$> prim pType+      Optional pType       -> cont <$> prim pType+      Repeated pType       -> cont <$> prim pType+      NestedRepeated pType -> cont <$> prim pType+      Map k v  | validMapKey k -> tyApp . cont <$> prim k <*> go (Prim v) -- need to 'Nest' message types+               | otherwise -> throwError $ InvalidMapKeyType (show $ pPrint k)++-- | Translate DotProtoType constructors to wrapped Haskell container types+-- (for Message serde instances).+--+-- When the given 'FieldContext' is 'WithinOneOf' we do not wrap submessages+-- in "Maybe" because the entire oneof is already wrapped in a "Maybe".+dptToHsWrappedContType :: FieldContext -> TypeContext -> [DotProtoOption] -> DotProtoType -> Maybe (HsType -> HsType)+dptToHsWrappedContType fc ctxt opts = \case+  Prim (Named tyName)+    | WithinMessage <- fc, isMessage ctxt tyName+                            -> Just $ tyApp (protobufType_ "Nested")+  Optional (Named tyName)+    | isMessage ctxt tyName -> Just $ tyApp (protobufType_ "Nested")+  Optional _                -> Just $ tyApp maybeT . tyApp forceEmitT+  Repeated (Named tyName)+    | isMessage ctxt tyName -> Just $ tyApp (protobufType_ "NestedVec")+  Repeated ty+    | isUnpacked opts       -> Just $ tyApp (protobufType_ "UnpackedVec")+    | isPacked opts         -> Just $ tyApp (protobufType_ "PackedVec")+    | isPackable ctxt ty    -> Just $ tyApp (protobufType_ "PackedVec")+    | otherwise             -> Just $ tyApp (protobufType_ "UnpackedVec")+  _ -> Nothing++-- | Translate DotProtoType to Haskell container types.+--+-- When the given 'FieldContext' is 'WithinOneOf' we do not wrap submessages+-- in "Maybe" because the entire oneof is already wrapped in a "Maybe".+dptToHsContType :: FieldContext -> TypeContext -> DotProtoType -> HsType -> HsType+dptToHsContType fc ctxt = \case+  Prim (Named tyName) | WithinMessage <- fc, isMessage ctxt tyName+                     -> tyApp $ primType_ "Maybe"+  Optional _         -> tyApp $ primType_ "Maybe"+  Repeated _         -> tyApp $ primType_ "Vector"+  NestedRepeated _   -> tyApp $ primType_ "Vector"+  Map _ _            -> tyApp $ primType_ "Map"+  _                  -> id++-- | Convert a dot proto prim type to an unwrapped Haskell type+dpptToHsType ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  TypeContext ->+  DotProtoPrimType ->+  m HsType+dpptToHsType ctxt | StringType _ stringType <- ?stringType = \case+  Int32    -> pure $ primType_ "Int32"+  Int64    -> pure $ primType_ "Int64"+  SInt32   -> pure $ primType_ "Int32"+  SInt64   -> pure $ primType_ "Int64"+  UInt32   -> pure $ primType_ "Word32"+  UInt64   -> pure $ primType_ "Word64"+  Fixed32  -> pure $ primType_ "Word32"+  Fixed64  -> pure $ primType_ "Word64"+  SFixed32 -> pure $ primType_ "Int32"+  SFixed64 -> pure $ primType_ "Int64"+  String   -> pure $ primType_ stringType+  Bytes    -> pure $ primType_ "ByteString"+  Bool     -> pure $ primType_ "Bool"+  Float    -> pure $ primType_ "Float"+  Double   -> pure $ primType_ "Double"+  Named (Dots (Path ("google" :| ["protobuf", x])))+    | x == "Int32Value" -> pure $ primType_ "Int32"+    | x == "Int64Value" -> pure $ primType_ "Int64"+    | x == "UInt32Value" -> pure $ primType_ "Word32"+    | x == "UInt64Value" -> pure $ primType_ "Word64"+    | x == "StringValue" -> pure $ primType_ stringType+    | x == "BytesValue" -> pure $ primType_ "ByteString"+    | x == "BoolValue" -> pure $ primType_ "Bool"+    | x == "FloatValue" -> pure $ primType_ "Float"+    | x == "DoubleValue" -> pure $ primType_ "Double"+  Named msgName ->+    case M.lookup msgName ctxt of+      Just ty@(DotProtoTypeInfo { dotProtoTypeInfoKind = DotProtoKindEnum }) ->+        tyApp (protobufType_ "Enumerated") <$> msgTypeFromDpTypeInfo ctxt ty msgName+      Just ty -> msgTypeFromDpTypeInfo ctxt ty msgName+      Nothing -> noSuchTypeError msgName++validMapKey :: DotProtoPrimType -> Bool+validMapKey = (`elem` [ Int32, Int64, SInt32, SInt64, UInt32, UInt64+                      , Fixed32, Fixed64, SFixed32, SFixed64+                      , String, Bool])++-- | Convert a dot proto type to a Haskell type of kind `Proto3.Suite.Form.Cardinality`.+-- It is ASSUMED that the field with this type is NOT part of a @oneof@.+dptToFormCardinality ::+  MonadError CompileError m => [DotProtoOption] -> TypeContext -> DotProtoType -> m HsType+dptToFormCardinality opts ctxt = \case+  Prim (Named tyName)+    | isMessage ctxt tyName -> pure formOptionalT+  Prim _                    -> pure formImplicitT+  Optional _                -> pure formOptionalT+  Repeated (Named tyName)+    | isMessage ctxt tyName -> pure unpacked+  Repeated pType+    | isUnpacked opts       -> pure unpacked+    | isPacked opts         -> pure packed+    | isPackable ctxt pType -> pure packed+    | otherwise             -> pure unpacked+  NestedRepeated pType      -> internalError $ "unexpected NestedRepeated on " ++ show pType+  Map k _+    | validMapKey k         -> pure unpacked+    | otherwise             -> throwError $ InvalidMapKeyType (show $ pPrint k)+  where+    packed = tyApp formRepeatedT formPackedT+    unpacked = tyApp formRepeatedT formUnpackedT++-- | Convert a dot proto type to a Haskell type of kind `Proto3.Suite.Form.ProtoType`,+-- with `Proto3.Suite.Form.Optional` serving the role elsewhere served by wrapper types+-- and by `Proto3.Suite.Types.ForceEmit`.+dptToFormType :: MonadError CompileError m => TypeContext -> DotProtoType -> m HsType+dptToFormType ctxt = \case+  Prim pType -> dpptToFormType ctxt pType+  Optional pType -> dpptToFormType ctxt pType+  Repeated pType -> dpptToFormType ctxt pType+  NestedRepeated pType -> internalError $ "unexpected NestedRepeated on " ++ show pType+  Map k v+    | validMapKey k -> do+        k2 <- dpptToFormType ctxt k+        v2 <- dptToFormType ctxt (Prim v)+        pure $ tyApply formMapT [k2, v2]+    | otherwise ->+        throwError $ InvalidMapKeyType (show $ pPrint k)++-- | Like 'dptToFormType' but for primitive types.+dpptToFormType ::+  forall m .+  MonadError CompileError m =>+  TypeContext ->+  DotProtoPrimType ->+  m HsType+dpptToFormType ctxt = \case+    Int32 ->+      pure formInt32T+    Int64 ->+      pure formInt64T+    SInt32 ->+      pure formSInt32T+    SInt64 ->+      pure formSInt64T+    UInt32 ->+      pure formUInt32T+    UInt64 ->+      pure formUInt64T+    Fixed32 ->+      pure formFixed32T+    Fixed64 ->+      pure formFixed64T+    SFixed32 ->+      pure formSFixed32T+    SFixed64 ->+      pure formSFixed64T+    String ->+      pure formStringT+    Bytes ->+      pure formBytesT+    Bool ->+      pure formBoolT+    Float ->+      pure formFloatT+    Double ->+      pure formDoubleT+    Named (Dots (Path ("google" :| ["protobuf", x])))+      | x == "Int32Value" ->+          wrapper formInt32T+      | x == "Int64Value" ->+          wrapper formInt64T+      | x == "UInt32Value" ->+          wrapper formUInt32T+      | x == "UInt64Value" ->+          wrapper formUInt64T+      | x == "StringValue" ->+          wrapper formStringT+      | x == "BytesValue" ->+          wrapper formBytesT+      | x == "BoolValue" ->+          wrapper formBoolT+      | x == "FloatValue" ->+          wrapper formFloatT+      | x == "DoubleValue" ->+          wrapper formDoubleT+    Named msgName ->+      case M.lookup msgName ctxt of+        Just ty@(DotProtoTypeInfo { dotProtoTypeInfoKind = DotProtoKindEnum }) ->+          tyApp formEnumerationT <$> msgTypeFromDpTypeInfo ctxt ty msgName+        Just ty -> tyApp formMessageT <$> msgTypeFromDpTypeInfo ctxt ty msgName+        Nothing -> noSuchTypeError msgName+  where+    wrapper :: HsType -> m HsType+    wrapper = pure . tyApp formMessageT . tyApp formWrapperT++--------------------------------------------------------------------------------+--+-- * Code generation+--++-- ** Generate instances for a 'DotProto' package++dotProtoDefinitionD ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  , (?typeLevelFormat :: Bool)+  ) =>+  DotProtoPackageSpec ->+  TypeContext ->+  DotProtoDefinition ->+  m [HsDecl]+dotProtoDefinitionD pkgSpec ctxt = \case+  DotProtoMessage _ messageName messageParts ->+    dotProtoMessageD ctxt Anonymous messageName messageParts++  DotProtoEnum _ enumName enumParts ->+    dotProtoEnumD Anonymous enumName enumParts++  DotProtoService _ serviceName serviceParts ->+    dotProtoServiceD pkgSpec ctxt serviceName serviceParts++-- | Generate 'Named' instance for a type in this package+namedInstD :: String -> HsDecl+namedInstD messageName =+    instDecl_ (protobufName tcName "Named")+              [ type_ messageName ]+              [ functionS_ "nameOf" [nameOf] ]+  where+    nameOf = ([wild_], apply fromStringE [ str_ messageName ])++hasDefaultInstD :: String -> HsDecl+hasDefaultInstD messageName =+  instDecl_ (protobufName tcName "HasDefault")+            [ type_ messageName ]+            [ ]++-- ** Generate types and instances for .proto messages++-- | Generate data types, 'Bounded', 'Enum', 'FromJSONPB', 'Named', 'Message',+--   'ToJSONPB' instances as appropriate for the given 'DotProtoMessagePart's+dotProtoMessageD ::+  forall m .+  ( MonadError CompileError m+  , (?stringType :: StringType)+  , (?typeLevelFormat :: Bool)+  ) =>+  TypeContext ->+  DotProtoIdentifier ->+  DotProtoIdentifier ->+  [DotProtoMessagePart] ->+  m [HsDecl]+dotProtoMessageD ctxt parentIdent messageIdent messageParts = do+    messageName <- qualifiedMessageName parentIdent messageIdent++    let mkDataDecl flds =+          dataDecl_ messageName+                    []+                    [ recDecl_ (unqual_ varName messageName) flds ]+                    defaultMessageDeriving++#ifdef SWAGGER+    let getName = \case+          DotProtoMessageField fld -> (: []) <$> getFieldNameForSchemaInstanceDeclaration fld+          DotProtoMessageOneOf ident _ -> (: []) . (Nothing, ) <$> dpIdentUnqualName ident+          _ -> pure []+#endif++    messageDataDecl <- mkDataDecl <$> foldMapM (messagePartFieldD messageName) messageParts++    foldMapM id+      [ sequence+          [ pure messageDataDecl+          , pure (Record.nfDataInstD messageDataDecl messageName)+          , pure (namedInstD messageName)+          , pure (hasDefaultInstD messageName)+          , messageInstD ctxt' parentIdent messageIdent messageParts++          , toJSONPBMessageInstD ctxt' parentIdent messageIdent messageParts+          , fromJSONPBMessageInstD ctxt' parentIdent messageIdent messageParts++            -- Generate Aeson instances in terms of JSONPB instances+          , pure (toJSONInstDecl messageName)+          , pure (fromJSONInstDecl messageName)++#ifdef SWAGGER+          -- And the Swagger ToSchema instance corresponding to JSONPB encodings+          , toSchemaInstanceDeclaration ctxt' messageName Nothing+              =<< foldMapM getName messageParts+#endif++#ifdef DHALL+          -- Generate Dhall instances+          , pure (dhallInterpretInstDecl messageName)+          , pure (dhallInjectInstDecl messageName)+#endif+          ]++      , if ?typeLevelFormat+          then typeLevelInstsD ctxt' parentIdent messageIdent messageParts+          else pure []++      -- Nested regular and oneof message decls+      , foldMapOfM (traverse . _DotProtoMessageDefinition)+                   nestedDecls+                   messageParts++      , foldMapOfM (traverse . _DotProtoMessageOneOf)+                   (uncurry $ nestedOneOfDecls messageName)+                   messageParts+      ]++  where+    ctxt' :: TypeContext+    ctxt' = maybe mempty dotProtoTypeChildContext (M.lookup messageIdent ctxt)+                <> ctxt++    messagePartFieldD :: String -> DotProtoMessagePart -> m [([HsName], HsBangType)]+    messagePartFieldD messageName (DotProtoMessageField DotProtoField{..}) = do+      fullName <- prefixedFieldName messageName =<< dpIdentUnqualName dotProtoFieldName+      fullTy <- dptToHsType WithinMessage ctxt' dotProtoFieldType+      pure [ ([unqual_ varName fullName], unbangedTy_ fullTy) ]++    messagePartFieldD messageName (DotProtoMessageOneOf fieldName _) = do+      fullName <- prefixedFieldName messageName =<< dpIdentUnqualName fieldName+      qualTyName <- prefixedConName messageName =<< dpIdentUnqualName fieldName+      let fullTy = tyConApp (haskellName tcName "Maybe") . type_ $ qualTyName+      pure [ ([unqual_ varName fullName], unbangedTy_ fullTy) ]++    messagePartFieldD _ _ = pure []++    nestedDecls :: DotProtoDefinition -> m [HsDecl]+    nestedDecls (DotProtoMessage _ subMsgName subMessageDef) = do+      parentIdent' <- concatDotProtoIdentifier parentIdent messageIdent+      dotProtoMessageD ctxt' parentIdent' subMsgName subMessageDef++    nestedDecls (DotProtoEnum _ subEnumName subEnumDef) = do+      parentIdent' <- concatDotProtoIdentifier parentIdent messageIdent+      dotProtoEnumD parentIdent' subEnumName subEnumDef++    nestedDecls _ = pure []++    nestedOneOfDecls :: String -> DotProtoIdentifier -> [DotProtoField] -> m [HsDecl]+    nestedOneOfDecls messageName identifier fields = do+      fullName <- prefixedConName messageName =<< dpIdentUnqualName identifier++      (cons, _idents) <- fmap unzip (mapM (oneOfCons fullName) fields)++#ifdef SWAGGER+      toSchemaInstance <- toSchemaInstanceDeclaration ctxt' fullName (Just _idents)+                            =<< mapM getFieldNameForSchemaInstanceDeclaration fields+#endif++      let nestedDecl = dataDecl_ fullName [] cons defaultMessageDeriving+      pure [ nestedDecl+           , Record.nfDataInstD nestedDecl fullName+           , namedInstD fullName+#ifdef SWAGGER+           , toSchemaInstance+#endif++#ifdef DHALL+           , dhallInterpretInstDecl fullName+           , dhallInjectInstDecl fullName+#endif+           ]++    oneOfCons :: String -> DotProtoField -> m (HsConDecl, HsName)+    oneOfCons fullName DotProtoField{..} = do+       consTy <- dptToHsType WithinOneOf ctxt' dotProtoFieldType+       consName <- prefixedConName fullName =<< dpIdentUnqualName dotProtoFieldName+       let ident = unqual_ dataName consName+       pure (conDecl_ ident [unbangedTy_ consTy], ident)++-- *** Generate type family instances providing type-level information about protobuf formats.++type FieldOccurrences = (Histogram FieldName, Histogram FieldNumber)++data FieldSpec = FieldSpec+  { fieldSpecName :: FieldName+  , fieldSpecNumber :: FieldNumber+  , fieldSpecOneOf :: Maybe FieldName+  , fieldSpecCardinality :: HsType+  , fieldSpecProtoType :: HsType+  }++typeLevelInstsD ::+  forall m .+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  TypeContext ->+  DotProtoIdentifier->+  DotProtoIdentifier ->+  [DotProtoMessagePart]->+  m [HsDecl]+typeLevelInstsD ctxt parentIdent msgIdent messageParts = do+    msgName <- qualifiedMessageName parentIdent msgIdent++    qualifiedFields <- getQualifiedFields msgName messageParts++    (fieldSpecLists, (fieldNames, fieldNumbers)) <-+      runWriterT (mapM mkFieldSpecs qualifiedFields)++    let (sort -> oneOfs, sortBy (compare `on` fieldSpecName) -> fieldSpecs) = fold fieldSpecLists+        repeatedFieldNames = mulipleOccurrencesOnly fieldNames+        repeatedFieldNumbers = mulipleOccurrencesOnly fieldNumbers++    when (repeatedFieldNames /= mempty || repeatedFieldNumbers /= mempty) $+      throwError $ RedefinedFields repeatedFieldNames repeatedFieldNumbers++    when (let Histogram m = fieldNames in M.member "" m) $+      internalError $ "empty field name within message " ++ show msgIdent++    let msgNameT = type_ msgName+        msgNumberOf = unqual_ tcName (msgName ++ "_NumberOf")+        msgProtoTypeOf = unqual_ tcName (msgName ++ "_ProtoTypeOf")+        msgOneOfOf = unqual_ tcName (msgName ++ "_OneOfOf")+        msgCardinalityOf = unqual_ tcName (msgName ++ "_CardinalityOf")+        fieldNameVar = tvarn_ "name"+        fieldNameVarT = typeNamed_ fieldNameVar+        fieldNameVarB = kindedTyVar_ synDef fieldNameVar symbolT+        err msg =+          [(Nothing, [fieldNameVarT], tyApp typeErrorT (tyApply msg [msgNameT, fieldNameVarT]))]+        toSym = symT . getFieldName+        fieldNameT = toSym . fieldSpecName+        fieldNumberT = natTLit . getFieldNumber . fieldSpecNumber+        oneOfT = maybe (symT "") toSym . fieldSpecOneOf++    let onFields :: (FieldSpec -> HsType) -> [(Maybe [HsTyVarBndrU], [HsType], HsType)]+        onFields rhs = fieldSpecs <&> \f -> (Nothing, [ fieldNameT f ], rhs f)++        onOneOfs :: (FieldName -> HsType) -> [(Maybe [HsTyVarBndrU], [HsType], HsType)]+        onOneOfs rhs = oneOfs <&> \o -> (Nothing, [ toSym o ], rhs o)++    let namesOf :: HsDecl+        numberOf, protoTypeOf, oneOfOf, cardinalityOf :: [HsDecl]+        namesOf = tyFamInstDecl_ formNamesOf Nothing [ msgNameT ]+          (listT_ (map fieldNameT fieldSpecs))+        numberOf =+          [ tyFamInstDecl_ formNumberOf Nothing [ msgNameT, fieldNameVarT ]+              (tyApp (typeNamed_ msgNumberOf) fieldNameVarT)+          , closedTyFamDecl_ msgNumberOf [ fieldNameVarB ] natT+              (onFields fieldNumberT ++ err formFieldNotFound)+          ]+        protoTypeOf =+          [ tyFamInstDecl_ formProtoTypeOf Nothing [ msgNameT, fieldNameVarT ]+              (tyApp (typeNamed_ msgProtoTypeOf) fieldNameVarT)+          , closedTyFamDecl_ msgProtoTypeOf [ fieldNameVarB ] formProtoTypeT+              (onFields fieldSpecProtoType ++ err formFieldNotFound)+          ]+        oneOfOf =+          [ tyFamInstDecl_ formOneOfOf Nothing [ msgNameT, fieldNameVarT ]+              (tyApp (typeNamed_ msgOneOfOf) fieldNameVarT)+          , closedTyFamDecl_ msgOneOfOf [ fieldNameVarB ] symbolT+              (onFields oneOfT ++ onOneOfs toSym ++ err formFieldOrOneOfNotFound)+          ]+        cardinalityOf =+          [ tyFamInstDecl_ formCardinalityOf Nothing [ msgNameT, fieldNameVarT ]+              (tyApp (typeNamed_ msgCardinalityOf) fieldNameVarT)+          , closedTyFamDecl_ msgCardinalityOf [ fieldNameVarB ] formCardinalityT+              ( onFields fieldSpecCardinality +++                onOneOfs (const formOptionalT) +++                err formFieldOrOneOfNotFound+              )+          ]++    pure $ namesOf : numberOf ++ protoTypeOf ++ oneOfOf ++ cardinalityOf+  where+    mkFieldSpecs :: QualifiedField -> WriterT FieldOccurrences m ([FieldName], [FieldSpec])+    mkFieldSpecs QualifiedField{fieldInfo} = case fieldInfo of+      FieldNormal fieldName fieldNum dpType options -> do+        tell (oneOccurrence fieldName, oneOccurrence fieldNum)+        cardinality <- dptToFormCardinality options ctxt dpType+        protoType <- dptToFormType ctxt dpType+        pure ( [], [ FieldSpec+                       { fieldSpecName = fieldName+                       , fieldSpecNumber = fieldNum+                       , fieldSpecOneOf = Nothing+                       , fieldSpecCardinality = cardinality+                       , fieldSpecProtoType = protoType+                       } ] )++      FieldOneOf oneofName OneofField{subfields} -> do+          tell (oneOccurrence oneofName, mempty)+          ([oneofName], ) <$> mapM mkSubfieldSpec subfields+        where+          mkSubfieldSpec :: OneofSubfield -> WriterT FieldOccurrences m FieldSpec+          mkSubfieldSpec (OneofSubfield+                            { subfieldNumber = subfieldNum+                            , subfieldName = subfieldName+                            , subfieldType = dpType+                            }) = do+            tell (oneOccurrence subfieldName, oneOccurrence subfieldNum)+            protoType <- dptToFormType ctxt dpType+            pure FieldSpec+                   { fieldSpecName = subfieldName+                   , fieldSpecNumber = subfieldNum+                   , fieldSpecOneOf = Just oneofName+                   , fieldSpecCardinality = formOptionalT+                   , fieldSpecProtoType = protoType+                   }++-- *** Generate Protobuf 'Message' type class instances++messageInstD ::+  forall m .+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  TypeContext ->+  DotProtoIdentifier ->+  DotProtoIdentifier ->+  [DotProtoMessagePart] ->+  m HsDecl+messageInstD ctxt parentIdent msgIdent messageParts = do+     msgName         <- qualifiedMessageName parentIdent msgIdent+     qualifiedFields <- getQualifiedFields msgName messageParts++     encodedFields   <- mapM encodeMessageField qualifiedFields+     decodedFields   <- mapM decodeMessageField qualifiedFields++     let encodeMessageBind :: HsBind+         encodeMessageBind =+           functionS_ "encodeMessage" [([wild_, recordPattern], encodeMessageE)]++         encodeMessageE :: HsExp+         encodeMessageE = case encodedFields of+           [] -> memptyE+           (field : fields) -> foldl op (paren field) fields+             where op fs f = apply (apply mappendE [fs]) [paren f]+             -- NOTE: We use a left fold because this way the leftmost field+             -- is the most nested and the rightmost field--the one to be written+             -- first by the right-to-left builder--is the one that is least nested.++         recordPattern :: HsPat+         recordPattern = recPat (unqual_ dataName msgName) punnedFieldsP++         punnedFieldsP :: [GHC.LHsRecField GHC.GhcPs HsPat]+         punnedFieldsP = map (fp . coerce . recordFieldName) qualifiedFields+           where+             fp = fieldPunPat . unqual_ varName++     let decodeMessageBind :: HsBind+         decodeMessageBind = functionS_ "decodeMessage" [([wild_], decodeMessageE)]++         decodeMessageE :: HsExp+         decodeMessageE = foldl (\f -> opApp f apOp)+                                (apply pureE [ uvar_ msgName ])+                                decodedFields++     let dotProtoBind :: HsBind+         dotProtoBind = functionS_ "dotProto" [([wild_], dotProtoE)]++         dotProtoE :: HsExp+         dotProtoE = list_ $ do+           DotProtoMessageField DotProtoField{..} <- messageParts+           pure $ apply dotProtoFieldC+                        [ fieldNumberE dotProtoFieldNumber+                        , dpTypeE dotProtoFieldType+                        , dpIdentE dotProtoFieldName+                        , list_ (map optionE dotProtoFieldOptions)+                        , str_ dotProtoFieldComment+                        ]++     pure $ instDecl_ (protobufName tcName "Message")+                      [ type_ msgName ]+                      [ encodeMessageBind+                      , decodeMessageBind+                      , dotProtoBind+                      ]+  where+    encodeMessageField :: QualifiedField -> m HsExp+    encodeMessageField QualifiedField{recordFieldName, fieldInfo} =+      let recordFieldName' = uvar_ (coerce recordFieldName) in+      case fieldInfo of+        FieldNormal _fieldName fieldNum dpType options -> do+            fieldE <- wrapE WithinMessage ctxt options dpType recordFieldName'+            pure $ apply encodeMessageFieldE [ fieldNumberE fieldNum, fieldE ]++        FieldOneOf _ OneofField{subfields} -> do+            alts <- mapM mkAlt subfields+            pure $ case_ recordFieldName'+                    [ alt_ (conPat nothingN []) memptyE+                    , alt_ (conPat justN [patVar "x"]) (case_ (uvar_ "x") alts)+                    ]+          where+            -- Create all pattern match & expr for each constructor:+            --    Constructor y -> encodeMessageField num (Nested (Just y)) -- for embedded messages+            --    Constructor y -> encodeMessageField num (ForceEmit y)     -- for everything else+            mkAlt (OneofSubfield+                     { subfieldNumber = fieldNum+                     , subfieldConsName = conName+                     , subfieldType = dpType+                     , subfieldOptions = options+                     }) = do+              let isMaybe+                     | Prim (Named tyName) <- dpType+                     = isMessage ctxt tyName+                     | otherwise+                     = False++              let wrapJust = paren . app justC++              xE <- (if isMaybe then id else fmap forceEmitE)+                     . wrapE WithinMessage ctxt options dpType+                         -- For now we use 'WithinMessage' to preserve+                         -- the historical approach of treating this field+                         -- as if it were an ordinary non-oneof field that+                         -- just happens to be present, then forcing it to+                         -- be emitted.+                     . (if isMaybe then wrapJust else id)+                     $ uvar_ "y"++              pure $ alt_ (conPat (unqual_ dataName conName) [patVar "y"])+                          (apply encodeMessageFieldE [fieldNumberE fieldNum, xE])++    decodeMessageField :: QualifiedField -> m HsExp+    decodeMessageField QualifiedField{fieldInfo} =+      case fieldInfo of+        FieldNormal _fieldName fieldNum dpType options ->+            unwrapE WithinMessage ctxt options dpType $+              apply atE [ decodeMessageFieldE, fieldNumberE fieldNum ]++        FieldOneOf _ OneofField{subfields} -> do+            parsers <- mapM subfieldParserE subfields+            pure $ apply oneofE [ nothingC, list_ parsers ]+          where+            -- create a list of (fieldNumber, Cons <$> parser)+            subfieldParserE (OneofSubfield+                               { subfieldNumber = fieldNumber+                               , subfieldConsName = consName+                               , subfieldType = dpType+                               , subfieldOptions = options+                               }) = do+              let fE | Prim (Named tyName) <- dpType, isMessage ctxt tyName =+                         paren (app fmapE (uvar_ consName))+                     | otherwise =+                         paren (opApp justC composeOp (uvar_ consName))++              -- For now we continue the historical practice of parsing+              -- submessages within oneofs as if were outside of oneofs,+              -- and replacing the "Just . Ctor" with "fmap . Ctor".+              -- That is why we do not pass WithinOneOf.+              alts <- unwrapE WithinMessage ctxt options dpType decodeMessageFieldE++              pure $ tuple_+                   [ fieldNumberE fieldNumber+                   , opApp (apply pureE [ fE ]) apOp alts+                   ]+++-- *** Generate ToJSONPB/FromJSONPB instances++toJSONPBMessageInstD ::+  forall m .+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  TypeContext ->+  DotProtoIdentifier ->+  DotProtoIdentifier ->+  [DotProtoMessagePart] ->+  m HsDecl+toJSONPBMessageInstD ctxt parentIdent msgIdent messageParts = do+    msgName    <- qualifiedMessageName parentIdent msgIdent+    qualFields <- getQualifiedFields msgName messageParts++    let applyE nm oneofNm = do+          fs <- traverse (encodeMessageField oneofNm) qualFields+          pure $ apply (var_ (jsonpbName varName nm)) [list_ fs]++    let patBinder = foldQF (const fieldBinder) (oneofSubDisjunctBinder . subfields)+    let matchE nm appNm oneofAppNm = do+          rhs <- applyE appNm oneofAppNm+          pure $ functionS_ nm+            [ ( [conPat (unqual_ dataName msgName) (patVar . patBinder <$> qualFields)]+              , rhs+              )+            ]++    toJSONPB <- matchE "toJSONPB" "object" "objectOrNull"+    toEncoding <- matchE "toEncodingPB" "pairs" "pairsOrNull"++    pure $ instDecl_ (jsonpbName tcName "ToJSONPB")+                     [ type_ msgName ]+                     [ toJSONPB+                     , toEncoding+                     ]++  where+    encodeMessageField :: String -> QualifiedField -> m HsExp+    encodeMessageField oneofNm (QualifiedField _ fieldInfo) =+      case fieldInfo of+        FieldNormal fldName fldNum dpType options ->+          defPairE fldName fldNum dpType options+        FieldOneOf _ oo ->+          oneofCaseE oneofNm oo++    -- E.g.+    -- "another" .= f2 -- always succeeds (produces default value on missing field)+    defPairE fldName fldNum dpType options = do+      w <- wrapE WithinMessage ctxt options dpType (uvar_ (fieldBinder fldNum))+      pure $ opApp (str_ (coerce fldName)) toJSONPBOp w++    -- E.g.+    -- HsJSONPB.pair "name" f4 -- fails on missing field+    oneOfPairE fldNm varNm options dpType = do+      w <- wrapE WithinOneOf ctxt options dpType (uvar_ varNm)+      pure $ apply (var_ (jsonpbName varName "pair")) [str_ (coerce fldNm), w]++    -- Suppose we have a sum type Foo, nested inside a message Bar.+    -- We want to generate the following:+    --+    -- > toJSONPB (Bar foo more stuff) =+    -- >   HsJSONPB.object+    -- >     [ (let encodeFoo = (<case expr scrutinising foo> :: Options -> Value)+    -- >        in \option -> if optEmitNamedOneof option+    -- >                      then ("Foo" .= (PB.objectOrNull [encodeFoo] option)) option+    -- >                      else encodeFoo option+    -- >       )+    -- >     , <encode more>+    -- >     , <encode stuff>+    -- >     ]+    oneofCaseE :: String -> OneofField -> m HsExp+    oneofCaseE retJsonCtor (OneofField typeName subfields) = do+        altEs <- traverse altE subfields+        pure $ paren+          $ let_ [ functionS_ caseName [([], caseExpr altEs)] ]+          $ lambda_ [patVar optsStr] (if_ dontInline noInline yesInline)+      where+        optsStr = "options"+        opts    = uvar_ optsStr++        caseName = "encode" <> over (ix 0) toUpper typeName+        caseBnd = uvar_ caseName++        dontInline = app (var_ (jsonpbName varName "optEmitNamedOneof")) opts++        noInline = app (paren (opApp (str_ typeName)+                                     toJSONPBOp+                                     (apply (var_ (jsonpbName varName retJsonCtor))+                                            [ list_ [caseBnd], opts ])))+                       opts++        yesInline = app caseBnd opts++        altE sub@(OneofSubfield+                    { subfieldConsName = conName+                    , subfieldName = pbFldNm+                    , subfieldType = dpType+                    , subfieldOptions = options+                    }) = do+          let patVarNm = oneofSubBinder sub+          p <- oneOfPairE pbFldNm patVarNm options dpType+          pure $+            alt_ (conPat justN [parenPat (conPat (unqual_ dataName conName) [patVar patVarNm])]) p++        -- E.g.+        -- case f4_or_f9 of+        --   Just (SomethingPickOneName f4)+        --     -> HsJSONPB.pair "name" f4+        --   Just (SomethingPickOneSomeid f9)+        --     -> HsJSONPB.pair "someid" f9+        --   Nothing+        --     -> mempty+        caseExpr altEs = paren $+            case_ disjunctName (altEs <> [fallthroughE])+          where+            disjunctName = uvar_ (oneofSubDisjunctBinder subfields)+            fallthroughE = alt_ (conPat nothingN []) memptyE++fromJSONPBMessageInstD ::+  forall m .+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  TypeContext ->+  DotProtoIdentifier ->+  DotProtoIdentifier ->+  [DotProtoMessagePart] ->+  m HsDecl+fromJSONPBMessageInstD ctxt parentIdent msgIdent messageParts = do+    msgName    <- qualifiedMessageName parentIdent msgIdent+    qualFields <- getQualifiedFields msgName messageParts++    fieldParsers <- traverse parseField qualFields++    let parseJSONPBE =+          apply (var_ (jsonpbName varName "withObject"))+                [ str_ msgName+                , paren (lambda_ [lambdaPVar] fieldAps)+                ]+          where+            fieldAps = foldl (\f -> opApp f apOp)+                             (apply pureE [ uvar_ msgName ])+                             fieldParsers++    let parseJSONPBBind = functionS_ "parseJSONPB" [([], parseJSONPBE)]++    pure (instDecl_ (jsonpbName tcName "FromJSONPB")+                    [ type_ msgName ]+                    [ parseJSONPBBind ])+  where+    lambdaPVar = patVar "obj"+    lambdaVar  = uvar_ "obj"++    parseField (QualifiedField _ (FieldNormal fldName _ dpType options)) =+      normalParserE fldName dpType options+    parseField (QualifiedField _ (FieldOneOf _ fld)) =+      oneofParserE fld++    -- E.g., for message+    --   message Something { oneof name_or_id { string name = _; int32 someid = _; } }+    --+    -- ==>+    --+    -- (let parseSomethingNameOrId parseObj = <FUNCTION, see tryParseDisjunctsE>+    --  in ((obj .: "nameOrId") Hs.>>=+    --      (HsJSONPB.withObject "nameOrId" parseSomethingNameOrId))+    --     <|>+    --     (parseSomethingNameOrId obj)+    -- )+    oneofParserE :: OneofField -> m HsExp+    oneofParserE (OneofField oneofType fields) = do+        ds <- tryParseDisjunctsE+        pure $ paren $+          let_ [ functionS_ letBndStr [([patVar letArgStr], ds)] ]+               (opApp parseWrapped altOp parseUnwrapped)+      where+        oneofTyLit = str_ oneofType -- FIXME++        letBndStr  = "parse" <> over (ix 0) toUpper oneofType+        letBndName = uvar_ letBndStr+        letArgStr  = "parseObj"+        letArgName = uvar_ letArgStr++        parseWrapped = paren $+          opApp (opApp lambdaVar parseJSONPBOp oneofTyLit)+                bindOp+                (apply (var_ (jsonpbName varName "withObject")) [ oneofTyLit , letBndName ])++        parseUnwrapped = paren (app letBndName lambdaVar)++        -- parseSomethingNameOrId parseObj =+        --   Hs.msum+        --     [ (Just . SomethingPickOneName) <$> (HsJSONPB.parseField parseObj "name")+        --     , (Just . SomethingPickOneSomeid) <$> (HsJSONPB.parseField parseObj "someid")+        --     , pure Nothing+        --     ]+        tryParseDisjunctsE = do+          fs <- traverse subParserE fields+          pure $ app msumE (list_ (fs <> fallThruE))++        fallThruE = [ app pureE nothingC ]++        subParserE OneofSubfield{subfieldConsName, subfieldName,+                                 subfieldType, subfieldOptions} = do+          maybeCoercion <-+            unwrapFunE False WithinOneOf ctxt subfieldOptions subfieldType+          let inject = opApp justC composeOp (uvar_ subfieldConsName)+          pure $ opApp+              (maybe inject (opApp inject composeOp) maybeCoercion)+              fmapOp+              (apply (var_ (jsonpbName varName "parseField"))+                     [ letArgName+                     , str_ (coerce subfieldName)])++    -- E.g. obj .: "someid"+    normalParserE :: FieldName -> DotProtoType -> [DotProtoOption] -> m HsExp+    normalParserE fldName dpType options =+      unwrapE WithinMessage ctxt options dpType $+        opApp lambdaVar+                   parseJSONPBOp+                   (str_(coerce fldName))++-- *** Generate default Aeson To/FromJSON and Swagger ToSchema instances+-- (These are defined in terms of ToJSONPB)++toJSONInstDecl :: String -> HsDecl+toJSONInstDecl typeName =+  instDecl_ (jsonpbName tcName "ToJSON")+            [ type_ typeName ]+            [ functionS_ "toJSON"+                         [([], var_ (jsonpbName varName "toAesonValue"))]+            , functionS_ "toEncoding"+                         [([], var_ (jsonpbName varName "toAesonEncoding"))]+            ]++fromJSONInstDecl :: String -> HsDecl+fromJSONInstDecl typeName =+  instDecl_ (jsonpbName tcName "FromJSON")+            [ type_ typeName ]+            [ functionS_ "parseJSON"+                         [([], var_ (jsonpbName varName "parseJSONPB"))]+            ]+++-- *** Generate `ToSchema` instance++#ifdef SWAGGER+getFieldNameForSchemaInstanceDeclaration+  :: MonadError CompileError m+  => DotProtoField+  -> m (Maybe ([DotProtoOption], DotProtoType), String)+getFieldNameForSchemaInstanceDeclaration fld = do+  unqual <- dpIdentUnqualName (dotProtoFieldName fld)+  let optsType = (dotProtoFieldOptions fld, dotProtoFieldType fld)+  pure (Just optsType, unqual)++toSchemaInstanceDeclaration ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  TypeContext ->+  -- | Name of the message type to create an instance for+  String ->+  -- | Oneof constructors+  Maybe [HsName] ->+  -- | Field names, with every field that is not actually a oneof+  -- combining fields paired with its options and protobuf type+  [(Maybe ([DotProtoOption], DotProtoType), String)] ->+  m HsDecl+toSchemaInstanceDeclaration ctxt messageName maybeConstructors fieldNamesEtc = do+  let fieldNames = map snd fieldNamesEtc++  qualifiedFieldNames <- mapM (prefixedFieldName messageName) fieldNames++  let messageConstructor = uvar_ messageName++  let _namedSchemaNameExpression = app justC (str_ messageName)++#ifdef SWAGGER+      -- { _paramSchemaType = HsJSONPB.SwaggerObject+      -- }+  let paramSchemaUpdates =+        [ fieldUpd_ _paramSchemaType _paramSchemaTypeExpression+        ]+        where+          _paramSchemaType = jsonpbName varName "_paramSchemaType"++#if MIN_VERSION_swagger2(2,4,0)+          _paramSchemaTypeExpression = app justC (var_ (jsonpbName dataName "SwaggerObject"))+#else+          _paramSchemaTypeExpression = var_ (jsonpbName dataName "SwaggerObject")+#endif+#else+  let paramSchemaUpdates = []+#endif++  let _schemaParamSchemaExpression = recordUpd_ memptyE paramSchemaUpdates++      -- [ ("fieldName0", qualifiedFieldName0)+      -- , ("fieldName1", qualifiedFieldName1)+      -- ...+      -- ]+  let properties = list_ $ do+        (fieldName, qualifiedFieldName) <- zip fieldNames qualifiedFieldNames+        pure (tuple_ [ str_  fieldName, uvar_ qualifiedFieldName ])++  let _schemaPropertiesExpression =+        app (var_ (jsonpbName varName "insOrdFromList")) properties++      -- { _schemaParamSchema = ...+      -- , _schemaProperties  = ...+      -- , ...+      -- }+  let schemaUpdates = normalUpdates ++ extraUpdates+        where+          normalUpdates =+            [ fieldUpd_ _schemaParamSchema _schemaParamSchemaExpression+            , fieldUpd_ _schemaProperties  _schemaPropertiesExpression+            ]++          extraUpdates =+            case maybeConstructors of+                Just _ ->+                  [ fieldUpd_ _schemaMinProperties justOne+                  , fieldUpd_ _schemaMaxProperties justOne+                  ]+                Nothing ->+                  []++          _schemaParamSchema    = jsonpbName varName "_schemaParamSchema"+          _schemaProperties     = jsonpbName varName "_schemaProperties"+          _schemaMinProperties  = jsonpbName varName "_schemaMinProperties"+          _schemaMaxProperties  = jsonpbName varName "_schemaMaxProperties"++          justOne = app justC (intE (1 :: Integer))++  let _namedSchemaSchemaExpression = recordUpd_ memptyE schemaUpdates++      -- { _namedSchemaName   = ...+      -- , _namedSchemaSchema = ...+      -- }+  let namedSchemaBinds =+        [ fieldBind_ _namedSchemaName   _namedSchemaNameExpression+        , fieldBind_ _namedSchemaSchema _namedSchemaSchemaExpression+        ]+        where+          _namedSchemaName   = jsonpbName varName "_namedSchemaName"+          _namedSchemaSchema = jsonpbName varName "_namedSchemaSchema"++  let namedSchema = recordCtor_ (jsonpbName dataName "NamedSchema") namedSchemaBinds++  let toDeclareName fieldName = "declare_" ++ fieldName++  let toArgument fc (maybeOptsType, fieldName) =+          maybe pure (uncurry (unwrapE fc ctxt)) maybeOptsType $+            app asProxy declare+        where+          declare = uvar_ (toDeclareName fieldName)+          asProxy = var_ (jsonpbName varName "asProxy")++      -- do let declare_fieldName0 = HsJSONPB.declareSchemaRef+      --    qualifiedFieldName0 <- declare_fieldName0 Proxy.Proxy+      --    let declare_fieldName1 = HsJSONPB.declareSchemaRef+      --    qualifiedFieldName1 <- declare_fieldName1 Proxy.Proxy+      --    ...+      --    let _ = pure MessageName <*> HsJSONPB.asProxy declare_fieldName0 <*> HsJSONPB.asProxy declare_fieldName1 <*> ...+      --    return (...)+  let expressionForMessage = do+        let bindingStatements = do+              (fieldName, qualifiedFieldName) <- zip fieldNames qualifiedFieldNames++              let declareIdentifier = unqual_ varName (toDeclareName fieldName)++              let stmt0 = letStmt_+                    [ function_ declareIdentifier+                        [([], var_ (jsonpbName varName "declareSchemaRef"))] ]++              let stmt1 = bindStmt_ (patVar qualifiedFieldName)+                                    (app (var_ declareIdentifier)+                                         (var_ (proxyName dataName "Proxy")))+              [ stmt0, stmt1]++        inferenceStatement <- do+          arguments <- traverse (toArgument WithinMessage) fieldNamesEtc+          let patternBind = patBind_ wild_ (applicativeApply messageConstructor arguments)+          pure $ if null fieldNames then [] else [ letStmt_ [ patternBind ] ]++        let returnStatement = lastStmt_ (app returnE (paren namedSchema))++        pure $ do_ (bindingStatements ++ inferenceStatement ++ [ returnStatement ])++      -- do let declare_fieldName0 = HsJSONPB.declareSchemaRef+      --    let _ = pure ConstructorName0 <*> HsJSONPB.asProxy declare_fieldName0+      --    qualifiedFieldName0 <- declare_fieldName0 Proxy.Proxy+      --    let declare_fieldName1 = HsJSONPB.declareSchemaRef+      --    let _ = pure ConstructorName1 <*> HsJSONPB.asProxy declare_fieldName1+      --    qualifiedFieldName1 <- declare_fieldName1 Proxy.Proxy+      --    ...+      --    return (...)+  let expressionForOneOf constructors = do+        let bindingStatement (fieldNameEtc, qualifiedFieldName, constructor) = do+              let declareIdentifier = unqual_ varName (toDeclareName (snd fieldNameEtc))++              let stmt0 = letStmt_+                    [ function_ declareIdentifier+                        [([], var_ (jsonpbName varName "declareSchemaRef"))] ]++              let stmt1 = bindStmt_ (patVar qualifiedFieldName)+                                    (app (var_ declareIdentifier)+                                         (var_ (proxyName dataName "Proxy")))++              inferenceStatement <- do+                argument <- toArgument WithinOneOf fieldNameEtc+                let patternBind = patBind_ wild_ (applicativeApply (var_ constructor) [ argument ])+                pure $ if null fieldNames then [] else [ letStmt_ [ patternBind ] ]++              pure $ [stmt0, stmt1] ++ inferenceStatement++        bindingStatements <- foldMapM bindingStatement $+          zip3 fieldNamesEtc qualifiedFieldNames constructors++        let returnStatement = lastStmt_ (app returnE (paren namedSchema))++        pure $ do_ (bindingStatements ++ [ returnStatement ])++  expression <- case maybeConstructors of+    Nothing           -> expressionForMessage+    Just constructors -> expressionForOneOf constructors++  let instanceDeclaration =+          instDecl_ className [ classArgument ] [ classDeclaration ]+        where+          className = jsonpbName tcName "ToSchema"++          classArgument = type_ messageName++          classDeclaration =+            functionS_ "declareNamedSchema" [([ wild_ ], expression)]++  pure instanceDeclaration+#endif+++-- ** Generate types and instances for .proto enums++dotProtoEnumD+    :: MonadError CompileError m+    => DotProtoIdentifier+    -> DotProtoIdentifier+    -> [DotProtoEnumPart]+    -> m [HsDecl]+dotProtoEnumD parentIdent enumIdent enumParts = do+  enumName <- qualifiedMessageName parentIdent enumIdent++  let enumeratorDecls =+        [ (i, conIdent) | DotProtoEnumField conIdent i _options <- enumParts ]++  enumeratorDeclsNE <- case enumeratorDecls of+    [] -> throwError $ EmptyEnumeration enumName+    h@(i, conIdent) : t+      | i == 0 -> pure (h :| t)+      | otherwise -> throwError $ NonzeroFirstEnumeration enumName conIdent i++  enumCons <- NE.sortBy (comparing fst) <$>+    traverse (traverse (fmap (prefixedEnumFieldName enumName) . dpIdentUnqualName))+             enumeratorDeclsNE++  let enumConNames = fmap snd enumCons++      minBoundD :: HsBind+      minBoundD = functionS_ "minBound" [([], uvar_ (NE.head enumConNames))]++      maxBoundD :: HsBind+      maxBoundD = functionS_ "maxBound" [([], uvar_ (NE.last enumConNames))]++      compareD :: HsBind+      compareD = functionS_ "compare"+          [ ( [ patVar "x", patVar "y" ]+            , app+                  (app+                      (var_ (haskellName varName "compare"))+                      (paren+                          (app (var_ (protobufName varName "fromProtoEnum"))+                                 (uvar_ "x")+                          )+                      )+                  )+                  (paren+                      (app (var_ (protobufName varName "fromProtoEnum"))+                             (uvar_ "y")+                      )+                  )+            )+          ]++      fromProtoEnumD :: HsBind+      fromProtoEnumD = functionS_ "fromProtoEnum"+          [ ([ conPat (unqual_ dataName conName) [] ], intE conIdx)+          | (conIdx, conName) <- NE.toList enumCons+          ]++      toProtoEnumMayD :: HsBind+      toProtoEnumMayD = functionS_ "toProtoEnumMay" $+          [ ([ intP conIdx ], app justC (uvar_ conName))+          | (conIdx, conName) <- NE.toList enumCons ] +++          [ ([ wild_ ], nothingC) ]++      parseJSONPBDecl :: HsBind+      parseJSONPBDecl = functionS_ "parseJSONPB" $+          foldr ((:) . matchConName) [mismatch] enumConNames+        where+          matchConName conName = ([pat conName], app pureE (uvar_ conName))++          pat nm = conPat (jsonpbName dataName "String") [ strPat (tryStripEnumName nm) ]++          tryStripEnumName = fromMaybe <*> stripPrefix enumName++          mismatch =+            ( [patVar "v"]+            , apply (var_ (jsonpbName varName "typeMismatch"))+                    [ str_ enumName, uvar_ "v" ]+            )++      toJSONPBDecl :: HsBind+      toJSONPBDecl =+        functionS_ "toJSONPB"+          [( [ patVar "x", wild_ ]+           , app (var_ (jsonpbName varName "enumFieldString")) (uvar_ "x")+           )]++      toEncodingPBDecl :: HsBind+      toEncodingPBDecl =+        functionS_ "toEncodingPB"+          [([ patVar "x", wild_ ]+           , app (var_ (jsonpbName varName "enumFieldEncoding")) (uvar_ "x")+           )]++  pure [ dataDecl_ enumName+                   []+                   [ conDecl_ (unqual_ dataName con) [] | con <- NE.toList enumConNames ]+                   defaultEnumDeriving+       , namedInstD enumName+       , hasDefaultInstD enumName+       , instDecl_ (haskellName tcName "Bounded") [ type_ enumName ]+                   [ minBoundD+                   , maxBoundD+                   ]+       , instDecl_ (haskellName tcName "Ord") [ type_ enumName ]+                   [ compareD ]+       , instDecl_ (protobufName tcName "ProtoEnum") [ type_ enumName ]+                   [ toProtoEnumMayD+                   , fromProtoEnumD+                   ]+       , instDecl_ (jsonpbName tcName "ToJSONPB") [ type_ enumName ]+                   [ toJSONPBDecl+                   , toEncodingPBDecl+                   ]+       , instDecl_ (jsonpbName tcName "FromJSONPB") [ type_ enumName ]+                   [ parseJSONPBDecl ]+       -- Generate Aeson instances in terms of JSONPB instances+       , toJSONInstDecl enumName+       , fromJSONInstDecl enumName++#ifdef DHALL+       -- Generate Dhall instances+       , dhallInterpretInstDecl enumName+       , dhallInjectInstDecl enumName+#endif++       -- And the Finite instance, used to infer a Swagger ToSchema instance+       -- for this enumerated type.+       , instDecl_ (protobufName tcName "Finite") [ type_ enumName ] []+       ]++-- ** Generate code for dot proto services++dotProtoServiceD ::+  ( MonadError CompileError m+  , (?stringType :: StringType)+  ) =>+  DotProtoPackageSpec ->+  TypeContext ->+  DotProtoIdentifier ->+  [DotProtoServicePart] ->+  m [HsDecl]+dotProtoServiceD pkgSpec ctxt serviceIdent service = do+     serviceName <- typeLikeName =<< dpIdentUnqualName serviceIdent++     endpointPrefix <-+       case pkgSpec of+         DotProtoPackageSpec pkgIdent -> do+           packageName <- dpIdentQualName pkgIdent+           pure $ "/" ++ packageName ++ "." ++ serviceName ++ "/"+         DotProtoNoPackage -> pure $ "/" ++ serviceName ++ "/"++     let serviceFieldD (DotProtoServiceRPCMethod RPCMethod{..}) = do+           fullName <- prefixedMethodName serviceName =<< dpIdentUnqualName rpcMethodName++           methodName <- case rpcMethodName of+                           Single nm -> pure nm+                           _ -> invalidMethodNameError rpcMethodName++           requestTy  <- dpptToHsType ctxt (Named rpcMethodRequestType)++           responseTy <- dpptToHsType ctxt (Named rpcMethodResponseType)++           let streamingType =+                 case (rpcMethodRequestStreaming, rpcMethodResponseStreaming) of+                   (Streaming, Streaming)       -> biDiStreamingC+                   (Streaming, NonStreaming)    -> clientStreamingC+                   (NonStreaming, Streaming)    -> serverStreamingC+                   (NonStreaming, NonStreaming) -> normalC++           pure [ ( endpointPrefix ++ methodName+                  , fullName, rpcMethodRequestStreaming, rpcMethodResponseStreaming+                  , unbangedTy_ $+                    funTy (tyApply (tvar_ "request") [streamingType, requestTy, responseTy])+                          (tyApply ioT [tyApply (tvar_ "response") [streamingType, responseTy]])+                  )+                ]++         serviceFieldD _ = pure []++     fieldsD <- foldMapM serviceFieldD service++     serverFuncName <- prefixedFieldName serviceName "server"+     clientFuncName <- prefixedFieldName serviceName "client"++     let conDecl = recDecl_ (unqual_ dataName serviceName)+                            [ ([unqual_ varName hsName], ty) | (_, hsName, _, _, ty) <- fieldsD ]++     let serverT = tyApply (typeNamed_ (unqual_ tcName serviceName))+                           [ serverRequestT, serverResponseT ]++     let serviceServerTypeD =+           typeSig_ [ unqual_ varName serverFuncName ] implicitOuterSigTyVarBinders_+                    (funTy serverT (funTy serviceOptionsC ioActionT))++     let serviceServerD = valDecl_ $+             functionS_ serverFuncName [(serverFuncPats, serverFuncRhs)]+           where+             serverFuncPats =+                 [ recPat (unqual_ dataName serviceName)+                          [ fieldPunPat (unqual_ varName methodName)+                          | (_, methodName, _, _, _) <- fieldsD+                          ]+                 , conPat (unqual_ dataName "ServiceOptions")+                          [ patVar "serverHost"+                          , patVar "serverPort"+                          , patVar "useCompression"+                          , patVar "userAgentPrefix"+                          , patVar "userAgentSuffix"+                          , patVar "initialMetadata"+                          , patVar "sslConfig"+                          , patVar "logger"+                          , patVar "serverMaxReceiveMessageLength"+                          , patVar "serverMaxMetadataSize"+                          ]+                 ]++             serverFuncRhs = apply serverLoopE [ serverOptsE ]++             handlerE handlerC adapterE methodName hsName =+                 apply handlerC [ apply methodNameC [ str_ methodName ]+                                , apply adapterE [ uvar_ hsName ]+                                ]++             update u v = fieldUpd_ (unqual_ varName u) (uvar_ v)++             serverOptsE = recordUpd_ defaultOptionsE+                 [ fieldUpd_ (grpcName varName "optNormalHandlers") $+                       list_ [ handlerE unaryHandlerC convertServerHandlerE endpointName hsName+                             | (endpointName, hsName, NonStreaming, NonStreaming, _) <- fieldsD+                             ]++                 , fieldUpd_ (grpcName varName "optClientStreamHandlers") $+                       list_ [ handlerE clientStreamHandlerC convertServerReaderHandlerE endpointName hsName+                             | (endpointName, hsName, Streaming, NonStreaming, _) <- fieldsD+                             ]++                 , fieldUpd_ (grpcName varName "optServerStreamHandlers") $+                       list_ [ handlerE serverStreamHandlerC convertServerWriterHandlerE endpointName hsName+                             | (endpointName, hsName, NonStreaming, Streaming, _) <- fieldsD+                             ]++                 , fieldUpd_ (grpcName varName "optBiDiStreamHandlers") $+                       list_ [ handlerE biDiStreamHandlerC convertServerRWHandlerE endpointName hsName+                             | (endpointName, hsName, Streaming, Streaming, _) <- fieldsD+                             ]++                 , update "optServerHost" "serverHost"+                 , update "optServerPort" "serverPort"+                 , update "optUseCompression" "useCompression"+                 , update "optUserAgentPrefix" "userAgentPrefix"+                 , update "optUserAgentSuffix" "userAgentSuffix"+                 , update "optInitialMetadata" "initialMetadata"+                 , update "optSSLConfig" "sslConfig"+                 , update "optLogger" "logger"+                 , update "optMaxReceiveMessageLength" "serverMaxReceiveMessageLength"+                 , update "optMaxMetadataSize" "serverMaxMetadataSize"+                 ]++     let clientT = tyApply (type_ serviceName) [ clientRequestT, clientResultT ]++     let serviceClientTypeD =+            typeSig_ [ unqual_ varName clientFuncName ] implicitOuterSigTyVarBinders_+                     (funTy grpcClientT (tyApp ioT clientT))++     let serviceClientD = valDecl_ $+              functionS_ clientFuncName [([patVar "client"], clientRecE)]+            where+              clientRecE = foldl+                (\f -> opApp f apOp)+                (apply pureE [ uvar_ serviceName ])+                [ paren (opApp clientRequestE' apOp (registerClientMethodE endpointName))+                | (endpointName, _, _, _, _) <- fieldsD+                ]++              clientRequestE' = apply pureE [ apply clientRequestE [ uvar_ "client" ] ]++              registerClientMethodE endpoint =+                apply clientRegisterMethodE [ uvar_ "client"+                                            , apply methodNameC [ str_ endpoint ]+                                            ]++     pure [ dataDecl_ serviceName+                      [ userTyVar_ synDef (unqual_ GHC.tvName "request")+                      , userTyVar_ synDef (unqual_ GHC.tvName "response")+                      ]+                      [ conDecl ]+                      defaultServiceDeriving++          , serviceServerTypeD+          , serviceServerD++          , serviceClientTypeD+          , serviceClientD+          ]++--------------------------------------------------------------------------------++--+-- * Common Haskell expressions, constructors, and operators+--++unaryHandlerC, clientStreamHandlerC, serverStreamHandlerC, biDiStreamHandlerC,+  methodNameC, defaultOptionsE, serverLoopE, convertServerHandlerE,+  convertServerReaderHandlerE, convertServerWriterHandlerE,+  convertServerRWHandlerE, clientRegisterMethodE, clientRequestE :: HsExp++unaryHandlerC               = var_ (grpcName dataName "UnaryHandler")+clientStreamHandlerC        = var_ (grpcName dataName "ClientStreamHandler")+serverStreamHandlerC        = var_ (grpcName dataName "ServerStreamHandler")+biDiStreamHandlerC          = var_ (grpcName dataName "BiDiStreamHandler")+methodNameC                 = var_ (grpcName tcName "MethodName")+defaultOptionsE             = var_ (grpcName varName "defaultOptions")+serverLoopE                 = var_ (grpcName varName "serverLoop")+convertServerHandlerE       = var_ (grpcName varName "convertGeneratedServerHandler")+convertServerReaderHandlerE = var_ (grpcName varName "convertGeneratedServerReaderHandler")+convertServerWriterHandlerE = var_ (grpcName varName "convertGeneratedServerWriterHandler")+convertServerRWHandlerE     = var_ (grpcName varName "convertGeneratedServerRWHandler")+clientRegisterMethodE       = var_ (grpcName varName "clientRegisterMethod")+clientRequestE              = var_ (grpcName varName "clientRequest")++biDiStreamingC, serverStreamingC, clientStreamingC, normalC, serviceOptionsC,+  ioActionT, serverRequestT, serverResponseT, clientRequestT, clientResultT,+  ioT, grpcClientT :: HsType+biDiStreamingC   = typeNamed_ (qual_ grpcModule dataName "BiDiStreaming")+serverStreamingC = typeNamed_ (qual_ grpcModule dataName "ServerStreaming")+clientStreamingC = typeNamed_ (qual_ grpcModule dataName "ClientStreaming")+normalC          = typeNamed_ (qual_ grpcModule dataName "Normal")+serviceOptionsC  = typeNamed_ (qual_ grpcModule tcName "ServiceOptions")+serverRequestT   = typeNamed_ (grpcName tcName "ServerRequest")+serverResponseT  = typeNamed_ (grpcName tcName "ServerResponse")+clientRequestT   = typeNamed_ (grpcName tcName "ClientRequest")+clientResultT    = typeNamed_ (grpcName tcName "ClientResult")+grpcClientT      = typeNamed_ (grpcName tcName "Client")+ioActionT        = tyApp ioT (tupleType_ [])+ioT              = typeNamed_ (haskellName tcName "IO")++grpcModule :: GHC.ModuleName+grpcModule = GHC.mkModuleName "HsGRPC"++-- ** Expressions for protobuf-wire types++forceEmitE :: HsExp -> HsExp+forceEmitE = paren . app forceEmitC++fieldNumberE :: FieldNumber -> HsExp+fieldNumberE = paren . app fieldNumberC . intE . getFieldNumber++dpIdentE :: DotProtoIdentifier -> HsExp+dpIdentE (Single n) = apply singleC [ str_ n ]+dpIdentE (Dots (Path (n NE.:| ns))) =+  apply dotsC [ apply pathC [ paren (opApp (str_ n) neConsOp (list_ (map str_ ns))) ] ]+dpIdentE (Qualified a b)  = apply qualifiedC [ dpIdentE a, dpIdentE b ]+dpIdentE Anonymous        = anonymousC++dpValueE :: DotProtoValue -> HsExp+dpValueE (Identifier nm) = apply identifierC [ dpIdentE nm ]+dpValueE (StringLit s)   = apply stringLitC  [ str_ s ]+dpValueE (IntLit i)      = apply intLitC     [ intE i ]+dpValueE (FloatLit f)    = apply floatLitC   [ floatE f ]+dpValueE (BoolLit True)  = apply boolLitC    [ trueC ]+dpValueE (BoolLit False) = apply boolLitC    [ falseC ]++optionE :: DotProtoOption -> HsExp+optionE (DotProtoOption name value) =+  apply dotProtoOptionC [ dpIdentE name, dpValueE value ]++-- | Translate a dot proto type to its Haskell AST type+dpTypeE :: DotProtoType -> HsExp+dpTypeE (Prim p)           = apply primC           [ dpPrimTypeE p ]+dpTypeE (Optional p)       = apply optionalC       [ dpPrimTypeE p ]+dpTypeE (Repeated p)       = apply repeatedC       [ dpPrimTypeE p ]+dpTypeE (NestedRepeated p) = apply nestedRepeatedC [ dpPrimTypeE p ]+dpTypeE (Map k v)          = apply mapC            [ dpPrimTypeE k, dpPrimTypeE v]+++-- | Translate a dot proto primitive type to a Haskell AST primitive type.+dpPrimTypeE :: DotProtoPrimType -> HsExp+dpPrimTypeE ty =+    let wrap = var_ . protobufASTName dataName in+    case ty of+        Named n  -> apply namedC [ dpIdentE n ]+        Int32    -> wrap "Int32"+        Int64    -> wrap "Int64"+        SInt32   -> wrap "SInt32"+        SInt64   -> wrap "SInt64"+        UInt32   -> wrap "UInt32"+        UInt64   -> wrap "UInt64"+        Fixed32  -> wrap "Fixed32"+        Fixed64  -> wrap "Fixed64"+        SFixed32 -> wrap "SFixed32"+        SFixed64 -> wrap "SFixed64"+        String   -> wrap "String"+        Bytes    -> wrap "Bytes"+        Bool     -> wrap "Bool"+        Float    -> wrap "Float"+        Double   -> wrap "Double"++defaultImports ::+  ( (?stringType :: StringType)+  , (?typeLevelFormat :: Bool)+  ) =>+  -- | Uses GRPC?+  Bool ->+  [HsImportDecl]+defaultImports icUsesGrpc | StringType stringModule stringType <- ?stringType =+    [ importDecl_ (m "Prelude")               & qualified haskellNS  & everything+    , importDecl_ (m "Proto3.Suite.Class")    & qualified protobufNS & everything+#ifdef DHALL+    , importDecl_ (m "Proto3.Suite.DhallPB")  & qualified (m hsDhallPB) & everything+#endif+    , importDecl_ (m "Proto3.Suite.DotProto") & qualified protobufASTNS & everything+    , importDecl_ (m "Proto3.Suite.JSONPB")   & qualified jsonpbNS   & everything+    , importDecl_ (m "Proto3.Suite.JSONPB")   & unqualified          & selecting  [s".=", s".:"]+    , importDecl_ (m "Proto3.Suite.Types")    & qualified protobufNS & everything+    , importDecl_ (m "Proto3.Wire")           & qualified protobufNS & everything+    , importDecl_ (m "Proto3.Wire.Decode")    & qualified protobufNS & selecting  [i"Parser", i"RawField"]+    , importDecl_ (m "Control.Applicative")   & qualified haskellNS  & everything+    , importDecl_ (m "Control.Applicative")   & unqualified          & selecting  [s"<*>", s"<|>", s"<$>"]+    , importDecl_ (m "Control.DeepSeq")       & qualified haskellNS  & everything+    , importDecl_ (m "Control.Monad")         & qualified haskellNS  & everything+    , importDecl_ (m "Data.ByteString")       & qualified haskellNS  & everything+    , importDecl_ (m "Data.Coerce")           & qualified haskellNS  & everything+    , importDecl_ (m "Data.Int")              & qualified haskellNS  & selecting  [i"Int16", i"Int32", i"Int64"]+    , importDecl_ (m "Data.List.NonEmpty")    & qualified haskellNS  & selecting  [ieNameAll_ (unqual_ tcName "NonEmpty")]+    , importDecl_ (m "Data.Map")              & qualified haskellNS  & selecting  [i"Map", i"mapKeysMonotonic"]+    , importDecl_ (m "Data.Proxy")            & qualified proxyNS    & everything+    , importDecl_ (m "Data.String")           & qualified haskellNS  & selecting  [i"fromString"]+    , importDecl_ (m stringModule)            & qualified haskellNS  & selecting  [i stringType]+    , importDecl_ (m "Data.Vector")           & qualified haskellNS  & selecting  [i"Vector"]+    , importDecl_ (m "Data.Word")             & qualified haskellNS  & selecting  [i"Word16", i"Word32", i"Word64"]+    , importDecl_ (m "GHC.Enum")              & qualified haskellNS  & everything+    , importDecl_ (m "GHC.Generics")          & qualified haskellNS  & everything+    , importDecl_ (m "Google.Protobuf.Wrappers.Polymorphic") & qualified protobufNS & selecting [ieNameAll_ (unqual_ tcName "Wrapped")]+    , importDecl_ (m "Unsafe.Coerce")         & qualified haskellNS  & everything+    ]+    <>+    (if not icUsesGrpc then [] else+    [ importDecl_ (m "Network.GRPC.HighLevel.Generated")           & alias grpcNS & everything+    , importDecl_ (m "Network.GRPC.HighLevel.Client")              & alias grpcNS & everything+    , importDecl_ (m "Network.GRPC.HighLevel.Server")              & alias grpcNS & hiding    [i"serverLoop"]+    , importDecl_ (m "Network.GRPC.HighLevel.Server.Unregistered") & alias grpcNS & selecting [i"serverLoop"]+    ])+    <>+    ( if not ?typeLevelFormat then [] else+    [ importDecl_ (m "Proto3.Suite.Form") & qualified protobufFormNS & everything+    , importDecl_ (m "GHC.TypeLits")      & qualified haskellNS      & selecting [i"Nat", i"Symbol", i"TypeError"]+    ])+  where+    m = GHC.mkModuleName+    i n = ieName_ (unqual_ (if foldr (const . isLower) True n then varName else tcName) n)+    s n = ieName_ (unqual_ varName n)++    grpcNS                    = m "HsGRPC"+    jsonpbNS                  = m "HsJSONPB"+    protobufNS                = m "HsProtobuf"+    protobufASTNS             = m "HsProtobufAST"+    proxyNS                   = m "Proxy"++    -- staged constructors for importDecl+    qualified :: Module -> (Bool -> Maybe Module -> a)  -> a+    qualified m' f = f True (Just m')++    unqualified :: (Bool -> Maybe Module -> a) -> a+    unqualified f = f False Nothing++    -- import unqualified AND also under a namespace+    alias :: Module -> (Bool -> Maybe Module -> a) -> a+    alias m' f = f False (Just m')++    selecting :: [HsImportSpec] -> (Maybe (Bool, [HsImportSpec]) -> a) -> a+    selecting is f = f (Just (False, is))++    hiding :: [HsImportSpec] -> (Maybe (Bool, [HsImportSpec]) -> a) -> a+    hiding is f =  f (Just (True, is))++    everything :: (Maybe (Bool, [HsImportSpec]) -> a) -> a+    everything f = f Nothing++defaultMessageDeriving :: [HsQName]+defaultMessageDeriving = map (haskellName tcName) [ "Show", "Eq", "Ord", "Generic" ]++defaultEnumDeriving :: [HsQName]+defaultEnumDeriving = map (haskellName tcName) [ "Show", "Eq", "Generic", "NFData" ]++defaultServiceDeriving :: [HsQName]+defaultServiceDeriving = map (haskellName tcName) [ "Generic" ]
− src/Proto3/Suite/DotProto/Generate/LargeRecord.hs
@@ -1,22 +0,0 @@-{- | This module provides functions to generate Haskell records using-   the large-records library.--}-module Proto3.Suite.DotProto.Generate.LargeRecord where--import Language.Haskell.Syntax-import Proto3.Suite.DotProto.Generate.Syntax--isLargeRecord :: HsDecl -> Bool-isLargeRecord (HsDataDecl _ _ _ _ [HsRecDecl _ _ (_fld1:_fld2:_)] _) = True-isLargeRecord _ = False---- | Generate 'NFData' instance for a type using large-generics-nfDataInstD :: HsDecl -> String -> HsDecl-nfDataInstD typeDecl typeName =-  instDecl_ (haskellName "NFData")-      [ type_ typeName ]-      [ HsFunBind [rnfDecl] | isLargeRecord typeDecl ]-  where-    rnfDecl = match_ (HsIdent "rnf") []-                     (HsUnGuardedRhs (HsVar (lrName "grnf")))-                     []
src/Proto3/Suite/DotProto/Generate/Record.hs view
@@ -1,14 +1,12 @@-{- | This module provides functions to generate regular Haskell records-   without using the large-records library.--}+-- | This module provides functions to generate Haskell records module Proto3.Suite.DotProto.Generate.Record where -import Language.Haskell.Syntax+import GHC.Types.Name.Occurrence (tcName) import Proto3.Suite.DotProto.Generate.Syntax --- | Generate 'NFData' instance for a type using GHC generics+-- | Generate `Control.DeepSeq.NFData` instance for a type using GHC generics nfDataInstD :: HsDecl -> String -> HsDecl nfDataInstD _ typeName =-  instDecl_ (haskellName "NFData")-      [ type_ typeName ]-      []+  instDecl_ (haskellName tcName "NFData")+            [ type_ typeName ]+            []
src/Proto3/Suite/DotProto/Generate/Swagger.hs view
@@ -59,6 +59,10 @@ -- Zig-zag encoding issues do not matter to JSONPB. deriving newtype instance ToSchema a => ToSchema (Signed a) +-- `Proto3.Suite.Types.ForceEmit` affects the binary format, not the JSONPB schema, but+-- that might change if we find a way to express the meaning of omission in such a schema.+deriving newtype instance ToSchema a => ToSchema (Proto3.Suite.Types.ForceEmit a)+ -- Packed/unpacked distinctions do not matter to JSONPB. deriving via (V.Vector a) instance ToSchema a => ToSchema (NestedVec a) deriving via (V.Vector a) instance ToSchema a => ToSchema (PackedVec a)
src/Proto3/Suite/DotProto/Generate/Syntax.hs view
@@ -1,178 +1,1213 @@-{-| Utilities to manipulate Haskell AST -}-module Proto3.Suite.DotProto.Generate.Syntax where--import Language.Haskell.Syntax--haskellName, jsonpbName, grpcName, lrName, protobufName, protobufASTName, proxyName :: String -> HsQName-haskellName  name = Qual (Module "Hs")         (HsIdent name)-jsonpbName   name = Qual (Module "HsJSONPB")   (HsIdent name)-grpcName     name = Qual (Module "HsGRPC")     (HsIdent name)-lrName       name = Qual (Module "LR")         (HsIdent name)-protobufName name = Qual (Module "HsProtobuf") (HsIdent name)-protobufASTName name = Qual (Module "HsProtobufAST") (HsIdent name)-proxyName    name = Qual (Module "Proxy")      (HsIdent name)--haskellNS :: Module-haskellNS = Module "Hs"---------------------------------------------------------------------------------------- * Wrappers around haskell-src-exts constructors-----apply :: HsExp -> [HsExp] -> HsExp-apply f = paren . foldl HsApp f--maybeModify :: HsExp -> Maybe HsExp -> HsExp-maybeModify x Nothing = x-maybeModify x (Just f) = paren (HsApp f (paren x))--paren :: HsExp -> HsExp-paren e@(HsParen _) = e-paren e = HsParen e--applicativeApply :: HsExp -> [HsExp] -> HsExp-applicativeApply f = foldl snoc nil-  where-    nil = HsApp pureE f--    snoc g x = HsInfixApp g apOp x--tyApp :: HsType -> [HsType] -> HsType-tyApp = foldl HsTyApp--module_ :: Module -> Maybe [HsExportSpec] -> [HsImportDecl] -> [HsDecl] -> HsModule-module_ = HsModule defaultSrcLoc--importDecl_ :: Module -> Bool -> Maybe Module -> Maybe (Bool, [HsImportSpec]) -> HsImportDecl-importDecl_ = HsImportDecl defaultSrcLoc--dataDecl_ :: String -> [HsConDecl] -> [HsQName] -> HsDecl-dataDecl_ messageName [constructor@(HsRecDecl _ _ [_])] =-  HsNewTypeDecl defaultSrcLoc [] (HsIdent messageName) [] constructor-dataDecl_ messageName constructors =-  HsDataDecl defaultSrcLoc [] (HsIdent messageName) [] constructors--recDecl_ :: HsName -> [([HsName], HsBangType)] -> HsConDecl-recDecl_ = HsRecDecl defaultSrcLoc--conDecl_ :: HsName -> [HsBangType] -> HsConDecl-conDecl_ = HsConDecl defaultSrcLoc--instDecl_ :: HsQName -> [HsType] -> [HsDecl] -> HsDecl-instDecl_ = HsInstDecl defaultSrcLoc []--match_ :: HsName -> [HsPat] -> HsRhs -> [HsDecl] -> HsMatch-match_ = HsMatch defaultSrcLoc--unqual_ :: String -> HsQName-unqual_ = UnQual . HsIdent--uvar_ :: String -> HsExp-uvar_ = HsVar . unqual_--protobufType_, primType_, protobufStringType_, protobufBytesType_ :: String -> HsType-protobufType_ = HsTyCon . protobufName-primType_ = HsTyCon . haskellName-protobufStringType_ = HsTyApp (protobufType_ "String") . HsTyCon . haskellName-protobufBytesType_ = HsTyApp (protobufType_ "Bytes") . HsTyCon . haskellName--protobufFixedType_, protobufSignedType_, protobufWrappedType_ :: HsType -> HsType-protobufFixedType_ = HsTyApp (protobufType_ "Fixed")-protobufSignedType_ = HsTyApp (protobufType_ "Signed")-protobufWrappedType_ = HsTyApp (HsTyCon (protobufName "Wrapped"))--type_ :: String -> HsType-type_ = HsTyCon . unqual_--patVar :: String -> HsPat-patVar =  HsPVar . HsIdent--alt_ :: HsPat -> HsGuardedAlts -> [HsDecl] -> HsAlt-alt_ = HsAlt defaultSrcLoc--str_ :: String -> HsExp-str_ = HsLit . HsString---- | For some reason, haskell-src-exts needs this 'SrcLoc' parameter---   for some data constructors. Its value does not affect---   pretty-printed output-defaultSrcLoc :: SrcLoc-defaultSrcLoc = SrcLoc "<generated>" 0 0---------------------------------------------------------------------------------------- * Common Haskell expressions, constructors, and operators-----dotProtoFieldC, primC, repeatedC, nestedRepeatedC, namedC, mapC,-  fieldNumberC, singleC, dotsC, pathC, qualifiedC, anonymousC, dotProtoOptionC,-  identifierC, stringLitC, intLitC, floatLitC, boolLitC, trueC, falseC, nothingC,-  justC, forceEmitC,  encodeMessageFieldE, fromStringE, decodeMessageFieldE,-  pureE, returnE, mappendE, memptyE, msumE, atE, oneofE, fmapE :: HsExp--dotProtoFieldC       = HsVar (protobufASTName "DotProtoField")-primC                = HsVar (protobufASTName "Prim")-repeatedC            = HsVar (protobufASTName "Repeated")-nestedRepeatedC      = HsVar (protobufASTName "NestedRepeated")-namedC               = HsVar (protobufASTName "Named")-mapC                 = HsVar (protobufASTName "Map")-fieldNumberC         = HsVar (protobufName "FieldNumber")-singleC              = HsVar (protobufASTName "Single")-pathC                = HsVar (protobufASTName "Path")-dotsC                = HsVar (protobufASTName "Dots")-qualifiedC           = HsVar (protobufASTName "Qualified")-anonymousC           = HsVar (protobufASTName "Anonymous")-dotProtoOptionC      = HsVar (protobufASTName "DotProtoOption")-identifierC          = HsVar (protobufASTName "Identifier")-stringLitC           = HsVar (protobufASTName "StringLit")-intLitC              = HsVar (protobufASTName "IntLit")-floatLitC            = HsVar (protobufASTName "FloatLit")-boolLitC             = HsVar (protobufASTName "BoolLit")-forceEmitC           = HsVar (protobufName "ForceEmit")-encodeMessageFieldE  = HsVar (protobufName "encodeMessageField")-decodeMessageFieldE  = HsVar (protobufName "decodeMessageField")-atE                  = HsVar (protobufName "at")-oneofE               = HsVar (protobufName "oneof")--trueC                = HsVar (haskellName "True")-falseC               = HsVar (haskellName "False")-nothingC             = HsVar (haskellName "Nothing")-justC                = HsVar (haskellName "Just")-fromStringE          = HsVar (haskellName "fromString")-pureE                = HsVar (haskellName "pure")-returnE              = HsVar (haskellName "return")-mappendE             = HsVar (haskellName "mappend")-memptyE              = HsVar (haskellName "mempty")-msumE                = HsVar (haskellName "msum")-fmapE                = HsVar (haskellName "fmap")--apOp :: HsQOp-apOp  = HsQVarOp (UnQual (HsSymbol "<*>"))--fmapOp :: HsQOp-fmapOp  = HsQVarOp (UnQual (HsSymbol "<$>"))--composeOp :: HsQOp-composeOp = HsQVarOp (Qual haskellNS (HsSymbol "."))--bindOp :: HsQOp-bindOp = HsQVarOp (Qual haskellNS (HsSymbol ">>="))--altOp :: HsQOp-altOp = HsQVarOp (UnQual (HsSymbol "<|>"))--toJSONPBOp :: HsQOp-toJSONPBOp = HsQVarOp (UnQual (HsSymbol ".="))--parseJSONPBOp :: HsQOp-parseJSONPBOp = HsQVarOp (UnQual (HsSymbol ".:"))--neConsOp :: HsQOp-neConsOp = HsQVarOp (Qual haskellNS (HsSymbol ":|"))--intE :: Integral a => a -> HsExp-intE x = (if x < 0 then HsParen else id) . HsLit . HsInt . fromIntegral $ x--intP :: Integral a => a -> HsPat-intP x = (if x < 0 then HsPParen else id) . HsPLit . HsInt . fromIntegral $ x+{-# LANGUAGE CPP #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE NegativeLiterals #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TupleSections #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ViewPatterns #-}++{-| Utilities to manipulate Haskell AST -}+module Proto3.Suite.DotProto.Generate.Syntax where++import Data.Functor ((<&>))+import Data.Maybe (maybeToList)+#if !MIN_VERSION_ghc_lib_parser(9,12,0)+import GHC.Data.Bag (listToBag)+#endif+import GHC.Data.FastString (mkFastString)+import qualified GHC.Hs as GHC+         (HsDecl(..), HsDerivingClause(..), HsModule(..), HsTyVarBndr(..), HsType(..))++import GHC.Types.Basic (Origin(..))+import GHC.Types.Name.Occurrence (NameSpace, dataName, mkOccName, tcName, tvName, varName)+import GHC.Types.Name.Reader (mkRdrQual, mkRdrUnqual, rdrNameSpace)+import GHC.Types.SrcLoc (GenLocated(..), SrcSpan, generatedSrcSpan)++#if MIN_VERSION_ghc_lib_parser(9,10,0)+import GHC.Types.Basic (GenReason(OtherExpansion))+#endif+#if MIN_VERSION_ghc_lib_parser(9,8,0)+import Control.Arrow ((***))+import Data.Bool (bool)+import Data.Ratio ((%))+import Data.Void (Void)+import GHC.Hs hiding (HsBind, HsDecl, HsDerivingClause, HsOuterFamEqnTyVarBndrs,+                      HsOuterSigTyVarBndrs, HsTyVarBndr, HsType)+import qualified GHC.Hs as GHC (HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs)+import GHC.Types.Basic (DoPmc(..), TopLevelFlag(..))+import GHC.Types.Fixity (LexicalFixity(..))+import GHC.Types.PkgQual (RawPkgQual(..))+import GHC.Types.SourceText+         (IntegralLit(..), FractionalExponentBase(..), FractionalLit(..), SourceText(..))+#elif MIN_VERSION_ghc_lib_parser(9,6,0)+import Control.Arrow ((***))+import Data.Bool (bool)+import Data.Ratio ((%))+import Data.Void (Void)+import GHC.Hs hiding (HsBind, HsDecl, HsDerivingClause, HsOuterFamEqnTyVarBndrs,+                      HsOuterSigTyVarBndrs, HsTyVarBndr, HsType)+import qualified GHC.Hs as GHC (HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs)+import GHC.Types.Basic (TopLevelFlag(..))+import GHC.Types.Fixity (LexicalFixity(..))+import GHC.Types.PkgQual (RawPkgQual(..))+import GHC.Types.SourceText+         (IntegralLit(..), FractionalExponentBase(..), FractionalLit(..), SourceText(..))+#elif MIN_VERSION_ghc_lib_parser(9,4,0)+import Data.Ratio ((%))+import Data.Void (Void)+import GHC.Hs hiding (HsBind, HsDecl, HsDerivingClause, HsOuterFamEqnTyVarBndrs,+                      HsOuterSigTyVarBndrs, HsTyVarBndr, HsType)+import qualified GHC.Hs as GHC (HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs)+import GHC.Types.Basic (PromotionFlag(..), TopLevelFlag(..))+import GHC.Types.Fixity (LexicalFixity(..))+import GHC.Types.PkgQual (RawPkgQual(..))+import GHC.Types.SourceText+         (IntegralLit(..), FractionalExponentBase(..), FractionalLit(..), SourceText(..))+import GHC.Types.SrcLoc (LayoutInfo(..))+import GHC.Unit (IsBootInterface(..))+import GHC.Unit.Module (ModuleName, mkModuleName)+#else+import Data.Ratio ((%))+import Data.Void (Void)+import GHC.Hs hiding (HsBind, HsDecl, HsDerivingClause, HsOuterFamEqnTyVarBndrs,+                      HsOuterSigTyVarBndrs, HsTyVarBndr, HsType)+import qualified GHC.Hs as GHC (HsOuterFamEqnTyVarBndrs, HsOuterSigTyVarBndrs)+import GHC.Types.Basic (PromotionFlag(..), TopLevelFlag(..))+import GHC.Types.Fixity (LexicalFixity(..))+import GHC.Types.SourceText+         (IntegralLit(..), FractionalExponentBase(..), FractionalLit(..), SourceText(..))+import GHC.Types.SrcLoc (LayoutInfo(..), noLoc)+import GHC.Unit (IsBootInterface(..))+import GHC.Unit.Module (ModuleName, mkModuleName)+#endif++#if MIN_VERSION_base(4,16,0)+import GHC.Exts (considerAccessible)+#endif++type HsAlt = LMatch GhcPs HsExp+type HsBangType = LBangType GhcPs+type HsBind = LHsBind GhcPs+type HsConDecl = LConDecl GhcPs+type HsDecl = LHsDecl GhcPs+type HsDerivStrategy = LDerivStrategy GhcPs+type HsDerivingClause = LHsDerivingClause GhcPs+type HsExp = LHsExpr GhcPs+type HsExportSpec = LIE GhcPs+type HsGrhs = LGRHS GhcPs HsExp+type HsGuardedAlts = GRHSs GhcPs HsExp+type HsImportDecl = LImportDecl GhcPs+type HsImportSpec = LIE GhcPs+type HsMatch = LMatch GhcPs HsExp+type HsName = LIdP GhcPs+type HsOuterFamEqnTyVarBndrs = GHC.HsOuterFamEqnTyVarBndrs GhcPs+type HsOuterSigTyVarBndrs = GHC.HsOuterSigTyVarBndrs GhcPs+type HsPat = LPat GhcPs+type HsQName = LIdP GhcPs+type HsQOp = LHsExpr GhcPs+type HsSig = LSig GhcPs+type HsTyVarBndrU = LHsTyVarBndr () GhcPs+type HsTyVarBndrV = LHsTyVarBndr+#if MIN_VERSION_ghc_lib_parser(9,8,0)+                                 (HsBndrVis GhcPs)+#else+                                 ()+#endif+                                                   GhcPs+type HsType = LHsType GhcPs+type Module = ModuleName++#if MIN_VERSION_ghc_lib_parser(9,10,0)++pattern VirtualBraces :: Int -> EpLayout+pattern VirtualBraces indentation = EpVirtualBraces indentation++#endif++class SyntaxDefault a+  where+    synDef :: a++instance SyntaxDefault ()+  where+    synDef = ()++instance (SyntaxDefault a, SyntaxDefault b, SyntaxDefault c) => SyntaxDefault (a, b, c)+  where+    synDef = (synDef, synDef, synDef)++instance SyntaxDefault (Maybe a)+  where+    synDef = Nothing++instance SyntaxDefault [a]+  where+    synDef = []++instance (SyntaxDefault a, SyntaxDefault b) => SyntaxDefault (a, b)+  where+    synDef = (synDef, synDef)++instance SyntaxDefault NoExtField+  where+    synDef = NoExtField++instance SyntaxDefault SourceText+  where+    synDef = NoSourceText++instance SyntaxDefault SrcSpan+  where+    synDef = generatedSrcSpan++#if MIN_VERSION_ghc_lib_parser(9,10,0)++instance SyntaxDefault AnnParen+  where+    synDef = noAnn++instance SyntaxDefault AnnPragma+  where+    synDef = noAnn++instance SyntaxDefault AnnSig+  where+    synDef = noAnn++instance SyntaxDefault AnnsIf+  where+    synDef = noAnn++instance SyntaxDefault (AnnSortKey tag)+  where+    synDef = NoAnnSortKey++instance NoAnn a => SyntaxDefault (EpAnn a)+  where+    synDef = noAnn++instance SyntaxDefault EpAnnHsCase+  where+    synDef = noAnn++instance SyntaxDefault (EpToken token)+  where+    synDef = NoEpTok++instance SyntaxDefault (EpUniToken token utoken)+  where+    synDef = NoEpUniTok++instance SyntaxDefault (HsBndrVis GhcPs)+  where+    synDef = HsBndrRequired synDef++#endif++#if MIN_VERSION_ghc_lib_parser(9,8,0) && !MIN_VERSION_ghc_lib_parser(9,10,0)++instance SyntaxDefault (HsBndrVis GhcPs)+  where+    synDef = HsBndrRequired++#endif++#if MIN_VERSION_ghc_lib_parser(9,4,0)++instance SyntaxDefault a => SyntaxDefault (GenLocated TokenLocation a)+  where+    synDef = L NoTokenLoc synDef++#endif++#if MIN_VERSION_ghc_lib_parser(9,4,0) && !MIN_VERSION_ghc_lib_parser(9,10,0)++instance SyntaxDefault (SrcAnn a)+  where+    synDef = noSrcSpanA++instance SyntaxDefault (HsToken tok)+  where+    synDef = HsTok++instance SyntaxDefault (HsUniToken tok utok)+  where+    synDef = HsNormalTok++#else++instance SyntaxDefault IsUnicodeSyntax+  where+    synDef = NormalSyntax++#endif++pattern PfxCon :: [arg] -> HsConDetails Void arg r+pattern PfxCon args = PrefixCon [] args++#if !MIN_VERSION_ghc_lib_parser(9,10,0)++instance SyntaxDefault e => SyntaxDefault (GenLocated (SrcAnn a) e)+  where+    synDef = noLocA synDef++instance SyntaxDefault (EpAnn a)+  where+    synDef = EpAnnNotUsed++instance SyntaxDefault EpAnnComments+  where+    synDef = emptyComments++instance SyntaxDefault AnnSortKey+  where+    synDef = NoAnnSortKey++#endif++#if !MIN_VERSION_ghc_lib_parser(9,4,0)++dataConCantHappen :: NoExtCon -> a+dataConCantHappen = noExtCon++#endif++haskellName, jsonpbName, grpcName, lrName, protobufName,+  protobufASTName, protobufFormName, proxyName ::+  NameSpace -> String -> HsQName+haskellName      = qual_ haskellNS+jsonpbName       = qual_ (mkModuleName "HsJSONPB")+grpcName         = qual_ (mkModuleName "HsGRPC")+lrName           = qual_ (mkModuleName "LR")+protobufName     = qual_ (mkModuleName "HsProtobuf")+protobufASTName  = qual_ (mkModuleName "HsProtobufAST")+protobufFormName = qual_ protobufFormNS+proxyName        = qual_ (mkModuleName "Proxy")++haskellNS :: ModuleName+haskellNS = mkModuleName "Hs"++protobufFormNS :: ModuleName+protobufFormNS = mkModuleName "HsProtobufForm"++protobufFormType :: NameSpace -> String -> HsType+protobufFormType ns = typeNamed_ . protobufFormName ns++formProtoTypeT :: HsType+formProtoTypeT = protobufFormType tcName "ProtoType"++formNamesOf, formNumberOf, formOneOfOf, formCardinalityOf, formProtoTypeOf :: HsQName+formNamesOf = protobufFormName tcName "NamesOf"+formNumberOf = protobufFormName tcName "NumberOf"+formOneOfOf = protobufFormName tcName "OneOfOf"+formCardinalityOf = protobufFormName tcName "CardinalityOf"+formProtoTypeOf = protobufFormName tcName "ProtoTypeOf"++formFieldNotFound, formFieldOrOneOfNotFound :: HsType+formFieldNotFound = protobufFormType tcName "FieldNotFound"+formFieldOrOneOfNotFound = protobufFormType tcName "FieldOrOneOfNotFound"++formUnpackedT, formPackedT :: HsType+formUnpackedT = protobufFormType dataName "Unpacked"+formPackedT = protobufFormType dataName "Packed"++formCardinalityT, formImplicitT, formOptionalT, formRepeatedT :: HsType+formCardinalityT = protobufFormType tcName "Cardinality"+formImplicitT = protobufFormType dataName "Implicit"+formOptionalT = protobufFormType dataName "Optional"+formRepeatedT = protobufFormType dataName "Repeated"++formInt32T, formInt64T, formSInt32T, formSInt64T, formUInt32T, formUInt64T,+  formFixed32T, formFixed64T, formSFixed32T, formSFixed64T,+  formStringT, formBytesT, formBoolT, formFloatT, formDoubleT,+  formEnumerationT, formMessageT, formMapT :: HsType+formInt32T = protobufFormType dataName "Int32"+formInt64T = protobufFormType dataName "Int64"+formSInt32T = protobufFormType dataName "SInt32"+formSInt64T = protobufFormType dataName "SInt64"+formUInt32T = protobufFormType dataName "UInt32"+formUInt64T = protobufFormType dataName "UInt64"+formFixed32T = protobufFormType dataName "Fixed32"+formFixed64T = protobufFormType dataName "Fixed64"+formSFixed32T = protobufFormType dataName "SFixed32"+formSFixed64T = protobufFormType dataName "SFixed64"+formStringT = protobufFormType dataName "String"+formBytesT = protobufFormType dataName "Bytes"+formBoolT = protobufFormType dataName "Bool"+formFloatT = protobufFormType dataName "Float"+formDoubleT = protobufFormType dataName "Double"+formEnumerationT = protobufFormType dataName "Enumeration"+formMessageT = protobufFormType dataName "Message"+formMapT = protobufFormType dataName "Map"++formWrapperT :: HsType+formWrapperT = protobufFormType tcName "Wrapper"++--------------------------------------------------------------------------------+--+-- * Wrappers around ghc constructors+--++app :: HsExp -> HsExp -> HsExp+app f x = mkHsApp f (paren x)++apply :: HsExp -> [HsExp] -> HsExp+apply f xs = mkHsApps f (map paren xs)++appAt :: HsExp -> HsType -> HsExp+appAt f t = noLocA (HsAppType synDef f+#if MIN_VERSION_ghc_lib_parser(9,6,0) && !MIN_VERSION_ghc_lib_parser(9,10,0)+                                       synDef+#endif+                                              (HsWC NoExtField (parenTy t)))++applyAt :: HsExp -> [HsType] -> HsExp+applyAt f = paren . foldl appAt f++opApp :: HsExp -> HsQOp -> HsExp -> HsExp+opApp x op y = noLocA $ OpApp synDef x op y++maybeModify :: HsExp -> Maybe HsExp -> HsExp+maybeModify x Nothing = x+maybeModify x (Just f) = paren (app f x)++paren :: HsExp -> HsExp+paren = mkLHsPar++parenPat :: HsPat -> HsPat+parenPat = mkParPat++parenTy :: HsType -> HsType+parenTy t@(L _ (GHC.HsParTy {})) = t+parenTy t@(L _ (GHC.HsTyVar {})) = t+parenTy t@(L _ (GHC.HsTupleTy {})) = t+parenTy t = nlHsParTy t++applicativeApply :: HsExp -> [HsExp] -> HsExp+applicativeApply f = foldl snoc nil+  where+    nil = apply pureE [f]+    snoc g x = noLocA (OpApp synDef g apOp x)++tyApp :: HsType -> HsType -> HsType+tyApp f = parenTy . mkHsAppTy (parenTy f) . parenTy++tyApply :: HsType -> [HsType] -> HsType+tyApply = foldl tyApp++-- | Whenever @f@ is not itself a type application,+-- @'splitTyApp' ('tyApply' f as) = (f, as)@.+splitTyApp :: HsType -> (HsType, [HsType])+splitTyApp (L _ (GHC.HsParTy _ x)) = splitTyApp x+splitTyApp (L _ (GHC.HsAppTy NoExtField x y)) = (++ [y]) <$> splitTyApp x+splitTyApp x = (x, [])++tyConApp :: HsName -> HsType -> HsType+tyConApp = tyApp . typeNamed_++tyConApply :: HsName -> [HsType] -> HsType+tyConApply = tyApply . typeNamed_++-- | @'splitTyConApp' ('tyApply' (L _ (GHC.HsTyVar _ NotPromoted tc)) as) = Just (tc, as)@.+splitTyConApp :: HsType -> Maybe (HsName, [HsType])+splitTyConApp x = case splitTyApp x of+  (L _ (GHC.HsTyVar _ NotPromoted tc), as) -> Just (tc, as)+  _ -> Nothing++funTy :: HsType -> HsType -> HsType+funTy a b = noLocA (GHC.HsFunTy synDef unrestrictedArrow_ a b)++unrestrictedArrow_ :: HsArrow GhcPs+unrestrictedArrow_ = HsUnrestrictedArrow synDef++unbangedTy_ :: HsType -> HsBangType+#if MIN_VERSION_ghc_lib_parser(9,12,0)+unbangedTy_ = noLocA . GHC.HsBangTy noAnn (HsBang NoSrcUnpack NoSrcStrict) . parenTy+#else+unbangedTy_ = noLocA . GHC.HsBangTy synDef (HsSrcBang synDef NoSrcUnpack NoSrcStrict) . parenTy+#endif++#if MIN_VERSION_ghc_lib_parser(9,6,0)+-- https://hackage.haskell.org/package/ghc-lib-parser-9.6.2.20231121/docs/GHC-Hs.html#t:HsModule+module_ :: ModuleName -> Maybe [HsExportSpec] -> [HsImportDecl] -> [HsDecl] -> GHC.HsModule GhcPs+module_ moduleName maybeExports imports decls =+  GHC.HsModule+  { hsmodExt = XModulePs+    { hsmodAnn = synDef+    , hsmodLayout = VirtualBraces 2+    , hsmodDeprecMessage = Nothing+    , hsmodHaddockModHeader = Nothing+    }+  , hsmodName = Just $ noLocA moduleName+  , hsmodExports = noLocA <$> maybeExports+  , hsmodImports = imports+  , hsmodDecls = decls+  }+#else+-- https://hackage.haskell.org/package/ghc-lib-parser-9.2.2.20220307/docs/GHC-Hs.html#t:HsModule+module_ :: ModuleName -> Maybe [HsExportSpec] -> [HsImportDecl] -> [HsDecl] -> GHC.HsModule+module_ moduleName maybeExports imports decls =+  GHC.HsModule+  { hsmodAnn = synDef+  , hsmodLayout = VirtualBraces 2+  , hsmodName = Just $ noLocA moduleName+  , hsmodExports = noLocA <$> maybeExports+  , hsmodImports = imports+  , hsmodDecls = decls+  , hsmodDeprecMessage = Nothing+  , hsmodHaddockModHeader = Nothing+  }+#endif++importDecl_ ::+  ModuleName ->+  Bool ->+  Maybe ModuleName ->+  Maybe (Bool, [HsImportSpec]) ->+  HsImportDecl+importDecl_ moduleName qualified maybeAs details = noLocA ImportDecl+  {+#if MIN_VERSION_ghc_lib_parser(9,6,0)+    ideclExt = XImportDeclPass+      { ideclAnn = synDef+      , ideclSourceText = synDef+      , ideclImplicit = False+      }+#else+    ideclExt = synDef+  , ideclSourceSrc = NoSourceText+#endif+  , ideclName = noLocA moduleName+  , ideclPkgQual =+#if MIN_VERSION_ghc_lib_parser(9,4,0)+      NoRawPkgQual+#else+      Nothing+#endif+  , ideclSource = NotBoot+  , ideclSafe = False+  , ideclQualified = if qualified then QualifiedPre else NotQualified+#if !MIN_VERSION_ghc_lib_parser(9,6,0)+  , ideclImplicit = False+#endif+  , ideclAs = noLocA <$> maybeAs+#if MIN_VERSION_ghc_lib_parser(9,6,0)+  , ideclImportList = (bool Exactly EverythingBut *** noLocA) <$> details+#else+  , ideclHiding = fmap noLocA <$> details+#endif+  }++ieName_ :: HsName -> HsImportSpec+ieName_ =+  noLocA .+#if MIN_VERSION_ghc_lib_parser(9,10,0)+  flip (IEVar synDef) Nothing .+#else+  IEVar synDef .+#endif+  noLocA .+  IEName+#if MIN_VERSION_ghc_lib_parser(9,6,0)+         synDef+#endif++ieNameAll_ :: HsName -> HsImportSpec+ieNameAll_ =+  noLocA .+#if MIN_VERSION_ghc_lib_parser(9,10,0)+  flip (IEThingAll synDef) Nothing .+#else+  (IEThingAll synDef) .+#endif+  noLocA .+  IEName+#if MIN_VERSION_ghc_lib_parser(9,6,0)+         synDef+#endif++dataDecl_ :: String -> [HsTyVarBndrV] -> [HsConDecl] -> [HsQName] -> HsDecl+dataDecl_ messageName bndrs constructors derivedInstances = noLocA $ GHC.TyClD NoExtField DataDecl+    { tcdDExt = synDef+    , tcdLName = unqual_ tcName messageName+    , tcdTyVars = HsQTvs NoExtField bndrs+    , tcdFixity = Prefix+    , tcdDataDefn = HsDataDefn+#if MIN_VERSION_ghc_lib_parser(9,12,0)+        { dd_ext = noAnn+#else+        { dd_ext = NoExtField+#endif+#if !MIN_VERSION_ghc_lib_parser(9,6,0)+        , dd_ND = maybe DataType (const NewType) newtypeCtor+#endif+        , dd_ctxt = synDef+        , dd_cType = Nothing+        , dd_kindSig = Nothing+        , dd_cons =+#if MIN_VERSION_ghc_lib_parser(9,6,0)+            maybe (DataTypeCons False constructors) NewTypeCon newtypeCtor+#else+            constructors+#endif++        , dd_derivs =+              maybeToList $ derivingClause_ Nothing $ derivedInstances <&> \className ->+                (implicitOuterSigTyVarBinders_, typeNamed_ className)+        }+    }+  where+    -- TO DO: Support GADT syntax, assuming we ever start to use it in generated code.+    newtypeCtor = case constructors of+      [ con@( L _ ( ConDeclH98 { con_forall = False+                               , con_ex_tvs = []+                               , con_mb_cxt = Nothing+                               , con_args = args+                               } ) ) ] -> case args of+        PfxCon [_] -> Just con+        RecCon (L _ [L _ ConDeclField { cd_fld_names = [_] }]) -> Just con+        _ -> Nothing+      _ -> Nothing++recDecl_ :: HsName -> [([HsName], HsBangType)] -> HsConDecl+recDecl_ name fields = noLocA ConDeclH98+#if MIN_VERSION_ghc_lib_parser(9,12,0)+  { con_ext = noAnn+#else+  { con_ext = synDef+#endif+  , con_name = name+  , con_forall = False+  , con_ex_tvs = []+  , con_mb_cxt = Nothing+  , con_args = RecCon $ noLocA $ fields <&> \(names, bangTy) -> noLocA ConDeclField+      { cd_fld_ext = synDef+      , cd_fld_names =+#if MIN_VERSION_ghc_lib_parser(9,4,0)+          noLocA+#else+          noLoc+#endif+          . FieldOcc NoExtField <$> names+      , cd_fld_type = bangTy+      , cd_fld_doc = Nothing+      }+  , con_doc = Nothing+  }++conDecl_ :: HsName -> [HsBangType] -> HsConDecl+conDecl_ name fields = noLocA ConDeclH98+#if MIN_VERSION_ghc_lib_parser(9,12,0)+  { con_ext = noAnn+#else+  { con_ext = synDef+#endif+  , con_name = name+  , con_forall = False+  , con_ex_tvs = []+  , con_mb_cxt = Nothing+  , con_args = PfxCon (HsScaled unrestrictedArrow_ <$> fields)+  , con_doc = Nothing+  }++derivingClause_ ::+  Maybe HsDerivStrategy ->+  [(HsOuterSigTyVarBndrs, HsType)] ->+  Maybe HsDerivingClause+derivingClause_ _ [] = Nothing+derivingClause_ strategy classTypes = Just $ L synDef $+  GHC.HsDerivingClause+    { GHC.deriv_clause_ext = synDef+    , GHC.deriv_clause_strategy = strategy+    , GHC.deriv_clause_tys = noLocA $ DctMulti NoExtField $+        noLocA . uncurry (HsSig NoExtField) <$> classTypes+    }++splitDerivingClause ::+  HsDerivingClause ->+  (Maybe HsDerivStrategy, [(HsOuterSigTyVarBndrs, HsType)])+splitDerivingClause (L _ GHC.HsDerivingClause+                           { GHC.deriv_clause_strategy = strategy+                           , GHC.deriv_clause_tys = L _ clauseTypes+                           }) =+    case clauseTypes of+      DctSingle _ sig -> (strategy, [splitSig sig])+      DctMulti _ sigs -> (strategy, map splitSig sigs)+  where+    splitSig (L _ sig) = case sig of+      HsSig _ binders classType -> (binders, classType)+      XHsSigType impossible+#if MIN_VERSION_base(4,16,0)+        | considerAccessible+            -- We use 'considerAccessible' because GHC 9.4.6 will issue the warning+            -- "Pattern match is redundant" (-Woverlapping-patterns) if we provide+            -- this match *and* use its strict field 'impossible', and yet+            -- if we omit this match then GHC 9.4.6 will issue the warning+            -- "Pattern match(es) are non-exhaustive" (-Wincomplete-patterns).+            -- We cannot avoid the warning without either 'considerAccessible'+            -- or avoiding any use of 'impossible', which would require 'error'+            -- or similar to handle this impossible case match.+#endif+          -> dataConCantHappen impossible++instDecl_ :: HsQName -> [HsType] -> [HsBind] -> HsDecl+instDecl_ className classArgs binds = noLocA $ GHC.InstD NoExtField ClsInstD+  { cid_d_ext = NoExtField+  , cid_inst = ClsInstDecl+#if MIN_VERSION_ghc_lib_parser(9,12,0)+      { cid_ext = (Nothing, noAnn, NoAnnSortKey)+#else+      { cid_ext = synDef+#endif+      , cid_poly_ty = noLocA $ HsSig NoExtField implicitOuterSigTyVarBinders_ (tyConApply className classArgs)+#if MIN_VERSION_ghc_lib_parser(9,12,0)+      , cid_binds = binds+#else+      , cid_binds = listToBag binds+#endif+      , cid_sigs = []+      , cid_tyfam_insts = []+      , cid_datafam_insts = []+      , cid_overlap_mode = Nothing+      }+  }++typeOfInstDecl :: HsDecl -> Maybe (HsOuterSigTyVarBndrs, HsType)+typeOfInstDecl ( L _ ( GHC.InstD _ ClsInstD+                       { cid_inst = ClsInstDecl+                         { cid_poly_ty = L _ (HsSig _ binders classType)+                         } } ) ) =+  Just (binders, classType)+typeOfInstDecl _ =+  Nothing++closedTyFamDecl_ ::+  HsQName ->+  [HsTyVarBndrV] ->+  HsType ->+  [(Maybe [HsTyVarBndrU], [HsType], HsType)] ->+  HsDecl+closedTyFamDecl_ tyFamName famBndrs resultKind eqns =+  noLocA $ GHC.TyClD NoExtField $ FamDecl synDef $ FamilyDecl+#if MIN_VERSION_ghc_lib_parser(9,12,0)+    { fdExt = noAnn+#else+    { fdExt = synDef+#endif+    , fdInfo = ClosedTypeFamily (Just (map onEqn eqns))+    , fdTopLevel = TopLevel+    , fdLName = tyFamName+    , fdTyVars = HsQTvs synDef famBndrs+    , fdFixity = Prefix+    , fdResultSig =+#if MIN_VERSION_ghc_lib_parser(9,4,0)+        noLocA $+#else+        noLoc $+#endif+          KindSig synDef resultKind+    , fdInjectivityAnn = Nothing+    }+  where+    onEqn (eqnBndrs, pats, rhs) = noLocA $+        FamEqn+          { feqn_ext = synDef+          , feqn_tycon = tyFamName+          , feqn_bndrs = maybe (HsOuterImplicit NoExtField) (HsOuterExplicit synDef) eqnBndrs+          , feqn_pats = map+              (HsValArg+#if MIN_VERSION_ghc_lib_parser(9,10,0)+                        synDef+#endif+              ) pats+          , feqn_fixity = Prefix+          , feqn_rhs = rhs+          }++tyFamInstDecl_ :: HsQName -> Maybe [HsTyVarBndrU] -> [HsType] -> HsType -> HsDecl+tyFamInstDecl_ tyFamName bndrs pats rhs = noLocA $ GHC.InstD NoExtField TyFamInstD+  { tfid_ext = NoExtField+  , tfid_inst = TyFamInstDecl+      { tfid_xtn = synDef+      , tfid_eqn = FamEqn+            { feqn_ext = synDef+            , feqn_tycon = tyFamName+            , feqn_bndrs = maybe (HsOuterImplicit NoExtField) (HsOuterExplicit synDef) bndrs+            , feqn_pats = map+                (HsValArg+#if MIN_VERSION_ghc_lib_parser(9,10,0)+                          synDef+#endif+                ) pats+            , feqn_fixity = Prefix+            , feqn_rhs = rhs+            }+      }+  }++-- | 'HsBind' includes a location, and this is one of the few places+-- where we do not need a location.  Rather than distinguishing in+-- the type between bindings that have a location and those that+-- do not, we simply ignore any binding location given here.+valDecl_ :: HsBind -> HsDecl+valDecl_ (L _ b) = noLocA (GHC.ValD NoExtField b)++patBind_ :: HsPat -> HsExp -> HsBind+patBind_ (L _ (VarPat _ nm)) rhs =+  function_ nm [([], rhs)]  -- The comments at 'HsBindLR' say to use 'FunBind'.+patBind_ (L _ (BangPat _ (L _ (VarPat _ nm)))) rhs =+  functionLike_ SrcStrict nm [([], rhs)]  -- The comments at 'HsBindLR' say to use 'FunBind'.+patBind_ (L _ (LazyPat _ (L _ (VarPat _ nm)))) rhs =+  functionLike_ SrcLazy nm [([], rhs)]  -- The comments at 'HsBindLR' say to use 'FunBind'.+patBind_ pat rhs = noLocA PatBind+  { pat_ext = synDef+  , pat_lhs = pat+#if MIN_VERSION_ghc_lib_parser(9,10,0)+  , pat_mult = HsNoMultAnn synDef+#endif+  , pat_rhs = unguardedGRHSs synDef rhs synDef+#if !MIN_VERSION_ghc_lib_parser(9,6,0)+  , pat_ticks = synDef+#endif+  }++-- | @'functionS_' = 'function_' . 'unqual_' 'varName'@+functionS_ :: String -> [([HsPat], HsExp)] -> HsBind+functionS_ = function_ . unqual_ varName++-- | A function with prefix syntax (as opposed to infix).+function_ :: HsName -> [([HsPat], HsExp)] -> HsBind+function_ = functionLike_ NoSrcStrict++functionLike_ :: SrcStrictness -> HsName -> [([HsPat], HsExp)] -> HsBind+functionLike_ strictness name alts = noLocA $ mkFunBind generated name (map match alts)+  where+    generated :: Origin+    generated = Generated+#if MIN_VERSION_ghc_lib_parser(9,10,0)+                          OtherExpansion+#endif+#if MIN_VERSION_ghc_lib_parser(9,8,0)+                                         DoPmc+#endif++    match :: ([HsPat], HsExp) -> HsMatch+#if MIN_VERSION_ghc_lib_parser(9,12,0)+    match (pats, rhs) = mkSimpleMatch ctxt (noLocA pats) rhs+#else+    match (pats, rhs) = mkSimpleMatch ctxt pats rhs+#endif++    ctxt = FunRhs+      { mc_fun = name+      , mc_fixity = Prefix+      , mc_strictness = strictness+#if MIN_VERSION_ghc_lib_parser(9,12,0)+      , mc_an = noAnn+#endif+      }++typeSig_ :: [HsName] -> HsOuterSigTyVarBndrs -> HsType -> HsDecl+typeSig_ nms bndrs ty = noLocA $ GHC.SigD NoExtField $ TypeSig synDef nms $+  HsWC NoExtField $+  noLocA $+  HsSig NoExtField bndrs ty++implicitOuterFamEqnTyVarBinders_ :: HsOuterFamEqnTyVarBndrs+implicitOuterFamEqnTyVarBinders_ = HsOuterImplicit NoExtField++implicitOuterSigTyVarBinders_ :: HsOuterSigTyVarBndrs+implicitOuterSigTyVarBinders_ = HsOuterImplicit NoExtField++userTyVar_ :: flag -> HsName -> LHsTyVarBndr flag GhcPs+#if MIN_VERSION_ghc_lib_parser(9,12,0)+userTyVar_ flag nm = noLocA $ GHC.HsTvb noAnn flag (HsBndrVar NoExtField nm) (HsBndrNoKind NoExtField)+#else+userTyVar_ flag nm = noLocA $ GHC.UserTyVar synDef flag nm+#endif++kindedTyVar_ :: flag -> HsName -> HsType -> LHsTyVarBndr flag GhcPs+#if MIN_VERSION_ghc_lib_parser(9,12,0)+kindedTyVar_ flag nm ty = noLocA $ GHC.HsTvb noAnn flag (HsBndrVar NoExtField nm) (HsBndrKind NoExtField ty)+#else+kindedTyVar_ flag nm ty = noLocA $ GHC.KindedTyVar synDef flag nm ty+#endif++wild_ :: HsPat+wild_ = noLocA $ WildPat NoExtField++qual_ :: ModuleName -> NameSpace -> String -> HsQName+qual_ m ns name = noLocA $ mkRdrQual m (mkOccName ns name)++unqual_ :: NameSpace -> String -> HsName+unqual_ ns name = noLocA $ mkRdrUnqual (mkOccName ns name)++uvar_ :: String -> HsExp+uvar_ = var_ . unqual_ varName++var_ :: HsQName -> HsExp+var_ = noLocA . HsVar NoExtField++fieldBind_ :: HsName -> HsExp -> LHsRecField GhcPs HsExp+fieldBind_ nm val = noLocA+#if MIN_VERSION_ghc_lib_parser(9,4,0)+  HsFieldBind+    { hfbAnn = synDef+    , hfbLHS = noLocA $ FieldOcc NoExtField nm+    , hfbRHS = val+    , hfbPun = False+    }+#else+  HsRecField+    { hsRecFieldAnn = synDef+    , hsRecFieldLbl = noLoc $ FieldOcc NoExtField nm+    , hsRecFieldArg = val+    , hsRecPun = False+    }+#endif++recordCtor_ :: HsName -> [LHsRecField GhcPs HsExp] -> HsExp+recordCtor_ nm fields = noLocA RecordCon+  { rcon_ext = synDef+  , rcon_con = nm+  , rcon_flds = HsRecFields+      { rec_flds = fields+      , rec_dotdot = Nothing+#if MIN_VERSION_ghc_lib_parser(9,12,0)+      , rec_ext = NoExtField+#endif+      }+  }++fieldUpd_ :: HsName -> HsExp -> LHsRecUpdField GhcPs+#if MIN_VERSION_ghc_lib_parser(9,8,0)+                                                     GhcPs+#endif+fieldUpd_ nm val = noLocA+#if MIN_VERSION_ghc_lib_parser(9,4,0)+  HsFieldBind+    { hfbAnn = synDef+#if MIN_VERSION_ghc_lib_parser(9,12,0)+    , hfbLHS = noLocA $ FieldOcc NoExtField nm+#else+    , hfbLHS = noLocA $ Ambiguous NoExtField nm+#endif+    , hfbRHS = val+    , hfbPun = False+    }+#else+  HsRecField+    { hsRecFieldAnn = synDef+    , hsRecFieldLbl = noLoc $ Ambiguous NoExtField nm+    , hsRecFieldArg = val+    , hsRecPun = False+    }+#endif++recordUpd_ :: HsExp -> [ LHsRecUpdField GhcPs+#if MIN_VERSION_ghc_lib_parser(9,8,0)+                                              GhcPs+#endif+                       ] -> HsExp+recordUpd_ r fields = noLocA RecordUpd+  { rupd_ext = synDef+  , rupd_expr = r+  , rupd_flds =+#if MIN_VERSION_ghc_lib_parser(9,8,0)+      RegularRecUpdFields synDef+#else+      Left+#endif+        fields+  }++protobufType_, primType_, protobufStringType_, protobufBytesType_ :: String -> HsType+protobufType_ = typeNamed_ . protobufName tcName+primType_ = typeNamed_ . haskellName tcName+protobufStringType_ = tyApp (protobufType_ "String") . typeNamed_ . haskellName tcName+protobufBytesType_ = tyApp (protobufType_ "Bytes") . typeNamed_ . haskellName tcName++protobufFixedType_, protobufSignedType_, protobufWrappedType_ :: HsType -> HsType+protobufFixedType_ = tyApp (protobufType_ "Fixed")+protobufSignedType_ = tyApp (protobufType_ "Signed")+protobufWrappedType_ = tyApp (protobufType_ "Wrapped")++typeNamed_ :: HsName -> HsType+typeNamed_ nm@(L _ r) = noLocA $ GHC.HsTyVar synDef promotion nm+  where+    promotion+      | rdrNameSpace r == dataName = IsPromoted+      | otherwise = NotPromoted++type_ :: String -> HsType+type_ = typeNamed_ . unqual_ tcName++tvarn_ :: String -> HsName+tvarn_ = unqual_ tvName++tvar_ :: String -> HsType+tvar_ = typeNamed_ . tvarn_++kindSig_ :: HsType -> HsType -> HsType+kindSig_ ty = noLocA . GHC.HsKindSig synDef ty++tupleType_ :: [HsType] -> HsType+tupleType_ = noLocA . GHC.HsTupleTy synDef HsBoxedOrConstraintTuple++patVar :: String -> HsPat+patVar = noLocA . VarPat NoExtField . unqual_ varName++conPat :: HsQName -> [HsPat] -> HsPat+conPat (L _ ctor) = nlConPat ctor++recPat :: HsQName -> [LHsRecField GhcPs HsPat] -> HsPat+recPat ctor fields = noLocA $ ConPat synDef ctor $ RecCon $ HsRecFields+  { rec_flds = fields+  , rec_dotdot = Nothing+#if MIN_VERSION_ghc_lib_parser(9,12,0)+  , rec_ext = NoExtField+#endif+  }++fieldPunPat :: HsName -> LHsRecField GhcPs HsPat+fieldPunPat nm = noLocA+#if MIN_VERSION_ghc_lib_parser(9,4,0)+  HsFieldBind+    { hfbAnn = synDef+    , hfbLHS = noLocA $ FieldOcc NoExtField nm+    , hfbRHS = noLocA $ VarPat NoExtField nm+    , hfbPun = True+    }+#else+  HsRecField+    { hsRecFieldAnn = synDef+    , hsRecFieldLbl = noLoc $ FieldOcc NoExtField nm+    , hsRecFieldArg = noLocA $ VarPat NoExtField nm+    , hsRecPun = True+    }+#endif++alt_ :: HsPat -> HsExp -> HsAlt+alt_ = mkHsCaseAlt++case_ :: HsExp -> [HsAlt] -> HsExp+case_ e = noLocA . HsCase synDef e . mkMatchGroup generated . noLocA+  where+    generated :: Origin+    generated = Generated+#if MIN_VERSION_ghc_lib_parser(9,10,0)+                          OtherExpansion+#endif+#if MIN_VERSION_ghc_lib_parser(9,8,0)+                                         DoPmc+#endif++-- | Simple let expression for ordinary bindings.+let_ :: [HsBind] -> HsExp -> HsExp+let_ locals e =+#if MIN_VERSION_ghc_lib_parser(9,10,0)+    noLocA $ HsLet synDef binds e+#elif MIN_VERSION_ghc_lib_parser(9,4,0)+    noLocA $ HsLet synDef synDef binds synDef e+#else+    noLocA $ HsLet synDef binds e+#endif+  where+#if MIN_VERSION_ghc_lib_parser(9,12,0)+    binds = HsValBinds synDef (ValBinds synDef locals [])+#else+    binds = HsValBinds synDef (ValBinds synDef (listToBag locals) [])+#endif++-- | Lambda abstraction.+lambda_ :: [HsPat] -> HsExp -> HsExp+#if MIN_VERSION_ghc_lib_parser(9,12,0)+lambda_ = mkHsLam . noLocA+#else+lambda_ = mkHsLam+#endif++if_ :: HsExp -> HsExp -> HsExp -> HsExp+if_ c t f = noLocA $ mkHsIf c t f synDef++-- | A boxed tuple with all components present.+tuple_ :: [HsExp] -> HsExp+#if MIN_VERSION_ghc_lib_parser(9,12,0)+tuple_ xs = mkLHsTupleExpr xs noAnn+#else+tuple_ xs = mkLHsTupleExpr xs synDef+#endif++-- | A promoted boxed tuple value with all components present.+tupleT_ :: [HsType] -> HsType+tupleT_ = noLocA . HsExplicitTupleTy synDef+#if MIN_VERSION_ghc_lib_parser(9,12,0)+                          NotPromoted+#endif++list_ :: [HsExp] -> HsExp+list_ = nlList++listT_ :: [HsType] -> HsType+listT_ = noLocA . HsExplicitListTy synDef IsPromoted++str_ :: String -> HsExp+str_ = noLocA . HsLit synDef . mkHsString++strPat :: String -> HsPat+strPat = noLocA . LitPat NoExtField . HsString NoSourceText . mkFastString++symT :: String -> HsType+symT = noLocA . HsTyLit synDef . HsStrTy NoSourceText . mkFastString++--------------------------------------------------------------------------------+--+-- * Common Haskell expressions, constructors, and operators+--++nothingN, justN :: HsQName++dotProtoFieldC, primC, optionalC, repeatedC, nestedRepeatedC, namedC, mapC,+  fieldNumberC, singleC, dotsC, pathC, qualifiedC, anonymousC, dotProtoOptionC,+  identifierC, stringLitC, intLitC, floatLitC, boolLitC, trueC, falseC, nothingC,+  justC, forceEmitC, encodeMessageFieldE, fromStringE, decodeMessageFieldE,+  pureE, returnE, mappendE, memptyE, msumE, atE, oneofE, fmapE :: HsExp++forceEmitT, justT, maybeT, nothingT, natT, symbolT, typeErrorT :: HsType++dotProtoFieldC       = var_ (protobufASTName tcName "DotProtoField")+primC                = var_ (protobufASTName dataName "Prim")+optionalC            = var_ (protobufASTName dataName "Optional")+repeatedC            = var_ (protobufASTName dataName "Repeated")+nestedRepeatedC      = var_ (protobufASTName dataName "NestedRepeated")+namedC               = var_ (protobufASTName tcName "Named")+mapC                 = var_ (protobufASTName dataName  "Map")+fieldNumberC         = var_ (protobufName dataName "FieldNumber")+singleC              = var_ (protobufASTName dataName "Single")+pathC                = var_ (protobufASTName dataName "Path")+dotsC                = var_ (protobufASTName dataName "Dots")+qualifiedC           = var_ (protobufASTName dataName "Qualified")+anonymousC           = var_ (protobufASTName dataName "Anonymous")+dotProtoOptionC      = var_ (protobufASTName tcName "DotProtoOption")+identifierC          = var_ (protobufASTName dataName "Identifier")+stringLitC           = var_ (protobufASTName dataName "StringLit")+intLitC              = var_ (protobufASTName dataName "IntLit")+floatLitC            = var_ (protobufASTName dataName "FloatLit")+boolLitC             = var_ (protobufASTName dataName "BoolLit")+forceEmitC           = var_ (protobufName dataName "ForceEmit")+forceEmitT           = protobufType_ "ForceEmit"+encodeMessageFieldE  = var_ (protobufName varName "encodeMessageField")+decodeMessageFieldE  = var_ (protobufName varName "decodeMessageField")+atE                  = var_ (protobufName varName "at")+oneofE               = var_ (protobufName varName "oneof")++trueC                = var_ (haskellName dataName "True")+falseC               = var_ (haskellName dataName "False")+nothingC             = var_ nothingN+nothingN             = haskellName dataName "Nothing"+nothingT             = typeNamed_ (haskellName tcName "Nothing")+justC                = var_ justN+justN                =       haskellName dataName "Just"+justT                = typeNamed_ (haskellName tcName "Just")+maybeT               = typeNamed_ (haskellName tcName "Maybe")+fromStringE          = var_ (haskellName varName "fromString")+pureE                = var_ (haskellName varName "pure")+returnE              = var_ (haskellName varName "return")+mappendE             = var_ (haskellName varName "mappend")+memptyE              = var_ (haskellName varName "mempty")+msumE                = var_ (haskellName varName "msum")+fmapE                = var_ (haskellName varName "fmap")+natT                 = typeNamed_ (haskellName tcName "Nat")+symbolT              = typeNamed_ (haskellName tcName "Symbol")+typeErrorT           = typeNamed_ (haskellName tcName "TypeError")++apOp :: HsQOp+apOp  = uvar_ "<*>"++fmapOp :: HsQOp+fmapOp  = uvar_ "<$>"++composeOp :: HsQOp+composeOp = var_ (haskellName varName ".")++fractionOp :: HsQOp+fractionOp = var_ (haskellName varName "/")++bindOp :: HsQOp+bindOp = var_ (haskellName varName ">>=")++altOp :: HsQOp+altOp = uvar_ "<|>"++toJSONPBOp :: HsQOp+toJSONPBOp = uvar_ ".="++parseJSONPBOp :: HsQOp+parseJSONPBOp = uvar_ ".:"++neConsOp :: HsQOp+neConsOp = var_ (haskellName varName ":|")++intE :: Integral a => a -> HsExp+intE x = noLocA $ HsOverLit synDef $ mkHsIntegral $ IL+  { il_text = NoSourceText+  , il_neg = x < 0+  , il_value = toInteger x+  }++intP :: Integral a => a -> HsPat+intP x = noLocA $ NPat synDef overlit Nothing NoExtField+  where+    overlit = L synDef $ mkHsIntegral $ IL+      { il_text = NoSourceText+      , il_neg = x < 0+      , il_value = toInteger x+      }++natTLit :: Integral a => a -> HsType+natTLit = noLocA . HsTyLit synDef . HsNumTy NoSourceText . toInteger++floatE :: forall f . RealFloat f => f -> HsExp+floatE x+    | isNaN x = opApp zero fractionOp zero+    | isInfinite x = opApp (if x < 0 then minusOne else plusOne) fractionOp zero+    | otherwise = scientific x+  where+    zero = scientific (0 :: f)+    minusOne = scientific (-1 :: f)+    plusOne = scientific (1 :: f)+    scientific y = noLocA $ HsOverLit synDef overlit+      where+        (_s, _e) = decodeFloat (abs y)+        overlit = mkHsFractional $ FL+          { fl_text = NoSourceText+          , fl_neg = y < 0+          , fl_signi = _s % 1+          , fl_exp = toInteger _e+          , fl_exp_base = case floatRadix y of+              2 -> Base2+              10 -> Base10+              b -> error $ "doubleE: unsupported floatRadix " ++ show b+          }++do_ :: [ExprLStmt GhcPs] -> HsExp+do_ = noLocA . mkHsDo (DoExpr Nothing) . noLocA++letStmt_ :: [HsBind] -> ExprLStmt GhcPs+letStmt_ locals = noLocA $ LetStmt synDef binds+  where+#if MIN_VERSION_ghc_lib_parser(9,12,0)+    binds = HsValBinds synDef (ValBinds synDef locals [])+#else+    binds = HsValBinds synDef (ValBinds synDef (listToBag locals) [])+#endif++bindStmt_ :: HsPat -> HsExp -> ExprLStmt GhcPs+bindStmt_ p e = noLocA $ mkPsBindStmt synDef p e++lastStmt_ :: HsExp -> ExprLStmt GhcPs+lastStmt_ = noLocA . mkLastStmt++bodyStmt_ :: HsExp -> ExprLStmt GhcPs+bodyStmt_ = noLocA . mkBodyStmt
src/Proto3/Suite/DotProto/Internal.hs view
@@ -1,17 +1,18 @@ -- | This module provides misc internal helpers and utilities -{-# LANGUAGE CPP               #-}-{-# LANGUAGE FlexibleContexts  #-}-{-# LANGUAGE LambdaCase        #-}-{-# LANGUAGE MultiWayIf        #-}-{-# LANGUAGE NamedFieldPuns    #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE QuasiQuotes       #-}-{-# LANGUAGE RankNTypes        #-}-{-# LANGUAGE RecordWildCards   #-}+{-# LANGUAGE CPP                 #-}+{-# LANGUAGE DerivingStrategies  #-}+{-# LANGUAGE FlexibleContexts    #-}+{-# LANGUAGE LambdaCase          #-}+{-# LANGUAGE MultiWayIf          #-}+{-# LANGUAGE NamedFieldPuns      #-}+{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE QuasiQuotes         #-}+{-# LANGUAGE RankNTypes          #-}+{-# LANGUAGE RecordWildCards     #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TupleSections     #-}-{-# LANGUAGE ViewPatterns      #-}+{-# LANGUAGE TupleSections       #-}+{-# LANGUAGE ViewPatterns        #-}  module Proto3.Suite.DotProto.Internal where @@ -29,7 +30,7 @@ import           Data.Foldable import           Data.Functor.Compose import           Data.Int                  (Int32)-import           Data.List                 (intercalate)+import           Data.List                 (intercalate, sort) import qualified Data.List.NonEmpty        as NE import qualified Data.Map                  as M import           Data.Maybe                (fromMaybe)@@ -87,6 +88,159 @@   mapM_ Turtle.err msg   Turtle.exit (ExitFailure 1) +-- | The proposition that some third value comes strictly after+-- the first argument but strictly before the second argument.+nonconsecutive :: (Enum a, Ord a) => a -> a -> Bool+nonconsecutive x y = x < y && succ x < y+  -- The check that @x < y@ avoids the potential for arithmetic overflow in @succ x@.+{-# INLINABLE nonconsecutive #-}  -- To allow specialization to particular type class instances.++-- | This function yields 'Just' of the union of its arguments if that union+-- can be expressed as a single interval, and otherwise yields 'Nothing'.+joinIntervals :: (Enum a, Ord a) => (a, a) -> (a, a) -> Maybe (a, a)+joinIntervals (a, b) (c, d)+  | b < a = Just (c, d)  -- (a, b) is empty; we can just drop it+  | d < c = Just (a, b)  -- (c, d) is empty; we can just drop it+  | a <= c = if+      | nonconsecutive b c -> Nothing   -- (a, b), then something strictly between, then (c, d)+      | otherwise -> Just (a, max b d)  -- no value lies strictly between b and c+  | otherwise = if+      | nonconsecutive d a -> Nothing   -- (c, d), then something strictly between, then (a, b)+      | otherwise -> Just (c, max b d)  -- no value lies strictly between d and a+{-# INLINABLE joinIntervals #-}  -- To allow specialization to particular type class instances.++-- | Finds the unique shortest list of intervals having the same+-- set union as the given list and nondecreasing low endpoints.+--+-- The result also satisfies the definition of /normal/ given below.+--+-- Each interval is specified by pairing its low and high endpoints,+-- which are included in the interval, except when the first component+-- of the pair exceeds the second, in which case the interval is empty.+--+-- = Supporting Theory+--+-- == Definition of /normal/+--+-- Call a list of intervals /normal/ when it excludes empty intervals+-- and for any two consecutive intervals /[a .. b]/ and /[c .. d]/,+-- there exists an /x/ such that /b < x < c/.+--+-- We claim that, among those interval lists having any given union,+-- normality is equivalent to having minimal length and nondecreasing+-- low endpoints.+--+-- == Normal implies minimal length+--+-- To see why, first consider any normal interval list /N/.  Clearly its+-- low endpoints are nondecreasing--and in fact are strictly increasing+-- with gaps inbetween.  Therefore any interval intersecting at least two+-- intervals of /N/ necessarily includes at least one point in such a gap,+-- and that point is outside the union of /N/.  Hence every interval list+-- with the same union as /N/ consists of (possibly empty) subintervals of+-- intervals listed by /N/.  Hence /N/ has minimal length among such lists.+--+-- == Minimal length implies normal+--+-- To establish the converse, consider any interval list /N/ having+-- nondecreasing endpoints and minimal length.  Deleting empty intervals+-- from /N/ would only decrease its length, so /N/ must not include any.+-- Next note that if /[a .. b]/ and /[c .. d]/ are consecutive intervals+-- within /N/, then either there exists an /x/ such that /b < x < c/, or+-- else we may shorten /N/ without changing its union by replacing both+-- /[a .. b]/ and /[c .. d]/ by the single interval /[a .. max b d]/,+-- which would contradict the minimality of the length of /N/.  Thus+-- /N/ fulfills all the requirements of being a normal interval list.+--+-- == Existence+--+-- Having proved the desired equivalence, we turn to the question of+-- the existence of the shortest interval list having the same union+-- as any given interval list and nondecreasing low endpoints.+--+-- Consider the set /S/ of interval lists having the same union as+-- the given interval list and nondecreasing low endpoints.  Note+-- that by performing a stable sort on the given interval list we+-- immediately find that /S/ is nonempty.  Being nonempty, it must+-- contain at least one element of minimal length.+--+-- == Uniqueness+--+-- But could there be two different interval lists of minimal length+-- for their common union, both with nondecreasing low endpoints?+--+-- We claim the answer is no, and proceed by induction on that shared+-- minimal length.  The base case is trivial: if both lists are empty,+-- then they cannot differ.+--+-- For the induction step, suppose that there are two interval lists+-- that share the same positive minimal length among those that+-- have nondecreasing low endpoints and a given same union.+-- Call them /L/ and /N/.  We will prove that /L = N/.+--+-- Let /(a, b) = head L/ and /(e, f) = head N/.+--+-- If /a < e/ then /a/ is in /union L/ but not in /union N/,+-- contradicting our assumpion that /union L = union N/.  Likewise+-- we may exclude /e < a/, leaving /a = e/ and /(a, f) = head N/.+--+-- Next suppose that /b < f/.  If /tail L == []/ then clearly /f/+-- is outside of /union L/ and yet inside of /union N/, which is+-- once again beyond our scenario.  Let /(c, d) = head (tail L)/.+-- By the equivalence we established earlier, /L/ is normal and+-- hence there exists an /x/ such that /b < x < c/.  If /x <= f/,+-- then /x/ is in /[a .. f]/ and yet outside of /union L/, once+-- again contradicting our hypotheses.  Otherwise /f < x < c/, and+-- hence /f/ is outside of /union L/, a similar contradiction.+-- Therefore our supposition that /b < f/ must be impossible,+-- and we can likewise exclude /f < b/.  Hence /b = f/.+--+-- Having establishing both /a = e/ and /b = f/, we conclude that+-- /head L = head N/.  It follows that /tail L/ and /tail N/ have+-- the same union as each other.  Both tails must be minimal in+-- length, because otherwise there would also be a way to shorten+-- /L/ or /N/ in a union-preserving way.  Invoking our induction+-- hypothesis we find that /tail L = tail N/; therefore /L = N/.+--+-- = Conclusions+--+-- In conclusion, the desired behavior of this function is well defined+-- by the first paragraph in this comment block, and the second paragraph+-- (once combined with a requirement to preserve the union) provides+-- an equivalent definition.+--+-- To check that the implementation actually fulfills these requirements,+-- note that it filters out empty intervals, sorts those that remain,+-- and then merges intervals until the resulting list becomes normal.+--+-- There are also unit tests checking that the result is+-- normal and has the same union as the given list.+normalizeIntervals :: (Enum a, Ord a) => [(a, a)] -> [(a, a)]+normalizeIntervals = mergeIntervals . filter \(x, y) -> x <= y+{-# INLINABLE normalizeIntervals #-}  -- To allow specialization to particular type class instances.++-- | Returns a sorted list that contains all intervals from the minimal set of+-- intervals to represent the given list of intervals.+--+-- "Merges" overlapping intervals in a list of intervals. Think disjunctive+-- normal form.+mergeIntervals :: forall a . (Enum a, Ord a) => [(a, a)] -> [(a, a)]+mergeIntervals = foldr step [] . sort+  where+    step :: (a, a) -> [(a, a)] -> [(a, a)]+    step x [] = [x]+    step x (y : ys) = case joinIntervals x y of+      Nothing -> x : y : ys+        -- In this case @x@ and @y@ could not be merged, and therefore there is+        -- some value strictly inbetween the end of @x@ and the start of @y@.+        -- Compare this property to the definition of /normal/ (above).+      Just xy -> step xy ys+        -- Recursion is necessary here because @x@ may end later than did @y@,+        -- possibly making @xy@ mergable with some prefix of @ys@, unlike @y@.+        -- By merging @x@ and @y@ into @xy@ we have shortened the overall+        -- length of the list, and therefore this recursion must terminate.+{-# INLINABLE mergeIntervals #-}  -- To allow specialization to particular type class instances.+ -------------------------------------------------------------------------------- -- -- * Reading files@@ -568,13 +722,13 @@  -- | Bookeeping for qualified fields data QualifiedField = QualifiedField-  { recordFieldName :: FieldName-  , fieldInfo       :: FieldInfo+  { recordFieldName   :: FieldName+  , fieldInfo         :: FieldInfo   } deriving Show  -- | Bookkeeping for fields data FieldInfo-  = FieldOneOf OneofField+  = FieldOneOf FieldName OneofField   | FieldNormal FieldName FieldNumber DotProtoType [DotProtoOption]   deriving Show @@ -586,11 +740,11 @@  -- | Bookkeeping for oneof subfields data OneofSubfield = OneofSubfield-  { subfieldNumber   :: FieldNumber-  , subfieldConsName :: String-  , subfieldName     :: FieldName-  , subfieldType     :: DotProtoType-  , subfieldOptions  :: [DotProtoOption]+  { subfieldNumber       :: FieldNumber+  , subfieldConsName     :: String+  , subfieldName         :: FieldName+  , subfieldType         :: DotProtoType+  , subfieldOptions      :: [DotProtoOption]   } deriving Show  getQualifiedFields :: MonadError CompileError m@@ -617,14 +771,21 @@     let mkSubfield DotProtoField{..} = do             s <- dpIdentUnqualName dotProtoFieldName             c <- prefixedConName oneofTypeName s-            pure [OneofSubfield dotProtoFieldNumber c (coerce s) dotProtoFieldType dotProtoFieldOptions]-        mkSubfield DotProtoEmptyField = pure []+            pure [ OneofSubfield+                     { subfieldNumber       = dotProtoFieldNumber+                     , subfieldConsName     = c+                     , subfieldName         = coerce s+                     , subfieldType         = dotProtoFieldType+                     , subfieldOptions      = dotProtoFieldOptions+                     }+                 ]      fieldElems <- foldMapM mkSubfield fields -    pure . (:[]) $ QualifiedField { recordFieldName = coerce oneofName-                                  , fieldInfo = FieldOneOf (OneofField ident fieldElems)-                                  }+    pure . (:[]) $ QualifiedField+                     { recordFieldName = coerce oneofName+                     , fieldInfo = FieldOneOf (coerce ident) (OneofField ident fieldElems)+                     }   _ -> pure []  -- | Project qualified fields, given a projection function per field type.@@ -633,7 +794,7 @@        -> QualifiedField        -> a foldQF f _ (QualifiedField _ (FieldNormal fldName fldNum _ _)) = f fldName fldNum-foldQF _ g (QualifiedField _ (FieldOneOf fld))                 = g fld+foldQF _ g (QualifiedField _ (FieldOneOf _ fld))               = g fld  fieldBinder :: FieldNumber -> String fieldBinder = ("f" ++) . show@@ -663,6 +824,12 @@   | NonzeroFirstEnumeration String DotProtoIdentifier Int32   | EmptyEnumeration String   | Unimplemented String+  | RedefinedFields (Histogram FieldName) (Histogram FieldNumber)+      -- ^ At least one field/oneof name and or field number was+      -- used more than once within the same message definition,+      -- which violates the protobuf specification.  The histograms+      -- mention only the repeated names and numbers, not the ones+      -- used only once.   deriving (Show, Eq)  @@ -680,3 +847,21 @@  noSuchTypeError :: MonadError CompileError m => DotProtoIdentifier -> m a noSuchTypeError = throwError . NoSuchType+++newtype Histogram a = Histogram (M.Map a Int)+  deriving stock (Eq, Ord, Show)++instance Ord a => Semigroup (Histogram a)+  where+    Histogram x <> Histogram y = Histogram (M.unionWith (+) x y)++instance Ord a => Monoid (Histogram a)+  where+    mempty = Histogram M.empty++oneOccurrence :: a -> Histogram a+oneOccurrence k = Histogram (M.singleton k 1)++mulipleOccurrencesOnly :: Histogram a -> Histogram a+mulipleOccurrencesOnly (Histogram m) = Histogram (M.filter (1 <) m)
src/Proto3/Suite/DotProto/Parsing.hs view
@@ -1,6 +1,7 @@ -- | This module contains a near-direct translation of the proto3 grammar --   It uses String for easier compatibility with DotProto.Generator, which needs it for not very good reasons +{-# LANGUAGE BlockArguments #-} {-# LANGUAGE CPP #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE LambdaCase #-}@@ -26,6 +27,9 @@     -- * Extension Parsers   , pExtendStmt   , pExtendKw++    -- * Empty Statement+  , pEmptyStmt   ) where  import Prelude hiding (fail)@@ -38,6 +42,7 @@ import Control.Monad.Fail #endif import qualified Data.Char as Char+import Data.Maybe (catMaybes) import Data.List.NonEmpty (NonEmpty ((:|))) import qualified Data.List.NonEmpty as NE import Data.Functor@@ -273,8 +278,8 @@ -- top-level statements  topStatement :: ProtoParser DotProtoStatement-topStatement = -  choice +topStatement =+  choice     [ DPSImport <$> import_     , DPSPackage <$> package     , DPSOption <$> pOptionStmt@@ -299,17 +304,17 @@              return $ DotProtoPackageSpec p  definition :: ProtoParser DotProtoDefinition-definition = -  choice +definition =+  choice     [ try message-    , try enum+    , try pEnumDefn     , service     ]  -------------------------------------------------------------------------------- -- options --- | Parses a protobuf option that could appear in a service, RPC, message, +-- | Parses a protobuf option that could appear in a service, RPC, message, -- enumeration, or at the top-level. -- -- @since 0.5.2@@ -321,7 +326,7 @@ -- @since 0.5.2 pFieldOptions :: ProtoParser [DotProtoOption] pFieldOptions = pOptions <|> pure []-  where +  where     pOptions :: ProtoParser [DotProtoOption]     pOptions = between lbracket rbracket (commaSep1 (token pFieldOptionStmt)) @@ -335,8 +340,8 @@ -- -- @since 0.5.2 pFieldOptionStmt :: ProtoParser DotProtoOption-pFieldOptionStmt = token $ do -  idt <- pOptionId +pFieldOptionStmt = token $ do+  idt <- pOptionId   token (char '=')   val <- value   pure (DotProtoOption idt val)@@ -345,23 +350,23 @@ -- -- @since 0.5.2 pOptionId :: ProtoParser DotProtoIdentifier-pOptionId = -  choice +pOptionId =+  choice     [ try pOptionQName     , try (parens pOptionName)     , pOptionName     ]-  where +  where     pOptionName :: ProtoParser DotProtoIdentifier     pOptionName = token $ do       nm <- identifierName       nms <- many (char '.' *> identifierName)-      if null nms +      if null nms         then pure (Single nm)         else pure (Dots (Path (nm :| nms)))      pOptionQName :: ProtoParser DotProtoIdentifier-    pOptionQName = token $ do +    pOptionQName = token $ do       idt <- parens pOptionName       nms <- char '.' *> pOptionName       pure (Qualified idt nms)@@ -378,10 +383,11 @@ -------------------------------------------------------------------------------- -- service statements -servicePart :: ProtoParser DotProtoServicePart-servicePart = DotProtoServiceRPCMethod <$> rpc-          <|> DotProtoServiceOption <$> pOptionStmt-          <|> DotProtoServiceEmpty <$ empty+servicePart :: ProtoParser (Maybe DotProtoServicePart)+servicePart =+  try (fmap (Just . DotProtoServiceRPCMethod) rpc)+    <|> try (fmap (Just . DotProtoServiceOption) pOptionStmt)+    <|> Nothing <$ pEmptyStmt  rpcOptions :: ProtoParser [DotProtoOption] rpcOptions = braces $ many pOptionStmt@@ -402,53 +408,70 @@          return RPCMethod{..}  service :: ProtoParser DotProtoDefinition-service = do symbol "service"-             name <- singleIdentifier-             statements <- braces (many servicePart)-             return $ DotProtoService mempty name statements+service = do+  symbol "service"+  name <- singleIdentifier+  statements <- braces do+    results <- many servicePart+    pure (catMaybes results)+  return $ DotProtoService mempty name statements  -------------------------------------------------------------------------------- -- message definitions  message :: ProtoParser DotProtoDefinition-message = do symbol "message"-             name <- singleIdentifier-             body <- braces (many messagePart)-             return $ DotProtoMessage mempty name body+message = do+  symbol "message"+  name <- singleIdentifier+  body <- braces do+    results <- many messagePart+    pure (catMaybes results)+  pure (DotProtoMessage mempty name body)  messageOneOf :: ProtoParser DotProtoMessagePart messageOneOf = do symbol "oneof"                   name <- singleIdentifier-                  body <- braces $ many (messageField <|> empty $> DotProtoEmptyField)+                  body <- braces (many oneofField)                   return $ DotProtoMessageOneOf name body -messagePart :: ProtoParser DotProtoMessagePart-messagePart = try (DotProtoMessageDefinition <$> enum)-          <|> try (DotProtoMessageReserved   <$> reservedField)-          <|> try (DotProtoMessageDefinition <$> message)-          <|> try messageOneOf-          <|> try (DotProtoMessageField      <$> messageField)-          <|> try (DotProtoMessageOption     <$> pOptionStmt)+messagePart :: ProtoParser (Maybe DotProtoMessagePart)+messagePart =+  try (Just . DotProtoMessageDefinition <$> pEnumDefn)+    <|> try (Just . DotProtoMessageReserved   <$> pReserved)+    <|> try (Just . DotProtoMessageDefinition <$> message)+    <|> try (fmap Just messageOneOf)+    <|> try (Just . DotProtoMessageField      <$> messageField)+    <|> try (Just . DotProtoMessageOption     <$> pOptionStmt)+    <|> (Nothing <$ pEmptyStmt)  messageType :: ProtoParser DotProtoType-messageType = try mapType <|> try repType <|> (Prim <$> primType)+messageType = try mapType <|> try optType <|> try repType <|> (Prim <$> primType)   where     mapType = do symbol "map"                  angles $ Map <$> (primType <* comma)                               <*> primType +    optType = do symbol "optional"+                 Optional <$> primType+     repType = do symbol "repeated"                  Repeated <$> primType  messageField :: ProtoParser DotProtoField-messageField = do mtype <- messageType-                  mname <- identifier-                  symbol "="-                  mnumber <- fieldNumber-                  moptions <- pFieldOptions-                  semi-                  return $ DotProtoField mnumber mtype mname moptions mempty+messageField = messageFieldFor messageType +oneofField :: ProtoParser DotProtoField+oneofField = messageFieldFor (Prim <$> primType)++messageFieldFor :: ProtoParser DotProtoType -> ProtoParser DotProtoField+messageFieldFor parseType = do mtype <- parseType+                               mname <- identifier+                               symbol "="+                               mnumber <- fieldNumber+                               moptions <- pFieldOptions+                               semi+                               return $ DotProtoField mnumber mtype mname moptions mempty+ -------------------------------------------------------------------------------- -- enumerations @@ -461,16 +484,21 @@                return $ DotProtoEnumField fname fpos opts  -enumStatement :: ProtoParser DotProtoEnumPart-enumStatement = try (DotProtoEnumOption <$> pOptionStmt)-            <|> enumField-            <|> empty $> DotProtoEnumEmpty+enumStatement :: ProtoParser (Maybe DotProtoEnumPart)+enumStatement =+  try (fmap (Just . DotProtoEnumReserved) pReserved)+    <|> try (fmap (Just . DotProtoEnumOption) pOptionStmt)+    <|> try (fmap Just enumField)+    <|> (Nothing <$ pEmptyStmt) -enum :: ProtoParser DotProtoDefinition-enum = do symbol "enum"-          ename <- singleIdentifier-          ebody <- braces (many enumStatement)-          return $ DotProtoEnum mempty ename ebody+pEnumDefn :: ProtoParser DotProtoDefinition+pEnumDefn = do+  symbol "enum"+  ename <- singleIdentifier+  ebody <- braces do+    results <- many enumStatement+    pure (catMaybes results)+  pure (DotProtoEnum mempty ename ebody)  -------------------------------------------------------------------------------- -- field reservations@@ -485,11 +513,12 @@ ranges :: ProtoParser [DotProtoReservedField] ranges = commaSep1 (try range <|> (SingleField . fromInteger <$> integer)) -reservedField :: ProtoParser [DotProtoReservedField]-reservedField = do symbol "reserved"-                   v <- ranges <|> commaSep1 (ReservedIdentifier <$> strFieldName)-                   semi-                   return v+pReserved :: ProtoParser [DotProtoReservedField]+pReserved = do+  symbol "reserved"+  v <- ranges <|> commaSep1 (ReservedIdentifier <$> strFieldName)+  semi+  return v  strFieldName :: ProtoParser String strFieldName =@@ -499,10 +528,12 @@ -- Message Extensions ----------------------------------------------------------  pExtendStmt :: ProtoParser (DotProtoIdentifier, [DotProtoMessagePart])-pExtendStmt = do +pExtendStmt = do   pExtendKw   idt <- identifier-  fxs <- braces (many messagePart)+  fxs <- braces do+    results <- many messagePart+    pure (catMaybes results)   pure (idt, fxs)  -- | Parses a single keyword token "extend".@@ -510,6 +541,14 @@ -- @since 0.5.2 pExtendKw :: ProtoParser () pExtendKw = do-  spaces -  token (string "extend" >> notFollowedBy alphaNum) +  spaces+  token (string "extend" >> notFollowedBy alphaNum)     <?> "keyword 'extend'"++-- Parse - Empty Statements ----------------------------------------------------++-- | Parses a single empty statement (i.e. a semicolon).+--+-- See: https://protobuf.dev/reference/protobuf/proto3-spec/#emptystatement+pEmptyStmt :: ProtoParser ()+pEmptyStmt = token (() <$ char ';') <?> "empty statement"
src/Proto3/Suite/DotProto/Rendering.hs view
@@ -1,11 +1,9 @@ -- | This module provides types and functions to generate .proto files. -{-# LANGUAGE CPP #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE OverloadedLists            #-} {-# LANGUAGE RecordWildCards            #-} {-# LANGUAGE ScopedTypeVariables        #-}-{-# OPTIONS_GHC -fno-warn-orphans       #-}  module Proto3.Suite.DotProto.Rendering   ( renderDotProto@@ -19,17 +17,11 @@   , Pretty(..)   ) where -import           Data.Char-import qualified Data.List.NonEmpty              as NE-#if (MIN_VERSION_base(4,11,0))-import           Prelude                         hiding ((<>))-#endif import           Proto3.Suite.DotProto.AST import           Proto3.Wire.Types               (FieldNumber (..))-import           Text.PrettyPrint                (($$), (<+>), (<>))+import           Text.PrettyPrint                (($$), (<+>)) import qualified Text.PrettyPrint                as PP import           Text.PrettyPrint.HughesPJClass  (Pretty(..))-import           Turtle.Compat                   (encodeString)  -- | Options for rendering a @.proto@ file. data RenderingOptions = RenderingOptions@@ -67,30 +59,6 @@  $$ (PP.vcat $ topOption <$> protoOptions)  $$ (PP.vcat $ prettyPrintProtoDefinition opts <$> protoDefinitions) -strLit :: String -> PP.Doc-strLit string = PP.text "\"" <> foldMap escape string <> PP.text "\""-  where-    escape '\n' = PP.text "\\n"-    escape '\\' = PP.text "\\\\"-    escape '\0' = PP.text "\\x00"-    escape '"'  = PP.text "\\\""-    escape  c   = PP.text [ c ]--instance Pretty DotProtoPackageSpec where-  pPrint (DotProtoPackageSpec p) = PP.text "package" <+> pPrint p <> PP.text ";"-  pPrint (DotProtoNoPackage)     = PP.empty--instance Pretty DotProtoImport where-  pPrint (DotProtoImport q i) =-    PP.text "import" <+> pPrint q <+> strLit fp <> PP.text ";"-    where-      fp = encodeString i--instance Pretty DotProtoImportQualifier where-  pPrint DotProtoImportDefault = PP.empty-  pPrint DotProtoImportPublic  = PP.text "public"-  pPrint DotProtoImportWeak    = PP.text "weak"- optionAnnotation :: [DotProtoOption] -> PP.Doc optionAnnotation [] = PP.empty optionAnnotation os = PP.brackets@@ -99,10 +67,7 @@                     $ pPrint <$> os  topOption :: DotProtoOption -> PP.Doc-topOption o = PP.text "option" <+> pPrint o <> PP.text ";"--instance Pretty DotProtoOption where-  pPrint (DotProtoOption key value) = pPrint key <+> PP.text "=" <+> pPrint value+topOption o = PP.text "option" <+> pPrint o PP.<> PP.text ";"  renderComment :: String -> PP.Doc renderComment = PP.vcat . map ((PP.text "//" <+>) . textIfNonempty) . lines@@ -133,21 +98,20 @@   msgPart _       (DotProtoMessageReserved reservations)     =   PP.text "reserved"     <+> (PP.hcat . PP.punctuate (PP.text ", ") $ pPrint <$> reservations)-    <>  PP.text ";"+    PP.<> PP.text ";"   msgPart msgName (DotProtoMessageOneOf name fields)     = vbraces (PP.text "oneof" <+> pPrint name) (PP.vcat $ field msgName <$> fields)   msgPart _       (DotProtoMessageOption opt)-    = PP.text "option" <+> pPrint opt <> PP.text ";"+    = PP.text "option" <+> pPrint opt PP.<> PP.text ";"    field :: DotProtoIdentifier -> DotProtoField -> PP.Doc   field msgName (DotProtoField number mtype name options comments)     =   pPrint mtype     <+> roSelectorName opts msgName name number     <+> PP.text "="-    <+> pPrint number+    <+> pPrintFieldNumber number     <+> optionAnnotation options-    <>  PP.text ";"+    PP.<> PP.text ";"     $$  PP.nest 2 (renderComment comments)-  field _ DotProtoEmptyField = PP.empty    enumPart :: DotProtoIdentifier -> DotProtoEnumPart -> PP.Doc   enumPart msgName (DotProtoEnumField name value options)@@ -155,73 +119,14 @@     <+> PP.text "="     <+> pPrint (fromIntegral value :: Int)     <+> optionAnnotation options-    <> PP.text ";"+    PP.<> PP.text ";"+  enumPart _       (DotProtoEnumReserved reservedFields)+    = PP.text "reserved" <+> (PP.hcat . PP.punctuate (PP.text ", ") $ pPrint <$> reservedFields)   enumPart _       (DotProtoEnumOption opt)-    = PP.text "option" <+> pPrint opt <> PP.text ";"-  enumPart _       DotProtoEnumEmpty-    = PP.empty--instance Pretty DotProtoServicePart where-  pPrint (DotProtoServiceRPCMethod RPCMethod{..})-    =   PP.text "rpc"-    <+> pPrint rpcMethodName-    <+> PP.parens (pPrint rpcMethodRequestStreaming <+> pPrint rpcMethodRequestType)-    <+> PP.text "returns"-    <+> PP.parens (pPrint rpcMethodResponseStreaming <+> pPrint rpcMethodResponseType)-    <+> case rpcMethodOptions of-          [] -> PP.text ";"-          _  -> PP.braces . PP.vcat $ topOption <$> rpcMethodOptions-  pPrint (DotProtoServiceOption option) = topOption option-  pPrint DotProtoServiceEmpty           = PP.empty--instance Pretty Streaming where-  pPrint Streaming    = PP.text "stream"-  pPrint NonStreaming = PP.empty--instance Pretty DotProtoIdentifier where-  pPrint (Single name)                    = PP.text name-  pPrint (Dots (Path names))              = PP.hcat . PP.punctuate (PP.text ".") $ PP.text <$> NE.toList names-  pPrint (Qualified qualifier identifier) = PP.parens (pPrint qualifier) <> PP.text "." <> pPrint identifier-  pPrint Anonymous                        = PP.empty--instance Pretty DotProtoValue where-  pPrint (Identifier value) = pPrint value-  pPrint (StringLit  value) = strLit value-  pPrint (IntLit     value) = PP.text $ show value-  pPrint (FloatLit   value) = PP.text $ show value-  pPrint (BoolLit    value) = PP.text $ toLower <$> show value--instance Pretty DotProtoType where-  pPrint (Prim           ty) = pPrint ty-  pPrint (Repeated       ty) = PP.text "repeated" <+> pPrint ty-  pPrint (NestedRepeated ty) = PP.text "repeated" <+> pPrint ty-  pPrint (Map keyty valuety) = PP.text "map<" <> pPrint keyty <> PP.text ", " <> pPrint valuety <> PP.text ">"--instance Pretty DotProtoPrimType where-  pPrint (Named i)  = pPrint i-  pPrint Int32      = PP.text "int32"-  pPrint Int64      = PP.text "int64"-  pPrint SInt32     = PP.text "sint32"-  pPrint SInt64     = PP.text "sint64"-  pPrint UInt32     = PP.text "uint32"-  pPrint UInt64     = PP.text "uint64"-  pPrint Fixed32    = PP.text "fixed32"-  pPrint Fixed64    = PP.text "fixed64"-  pPrint SFixed32   = PP.text "sfixed32"-  pPrint SFixed64   = PP.text "sfixed64"-  pPrint String     = PP.text "string"-  pPrint Bytes      = PP.text "bytes"-  pPrint Bool       = PP.text "bool"-  pPrint Float      = PP.text "float"-  pPrint Double     = PP.text "double"--instance Pretty FieldNumber where-  pPrint = PP.text . show . getFieldNumber+    = PP.text "option" <+> pPrint opt PP.<> PP.text ";" -instance Pretty DotProtoReservedField where-  pPrint (SingleField num)      = PP.text $ show num-  pPrint (FieldRange start end) = (PP.text $ show start) <+> PP.text "to" <+> (PP.text $ show end)-  pPrint (ReservedIdentifier i) = PP.text $ show i+pPrintFieldNumber :: FieldNumber -> PP.Doc+pPrintFieldNumber = PP.text . show . getFieldNumber  -- | Render protobufs metadata as a .proto file stringy toProtoFile :: RenderingOptions -> DotProto -> String
+ src/Proto3/Suite/Form.hs view
@@ -0,0 +1,403 @@+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ImportQualifiedPost #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE UndecidableInstances #-}++-- | Type-Level Format Information+--+-- Use @compile-proto-file --typeLevelFormat ...@ to instantiate these type families to+-- provide type-level information that may be used to define custom encoders and decoders.+--+-- /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.+module Proto3.Suite.Form+  ( NamesOf+  , NumberOf+  , ProtoTypeOf+  , OneOfOf+  , CardinalityOf+  , FieldNotFound+  , FieldOrOneOfNotFound+  , Packing(..)+  , Cardinality(..)+  , ProtoType(..)+  , Association+  , CardinalityOfMapped+  , Wrapper+  , RecoverCardinality+  , RecoverProtoType+  , MessageFieldType+  , OptionalMessageFieldType+  , RepeatedMessageFieldType+  ) where++import Data.Int (Int32, Int64)+import Data.Kind (Type)+import Data.Map qualified as M+import Data.Word (Word32, Word64)+import GHC.Exts (Constraint)+import GHC.TypeLits (ErrorMessage(..), Nat, Symbol, TypeError)+import Prelude hiding (String)+import Proto3.Suite.Types (Bytes, Enumerated, Commented, Fixed, ForceEmit, Nested,+                           NestedVec, PackedVec, Signed, String, UnpackedVec)++-- | Returns the names of the fields within a given type of message.+--+-- The names appear in increasing order of field number, in case that helps+-- type-level search algorithms, though at present it is likely that there+-- is no benefit other than ensuring that declaration order is irrelevant.+--+-- Note that the names of fields and oneofs must be unique within their shared namespace+-- (see <https://protobuf.dev/reference/protobuf/proto3-spec/#message_definition>).+type family NamesOf (message :: Type) :: [Symbol]++-- | In the context of a message type, maps its field names to their numbers.+type family NumberOf (message :: Type) (name :: Symbol) :: Nat++-- | In the context of a message type, maps the name of every field to its protobuf type.+type family ProtoTypeOf (message :: Type) (name :: Symbol) :: ProtoType++-- | In the context of a message type, maps the name of every field to the name+-- of its containing @oneof@, or to @""@ if that field is not part of a oneof.+-- Also maps the name of every @oneof@ in the message to itself.+type family OneOfOf (message :: Type) (name :: Symbol) :: Symbol++-- | In the context of a message type, maps the name+-- of every field and @oneof@ to its 'Cardinality'.+--+-- (Every @oneof@ in the message is mapped to 'OneOf',+-- as are those fields that are within @oneof@s.)+type family CardinalityOf (message :: Type) (name :: Symbol) :: Cardinality++-- | A compilation error message for when the given message+-- does not contain a field with the given name.+type FieldNotFound (message :: Type) (name :: Symbol) =+  'Text "Field " ':<>: 'ShowType name ':<>:+  'Text " not found in message:" ':$$: 'ShowType message++-- | A compilation error message for when the given message+-- does not contain a field or oneof with the given name.+type FieldOrOneOfNotFound (message :: Type) (name :: Symbol) =+  'Text "Field or oneof " ':<>: 'ShowType name ':<>:+  'Text " not found in message:" ':$$: 'ShowType message++-- | The packing of field that is @repeated@ or is a @map@.  Every+-- encoding appends and element, and omission means zero elements.+data Packing+  = Unpacked+      -- ^ Packing is not preferred or not supported (for example, submessages and maps).+  | Packed+      -- ^ Packing is supported and preferred (perhaps implicitly).++-- | Expresses how many values we expect a field to contain, what it means when its+-- encoding is omitted, and if it is @repeated@, whether or not packing is preferred.+--+-- Each data constructor is chosen in such a way that it implies how many+-- values are expected as arguments to `Proto3.Suite.Form.Encode.field`.+-- This choice simplifies instantiation of type classes.+data Cardinality+  = Implicit+      -- ^ We expect exactly one value for this field,+      -- though the default value is expressed by omission+      -- in the binary format.  Such a field is never "unset".+      --+      -- In the terminology of the proto3 specification, the field is+      -- "singular" and is neither @optional@ nor part of a @oneof@.+      --+      -- Put another way: the field is not declared @optional@ or+      -- @repeated@, it is not a @map@, it does not have a message type,+      -- and it is not part of a @oneof@.+      --+      -- `Proto3.Suite.Form.Encode.field` will expect exactly one field+      -- value as its argument.  Typically the argument type is not+      -- a container type.  But there may be application-specific reasons+      -- for supplying a container type, such as the field type being+      -- a message that has container semantics implemented by an+      -- application-specific instance of `Proto3.Suite.Form.Encode.FieldForm`.+  | Optional+      -- ^ The field is singular and has optional field presence.  That is,+      -- That is, it is a non-@repeated@ submessage field (which is optional+      -- even when not explicitly declared @optional@), or an @optional@+      -- scalar/enumerated field whose omission implies an "unset" value+      -- distinct from the default value, or any field within a @oneof@.+      --+      -- `Proto3.Suite.Form.Encode.field` will expect zero or one field+      -- values as its argument.  Typically the type involves 'Maybe',+      -- but when the 'Nothing' case can be excluded, feel free to+      -- use `Data.Functor.Identity.Identity` to illustrate that fact.+  | Repeated Packing+      -- ^ The field is @repeated@ or is a @map@, with the indicated+      -- packing preference (which for @map is always 'Unpacked').+      --+      -- `Proto3.Suite.Form.Encode.field` will expect zero or more+      -- field values, typically expressed by a container type having+      -- an instance of `Proto3.Wire.Encode.Repeated.ToRepeated`.++-- | The type of a message field, but when the field is repeated, this is the element type.+--+-- Design Note: We do not use the same Haskell types recognized+-- by `Proto3.Suite.Class.MessageField` because there more than+-- one such type corresponds to protobuf type @string@.+-- But see 'RecoverProtoType'.+data ProtoType+  = Int32+  | Int64+  | SInt32+  | SInt64+  | UInt32+  | UInt64+  | Fixed32+  | Fixed64+  | SFixed32+  | SFixed64+  | String+  | Bytes+  | Bool+  | Float+  | Double+  | Enumeration Type+      -- ^ The field is the type created by code generation from the protobuf enum.+  | Message Type+      -- ^ The field is the type created by code generation from the protobuf message.+  | Map ProtoType ProtoType+      -- ^ A map with the given key and value types.++-- | The type of the repeated key-value pair submessage implied by a map field.+--+-- We never need to construct values; instead we construct values of types+-- such as @`Proto3.Suite.Form.Encode.Encoding` ('Association' key value)@.+--+-- The key field is named @"key"@ and the value field is named @"value"@.+data Association (key :: ProtoType) (value :: ProtoType)++type instance NamesOf (Association _ _) = '[ "key", "value" ]++type instance NumberOf (Association _ _) "key" = 1+type instance NumberOf (Association _ _) "value" = 2++type instance ProtoTypeOf (Association key _) "key" = key+type instance ProtoTypeOf (Association _ value) "value" = value++type instance OneOfOf (Association _ _) "key" = ""+type instance OneOfOf (Association _ _) "value" = ""++type instance CardinalityOf (Association _ _) "key" = 'Implicit+type instance CardinalityOf (Association _ value) "value" = CardinalityOfMapped value++-- | Yields the field presence of a mapped value of the given protobuf type.+type family CardinalityOfMapped (protoType :: ProtoType) :: Cardinality+  where+    CardinalityOfMapped ('Message _) = 'Optional+    CardinalityOfMapped ('Map k v) = TypeError+      ( 'Text "Nested maps are disallowed, so this cannot be a mapped type:"+        ':$$: 'ShowType ('Map k v) )+    CardinalityOfMapped _ = 'Implicit++-- | Indicates the standard protobuf wrapper having+-- the field type given by the type argument.+--+-- We never need to construct values; instead we construct values of types+-- such as @`Proto3.Suite.Form.Encode.Encoding` ('Wrapper' protoType)@ or+-- @`Proto.Suite.Form.Encode.Wrap` a@, where @a@ is a corresponding native representation.+--+-- Note that if Google ever adds wrappers for "sint..." or "...fixed..."+-- then this type constructor will naturally support such wrappers.+data Wrapper (protoType :: ProtoType)++type instance NamesOf (Wrapper protoType) = '[ "value" ]++type instance NumberOf (Wrapper protoType) "value" = 1++type instance ProtoTypeOf (Wrapper protoType) "value" = protoType++type instance OneOfOf (Wrapper protoType) "value" = ""++type instance CardinalityOf (Wrapper protoType) "value" = 'Implicit++-- | Given the Haskell type used by features such as `Proto3.Suite.Class.MessageField`+-- to indicate the encoding of a message field.+type family RecoverCardinality (haskellType :: Type) :: Cardinality+  where+    RecoverCardinality (Commented _ haskellType) = RecoverCardinality haskellType+    RecoverCardinality (Maybe (ForceEmit _)) = 'Optional+    RecoverCardinality (PackedVec _) = 'Repeated 'Packed+    RecoverCardinality (UnpackedVec _) = 'Repeated 'Unpacked+    RecoverCardinality (NestedVec _) = 'Repeated 'Unpacked+    RecoverCardinality (Nested _) = 'Optional+    RecoverCardinality (Enumerated _) = 'Implicit+    RecoverCardinality (M.Map _ _) = 'Repeated 'Unpacked+    RecoverCardinality Int32 = 'Implicit+    RecoverCardinality Int64 = 'Implicit+    RecoverCardinality (Signed Int32) = 'Implicit+    RecoverCardinality (Signed Int64) = 'Implicit+    RecoverCardinality Word32 = 'Implicit+    RecoverCardinality Word64 = 'Implicit+    RecoverCardinality (Fixed Word32) = 'Implicit+    RecoverCardinality (Fixed Word64) = 'Implicit+    RecoverCardinality (Signed (Fixed Int32)) = 'Implicit+    RecoverCardinality (Signed (Fixed Int64)) = 'Implicit+    RecoverCardinality (String _) = 'Implicit+    RecoverCardinality (Bytes _) = 'Implicit+    RecoverCardinality Bool = 'Implicit+    RecoverCardinality Float = 'Implicit+    RecoverCardinality Double = 'Implicit++-- | Given the Haskell type used by features such as `Proto3.Suite.Class.MessageField`+-- to indicate the encoding of a message field, returns the corresponding type of kind+-- 'ProtoType', which for repeated types is the element type.  This type family is /not/+-- injective because multiple types are supported for fields of protobuf type @string@.+type family RecoverProtoType (haskellType :: Type) :: ProtoType+  where+    RecoverProtoType Int32 = 'Int32+    RecoverProtoType Int64 = 'Int64+    RecoverProtoType (Signed Int32) = 'SInt32+    RecoverProtoType (Signed Int64) = 'SInt64+    RecoverProtoType Word32 = 'UInt32+    RecoverProtoType Word64 = 'UInt64+    RecoverProtoType (Fixed Word32) = 'Fixed32+    RecoverProtoType (Fixed Word64) = 'Fixed64+    RecoverProtoType (Signed (Fixed Int32)) = 'SFixed32+    RecoverProtoType (Signed (Fixed Int64)) = 'SFixed64+    RecoverProtoType (String _) = 'String+    RecoverProtoType (Bytes _) = 'Bytes+    RecoverProtoType Bool = 'Bool+    RecoverProtoType Float = 'Float+    RecoverProtoType Double = 'Double+    RecoverProtoType (Commented _ haskellType) = RecoverProtoType haskellType+    RecoverProtoType (Maybe (ForceEmit haskellType)) = RecoverProtoType haskellType+    RecoverProtoType (PackedVec haskellType) = RecoverProtoType haskellType+    RecoverProtoType (UnpackedVec haskellType) = RecoverProtoType haskellType+    RecoverProtoType (Enumerated e) = 'Enumeration e+    RecoverProtoType (Nested m) = 'Message m+    RecoverProtoType (NestedVec m) = 'Message m+    RecoverProtoType (M.Map k v) = 'Map (RecoverProtoType k) (RecoverProtoType v)+    RecoverProtoType m = 'Message m++-- | Inhabited by Haskell types used by features such as `Proto3.Suite.Class.MessageField`+-- that correspond to particular protobuf types that are repeated in the specified way.+class ( RecoverCardinality haskellType ~ cardinality+      , RecoverProtoType haskellType ~ protoType+      ) =>+      MessageFieldType (cardinality :: Cardinality) (protoType :: ProtoType) (haskellType :: Type)++instance MessageFieldType 'Implicit 'Int32 Int32+instance MessageFieldType 'Implicit 'Int64 Int64+instance MessageFieldType 'Implicit 'SInt32 (Signed Int32)+instance MessageFieldType 'Implicit 'SInt64 (Signed Int64)+instance MessageFieldType 'Implicit 'UInt32 (Word32)+instance MessageFieldType 'Implicit 'UInt64  (Word64)+instance MessageFieldType 'Implicit 'Fixed32 (Fixed Word32)+instance MessageFieldType 'Implicit 'Fixed64 (Fixed Word64)+instance MessageFieldType 'Implicit 'SFixed32 (Signed (Fixed Int32))+instance MessageFieldType 'Implicit 'SFixed64 (Signed (Fixed Int64))+instance MessageFieldType 'Implicit 'String (String a)+instance MessageFieldType 'Implicit 'Bytes (Bytes a)+instance MessageFieldType 'Implicit 'Bool Bool+instance MessageFieldType 'Implicit 'Float Float+instance MessageFieldType 'Implicit 'Double Double+instance MessageFieldType 'Implicit ('Enumeration e) (Enumerated e)++instance MessageFieldType 'Optional 'Int32 (Maybe (ForceEmit Int32))+instance MessageFieldType 'Optional 'Int64 (Maybe (ForceEmit Int64))+instance MessageFieldType 'Optional 'SInt32 (Maybe (ForceEmit (Signed Int32)))+instance MessageFieldType 'Optional 'SInt64 (Maybe (ForceEmit (Signed Int64)))+instance MessageFieldType 'Optional 'UInt32 (Maybe (ForceEmit Word32))+instance MessageFieldType 'Optional 'UInt64  (Maybe (ForceEmit Word64))+instance MessageFieldType 'Optional 'Fixed32 (Maybe (ForceEmit (Fixed Word32)))+instance MessageFieldType 'Optional 'Fixed64 (Maybe (ForceEmit (Fixed Word64)))+instance MessageFieldType 'Optional 'SFixed32 (Maybe (ForceEmit (Signed (Fixed Int32))))+instance MessageFieldType 'Optional 'SFixed64 (Maybe (ForceEmit (Signed (Fixed Int64))))+instance MessageFieldType 'Optional 'String (Maybe (ForceEmit (String a)))+instance MessageFieldType 'Optional 'Bytes (Maybe (ForceEmit (Bytes a)))+instance MessageFieldType 'Optional 'Bool (Maybe (ForceEmit Bool))+instance MessageFieldType 'Optional 'Float (Maybe (ForceEmit Float))+instance MessageFieldType 'Optional 'Double (Maybe (ForceEmit Double))+instance MessageFieldType 'Optional ('Enumeration e) (Maybe (ForceEmit (Enumerated e)))++-- | Helps to diagnose the absence of an instance for 'MessageFieldType'+-- for optional submessages by requiring that the second type parameter+-- be 'Nested' of the first.  Please try to avoid using this type family+-- directly; it is exported only to help explain compilation errors.+type family OptionalMessageFieldType (m :: Type) (haskellType :: Type)+  where+    OptionalMessageFieldType m (Nested m) = (() :: Constraint)+    OptionalMessageFieldType m (Nested a) = TypeError+      ( 'Text "Expected reflected protobuf submessage type " ':<>: 'ShowType m ':$$:+        'Text "Actual type: " ':<>: 'ShowType a )+    OptionalMessageFieldType m haskellType = TypeError+      ( 'Text "When using a Haskell type to specify an optional protobuf submessage" ':$$:+        'Text "(as opposed to repeated one or a submessage within a oneof)" ':$$:+        'Text "you must wrap the Haskell reflection type in Proto3.Suite.Nested." ':$$:+        'Text "Expected reflected protobuf submessage type " ':<>: 'ShowType m ':$$:+        'Text "Haskell type provided: " ':<>: 'ShowType haskellType )++instance ( OptionalMessageFieldType m haskellType+         , RecoverCardinality haskellType ~ 'Optional+         , RecoverProtoType haskellType ~ 'Message m+         ) =>+         MessageFieldType 'Optional ('Message m) haskellType++instance MessageFieldType ('Repeated 'Unpacked) 'Int32 (UnpackedVec Int32)+instance MessageFieldType ('Repeated 'Unpacked) 'Int64 (UnpackedVec Int64)+instance MessageFieldType ('Repeated 'Unpacked) 'SInt32 (UnpackedVec (Signed Int32))+instance MessageFieldType ('Repeated 'Unpacked) 'SInt64 (UnpackedVec (Signed Int64))+instance MessageFieldType ('Repeated 'Unpacked) 'UInt32 (UnpackedVec (Word32))+instance MessageFieldType ('Repeated 'Unpacked) 'UInt64 (UnpackedVec (Word64))+instance MessageFieldType ('Repeated 'Unpacked) 'Fixed32 (UnpackedVec (Fixed Word32))+instance MessageFieldType ('Repeated 'Unpacked) 'Fixed64 (UnpackedVec (Fixed Word64))+instance MessageFieldType ('Repeated 'Unpacked) 'SFixed32 (UnpackedVec (Signed (Fixed Int32)))+instance MessageFieldType ('Repeated 'Unpacked) 'SFixed64 (UnpackedVec (Signed (Fixed Int64)))+instance MessageFieldType ('Repeated 'Unpacked) 'String (UnpackedVec (String a))+instance MessageFieldType ('Repeated 'Unpacked) 'Bytes (UnpackedVec (Bytes a))+instance MessageFieldType ('Repeated 'Unpacked) 'Bool (UnpackedVec Bool)+instance MessageFieldType ('Repeated 'Unpacked) 'Float (UnpackedVec Float)+instance MessageFieldType ('Repeated 'Unpacked) 'Double (UnpackedVec Double)+instance MessageFieldType ('Repeated 'Unpacked) ('Enumeration e) (UnpackedVec (Enumerated e))++-- | Helps to diagnose the absence of an instance for 'MessageFieldType'+-- for repeated submessages by requiring that the second type parameter+-- be 'NestedVec' of the first.  Please try to avoid using this type family+-- directly; it is exported only to help explain compilation errors.+type family RepeatedMessageFieldType (m :: Type) (haskellType :: Type)+  where+    RepeatedMessageFieldType m (NestedVec m) = (() :: Constraint)+    RepeatedMessageFieldType m (NestedVec a) = TypeError+      ( 'Text "Expected reflected protobuf submessage type " ':<>: 'ShowType m ':$$:+        'Text "Actual type: " ':<>: 'ShowType a )+    RepeatedMessageFieldType m haskellType = TypeError+      ( 'Text "When using a Haskell type to specify a repeated protobuf submessage" ':$$:+        'Text "(as opposed to an optional one or a submessage within a oneof)" ':$$:+        'Text "you must wrap the Haskell reflection type in Proto3.Suite.NestedVec." ':$$:+        'Text "Expected reflected protobuf submessage type " ':<>: 'ShowType m ':$$:+        'Text "Haskell type provided: " ':<>: 'ShowType haskellType )++instance ( RepeatedMessageFieldType m haskellType+         , RecoverCardinality haskellType ~ 'Repeated 'Unpacked+         , RecoverProtoType haskellType ~ 'Message m+         ) =>+         MessageFieldType ('Repeated 'Unpacked) ('Message m) haskellType++instance ( MessageFieldType 'Implicit k kh+         , MessageFieldType (CardinalityOfMapped v) v vh+         ) =>+         MessageFieldType ('Repeated 'Unpacked) ('Map k v) (M.Map kh vh)++instance MessageFieldType ('Repeated 'Packed) 'Int32 (PackedVec Int32)+instance MessageFieldType ('Repeated 'Packed) 'Int64 (PackedVec Int64)+instance MessageFieldType ('Repeated 'Packed) 'SInt32 (PackedVec (Signed Int32))+instance MessageFieldType ('Repeated 'Packed) 'SInt64 (PackedVec (Signed Int64))+instance MessageFieldType ('Repeated 'Packed) 'UInt32 (PackedVec (Word32))+instance MessageFieldType ('Repeated 'Packed) 'UInt64 (PackedVec (Word64))+instance MessageFieldType ('Repeated 'Packed) 'Fixed32 (PackedVec (Fixed Word32))+instance MessageFieldType ('Repeated 'Packed) 'Fixed64 (PackedVec (Fixed Word64))+instance MessageFieldType ('Repeated 'Packed) 'SFixed32 (PackedVec (Signed (Fixed Int32)))+instance MessageFieldType ('Repeated 'Packed) 'SFixed64 (PackedVec (Signed (Fixed Int64)))+instance MessageFieldType ('Repeated 'Packed) 'Bool (PackedVec Bool)+instance MessageFieldType ('Repeated 'Packed) 'Float (PackedVec Float)+instance MessageFieldType ('Repeated 'Packed) 'Double (PackedVec Double)+instance MessageFieldType ('Repeated 'Packed) ('Enumeration e) (PackedVec (Enumerated e))
+ src/Proto3/Suite/Form/Encode.hs view
@@ -0,0 +1,573 @@+{-# 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 = UnsafeMessageEncoder . 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 (Generic)+  deriving newtype (NFData)++type role MessageEncoding nominal++instance FieldForm 'Optional ('Message inner) (Identity (MessageEncoding inner))+  where+    fieldForm rep ty !fn (Identity e) = fieldForm rep ty fn (Identity (cachedMessageEncoding 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 rep ty !fn (Identity a) = fieldForm rep ty fn (Identity (cachedMessageEncoding 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 = UnsafeMessageEncoding . messageEncoderToByteString++-- | Encodes a precomputed 'MessageEncoder' by copying octets from a memory buffer.+-- See 'cacheMessageEncoding'.+--+-- See also: 'cachedFieldsEncoding'+cachedMessageEncoding :: MessageEncoding message -> MessageEncoder message+cachedMessageEncoding = unsafeByteStringToMessageEncoder . messageEncodingToByteString++-- | Strips type information from the message encoding, leaving only its octets.+messageEncodingToByteString :: MessageEncoding message -> B.ByteString+messageEncodingToByteString (UnsafeMessageEncoding octets) = 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 = 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 { 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 =+  UnsafeFieldsEncoding . BL.toStrict . Encode.toLazyByteString . 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 = UnsafeFieldsEncoder . Encode.unsafeFromByteString . 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 rep _ !fn x = fieldForm rep (proxy# :: Proxy# 'Int32) fn (fromProtoEnum x)+    {-# INLINE fieldForm #-}++instance ( ProtoEnum e+         , FieldForm 'Optional 'Int32 (Identity Int32)+         ) =>+         FieldForm 'Optional ('Enumeration e) (Identity e)+  where+    fieldForm rep _ !fn (Identity x) =+      fieldForm rep (proxy# :: Proxy# 'Int32) fn (Identity (fromProtoEnum x))+    {-# INLINE fieldForm #-}++instance ( ProtoEnum e+         , FieldForm 'Implicit 'Int32 Int32+         ) =>+         FieldForm 'Implicit ('Enumeration e) (Enumerated e)+  where+    fieldForm rep _ !fn x = fieldForm rep (proxy# :: Proxy# 'Int32) fn (codeFromEnumerated x)+    {-# INLINE fieldForm #-}++instance ( ProtoEnum e+         , FieldForm 'Optional 'Int32 (Identity Int32)+         ) =>+         FieldForm 'Optional ('Enumeration e) (Identity (Enumerated e))+  where+    fieldForm rep _ !fn (Identity x) =+      fieldForm rep (proxy# :: Proxy# 'Int32) fn (Identity (codeFromEnumerated x))+    {-# INLINE fieldForm #-}++instance ProtoEnum e =>+         PackedFieldForm ('Enumeration e) e+  where+    packedFieldForm _ !fn xs =+      packedFieldForm (proxy# :: Proxy# 'Int32) fn (fmap fromProtoEnum xs)+    {-# INLINE packedFieldForm #-}++instance ProtoEnum e =>+         PackedFieldForm ('Enumeration e) (Enumerated e)+  where+    packedFieldForm _ !fn xs =+      packedFieldForm (proxy# :: Proxy# 'Int32) fn (fmap codeFromEnumerated xs)+    {-# INLINE packedFieldForm #-}++instance FieldForm 'Optional 'Bytes (Identity RB.BuildR)+  where+    fieldForm _ _ = coerce+      @(FieldNumber -> RB.BuildR -> Encode.MessageBuilder)+      @(FieldNumber -> Identity RB.BuildR -> Encode.MessageBuilder)+      Encode.bytes+    {-# INLINE fieldForm #-}++instance FieldForm 'Implicit 'Bytes RB.BuildR+  where+    fieldForm _ _ = 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 prefixes =+  UnsafeFieldsEncoder (Encode.repeatedMessageBuilder (mapRepeated untypedFieldsEncoder 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 = 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 = 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 _ _ = coerce (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 m = coerce (encodeMessage @message (fieldNumber 1) 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 m = cacheMessageEncoding (messageReflection m)+{-# INLINABLE messageCache #-}++instance (Message message, Show message) =>+         Show (MessageEncoding message)+  where+    showsPrec d (messageEncodingToByteString -> bs) = showParen (d >= 11) $+      case fromByteString bs of+        Left _ -> shows 'unsafeByteStringToMessageEncoding . showChar ' ' . showsPrec 11 bs+        Right (msg :: message) -> shows 'messageCache . showChar ' ' . showsPrec 11 msg++instance (Message message, Show message) =>+         Show (MessageEncoder message)+  where+    showsPrec d (messageEncoderToByteString -> bs) = showParen (d >= 11) $+      case fromByteString bs of+        Left _ -> shows 'unsafeByteStringToMessageEncoder . showChar ' ' . showsPrec 11 bs+        Right (msg :: message) -> shows 'messageReflection . showChar ' ' . showsPrec 11 msg++instance (Message message, JSONPB.ToJSONPB message) =>+         JSONPB.ToJSONPB (MessageEncoding message)+  where+    toJSONPB (messageEncodingToByteString -> bs) opts =+      case fromByteString bs of+        Left _ -> JSONPB.toJSONPB @B.ByteString bs opts+        Right (msg :: message) -> JSONPB.toJSONPB @message msg opts++    toEncodingPB (messageEncodingToByteString -> bs) opts =+      case fromByteString bs of+        Left _ -> JSONPB.toEncodingPB @B.ByteString bs opts+        Right (msg :: message) -> JSONPB.toEncodingPB @message msg opts++instance (Message message, JSONPB.ToJSONPB message) =>+         JSONPB.ToJSONPB (MessageEncoder message)+  where+    toJSONPB = JSONPB.toJSONPB @(MessageEncoding message) . cacheMessageEncoding+    toEncodingPB = JSONPB.toEncodingPB @(MessageEncoding message) . cacheMessageEncoding++instance (Message message, JSONPB.FromJSONPB message) =>+         JSONPB.FromJSONPB (MessageEncoding message)+  where+    parseJSONPB v =+      messageCache <$> JSONPB.parseJSONPB @message v <|>+      unsafeByteStringToMessageEncoding <$> JSONPB.parseJSONPB @B.ByteString v++instance (Message message, JSONPB.FromJSONPB message) =>+         JSONPB.FromJSONPB (MessageEncoder message)+  where+    parseJSONPB v =+      messageReflection <$> JSONPB.parseJSONPB @message v <|>+      unsafeByteStringToMessageEncoder <$> JSONPB.parseJSONPB @B.ByteString v++instance (Message message, JSONPB.ToJSONPB message) =>+         Aeson.ToJSON (MessageEncoding message)+  where+    toJSON = JSONPB.toAesonValue+    toEncoding = JSONPB.toAesonEncoding++instance (Message message, JSONPB.ToJSONPB message) =>+         Aeson.ToJSON (MessageEncoder message)+  where+    toJSON = JSONPB.toAesonValue+    toEncoding = JSONPB.toAesonEncoding++instance (Message message, JSONPB.FromJSONPB message) =>+         Aeson.FromJSON (MessageEncoding message)+  where+    parseJSON = JSONPB.parseJSONPB++instance (Message message, JSONPB.FromJSONPB message) =>+         Aeson.FromJSON (MessageEncoder message)+  where+    parseJSON = JSONPB.parseJSONPB
+ src/Proto3/Suite/Form/Encode/Core.hs view
@@ -0,0 +1,778 @@+{-# 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+  { 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 = Encode.toLazyByteString . 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 = BL.toStrict . messageEncoderToLazyByteString++-- | Like 'Encode.etaMessageBuilder' but for 'MessageEncoder'.+etaMessageEncoder :: forall a message . (a -> MessageEncoder message) -> a -> MessageEncoder message+etaMessageEncoder = coerce (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 { 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 = UnsafeFieldsEncoder mempty+    f . g = UnsafeFieldsEncoder (untypedFieldsEncoder f <> untypedFieldsEncoder g)++-- | Like 'Encode.etaMessageBuilder' but for 'FieldsEncoder'.+etaFieldsEncoder ::+  forall a message possible following .+  (a -> FieldsEncoder message possible following) ->+  a -> FieldsEncoder message possible following+etaFieldsEncoder = coerce (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 = UnsafeMessageEncoder . 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 = UnsafeFieldsEncoder mempty++-- | Singleton field number type.+newtype SFieldNumber (fieldNumber :: Nat)+  = UnsafeSFieldNumber { 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 =+      UnsafeSFieldNumber (fieldNumber (fromInteger (natVal' (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 = untypedSFieldNumber (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 = coerce+      @(a -> Encode.MessageBuilder)+      @(a -> FieldsEncoder message names (Occupy message name names))+      (fieldForm @(CardinalityOf message name) @(ProtoTypeOf message name) @a+                 proxy# proxy# (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 rep ty !fn = Encode.etaMessageBuilder $+      foldMap @Maybe (fieldForm rep ty fn . Identity)+    {-# INLINE fieldForm #-}++instance ( ToRepeated c e+         , FieldForm 'Optional protoType (Identity e)+         ) =>+         FieldForm ('Repeated 'Unpacked) protoType c+  where+    fieldForm _ ty !fn = Encode.etaMessageBuilder $+      Encode.repeatedMessageBuilder .+      mapRepeated (fieldForm (proxy# :: Proxy# 'Optional) ty fn . 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 _ ty !fn (toRepeated -> !xs@(ReverseRepeated prediction reversed)) =+        case prediction of+          Just count+            | 2 <= count -> packedFieldForm ty fn xs  -- multiple packed elements+            | otherwise -> fieldForm (proxy# :: Proxy# ('Repeated 'Unpacked)) ty fn xs  -- 0 or 1+          Nothing -> case foldr singletonOp Empty reversed of+            Empty -> mempty  -- 0 elements can be expressed implicitly+            Singleton x -> fieldForm (proxy# :: Proxy# 'Optional) ty fn (Identity x) -- unpacked+            Multiple -> packedFieldForm ty fn xs  -- multiple packed elements+      where+        singletonOp :: a -> Singleton a -> Singleton a+        singletonOp x Empty = Singleton x+        singletonOp _ _ = Multiple+    {-# INLINE fieldForm #-}++data Singleton a = Empty | Singleton a | Multiple++instance FieldForm 'Optional ('Message inner) (Identity (MessageEncoder inner))+  where+    fieldForm _ _ !fn (Identity e) = Encode.embedded fn (untypedMessageEncoder 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 _ _ !fn (Identity a) = Encode.embedded fn (untypedMessageEncoder 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 { unwrap :: a }+  deriving stock (Foldable, Functor, Generic, Traversable)+  deriving newtype (Bounded, Enum, Eq, Fractional, Integral, Ord, Num, Read, Real, Show)++instance FieldForm 'Implicit protoType a =>+         FieldForm 'Optional ('Message (Wrapper protoType)) (Identity (Wrap a))+  where+    fieldForm _ ty !fn (Identity (Wrap x)) =+      fieldForm (proxy# :: Proxy# 'Optional) ty fn+                (Identity (fieldsToMessage @(Wrapper protoType) (field @"value" 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 { unauto :: a }+  deriving stock (Foldable, Functor, Generic, Traversable)+  deriving newtype (Bounded, Enum, Eq, Fractional, Integral, Ord, Num, Read, Real, 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 protoType elementType encoder packedEncoder promotions hasWrapper = do+  direct <-+    [d|++      instance FieldForm 'Optional $protoType (Identity $elementType)+        where+          fieldForm _ _ = coerce+            @(FieldNumber -> $elementType -> Encode.MessageBuilder)+            @(FieldNumber -> Identity $elementType -> Encode.MessageBuilder)+            $encoder+          {-# INLINE fieldForm #-}++      instance FieldForm 'Implicit $protoType $elementType+        where+          fieldForm _ ty !fn x+            | isDefault x = mempty+            | otherwise = fieldForm (proxy# :: Proxy# 'Optional) ty fn (Identity x)+          {-# INLINE fieldForm #-}++      instance (a ~ $elementType) =>+               FieldForm 'Optional $protoType (Identity (Auto a))+        where+          fieldForm = coerce (fieldForm @'Optional @($protoType) @(Identity a))+          {-# INLINE fieldForm #-}++      instance (a ~ $elementType) =>+               FieldForm 'Implicit $protoType (Auto a)+        where+          fieldForm = coerce (fieldForm @'Implicit @($protoType) @a)+          {-# INLINE fieldForm #-}++      instance PackedFieldForm $protoType $elementType+        where+          packedFieldForm _ = $packedEncoder+          {-# INLINE packedFieldForm #-}++      instance (a ~ $elementType) =>+               PackedFieldForm $protoType (Auto a)+        where+          packedFieldForm = coerce (packedFieldForm @($protoType) @a)+          {-# INLINE packedFieldForm #-}++      |]++  promoted <- for promotions $ \(supportedType, conversion, compatibleProtoType) ->+    [d|++      instance FieldForm 'Optional $protoType (Identity $supportedType)+        where+          fieldForm rep _ !fn (Identity x) =+            fieldForm rep (proxy# :: Proxy# $compatibleProtoType) fn (Identity ($conversion x))+          {-# INLINE fieldForm #-}++      instance FieldForm 'Implicit $protoType $supportedType+        where+          fieldForm rep _ !fn x =+            fieldForm rep (proxy# :: Proxy# $compatibleProtoType) fn ($conversion x)+          {-# INLINE fieldForm #-}++      instance PackedFieldForm $protoType $supportedType+        where+          packedFieldForm _ !fn xs =+            packedFieldForm (proxy# :: Proxy# $compatibleProtoType) fn (fmap $conversion xs)+          {-# INLINE packedFieldForm #-}++      |]++  wrapped <- if not hasWrapper then pure [] else+    [d|++      instance FieldForm 'Optional ('Message (Wrapper $protoType)) (Identity $elementType)+        where+          fieldForm = coerce+            (fieldForm @'Optional @('Message (Wrapper $protoType)) @(Identity (Wrap $elementType)))+          {-# INLINE fieldForm #-}++      instance (a ~ $elementType) =>+               FieldForm 'Optional ('Message (Wrapper $protoType)) (Identity (Auto a))+        where+          fieldForm = coerce+            (fieldForm @'Optional @('Message (Wrapper $protoType)) @(Identity (Wrap a)))+          {-# INLINE fieldForm #-}++      |]++  wrappedPromoted <- if not hasWrapper then pure [] else+    for promotions $ \(supportedType, _, _) -> do+      [d|++        instance FieldForm 'Optional ('Message (Wrapper $protoType)) (Identity $supportedType)+          where+            fieldForm = coerce+              (fieldForm @'Optional @('Message (Wrapper $protoType)) @(Identity (Wrap $supportedType)))+            {-# INLINE fieldForm #-}++        |]++  pure $ direct ++ concat promoted ++ wrapped ++ concat 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 protoType argumentType encoder additional = do+  preferred <- [d|++    instance FieldForm 'Optional $protoType (Identity $argumentType)+      where+        fieldForm _ _ = coerce+          @(FieldNumber -> $argumentType -> Encode.MessageBuilder)+          @(FieldNumber -> Identity $argumentType -> Encode.MessageBuilder)+          $encoder+        {-# INLINE fieldForm #-}++    instance FieldForm 'Implicit $protoType $argumentType+      where+        fieldForm _ ty !fn x+          | isDefault x = mempty+          | otherwise = fieldForm (proxy# :: Proxy# 'Optional) ty fn (Identity x)+        {-# INLINE fieldForm #-}++    instance (a ~ $argumentType) =>+             FieldForm 'Optional $protoType (Identity (Auto a))+      where+        fieldForm = coerce (fieldForm @'Optional @($protoType) @(Identity a))+        {-# INLINE fieldForm #-}++    instance (a ~ $argumentType) =>+             FieldForm 'Implicit $protoType (Auto a)+      where+        fieldForm = coerce (fieldForm @'Implicit @($protoType) @a)+        {-# INLINE fieldForm #-}++    instance FieldForm 'Optional ('Message (Wrapper $protoType)) (Identity $argumentType)+      where+        fieldForm = coerce+          (fieldForm @'Optional @('Message (Wrapper $protoType)) @(Identity (Wrap $argumentType)))+        {-# INLINE fieldForm #-}++    instance (a ~ $argumentType) =>+             FieldForm 'Optional ('Message (Wrapper $protoType)) (Identity (Auto a))+      where+        fieldForm = coerce+          (fieldForm @'Optional @('Message (Wrapper $protoType)) @(Identity (Wrap a)))+        {-# INLINE fieldForm #-}++    |]++  supported <- for additional $ \(supportedType, additionalEncoder) -> [d|++    instance FieldForm 'Optional $protoType (Identity $supportedType)+      where+        fieldForm _ _ = coerce+          @(FieldNumber -> $supportedType -> Encode.MessageBuilder)+          @(FieldNumber -> Identity $supportedType -> Encode.MessageBuilder)+          $additionalEncoder+        {-# INLINE fieldForm #-}++    instance FieldForm 'Implicit $protoType $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 $protoType)) (Identity $supportedType)+      where+        fieldForm = coerce+          (fieldForm @'Optional @('Message (Wrapper $protoType)) @(Identity (Wrap $supportedType)))+        {-# INLINE fieldForm #-}++    |]++  pure $ preferred ++ concat supported
+ src/Proto3/Suite/Haskell/Parser.hs view
@@ -0,0 +1,248 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE ViewPatterns #-}++module Proto3.Suite.Haskell.Parser+  ( Logger+  , initLogger+  , parseModule+  , renderSDoc+  ) where++import qualified GHC.Data.EnumSet as EnumSet+import GHC.Data.StringBuffer (StringBuffer)+import GHC.Driver.Session (languageExtensions)+import qualified GHC.Hs+import qualified GHC.Parser+import GHC.Parser.Lexer (P(..), PState, ParseResult(..))+import GHC.Types.SrcLoc (Located, RealSrcLoc)+import GHC.Utils.Outputable (SDoc)++#if MIN_VERSION_ghc_lib_parser(9,8,0)+import qualified GHC.Driver.Errors (printMessages)+import GHC.Parser.Errors.Types (PsMessage)+import GHC.Parser.Lexer (getPsMessages, initParserState, mkParserOpts)+import GHC.Types.Error (Messages, NoDiagnosticOpts(..), partitionMessages, unionMessages)+import GHC.Utils.Error (DiagOpts, emptyDiagOpts)+import GHC.Utils.Logger (Logger, initLogger)+import GHC.Utils.Outputable (defaultSDocContext, renderWithContext)+#elif MIN_VERSION_ghc_lib_parser(9,6,0)+import qualified GHC.Driver.Errors (printMessages)+import GHC.Parser.Errors.Types (PsMessage)+import GHC.Parser.Lexer (getPsMessages, initParserState, mkParserOpts)+import GHC.Types.Error (Messages, NoDiagnosticOpts(..), partitionMessages, unionMessages)+import GHC.Utils.Error (DiagOpts(..))+import GHC.Utils.Logger (Logger, initLogger)+import GHC.Utils.Outputable (defaultSDocContext, renderWithContext)+#elif MIN_VERSION_ghc_lib_parser(9,4,0)+import qualified GHC.Driver.Errors (printMessages)+import GHC.Parser.Errors.Types (PsMessage)+import GHC.Parser.Lexer (getPsMessages, initParserState, mkParserOpts)+import GHC.Types.Error (Messages, partitionMessages, unionMessages)+import GHC.Utils.Error (DiagOpts(..))+import GHC.Utils.Logger (Logger, initLogger)+import GHC.Utils.Outputable (defaultSDocContext, renderWithContext)+#else+import Control.Arrow ((***))+import Data.Foldable (traverse_)+import GHC.ByteOrder (targetByteOrder)+import GHC.Data.Bag (Bag)+import GHC.Driver.Session+         (DynFlags(..), FileSettings(..), GhcNameVersion(..),+          LlvmConfig(..), Settings(..), defaultDynFlags)+import GHC.Parser.Errors.Ppr (pprError, pprWarning)+import GHC.Parser.Lexer (getMessages, initParserState, mkParserOpts)+import GHC.Platform (ArchOS(..))+import GHC.Settings (Platform(..), PlatformMisc(..), ToolSettings(..))+import GHC.Types.Error (DecoratedSDoc, MsgEnvelope(..), renderDiagnostic)+import GHC.Utils.Error (formatBulleted, sortMsgBag)+import GHC.Utils.Fingerprint (fingerprint0)+import GHC.Utils.Logger (Logger, initLogger, putLogMsg)+import GHC.Utils.Outputable (defaultSDocContext, mkErrStyle, renderWithContext, withPprStyle)+#endif++-- | Parses the module with the specified location and content,+-- returning 'Nothing' on parse failure.  Errors and warnings+-- are sent to the given 'Logger', except on GHC 9.0, which+-- would require a 'DynFlags' in order to report messages.+-- Unfortunately, creating a 'DynFlags' would require a directory+-- containing a GHC installation; we do not wish to require that.+parseModule ::+  Logger ->+  RealSrcLoc ->+  StringBuffer ->+  IO (Maybe (Located (GHC.Hs.HsModule+#if MIN_VERSION_ghc_lib_parser(9,6,0)+                                      GHC.Hs.GhcPs+#endif+                     )))+parseModule logger location input = do+    case unP GHC.Parser.parseModule initialState of+      POk _finalState m -> do+        printWarningsAndErrors logger diagOpts _finalState+        pure (Just m)+      PFailed _finalState -> do+        printWarningsAndErrors logger diagOpts _finalState+        pure Nothing+  where+    exts = EnumSet.fromList (languageExtensions Nothing)+#if MIN_VERSION_ghc_lib_parser(9,4,0)+    diagOpts =+#if MIN_VERSION_ghc_lib_parser(9,8,0)+      emptyDiagOpts+#else+      DiagOpts+        { diag_warning_flags = mempty+        , diag_fatal_warning_flags = mempty+        , diag_warn_is_error = False+        , diag_reverse_errors = False+        , diag_max_errors = Nothing+        , diag_ppr_ctx = defaultSDocContext+        }+#endif+    parserOpts = mkParserOpts exts diagOpts [] False True True True+    initialState = initParserState parserOpts input location+#else+    diagOpts = DiagOpts+    parserOpts = mkParserOpts EnumSet.empty exts False True True True+    initialState = initParserState parserOpts input location+#endif++printWarningsAndErrors :: Logger -> DiagOpts -> PState -> IO ()+printWarningsAndErrors logger diagOpts state = do+#if MIN_VERSION_ghc_lib_parser(9,4,0)+  let (ws, es) = getPsMessages state+  let (warnings, unionMessages es -> errors) = partitionMessages ws+#else+  let (warnings, errors) = (fmap pprWarning *** fmap pprError) (getMessages state)+#endif+  printMessages logger diagOpts warnings+  printMessages logger diagOpts errors++#if MIN_VERSION_ghc_lib_parser(9,6,0)++printMessages :: Logger -> DiagOpts -> Messages PsMessage -> IO ()+printMessages logger = GHC.Driver.Errors.printMessages logger NoDiagnosticOpts++#elif MIN_VERSION_ghc_lib_parser(9,4,0)++printMessages :: Logger -> DiagOpts -> Messages PsMessage -> IO ()+printMessages = GHC.Driver.Errors.printMessages++#else++printMessages :: Logger -> DiagOpts -> Bag (MsgEnvelope DecoratedSDoc) -> IO ()+printMessages logger _ = traverse_ report . sortMsgBag Nothing+  where+    report MsgEnvelope+             { errMsgContext = errCtxt+             , errMsgDiagnostic = diagnostic+             , errMsgReason = reason+             , errMsgSeverity = severity+             , errMsgSpan = sp } =+        putLogMsg logger renderingDynFlags reason severity sp $+          withPprStyle (mkErrStyle errCtxt) $+            formatBulleted defaultSDocContext (renderDiagnostic diagnostic)++#endif++renderSDoc :: SDoc -> String+renderSDoc = renderWithContext defaultSDocContext++#if !MIN_VERSION_ghc_lib_parser(9,4,0)++data DiagOpts = DiagOpts++-- | 'DynFlags' suitable only for rendering+-- Haskell source and diagnostic messages.+--+-- NOTE: For use with GHC 9.0 only.  These flags are rather questionable+-- all of the tools direction information consists of placeholders so+-- that compile-proto-file does not require an actual GHC installation.+renderingDynFlags :: DynFlags+renderingDynFlags = defaultDynFlags placeholderSettings placeholderLlvmConfig+  where+    archUnknown = read "ArchUnknown"+    osUnknown = read "OSUnknown"+    placeholderSettings = Settings+      { sGhcNameVersion = GhcNameVersion "compile-proto-file" "v?"+      , sFileSettings = FileSettings+        { fileSettings_ghcUsagePath = mempty+        , fileSettings_ghciUsagePath = mempty+        , fileSettings_toolDir = Nothing+        , fileSettings_topDir = mempty+        , fileSettings_tmpDir = mempty+        , fileSettings_globalPackageDatabase = mempty+        }+      , sTargetPlatform = Platform+        { platformArchOS = ArchOS archUnknown osUnknown+        , platformWordSize = read "8"+        , platformByteOrder = targetByteOrder+        , platformUnregisterised = True+        , platformHasGnuNonexecStack = False+        , platformHasIdentDirective = False+        , platformHasSubsectionsViaSymbols = False+        , platformIsCrossCompiling = True+        , platformLeadingUnderscore = True+        , platformTablesNextToCode = False+        , platform_constants = Nothing+        }+      , sToolSettings = ToolSettings+        { toolSettings_ldSupportsCompactUnwind = False+        , toolSettings_ldSupportsBuildId = False+        , toolSettings_ldSupportsFilelist = False+        , toolSettings_ldIsGnuLd = False+        , toolSettings_ccSupportsNoPie = False+        , toolSettings_pgm_L = mempty+        , toolSettings_pgm_P = mempty+        , toolSettings_pgm_F = mempty+        , toolSettings_pgm_c = mempty+        , toolSettings_pgm_a = mempty+        , toolSettings_pgm_l = mempty+        , toolSettings_pgm_lm = mempty+        , toolSettings_pgm_dll = mempty+        , toolSettings_pgm_T = mempty+        , toolSettings_pgm_windres = mempty+        , toolSettings_pgm_libtool = mempty+        , toolSettings_pgm_ar = mempty+        , toolSettings_pgm_otool = mempty+        , toolSettings_pgm_install_name_tool = mempty+        , toolSettings_pgm_ranlib = mempty+        , toolSettings_pgm_lo = mempty+        , toolSettings_pgm_lc = mempty+        , toolSettings_pgm_lcc = mempty+        , toolSettings_pgm_i = mempty+        , toolSettings_opt_L = mempty+        , toolSettings_opt_P = mempty+        , toolSettings_opt_P_fingerprint = fingerprint0+        , toolSettings_opt_F = mempty+        , toolSettings_opt_c = mempty+        , toolSettings_opt_cxx = mempty+        , toolSettings_opt_a = mempty+        , toolSettings_opt_l = mempty+        , toolSettings_opt_lm = mempty+        , toolSettings_opt_windres = mempty+        , toolSettings_opt_lo = mempty+        , toolSettings_opt_lc = mempty+        , toolSettings_opt_lcc = mempty+        , toolSettings_opt_i = mempty+        , toolSettings_extraGccViaCFlags = mempty+        }+      , sPlatformMisc = PlatformMisc+        { platformMisc_targetPlatformString = mempty+        , platformMisc_ghcWithInterpreter = False+        , platformMisc_ghcWithSMP = False+        , platformMisc_ghcRTSWays = mempty+        , platformMisc_libFFI = False+        , platformMisc_ghcRtsWithLibdw = False+        , platformMisc_llvmTarget = mempty+        }+      , sRawSettings = mempty+      }++    placeholderLlvmConfig = LlvmConfig+      { llvmTargets = mempty+      , llvmPasses = mempty+      }++#endif
src/Proto3/Suite/JSONPB/Class.hs view
@@ -70,7 +70,7 @@                                                         ToJSON (..), Value (..),                                                         ToJSON1(..), FromJSON1(..),                                                         ToJSONKey(..),-                                                        decode, eitherDecode, json,+                                                        decode, eitherDecode,                                                         (.!=)) import qualified Data.Aeson.Encoding              as E import qualified Data.Aeson.Encoding.Internal     as E@@ -80,7 +80,7 @@ #if MIN_VERSION_aeson(2,0,0) import qualified Data.Aeson.Key                   as A #endif-import qualified Data.Aeson.Parser                as A (eitherDecodeWith)+import qualified Data.Aeson.Parser                as A (eitherDecodeWith, json) import qualified Data.Aeson.Types                 as A (Object, Pair, Parser,                                                         Series,                                                         explicitParseField,@@ -117,9 +117,9 @@ import           Proto3.Suite.Class               (HasDefault (def, isDefault),                                                    Named (nameOf)) import           Proto3.Suite.Types               (Enumerated(..), Fixed(..),-                                                   Nested(..), NestedVec(..),-                                                   PackedVec(..), Signed(..),-                                                   UnpackedVec(..))+                                                   ForceEmit(..), Nested(..),+                                                   NestedVec(..), PackedVec(..),+                                                   Signed(..), UnpackedVec(..)) import qualified Proto3.Suite.Types import           Proto3.Wire.Class                (ProtoEnum(..)) import           Test.QuickCheck.Arbitrary        (Arbitrary(..))@@ -551,6 +551,12 @@ deriving via (Maybe a) instance ToJSONPB a => ToJSONPB (Nested a)  --------------------------------------------------------------------------------+-- Instances for optional fields++deriving newtype instance FromJSONPB a => FromJSONPB (ForceEmit a)+deriving newtype instance ToJSONPB a => ToJSONPB (ForceEmit a)++-------------------------------------------------------------------------------- -- Instances for map  deriving newtype instance A.FromJSONKey a => A.FromJSONKey (Fixed a)@@ -588,11 +594,23 @@ #endif  instance (A.ToJSONKey k, ToJSONPB k, ToJSONPB v) => ToJSONPB (M.Map k v) where-  toJSONPB m opts = A.liftToJSON @(M.Map k) (`toJSONPB` opts) (A.Array . V.fromList . map (`toJSONPB` opts)) m-  toEncodingPB m opts = A.liftToEncoding @(M.Map k) (`toEncodingPB` opts) (E.list (`toEncodingPB` opts)) m+  toJSONPB m opts = A.liftToJSON @(M.Map k)+#if MIN_VERSION_aeson(2,2,0)+                      (const False)  -- Unless and until we test for the protobuf default value.+#endif+                         (`toJSONPB` opts) (A.Array . V.fromList . map (`toJSONPB` opts)) m+  toEncodingPB m opts = A.liftToEncoding @(M.Map k)+#if MIN_VERSION_aeson(2,2,0)+                          (const False)  -- Unless and until we test for the protobuf default value.+#endif+                            (`toEncodingPB` opts) (E.list (`toEncodingPB` opts)) m  instance (Ord k, A.FromJSONKey k, FromJSONPB k, FromJSONPB v) => FromJSONPB (M.Map k v) where-  parseJSONPB = A.liftParseJSON @(M.Map k) parseJSONPB parseList+  parseJSONPB = A.liftParseJSON @(M.Map k)+#if MIN_VERSION_aeson(2,2,0)+                  Nothing  -- Unless and until we decide to use the protobuf default value.+#endif+                    parseJSONPB parseList     where       parseList (A.Array a) = traverse parseJSONPB (V.toList a)       parseList v = A.typeMismatch "not a list" v
src/Proto3/Suite/Types.hs view
@@ -2,12 +2,12 @@ {-# LANGUAGE DeriveFunctor #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveTraversable #-}+{-# LANGUAGE ExplicitNamespaces #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeOperators #-}-{-# LANGUAGE ExplicitNamespaces #-}  module Proto3.Suite.Types   (@@ -17,6 +17,8 @@    -- * Enumerable Types   , Enumerated(..)+  , codeFromEnumerated+  , codeToEnumerated    -- * String and Bytes Types   , String(..)@@ -34,7 +36,7 @@ import           Control.Applicative import           Control.DeepSeq (NFData) import           GHC.Exts (IsList(..))-import           GHC.Generics+import           GHC.Generics (Generic) import           Data.Function (on) import           Data.Int (Int32) import qualified Data.Vector as V@@ -73,6 +75,18 @@     i <- arbitrary     return . Enumerated $ maybe (Left i) Right (toProtoEnumMay i) +-- | Pass through those values that are outside the enum range;+-- this is for forward compatibility as enumerations are extended.+codeFromEnumerated :: ProtoEnum e => Enumerated e -> Int32+codeFromEnumerated = either id fromProtoEnum . enumerated+{-# INLINE codeFromEnumerated #-}++-- | Values inside the enum range are in Right, the rest in Left;+-- this is for forward compatibility as enumerations are extended.+codeToEnumerated :: ProtoEnum e => Int32 -> Enumerated e+codeToEnumerated code = Enumerated (maybe (Left code) Right (toProtoEnumMay code))+{-# INLINE codeToEnumerated #-}+ -- | 'String' provides a way to indicate that the given type expresses -- a Protobuf string scalar.  @'String' a@ may have type class instances -- that are more specific to Protobuf uses than those of @a@.@@ -131,9 +145,9 @@   deriving (Show, Eq, Ord, Generic, NFData, Monoid, Arbitrary, Functor, Foldable,             Traversable, Applicative, Alternative, Monad, Semigroup) --- | 'ForceEmit' provides a way to force emission of field values, even when--- default-value semantics states otherwise. Used when serializing oneof--- subfields.+-- | 'ForceEmit' provides a way to force emission of field values,+-- even when they have the default value.  Used for @optional@ fields+-- and fields that are part of a @oneof@. newtype ForceEmit a = ForceEmit{ forceEmit :: a }   deriving (Show, Eq, Ord, Generic, NFData, Monoid, Arbitrary, Functor, Foldable,             Traversable, Semigroup)
test-files/with_repeated_signed.bin view

binary file changed (14 → 102 bytes)

tests/ArbitraryGeneratedTestTypes.hs view
@@ -11,8 +11,10 @@ import           Test.QuickCheck.Arbitrary.Generic (genericArbitrary, Arbitrary (..)) import           TestProto import qualified TestProtoImport+import qualified TestProtoNegativeEnum import qualified TestProtoOneof import qualified TestProtoOneofImport+import qualified TestProtoOptional  instance Arbitrary Trivial where   arbitrary = Trivial <$> arbitrary@@ -163,3 +165,43 @@       [ TestProtoOneofImport.WithOneofPickOneA <$> fmap fromString arbitrary       , TestProtoOneofImport.WithOneofPickOneB <$> arbitrary       ]++instance Arbitrary TestProtoNegativeEnum.NegativeEnum where+  arbitrary = QC.elements+    [ TestProtoNegativeEnum.NegativeEnumNEGATIVE_ENUM_0+    , TestProtoNegativeEnum.NegativeEnumNEGATIVE_ENUM_NEGATIVE_1+    , TestProtoNegativeEnum.NegativeEnumNEGATIVE_ENUM_1+    , TestProtoNegativeEnum.NegativeEnumNEGATIVE_ENUM_NEGATIVE_128+    , TestProtoNegativeEnum.NegativeEnumNEGATIVE_ENUM_128+    ]++instance Arbitrary TestProtoNegativeEnum.WithNegativeEnum where+  arbitrary =+    TestProtoNegativeEnum.WithNegativeEnum+    <$> arbitrary++instance Arbitrary TestProtoOptional.Submessage where+  arbitrary =+    TestProtoOptional.Submessage+    <$> arbitrary++instance Arbitrary TestProtoOptional.WithOptional where+  arbitrary =+    TestProtoOptional.WithOptional+    <$> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary+    <*> arbitrary
tests/Main.hs view
@@ -1,8 +1,17 @@-{-# LANGUAGE LambdaCase        #-}-{-# LANGUAGE MagicHash         #-}-{-# LANGUAGE OverloadedLists   #-}-{-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE CPP               #-}+{-# LANGUAGE AllowAmbiguousTypes   #-}+{-# LANGUAGE BlockArguments        #-}+{-# LANGUAGE CPP                   #-}+{-# LANGUAGE DataKinds             #-}+{-# LANGUAGE FlexibleContexts      #-}+{-# LANGUAGE ImplicitParams        #-}+{-# LANGUAGE MagicHash             #-}+{-# LANGUAGE OverloadedLists       #-}+{-# LANGUAGE OverloadedStrings     #-}+{-# LANGUAGE PolyKinds             #-}+{-# LANGUAGE ScopedTypeVariables   #-}+{-# LANGUAGE TypeApplications      #-}+{-# LANGUAGE TypeFamilies          #-}+{-# LANGUAGE UndecidableInstances  #-}  {-# OPTIONS_GHC -fno-warn-orphans #-} @@ -12,23 +21,39 @@ import qualified Data.ByteString             as B import qualified Data.ByteString.Char8       as BC import qualified Data.ByteString.Lazy        as BL+import qualified Data.ByteString.Short       as BS import           Data.Either                 (isRight)+import           Data.Functor.Identity       (Identity(..))+import           Data.Int                    (Int8, Int16, Int32, Int64) import qualified Data.List.NonEmpty          as NE+import           Data.Proxy                  (Proxy(..)) import           Data.String+import qualified Data.Text.Short+import           Data.Typeable               (Typeable, showsTypeRep, typeRep)+import           Data.Word                   (Word8, Word16, Word32, Word64)+import qualified Data.Vector                 as V import           GHC.Exts                    (fromList, Proxy#)+import           GHC.TypeLits                (Nat, SomeNat(..), Symbol, TypeError, someNatVal) import           Proto3.Suite+import qualified Proto3.Suite.Form           as Form+import qualified Proto3.Suite.Form.Encode    as FormE+import           Proto3.Suite.Haskell.Parser (Logger, initLogger)+import qualified Proto3.Suite.JSONPB.Class   as JSONPB import           Proto3.Wire.Decode          (ParseError) import qualified Proto3.Wire.Decode          as Decode+import qualified Proto3.Wire.Reverse         as RB import           Proto3.Wire.Types           as P import qualified Test.DocTest-import           Test.QuickCheck             (Arbitrary, Property, arbitrary,-                                              counterexample, oneof)+import           Test.QuickCheck             (Arbitrary, Property, (.&&.), arbitrary, choose,+                                              counterexample, forAll, oneof, property) import           Test.Tasty-import           Test.Tasty.HUnit            (Assertion, assertBool, testCase,-                                              (@=?), (@?=))+import           Test.Tasty.HUnit            (Assertion, assertBool, assertEqual,+                                              testCase, (@=?), (@?=)) import           Test.Tasty.QuickCheck       (testProperty, (===)) import           TestCodeGen import qualified TestProto                   as TP+import qualified TestProtoOneof              as TPO+import qualified TestProtoOneofImport        as TPOI  #ifdef DHALL import           TestDhall@@ -36,23 +61,29 @@  import qualified Test.Proto.Generate.Name import qualified Test.Proto.Parse.Option+import qualified Test.Proto.Interval+import           Test.Proto.ToEncoder        (Iterator(Forward, Vector),+                                              Stripping(Keep, Strip), ToEncoder(..))  -- -----------------------------------------------------------------------------  main :: IO ()-main = defaultMain tests+main = do+  logger <- initLogger+  defaultMain (tests logger) -tests :: TestTree-tests = testGroup "Tests"+tests :: Logger -> TestTree+tests logger = testGroup "Tests"   [ docTests   , qcProperties   , encodeUnitTests   , decodeUnitTests   , parserUnitTests   , dotProtoUnitTests-  , codeGenTests-  , Test.Proto.Generate.Name.tests-  , Test.Proto.Parse.Option.tests+  , codeGenTests logger+  , Test.Proto.Generate.Name.testTree+  , Test.Proto.Parse.Option.testTree+  , Test.Proto.Interval.testTree  #ifdef DHALL   , dhallTests@@ -67,7 +98,10 @@   putStrLn "Running all doctests..."   Test.DocTest.doctest     [ "--verbose"+    , "-package"+    , "ghc-lib-parser"     , "-isrc"+    , "-XBlockArguments" #ifdef SWAGGER #ifdef SWAGGER_WRAPPER_FORMAT     , "-isrc/swagger-wrapper-format"@@ -133,6 +167,16 @@ encodeUnitTests :: TestTree encodeUnitTests = testGroup "Encoder unit tests"   [ encoderMatchesGoldens+  , encoderPromotionsAndAuto+  , encodeBytesFromBuilder+  , encodeMessageReflection+  , encodeCachedSubmessage+  , testShowMessageEncoder+  , testShowMessageEncoding+  , testToJSONPBMessageEncoder+  , testToJSONPBMessageEncoding+  , testFromJSONPBMessageEncoder+  , testFromJSONPBMessageEncoding   ]  -- TODO: We should consider generating the reference encodings@@ -148,7 +192,13 @@   , check "with_enum0.bin"            $ TP.WithEnum $ Enumerated $ Right $ TP.WithEnum_TestEnumENUM1   , check "with_enum1.bin"            $ TP.WithEnum $ Enumerated $ Right $ TP.WithEnum_TestEnumENUM2   , check "with_repetition.bin"       $ TP.WithRepetition [1..5]-  , check "with_repeated_signed.bin"  $ TP.WithRepeatedSigned [0,1,-1,2,-2] [0,1,-1,2,-2]+  , check "with_repeated_signed.bin"  $ TP.WithRepeatedSigned+      [ 0, -1, 1, -2, 2,+        0x3FFFFFFF, -0x40000000, 0x40000000, -0x40000001,+        0x7FFFFFFF, -0x7FFFFFFF - 1 ]+      [ 0, -1, 1, -2, 2,+        0x3FFFFFFFFFFFFFFF, -0x4000000000000000, 0x4000000000000000, -0x4000000000000001,+        0x7FFFFFFFFFFFFFFF, -0x7FFFFFFFFFFFFFFF - 1 ]   , check "with_bytes.bin"            $ TP.WithBytes (BC.pack "abc") (fromList $ map BC.pack ["abc","123"])   , check "with_nesting_repeated.bin" $ TP.WithNestingRepeated                                           [ TP.WithNestingRepeated_Nested "123abc" 123456 [1,2,3,4] [5,6,7,8]@@ -158,8 +208,518 @@   where     check fp v = testCase fp $ do       goldenEncoding <- BL.readFile (testFilesPfx <> fp)-      toLazyByteString v @?= goldenEncoding+      assertEqual (show fp ++ ": encoding from intermediate representation")+        goldenEncoding (toLazyByteString v)+      -- NOTE: We skip the 'Identity' iterator in this test because we expect it+      -- will create longer output for packed fields than the golden result when+      -- there is more than one element of the repetition--in which case our test+      -- code misuses 'Identity' by using it repeatedly, once for each element.+      -- Though suboptimal, the resulting encoding remains decodable by parsers+      -- that adhere to the protobuf specification.  We check that decodability+      -- in other tests that pair a Haskell encoder with a Python decoder.+      assertEqual (show fp ++ ": direct encoding, Forward iterator, keep wrappers")+        goldenEncoding $ FormE.messageEncoderToLazyByteString $+          let ?iterator = Forward+              ?stripping = Keep+          in toEncoder v+      assertEqual (show fp ++ ": direct encoding, Forward iterator, strip wrappers")+        goldenEncoding $ FormE.messageEncoderToLazyByteString $+          let ?iterator = Forward+              ?stripping = Strip+          in toEncoder v+      assertEqual (show fp ++ ": direct encoding, Vector iterator, keep wrappers")+        goldenEncoding $ FormE.messageEncoderToLazyByteString $+          let ?iterator = Vector+              ?stripping = Keep+          in toEncoder v+      assertEqual (show fp ++ ": direct encoding, Vector iterator, strip wrappers")+        goldenEncoding $ FormE.messageEncoderToLazyByteString $+          let ?iterator = Vector+              ?stripping = Strip+          in toEncoder v +-- Simulated protobuf message type having a single field named @myBytes@ of+-- type @bytes@ with field number @8@ and the specified 'Form.Cardinality'.+data MyWithBytes (r :: Form.Cardinality)++type instance Form.NamesOf (MyWithBytes r) = '["x"]++type instance Form.NumberOf (MyWithBytes r) name = MyWithBytes_NumberOf r name++type family MyWithBytes_NumberOf (r :: Form.Cardinality) (name :: Symbol) :: Nat+  where+    MyWithBytes_NumberOf _ "myBytes" = 8+    MyWithBytes_NumberOf r name = TypeError (Form.FieldNotFound (MyWithBytes r) name)++type instance Form.ProtoTypeOf (MyWithBytes r) name = MyWithBytes_ProtoTypeOf r name++type family MyWithBytes_ProtoTypeOf (r :: Form.Cardinality) (name :: Symbol) :: Form.ProtoType+  where+    MyWithBytes_ProtoTypeOf _ "myBytes" = 'Form.Bytes+    MyWithBytes_ProtoTypeOf r name = TypeError (Form.FieldNotFound (MyWithBytes r) name)++type instance Form.OneOfOf (MyWithBytes r) name = MyWithBytes_OneOfOf r name++type family MyWithBytes_OneOfOf (r :: Form.Cardinality) (name :: Symbol) :: Symbol+  where+    MyWithBytes_OneOfOf 'Form.Optional "myBytes" = "pickOne"+    MyWithBytes_OneOfOf 'Form.Optional "pickOne" = "pickOne"+    MyWithBytes_OneOfOf r "myBytes" = ""+    MyWithBytes_OneOfOf r name = TypeError (Form.FieldOrOneOfNotFound (MyWithBytes r) name)++type instance Form.CardinalityOf (MyWithBytes r) name = MyWithBytes_CardinalityOf r name++type family MyWithBytes_CardinalityOf (r :: Form.Cardinality) (name :: Symbol) :: Form.Cardinality+  where+    MyWithBytes_CardinalityOf r "myBytes" = r+    MyWithBytes_CardinalityOf 'Form.Optional "pickOne" = 'Form.Optional+    MyWithBytes_CardinalityOf r name = TypeError (Form.FieldOrOneOfNotFound (MyWithBytes r) name)++encodeBytesFromBuilder :: TestTree+encodeBytesFromBuilder = testCase "bytes from builder" $ do+    assertEqual "implicitly empty"+      (enc @'Form.Implicit (mempty :: RB.BuildR)) ""+    assertEqual "implicit but nonempty"+      (enc @'Form.Implicit (RB.byteString "xyz")) "B\ETXxyz"+    assertEqual "unset optional"+      (enc @'Form.Optional (Nothing :: Maybe RB.BuildR)) ""+    assertEqual "set empty optional"+      (enc @'Form.Optional (Just (mempty :: RB.BuildR))) "B\NUL"+    assertEqual "set nonempty optional"+      (enc @'Form.Optional (Just (RB.byteString "xyz"))) "B\ETXxyz"+    assertEqual "zero repetitions"+      (enc @('Form.Repeated 'Form.Unpacked)+           ([] :: [RB.BuildR]))+      ""+    assertEqual "single empty"+      (enc @('Form.Repeated 'Form.Unpacked)+           ([mempty] :: [RB.BuildR]))+      "B\NUL"+    assertEqual "double empty"+      (enc @('Form.Repeated 'Form.Unpacked)+           ([mempty, mempty] :: [RB.BuildR]))+      "B\NULB\NUL"+    assertEqual "empty nonempty"+      (enc @('Form.Repeated 'Form.Unpacked)+           ([mempty, RB.byteString "xyz"] :: [RB.BuildR]))+      "B\NULB\ETXxyz"+    assertEqual "nonempty empty"+      (enc @('Form.Repeated 'Form.Unpacked)+           (V.fromList [RB.byteString "uv", mempty]))+      "B\STXuvB\NUL"+    assertEqual "double nonempty"+      (enc @('Form.Repeated 'Form.Unpacked)+           (V.fromList [RB.byteString "uv", RB.byteString "xyz"]))+      "B\STXuvB\ETXxyz"+  where+    enc ::+      forall r a .+      ( FormE.Distinct (MyWithBytes r) (FormE.Occupy (MyWithBytes r) "myBytes" '[])+      , FormE.Field "myBytes" a (MyWithBytes r)+      ) =>+      a ->+      BL.ByteString+    enc =+      FormE.messageEncoderToLazyByteString .+      FormE.fieldsToMessage .+      FormE.field @"myBytes" @a @(MyWithBytes r)++encodeMessageReflection :: TestTree+encodeMessageReflection = testCase "messageReflection" $ do+  let msg = TP.Trivial 123+  FormE.messageEncoderToLazyByteString (FormE.messageReflection msg) @?= toLazyByteString msg++encodeCachedSubmessage :: TestTree+encodeCachedSubmessage = testGroup "Cached Submessages"+  [ testOptional+  , testRepeated+  , testOneof+  ]+  where+    testOptional :: TestTree+    testOptional = testCase "cached optional submessage" $ do+      let trivial = TP.Trivial 123+          wrappedTrivial = FormE.fieldsToMessage @TP.WrappedTrivial $+            FormE.field @"trivial" (Just (FormE.messageCache trivial))+      FormE.messageEncoderToLazyByteString wrappedTrivial @?=+        toLazyByteString (TP.WrappedTrivial (Just trivial))++    testRepeated :: TestTree+    testRepeated = testCase "cached repeated submessage" $ do+      let trivials :: V.Vector TP.MapTestEmulation_Trivial+          trivials =+            [ TP.MapTestEmulation_Trivial 15 (Just (TP.WrappedTrivial (Just (TP.Trivial 465))))+            , TP.MapTestEmulation_Trivial 25 (Just (TP.WrappedTrivial (Just (TP.Trivial 789))))+            ]+          mapTestEmulation = FormE.fieldsToMessage @TP.MapTestEmulation $+            FormE.field @"trivial" (V.map FormE.messageCache trivials)+      FormE.messageEncoderToLazyByteString mapTestEmulation @?=+        toLazyByteString (TP.MapTestEmulation mempty trivials mempty)++    testOneof :: TestTree+    testOneof = testCase "cached submessage within oneof" $ do+      let withOneof = TPOI.WithOneof (Just (TPOI.WithOneofPickOneB 123))+          withImported = FormE.fieldsToMessage @TPO.WithImported $+            FormE.field @"withOneof" (Just (FormE.messageCache withOneof))+      FormE.messageEncoderToLazyByteString withImported @?=+        toLazyByteString (TPO.WithImported (Just (TPO.WithImportedPickOneWithOneof withOneof)))++testShowMessageEncoding :: TestTree+testShowMessageEncoding = testCase "Show MessageEncoding" $ do+  let trivial = TP.Trivial 123+      badForm = "abc"+      encoding :: FormE.MessageEncoding TP.Trivial+      encoding = FormE.messageCache trivial+      bogus :: FormE.MessageEncoding TP.Trivial+      bogus = FormE.unsafeByteStringToMessageEncoding badForm+  -- Test desired behavior for valid encoding:+  show (Just encoding) @?=+    "Just (Proto3.Suite.Form.Encode.messageCache " ++ showsPrec 11 trivial ")"+  -- Test fallback behavior for invalid encoding:+  show (Just bogus) @?=+    "Just (Proto3.Suite.Form.Encode.unsafeByteStringToMessageEncoding " ++ showsPrec 11 badForm ")"++testShowMessageEncoder :: TestTree+testShowMessageEncoder = testCase "Show MessageEncoder" $ do+  let trivial = TP.Trivial 123+      badForm = "abc"+      encoder :: FormE.MessageEncoder TP.Trivial+      encoder = FormE.messageReflection trivial+      bogus :: FormE.MessageEncoder TP.Trivial+      bogus = FormE.unsafeByteStringToMessageEncoder badForm+  -- Test desired behavior for valid encoder:+  show (Just encoder) @?=+    "Just (Proto3.Suite.Form.Encode.messageReflection " ++ showsPrec 11 trivial ")"+  -- Test fallback behavior for invalid encoder:+  show (Just bogus) @?=+    "Just (Proto3.Suite.Form.Encode.unsafeByteStringToMessageEncoder " ++ showsPrec 11 badForm ")"++testToJSONPBMessageEncoding :: TestTree+testToJSONPBMessageEncoding = testProperty "ToJSONPB MessageEncoding" $ \opts ->+  let trivial = TP.Trivial 123+      badForm = "abc"+      encoding :: FormE.MessageEncoding TP.Trivial+      encoding = FormE.messageCache trivial+      bogus :: FormE.MessageEncoding TP.Trivial+      bogus = FormE.unsafeByteStringToMessageEncoding badForm+  in+    -- Test desired behavior for valid encoding:+    JSONPB.toJSONPB encoding opts === JSONPB.toJSONPB trivial opts+    .&&.+    JSONPB.toEncodingPB encoding opts === JSONPB.toEncodingPB trivial opts+    .&&.+    -- Test fallback behavior for invalid encoding:+    JSONPB.toJSONPB bogus opts === JSONPB.toJSONPB badForm opts+    .&&.+    JSONPB.toEncodingPB bogus opts === JSONPB.toEncodingPB badForm opts++testToJSONPBMessageEncoder :: TestTree+testToJSONPBMessageEncoder = testProperty "ToJSONPB MessageEncoder" $ \opts ->+  let trivial = TP.Trivial 123+      badForm = "abc"+      encoder :: FormE.MessageEncoder TP.Trivial+      encoder = FormE.messageReflection trivial+      bogus :: FormE.MessageEncoder TP.Trivial+      bogus = FormE.unsafeByteStringToMessageEncoder badForm+  in+    -- Test desired behavior for valid encoder:+    JSONPB.toJSONPB encoder opts === JSONPB.toJSONPB trivial opts+    .&&.+    JSONPB.toEncodingPB encoder opts === JSONPB.toEncodingPB trivial opts+    .&&.+    -- Test fallback behavior for invalid encoder:+    JSONPB.toJSONPB bogus opts === JSONPB.toJSONPB badForm opts+    .&&.+    JSONPB.toEncodingPB bogus opts === JSONPB.toEncodingPB badForm opts++testFromJSONPBMessageEncoding :: TestTree+testFromJSONPBMessageEncoding = testProperty "FromJSONPB MessageEncoding" $ \opts ->+  let trivial = TP.Trivial 123+      badForm = "abc"+      encoding :: FormE.MessageEncoding TP.Trivial+      encoding = FormE.messageCache trivial+      bogus :: FormE.MessageEncoding TP.Trivial+      bogus = FormE.unsafeByteStringToMessageEncoding badForm+      edec :: BL.ByteString -> Either String (FormE.MessageEncoding TP.Trivial)+      edec = JSONPB.eitherDecode+  in+    -- Test desired behavior for valid encoder:+    fmap (fromByteString . FormE.messageEncodingToByteString) (edec (JSONPB.encode opts encoding))+      === Right (Right trivial)+    .&&.+    -- Test fallback behavior for invalid encoder:+    fmap FormE.messageEncodingToByteString (edec (JSONPB.encode opts bogus)) === Right badForm++testFromJSONPBMessageEncoder :: TestTree+testFromJSONPBMessageEncoder = testProperty "FromJSONPB MessageEncoder" $ \opts ->+  let trivial = TP.Trivial 123+      badForm = "abc"+      encoder :: FormE.MessageEncoder TP.Trivial+      encoder = FormE.messageReflection trivial+      bogus :: FormE.MessageEncoder TP.Trivial+      bogus = FormE.unsafeByteStringToMessageEncoder badForm+      edec :: BL.ByteString -> Either String (FormE.MessageEncoder TP.Trivial)+      edec = JSONPB.eitherDecode+  in+    -- Test desired behavior for valid encoder:+    fmap (fromByteString . FormE.messageEncoderToByteString) (edec (JSONPB.encode opts encoder))+      === Right (Right trivial)+    .&&.+    -- Test fallback behavior for invalid encoder:+    fmap FormE.messageEncoderToByteString (edec (JSONPB.encode opts bogus)) === Right badForm++data TestMessage+       (num :: Nat)+       (repetition :: Maybe Form.Cardinality)+       (protoType :: Form.ProtoType)+  -- ^ Omitting the repetition means that field @"name"@ is in a @oneof@ named @"pickOne"@.++type instance Form.NamesOf (TestMessage num maybeRepetition protoType) = '[ "name" ]++type instance Form.NumberOf (TestMessage num maybeRepetition protoType) "name" = num++type instance Form.ProtoTypeOf (TestMessage num maybeRepetition protoType) "name" = protoType++type instance Form.OneOfOf (TestMessage num 'Nothing protoType) "name" = "pickOne"+type instance Form.OneOfOf (TestMessage num 'Nothing protoType) "pickOne" = "pickOne"+type instance Form.OneOfOf (TestMessage num ('Just _) protoType) "name" = ""++type instance Form.CardinalityOf (TestMessage num 'Nothing protoType) "name" = 'Form.Optional+type instance Form.CardinalityOf (TestMessage num 'Nothing protoType) "pickOne" = 'Form.Optional+type instance Form.CardinalityOf (TestMessage num ('Just repetition) protoType) "name" = repetition++encoderPromotionsAndAuto :: TestTree+encoderPromotionsAndAuto = testGroup "Encoder promotes types correctly and Auto-selection works"+  [ testGroup "Encoder promotes types correctly"+      [ check @'Form.Int32 @Int8 @Int32 "int32" (fromIntegral @Int8 @Int32)+      , check @'Form.Int32 @Word8 @Int32 "int32" (fromIntegral @Word8 @Int32)+      , check @'Form.Int32 @Int16 @Int32 "int32" (fromIntegral @Int16 @Int32)+      , check @'Form.Int32 @Word16 @Int32 "int32" (fromIntegral @Word16 @Int32)+      , check @'Form.Int64 @Int8 @Int64 "int64" (fromIntegral @Int8 @Int64)+      , check @'Form.Int64 @Word8 @Int64 "int64" (fromIntegral @Word8 @Int64)+      , check @'Form.Int64 @Int16 @Int64 "int64"(fromIntegral @Int16 @Int64)+      , check @'Form.Int64 @Word16 @Int64 "int64"(fromIntegral @Word16 @Int64)+      , check @'Form.Int64 @Int32 @Int64 "int64"(fromIntegral @Int32 @Int64)+      , check @'Form.Int64 @Word32 @Int64 "int64"(fromIntegral @Word32 @Int64)+      , check @'Form.SInt32 @Int8 @Int32 "sint32" (fromIntegral @Int8 @Int32)+      , check @'Form.SInt32 @Word8 @Int32 "sint32" (fromIntegral @Word8 @Int32)+      , check @'Form.SInt32 @Int16 @Int32 "sint32" (fromIntegral @Int16 @Int32)+      , check @'Form.SInt32 @Word16 @Int32 "sint32" (fromIntegral @Word16 @Int32)+      , check @'Form.SInt64 @Int8 @Int64 "sint64" (fromIntegral @Int8 @Int64)+      , check @'Form.SInt64 @Word8 @Int64 "sint64" (fromIntegral @Word8 @Int64)+      , check @'Form.SInt64 @Int16 @Int64 "sint64" (fromIntegral @Int16 @Int64)+      , check @'Form.SInt64 @Word16 @Int64 "sint64" (fromIntegral @Word16 @Int64)+      , check @'Form.SInt64 @Int32 @Int64 "sint64" (fromIntegral @Int32 @Int64)+      , check @'Form.SInt64 @Word32 @Int64 "sint64" (fromIntegral @Word32 @Int64)+      , check @'Form.UInt32 @Word8 @Word32 "uint32" (fromIntegral @Word8 @Word32)+      , check @'Form.UInt32 @Word16 @Word32 "uint32" (fromIntegral @Word16 @Word32)+      , check @'Form.UInt64 @Word8 @Word64 "uint64" (fromIntegral @Word8 @Word64)+      , check @'Form.UInt64 @Word16 @Word64 "uint64" (fromIntegral @Word16 @Word64)+      , check @'Form.UInt64 @Word32 @Word64 "uint64" (fromIntegral @Word32 @Word64)+      , check @'Form.Fixed32 @Word8 @Word32 "fixed32" (fromIntegral @Word8 @Word32)+      , check @'Form.Fixed32 @Word16 @Word32 "fixed32" (fromIntegral @Word16 @Word32)+      , check @'Form.Fixed64 @Word8 @Word64 "fixed64" (fromIntegral @Word8 @Word64)+      , check @'Form.Fixed64 @Word16 @Word64 "fixed64" (fromIntegral @Word16 @Word64)+      , check @'Form.Fixed64 @Word32 @Word64 "fixed64" (fromIntegral @Word32 @Word64)+      , check @'Form.SFixed32 @Int8 @Int32 "sfixed32" (fromIntegral @Int8 @Int32)+      , check @'Form.SFixed32 @Word8 @Int32 "sfixed32" (fromIntegral @Word8 @Int32)+      , check @'Form.SFixed32 @Int16 @Int32 "sfixed32" (fromIntegral @Int16 @Int32)+      , check @'Form.SFixed32 @Word16 @Int32 "sfixed32" (fromIntegral @Word16 @Int32)+      , check @'Form.SFixed64 @Int8 @Int64 "sfixed64" (fromIntegral @Int8 @Int64)+      , check @'Form.SFixed64 @Word8 @Int64 "sfixed64" (fromIntegral @Word8 @Int64)+      , check @'Form.SFixed64 @Int16 @Int64 "sfixed64" (fromIntegral @Int16 @Int64)+      , check @'Form.SFixed64 @Word16 @Int64 "sfixed64" (fromIntegral @Word16 @Int64)+      , check @'Form.SFixed64 @Int32 @Int64 "sfixed64" (fromIntegral @Int32 @Int64)+      , check @'Form.SFixed64 @Word32 @Int64 "sfixed64" (fromIntegral @Word32 @Int64)+      , check @'Form.Double @Float @Double "double" (realToFrac @Float @Double)+      ]+  , testGroup "Encoder Auto wrapper does not change format"+      [ check @'Form.Int32 @Int32 @(FormE.Auto Int32) "int32" FormE.Auto+      , check @'Form.Int64 @Int64 @(FormE.Auto Int64) "int64" FormE.Auto+      , check @'Form.SInt32 @Int32 @(FormE.Auto Int32) "sint32" FormE.Auto+      , check @'Form.SInt64 @Int64 @(FormE.Auto Int64) "sint64" FormE.Auto+      , check @'Form.UInt32 @Word32 @(FormE.Auto Word32) "uint32" FormE.Auto+      , check @'Form.UInt64 @Word64 @(FormE.Auto Word64) "uint64" FormE.Auto+      , check @'Form.Fixed32 @Word32 @(FormE.Auto Word32) "fixed32" FormE.Auto+      , check @'Form.Fixed64 @Word64 @(FormE.Auto Word64) "fixed64" FormE.Auto+      , check @'Form.SFixed32 @Int32 @(FormE.Auto Int32) "sfixed32" FormE.Auto+      , check @'Form.SFixed64 @Int64 @(FormE.Auto Int64) "sfixed64" FormE.Auto+      , check @'Form.Bool @Bool @(FormE.Auto Bool) "bool" FormE.Auto+      , check @'Form.Float @Float @(FormE.Auto Float) "float" FormE.Auto+      , check @'Form.Double @Double @(FormE.Auto Double) "double" FormE.Auto+      , checkNotPacked @'Form.String @Data.Text.Short.ShortText @(FormE.Auto Data.Text.Short.ShortText) "string" FormE.Auto+      , checkNotPacked @'Form.Bytes @BS.ShortByteString @(FormE.Auto BS.ShortByteString) "bytes" FormE.Auto+      ]+  ]+  where+    check ::+      forall (protoType :: Form.ProtoType) a b .+      ( Typeable a+      , Typeable b+      , Arbitrary a+      , Show a+      , FormE.FieldForm 'Form.Implicit protoType a+      , FormE.FieldForm 'Form.Implicit protoType b+      , FormE.FieldForm 'Form.Optional protoType (Maybe a)+      , FormE.FieldForm 'Form.Optional protoType (Maybe b)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (Identity a)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (Identity b)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType [a]+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType [b]+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (V.Vector a)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (V.Vector b)+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType (Identity a)+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType (Identity b)+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType [a]+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType [b]+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType (V.Vector a)+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType (V.Vector b)+      ) =>+      String ->+      (a -> b) ->+      TestTree+    check protoTypeName convert =+      testProperty (showString protoTypeName $ showString ": " $+                    showsType @a $ showString " -> " $ showsType @b "") $+        propNotPacked @protoType convert .&&.+        propPacked @protoType convert++    checkNotPacked ::+      forall (protoType :: Form.ProtoType) a b .+      ( Typeable a+      , Typeable b+      , Arbitrary a+      , Show a+      , FormE.FieldForm 'Form.Implicit protoType a+      , FormE.FieldForm 'Form.Implicit protoType b+      , FormE.FieldForm 'Form.Optional protoType (Maybe a)+      , FormE.FieldForm 'Form.Optional protoType (Maybe b)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (Identity a)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (Identity b)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType [a]+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType [b]+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (V.Vector a)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (V.Vector b)+      ) =>+      String ->+      (a -> b) ->+      TestTree+    checkNotPacked protoTypeName convert =+      testProperty (showString protoTypeName $ showString ": " $+                    showsType @a $ showString " -> " $ showsType @b "") $+        propNotPacked @protoType convert++    propNotPacked ::+      forall (protoType :: Form.ProtoType) a b .+      ( Typeable a+      , Typeable b+      , Arbitrary a+      , Show a+      , FormE.FieldForm 'Form.Implicit protoType a+      , FormE.FieldForm 'Form.Implicit protoType b+      , FormE.FieldForm 'Form.Optional protoType (Maybe a)+      , FormE.FieldForm 'Form.Optional protoType (Maybe b)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (Identity a)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (Identity b)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType [a]+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType [b]+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (V.Vector a)+      , FormE.FieldForm ('Form.Repeated 'Form.Unpacked) protoType (V.Vector b)+      ) =>+      (a -> b) ->+      Property+    propNotPacked convert =+      forAll (choose (1, 536870911)) $ \fieldNum ->+      case someNatVal fieldNum of+        Nothing ->+          property False  -- Should never happen.+        Just (SomeNat (_ :: Proxy num)) ->+          forAll arbitrary $ \a ->+          forAll arbitrary $ \(as :: [a])->+          let b :: b+              b = convert a+              bs :: [b]+              bs = map convert as+              asVec :: V.Vector a+              asVec = V.fromList as+              bsVec :: V.Vector b+              bsVec = V.fromList bs+          in+          counterexample "Implicit"+            (check1 @num @('Just 'Form.Implicit) @protoType a b) .&&.+          counterexample "Optional - Nothing"+            (check1 @num @('Just 'Form.Optional) @protoType (Nothing @a) (Nothing @b)) .&&.+          counterexample "Optional - Just"+            (check1 @num @('Just 'Form.Optional) @protoType (Just a) (Just b)) .&&.+          counterexample "inside oneof"+            (check1 @num @'Nothing @protoType (Just a) (Just b)) .&&.+          counterexample "Unpacked Identity"+            (check1 @num @('Just ('Form.Repeated 'Form.Unpacked)) @protoType (Identity a) (Identity b)) .&&.+          counterexample "Unpacked Forward"+            (check1 @num @('Just ('Form.Repeated 'Form.Unpacked)) @protoType as bs) .&&.+          counterexample "Unpacked Vector"+            (check1 @num @('Just ('Form.Repeated 'Form.Unpacked)) @protoType asVec bsVec)++    propPacked ::+      forall (protoType :: Form.ProtoType) a b .+      ( Typeable a+      , Typeable b+      , Arbitrary a+      , Show a+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType (Identity a)+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType (Identity b)+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType [a]+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType [b]+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType (V.Vector a)+      , FormE.FieldForm ('Form.Repeated 'Form.Packed) protoType (V.Vector b)+      ) =>+      (a -> b) ->+      Property+    propPacked convert =+      forAll (choose (1, 536870911)) $ \fieldNum ->+      case someNatVal fieldNum of+        Nothing ->+          property False  -- Should never happen.+        Just (SomeNat (_ :: Proxy num)) ->+          forAll arbitrary $ \a ->+          forAll arbitrary $ \(as :: [a])->+          let b :: b+              b = convert a+              bs :: [b]+              bs = map convert as+              asVec :: V.Vector a+              asVec = V.fromList as+              bsVec :: V.Vector b+              bsVec = V.fromList bs+          in+          counterexample "Packed Identity"+            (check1 @num @('Just ('Form.Repeated 'Form.Packed)) @protoType (Identity a) (Identity b)) .&&.+          counterexample "Packed Forward"+            (check1 @num @('Just ('Form.Repeated 'Form.Packed)) @protoType as bs) .&&.+          counterexample "Packed Vector"+            (check1 @num @('Just ('Form.Repeated 'Form.Packed)) @protoType asVec bsVec)++    check1 ::+      forall (num :: Nat) (maybeRepetition :: Maybe Form.Cardinality)+             (protoType :: Form.ProtoType) a b .+      ( FormE.Field "name" a (TestMessage num maybeRepetition protoType)+      , FormE.Field "name" b (TestMessage num maybeRepetition protoType)+      , FormE.Distinct (TestMessage num maybeRepetition protoType)+                       (FormE.Occupy (TestMessage num maybeRepetition protoType) "name" '[])+      ) =>+      a ->+      b ->+      Property+    check1 a b =+      FormE.messageEncoderToLazyByteString+        (FormE.fieldsToMessage (FormE.field @"name" @a @(TestMessage num maybeRepetition protoType) a))+      ===+      FormE.messageEncoderToLazyByteString+        (FormE.fieldsToMessage (FormE.field @"name" @b @(TestMessage num maybeRepetition protoType) b))++    showsType :: forall a . Typeable a => ShowS+    showsType = showsTypeRep (typeRep (Proxy :: Proxy a))+ -------------------------------------------------------------------------------- -- Decoding @@ -203,7 +763,13 @@   , check "with_enum0.bin"            $ TP.WithEnum $ Enumerated $ Right $ TP.WithEnum_TestEnumENUM1   , check "with_enum1.bin"            $ TP.WithEnum $ Enumerated $ Right $ TP.WithEnum_TestEnumENUM2   , check "with_repetition.bin"       $ TP.WithRepetition [1..5]-  , check "with_repeated_signed.bin"  $ TP.WithRepeatedSigned [0,1,-1,2,-2] [0,1,-1,2,-2]+  , check "with_repeated_signed.bin"  $ TP.WithRepeatedSigned+      [ 0, -1, 1, -2, 2,+        0x3FFFFFFF, -0x40000000, 0x40000000, -0x40000001,+        0x7FFFFFFF, -0x7FFFFFFF - 1 ]+      [ 0, -1, 1, -2, 2,+        0x3FFFFFFFFFFFFFFF, -0x4000000000000000, 0x4000000000000000, -0x4000000000000001,+        0x7FFFFFFFFFFFFFFF, -0x7FFFFFFFFFFFFFFF - 1 ]   , check "with_fixed.bin"            $ TP.WithFixed 16 (-123) 4096 (-4096)   , check "with_bytes.bin"            $ TP.WithBytes (BC.pack "abc") (fromList $ map BC.pack ["abc","123"])   , check "with_packing.bin"          $ TP.WithPacking [1,2,3] [1,2,3]@@ -264,6 +830,7 @@ dotProtoUnitTests = testGroup ".proto parsing tests"   [ dotProtoParseTrivial   , dotProtoPrintTrivial+  , dotProtoParseEmptyStatement   , dotProtoRoundtripTrivial   , dotProtoRoundtripSimpleMessage   , dotProtoRoundtripExtend@@ -282,6 +849,44 @@ dotProtoPrintTrivial = testCase   "Print a content-less DotProto" $   testDotProtoPrint trivialDotProto "syntax = \"proto3\";"++dotProtoParseEmptyStatement :: TestTree+dotProtoParseEmptyStatement =+  testCase "Parse empty statements" (testDotProtoParse filePath dotProtoAST)+  where+    filePath :: FilePath+    filePath = testFilesPfx <> "test_proto_empty_field.proto"++    dotProtoAST :: DotProto+    dotProtoAST =+      DotProto [] []+        (DotProtoPackageSpec (Single "TestProtoEmptyField"))+        [ DotProtoEnum+            ""+            (Single "EnumWithEmptyField")+            [ DotProtoEnumField (Single "enum_foo") 0 []+            , DotProtoEnumField (Single "enum_bar") 1 []+            ]+        , DotProtoMessage+            ""+            (Single "MessageWithEmptyField")+            [ DotProtoMessageField (DotProtoField+                { dotProtoFieldNumber = 1+                , dotProtoFieldType = Prim UInt32+                , dotProtoFieldName = Single "foo"+                , dotProtoFieldOptions = []+                , dotProtoFieldComment = ""+                })+            , DotProtoMessageField (DotProtoField+                { dotProtoFieldNumber = 2+                , dotProtoFieldType = Prim UInt32+                , dotProtoFieldName = Single "bar"+                , dotProtoFieldOptions = []+                , dotProtoFieldComment = ""+                })+            ]+        ]+        (DotProtoMeta (Path (testFilesPfx NE.:| ["test_proto_empty_field.proto"])))  dotProtoRoundtripTrivial :: TestTree dotProtoRoundtripTrivial = testCase
tests/Test/Proto/Generate/Name.hs view
@@ -4,7 +4,7 @@  -- | ---module Test.Proto.Generate.Name (tests) where+module Test.Proto.Generate.Name (testTree) where  import Test.Tasty (TestTree, testGroup) import Test.Tasty.Hedgehog (testProperty)@@ -20,8 +20,8 @@  -- ----------------------------------------------------------------------------- -tests :: TestTree-tests =+testTree :: TestTree+testTree =   testGroup     "Test.Proto.Generate.Name"     [ testProperty "filenames" resolve'protofile
+ tests/Test/Proto/Interval.hs view
@@ -0,0 +1,181 @@+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE NegativeLiterals #-}+{-# LANGUAGE PatternSynonyms #-}+{-# LANGUAGE TypeApplications #-}++module Test.Proto.Interval (testTree) where++import Data.Foldable (for_)++import Proto3.Suite.DotProto.Internal (joinIntervals, normalizeIntervals)++import Hedgehog (Gen, forAll, property, (===))+import Hedgehog qualified+import Hedgehog.Gen qualified as Gen+import Hedgehog.Range qualified as Range++import Test.Tasty (TestTree, testGroup)+import Test.Tasty.Hedgehog (testProperty)++--------------------------------------------------------------------------------++-- | Check if the given value is some given bounds (inclusive).+isIn :: (Ord a) => a -> (a, a) -> Bool+isIn x (a, b) = a <= x && x <= b++-- | Check if the given value is any of the given bounds (inclusive).+isInAnyOf :: (Ord a) => a -> [(a, a)] -> Bool+isInAnyOf = any . isIn++-- | Generates an arbitrary interval.  May generate+-- empty intervals, though at about 10% probability.+genInterval :: (Bounded a, Integral a) => Gen (a, a)+genInterval = Gen.frequency [(4, alwaysNonempty), (1, halfEmpty)]+  where+    alwaysNonempty = do+      x <- Gen.integral Range.constantBounded+      y <- Gen.integral Range.constantBounded+      pure (min x y, max x y)++    halfEmpty = do+      x <- Gen.integral Range.constantBounded+      y <- Gen.integral Range.constantBounded+      pure (x, y)++-- | A value in the range [-8 .. 7].  We intentionally limit this type to+-- just a few values in order to increase the chance of overlapping intervals+-- in some tests, while still retaining enough distinct values to allow many+-- different relationships between intervals.  We also want to check for+-- arithmetic overflow in the code under test by throwing an exception,+-- which should cause the test to fail.+newtype Nybble = UnsafeNybble Int+  deriving newtype (Eq, Ord, Real, Show)++{-# COMPLETE Nybble #-}++pattern Nybble :: Int -> Nybble+pattern Nybble x <- UnsafeNybble x+  where+    Nybble x+      | -8 <= x && x <= 7 = UnsafeNybble x+      | otherwise = error $ "Nybble out of bounds: " ++ show x++instance Bounded Nybble+  where+    minBound = Nybble -8+    maxBound = Nybble 7++-- | Manual implementation to ensure an exception is thrown for out-of-bounds values.+instance Enum Nybble+  where+    toEnum x = Nybble x+    fromEnum (Nybble x) = x++-- | Manual implementation to ensure an exception is thrown for arithmetic overflow.+instance Num Nybble+  where+    Nybble x + Nybble y = Nybble (x + y)+    Nybble x - Nybble y = Nybble (x - y)+    Nybble x * Nybble y = Nybble (x * y)+    negate (Nybble x) = Nybble (negate x)+    abs (Nybble x) = Nybble (abs x)+    signum (Nybble x) = Nybble (signum x)+    fromInteger x = Nybble (fromInteger x)++-- | Manual implementation to ensure an exception is thrown for arithmetic overflow.+instance Integral Nybble+  where+    quotRem (Nybble n) (Nybble d) = let (q, r) = quotRem n d in (Nybble q, Nybble r)+    toInteger (Nybble x) = toInteger x++--------------------------------------------------------------------------------++testTree :: TestTree+testTree =+  testGroup+    "Test.Proto.Interval"+    [ testJoinIntervals+    , testNormalizeIntervals+    ]++-- This test verifies the documented behavior of 'joinIntervals'.+testJoinIntervals :: TestTree+testJoinIntervals = testProperty "joinIntervals" $ property do+  (a, b) <- forAll $ genInterval @Nybble+  (c, d) <- forAll $ genInterval @Nybble+  case joinIntervals (a, b) (c, d) of+    Nothing -> do+      -- The code under test says that one cannot merge the two intervals into+      -- a single interval.  For that to be true, both intervals must be nonempty/valid:+      Hedgehog.assert (a <= b)+      Hedgehog.assert (c <= d)+      -- And in addition, the least interval containing both of the given intervals+      -- must /not/ be their union.  Namely, it must include some extra element:+      let extra x = not (x `isIn` (a, b) || x `isIn` (c, d))+      Hedgehog.assert (any extra [min a c .. max b d])+      -- That suffices to verify that the intervals cannot be combined, but because+      -- the code under test currently considers similar issues, we note that there+      -- must be at least one value strictly between the two given intervals;+      -- otherwise we could merge them because there would be nothing between them:+      let between x = (b < x && x < c) || (d < x && x < a)+      Hedgehog.assert (any between [minBound .. maxBound])+    Just combined -> do+      -- The code under test claims that 'combined' equals the union of the given+      -- intervals.  We check that conclusion by testing every possible element:+      Hedgehog.annotateShow combined+      for_ [minBound .. maxBound] \x -> do+        x `isIn` combined === (x `isIn` (a, b) || x `isIn` (c, d))++-- This test verifies the documented behavior of 'normalizeIntervals'.+-- (Note the correspondence between the various documented properties+-- and the specific checks included here.)+--+-- This test also checks an additional property: that 'normalizeIntervals'+-- never increases the sum of the sizes of the listed intervals, where by+-- "size" we mean the count of elements within the interval.  That is, we+-- are only eliminating redundancy in the+testNormalizeIntervals :: TestTree+testNormalizeIntervals = testProperty "normalizeIntervals" $ property do+  messy <- forAll $ Gen.list (Range.linear 0 20) $ genInterval @Nybble++  let clean :: [(Nybble, Nybble)]+      clean = normalizeIntervals messy+  Hedgehog.annotateShow clean++  -- The result must not contain any empty intervals.+  for_ clean \(a, b) ->+    Hedgehog.assert (a <= b)++  -- The union of the result must be the same as the union of the input.+  for_ [minBound .. maxBound] \x -> do+    (x, isInAnyOf x clean) === (x, isInAnyOf x messy)++  -- Check that the listed intervals do not overlap, and moreover,+  -- cannot be merged because there are no values between them.+  --+  -- Note that here we rely upon the accuracy of 'joinIntervals',+  -- which is checked in isolation by the test 'testJoinIntervals'.+  for_ (zip [1 ..] clean) \(d, i1) ->+    for_ (drop d clean) \i2 -> do+      (i1, i2, joinIntervals i1 i2) === (i1, i2, Nothing)++  -- The code under test should have ensured that for any two consecutive intervals,+  -- there is at least one value strictly inbetween those two intervals.  This check+  -- should subsume the previous one, but we run both checks just to be sure.+  --+  -- The nonempty gaps between intervals prevent further merging, making 'clean'+  -- at least locally minimal.  But a simple exhaustive search would be extremely+  -- expensive, and hence we rely upon the mathematical argument in the comments for+  -- 'normalizeIntervals' to completely rule out the possibility of shorter lists.+  for_ (zip clean (drop 1 clean)) \((_, b), (c, _)) ->+    Hedgehog.assert (b < c && succ b < c)  -- The first check is to sure that 'succ' is safe.++  -- Verify interval merging by checking that the size of the merged intervals is+  -- bounded below the sum of the sizes of each individual interval that was merged.+  let intervalSize :: (Nybble, Nybble) -> Integer+      intervalSize (a, b) = if a <= b then toInteger b + 1 - toInteger a else 0+      overallSize :: [(Nybble, Nybble)] -> Integer+      overallSize = sum . map intervalSize+  Hedgehog.annotateShow (overallSize clean, overallSize messy)+  Hedgehog.assert (overallSize clean <= overallSize messy)
+ tests/Test/Proto/Parse.hs view
@@ -0,0 +1,21 @@++module Test.Proto.Parse (testTree) where++import Hedgehog (property, (===))++import Proto3.Suite.DotProto.Parsing qualified as Proto3+import Proto3.Suite.DotProto.Rendering ()++import Test.Proto.Parse.Core (runParseTest)+import Test.Tasty (TestTree, testGroup)+import Test.Tasty.Hedgehog (testProperty)++--------------------------------------------------------------------------------++testTree :: TestTree+testTree =+  testGroup+    "Test.Proto.Parse"+    [ testProperty "empty" $ property do+        runParseTest Proto3.pEmptyStmt ";" === Right ()+    ]
+ tests/Test/Proto/Parse/Core.hs view
@@ -0,0 +1,24 @@++module Test.Proto.Parse.Core+  ( runParseTest+  , parseTrip+  ) where++import Hedgehog (PropertyT)+import Hedgehog qualified as Hedgehog++import Text.Parsec (ParseError)+import Text.Parsec qualified as Parsec+import Text.PrettyPrint (render)+import Text.PrettyPrint.HughesPJClass (Pretty, pPrint)++import Proto3.Suite.DotProto.Parsing (ProtoParser)+import Proto3.Suite.DotProto.Parsing qualified as Proto3++--------------------------------------------------------------------------------++runParseTest :: ProtoParser a -> String -> Either ParseError a+runParseTest p = Parsec.parse (Proto3.runProtoParser p) ""++parseTrip :: (Eq a, Pretty a, Show a) => a -> ProtoParser a -> PropertyT IO ()+parseTrip x p = Hedgehog.tripping x (render . pPrint) (runParseTest p)
tests/Test/Proto/Parse/Option.hs view
@@ -1,27 +1,26 @@ -module Test.Proto.Parse.Option (tests) where+module Test.Proto.Parse.Option (testTree) where -import Hedgehog (Property, PropertyT, forAll, property, (===))+import Hedgehog (Property, forAll, property, (===)) import qualified Hedgehog as Hedgehog import qualified Hedgehog.Gen as Gen import Test.Tasty (TestTree, testGroup) import Test.Tasty.Hedgehog (testProperty) +import Test.Proto.Parse.Core (runParseTest, parseTrip) import qualified Test.Proto.Parse.Gen as Gen  import qualified Data.Char as Char import Data.Either (isLeft) import Text.Parsec (ParseError)-import qualified Text.Parsec as Parsec-import Text.PrettyPrint (render)-import Text.PrettyPrint.HughesPJClass (Pretty, pPrint) -import Proto3.Suite.DotProto.Parsing (ProtoParser) import qualified Proto3.Suite.DotProto.Parsing as Proto3 import Proto3.Suite.DotProto.Rendering () -- orphan Pretty DotProtoIdentifier -tests :: TestTree-tests =+--------------------------------------------------------------------------------++testTree :: TestTree+testTree =   testGroup     "Test.Proto.Parse.Option"     [ testProperty "Unqualified Option Identifier" propParseName@@ -29,12 +28,6 @@     , testProperty "Keyword 'Option'" propParseOptionKw     , testsOptionKw     ]--runParseTest :: ProtoParser a -> String -> Either ParseError a-runParseTest p = Parsec.parse (Proto3.runProtoParser p) ""--parseTrip :: (Eq a, Pretty a, Show a) => a -> ProtoParser a -> PropertyT IO ()-parseTrip x p = Hedgehog.tripping x (render . pPrint) (runParseTest p)  propParseName :: Property propParseName = property $ do
+ tests/Test/Proto/ToEncoder.hs view
@@ -0,0 +1,531 @@+{-# LANGUAGE AllowAmbiguousTypes #-}+{-# LANGUAGE CPP #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FunctionalDependencies #-}+{-# LANGUAGE ImplicitParams #-}+{-# LANGUAGE PolyKinds #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeOperators #-}++module Test.Proto.ToEncoder+  ( Iterator(..)+  , Stripping(..)+  , ToEncoder(..)+  ) where++import Control.Category ((.))+import Prelude hiding ((.))++import Data.Foldable (toList)+import qualified Data.Functor.Identity as Functor (Identity(..))+import Data.Kind (Type)+import qualified Data.Map as M+import qualified Data.Vector+import qualified Proto3.Suite.Form as Form+import qualified Proto3.Suite.Form.Encode as FormE+import Proto3.Wire.Encode.Repeated (mapRepeated)++import           TestProto+import qualified TestProtoImport+import qualified TestProtoNegativeEnum+import qualified TestProtoOneof+import qualified TestProtoOneofImport+import qualified TestProtoOptional+import qualified TestProtoWrappers++-- | Which kind of iteration we should test for repeated fields.+data Iterator+  = Identity+  | Forward+  | Vector+  deriving stock (Bounded, Enum, Eq, Read, Show)++-- | Whether we should strip 'FormE.Wrap' from the types of the values to be contained+-- in standard wrappers; either approach should be supported for typically-used types.+data Stripping+  = Keep+  | Strip+  deriving stock (Bounded, Enum, Eq, Read, Show)++class ToEncoder a+  where+    toEncoder :: (?iterator :: Iterator, ?stripping :: Stripping) => a -> FormE.MessageEncoder a++#if TYPE_LEVEL_FORMAT++type family IsWrapped (a :: Type) :: Bool+  where+    IsWrapped (FormE.Wrap _) = 'True+    IsWrapped _ = 'False++class (IsWrapped a ~ w) =>+      Strip a b w | a w -> b+  where+    strip :: a -> b++instance (IsWrapped a ~ 'False) =>+         Strip a a 'False+  where+    strip = id++instance Strip (FormE.Wrap a) a 'True+  where+    strip = FormE.unwrap++implicit ::+  forall name a message names b .+  ( Strip a b (IsWrapped a)+  , FormE.Field name a message+  , FormE.Field name b message+  , ?stripping :: Stripping+  ) =>+  a ->+  FormE.FieldsEncoder message names (FormE.Occupy message name names)+implicit v = case ?stripping of+  Keep -> FormE.field @name @a v+  Strip -> FormE.field @name @b (strip v)++optional ::+  forall name a message names b .+  ( Strip a b (IsWrapped a)+  , FormE.Field name (Maybe a) message+  , FormE.Field name (Maybe b) message+  , ?stripping :: Stripping+  ) =>+  Maybe a ->+  FormE.FieldsEncoder message names (FormE.Occupy message name names)+optional v = case ?stripping of+  Keep -> FormE.field @name @(Maybe a) v+  Strip -> FormE.field @name @(Maybe b) (fmap @Maybe strip v)++repeated ::+  forall name a b c message names .+  ( ?iterator :: Iterator+  , ?stripping :: Stripping+  , Strip b c (IsWrapped b)+  , FormE.Occupy message name names ~ names+  , FormE.Field name (Functor.Identity b) message+  , FormE.Field name ([b]) message+  , FormE.Field name (Data.Vector.Vector b) message+  , FormE.Field name (Functor.Identity c) message+  , FormE.Field name ([c]) message+  , FormE.Field name (Data.Vector.Vector c) message+  ) =>+  (a -> b) ->+  Data.Vector.Vector a ->+  FormE.FieldsEncoder message names names+repeated f = case (?iterator, ?stripping) of+  (Identity, Keep) ->+    -- We use 'Identity' to indicate we should emit the field elements one at a time,+    -- without the potential for packing, though in any case not all types support packing.+    FormE.foldFieldsEncoders . fmap (FormE.field @name . Functor.Identity . f)+  (Identity, Strip) ->+    -- We use 'Identity' to indicate we should emit the field elements one at a time,+    -- without the potential for packing, though in any case not all types support packing.+    FormE.foldFieldsEncoders . fmap (FormE.field @name . Functor.Identity . strip . f)+  (Forward, Keep) ->+    FormE.field @name . map f . toList+  (Forward, Strip) ->+    FormE.field @name . map (strip . f) . toList+  (Vector, Keep) ->+    FormE.field @name . Data.Vector.map f+  (Vector, Strip) ->+    FormE.field @name . Data.Vector.map f++associations ::+  forall name k v key value message names .+  ( Form.ProtoTypeOf message name ~ 'Form.Map key value+  , Form.CardinalityOf message name ~ 'Form.Repeated 'Form.Unpacked+  , ?iterator :: Iterator+  , FormE.Field name (Functor.Identity (FormE.MessageEncoder (Form.Association key value))) message+  , FormE.Field name [FormE.MessageEncoder (Form.Association key value)] message+  , FormE.Field name (Data.Vector.Vector (FormE.MessageEncoder (Form.Association key value))) message+  , FormE.KnownFieldNumber message name+  ) =>+  ((k, v) -> FormE.MessageEncoder (Form.Association key value)) ->+  M.Map k v ->+  FormE.FieldsEncoder message names names+associations f = case ?iterator of+  Identity -> FormE.foldFieldsEncoders .+              mapRepeated (FormE.associations @name . Functor.Identity . f) .+              M.toAscList+  Forward -> FormE.associations @name . map f . M.toAscList+  Vector -> FormE.associations @name . Data.Vector.map f . Data.Vector.fromList . M.toAscList++instance ToEncoder Trivial+  where+    toEncoder (Trivial f1) = FormE.fieldsToMessage @Trivial @'["trivialField"] $+      implicit @"trivialField" f1++instance ToEncoder MultipleFields+  where+    toEncoder (MultipleFields f1 f2 f3 f4 f5 f6) = FormE.fieldsToMessage $+      implicit @"multiFieldDouble" f1 .+      implicit @"multiFieldFloat" f2 .+      implicit @"multiFieldInt32" f3 .+      implicit @"multiFieldInt64" f4 .+      implicit @"multiFieldString" f5 .+      implicit @"multiFieldBool" f6++instance ToEncoder SignedInts+  where+    toEncoder (SignedInts f1 f2) = FormE.fieldsToMessage $+      implicit @"signed32" f1 .+      implicit @"signed64" f2++instance ToEncoder WithEnum+  where+    toEncoder (WithEnum f1) = FormE.fieldsToMessage $+      implicit @"enumField" f1++instance ToEncoder WithNesting_Nested+  where+    toEncoder (WithNesting_Nested f1 f2 f3 f4) = FormE.fieldsToMessage $+      implicit @"nestedField1" f1 .+      implicit @"nestedField2" f2 .+      repeated @"nestedPacked" id f3 .+      repeated @"nestedUnpacked" id f4++instance ToEncoder WithNesting+  where+    toEncoder (WithNesting f1) = FormE.fieldsToMessage $+      optional @"nestedMessage" (fmap @Maybe toEncoder f1)++instance ToEncoder WithNestingRepeated_Nested+  where+    toEncoder (WithNestingRepeated_Nested f1 f2 f3 f4) = FormE.fieldsToMessage $+      implicit @"nestedField1" f1 .+      implicit @"nestedField2" f2 .+      repeated @"nestedPacked" id f3 .+      repeated @"nestedUnpacked" id f4++instance ToEncoder WithNestingRepeated+  where+    toEncoder (WithNestingRepeated f1) = FormE.fieldsToMessage $+      repeated @"nestedMessages" toEncoder f1++instance ToEncoder NestedInts+  where+    toEncoder (NestedInts f1 f2) = FormE.fieldsToMessage $+      implicit @"nestedInt1" f1 .+      implicit @"nestedInt2" f2++instance ToEncoder WithNestingRepeatedInts+  where+    toEncoder (WithNestingRepeatedInts f1) = FormE.fieldsToMessage $+      repeated @"nestedInts" toEncoder f1++instance ToEncoder WithRepetition+  where+    toEncoder (WithRepetition f1) = FormE.fieldsToMessage $+      repeated @"repeatedField1" id f1++instance ToEncoder WithRepeatedSigned+  where+    toEncoder (WithRepeatedSigned f1 f2) = FormE.fieldsToMessage $+      repeated @"r32" id f1 .+      repeated @"r64" id f2++instance ToEncoder WithFixed+  where+    toEncoder (WithFixed f1 f2 f3 f4) = FormE.fieldsToMessage $+      implicit @"fixed1" f1 .+      implicit @"fixed2" f2 .+      implicit @"fixed3" f3 .+      implicit @"fixed4" f4++instance ToEncoder WithBytes+  where+    toEncoder (WithBytes f1 f2) = FormE.fieldsToMessage $+      implicit @"bytes1" f1 .+      repeated @"bytes2" id f2++instance ToEncoder WithPacking+  where+    toEncoder (WithPacking f1 f2) = FormE.fieldsToMessage $+      repeated @"packing1" id f1 .+      repeated @"packing2" id f2++instance ToEncoder AllPackedTypes+  where+    toEncoder (AllPackedTypes f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13) = FormE.fieldsToMessage $+      repeated @"packedWord32" id f1 .+      repeated @"packedWord64" id f2 .+      repeated @"packedInt32" id f3 .+      repeated @"packedInt64" id f4 .+      repeated @"packedFixed32" id f5 .+      repeated @"packedFixed64" id f6 .+      repeated @"packedFloat" id f7 .+      repeated @"packedDouble" id f8 .+      repeated @"packedSFixed32" id f9 .+      repeated @"packedSFixed64" id f10 .+      repeated @"packedBool" id f11 .+      repeated @"packedEnum" id f12 .+      repeated @"unpackedEnum" id f13++instance ToEncoder OutOfOrderFields+  where+    toEncoder (OutOfOrderFields f1 f2 f3 f4) = FormE.fieldsToMessage $+      repeated @"field1" id f1 .+      implicit @"field2" f2 .+      implicit @"field3" f3 .+      repeated @"field4" id f4++instance ToEncoder ShadowedMessage+  where+    toEncoder (ShadowedMessage f1 f2) = FormE.fieldsToMessage $+      implicit @"name" f1 .+      implicit @"value" f2++instance ToEncoder MessageShadower_ShadowedMessage+  where+    toEncoder (MessageShadower_ShadowedMessage f1 f2) = FormE.fieldsToMessage $+      implicit @"name" f1 .+      implicit @"value" f2++instance ToEncoder MessageShadower+  where+    toEncoder (MessageShadower f1 f2) = FormE.fieldsToMessage $+      optional @"shadowed_message" (fmap @Maybe toEncoder f1) .+      implicit @"name" f2++instance ToEncoder WithQualifiedName+  where+    toEncoder (WithQualifiedName f1 f2) = FormE.fieldsToMessage $+      optional @"qname1" (fmap @Maybe toEncoder f1) .+      optional @"qname2" (fmap @Maybe toEncoder f2)++instance ToEncoder TestProtoImport.WithNesting_Nested+  where+    toEncoder (TestProtoImport.WithNesting_Nested f1 f2) = FormE.fieldsToMessage $+      implicit @"nestedField1" f1 .+      implicit @"nestedField2" f2++instance ToEncoder TestProtoImport.WithNesting+  where+    toEncoder (TestProtoImport.WithNesting f1 f2) = FormE.fieldsToMessage $+      optional @"nestedMessage1" (fmap @Maybe toEncoder f1) .+      optional @"nestedMessage2" (fmap @Maybe toEncoder f2)++instance ToEncoder UsingImported+  where+    toEncoder (UsingImported f1 f2) = FormE.fieldsToMessage $+      optional @"importedNesting" (fmap @Maybe toEncoder f1) .+      optional @"localNesting" (fmap @Maybe toEncoder f2)++instance ToEncoder TestProtoOneof.DummyMsg+  where+    toEncoder (TestProtoOneof.DummyMsg f1) = FormE.fieldsToMessage $+      implicit @"dummy" f1++instance ToEncoder TestProtoOneofImport.AMessage+  where+    toEncoder (TestProtoOneofImport.AMessage f1 f2) = FormE.fieldsToMessage $+      implicit @"x" f1 .+      implicit @"y" f2++instance ToEncoder TestProtoOneofImport.WithOneof+  where+    toEncoder (TestProtoOneofImport.WithOneof f1) = FormE.fieldsToMessage $+      case f1 of+        Nothing ->+          FormE.omitted+        Just (TestProtoOneofImport.WithOneofPickOneA v) ->+          optional @"a" (Just v)+        Just (TestProtoOneofImport.WithOneofPickOneB v) ->+          optional @"b" (Just v)+        Just (TestProtoOneofImport.WithOneofPickOneC v) ->+          optional @"c" (Just (toEncoder v))++instance ToEncoder TestProtoOneof.Something+  where+    toEncoder (TestProtoOneof.Something f1 f2 f3) = FormE.fieldsToMessage $+      implicit @"value" f1 .+      implicit @"another" f2 .+      case f3 of+        Nothing ->+          FormE.omitted+        Just (TestProtoOneof.SomethingPickOneName v) ->+          optional @"name" (Just v)+        Just (TestProtoOneof.SomethingPickOneSomeid v) ->+          optional @"someid" (Just v)+        Just (TestProtoOneof.SomethingPickOneDummyMsg1 v) ->+          optional @"dummyMsg1" (Just (toEncoder v))+        Just (TestProtoOneof.SomethingPickOneDummyMsg2 v) ->+          optional @"dummyMsg2" (Just (toEncoder v))+        Just (TestProtoOneof.SomethingPickOneDummyEnum v) ->+          optional @"dummyEnum" (Just v)++instance ToEncoder TestProtoOneof.WithImported+  where+    toEncoder (TestProtoOneof.WithImported f1) = FormE.fieldsToMessage $+      case f1 of+        Nothing ->+          FormE.omitted+        Just (TestProtoOneof.WithImportedPickOneDummyMsg1 v) ->+          optional @"dummyMsg1" (Just (toEncoder v))+        Just (TestProtoOneof.WithImportedPickOneWithOneof v) ->+          optional @"withOneof" (Just (toEncoder v))++instance ToEncoder TestProtoWrappers.TestDoubleValue+  where+    toEncoder (TestProtoWrappers.TestDoubleValue f1 f2 f3) = FormE.fieldsToMessage $+      optional @"wrapper" (fmap FormE.Wrap f1) .+      repeated @"many" FormE.Wrap f2 .+      case f3 of+        Nothing ->+          FormE.omitted+        Just (TestProtoWrappers.TestDoubleValuePickOneOne v) ->+          optional @"one" (Just (FormE.Wrap v))++instance ToEncoder TestProtoWrappers.TestFloatValue+  where+    toEncoder (TestProtoWrappers.TestFloatValue f1 f2 f3) = FormE.fieldsToMessage $+      optional @"wrapper" (fmap FormE.Wrap f1) .+      repeated @"many" FormE.Wrap f2 .+      case f3 of+        Nothing ->+          FormE.omitted+        Just (TestProtoWrappers.TestFloatValuePickOneOne v) ->+          optional @"one" (Just (FormE.Wrap v))++instance ToEncoder TestProtoWrappers.TestInt64Value+  where+    toEncoder (TestProtoWrappers.TestInt64Value f1 f2 f3) = FormE.fieldsToMessage $+      optional @"wrapper" (fmap FormE.Wrap f1) .+      repeated @"many" FormE.Wrap f2 .+      case f3 of+        Nothing ->+          FormE.omitted+        Just (TestProtoWrappers.TestInt64ValuePickOneOne v) ->+          optional @"one" (Just (FormE.Wrap v))++instance ToEncoder TestProtoWrappers.TestUInt64Value+  where+    toEncoder (TestProtoWrappers.TestUInt64Value f1 f2 f3) = FormE.fieldsToMessage $+      optional @"wrapper" (fmap FormE.Wrap f1) .+      repeated @"many" FormE.Wrap f2 .+      case f3 of+        Nothing ->+          FormE.omitted+        Just (TestProtoWrappers.TestUInt64ValuePickOneOne v) ->+          optional @"one" (Just (FormE.Wrap v))++instance ToEncoder TestProtoWrappers.TestInt32Value+  where+    toEncoder (TestProtoWrappers.TestInt32Value f1 f2 f3) = FormE.fieldsToMessage $+      optional @"wrapper" (fmap FormE.Wrap f1) .+      repeated @"many" FormE.Wrap f2 .+      case f3 of+        Nothing ->+          FormE.omitted+        Just (TestProtoWrappers.TestInt32ValuePickOneOne v) ->+          optional @"one" (Just (FormE.Wrap v))++instance ToEncoder TestProtoWrappers.TestUInt32Value+  where+    toEncoder (TestProtoWrappers.TestUInt32Value f1 f2 f3) = FormE.fieldsToMessage $+      optional @"wrapper" (fmap FormE.Wrap f1) .+      repeated @"many" FormE.Wrap f2 .+      case f3 of+        Nothing ->+          FormE.omitted+        Just (TestProtoWrappers.TestUInt32ValuePickOneOne v) ->+          optional @"one" (Just (FormE.Wrap v))++instance ToEncoder TestProtoWrappers.TestBoolValue+  where+    toEncoder (TestProtoWrappers.TestBoolValue f1 f2 f3) = FormE.fieldsToMessage $+      optional @"wrapper" (fmap FormE.Wrap f1) .+      repeated @"many" FormE.Wrap f2 .+      case f3 of+        Nothing ->+          FormE.omitted+        Just (TestProtoWrappers.TestBoolValuePickOneOne v) ->+          optional @"one" (Just (FormE.Wrap v))++instance ToEncoder TestProtoWrappers.TestStringValue+  where+    toEncoder (TestProtoWrappers.TestStringValue f1 f2 f3) = FormE.fieldsToMessage $+      optional @"wrapper" (fmap FormE.Wrap f1) .+      repeated @"many" FormE.Wrap f2 .+      case f3 of+        Nothing ->+          FormE.omitted+        Just (TestProtoWrappers.TestStringValuePickOneOne v) ->+          optional @"one" (Just (FormE.Wrap v))++instance ToEncoder TestProtoWrappers.TestBytesValue+  where+    toEncoder (TestProtoWrappers.TestBytesValue f1 f2 f3) = FormE.fieldsToMessage $+      optional @"wrapper" (fmap FormE.Wrap f1) .+      repeated @"many" FormE.Wrap f2 .+      case f3 of+        Nothing ->+          FormE.omitted+        Just (TestProtoWrappers.TestBytesValuePickOneOne v) ->+          optional @"one" (Just (FormE.Wrap v))++instance ToEncoder WrappedTrivial+  where+    toEncoder (WrappedTrivial f1) = FormE.fieldsToMessage $+      optional @"trivial" (fmap @Maybe toEncoder f1)++instance ToEncoder MapTest+  where+    toEncoder (MapTest f1 f2 f3) = FormE.fieldsToMessage $+        associations @"prim" assoc1 f1 .+        associations @"trivial" assoc2 f2 .+        associations @"signed" assoc3 f3+      where+        assoc1 (k, v) = FormE.fieldsToMessage $+          implicit @"key" k .+          implicit @"value" v++        assoc2 (k, v) = FormE.fieldsToMessage $+          implicit @"key" k .+          optional @"value" (fmap @Maybe toEncoder v)++        assoc3 (k, v) = FormE.fieldsToMessage $+          implicit @"key" k .+          implicit @"value" v++instance ToEncoder TestProtoNegativeEnum.WithNegativeEnum+  where+    toEncoder (TestProtoNegativeEnum.WithNegativeEnum f1) = FormE.fieldsToMessage $+      implicit @"v" f1++instance ToEncoder TestProtoOptional.Submessage+  where+    toEncoder (TestProtoOptional.Submessage f1) = FormE.fieldsToMessage $+      implicit @"someField" f1++instance ToEncoder TestProtoOptional.WithOptional+  where+    toEncoder (TestProtoOptional.WithOptional+                 f1 f2 f3 f4 f5 f6 f7 f8 f9 f10 f11 f12 f13 f14 f15 f16 f17+              ) = FormE.fieldsToMessage $+      optional @"optionalDouble" f1 .+      optional @"optionalFloat" f2 .+      optional @"optionalInt32" f3 .+      optional @"optionalInt64" f4 .+      optional @"optionalUint32" f5 .+      optional @"optionalUint64" f6 .+      optional @"optionalSint32" f7 .+      optional @"optionalSint64" f8 .+      optional @"optionalFixed32" f9 .+      optional @"optionalFixed64" f10 .+      optional @"optionalSfixed32" f11 .+      optional @"optionalSfixed64" f12 .+      optional @"optionalBool" f13 .+      optional @"optionalString" f14 .+      optional @"optionalBytes" f15 .+      optional @"optionalEnum" f16 .+      optional @"optionalSubmessage" (fmap @Maybe toEncoder f17)++#endif
tests/TestCodeGen.hs view
@@ -1,105 +1,127 @@ {-# LANGUAGE AllowAmbiguousTypes #-}-{-# LANGUAGE CPP                 #-}+{-# LANGUAGE CPP #-} {-# LANGUAGE DisambiguateRecordFields #-}-{-# LANGUAGE LambdaCase          #-}-{-# LANGUAGE OverloadedLists     #-}-{-# LANGUAGE OverloadedStrings   #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-}-{-# LANGUAGE TypeApplications    #-}+{-# LANGUAGE TypeApplications #-}  module TestCodeGen where  import           ArbitraryGeneratedTestTypes    () import           Control.Applicative import           Control.Monad+#ifdef SWAGGER import qualified Data.Aeson+#endif import qualified Data.ByteString.Lazy           as LBS import           Data.Proxy                     (Proxy(..)) import           Data.String                    (IsString)+#ifdef SWAGGER import           Data.Swagger                   (ToSchema) import qualified Data.Swagger+#endif import qualified Data.Text                      as T-import           Data.Typeable                  (Typeable, splitTyConApp,-                                                 tyConName, typeRep)+import           Data.Typeable                  (Typeable, typeRep,+#ifdef SWAGGER+                                                 splitTyConApp, tyConName+#endif+                                                )+import           GHC.Exts                       (Proxy#, proxy#)+#ifdef SWAGGER+import           GHC.Stack                      (HasCallStack)+#endif import           Google.Protobuf.Timestamp      (Timestamp(..)) import           Prelude                        hiding (FilePath)-import           Proto3.Suite.Class             (def)-import           Proto3.Suite.DotProto.Generate+import           Proto3.Suite.Class             (Message(..), def) import           Proto3.Suite.DotProto          (fieldLikeName, prefixedEnumFieldName, typeLikeName)+import           Proto3.Suite.DotProto.AST      (DotProtoField(..), DotProtoIdentifier(..),+                                                 DotProtoType(..), DotProtoPrimType(..))+import           Proto3.Suite.DotProto.Generate+import           Proto3.Suite.Haskell.Parser    (Logger) import           Proto3.Suite.JSONPB            (FromJSONPB (..), Options (..),                                                  ToJSONPB (..), defaultOptions,                                                  eitherDecode, encode,                                                  jsonPBOptions) import           Proto3.Suite.Types             (Enumerated(..)) import           System.Exit+import           Test.Proto.ToEncoder           (Iterator, Stripping) import           Test.Tasty import           Test.Tasty.HUnit               (testCase, (@?=)) import           Test.Tasty.QuickCheck          (Arbitrary, (===), testProperty) import qualified Turtle import qualified Turtle.Format                  as F import qualified TestProto+import qualified TestProtoNegativeEnum import qualified TestProtoOneof+import qualified TestProtoOptional+#ifdef SWAGGER import qualified TestProtoWrappers+#endif -codeGenTests :: TestTree-codeGenTests = testGroup "Code generator unit tests"-  [ jsonpbTests-  , swaggerTests+codeGenTests :: Logger -> TestTree+codeGenTests logger = testGroup "Code generator unit tests"+  [ dotProtoTests+  , jsonpbTests   , hasDefaultTests-  , swaggerWrapperFormat   , pascalCaseMessageNames   , camelCaseMessageFieldNames   , don'tAlterEnumFieldNames   , knownTypeMessages-  , pythonInteroperation+  , pythonInteroperation logger+#ifdef SWAGGER+  , swaggerTests+  , swaggerWrapperFormat+#endif   ] -pythonInteroperation :: TestTree-pythonInteroperation = testGroup "Python interoperation" $ do-#ifdef LARGE_RECORDS-  recStyle <- [RegularRecords, LargeRecords]-#else-  recStyle <- [RegularRecords]-#endif+pythonInteroperation :: Logger -> TestTree+pythonInteroperation logger = testGroup "Python interoperation" $ do   tt <- ["Data.Text.Lazy.Text", "Data.Text.Text", "Data.Text.Short.ShortText"]   format <- ["Binary", "Jsonpb"]-  direction <- [simpleEncodeDotProto, simpleDecodeDotProto]-  pure @[] (direction recStyle tt format)+  testEncode <- [True, False]+  direct <- [False, True]+  guard $ not direct || (testEncode && format == "Binary")+  let f = if testEncode then simpleEncodeDotProto direct else simpleDecodeDotProto+  pure @[] (f logger tt format) +#ifdef SWAGGER swaggerWrapperFormat :: TestTree swaggerWrapperFormat = testGroup "Swagger Wrapper Format"     [ expectSchema @TestProtoWrappers.TestDoubleValue-           "{\"properties\":{\"wrapper\":{\"format\":\"DoubleValue\",\"type\":\"number\"}},\"type\":\"object\"}"-           "{\"properties\":{\"wrapper\":{\"format\":\"double\",\"type\":\"number\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"DoubleValue\",\"type\":\"number\"},\"many\":{\"items\":{\"format\":\"double\",\"type\":\"number\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestDoubleValuePickOne\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"double\",\"type\":\"number\"},\"many\":{\"items\":{\"format\":\"double\",\"type\":\"number\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestDoubleValuePickOne\"}},\"type\":\"object\"}"     , expectSchema @TestProtoWrappers.TestFloatValue-           "{\"properties\":{\"wrapper\":{\"format\":\"FloatValue\",\"type\":\"number\"}},\"type\":\"object\"}"-           "{\"properties\":{\"wrapper\":{\"format\":\"float\",\"type\":\"number\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"FloatValue\",\"type\":\"number\"},\"many\":{\"items\":{\"format\":\"float\",\"type\":\"number\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestFloatValuePickOne\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"float\",\"type\":\"number\"},\"many\":{\"items\":{\"format\":\"float\",\"type\":\"number\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestFloatValuePickOne\"}},\"type\":\"object\"}"     , expectSchema @TestProtoWrappers.TestInt64Value-           "{\"properties\":{\"wrapper\":{\"format\":\"Int64Value\",\"maximum\":9223372036854775807,\"minimum\":-9223372036854775808,\"type\":\"integer\"}},\"type\":\"object\"}"-           "{\"properties\":{\"wrapper\":{\"format\":\"int64\",\"maximum\":9223372036854775807,\"minimum\":-9223372036854775808,\"type\":\"integer\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"Int64Value\",\"maximum\":9223372036854775807,\"minimum\":-9223372036854775808,\"type\":\"integer\"},\"many\":{\"items\":{\"format\":\"int64\",\"maximum\":9223372036854775807,\"minimum\":-9223372036854775808,\"type\":\"integer\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestInt64ValuePickOne\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"int64\",\"maximum\":9223372036854775807,\"minimum\":-9223372036854775808,\"type\":\"integer\"},\"many\":{\"items\":{\"format\":\"int64\",\"maximum\":9223372036854775807,\"minimum\":-9223372036854775808,\"type\":\"integer\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestInt64ValuePickOne\"}},\"type\":\"object\"}"     , expectSchema @TestProtoWrappers.TestUInt64Value-           "{\"properties\":{\"wrapper\":{\"format\":\"UInt64Value\",\"maximum\":18446744073709551615,\"minimum\":0,\"type\":\"integer\"}},\"type\":\"object\"}"-           "{\"properties\":{\"wrapper\":{\"format\":\"int64\",\"maximum\":18446744073709551615,\"minimum\":0,\"type\":\"integer\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"UInt64Value\",\"maximum\":18446744073709551615,\"minimum\":0,\"type\":\"integer\"},\"many\":{\"items\":{\"format\":\"int64\",\"maximum\":18446744073709551615,\"minimum\":0,\"type\":\"integer\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestUInt64ValuePickOne\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"int64\",\"maximum\":18446744073709551615,\"minimum\":0,\"type\":\"integer\"},\"many\":{\"items\":{\"format\":\"int64\",\"maximum\":18446744073709551615,\"minimum\":0,\"type\":\"integer\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestUInt64ValuePickOne\"}},\"type\":\"object\"}"     , expectSchema @TestProtoWrappers.TestInt32Value-           "{\"properties\":{\"wrapper\":{\"format\":\"Int32Value\",\"maximum\":2147483647,\"minimum\":-2147483648,\"type\":\"integer\"}},\"type\":\"object\"}"-           "{\"properties\":{\"wrapper\":{\"format\":\"int32\",\"maximum\":2147483647,\"minimum\":-2147483648,\"type\":\"integer\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"Int32Value\",\"maximum\":2147483647,\"minimum\":-2147483648,\"type\":\"integer\"},\"many\":{\"items\":{\"format\":\"int32\",\"maximum\":2147483647,\"minimum\":-2147483648,\"type\":\"integer\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestInt32ValuePickOne\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"int32\",\"maximum\":2147483647,\"minimum\":-2147483648,\"type\":\"integer\"},\"many\":{\"items\":{\"format\":\"int32\",\"maximum\":2147483647,\"minimum\":-2147483648,\"type\":\"integer\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestInt32ValuePickOne\"}},\"type\":\"object\"}"     , expectSchema @TestProtoWrappers.TestUInt32Value-           "{\"properties\":{\"wrapper\":{\"format\":\"UInt32Value\",\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"}},\"type\":\"object\"}"-           "{\"properties\":{\"wrapper\":{\"format\":\"int32\",\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"UInt32Value\",\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"},\"many\":{\"items\":{\"format\":\"int32\",\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestUInt32ValuePickOne\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"int32\",\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"},\"many\":{\"items\":{\"format\":\"int32\",\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestUInt32ValuePickOne\"}},\"type\":\"object\"}"     , expectSchema @TestProtoWrappers.TestBoolValue-           "{\"properties\":{\"wrapper\":{\"format\":\"BoolValue\",\"type\":\"boolean\"}},\"type\":\"object\"}"-           "{\"properties\":{\"wrapper\":{\"type\":\"boolean\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"BoolValue\",\"type\":\"boolean\"},\"many\":{\"items\":{\"type\":\"boolean\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestBoolValuePickOne\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"type\":\"boolean\"},\"many\":{\"items\":{\"type\":\"boolean\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestBoolValuePickOne\"}},\"type\":\"object\"}"     , expectSchema @TestProtoWrappers.TestStringValue-           "{\"properties\":{\"wrapper\":{\"format\":\"StringValue\",\"type\":\"string\"}},\"type\":\"object\"}"-           "{\"properties\":{\"wrapper\":{\"type\":\"string\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"StringValue\",\"type\":\"string\"},\"many\":{\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestStringValuePickOne\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"type\":\"string\"},\"many\":{\"items\":{\"type\":\"string\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestStringValuePickOne\"}},\"type\":\"object\"}"     , expectSchema @TestProtoWrappers.TestBytesValue-           "{\"properties\":{\"wrapper\":{\"format\":\"BytesValue\",\"type\":\"string\"}},\"type\":\"object\"}"-           "{\"properties\":{\"wrapper\":{\"format\":\"byte\",\"type\":\"string\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"BytesValue\",\"type\":\"string\"},\"many\":{\"items\":{\"format\":\"byte\",\"type\":\"string\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestBytesValuePickOne\"}},\"type\":\"object\"}"+           "{\"properties\":{\"wrapper\":{\"format\":\"byte\",\"type\":\"string\"},\"many\":{\"items\":{\"format\":\"byte\",\"type\":\"string\"},\"type\":\"array\"},\"pickOne\":{\"$ref\":\"#/definitions/TestBytesValuePickOne\"}},\"type\":\"object\"}"     ]   where     expectSchema ::       forall a .-      (ToSchema a, Typeable a) =>+      (ToSchema a, Typeable a, HasCallStack) =>       LBS.ByteString ->       LBS.ByteString ->       TestTree@@ -113,6 +135,7 @@ #else         wf = False #endif+#endif  knownTypeMessages :: TestTree knownTypeMessages =@@ -174,41 +197,58 @@ setPythonPath = Turtle.export "PYTHONPATH" .   maybe pyTmpDir (\p -> pyTmpDir <> ":" <> p) =<< Turtle.need "PYTHONPATH" -simpleEncodeDotProto :: RecordStyle -> String -> T.Text -> TestTree-simpleEncodeDotProto recStyle chosenStringType format =+simpleEncodeDotProto :: Bool -> Logger -> String -> T.Text -> TestTree+simpleEncodeDotProto direct logger chosenStringType format =     testCase ("generate code for a simple .proto and then use it to encode messages" ++               " with string type " ++ chosenStringType ++ " in format " ++ show format ++-              ", record style " ++ show recStyle)+              (if direct then ", direct mode" else ", intermediate mode"))     $ do          decodedStringType <- either die pure (parseStringType chosenStringType) -         compileTestDotProtos recStyle decodedStringType+         compileTestDotProtos logger decodedStringType direct          -- Compile our generated encoder          let encodeCmd = "tests/encode.sh " <> hsTmpDir+                           <> (if direct then " -DTYPE_LEVEL_FORMAT" else "") #if DHALL                            <> " -DDHALL" #endif          Turtle.shell encodeCmd empty >>= (@?= ExitSuccess) -         -- The python encoder test exits with a special error code to indicate-         -- all tests were successful+         -- The python test of encoding exits with a special error code to indicate+         -- all tests were successful.  When directly encoding without an intermediate+         -- data structure, we run the test several times (still compiling just once)+         -- in order to cover various supported ways of iterating over repeated fields.          setPythonPath-         let cmd = hsTmpDir <> "/simpleEncodeDotProto " <> format <> " | python tests/check_simple_dot_proto.py " <> format-         Turtle.shell cmd empty >>= (@?= ExitFailure 12)+         let iterators :: [Iterator]+             iterators+               | direct = [minBound .. maxBound]+               | otherwise = [minBound]  -- Just an unused placeholder+             strippings :: [Stripping]+             strippings+               | direct = [minBound .. maxBound]+               | otherwise = [minBound]  -- Just an unused placeholder+         forM_ iterators $ \(iterator :: Iterator) -> do+           forM_ strippings $ \(stripping :: Stripping) -> do+             when direct $ do+               putStrLn $ "        iterator: " ++ show iterator+               putStrLn $ "        stripping: " ++ show stripping+             let cmd = hsTmpDir <> "/simpleEncodeDotProto " <> format <>+                       " " <> T.pack (show iterator) <> " " <> T.pack (show stripping) <>+                       " | python tests/check_simple_dot_proto.py " <> format+             Turtle.shell cmd empty >>= (@?= ExitFailure 12)           -- Not using bracket so that we can inspect the output to fix the tests          Turtle.rmtree hsTmpDir          Turtle.rmtree pyTmpDir -simpleDecodeDotProto :: RecordStyle -> String -> T.Text -> TestTree-simpleDecodeDotProto recStyle chosenStringType format =+simpleDecodeDotProto :: Logger -> String -> T.Text -> TestTree+simpleDecodeDotProto logger chosenStringType format =     testCase ("generate code for a simple .proto and then use it to decode messages" ++-              " with string type " ++ chosenStringType ++ " in format " ++ show format ++-              ", record style " ++ show recStyle)+              " with string type " ++ chosenStringType ++ " in format " ++ show format)     $ do          decodedStringType <- either die pure (parseStringType chosenStringType) -         compileTestDotProtos recStyle decodedStringType+         compileTestDotProtos logger decodedStringType False          -- Compile our generated decoder          let decodeCmd = "tests/decode.sh " <> hsTmpDir #if DHALL@@ -233,14 +273,15 @@ defaultStringType :: StringType defaultStringType = StringType "Data.Text.Lazy" "Text" -compileTestDotProtos :: RecordStyle -> StringType -> IO ()-compileTestDotProtos recStyle decodedStringType = do+compileTestDotProtos :: Logger -> StringType -> Bool -> IO ()+compileTestDotProtos logger decodedStringType typeLevel = do   Turtle.mktree hsTmpDir   Turtle.mktree pyTmpDir   let protoFiles :: [Turtle.FilePath]       protoFiles =         [ "test_proto.proto"         , "test_proto_import.proto"+        , "test_proto_negative_enum.proto"         , "test_proto_oneof.proto"         , "test_proto_oneof_import.proto"         {- These tests have been temporarily removed to pass CI.@@ -249,16 +290,18 @@         -}         , "test_proto_nested_message.proto"         , "test_proto_wrappers.proto"+        , "test_proto_negative_enum.proto"+        , "test_proto_optional.proto"         ]    forM_ protoFiles $ \protoFile -> do-    compileDotProtoFileOrDie+    compileDotProtoFileOrDie logger         CompileArgs{ includeDir = ["test-files"]                    , extraInstanceFiles = ["test-files" Turtle.</> "Orphan.hs"]                    , outputDir = hsTmpDir                    , inputProto = protoFile                    , stringType = decodedStringType-                   , recordStyle = recStyle+                   , typeLevelFormat = typeLevel                    }      let cmd = T.concat [ "protoc --python_out="@@ -270,6 +313,57 @@    Turtle.touch (pyTmpDir Turtle.</> "__init__.py") +dotProtoTests :: TestTree+dotProtoTests = testGroup "dotProto method tests"+  [ dotProtoTest @TestProto.Trivial+      [ DotProtoField 1 (Prim Int32) (Single "trivialField") [] ""+      ]+  , dotProtoTest @TestProto.MultipleFields+      [ DotProtoField 1 (Prim Double) (Single "multiFieldDouble") [] ""+      , DotProtoField 2 (Prim Float) (Single "multiFieldFloat") [] ""+      , DotProtoField 3 (Prim Int32) (Single "multiFieldInt32") [] ""+      , DotProtoField 4 (Prim Int64) (Single "multiFieldInt64") [] ""+      , DotProtoField 5 (Prim String) (Single "multiFieldString") [] ""+      , DotProtoField 6 (Prim Bool) (Single "multiFieldBool") [] ""+      ]+  , dotProtoTest @TestProto.SignedInts+      [ DotProtoField 1 (Prim SInt32) (Single "signed32") [] ""+      , DotProtoField 2 (Prim SInt64) (Single "signed64") [] ""+      ]+  , dotProtoTest @TestProto.MapTest+      [ DotProtoField 1 (Map String SInt32) (Single "prim") [] ""+      , DotProtoField 2 (Map Int32 (Named (Single "WrappedTrivial"))) (Single "trivial") [] ""+      , DotProtoField 3 (Map SInt32 SInt32) (Single "signed") [] ""+          -- Current parser discards comments.+      ]+  , dotProtoTest @TestProto.WithNestingRepeatedInts+      [ DotProtoField 1 (Repeated (Named (Single "NestedInts"))) (Single "nestedInts") [] ""+      ]+  , dotProtoTest @TestProto.WithRepeatedSigned+      [ DotProtoField 1 (Repeated SInt32) (Single "r32") [] ""+      , DotProtoField 2 (Repeated SInt64) (Single "r64") [] ""+      ]+  , dotProtoTest @TestProtoOptional.WithOptional+      [ DotProtoField 10 (Optional Double) (Single "optionalDouble") [] ""+      , DotProtoField 20 (Optional Float) (Single "optionalFloat") [] ""+      , DotProtoField 30 (Optional Int32) (Single "optionalInt32") [] ""+      , DotProtoField 40 (Optional Int64) (Single "optionalInt64") [] ""+      , DotProtoField 50 (Optional UInt32) (Single "optionalUint32") [] ""+      , DotProtoField 60 (Optional UInt64) (Single "optionalUint64") [] ""+      , DotProtoField 70 (Optional SInt32) (Single "optionalSint32") [] ""+      , DotProtoField 80 (Optional SInt64) (Single "optionalSint64") [] ""+      , DotProtoField 90 (Optional Fixed32) (Single "optionalFixed32") [] ""+      , DotProtoField 100 (Optional Fixed64) (Single "optionalFixed64") [] ""+      , DotProtoField 110 (Optional SFixed32) (Single "optionalSfixed32") [] ""+      , DotProtoField 120 (Optional SFixed64) (Single "optionalSfixed64") [] ""+      , DotProtoField 130 (Optional Bool) (Single "optionalBool") [] ""+      , DotProtoField 140 (Optional String) (Single "optionalString") [] ""+      , DotProtoField 150 (Optional Bytes) (Single "optionalBytes") [] ""+      , DotProtoField 160 (Optional (Named (Single "Enum"))) (Single "optionalEnum") [] ""+      , DotProtoField 170 (Optional (Named (Single "Submessage"))) (Single "optionalSubmessage") [] ""+      ]+  ]+ jsonpbTests :: TestTree jsonpbTests = testGroup "JSONPB tests"   [ testGroup "Round-trip tests"@@ -291,6 +385,8 @@       , roundTripTest @TestProto.Wrapped       , roundTripTest @TestProtoOneof.Something       , roundTripTest @TestProtoOneof.WithImported+      , roundTripTest @TestProtoNegativeEnum.WithNegativeEnum+      , roundTripTest @TestProtoOptional.WithOptional       ]   , testGroup "Specific encoding tests" $       let jsonPB = jsonPBOptions@@ -376,6 +472,7 @@       ]   ] +#ifdef SWAGGER swaggerTests :: TestTree swaggerTests = testGroup "Swagger tests"   [ schemaOf @TestProtoOneof.Something@@ -386,8 +483,28 @@       "{\"properties\":{\"dummy\":{\"format\":\"int32\",\"maximum\":2147483647,\"minimum\":-2147483648,\"type\":\"integer\"}},\"type\":\"object\"}"   , schemaOf @(Enumerated TestProtoOneof.DummyEnum)       "{\"enum\":[\"DUMMY0\",\"DUMMY1\"],\"type\":\"string\"}"-+  , schemaOf @TestProtoOptional.WithOptional $+      "{\"properties\":{" <>+      "\"optionalDouble\":{\"format\":\"double\",\"type\":\"number\"}," <>+      "\"optionalFloat\":{\"format\":\"float\",\"type\":\"number\"}," <>+      "\"optionalInt32\":{\"format\":\"int32\",\"maximum\":2147483647,\"minimum\":-2147483648,\"type\":\"integer\"}," <>+      "\"optionalInt64\":{\"format\":\"int64\",\"maximum\":9223372036854775807,\"minimum\":-9223372036854775808,\"type\":\"integer\"}," <>+      "\"optionalUint32\":{\"format\":\"int32\",\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"}," <>+      "\"optionalUint64\":{\"format\":\"int64\",\"maximum\":18446744073709551615,\"minimum\":0,\"type\":\"integer\"}," <>+      "\"optionalSint32\":{\"format\":\"int32\",\"maximum\":2147483647,\"minimum\":-2147483648,\"type\":\"integer\"}," <>+      "\"optionalSint64\":{\"format\":\"int64\",\"maximum\":9223372036854775807,\"minimum\":-9223372036854775808,\"type\":\"integer\"}," <>+      "\"optionalFixed32\":{\"format\":\"int32\",\"maximum\":4294967295,\"minimum\":0,\"type\":\"integer\"}," <>+      "\"optionalFixed64\":{\"format\":\"int64\",\"maximum\":18446744073709551615,\"minimum\":0,\"type\":\"integer\"}," <>+      "\"optionalSfixed32\":{\"format\":\"int32\",\"maximum\":2147483647,\"minimum\":-2147483648,\"type\":\"integer\"}," <>+      "\"optionalSfixed64\":{\"format\":\"int64\",\"maximum\":9223372036854775807,\"minimum\":-9223372036854775808,\"type\":\"integer\"}," <>+      "\"optionalBool\":{\"type\":\"boolean\"}," <>+      "\"optionalString\":{\"type\":\"string\"}," <>+      "\"optionalBytes\":{\"format\":\"byte\",\"type\":\"string\"}," <>+      "\"optionalEnum\":{\"$ref\":\"#/definitions/Enum\"}," <>+      "\"optionalSubmessage\":{\"$ref\":\"#/definitions/Submessage\"}" <>+      "},\"type\":\"object\"}"   ]+#endif  hasDefaultTests :: TestTree hasDefaultTests = testGroup "Generic HasDefault"@@ -407,6 +524,15 @@  -- * Helper quickcheck props +dotProtoTest ::+  forall a .+  (Message a, Typeable a) =>+  [DotProtoField] ->+  TestTree+dotProtoTest expected =+  testProperty ("dotProtoTest @" ++ show (typeRep (Proxy :: Proxy a))) $+    dotProto (proxy# :: Proxy# a) === expected+ roundTripTest ::   forall a .   (ToJSONPB a, FromJSONPB a, Eq a, Arbitrary a, Show a, Typeable a) =>@@ -454,6 +580,7 @@       showString " == Right " .       showsPrec 11 x +#ifdef SWAGGER schemaOf ::   forall a .   (ToSchema a, Eq a, Show a, Typeable a) =>@@ -468,3 +595,4 @@  lbsSchemaOf :: forall a . ToSchema a => LBS.ByteString lbsSchemaOf = Data.Aeson.encode (Data.Swagger.toSchema (Proxy @a))+#endif
tests/decode.sh view
@@ -11,8 +11,10 @@     "$@"                                    \     $hsTmpDir/TestProto.hs                  \     $hsTmpDir/TestProtoImport.hs            \+    $hsTmpDir/TestProtoNegativeEnum.hs      \     $hsTmpDir/TestProtoOneof.hs             \     $hsTmpDir/TestProtoOneofImport.hs       \+    $hsTmpDir/TestProtoOptional.hs          \     $hsTmpDir/TestProtoWrappers.hs          \     tests/Test/Dhall/Orphan.hs              \     tests/SimpleDecodeDotProto.hs           \
tests/encode.sh view
@@ -11,10 +11,13 @@     "$@"                                    \     $hsTmpDir/TestProto.hs                  \     $hsTmpDir/TestProtoImport.hs            \+    $hsTmpDir/TestProtoNegativeEnum.hs      \     $hsTmpDir/TestProtoOneof.hs             \     $hsTmpDir/TestProtoOneofImport.hs       \+    $hsTmpDir/TestProtoOptional.hs          \     $hsTmpDir/TestProtoWrappers.hs          \     tests/Test/Dhall/Orphan.hs              \+    tests/Test/Proto/ToEncoder.hs           \     tests/SimpleEncodeDotProto.hs           \     >/dev/null 
tools/canonicalize-proto-file/Main.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE DataKinds              #-} {-# LANGUAGE DefaultSignatures      #-}-{-# LANGUAGE DeriveGeneric          #-} {-# LANGUAGE FlexibleInstances      #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE LambdaCase             #-}@@ -11,26 +10,61 @@ {-# LANGUAGE TypeFamilies           #-} {-# LANGUAGE TypeOperators          #-} -module Main (main) where+module Main where -import           Control.Monad.Except-import           Data.List                        (sort, sortOn)-import qualified Data.List.NonEmpty              as NE-import           Data.RangeSet.List               (fromRangeList, toRangeList)-import           Data.Semigroup                   (Min(..))-import           Options.Generic-import           Prelude                          hiding (FilePath)-import           Proto3.Suite.DotProto.AST-import           Proto3.Suite.DotProto.Generate-import           Proto3.Suite.DotProto.Rendering-import           Proto3.Wire.Types                (FieldNumber (..))-import           Turtle                           (FilePath)+import Control.Monad.Except (runExceptT) +import Data.List (sort, sortOn)+import Data.List.NonEmpty qualified as NE+import Data.Semigroup (Min(..))++import GHC.Generics (Generic)++import Options.Generic +  ( ParseRecord+  , Unwrapped+  , Wrapped +  , (:::)+  , type (<?>) (..)+  , unwrapRecord+  )++import Prelude hiding (FilePath)++import Proto3.Suite.DotProto.AST +  ( DotProto (..)+  , DotProtoDefinition (..)+  , DotProtoEnumPart (..)+  , DotProtoEnumValue +  , DotProtoField (..)+  , DotProtoIdentifier (..)+  , DotProtoImport (..)+  , DotProtoMessagePart (..)+  , DotProtoOption (..)+  , DotProtoPackageSpec (..)+  , DotProtoServicePart (..)+  , DotProtoReservedField (..)+  , DotProtoType (..)+  , DotProtoValue (..)+  , Path (..)+  , RPCMethod (..)+  )+import Proto3.Suite.DotProto.Generate (readDotProtoWithContext)+import Proto3.Suite.DotProto.Internal (normalizeIntervals)+import Proto3.Suite.DotProto.Rendering (defRenderingOptions, toProtoFile)+import Proto3.Wire.Types (FieldNumber (..))++import Turtle (FilePath)++--------------------------------------------------------------------------------+ data Args w = Args   { includeDir :: w ::: [FilePath] <?> "Path to search for included .proto files (can be repeated, and paths will be searched in order; the current directory is used if this option is not provided)"   , proto      :: w ::: FilePath   <?> "Path to input .proto file"   } deriving Generic+ instance ParseRecord (Args Wrapped)+ deriving instance Show (Args Unwrapped)  main :: IO ()@@ -150,15 +184,10 @@     fmap getMin . foldMap (fmap Min . canonicalRank)  instance Canonicalize [DotProtoField] where-  canonicalize = canonicalSort . filter keep-    where-      keep DotProtoEmptyField = False-      keep _ = True+  canonicalize = canonicalSort  instance CanonicalRank DotProtoField (Maybe FieldNumber) where-  canonicalRank = \case-    DotProtoField{..} -> Just dotProtoFieldNumber-    DotProtoEmptyField -> Nothing+  canonicalRank DotProtoField{..} = Just dotProtoFieldNumber  instance Canonicalize DotProtoField where   canonicalize DotProtoField{..} = DotProtoField@@ -169,7 +198,6 @@     , dotProtoFieldComment = ""  -- In future we might add a command-line                                  -- option to preserve comments.     }-  canonicalize DotProtoEmptyField = DotProtoEmptyField  instance Canonicalize DotProtoType where canonicalize = id @@ -187,23 +215,20 @@       unique [n] = [n]       unique (x : xs@(y : _)) = (if x == y then id else (x :)) (unique xs) -      numbers = map reserveNumbers (toRangeList (fromRangeList rangeList))+      numbers = map reserveNumbers (normalizeIntervals rangeList)        reserveNumbers (lo, hi) | lo == hi = SingleField lo                               | otherwise = FieldRange lo hi  instance Canonicalize [DotProtoEnumPart] where-  canonicalize = canonicalSort . filter keep-    where-      keep DotProtoEnumEmpty = False-      keep _ = True+  canonicalize = canonicalSort  instance CanonicalRank DotProtoEnumPart                        (Either (Maybe DotProtoOption) DotProtoEnumValue) where   canonicalRank = \case     DotProtoEnumField _ value _ -> Right value     DotProtoEnumOption option -> Left (Just option)-    DotProtoEnumEmpty -> Left Nothing+    DotProtoEnumReserved _ -> Left Nothing  instance Canonicalize DotProtoEnumPart where   canonicalize = \case@@ -211,21 +236,17 @@       DotProtoEnumField (canonicalize name) value (map canonicalize opts)     DotProtoEnumOption option ->       DotProtoEnumOption (canonicalize option)-    DotProtoEnumEmpty ->-      DotProtoEnumEmpty+    DotProtoEnumReserved reservedFields ->+      DotProtoEnumReserved (canonicalize reservedFields)  instance Canonicalize [DotProtoServicePart] where-  canonicalize = canonicalSort . filter keep-    where-      keep DotProtoServiceEmpty = False-      keep _ = True+  canonicalize = canonicalSort  instance CanonicalRank DotProtoServicePart                        (Either (Maybe DotProtoOption) DotProtoIdentifier) where   canonicalRank = \case     DotProtoServiceRPCMethod method -> Right (rpcMethodName method)     DotProtoServiceOption option -> Left (Just option)-    DotProtoServiceEmpty -> Left Nothing  instance Canonicalize DotProtoServicePart where   canonicalize = \case@@ -233,8 +254,6 @@       DotProtoServiceRPCMethod (canonicalize guts)     DotProtoServiceOption option ->       DotProtoServiceOption (canonicalize option)-    DotProtoServiceEmpty ->-      DotProtoServiceEmpty  instance Canonicalize RPCMethod where   canonicalize (RPCMethod name reqN reqS rspN rspS options) =
tools/compile-proto-file/Main.hs view
@@ -11,11 +11,18 @@ import           Options.Applicative import           Prelude                        hiding (FilePath) import           Proto3.Suite.DotProto.Generate+import           Proto3.Suite.Haskell.Parser    (initLogger)  parseArgs :: ParserInfo CompileArgs parseArgs = info (helper <*> parser) (fullDesc <> progDesc "Compiles a .proto file to a Haskell module")   where-    parser = CompileArgs <$> includes <*> extraInstances <*> proto <*> out <*> stringType <*> recordStyle+    parser = CompileArgs+      <$> includes+      <*> extraInstances+      <*> proto+      <*> out+      <*> stringType+      <*> typeLevelFormat      includes = many $ strOption $       long "includeDir"@@ -38,14 +45,18 @@         <> help "Output directory path where generated Haskell modules will be written (directory is created if it does not exist; note that files in the output directory may be overwritten!)"      stringType = option (eitherReader parseStringType)-      $ long "string-type"+      $ long "stringType"+      <> long "string-type"       <> metavar "Data.Text.Lazy.Text"-      <> help "Haskell representation of strings"+      <> help "Haskell representation of strings (--stringType is the preferred spelling)"       <> value (StringType "Data.Text.Lazy" "Text") -    recordStyle = flag RegularRecords LargeRecords-      $ long "largeRecords"-      <> help "Use large-records library to optimize the core code size of generated records"+    typeLevelFormat = switch+      $ long "typeLevelFormat"+      <> help "Define formats at the type level (by instantiating type family FieldFormsOf)."  main :: IO ()-main = execParser parseArgs >>= compileDotProtoFileOrDie+main = do+  logger <- initLogger+  compileArgs <- execParser parseArgs+  compileDotProtoFileOrDie logger compileArgs