chromium/chrome/browser/web_applications/isolated_web_apps/isolated_web_app_source.h

// Copyright 2024 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_SOURCE_H_
#define CHROME_BROWSER_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_SOURCE_H_

#include <iosfwd>
#include <type_traits>

#include "base/files/file_path.h"
#include "base/types/expected.h"
#include "base/values.h"
#include "chrome/browser/web_applications/isolated_web_apps/isolated_web_app_storage_location.h"
#include "third_party/abseil-cpp/absl/types/variant.h"
#include "url/origin.h"

namespace web_app {

// The classes defined in this file represent the source of an Isolated Web App.
// There are two kinds of sources: Bundle-based sources and proxy-based sources.
// These classes allow code that only deals with bundles, only deals with
// proxies, only deals with dev mode apps, etc., to be written in a type-safe
// way without having to resort to `CHECK`s or error handling for unsupported
// types of sources.
//
// Note: Not all of these forward declarations are technically required, but
// they make it easier to get an overview of the available classes.

// A source representing either a bundle or a proxy.
class IwaSource;

// A source representing either a bundle or a proxy, with additional information
// about whether the source is a dev mode or prod mode source.
class IwaSourceWithMode;
class IwaSourceDevMode;
class IwaSourceProdMode;  // can never be a proxy

// A source representing either a bundle or a proxy, with additional information
// about whether the source is a dev mode or prod mode source, as well as
// information about a file operation for bundle-based sources. The available
// file operations differ depending on whether it is a dev mode or prod mode
// source.
class IwaSourceWithModeAndFileOp;
class IwaSourceDevModeWithFileOp;
class IwaSourceProdModeWithFileOp;  // can never be a proxy

// Bundle-based sources:
class IwaSourceBundle;
class IwaSourceBundleWithMode;
class IwaSourceBundleDevMode;
class IwaSourceBundleProdMode;
class IwaSourceBundleWithModeAndFileOp;
class IwaSourceBundleDevModeWithFileOp;
class IwaSourceBundleProdModeWithFileOp;

// Proxy-based sources (there is just a single class here, because proxies are
// always dev mode and do not have a file operation):
class IwaSourceProxy;

class IwaSourceProxy {};
std::ostream& operator<<(std::ostream& os, const IwaSourceProxy& source);

enum class IwaSourceBundleModeAndFileOp {};
std::ostream& operator<<(std::ostream& os,
                         IwaSourceBundleModeAndFileOp bundle_mode_and_file_op);

enum class IwaSourceBundleDevFileOp {};
std::ostream& operator<<(std::ostream& os, IwaSourceBundleDevFileOp file_op);

enum class IwaSourceBundleProdFileOp {};
std::ostream& operator<<(std::ostream& os, IwaSourceBundleProdFileOp file_op);

// TODO(crbug.com/40286084): Currently, we do not copy/move bundles installed in
// dev mode (via CLI or dev mode UI) into the profile directory, but instead
// just reference them. This is because, ideally, we'd like the browser to use
// an updated bundle as soon as the user generates a new bundle. However, our
// bundle reading code is currently not able to deal with bundles that mutate
// while the browser is running, which causes the bundle reading code to produce
// garbage when the bundle is modified. We could either fix the bundle reading
// code for unowned dev-mode bundles, or change this to move/copy the bundle
// instead.
inline constexpr IwaSourceBundleDevFileOp kDefaultBundleDevFileOp =;

namespace internal {

class IwaSourceBundleBase {};

}  // namespace internal

class IwaSourceBundle : public internal::IwaSourceBundleBase {};
std::ostream& operator<<(std::ostream& os, const IwaSourceBundle& source);

class IwaSourceBundleWithMode : public internal::IwaSourceBundleBase {};
std::ostream& operator<<(std::ostream& os,
                         const IwaSourceBundleWithMode& source);

class IwaSourceBundleDevMode : public internal::IwaSourceBundleBase {};
std::ostream& operator<<(std::ostream& os,
                         const IwaSourceBundleDevMode& source);

class IwaSourceBundleProdMode : public internal::IwaSourceBundleBase {};
std::ostream& operator<<(std::ostream& os,
                         const IwaSourceBundleProdMode& source);

class IwaSourceBundleWithModeAndFileOp : public internal::IwaSourceBundleBase {};
std::ostream& operator<<(std::ostream& os,
                         const IwaSourceBundleWithModeAndFileOp& source);

class IwaSourceBundleDevModeWithFileOp : public IwaSourceBundleDevMode {};
std::ostream& operator<<(std::ostream& os,
                         const IwaSourceBundleDevModeWithFileOp& source);

class IwaSourceBundleProdModeWithFileOp : public IwaSourceBundleProdMode {};
std::ostream& operator<<(std::ostream& os,
                         const IwaSourceBundleProdModeWithFileOp& source);

class IwaSource {};
std::ostream& operator<<(std::ostream& os, const IwaSource& source);

class IwaSourceWithMode {};
std::ostream& operator<<(std::ostream& os, const IwaSourceWithMode& source);

class IwaSourceDevMode {};
std::ostream& operator<<(std::ostream& os, const IwaSourceDevMode& source);

class IwaSourceProdMode {};
std::ostream& operator<<(std::ostream& os, const IwaSourceProdMode& source);

class IwaSourceWithModeAndFileOp {};
std::ostream& operator<<(std::ostream& os,
                         const IwaSourceWithModeAndFileOp& source);

class IwaSourceDevModeWithFileOp {};
std::ostream& operator<<(std::ostream& os,
                         const IwaSourceDevModeWithFileOp& source);

class IwaSourceProdModeWithFileOp {};
std::ostream& operator<<(std::ostream& os,
                         const IwaSourceProdModeWithFileOp& source);

}  // namespace web_app

#endif  // CHROME_BROWSER_WEB_APPLICATIONS_ISOLATED_WEB_APPS_ISOLATED_WEB_APP_SOURCE_H_