parseConfigMonoidJSON :: Object -> WarningParser ConfigMonoid
parseConfigMonoidJSON obj = do
    configMonoidWorkDir <- obj ..:? configMonoidWorkDirName
    configMonoidDockerOpts <- jsonSubWarnings (obj ..:? configMonoidDockerOptsName ..!= mempty)
    configMonoidNixOpts <- jsonSubWarnings (obj ..:? configMonoidNixOptsName ..!= mempty)
    configMonoidConnectionCount <- obj ..:? configMonoidConnectionCountName
    configMonoidHideTHLoading <- obj ..:? configMonoidHideTHLoadingName
    configMonoidLatestSnapshotUrl <- obj ..:? configMonoidLatestSnapshotUrlName
    configMonoidPackageIndices <- jsonSubWarningsTT (obj ..:?  configMonoidPackageIndicesName)
    configMonoidSystemGHC <- obj ..:? configMonoidSystemGHCName
    configMonoidInstallGHC <- obj ..:? configMonoidInstallGHCName
    configMonoidSkipGHCCheck <- obj ..:? configMonoidSkipGHCCheckName
    configMonoidSkipMsys <- obj ..:? configMonoidSkipMsysName
    configMonoidRequireStackVersion <- unVersionRangeJSON <$>
                                       obj ..:? configMonoidRequireStackVersionName
                                           ..!= VersionRangeJSON anyVersion
    configMonoidOS <- obj ..:? configMonoidOSName
    configMonoidArch <- obj ..:? configMonoidArchName
    configMonoidGHCVariant <- obj ..:? configMonoidGHCVariantName
    configMonoidJobs <- obj ..:? configMonoidJobsName
    configMonoidExtraIncludeDirs <- obj ..:?  configMonoidExtraIncludeDirsName ..!= Set.empty
    configMonoidExtraLibDirs <- obj ..:?  configMonoidExtraLibDirsName ..!= Set.empty
    configMonoidConcurrentTests <- obj ..:? configMonoidConcurrentTestsName
    configMonoidLocalBinPath <- obj ..:? configMonoidLocalBinPathName
    configMonoidImageOpts <- jsonSubWarnings (obj ..:?  configMonoidImageOptsName ..!= mempty)
    templates <- obj ..:? "templates"
    (configMonoidScmInit,configMonoidTemplateParameters) <-
      case templates of
        Nothing -> return (Nothing,M.empty)
        Just tobj -> do
          scmInit <- tobj ..:? configMonoidScmInitName
          params <- tobj ..:? configMonoidTemplateParametersName
          return (scmInit,fromMaybe M.empty params)
    configMonoidCompilerCheck <- obj ..:? configMonoidCompilerCheckName

    mghcoptions <- obj ..:? configMonoidGhcOptionsName
    configMonoidGhcOptions <-
        case mghcoptions of
            Nothing -> return mempty
            Just m -> fmap Map.fromList $ mapM handleGhcOptions $ Map.toList m

    extraPath <- obj ..:? configMonoidExtraPathName ..!= []
    configMonoidExtraPath <- forM extraPath $
        either (fail . show) return . parseAbsDir . T.unpack

    configMonoidSetupInfoLocations <-
        maybeToList <$> jsonSubWarningsT (obj ..:?  configMonoidSetupInfoLocationsName)
    configMonoidPvpBounds <- obj ..:? configMonoidPvpBoundsName
    configMonoidModifyCodePage <- obj ..:? configMonoidModifyCodePageName
    configMonoidExplicitSetupDeps <-
        (obj ..:? configMonoidExplicitSetupDepsName ..!= mempty)
        >>= fmap Map.fromList . mapM handleExplicitSetupDep . Map.toList
    configMonoidRebuildGhcOptions <- obj ..:? configMonoidRebuildGhcOptionsName
    configMonoidApplyGhcOptions <- obj ..:? configMonoidApplyGhcOptionsName
    configMonoidAllowNewer <- obj ..:? configMonoidAllowNewerName

    return ConfigMonoid {..}
  where
    handleGhcOptions :: Monad m => (Text, Text) -> m (Maybe PackageName, [Text])
    handleGhcOptions (name', vals') = do
        name <-
            if name' == "*"
                then return Nothing
                else case parsePackageNameFromString $ T.unpack name' of
                        Left e -> fail $ show e
                        Right x -> return $ Just x

        case parseArgs Escaping vals' of
            Left e -> fail e
            Right vals -> return (name, map T.pack vals)

    handleExplicitSetupDep :: Monad m => (Text, Bool) -> m (Maybe PackageName, Bool)
    handleExplicitSetupDep (name', b) = do
        name <-
            if name' == "*"
                then return Nothing
                else case parsePackageNameFromString $ T.unpack name' of
                        Left e -> fail $ show e
                        Right x -> return $ Just x
        return (name, b)
parseConfigMonoidJSON :: Object -> WarningParser ConfigMonoid
parseConfigMonoidJSON obj = do
    configMonoidWorkDir <- obj ..:? configMonoidWorkDirName
    configMonoidDockerOpts <- jsonSubWarnings (obj ..:? configMonoidDockerOptsName ..!= mempty)
    configMonoidNixOpts <- jsonSubWarnings (obj ..:? configMonoidNixOptsName ..!= mempty)
    configMonoidConnectionCount <- obj ..:? configMonoidConnectionCountName
    configMonoidHideTHLoading <- obj ..:? configMonoidHideTHLoadingName
    configMonoidLatestSnapshotUrl <- obj ..:? configMonoidLatestSnapshotUrlName
    configMonoidPackageIndices <- jsonSubWarningsTT (obj ..:?  configMonoidPackageIndicesName)
    configMonoidSystemGHC <- obj ..:? configMonoidSystemGHCName
    configMonoidInstallGHC <- obj ..:? configMonoidInstallGHCName
    configMonoidSkipGHCCheck <- obj ..:? configMonoidSkipGHCCheckName
    configMonoidSkipMsys <- obj ..:? configMonoidSkipMsysName
    configMonoidRequireStackVersion <- unVersionRangeJSON <$>
                                       obj ..:? configMonoidRequireStackVersionName
                                           ..!= VersionRangeJSON anyVersion
    configMonoidOS <- obj ..:? configMonoidOSName
    configMonoidArch <- obj ..:? configMonoidArchName
    configMonoidGHCVariant <- obj ..:? configMonoidGHCVariantName
    configMonoidJobs <- obj ..:? configMonoidJobsName
    configMonoidExtraIncludeDirs <- obj ..:?  configMonoidExtraIncludeDirsName ..!= Set.empty
    configMonoidExtraLibDirs <- obj ..:?  configMonoidExtraLibDirsName ..!= Set.empty
    configMonoidConcurrentTests <- obj ..:? configMonoidConcurrentTestsName
    configMonoidLocalBinPath <- obj ..:? configMonoidLocalBinPathName
    configMonoidImageOpts <- jsonSubWarnings (obj ..:?  configMonoidImageOptsName ..!= mempty)
    templates <- obj ..:? "templates"
    (configMonoidScmInit,configMonoidTemplateParameters) <-
      case templates of
        Nothing -> return (Nothing,M.empty)
        Just tobj -> do
          scmInit <- tobj ..:? configMonoidScmInitName
          params <- tobj ..:? configMonoidTemplateParametersName
          return (scmInit,fromMaybe M.empty params)
    configMonoidCompilerCheck <- obj ..:? configMonoidCompilerCheckName

    mghcoptions <- obj ..:? configMonoidGhcOptionsName
    configMonoidGhcOptions <-
        case mghcoptions of
            Nothing -> return mempty
            Just m -> fmap Map.fromList $ mapM handleGhcOptions $ Map.toList m

    extraPath <- obj ..:? configMonoidExtraPathName ..!= []
    configMonoidExtraPath <- forM extraPath $
        either (fail . show) return . parseAbsDir . T.unpack

    configMonoidSetupInfoLocations <-
        maybeToList <$> jsonSubWarningsT (obj ..:?  configMonoidSetupInfoLocationsName)
    configMonoidPvpBounds <- obj ..:? configMonoidPvpBoundsName
    configMonoidModifyCodePage <- obj ..:? configMonoidModifyCodePageName
    configMonoidExplicitSetupDeps <-
        (obj ..:? configMonoidExplicitSetupDepsName ..!= mempty)
        >>= fmap Map.fromList . mapM handleExplicitSetupDep . Map.toList
    configMonoidRebuildGhcOptions <- obj ..:? configMonoidRebuildGhcOptionsName
    configMonoidApplyGhcOptions <- obj ..:? configMonoidApplyGhcOptionsName
    configMonoidAllowNewer <- obj ..:? configMonoidAllowNewerName

    return ConfigMonoid {..}
  where
    handleGhcOptions :: Monad m => (Text, Text) -> m (Maybe PackageName, [Text])
    handleGhcOptions (name', vals') = do
        name <-
            if name' == "*"
                then return Nothing
                else case parsePackageNameFromString $ T.unpack name' of
                        Left e -> fail $ show e
                        Right x -> return $ Just x

        case parseArgs Escaping vals' of
            Left e -> fail e
            Right vals -> return (name, map T.pack vals)

    handleExplicitSetupDep :: Monad m => (Text, Bool) -> m (Maybe PackageName, Bool)
    handleExplicitSetupDep (name', b) = do
        name <-
            if name' == "*"
                then return Nothing
                else case parsePackageNameFromString $ T.unpack name' of
                        Left e -> fail $ show e
                        Right x -> return $ Just x
        return (name, b)
parseConfigMonoidJSON obj = do
    configMonoidWorkDir <- obj ..:? configMonoidWorkDirName
    configMonoidDockerOpts <- jsonSubWarnings (obj ..:? configMonoidDockerOptsName ..!= mempty)
    configMonoidNixOpts <- jsonSubWarnings (obj ..:? configMonoidNixOptsName ..!= mempty)
    configMonoidConnectionCount <- obj ..:? configMonoidConnectionCountName
    configMonoidHideTHLoading <- obj ..:? configMonoidHideTHLoadingName
    configMonoidLatestSnapshotUrl <- obj ..:? configMonoidLatestSnapshotUrlName
    configMonoidPackageIndices <- jsonSubWarningsTT (obj ..:?  configMonoidPackageIndicesName)
    configMonoidSystemGHC <- obj ..:? configMonoidSystemGHCName
    configMonoidInstallGHC <- obj ..:? configMonoidInstallGHCName
    configMonoidSkipGHCCheck <- obj ..:? configMonoidSkipGHCCheckName
    configMonoidSkipMsys <- obj ..:? configMonoidSkipMsysName
    configMonoidRequireStackVersion <- unVersionRangeJSON <$>
                                       obj ..:? configMonoidRequireStackVersionName
                                           ..!= VersionRangeJSON anyVersion
    configMonoidOS <- obj ..:? configMonoidOSName
    configMonoidArch <- obj ..:? configMonoidArchName
    configMonoidGHCVariant <- obj ..:? configMonoidGHCVariantName
    configMonoidJobs <- obj ..:? configMonoidJobsName
    configMonoidExtraIncludeDirs <- obj ..:?  configMonoidExtraIncludeDirsName ..!= Set.empty
    configMonoidExtraLibDirs <- obj ..:?  configMonoidExtraLibDirsName ..!= Set.empty
    configMonoidConcurrentTests <- obj ..:? configMonoidConcurrentTestsName
    configMonoidLocalBinPath <- obj ..:? configMonoidLocalBinPathName
    configMonoidImageOpts <- jsonSubWarnings (obj ..:?  configMonoidImageOptsName ..!= mempty)
    templates <- obj ..:? "templates"
    (configMonoidScmInit,configMonoidTemplateParameters) <-
      case templates of
        Nothing -> return (Nothing,M.empty)
        Just tobj -> do
          scmInit <- tobj ..:? configMonoidScmInitName
          params <- tobj ..:? configMonoidTemplateParametersName
          return (scmInit,fromMaybe M.empty params)
    configMonoidCompilerCheck <- obj ..:? configMonoidCompilerCheckName

    mghcoptions <- obj ..:? configMonoidGhcOptionsName
    configMonoidGhcOptions <-
        case mghcoptions of
            Nothing -> return mempty
            Just m -> fmap Map.fromList $ mapM handleGhcOptions $ Map.toList m

    extraPath <- obj ..:? configMonoidExtraPathName ..!= []
    configMonoidExtraPath <- forM extraPath $
        either (fail . show) return . parseAbsDir . T.unpack

    configMonoidSetupInfoLocations <-
        maybeToList <$> jsonSubWarningsT (obj ..:?  configMonoidSetupInfoLocationsName)
    configMonoidPvpBounds <- obj ..:? configMonoidPvpBoundsName
    configMonoidModifyCodePage <- obj ..:? configMonoidModifyCodePageName
    configMonoidExplicitSetupDeps <-
        (obj ..:? configMonoidExplicitSetupDepsName ..!= mempty)
        >>= fmap Map.fromList . mapM handleExplicitSetupDep . Map.toList
    configMonoidRebuildGhcOptions <- obj ..:? configMonoidRebuildGhcOptionsName
    configMonoidApplyGhcOptions <- obj ..:? configMonoidApplyGhcOptionsName
    configMonoidAllowNewer <- obj ..:? configMonoidAllowNewerName

    return ConfigMonoid {..}
  where
    handleGhcOptions :: Monad m => (Text, Text) -> m (Maybe PackageName, [Text])
    handleGhcOptions (name', vals') = do
        name <-
            if name' == "*"
                then return Nothing
                else case parsePackageNameFromString $ T.unpack name' of
                        Left e -> fail $ show e
                        Right x -> return $ Just x

        case parseArgs Escaping vals' of
            Left e -> fail e
            Right vals -> return (name, map T.pack vals)

    handleExplicitSetupDep :: Monad m => (Text, Bool) -> m (Maybe PackageName, Bool)
    handleExplicitSetupDep (name', b) = do
        name <-
            if name' == "*"
                then return Nothing
                else case parsePackageNameFromString $ T.unpack name' of
                        Left e -> fail $ show e
                        Right x -> return $ Just x
        return (name, b)