    {- |
    Copyright  : Will Thompson, Iñaki García Etxebarria and Jonas Platte
    License    : LGPL-2.1
    Maintainer : Iñaki García Etxebarria (garetxe@gmail.com)

    A utility type for constructing container-type 'GVariant' instances.

    This is an opaque structure and may only be accessed using the
    following functions.

    'GI.GLib.Structs.VariantBuilder.VariantBuilder' is not threadsafe in any way.  Do not attempt to
    access it from more than one thread.
    -}

    #define ENABLE_OVERLOADING \
           (!defined(__HADDOCK_VERSION__))

    module GI.GLib.Structs.VariantBuilder
        (

    -- * Exported types
        VariantBuilder(..)                      ,
        noVariantBuilder                        ,

     -- * Methods
    -- ** addValue #method:addValue#

    #if ENABLE_OVERLOADING
        VariantBuilderAddValueMethodInfo        ,
    #endif
        variantBuilderAddValue                  ,

    -- ** close #method:close#

    #if ENABLE_OVERLOADING
        VariantBuilderCloseMethodInfo           ,
    #endif
        variantBuilderClose                     ,

    -- ** end #method:end#

    #if ENABLE_OVERLOADING
        VariantBuilderEndMethodInfo             ,
    #endif
        variantBuilderEnd                       ,

    -- ** new #method:new#

        variantBuilderNew                       ,

    -- ** open #method:open#

    #if ENABLE_OVERLOADING
        VariantBuilderOpenMethodInfo            ,
    #endif
        variantBuilderOpen                      ,

    -- ** ref #method:ref#

    #if ENABLE_OVERLOADING
        VariantBuilderRefMethodInfo             ,
    #endif
        variantBuilderRef                       ,

    -- ** unref #method:unref#

    #if ENABLE_OVERLOADING
        VariantBuilderUnrefMethodInfo           ,
    #endif
        variantBuilderUnref                     ,

        ) where

    import Data.GI.Base.ShortPrelude
    import qualified Data.GI.Base.ShortPrelude as SP
    import qualified Data.GI.Base.Overloading as O
    import qualified Prelude as P

    import qualified Data.GI.Base.Attributes as GI.Attributes
    import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
    import qualified Data.GI.Base.GError as B.GError
    import qualified Data.GI.Base.GVariant as B.GVariant
    import qualified Data.GI.Base.GValue as B.GValue
    import qualified Data.GI.Base.GParamSpec as B.GParamSpec
    import qualified Data.GI.Base.CallStack as B.CallStack
    import qualified Data.Text as T
    import qualified Data.ByteString.Char8 as B
    import qualified Data.Map as Map
    import qualified Foreign.Ptr as FP

    import {-# SOURCE #-} qualified GI.GLib.Structs.VariantType as GLib.VariantType

    -- | Memory-managed wrapper type.
    newtype VariantBuilder = VariantBuilder (ManagedPtr VariantBuilder)
    foreign import ccall "g_variant_builder_get_type" c_g_variant_builder_get_type ::
        IO GType

    instance BoxedObject VariantBuilder where
        boxedType _ = c_g_variant_builder_get_type

    -- | A convenience alias for `Nothing` :: `Maybe` `VariantBuilder`.
    noVariantBuilder :: Maybe VariantBuilder
    noVariantBuilder = Nothing

    #if ENABLE_OVERLOADING
    instance O.HasAttributeList VariantBuilder
    type instance O.AttributeList VariantBuilder = VariantBuilderAttributeList
    type VariantBuilderAttributeList = ('[ ] :: [(Symbol, *)])
    #endif

    -- method VariantBuilder::new
    -- method type : Constructor
    -- Args : [Arg {argCName = "type", argType = TInterface (Name {namespace = "GLib", name = "VariantType"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a container type", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "GLib", name = "VariantBuilder"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_variant_builder_new" g_variant_builder_new ::
        Ptr GLib.VariantType.VariantType ->     -- type : TInterface (Name {namespace = "GLib", name = "VariantType"})
        IO (Ptr VariantBuilder)

    {- |
    Allocates and initialises a new 'GI.GLib.Structs.VariantBuilder.VariantBuilder'.

    You should call 'GI.GLib.Structs.VariantBuilder.variantBuilderUnref' on the return value when it
    is no longer needed.  The memory will not be automatically freed by
    any other call.

    In most cases it is easier to place a 'GI.GLib.Structs.VariantBuilder.VariantBuilder' directly on
    the stack of the calling function and initialise it with
    @/g_variant_builder_init()/@.

    /Since: 2.24/
    -}
    variantBuilderNew ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        GLib.VariantType.VariantType
        {- ^ /@type@/: a container type -}
        -> m VariantBuilder
        {- ^ __Returns:__ a 'GI.GLib.Structs.VariantBuilder.VariantBuilder' -}
    variantBuilderNew type_ = liftIO $ do
        type_' <- unsafeManagedPtrGetPtr type_
        result <- g_variant_builder_new type_'
        checkUnexpectedReturnNULL "variantBuilderNew" result
        result' <- (wrapBoxed VariantBuilder) result
        touchManagedPtr type_
        return result'

    #if ENABLE_OVERLOADING
    #endif

    -- method VariantBuilder::add_value
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "GLib", name = "VariantBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GVariantBuilder", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "value", argType = TVariant, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GVariant", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_variant_builder_add_value" g_variant_builder_add_value ::
        Ptr VariantBuilder ->                   -- builder : TInterface (Name {namespace = "GLib", name = "VariantBuilder"})
        Ptr GVariant ->                         -- value : TVariant
        IO ()

    {- |
    Adds /@value@/ to /@builder@/.

    It is an error to call this function in any way that would create an
    inconsistent value to be constructed.  Some examples of this are
    putting different types of items into an array, putting the wrong
    types or number of items in a tuple, putting more than one value into
    a variant, etc.

    If /@value@/ is a floating reference (see 'GI.GLib.Structs.Variant.variantRefSink'),
    the /@builder@/ instance takes ownership of /@value@/.

    /Since: 2.24/
    -}
    variantBuilderAddValue ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        VariantBuilder
        {- ^ /@builder@/: a 'GI.GLib.Structs.VariantBuilder.VariantBuilder' -}
        -> GVariant
        {- ^ /@value@/: a 'GVariant' -}
        -> m ()
    variantBuilderAddValue builder value = liftIO $ do
        builder' <- unsafeManagedPtrGetPtr builder
        value' <- unsafeManagedPtrGetPtr value
        g_variant_builder_add_value builder' value'
        touchManagedPtr builder
        touchManagedPtr value
        return ()

    #if ENABLE_OVERLOADING
    data VariantBuilderAddValueMethodInfo
    instance (signature ~ (GVariant -> m ()), MonadIO m) => O.MethodInfo VariantBuilderAddValueMethodInfo VariantBuilder signature where
        overloadedMethod _ = variantBuilderAddValue

    #endif

    -- method VariantBuilder::close
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "GLib", name = "VariantBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GVariantBuilder", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_variant_builder_close" g_variant_builder_close ::
        Ptr VariantBuilder ->                   -- builder : TInterface (Name {namespace = "GLib", name = "VariantBuilder"})
        IO ()

    {- |
    Closes the subcontainer inside the given /@builder@/ that was opened by
    the most recent call to 'GI.GLib.Structs.VariantBuilder.variantBuilderOpen'.

    It is an error to call this function in any way that would create an
    inconsistent value to be constructed (ie: too few values added to the
    subcontainer).

    /Since: 2.24/
    -}
    variantBuilderClose ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        VariantBuilder
        {- ^ /@builder@/: a 'GI.GLib.Structs.VariantBuilder.VariantBuilder' -}
        -> m ()
    variantBuilderClose builder = liftIO $ do
        builder' <- unsafeManagedPtrGetPtr builder
        g_variant_builder_close builder'
        touchManagedPtr builder
        return ()

    #if ENABLE_OVERLOADING
    data VariantBuilderCloseMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo VariantBuilderCloseMethodInfo VariantBuilder signature where
        overloadedMethod _ = variantBuilderClose

    #endif

    -- method VariantBuilder::end
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "GLib", name = "VariantBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GVariantBuilder", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just TVariant
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_variant_builder_end" g_variant_builder_end ::
        Ptr VariantBuilder ->                   -- builder : TInterface (Name {namespace = "GLib", name = "VariantBuilder"})
        IO (Ptr GVariant)

    {- |
    Ends the builder process and returns the constructed value.

    It is not permissible to use /@builder@/ in any way after this call
    except for reference counting operations (in the case of a
    heap-allocated 'GI.GLib.Structs.VariantBuilder.VariantBuilder') or by reinitialising it with
    @/g_variant_builder_init()/@ (in the case of stack-allocated). This
    means that for the stack-allocated builders there is no need to
    call @/g_variant_builder_clear()/@ after the call to
    'GI.GLib.Structs.VariantBuilder.variantBuilderEnd'.

    It is an error to call this function in any way that would create an
    inconsistent value to be constructed (ie: insufficient number of
    items added to a container with a specific number of children
    required).  It is also an error to call this function if the builder
    was created with an indefinite array or maybe type and no children
    have been added; in this case it is impossible to infer the type of
    the empty array.

    /Since: 2.24/
    -}
    variantBuilderEnd ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        VariantBuilder
        {- ^ /@builder@/: a 'GI.GLib.Structs.VariantBuilder.VariantBuilder' -}
        -> m GVariant
        {- ^ __Returns:__ a new, floating, 'GVariant' -}
    variantBuilderEnd builder = liftIO $ do
        builder' <- unsafeManagedPtrGetPtr builder
        result <- g_variant_builder_end builder'
        checkUnexpectedReturnNULL "variantBuilderEnd" result
        result' <- B.GVariant.newGVariantFromPtr result
        touchManagedPtr builder
        return result'

    #if ENABLE_OVERLOADING
    data VariantBuilderEndMethodInfo
    instance (signature ~ (m GVariant), MonadIO m) => O.MethodInfo VariantBuilderEndMethodInfo VariantBuilder signature where
        overloadedMethod _ = variantBuilderEnd

    #endif

    -- method VariantBuilder::open
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "GLib", name = "VariantBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GVariantBuilder", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "type", argType = TInterface (Name {namespace = "GLib", name = "VariantType"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the #GVariantType of the container", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_variant_builder_open" g_variant_builder_open ::
        Ptr VariantBuilder ->                   -- builder : TInterface (Name {namespace = "GLib", name = "VariantBuilder"})
        Ptr GLib.VariantType.VariantType ->     -- type : TInterface (Name {namespace = "GLib", name = "VariantType"})
        IO ()

    {- |
    Opens a subcontainer inside the given /@builder@/.  When done adding
    items to the subcontainer, 'GI.GLib.Structs.VariantBuilder.variantBuilderClose' must be called. /@type@/
    is the type of the container: so to build a tuple of several values, /@type@/
    must include the tuple itself.

    It is an error to call this function in any way that would cause an
    inconsistent value to be constructed (ie: adding too many values or
    a value of an incorrect type).

    Example of building a nested variant:

    === /C code/
    >
    >GVariantBuilder builder;
    >guint32 some_number = get_number ();
    >g_autoptr (GHashTable) some_dict = get_dict ();
    >GHashTableIter iter;
    >const gchar *key;
    >const GVariant *value;
    >g_autoptr (GVariant) output = NULL;
    >
    >g_variant_builder_init (&builder, G_VARIANT_TYPE ("(ua{sv})"));
    >g_variant_builder_add (&builder, "u", some_number);
    >g_variant_builder_open (&builder, G_VARIANT_TYPE ("a{sv}"));
    >
    >g_hash_table_iter_init (&iter, some_dict);
    >while (g_hash_table_iter_next (&iter, (gpointer *) &key, (gpointer *) &value))
    >  {
    >    g_variant_builder_open (&builder, G_VARIANT_TYPE ("{sv}"));
    >    g_variant_builder_add (&builder, "s", key);
    >    g_variant_builder_add (&builder, "v", value);
    >    g_variant_builder_close (&builder);
    >  }
    >
    >g_variant_builder_close (&builder);
    >
    >output = g_variant_builder_end (&builder);

    /Since: 2.24/
    -}
    variantBuilderOpen ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        VariantBuilder
        {- ^ /@builder@/: a 'GI.GLib.Structs.VariantBuilder.VariantBuilder' -}
        -> GLib.VariantType.VariantType
        {- ^ /@type@/: the 'GI.GLib.Structs.VariantType.VariantType' of the container -}
        -> m ()
    variantBuilderOpen builder type_ = liftIO $ do
        builder' <- unsafeManagedPtrGetPtr builder
        type_' <- unsafeManagedPtrGetPtr type_
        g_variant_builder_open builder' type_'
        touchManagedPtr builder
        touchManagedPtr type_
        return ()

    #if ENABLE_OVERLOADING
    data VariantBuilderOpenMethodInfo
    instance (signature ~ (GLib.VariantType.VariantType -> m ()), MonadIO m) => O.MethodInfo VariantBuilderOpenMethodInfo VariantBuilder signature where
        overloadedMethod _ = variantBuilderOpen

    #endif

    -- method VariantBuilder::ref
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "GLib", name = "VariantBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GVariantBuilder allocated by g_variant_builder_new()", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
    -- Lengths : []
    -- returnType : Just (TInterface (Name {namespace = "GLib", name = "VariantBuilder"}))
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_variant_builder_ref" g_variant_builder_ref ::
        Ptr VariantBuilder ->                   -- builder : TInterface (Name {namespace = "GLib", name = "VariantBuilder"})
        IO (Ptr VariantBuilder)

    {- |
    Increases the reference count on /@builder@/.

    Don\'t call this on stack-allocated 'GI.GLib.Structs.VariantBuilder.VariantBuilder' instances or bad
    things will happen.

    /Since: 2.24/
    -}
    variantBuilderRef ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        VariantBuilder
        {- ^ /@builder@/: a 'GI.GLib.Structs.VariantBuilder.VariantBuilder' allocated by 'GI.GLib.Structs.VariantBuilder.variantBuilderNew' -}
        -> m VariantBuilder
        {- ^ __Returns:__ a new reference to /@builder@/ -}
    variantBuilderRef builder = liftIO $ do
        builder' <- unsafeManagedPtrGetPtr builder
        result <- g_variant_builder_ref builder'
        checkUnexpectedReturnNULL "variantBuilderRef" result
        result' <- (wrapBoxed VariantBuilder) result
        touchManagedPtr builder
        return result'

    #if ENABLE_OVERLOADING
    data VariantBuilderRefMethodInfo
    instance (signature ~ (m VariantBuilder), MonadIO m) => O.MethodInfo VariantBuilderRefMethodInfo VariantBuilder signature where
        overloadedMethod _ = variantBuilderRef

    #endif

    -- method VariantBuilder::unref
    -- method type : OrdinaryMethod
    -- Args : [Arg {argCName = "builder", argType = TInterface (Name {namespace = "GLib", name = "VariantBuilder"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GVariantBuilder allocated by g_variant_builder_new()", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferEverything}]
    -- Lengths : []
    -- returnType : Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_variant_builder_unref" g_variant_builder_unref ::
        Ptr VariantBuilder ->                   -- builder : TInterface (Name {namespace = "GLib", name = "VariantBuilder"})
        IO ()

    {- |
    Decreases the reference count on /@builder@/.

    In the event that there are no more references, releases all memory
    associated with the 'GI.GLib.Structs.VariantBuilder.VariantBuilder'.

    Don\'t call this on stack-allocated 'GI.GLib.Structs.VariantBuilder.VariantBuilder' instances or bad
    things will happen.

    /Since: 2.24/
    -}
    variantBuilderUnref ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        VariantBuilder
        {- ^ /@builder@/: a 'GI.GLib.Structs.VariantBuilder.VariantBuilder' allocated by 'GI.GLib.Structs.VariantBuilder.variantBuilderNew' -}
        -> m ()
    variantBuilderUnref builder = liftIO $ do
        builder' <- B.ManagedPtr.disownBoxed builder
        g_variant_builder_unref builder'
        touchManagedPtr builder
        return ()

    #if ENABLE_OVERLOADING
    data VariantBuilderUnrefMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.MethodInfo VariantBuilderUnrefMethodInfo VariantBuilder signature where
        overloadedMethod _ = variantBuilderUnref

    #endif

    #if ENABLE_OVERLOADING
    type family ResolveVariantBuilderMethod (t :: Symbol) (o :: *) :: * where
        ResolveVariantBuilderMethod "addValue" o = VariantBuilderAddValueMethodInfo
        ResolveVariantBuilderMethod "close" o = VariantBuilderCloseMethodInfo
        ResolveVariantBuilderMethod "end" o = VariantBuilderEndMethodInfo
        ResolveVariantBuilderMethod "open" o = VariantBuilderOpenMethodInfo
        ResolveVariantBuilderMethod "ref" o = VariantBuilderRefMethodInfo
        ResolveVariantBuilderMethod "unref" o = VariantBuilderUnrefMethodInfo
        ResolveVariantBuilderMethod l o = O.MethodResolutionFailed l o

    instance (info ~ ResolveVariantBuilderMethod t VariantBuilder, O.MethodInfo info VariantBuilder p) => O.IsLabelProxy t (VariantBuilder -> p) where
        fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)

    #if MIN_VERSION_base(4,9,0)
    instance (info ~ ResolveVariantBuilderMethod t VariantBuilder, O.MethodInfo info VariantBuilder p) => O.IsLabel t (VariantBuilder -> p) where
    #if MIN_VERSION_base(4,10,0)
        fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
    #else
        fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
    #endif
    #endif

    #endif