/*
 * Boston, MA 02110-1301, USA.
 */
// There are other form of function, but I just illustrate them in the class below.
// `freeFunction()`
func freeFunction() {
}
// May also be `struct`, `enum`, `extension`, or `protocol`.
class MyClass {
    // `MyClass.function()`
    func function() {
        // Local variables need not be given ChangeLog entries. This should not generate one.
        var local: Local {
        }
    }
    // By default the first argument to functions is unnamed, so in Swift you'd call this
    // as functionWithArgument(foo).
    //
    // `MyClass.functionWithArgument(_:)`
    func functionWithArgument(arg: Arg) {
    }
    // Second arguments do get a name.
    //
    // `MyClass.functionWithMoreArguments(_:arg2:)
    func functionWithMoreArguments(arg1: Arg, arg2: Arg) {
    }
    // You can give the first argument a name by specifying an explicit external name.
    // This would be called as functionWithNamedFirstArgument(argument: 1)
    //
    // `MyClass.functionWithNamedFirstArgument(argument:)`
    func functionWithNamedFirstArgument(argument arg: Arg) {
    }
    // You can also give a different external name to other arguments as so.
    //
    // `MyClass.functionWithNamedFirstAndSecondArgument(first:second:)`
    func functionWithNamedFirstAndSecondArgument(first arg1: Arg, second arg2: Arg) {
    }
    // Now for some things I don't know how to specify but can give random suggestions for…
    // I've not seen clever ways of differentiating class functions from instance functions :(
    //
    // `MyClass.classFunction()`
    class func classFunction() {
    }
    // These map to what would be -computedVariable and -setComputedVariable: in Objective-C.
    // To make things fun computed variables can also exist outside of a class definition, so
    // I think they should still be prefixed.
    var readWriteComputedVariable: Var {
        // `MyClass.readWriteComputedVariable { get }`
        get { return 0 }
        // `MyClass.readWriteComputedVariable { set }`
        set { print(newValue) }
    }
    // `MyClass.readOnlyComputedVariable { get }`
    var readOnlyComputedVariable: Var {
        return 0
    }
}
struct MyStruct {
    // `MyStruct.structFunction(argument:)`
    func structFunction(argument arg: Arg) {
    }
}
enum MyEnum {
    case a, b, c
    // `MyEnum.enumFunction(argument:)`
    func enumFunction(argument arg: Arg) {
    }
}
protocol MyProtocol {
    // `MyProtocol.protocolFunction(argument:)`
    func protocolFunction(argument arg: Arg) {
    }
}
extension ExtendedType {
    // `ExtendedType.extensionFunction(argument:)`
    func extensionFunction(argument arg: Arg) {
    }
}
// Swift functions also support type overloading. Traditionally we don't include types in
// the ChangeLogs for Objective-C, but I assume this can come up in C++ code so I'd suggest
// doing whatever we do there. That said, overloading is only supported in pure Swift,
// which I don't anticipate needing to worry about for a while longer.


ContentView

/*
 */
import SwiftUI
struct ContentView: View {
    var body: some View {
        WebGPUView().padding()
    }
}
struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}


WebGPUView+AppKit

/*
 */
import SwiftUI
import Foundation
import MetalKit
#if os(macOS)
struct WebGPUView: NSViewRepresentable {
    typealias NSViewType = MTKView
    typealias Coordinator = WebGPUCoordinator
    func makeNSView(context: Context) -> MTKView {
        let mtkView = MTKView()
        context.coordinator.setView(mtkView)
        mtkView.delegate = context.coordinator
        return mtkView
    }

    func updateNSView(_ nsView: MTKView, context: Context) {
    }
    func makeCoordinator() -> WebGPUCoordinator {
        return WebGPUCoordinator()
    }
}
#endif


AppPlaygroundApp

/*
 */
import SwiftUI
struct AppPlaygroundApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}


WebGPUView+UIKit

/*
 */
import SwiftUI
import Foundation
import MetalKit
#if os(iOS)
struct WebGPUView: UIViewRepresentable {
    typealias NSViewType = MTKView
    typealias Coordinator = WebGPUCoordinator
    func makeUIView(context: Context) -> MTKView {
        let mtkView = MTKView()
        context.coordinator.setView(mtkView)
        mtkView.delegate = coordinator
        return mtkView
    }

    func updateUIView(_ uiView: MTKView, context: Context) {
    }
    func makeCoordinator() -> Coordinator {
        return WebGPUCoordinator()
    }
}
#endif


URLField

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import SwiftUI
struct URLField<Accessory> : View where Accessory : View {
    init(
        url: URL?,
        isSecure: Bool = false,
        loadingProgress: Double? = nil,
    private var trailingAccessory: Accessory
    private var url: URL?
    private var urlIsSecure: Bool
    var body: some View {
        let content = HStack {
            leadingAccessory
            textField
            if !isEditing {
                trailingAccessory
                    .labelStyle(IconOnlyLabelStyle())
            }
        }
        .buttonStyle(PlainButtonStyle())
        .font(.body)
        .padding(.vertical, 6)
        .padding(.horizontal, 10)
        .background(Background(loadingProgress: loadingProgress))
        .frame(minWidth: 200, idealWidth: 400, maxWidth: 600)
        .onChange(of: url, perform: { _ in urlDidChange() })
#if os(macOS)
        return content
            .overlay(RoundedRectangle(cornerRadius: 6)
                        .stroke(Color.accentColor))
#else
        return content
#endif
    }
    private var leadingAccessory: some View {
        if isEditing {
            Image(systemName: "globe").foregroundColor(.secondary)
        } else if url?.isWebSearch == true {
            Image(systemName: "magnifyingglass").foregroundColor(.orange)
        } else if urlIsSecure {
            Image(systemName: "lock.fill").foregroundColor(.green)
        } else {
            Image(systemName: "globe").foregroundColor(.secondary)
        }
    }
    private var textField: some View {
        let view = TextField(
            "Search or website address",
            text: $text,
            onEditingChanged: onEditingChange(_:),
            onCommit: onCommit
        )
        .textFieldStyle(PlainTextFieldStyle())
        .disableAutocorrection(true)
#if os(macOS)
        return view
#else
        return view
            .textContentType(.URL)
            .autocapitalization(.none)
#endif
    }
    private func urlDidChange() {
        if !isEditing {
            text = url?.absoluteString ?? ""
        }
    }
    private func onEditingChange(_ isEditing: Bool) {
        self.isEditing = isEditing
        if !isEditing {
            urlDidChange()
        }
        externalOnEditingChange(isEditing)
    }
    private func onCommit() {
        onNavigate(text)
    }
}
private struct Background : View {
    var loadingProgress: Double?
    var body: some View {
        RoundedRectangle(cornerRadius: 6)
            .foregroundColor(Color("URLFieldBackground"))
            .overlay(progress)
    }
    private var progress: some View {
        GeometryReader { proxy in
            if let loadingProgress = loadingProgress {
                ProgressView(value: loadingProgress)
                    .offset(y: proxy.size.height - 4)
            }
        }
    }
}
struct URLField_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            URLField(
                url: nil,
                isSecure: false,
                loadingProgress: nil,
                onEditingChange: { _ in },
                onNavigate: { _ in }
            ) {
                EmptyView()
            }
            URLField(
                url: URL(string: "https://webkit.org")!,
                isSecure: true,
                loadingProgress: nil,
                onEditingChange: { _ in },
                onNavigate: { _ in }
            ) {
                Image(systemName: "arrow.clockwise")
            }
            URLField(
                url: URL(string: "https://webkit.org")!,
                isSecure: true,
                loadingProgress: nil,
                onEditingChange: { _ in },
                onNavigate: { _ in }
            ) {
                Image(systemName: "arrow.clockwise")
            }
            .environment(\.colorScheme, .dark)
        }
        .padding()
        .frame(maxWidth: 400)
        .previewLayout(.sizeThatFits)
    }
}


BrowserApp

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import SwiftUI
struct BrowserApp: App {
    var body: some Scene {
        BrowserScene()
    }
}


FoundationExtras

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import Foundation
extension URL {
    static let aboutBlank = URL(string: "about:blank")!
    init(searchTerm: String) {
        var components = URLComponents(string: "https://duckduckgo.com/")!
        components.queryItems = [ URLQueryItem(name: "q", value: searchTerm) ]
        self = components.url!
    }
    var highLevelDomain: String {
        guard let host = host else {
            return ""
        }
        for prefix in ["www"] where host.hasPrefix("\(prefix).") {
            let indexAfterPrefix = host.index(host.startIndex, offsetBy: prefix.count + 1)
            return String(host[indexAfterPrefix...])
        }
        return host
    }
    var isWebSearch: Bool {
        host == "duckduckgo.com" || host?.hasSuffix(".duckduckgo.com") == true
    }
}


BrowserScene

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import SwiftUI
struct BrowserScene : Scene {
    var body: some Scene {
#if os(macOS)
        WindowGroup {
            BrowserTab()
        }
        .windowToolbarStyle(UnifiedWindowToolbarStyle(showsTitle: false))
#else
        WindowGroup {
            NavigationView {
                BrowserTab()
            }
            .navigationViewStyle(StackNavigationViewStyle())
        }
#endif
    }
}


BrowserTab

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import SwiftUI
import _WebKit_SwiftUI
struct BrowserTab : View {
    var body: some View {
        let content = WebView(state: state)
            .webViewNavigationPolicy(onAction: decidePolicy(for:state:))
            .alert(item: $externalNavigation, content: makeExternalNavigationAlert(_:))
#if os(macOS)
        return content
            .edgesIgnoringSafeArea(.all)
            .navigationTitle(state.title.isEmpty ? "MiniBrowserSwiftUI" : state.title)
            .toolbar {
                ToolbarItemGroup(placement: .navigation) {
                    backItem
                    forwardItem
                }
                ToolbarItem(placement: .principal) {
                    urlField
                }
            }
#else
        return content
            // FIXME: This should be `.all`, but on iOS safe area insets do not seem to be respected
            // correctly when embedded in a `NavigationView`.
            .edgesIgnoringSafeArea(.bottom)
            .navigationBarTitleDisplayMode(.inline)
            .toolbar {
                ToolbarItemGroup(placement: .navigationBarLeading) {
                    backItem.labelStyle(IconOnlyLabelStyle())
                    forwardItem.labelStyle(IconOnlyLabelStyle())
                }
                ToolbarItem(placement: .principal) {
                    urlField
                }
            }
#endif
    }
    private var urlField: some View {
        URLField(
            url: state.url,
            isSecure: state.hasOnlySecureContent,
            loadingProgress: state.estimatedProgress,
            onNavigate: onNavigate(to:)
        ) {
            if state.isLoading {
                Button(action: state.stopLoading) {
                    Label("Stop Loading", systemImage: "xmark")
                }
            } else {
                Button(action: state.reload) {
                    Label("Reload", systemImage: "arrow.clockwise")
                }
                .disabled(state.url == nil)
            }
        }
    }
    private var backItem: some View {
        Button(action: state.goBack) {
            Label("Back", systemImage: "chevron.left")
                .frame(minWidth: 20)
        }
        .disabled(!state.canGoBack)
    }
    private var forwardItem: some View {
        Button(action: state.goForward) {
            Label("Forward", systemImage: "chevron.right")
                .frame(minWidth: 20)
        }
        .disabled(!state.canGoForward)
    }
    private func onNavigate(to string: String) {
        switch UserInput(string: string) {
        case .search(let term):
            state.load(URL(searchTerm: term))
        case .url(let url):
            state.load(url)
        case .invalid:
            break
        }
    }
    private func decidePolicy(for action: NavigationAction, state: WebViewState) {
        if let externalURL = action.request.url, !WebView.canHandle(externalURL) {
            externalNavigation = ExternalURLNavigation(
                source: state.url ?? .aboutBlank, destination: externalURL)
            action.decidePolicy(.cancel)
        } else {
            action.decidePolicy(.allow)
        }
    }
    private func makeExternalNavigationAlert(_ navigation: ExternalURLNavigation) -> Alert {
        Alert(title: Text("Allow “\(navigation.source.highLevelDomain)” to open “\(navigation.destination.scheme ?? "")”?"),
              primaryButton: .default(Text("Allow"), action: { openURL(navigation.destination) }),
              secondaryButton: .cancel())
    }
}
private enum UserInput {
    case search(String)
    case url(URL)
    case invalid
    init(string _string: String) {
        let string = _string.trimmingCharacters(in: .whitespaces)
        if string.isEmpty {
            self = .invalid
        } else if !string.contains(where: \.isWhitespace), string.contains("."), let url = URL(string: string) {
            self = .url(url)
        } else {
            self = .search(string)
        }
    }
}
private struct ExternalURLNavigation : Identifiable, Hashable {
    var source: URL
    var destination: URL
    var id: Self { self }
}
struct BrowserTab_Previews: PreviewProvider {
    static var previews: some View {
#if os(iOS)
        NavigationView {
            BrowserTab()
        }
        .navigationViewStyle(StackNavigationViewStyle())
#endif
    }
}


WebViewState

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import Combine
import SwiftUI
import WebKit
/// Holds the dynamic state of a `WebView`.
final public class WebViewState : ObservableObject {
    var initialRequest: URLRequest?
    var webViewObservations: [NSKeyValueObservation] = []
    var webView: WKWebView? {
        didSet {
            webViewObservations.forEach { $0.invalidate() }
            guard let webView = webView else {
                webViewObservations.removeAll()
                return
            }
            func register<T>(
                _ keyPath: KeyPath<WKWebView, T>
            ) -> NSKeyValueObservation where T : Equatable {
                webView.observe(
                    keyPath, options: [.prior, .old, .new],
                    changeHandler: webView(_:didChangeKeyPath:))
            }
            // TODO: Evaluate the performance impact of pre-registering all of these observations.
            // We can't know what changes will trigger view updates, so we need to observe every
            // property that get's republished below; however, there may be more efficient ways to
            // achieve this.
            webViewObservations = [
                register(\.canGoBack), register(\.canGoForward), register(\.title), register(\.url),
                register(\.isLoading), register(\.estimatedProgress),
            ]
        }
    }
    public let objectWillChange = ObservableObjectPublisher()
    /// Creates a new `WebViewState`.
    /// - Parameters:
    ///   - initialURL: The `URL` to navigate to immediatly upon `WebView` creation.
    ///   - configuration: Configuration for the `WebView`.
    public convenience init(
        initialURL: URL? = nil, configuration: WKWebViewConfiguration = .init()
    ) {
        self.init(
            initialRequest: initialURL.map { URLRequest(url: $0) },
            configuration: configuration)
    }
    /// Creates a new `WebViewState`.
    /// - Parameters:
    ///   - initialRequest: The `URLRequest` to navigate to immediatly upon `WebView` creation.
    ///   - configuration: Configuration for the `WebView`.
    public init(initialRequest: URLRequest?, configuration: WKWebViewConfiguration = .init()) {
        self.initialRequest = initialRequest
    }
    func webView<Value>(
        _: WKWebView, didChangeKeyPath change: NSKeyValueObservedChange<Value>
    ) where Value : Equatable {
        if change.isPrior && change.oldValue != change.newValue {
            objectWillChange.send()
        }
    }
    // NOTE: I'm eliding documentation comments here. These properties and methods related 1:1 with
    // their `WKWebView` counterparts.
    public var canGoBack: Bool { webView?.canGoBack ?? false }
    public var canGoForward: Bool { webView?.canGoForward ?? false }
    public var title: String { webView?.title ?? "" }
    public var url: URL? { webView?.url }
    public var isLoading: Bool { webView?.isLoading ?? false }
    public var estimatedProgress: Double? { isLoading ? webView?.estimatedProgress : nil }
    public var hasOnlySecureContent: Bool { webView?.hasOnlySecureContent ?? false }
    public func load(_ url: URL) {
        load(URLRequest(url: url))
    }
    public func load(_ request: URLRequest) {
        webView?.load(request)
    }
    public func goBack() {
        webView?.goBack()
    }
    public func goForward() {
        webView?.goForward()
    }
    public func reload() {
        webView?.reload()
    }
    public func stopLoading() {
        webView?.stopLoading()
    }
    func createPDF(
        configuration: WKPDFConfiguration = .init(),
    ) {
        if let webView = webView {
            webView.createPDF(configuration: configuration, completionHandler: completion)
        } else {
            completion(.failure(WKError(.unknown)))
        }
    }
}


WebView

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import SwiftUI
import WebKit
/// A view that displays interactive web content.
///
/// A `WebView` is useful in any scenario that requires rendering HTML, such as for a web browser,
/// ePub reader, or simply to display local HTML resources. It provides basic behaviors for handling
/// web content by default, which can be customized to provide alternate behaviors.
public struct WebView : View {
    /// Checks whether or not WebView can handle the given URL by default.
    public static func canHandle(_ url: URL) -> Bool {
        return url.scheme.map(WKWebView.handlesURLScheme(_:)) ?? false
    }
    fileprivate var state: WebViewState
    private var customDialog: Binding<Dialog?>? = nil
    fileprivate var dialog: Dialog? {
        get { (self.customDialog ?? self.$defaultDialog).wrappedValue }
        nonmutating set { (self.customDialog ?? self.$defaultDialog).wrappedValue = newValue }
    }
    private var useInternalDialogHandling = true
    /// Create a new `WebView` instance.
    ///
    /// In order to store the state of webpages, a `WebViewState` instance must be provided by the
    /// caller. Once the web view is displayed its state can be both read and modified from the
    /// `WebViewState`, such as determining whether the `WebView` contains back-forward history, or
    /// to reload the current page.
    ///
    /// - Parameters:
    ///   - state: State to be associated with this web view.
    ///   - dialog: A binding representing any dialog that the webpage needs displayed. A custom
    ///   binding should only be provided if you need to customize the display of dialogs, otherwise
    ///   `WebView` will manage display.
    public init(state: WebViewState, dialog: Binding<Dialog?>? = nil) {
        self.state = state
        self.customDialog = dialog
        self.useInternalDialogHandling = dialog == nil
    }
    public var body: some View {
        _WebView(owner: self)
            .overlay(dialogView)
    }
    private var dialogView: some View {
        if useInternalDialogHandling, let configuration = dialog?.configuration {
            switch configuration {
            case let .javaScriptAlert(message, completion):
                JavaScriptAlert(message: message, completion: {
                    dialog = nil
                    completion()
                })
            case let .javaScriptConfirm(message, completion):
                JavaScriptConfirm(message: message, completion: {
                    dialog = nil
                    completion($0)
                })
            case let .javaScriptPrompt(message, defaultText, completion):
                JavaScriptPrompt(message: message, defaultText: defaultText, completion: {
                    dialog = nil
                    completion($0)
                })
            }
        } else {
            EmptyView().hidden()
        }
    }
}
private struct _WebView {
    let owner: WebView
    func makeView(coordinator: Coordinator, environment: EnvironmentValues) -> WKWebView {
        let view = WKWebView()
        view.navigationDelegate = coordinator
        view.uiDelegate = coordinator
        coordinator.webView = view
        coordinator.environment = environment
        if let request = coordinator.initialRequest {
            view.load(request)
        }
        return view
    }
    func updateView(_ view: WKWebView, coordinator: Coordinator, environment: EnvironmentValues) {
        coordinator.environment = environment
        if let flag = environment.allowsBackForwardNavigationGestures {
            view.allowsBackForwardNavigationGestures = flag
        }
    }
    static func dismantleView(_ view: WKWebView, coordinator: Coordinator) {
        coordinator.webView = nil
    }
    func makeCoordinator() -> Coordinator {
        Coordinator(owner: owner)
    }
}
#if os(macOS)
extension _WebView : NSViewRepresentable {
    func makeNSView(context: Context) -> WKWebView {
        makeView(coordinator: context.coordinator, environment: context.environment)
    }
    func updateNSView(_ nsView: WKWebView, context: Context) {
        updateView(nsView, coordinator: context.coordinator, environment: context.environment)
    }
    static func dismantleNSView(_ nsView: WKWebView, coordinator: Coordinator) {
        dismantleView(nsView, coordinator: coordinator)
    }
}
#else
extension _WebView : UIViewRepresentable {
    func makeUIView(context: Context) -> WKWebView {
        makeView(coordinator: context.coordinator, environment: context.environment)
    }
    func updateUIView(_ uiView: WKWebView, context: Context) {
        updateView(uiView, coordinator: context.coordinator, environment: context.environment)
    }
    static func dismantleUIView(_ uiView: WKWebView, coordinator: Coordinator) {
        dismantleView(uiView, coordinator: coordinator)
    }
}
#endif
private final class Coordinator : NSObject, WKNavigationDelegate, WKUIDelegate {
    private var owner: WebView
    fileprivate var environment: EnvironmentValues?
    init(owner: WebView) {
        self.owner = owner
    }
    // MARK: WebViewState Proxy
    var webView: WKWebView? {
        get { owner.state.webView }
        set { owner.state.webView = newValue }
    }
    subscript<T>(dynamicMember keyPath: ReferenceWritableKeyPath<WebViewState, T>) -> T {
        get { owner.state[keyPath: keyPath] }
        set { owner.state[keyPath: keyPath] = newValue }
    }
    // MARK: Navigation
    func webView(
        _ webView: WKWebView,
        decidePolicyFor navigationAction: WKNavigationAction,
        preferences: WKWebpagePreferences,
    ) {
        if let decider = environment?.navigationResponseDecider {
            let response = NavigationResponse(navigationResponse, reply: decisionHandler)
            decider(response, owner.state)
        } else {
            decisionHandler(.allow)
        }
    }
    // MARK: Dialogs
    func webView(
        _ webView: WKWebView,
        runJavaScriptAlertPanelWithMessage message: String,
        initiatedByFrame frame: WKFrameInfo,
    ) {
        owner.dialog = .javaScriptConfirm(message, completion: completionHandler)
    }
    func webView(
        _ webView: WKWebView,
        runJavaScriptTextInputPanelWithPrompt prompt: String,
        defaultText: String?,
        initiatedByFrame frame: WKFrameInfo,
    ) {
        owner.dialog = .javaScriptPrompt(
            prompt, defaultText: defaultText ?? "", completion: completionHandler)
    }
}


SwiftUIExtras

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import SwiftUI
extension Color {
    static var platformSeparator: Color {
#if os(macOS)
        return Color(NSColor.separatorColor)
#else
        return Color(UIColor.separator)
#endif
    }
    static var platformBackground: Color {
#if os(macOS)
        return Color(NSColor.windowBackgroundColor)
#else
        return Color(UIColor.systemBackground)
#endif
    }
}


WebViewModifiers

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import SwiftUI
extension View {
    /// Customizes whether horizontal swipe gestures will trigger back-forward list navigations
    /// in a `Webview`.
    public func webViewAllowsBackForwardNavigationGestures(_ allowed: Bool) -> some View {
        environment(\.allowsBackForwardNavigationGestures, allowed)
    }
}
private struct WebViewAllowsBackForwardNavigationGesturesKey : EnvironmentKey {
    static let defaultValue: Bool? = nil
}
extension EnvironmentValues {
    var allowsBackForwardNavigationGestures: Bool? {
        get { self[WebViewAllowsBackForwardNavigationGesturesKey.self] }
        set { self[WebViewAllowsBackForwardNavigationGesturesKey.self] = newValue }
    }
}


JavaScriptDialogs

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import SwiftUI
/// A view providing the WebKit-default UI for a JavaScript alert.
struct JavaScriptAlert : View {
    private var message: String
    private var completion: () -> Void
        self.message = message
        self.completion = completion
    }
    var body: some View {
        DialogContainer {
            Text(message)
        } actions: {
            Button("OK", action: completion)
                .keyboardShortcut(.return)
        }
    }
}
/// A view providing the WebKit-default UI for a JavaScript alert.
struct JavaScriptConfirm : View {
    private var message: String
    private var completion: (Bool) -> Void
        self.message = message
        self.completion = completion
    }
    var body: some View {
        DialogContainer {
            Text(message)
        } actions: {
            Button("Cancel", action: { completion(false) })
                .keyboardShortcut(".")
            Button("OK", action: { completion(true) })
                .keyboardShortcut(.return)
        }
    }
}
/// A view providing the WebKit-default UI for a JavaScript alert.
struct JavaScriptPrompt : View {
    private var message: String
    private var completion: (String?) -> Void
        self.message = message
        self._text = State(wrappedValue: defaultText)
        self.completion = completion
    }
    var body: some View {
        DialogContainer {
            Text(message)
            TextField("Your Response", text: $text, onCommit: { completion(text) })
        } actions: {
            Button("Cancel", action: { completion(nil) })
                .keyboardShortcut(".")
            Button("OK", action: { completion(text) })
                .keyboardShortcut(.return)
        }
    }
}


Navigation

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import WebKit
import SwiftUI
extension View {
    /// Provides a block to be executed on navigation milestones, and allows for customized handling
    /// of navigation policy.
    ///
    /// When providing a custom policy decider you **must** ensure that the coresponding decider's
    /// completion method is invoked exactly once. Failure to do so will result in a
    /// runtime exception.
    ///
    /// - Parameters:
    ///   - actionDecider: Decides whether to allow or cancel a navigation.
    public func webViewNavigationPolicy(
    ) -> some View {
        environment(\.navigationActionDecider, actionDecider)
    }
    /// Provides a block to be executed on navigation milestones, and allows for customized handling
    /// of navigation policy.
    ///
    /// When providing a custom policy decider you **must** ensure that the coresponding decider's
    /// completion method is invoked exactly once. Failure to do so will result in a
    /// runtime exception.
    ///
    /// - Parameters:
    ///   - responseDecider: Decides whether to allow or cancel a navigation, after its response
    ///   is known.
    public func webViewNavigationPolicy(
    ) -> some View {
        environment(\.navigationResponseDecider, responseDecider)
    }
    /// Provides a block to be executed on navigation milestones, and allows for customized handling
    /// of navigation policy.
    ///
    /// When providing a custom policy decider you **must** ensure that the coresponding decider's
    /// completion method is invoked exactly once. Failure to do so will result in a
    /// runtime exception.
    ///
    /// - Parameters:
    ///   - actionDecider: Decides whether to allow or cancel a navigation.
    ///   - responseDecider: Decides whether to allow or cancel a navigation, after its response
    ///   is known.
    public func webViewNavigationPolicy(
public struct NavigationAction {
    public typealias Policy = WKNavigationActionPolicy
    private var action: WKNavigationAction
    private var reply: (WKNavigationActionPolicy, WKWebpagePreferences) -> Void
    /// The default set of webpage preferences. This may be changed by passing modified preferences
    /// to `decidePolicy(_:webpagePreferences:)`.
    public private(set) var webpagePreferences: WKWebpagePreferences
    // FIXME: `webpagePreferences` lacks value semantics, which breaks the API contract. This
    // instance should not be mutable, but that would require an Objective-C type bridge. We could
    ) {
        self.action = action
        self.reply = reply
        self.webpagePreferences = webpagePreferences
    }
    /// Decides what action to take for this navigation. This method **must** be invoked exactly
    /// once, otherwise WebKit will raise an exception.
    /// - Parameters:
    ///   - policy: The desired policy for this navigation.
    ///   - webpagePreferences: The preferences to use for this navigation, or `nil` to use the
    ///   default preferences.
    public func decidePolicy(_ policy: Policy, webpagePreferences: WKWebpagePreferences? = nil) {
        reply(policy, webpagePreferences ?? self.webpagePreferences)
    }
    public subscript<T>(dynamicMember keyPath: KeyPath<WKNavigationAction, T>) -> T {
        action[keyPath: keyPath]
    }
    fileprivate struct DeciderKey : EnvironmentKey {
        static let defaultValue: ((NavigationAction, WebViewState) -> Void)? = nil
    }
}
/// Contains information about a navigation response, used for making policy decisions.
        self.response = response
        self.reply = reply
    }
    /// Decides what action to take for this navigation. This method **must** be invoked exactly
    /// once, otherwise WebKit will raise an exception.
    /// - Parameters:
    ///   - policy: The desired policy for this navigation.
    public func decidePolicy(_ policy: Policy) {
        reply(policy)
    }
    public subscript<T>(dynamicMember keyPath: KeyPath<WKNavigationResponse, T>) -> T {
        response[keyPath: keyPath]
    }
    fileprivate struct DeciderKey : EnvironmentKey {
        static let defaultValue: ((NavigationResponse, WebViewState) -> Void)? = nil
    }
}
extension EnvironmentValues {
    var navigationActionDecider: ((NavigationAction, WebViewState) -> Void)? {
        get { self[NavigationAction.DeciderKey.self] }
        set { self[NavigationAction.DeciderKey.self] = newValue }
    }
    var navigationResponseDecider: ((NavigationResponse, WebViewState) -> Void)? {
        get { self[NavigationResponse.DeciderKey.self] }
        set { self[NavigationResponse.DeciderKey.self] = newValue }
    }
}


Dialog

/*
 * THE POSSIBILITY OF SUCH DAMAGE.
 */
import SwiftUI
/// A dialog requested for display by some aspect of web content.
public struct Dialog : Identifiable, Hashable {
    /// An opaque identifier for this dialog.
    public var id = ID()
    /// A configuration describing the purpose and contents of this dialog for display.
    public var configuration: Configuration
    /// Constructs a dialog from its component parts.
    public init(id: ID = ID(), _ configuration: Configuration) {
        self.id = id
        self.configuration = configuration
    }
    /// Constructs a dialog for a JavaScript `alert()`, which contains only a message to the user.
    /// - Parameters:
    ///   - id: An opaque identifier for the dialog.
    ///   - message: A message to display to the user.
    ///   - completion: A block to be invoked when the dialog has been dismissed. The webpage will
    ///   be paused until this block is invoked, and failure to invoke the block, or multiple
    ///   invocations will result in a runtime exception.
    public static func javaScriptAlert(
    ) -> Self {
        Dialog(id: id, .javaScriptConfirm(message, completion))
    }
    /// Constructs a dialog for a JavaScript `prompt()`, which contains a message to the user and
    /// expects the response of either a string or `nil`.
    /// - Parameters:
    ///   - id: An opaque identifier for the dialog.
    ///   - message: A message to display to the user.
    ///   - defaultText: A default response for the user, provided by the webpage.
    ///   - completion: A block to be invoked with the user's decision. For this reply, `nil` and
    ///   an empty string (`""`) are treated differently. `nil` means that the user selected a
    ///   _cancel_ operation, while any non-`nil` response implies an _ok_ operation. The webpage
    ///   will be paused until this block is invoked, and failure to invoke the block, or multiple
    ///   invocations will result in a runtime exception.
    public static func javaScriptPrompt(
        id: ID = ID(), _ message: String, defaultText: String = "",
    ) -> Self {
        Dialog(id: id, .javaScriptPrompt(message, defaultText: defaultText, completion))
    }
    public func hash(into hasher: inout Hasher) {
        hasher.combine(id)
    }
    public static func == (lhs: Dialog, rhs: Dialog) -> Bool {
        lhs.id == rhs.id
    }
    /// An opaque identifier for a `Dialog`.
    public struct ID : Hashable {
        private var rawValue = UUID()
        /// Constructs a new, unique identifier.
        public init() {
        }
    }
    /// Describes a specific type of dialog, along with any specific values for that type.
    public enum Configuration {
        /// A dialog triggered by the JavaScript `window.alert()` API.
        /// - Paramaters:
        ///   - 0: A message from the webpage for the user.
        ///   - 1: A block to be invoked when the dialog has been dismissed. The webpage will be
        ///   paused until this block is invoked, and failure to invoke the block, or multiple
        ///   invocations will result in a runtime exception.
        case javaScriptAlert(String, () -> Void)
        /// A dialog triggered by the JavaScript `window.confirm()` API.
        ///   - 0: A message from the webpage for the user.
        ///   - 1: A block to be invoked with a binary decision from the user. The webpage will be
        ///   paused until this block is invoked, and failure to invoke the block, or multiple
        ///   invocations will result in a runtime exception.
        case javaScriptConfirm(String, (Bool) -> Void)
        /// A dialog triggered by the JavaScript `window.prompt()` API.
        /// - Paramaters:
        ///   - 0: A message from the webpage for the user.
        ///   - defaultText: A webpage provided default response for the user.
        ///   - 1: A block to be invoked with the user's decision. For this reply, `nil` and an
        ///   empty string (`""`) are treated differently. `nil` means that the user selected a
        ///   _cancel_ operation, while any non-`nil` response implies an _ok_ operation. The
        ///   webpage will be paused until this block is invoked, and failure to invoke the block,
        ///   or multiple invocations will result in a runtime exception.
        case javaScriptPrompt(String, defaultText: String, (String?) -> Void)
    }
}
/// A view providing the WebKit-default UI for generic webpage dialogs.
struct DialogContainer<Contents, Actions> : View where Contents : View, Actions : View {
    var contents: Contents
    var actions: Actions
        self.contents = contents()
        self.actions = actions()
    }
    var body: some View {
        ZStack {
            Color(white: 0, opacity: 0.15)
            VStack(spacing: 0) {
                VStack(alignment: .leading) {
                    contents
                }
                .frame(maxWidth: .infinity, alignment: .leading)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
                Divider()
                HStack(spacing: 12) {
                    Spacer()
                    actions
                        .buttonStyle(_LinkButtonStyle())
                }
                .padding(.horizontal)
                .padding(.vertical, 12)
            }
            .frame(maxWidth: 300)
            .background(RoundedRectangle(cornerRadius: 10)
                            .foregroundColor(Color.platformBackground)
                            .shadow(radius: 12))
            .overlay(RoundedRectangle(cornerRadius: 10).stroke(Color.platformSeparator))
        }
    }
}
#if os(macOS)
private typealias _LinkButtonStyle = LinkButtonStyle
#else
private struct _LinkButtonStyle : ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .foregroundColor(.blue)
    }
}
#endif


GPBSwiftTests

// Protocol Buffers - Google's data interchange format
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
import Foundation
import XCTest
// Test some usage of the ObjC library from Swift.
class GPBBridgeTests: XCTestCase {
  func testProto2Basics() {
    let msg = Message2()
    let msg2 = Message2()
    let msg3 = Message2_OptionalGroup()
    msg.optionalInt32 = 100
    msg.optionalString = "abc"
    msg.optionalEnum = .bar
    msg2.optionalString = "other"
    msg.optional = msg2
    msg3.a = 200
    msg.optionalGroup = msg3
    msg.repeatedInt32Array.addValue(300)
    msg.repeatedInt32Array.addValue(301)
    msg.repeatedStringArray.add("mno")
    msg.repeatedStringArray.add("pqr")
    msg.repeatedEnumArray.addValue(Message2_Enum.bar.rawValue)
    msg.repeatedEnumArray.addValue(Message2_Enum.baz.rawValue)
    msg.mapInt32Int32.setInt32(400, forKey:500)
    msg.mapInt32Int32.setInt32(401, forKey:501)
    msg.mapStringString.setObject("foo", forKey:"bar" as NSString)
    msg.mapStringString.setObject("abc", forKey:"xyz" as NSString)
    msg.mapInt32Enum.setEnum(Message2_Enum.bar.rawValue, forKey:600)
    msg.mapInt32Enum.setEnum(Message2_Enum.baz.rawValue, forKey:601)
    // Check has*.
    XCTAssertTrue(msg.hasOptionalInt32)
    XCTAssertTrue(msg.hasOptionalString)
    XCTAssertTrue(msg.hasOptionalEnum)
    XCTAssertTrue(msg2.hasOptionalString)
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertTrue(msg3.hasA)
    XCTAssertTrue(msg.hasOptionalGroup)
    XCTAssertFalse(msg.hasOptionalInt64)
    XCTAssertFalse(msg.hasOptionalFloat)
    // Check values.
    XCTAssertEqual(msg.optionalInt32, Int32(100))
    XCTAssertEqual(msg.optionalString, "abc")
    XCTAssertEqual(msg2.optionalString, "other")
    XCTAssertTrue(msg.optional === msg2)
    XCTAssertEqual(msg.optionalEnum, Message2_Enum.bar)
    XCTAssertEqual(msg3.a, Int32(200))
    XCTAssertTrue(msg.optionalGroup === msg3)
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(2))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 0), Int32(300))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 1), Int32(301))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(2))
    XCTAssertEqual(msg.repeatedStringArray.object(at: 0) as? String, "mno")
    XCTAssertEqual(msg.repeatedStringArray.object(at: 1) as? String, "pqr")
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(2))
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 0), Message2_Enum.bar.rawValue)
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 1), Message2_Enum.baz.rawValue)
    XCTAssertEqual(msg.repeatedInt64Array.count, UInt(0))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
    var intValue: Int32 = 0
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey: 500))
    XCTAssertEqual(intValue, Int32(400))
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey: 501))
    XCTAssertEqual(intValue, Int32(401))
    XCTAssertEqual(msg.mapStringString.count, Int(2))
    XCTAssertEqual(msg.mapStringString.object(forKey: "bar") as? String, "foo")
    XCTAssertEqual(msg.mapStringString.object(forKey: "xyz") as? String, "abc")
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(2))
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:600))
    XCTAssertEqual(intValue, Message2_Enum.bar.rawValue)
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:601))
    XCTAssertEqual(intValue, Message2_Enum.baz.rawValue)
    // Clearing a string with nil.
    msg2.optionalString = nil
    XCTAssertFalse(msg2.hasOptionalString)
    XCTAssertEqual(msg2.optionalString, "")
    // Clearing a message with nil.
    msg.optionalGroup = nil
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertTrue(msg.optionalGroup !== msg3)  // New instance
    // Clear.
    msg.clear()
    XCTAssertFalse(msg.hasOptionalInt32)
    XCTAssertFalse(msg.hasOptionalString)
    XCTAssertFalse(msg.hasOptionalEnum)
    XCTAssertFalse(msg.hasOptionalMessage)
    XCTAssertFalse(msg.hasOptionalInt64)
    XCTAssertFalse(msg.hasOptionalFloat)
    XCTAssertEqual(msg.optionalInt32, Int32(0))
    XCTAssertEqual(msg.optionalString, "")
    XCTAssertTrue(msg.optional !== msg2)  // New instance
    XCTAssertEqual(msg.optionalEnum, Message2_Enum.foo)  // Default
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(0))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(0))
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(0))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(0))
    XCTAssertEqual(msg.mapStringString.count, Int(0))
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(0))
  }
  func testProto3Basics() {
    let msg = Message3()
    let msg2 = Message3()
    msg.optionalInt32 = 100
    msg.optionalString = "abc"
    msg.optionalEnum = .bar
    msg2.optionalString = "other"
    msg.optional = msg2
    msg.repeatedInt32Array.addValue(300)
    msg.repeatedInt32Array.addValue(301)
    msg.repeatedStringArray.add("mno")
    msg.repeatedStringArray.add("pqr")
    // "proto3" syntax lets enum get unknown values.
    msg.repeatedEnumArray.addValue(Message3_Enum.bar.rawValue)
    msg.repeatedEnumArray.addRawValue(666)
    SetMessage3_OptionalEnum_RawValue(msg2, 666)
    msg.mapInt32Int32.setInt32(400, forKey:500)
    msg.mapInt32Int32.setInt32(401, forKey:501)
    msg.mapStringString.setObject("foo", forKey:"bar" as NSString)
    msg.mapStringString.setObject("abc", forKey:"xyz" as NSString)
    msg.mapInt32Enum.setEnum(Message2_Enum.bar.rawValue, forKey:600)
    // "proto3" syntax lets enum get unknown values.
    msg.mapInt32Enum.setRawValue(666, forKey:601)
    // Has only exists on for message fields.
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertFalse(msg2.hasOptionalMessage)
    // Check values.
    XCTAssertEqual(msg.optionalInt32, Int32(100))
    XCTAssertEqual(msg.optionalString, "abc")
    XCTAssertEqual(msg2.optionalString, "other")
    XCTAssertTrue(msg.optional === msg2)
    XCTAssertEqual(msg.optionalEnum, Message3_Enum.bar)
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(2))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 0), Int32(300))
    XCTAssertEqual(msg.repeatedInt32Array.value(at: 1), Int32(301))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(2))
    XCTAssertEqual(msg.repeatedStringArray.object(at: 0) as? String, "mno")
    XCTAssertEqual(msg.repeatedStringArray.object(at: 1) as? String, "pqr")
    XCTAssertEqual(msg.repeatedInt64Array.count, UInt(0))
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(2))
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 0), Message3_Enum.bar.rawValue)
    XCTAssertEqual(msg.repeatedEnumArray.value(at: 1), Message3_Enum.gpbUnrecognizedEnumeratorValue.rawValue)
    XCTAssertEqual(msg.repeatedEnumArray.rawValue(at: 1), 666)
    XCTAssertEqual(msg2.optionalEnum, Message3_Enum.gpbUnrecognizedEnumeratorValue)
    XCTAssertEqual(Message3_OptionalEnum_RawValue(msg2), Int32(666))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
    var intValue: Int32 = 0
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey:500))
    XCTAssertEqual(intValue, Int32(400))
    XCTAssertTrue(msg.mapInt32Int32.getInt32(&intValue, forKey:501))
    XCTAssertEqual(intValue, Int32(401))
    XCTAssertEqual(msg.mapStringString.count, Int(2))
    XCTAssertEqual(msg.mapStringString.object(forKey: "bar") as? String, "foo")
    XCTAssertEqual(msg.mapStringString.object(forKey: "xyz") as? String, "abc")
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(2))
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:600))
    XCTAssertEqual(intValue, Message2_Enum.bar.rawValue)
    XCTAssertTrue(msg.mapInt32Enum.getEnum(&intValue, forKey:601))
    XCTAssertEqual(intValue, Message3_Enum.gpbUnrecognizedEnumeratorValue.rawValue)
    XCTAssertTrue(msg.mapInt32Enum.getRawValue(&intValue, forKey:601))
    XCTAssertEqual(intValue, 666)
    // Clearing a string with nil.
    msg2.optionalString = nil
    XCTAssertEqual(msg2.optionalString, "")
    // Clearing a message with nil.
    msg.optional = nil
    XCTAssertFalse(msg.hasOptionalMessage)
    XCTAssertTrue(msg.optional !== msg2)  // New instance
    // Clear.
    msg.clear()
    XCTAssertFalse(msg.hasOptionalMessage)
    XCTAssertEqual(msg.optionalInt32, Int32(0))
    XCTAssertEqual(msg.optionalString, "")
    XCTAssertTrue(msg.optional !== msg2)  // New instance
    XCTAssertEqual(msg.optionalEnum, Message3_Enum.foo)  // Default
    XCTAssertEqual(msg.repeatedInt32Array.count, UInt(0))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(0))
    XCTAssertEqual(msg.repeatedEnumArray.count, UInt(0))
    msg2.clear()
    XCTAssertEqual(msg2.optionalEnum, Message3_Enum.foo)  // Default
    XCTAssertEqual(Message3_OptionalEnum_RawValue(msg2), Message3_Enum.foo.rawValue)
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(0))
    XCTAssertEqual(msg.mapStringString.count, Int(0))
    XCTAssertEqual(msg.mapInt32Enum.count, UInt(0))
  }
  func testAutoCreation() {
    let msg = Message2()
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertFalse(msg.hasOptionalMessage)
    // Access shouldn't result in has* but should return objects.
    let msg2 = msg.optionalGroup
    let msg3 = msg.optional.optional
    let msg4 = msg.optional
    XCTAssertNotNil(msg2)
    XCTAssertNotNil(msg3)
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertFalse(msg.optional.hasOptionalMessage)
    XCTAssertFalse(msg.hasOptionalMessage)
    // Setting things should trigger has* getting set.
    msg.optionalGroup.a = 10
    msg.optional.optional.optionalInt32 = 100
    XCTAssertTrue(msg.hasOptionalGroup)
    XCTAssertTrue(msg.optional.hasOptionalMessage)
    XCTAssertTrue(msg.hasOptionalMessage)
    // And they should be the same pointer as before.
    XCTAssertTrue(msg2 === msg.optionalGroup)
    XCTAssertTrue(msg3 === msg.optional.optional)
    XCTAssertTrue(msg4 === msg.optional)
    // Clear gets us new objects next time around.
    msg.clear()
    XCTAssertFalse(msg.hasOptionalGroup)
    XCTAssertFalse(msg.optional.hasOptionalMessage)
    XCTAssertFalse(msg.hasOptionalMessage)
    msg.optionalGroup.a = 20
    msg.optional.optional.optionalInt32 = 200
    XCTAssertTrue(msg.hasOptionalGroup)
    XCTAssertTrue(msg.optional.hasOptionalMessage)
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertTrue(msg2 !== msg.optionalGroup)
    XCTAssertTrue(msg3 !== msg.optional.optional)
    XCTAssertTrue(msg4 !== msg.optional)
    // Explicit set of a message, means autocreated object doesn't bind.
    msg.clear()
    let autoCreated = msg.optional
    XCTAssertFalse(msg.hasOptionalMessage)
    let msg5 = Message2()
    msg5.optionalInt32 = 123
    msg.optional = msg5
    XCTAssertTrue(msg.hasOptionalMessage)
    // Modifying the autocreated doesn't replaced the explicit set one.
    autoCreated?.optionalInt32 = 456
    XCTAssertTrue(msg.hasOptionalMessage)
    XCTAssertTrue(msg.optional === msg5)
    XCTAssertEqual(msg.optional.optionalInt32, Int32(123))
  }
  func testProto2OneOfSupport() {
    let msg = Message2()
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    let autoCreated = msg.oneof  // Default create one.
    XCTAssertNotNil(autoCreated)
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofInt32)
    msg.oneofFloat = 20.0
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(20.0))
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofFloat)
    msg.oneofEnum = .bar
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.bar)
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofEnum)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 200
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(200))
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofMessage)
    // Clear the oneof.
    Message2_ClearOOneOfCase(msg)
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(110.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message2_Enum.baz)  // Default
    let autoCreated2 = msg.oneof  // Default create one
    XCTAssertNotNil(autoCreated2)
    XCTAssertTrue(autoCreated2 !== autoCreated)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofInt32)
    // Confirm Message.clear() handles the oneof correctly.
    msg.clear()
    XCTAssertEqual(msg.oneofInt32, Int32(100))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 300
    XCTAssertTrue(msg.oneof !== autoCreated)  // New instance
    XCTAssertTrue(msg.oneof !== autoCreated2)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(300))
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.oneofMessage)
    // Set message to nil clears the oneof.
    msg.oneof = nil
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message2_O_OneOfCase.gpbUnsetOneOfCase)
  }
  func testProto3OneOfSupport() {
    let msg = Message3()
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    let autoCreated = msg.oneof  // Default create one.
    XCTAssertNotNil(autoCreated)
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofInt32)
    msg.oneofFloat = 20.0
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(20.0))
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofFloat)
    msg.oneofEnum = .bar
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.bar)
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofEnum)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 200
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    XCTAssertTrue(msg.oneof === autoCreated)  // Still the same
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(200))
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofMessage)
    // Clear the oneof.
    Message3_ClearOOneOfCase(msg)
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oneofFloat, Float(0.0))  // Default
    XCTAssertEqual(msg.oneofEnum, Message3_Enum.foo)  // Default
    let autoCreated2 = msg.oneof  // Default create one
    XCTAssertNotNil(autoCreated2)
    XCTAssertTrue(autoCreated2 !== autoCreated)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    msg.oneofInt32 = 10
    XCTAssertEqual(msg.oneofInt32, Int32(10))
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofInt32)
    // Confirm Message.clear() handles the oneof correctly.
    msg.clear()
    XCTAssertEqual(msg.oneofInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
    // Sets via the autocreated instance.
    msg.oneof.optionalInt32 = 300
    XCTAssertTrue(msg.oneof !== autoCreated)  // New instance
    XCTAssertTrue(msg.oneof !== autoCreated2)  // New instance
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(300))
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.oneofMessage)
    // Set message to nil clears the oneof.
    msg.oneof = nil
    XCTAssertEqual(msg.oneof.optionalInt32, Int32(0))  // Default
    XCTAssertEqual(msg.oOneOfCase, Message3_O_OneOfCase.gpbUnsetOneOfCase)
  }
  func testSerialization() {
    let msg = Message2()
    msg.optionalInt32 = 100
    msg.optionalInt64 = 101
    msg.optionalGroup.a = 102
    msg.repeatedStringArray.add("abc")
    msg.repeatedStringArray.add("def")
    msg.mapInt32Int32.setInt32(200, forKey:300)
    msg.mapInt32Int32.setInt32(201, forKey:201)
    msg.mapStringString.setObject("foo", forKey:"bar" as NSString)
    msg.mapStringString.setObject("abc", forKey:"xyz" as NSString)
    let data = msg.data()
    let msg2 = try! Message2(data: data!)
    XCTAssertTrue(msg2 !== msg)  // New instance
    XCTAssertEqual(msg.optionalInt32, Int32(100))
    XCTAssertEqual(msg.optionalInt64, Int64(101))
    XCTAssertEqual(msg.optionalGroup.a, Int32(102))
    XCTAssertEqual(msg.repeatedStringArray.count, Int(2))
    XCTAssertEqual(msg.mapInt32Int32.count, UInt(2))
    XCTAssertEqual(msg.mapStringString.count, Int(2))
    XCTAssertEqual(msg2, msg)
  }
}


TFLBertTokenizerTest

class TFLBertTokenizerTest: XCTestCase {
  static let bundle = Bundle(for: TFLBertTokenizerTest.self)
  static let mobileBertVocabPath = bundle.path(forResource: "mobilebert_vocab", ofType: "txt")!
  func testInitBertTokenizerFromPath() {
    let bertTokenizer = TFLBertTokenizer(vocabPath: TFLBertTokenizerTest.mobileBertVocabPath)
    XCTAssertNotNil(bertTokenizer)
    let tokens = bertTokenizer.tokens(fromInput: "i'm questionansweraskask")
    XCTAssertEqual(tokens, ["i", "'", "m", "question", "##ans", "##wer", "##ask", "##ask"])
    let ids = bertTokenizer.ids(fromTokens: tokens)
    XCTAssertEqual(ids, [1045, 1005, 1049, 3160, 6962, 13777, 19895, 19895])
  }
  func testInitBertTokenizerFromVocab() {
    let bertTokenizer = TFLBertTokenizer(vocab: ["hell", "##o", "wor", "##ld", "there"])
    XCTAssertNotNil(bertTokenizer)
    let tokens = bertTokenizer.tokens(fromInput: "hello there hello world")
    XCTAssertEqual(tokens, ["hell", "##o", "there", "hell", "##o", "wor", "##ld"])
    let ids = bertTokenizer.ids(fromTokens: tokens)
    XCTAssertEqual(ids, [0, 1, 4, 0, 1, 2, 3])
  }
}


TFLSentencepieceTokenizerTest

class TFLSentencepieceTokenizerTest: XCTestCase {
  static let bundle = Bundle(for: TFLSentencepieceTokenizerTest.self)
  static let spModelPath = bundle.path(forResource: "30k-clean", ofType: "model")!
  func testInitSentenpieceTokenizerFromPath() {
    let spTokenizer = TFLSentencepieceTokenizer(
      modelPath: TFLSentencepieceTokenizerTest.spModelPath)
    XCTAssertNotNil(spTokenizer)
    let tokens = spTokenizer.tokens(fromInput: "good morning, i'm your teacher.\n")
    XCTAssertEqual(tokens, ["▁good", "▁morning", ",", "▁i", "'", "m", "▁your", "▁teacher", "."])
    let ids = spTokenizer.ids(fromTokens: tokens)
    XCTAssertEqual(ids, [254, 959, 15, 31, 22, 79, 154, 2197, 9])
  }
}


TFLAudioClassifierTests

class AudioClassifierTests: XCTestCase {
  static let bundle = Bundle(for: AudioClassifierTests.self)
  static let modelPath = bundle.path(
    forResource: "yamnet_audio_classifier_with_metadata",
    ofType: "tflite")
  func verifyError(
    _ error: Error,
    expectedLocalizedDescription: String
  ) {
    XCTAssertEqual(
      error.localizedDescription,
      expectedLocalizedDescription)
  }
  func verifyCategory(
    _ category: ClassificationCategory,
    expectedIndex: NSInteger,
    expectedScore: Float,
    expectedLabel: String,
    expectedDisplayName: String?
  ) {
    XCTAssertEqual(
      category.index,
      expectedIndex)
    XCTAssertEqual(
      category.score,
      expectedScore,
      accuracy: 1e-6)
    XCTAssertEqual(
      category.label,
      expectedLabel)
    XCTAssertEqual(
      category.displayName,
      expectedDisplayName)
  }
  func verifyClassifications(
    _ classifications: Classifications,
    expectedHeadIndex: NSInteger,
    expectedCategoryCount: NSInteger
  ) {
    XCTAssertEqual(
      classifications.headIndex,
      expectedHeadIndex)
    XCTAssertEqual(
      classifications.categories.count,
      expectedCategoryCount)
  }
  func verifyClassificationResult(
    _ classificationResult: ClassificationResult,
    expectedClassificationsCount: NSInteger
  ) {
    XCTAssertEqual(
      classificationResult.classifications.count,
      expectedClassificationsCount)
  }
  func bufferFromFile(
    withName name: String,
    fileExtension: String,
    audioFormat: AudioFormat
  ) -> AVAudioPCMBuffer? {
    guard
      let filePath = AudioClassifierTests.bundle.path(
        forResource: name,
        ofType: fileExtension)
    else {
      return nil
    }
    return AVAudioPCMBuffer.loadPCMBufferFromFile(
      withPath: filePath,
      audioFormat: audioFormat)
  }
  func createAudioClassifierOptions(
    modelPath: String?
  ) throws -> AudioClassifierOptions? {
    let modelPath = try XCTUnwrap(modelPath)
    let options = AudioClassifierOptions(modelPath: modelPath)
    return options
  }
  func createAudioClassifier(
    withModelPath modelPath: String?
  ) throws -> AudioClassifier? {
    let options = try XCTUnwrap(
      self.createAudioClassifierOptions(
        modelPath: AudioClassifierTests.modelPath))
    let audioClassifier = try XCTUnwrap(
      AudioClassifier.classifier(
        options: options))
    return audioClassifier
  }
  func createAudioTensor(
    withAudioClassifier audioClassifier: AudioClassifier
  ) -> AudioTensor {
    let audioTensor = audioClassifier.createInputAudioTensor()
    return audioTensor
  }
  func loadAudioTensor(
    _ audioTensor: AudioTensor,
    fromWavFileWithName fileName: String
  ) throws {
    // Load pcm buffer from file.
    let buffer = try XCTUnwrap(
      self.bufferFromFile(
        withName: fileName,
        fileExtension: "wav",
        audioFormat: audioTensor.audioFormat))
    // Get float buffer from pcm buffer.
    let floatBuffer = try XCTUnwrap(buffer.floatBuffer)
    // Load float buffer into the audio tensor.
    try audioTensor.load(
      buffer: floatBuffer,
      offset: 0,
      size: floatBuffer.size)
  }
  func classify(
    audioTensor: AudioTensor,
    usingAudioClassifier audioClassifier: AudioClassifier
  ) throws -> ClassificationResult? {
    let classificationResult = try XCTUnwrap(
      audioClassifier.classify(
        audioTensor: audioTensor))
    let expectedClassificationsCount = 1
    self.verifyClassificationResult(
      classificationResult,
      expectedClassificationsCount: expectedClassificationsCount)
    let expectedCategoryCount = 521
    let expectedHeadIndex = 0
    self.verifyClassifications(
      classificationResult.classifications[0],
      expectedHeadIndex: expectedHeadIndex,
      expectedCategoryCount: expectedCategoryCount)
    return classificationResult
  }
  func validateForInferenceWithFloatBuffer(
    categories: [ClassificationCategory]
  ) {
    self.verifyCategory(
      categories[0],
      expectedIndex: 0,
      expectedScore: 0.957031,
      expectedLabel: "Speech",
      expectedDisplayName: nil)
    self.verifyCategory(
      categories[1],
      expectedIndex: 500,
      0.019531,               // expectedScore
      expectedLabel: "Inside, small room",
      expectedDisplayName: nil)
  }
  func testInferenceWithFloatBufferSucceeds() throws {
    let audioClassifier = try XCTUnwrap(
      self.createAudioClassifier(
        withModelPath: AudioClassifierTests.modelPath))
    let audioTensor = self.createAudioTensor(
      withAudioClassifier: audioClassifier)
    try self.loadAudioTensor(
      audioTensor, fromWavFileWithName: "speech")
    let classificationResult = try XCTUnwrap(
      self.classify(
        audioTensor: audioTensor,
        usingAudioClassifier: audioClassifier))
    self.validateForInferenceWithFloatBuffer(
      categories: classificationResult.classifications[0].categories)
  }
  func testInferenceWithNoModelPathFails() throws {
    let options = AudioClassifierOptions()
    do {
      let audioClassifier = try AudioClassifier.classifier(
        options: options)
      XCTAssertNil(audioClassifier)
    } catch {
      self.verifyError(
        error,
        expectedLocalizedDescription:
          "INVALID_ARGUMENT: Missing mandatory `model_file` field in `base_options`")
    }
  }
}


TFLImageSegmenterTests

class ImageSegmenterTests: XCTestCase {
  static let bundle = Bundle(for: ImageSegmenterTests.self)
  static let modelPath = bundle.path(
    forResource: "deeplabv3",
    ofType: "tflite")
  // The maximum fraction of pixels in the candidate mask that can have a
  // different class than the golden mask for the test to pass.
  let kGoldenMaskTolerance: Float = 1e-2
  // Magnification factor used when creating the golden category masks to make
  // them more human-friendly. Each pixel in the golden masks has its value
  // multiplied by this factor, i.e. a value of 10 means class index 1, a value of
  // 20 means class index 2, etc.
  let kGoldenMaskMagnificationFactor: UInt8 = 10
  let deepLabV3SegmentationWidth = 257
  let deepLabV3SegmentationHeight = 257
  func verifyDeeplabV3PartialSegmentationResult(_ coloredLabels: [ColoredLabel]) {
    self.verifyColoredLabel(
      coloredLabels[0],
      expectedR: 0,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "background")
    self.verifyColoredLabel(
      coloredLabels[1],
      expectedR: 128,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "aeroplane")
    self.verifyColoredLabel(
      coloredLabels[2],
      expectedR: 0,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "bicycle")
    self.verifyColoredLabel(
      coloredLabels[3],
      expectedR: 128,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "bird")
    self.verifyColoredLabel(
      coloredLabels[4],
      expectedR: 0,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "boat")
    self.verifyColoredLabel(
      coloredLabels[5],
      expectedR: 128,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "bottle")
    self.verifyColoredLabel(
      coloredLabels[6],
      expectedR: 0,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "bus")
    self.verifyColoredLabel(
      coloredLabels[7],
      expectedR: 128,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "car")
    self.verifyColoredLabel(
      coloredLabels[8],
      expectedR: 64,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "cat")
    self.verifyColoredLabel(
      coloredLabels[9],
      expectedR: 192,
      expectedG: 0,
      expectedB: 0,
      expectedLabel: "chair")
    self.verifyColoredLabel(
      coloredLabels[10],
      expectedR: 64,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "cow")
    self.verifyColoredLabel(
      coloredLabels[11],
      expectedR: 192,
      expectedG: 128,
      expectedB: 0,
      expectedLabel: "dining table")
    self.verifyColoredLabel(
      coloredLabels[12],
      expectedR: 64,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "dog")
    self.verifyColoredLabel(
      coloredLabels[13],
      expectedR: 192,
      expectedG: 0,
      expectedB: 128,
      expectedLabel: "horse")
    self.verifyColoredLabel(
      coloredLabels[14],
      expectedR: 64,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "motorbike")
    self.verifyColoredLabel(
      coloredLabels[15],
      expectedR: 192,
      expectedG: 128,
      expectedB: 128,
      expectedLabel: "person")
    self.verifyColoredLabel(
      coloredLabels[16],
      expectedR: 0,
      expectedG: 64,
      expectedB: 0,
      expectedLabel: "potted plant")
    self.verifyColoredLabel(
      coloredLabels[17],
      expectedR: 128,
      expectedG: 64,
      expectedB: 0,
      expectedLabel: "sheep")
    self.verifyColoredLabel(
      coloredLabels[18],
      expectedR: 0,
      expectedG: 192,
      expectedB: 0,
      expectedLabel: "sofa")
    self.verifyColoredLabel(
      coloredLabels[19],
      expectedR: 128,
      expectedG: 192,
      expectedB: 0,
      expectedLabel: "train")
    self.verifyColoredLabel(
      coloredLabels[20],
      expectedR: 0,
      expectedG: 64,
      expectedB: 128,
      expectedLabel: "tv")
  }
  func verifyColoredLabel(
    _ coloredLabel: ColoredLabel,
    expectedR: UInt,
    expectedG: UInt,
    expectedB: UInt,
    expectedLabel: String
  ) {
    XCTAssertEqual(
      coloredLabel.r,
      expectedR)
    XCTAssertEqual(
      coloredLabel.g,
      expectedG)
    XCTAssertEqual(
      coloredLabel.b,
      expectedB)
    XCTAssertEqual(
      coloredLabel.label,
      expectedLabel)
  }
  func testSuccessfullInferenceOnMLImageWithUIImage() throws {
    let modelPath = try XCTUnwrap(ImageSegmenterTests.modelPath)
    let imageSegmenterOptions = ImageSegmenterOptions(modelPath: modelPath)
    let imageSegmenter =
      try ImageSegmenter.segmenter(options: imageSegmenterOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "segmentation_input_rotation0",
        type: "jpg"))
    let segmentationResult: SegmentationResult =
      try XCTUnwrap(imageSegmenter.segment(mlImage: gmlImage))
    XCTAssertEqual(segmentationResult.segmentations.count, 1)
    let coloredLabels = try XCTUnwrap(segmentationResult.segmentations[0].coloredLabels)
    verifyDeeplabV3PartialSegmentationResult(coloredLabels)
    let categoryMask = try XCTUnwrap(segmentationResult.segmentations[0].categoryMask)
    XCTAssertEqual(deepLabV3SegmentationWidth, categoryMask.width)
    XCTAssertEqual(deepLabV3SegmentationHeight, categoryMask.height)
    let goldenMaskImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "segmentation_golden_rotation0",
        type: "png"))
    let pixelBuffer = goldenMaskImage.grayScalePixelBuffer().takeRetainedValue()
    CVPixelBufferLockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.readOnly)
    let pixelBufferBaseAddress = (try XCTUnwrap(CVPixelBufferGetBaseAddress(pixelBuffer)))
      .assumingMemoryBound(to: UInt8.self)
    let numPixels = deepLabV3SegmentationWidth * deepLabV3SegmentationHeight
    let mask = try XCTUnwrap(categoryMask.mask)
    var inconsistentPixels: Float = 0.0
    for i in 0..<numPixels {
      if mask[i] * kGoldenMaskMagnificationFactor != pixelBufferBaseAddress[i] {
        inconsistentPixels += 1
      }
    }
    CVPixelBufferUnlockBaseAddress(pixelBuffer, CVPixelBufferLockFlags.readOnly)
    XCTAssertLessThan(inconsistentPixels / Float(numPixels), kGoldenMaskTolerance)
  }
}


TFLObjectDetectorTests

class ObjectDetectorTests: XCTestCase {
  static let bundle = Bundle(for: ObjectDetectorTests.self)
  static let modelPath = bundle.path(
    forResource: "coco_ssd_mobilenet_v1_1.0_quant_2018_06_29",
    ofType: "tflite")
  func verifyDetectionResult(_ detectionResult: DetectionResult) {
    XCTAssertGreaterThan(detectionResult.detections.count, 0)
    self.verifyDetection(
      detectionResult.detections[0],
      expectedBoundingBox: CGRect(x: 54, y: 396, width: 393, height: 199),
      expectedFirstScore: 0.632812,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[1],
      expectedBoundingBox: CGRect(x: 602, y: 157, width: 394, height: 447),
      expectedFirstScore: 0.609375,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[2],
      expectedBoundingBox: CGRect(x: 260, y: 394, width: 179, height: 209),
      expectedFirstScore: 0.5625,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[3],
      expectedBoundingBox: CGRect(x: 387, y: 197, width: 281, height: 409),
      expectedFirstScore: 0.488281,
      expectedFirstLabel: "dog")
  }
  func verifyDetection(
    _ detection: Detection, expectedBoundingBox: CGRect,
    expectedFirstScore: Float,
    expectedFirstLabel: String
  ) {
    XCTAssertGreaterThan(detection.categories.count, 0)
    XCTAssertEqual(
      detection.boundingBox.origin.x,
      expectedBoundingBox.origin.x)
    XCTAssertEqual(
      detection.boundingBox.origin.y,
      expectedBoundingBox.origin.y)
    XCTAssertEqual(
      detection.boundingBox.size.width,
      expectedBoundingBox.size.width)
    XCTAssertEqual(
      detection.boundingBox.size.height,
      expectedBoundingBox.size.height)
    XCTAssertEqual(
      detection.categories[0].label,
      expectedFirstLabel)
    XCTAssertEqual(
      detection.categories[0].score,
      expectedFirstScore, accuracy: 0.001)
  }
  func testSuccessfullInferenceOnMLImageWithUIImage() throws {
    let modelPath = try XCTUnwrap(ObjectDetectorTests.modelPath)
    let objectDetectorOptions = ObjectDetectorOptions(modelPath: modelPath)
    let objectDetector =
      try ObjectDetector.detector(options: objectDetectorOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "cats_and_dogs",
        type: "jpg"))
    let detectionResults: DetectionResult =
      try objectDetector.detect(mlImage: gmlImage)
    self.verifyDetectionResult(detectionResults)
  }
  func testModelOptionsWithMaxResults() throws {
    let modelPath = try XCTUnwrap(ObjectDetectorTests.modelPath)
    let objectDetectorOptions = ObjectDetectorOptions(modelPath: modelPath)
    let maxResults = 3
    objectDetectorOptions.classificationOptions.maxResults = maxResults
    let objectDetector =
      try ObjectDetector.detector(options: objectDetectorOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "cats_and_dogs",
        type: "jpg"))
    let detectionResult: DetectionResult = try objectDetector.detect(
      mlImage: gmlImage)
    XCTAssertLessThanOrEqual(detectionResult.detections.count, maxResults)
    self.verifyDetection(
      detectionResult.detections[0],
      expectedBoundingBox: CGRect(x: 54, y: 396, width: 393, height: 199),
      expectedFirstScore: 0.632812,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[1],
      expectedBoundingBox: CGRect(x: 602, y: 157, width: 394, height: 447),
      expectedFirstScore: 0.609375,
      expectedFirstLabel: "cat")
    self.verifyDetection(
      detectionResult.detections[2],
      expectedBoundingBox: CGRect(x: 260, y: 394, width: 179, height: 209),
      expectedFirstScore: 0.5625,
      expectedFirstLabel: "cat")
  }
}


TFLImageClassifierTests

class ImageClassifierTests: XCTestCase {
  static let bundle = Bundle(for: ImageClassifierTests.self)
  static let modelPath = bundle.path(
    forResource: "mobilenet_v2_1.0_224",
    ofType: "tflite")
  func testSuccessfullInferenceOnMLImageWithUIImage() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "burger",
        type: "jpg"))
    let classificationResults: ClassificationResult =
      try imageClassifier.classify(mlImage: gmlImage)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertGreaterThan(classificationResults.classifications[0].categories.count, 0)
    // TODO: match the score as image_classifier_test.cc
    let category = classificationResults.classifications[0].categories[0]
    XCTAssertEqual(category.label, "cheeseburger")
    XCTAssertEqual(category.score, 0.748976, accuracy: 0.001)
  }
  func testModelOptionsWithMaxResults() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let maxResults = 3
    imageClassifierOptions.classificationOptions.maxResults = maxResults
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "burger",
        type: "jpg"))
    let classificationResults: ClassificationResult = try imageClassifier.classify(
      mlImage: gmlImage)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertLessThanOrEqual(classificationResults.classifications[0].categories.count, maxResults)
    // TODO: match the score as image_classifier_test.cc
    let category = classificationResults.classifications[0].categories[0]
    XCTAssertEqual(category.label, "cheeseburger")
    XCTAssertEqual(category.score, 0.748976, accuracy: 0.001)
  }
  func testInferenceWithBoundingBox() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "multi_objects",
        type: "jpg"))
    let roi = CGRect(x: 406, y: 110, width: 148, height: 153)
    let classificationResults =
      try imageClassifier.classify(mlImage: gmlImage, regionOfInterest: roi)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertGreaterThan(classificationResults.classifications[0].categories.count, 0)
    // TODO: match the label and score as image_classifier_test.cc
    // let category = classificationResults.classifications[0].categories[0]
    // XCTAssertEqual(category.label, "soccer ball")
    // XCTAssertEqual(category.score, 0.256512, accuracy:0.001);
  }
  func testInferenceWithRGBAImage() throws {
    let modelPath = try XCTUnwrap(ImageClassifierTests.modelPath)
    let imageClassifierOptions = ImageClassifierOptions(modelPath: modelPath)
    let imageClassifier =
      try ImageClassifier.classifier(options: imageClassifierOptions)
    let gmlImage = try XCTUnwrap(
      MLImage.imageFromBundle(
        class: type(of: self),
        filename: "sparrow",
        type: "png"))
    let classificationResults =
      try imageClassifier.classify(mlImage: gmlImage)
    XCTAssertNotNil(classificationResults)
    XCTAssertEqual(classificationResults.classifications.count, 1)
    XCTAssertGreaterThan(classificationResults.classifications[0].categories.count, 0)
    let category = classificationResults.classifications[0].categories[0]
    XCTAssertEqual(category.label, "junco")
    XCTAssertEqual(category.score, 0.253016, accuracy: 0.001)
  }
}


TFLNLClassifierTest

class TFLNLClassifierTest: XCTestCase {
  static let bundle = Bundle(for: TFLNLClassifierTest.self)
  static let modelPath = bundle.path(
    forResource: "test_model_nl_classifier_with_regex_tokenizer",
    ofType: "tflite")!
  var modelOptions:TFLNLClassifierOptions!;
  override func setUp() {
    modelOptions = TFLNLClassifierOptions()
    modelOptions.inputTensorName = "input_text"
    modelOptions.outputScoreTensorName = "probability"
  }
  func testClassifyPositiveResult() {
    let nlClassifier = TFLNLClassifier.nlClassifier(
      modelPath: TFLNLClassifierTest.modelPath,
      options: modelOptions)
    XCTAssertNotNil(nlClassifier)
    let categories = nlClassifier.classify(
      text: "This is the best movie I’ve seen in recent years. Strongly recommend it!")
    XCTAssertGreaterThan(categories["Positive"]!.doubleValue, categories["Negative"]!.doubleValue)
  }
   func testClassifyNegativeResult() {
     let nlClassifier = TFLNLClassifier.nlClassifier(
       modelPath: TFLNLClassifierTest.modelPath,
       options: modelOptions)
     XCTAssertNotNil(nlClassifier)
     let categories = nlClassifier.classify(text: "What a waste of my time.")
     XCTAssertGreaterThan(categories["Negative"]!.doubleValue, categories["Positive"]!.doubleValue)
   }
}


TFLBertNLClassifierTest

class TFLBertNLClassifierTest: XCTestCase {
  static let bundle = Bundle(for: TFLBertNLClassifierTest.self)
  static let bertModelPath = bundle.path(forResource: "bert_nl_classifier", ofType: "tflite")!
  func testClassifyPositiveResult() {
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "it's a charming and often affecting journey")
    XCTAssertGreaterThan(categories["positive"]!.doubleValue, categories["negative"]!.doubleValue)
  }
  func testClassifyNegativeResult() {
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "unflinchingly bleak and desperate")
    XCTAssertGreaterThan(categories["negative"]!.doubleValue, categories["positive"]!.doubleValue)
  }
  func testCreateFromOptionsClassifyPositiveResult() {
    let modelOptions = TFLBertNLClassifierOptions()
    modelOptions.maxSeqLen = 128
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath,
      options: modelOptions)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "it's a charming and often affecting journey")
    XCTAssertGreaterThan(categories["positive"]!.doubleValue, categories["negative"]!.doubleValue)
  }
  func testCreateFromOptionsClassifyNegativeResult() {
    let modelOptions = TFLBertNLClassifierOptions()
    modelOptions.maxSeqLen = 128
    let bertNLClassifier = TFLBertNLClassifier.bertNLClassifier(
      modelPath: TFLBertNLClassifierTest.bertModelPath,
      options: modelOptions)
    XCTAssertNotNil(bertNLClassifier)
    let categories = bertNLClassifier.classify(text: "unflinchingly bleak and desperate")
    XCTAssertGreaterThan(categories["negative"]!.doubleValue, categories["positive"]!.doubleValue)
  }
}


TFLBertQuestionAnswererTest

class TFLBertQuestionAnswererTest: XCTestCase {
  static let bundle = Bundle(for: TFLBertQuestionAnswererTest.self)
  static let mobileBertModelPath = bundle.path(forResource: "mobilebert_with_metadata", ofType: "tflite")!
  static let albertModelPath = bundle.path(forResource: "albert_with_metadata", ofType: "tflite")!
  static let context = """
    The role of teacher is often formal and ongoing, carried out at a school or other place of
    formal education. In many countries, a person who wishes to become a teacher must first obtain
     specified professional qualifications or credentials from a university or college. These
    professional qualifications may include the study of pedagogy, the science of teaching.
    Teachers, like other professionals, may have to continue their education after they qualify,
    a process known as continuing professional development. Teachers may use a lesson plan to
    facilitate student learning, providing a course of study which is called the curriculum.
    """
  static let question = "What is a course of study called?"
  static let answer = "the curriculum."
  func testInitMobileBert() {
    let mobileBertAnswerer = TFLBertQuestionAnswerer.questionAnswerer(
      modelPath: TFLBertQuestionAnswererTest.mobileBertModelPath)
    XCTAssertNotNil(mobileBertAnswerer)
    let answers = mobileBertAnswerer.answer(
      context: TFLBertQuestionAnswererTest.context, question: TFLBertQuestionAnswererTest.question)
    XCTAssertNotNil(answers)
    XCTAssertEqual(answers[0].text, TFLBertQuestionAnswererTest.answer)
  }
  func testInitAlbert() {
    let albertAnswerer = TFLBertQuestionAnswerer.questionAnswerer(
      modelPath: TFLBertQuestionAnswererTest.albertModelPath)
    XCTAssertNotNil(albertAnswerer)
    let answers = albertAnswerer.answer(
      context: TFLBertQuestionAnswererTest.context, question: TFLBertQuestionAnswererTest.question)
    XCTAssertNotNil(answers)
    XCTAssertEqual(answers[0].text, TFLBertQuestionAnswererTest.answer)
  }
}


s

infix operator •: AdditionPrecedence
func • (a: Int, b: Int) -> Int {
  return a * b
}
func g(a: Int) -> Int{
  return a + 1
}
let i = g(a: 1 • 2)


import Swift

var s: [Int] = [1, 2, 3, 4]

func f() {
  for i in 0..<4 {
    print(s[i])
  }
}

f()


import NIOHTTP1
import NIO
public func test(_ start: UnsafeRawPointer, _ count: Int) -> CInt {
    let bytes = UnsafeRawBufferPointer(start: start, count: count)
    let channel = EmbeddedChannel()
    var buffer = channel.allocator.buffer(capacity: count)
    buffer.writeBytes(bytes)
    do {
        try channel.pipeline.addHandler(ByteToMessageHandler(HTTPRequestDecoder())).wait()
        try channel.writeInbound(buffer)
        channel.embeddedEventLoop.run()
    } catch {
    }
    do {
        try channel.finish(acceptAlreadyClosed: true)
    } catch {
    }
    return 0
}


Package

// swift-tools-version:5.3
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
    name: "swift-nio-fuzz",
    dependencies: [
        // Dependencies declare other packages that this package depends on.
        .package(name: "swift-nio", path: ".."),
    ],
    targets: [
        // Targets are the basic building blocks of a package. A target can define a module or a test suite.
        // Targets can depend on other targets in this package, and on products in packages this package depends on.
        .target(
            name: "swift-nio-http1-fuzz",
            dependencies: [.product(name: "NIOHTTP1", package: "swift-nio")]),
    ]
)


CoreMLDelegate

import TensorFlowLiteCCoreML
/// A delegate that uses the `Core ML` framework for performing TensorFlow Lite graph operations.
///
/// - Important: This is an experimental interface that is subject to change.
public final class CoreMLDelegate: Delegate {
  /// The configuration options for the `CoreMLDelegate`.
  public let options: Options
  // Conformance to the `Delegate` protocol.
  public private(set) var cDelegate: CDelegate
  /// Creates a new instance configured with the given `options`. Returns `nil` if the underlying
  /// Core ML delegate could not be created because `Options.enabledDevices` was set to
  /// `neuralEngine` but the device does not have the Neural Engine.
  ///
  /// - Parameters:
  ///   - options: Configurations for the delegate. The default is a new instance of
  ///       `CoreMLDelegate.Options` with the default configuration values.
  public init?(options: Options = Options()) {
    self.options = options
    var delegateOptions = TfLiteCoreMlDelegateOptions()
    delegateOptions.enabled_devices = options.enabledDevices.cEnabledDevices
    delegateOptions.coreml_version = Int32(options.coreMLVersion)
    delegateOptions.max_delegated_partitions = Int32(options.maxDelegatedPartitions)
    delegateOptions.min_nodes_per_partition = Int32(options.minNodesPerPartition)
    guard let delegate = TfLiteCoreMlDelegateCreate(&delegateOptions) else { return nil }
    cDelegate = delegate
  }
  deinit {
    TfLiteCoreMlDelegateDelete(cDelegate)
  }
}
extension CoreMLDelegate {
  /// A type indicating which devices the Core ML delegate should be enabled for.
  public enum EnabledDevices: Equatable, Hashable {
    /// Enables the delegate for devices with Neural Engine only.
    case neuralEngine
    /// Enables the delegate for all devices.
    case all
    /// The C `TfLiteCoreMlDelegateEnabledDevices` for the current `EnabledDevices`.
    var cEnabledDevices: TfLiteCoreMlDelegateEnabledDevices {
      switch self {
      case .neuralEngine:
        return TfLiteCoreMlDelegateDevicesWithNeuralEngine
      case .all:
        return TfLiteCoreMlDelegateAllDevices
      }
    }
  }
  /// Options for configuring the `CoreMLDelegate`.
  // TODO(b/143931022): Add preferred device support.
  public struct Options: Equatable, Hashable {
    /// A type indicating which devices the Core ML delegate should be enabled for. The default
    /// value is `.neuralEngine` indicating that the delegate is enabled for Neural Engine devices
    /// only.
    public var enabledDevices: EnabledDevices = .neuralEngine
    /// Target Core ML version for the model conversion. When it's not set, Core ML version will
    /// be set to highest available version for the platform.
    public var coreMLVersion = 0
    /// The maximum number of Core ML delegate partitions created. Each graph corresponds to one
    /// delegated node subset in the TFLite model. The default value is `0` indicating that all
    /// possible partitions are delegated.
    public var maxDelegatedPartitions = 0
    /// The minimum number of nodes per partition to be delegated by the Core ML delegate. The
    /// default value is `2`.
    public var minNodesPerPartition = 2
    /// Creates a new instance with the default values.
    public init() {}
  }
}


TensorFlowLite

import TensorFlowLiteC
/// TensorFlow Lite runtime values.
public enum Runtime {
  /// A string describing the semantic versioning information for the runtime. Is an empty string if
  /// the version could not be determined.
  public static var version: String { return TfLiteVersion().map(String.init) ?? "" }
}


Model

import TensorFlowLiteC
/// A TensorFlow Lite model used by the `Interpreter` to perform inference.
final class Model {
  /// The `TfLiteModel` C pointer type represented as an `UnsafePointer<TfLiteModel>`.
  typealias CModel = OpaquePointer
  /// The underlying `TfLiteModel` C pointer.
  let cModel: CModel?
  /// Creates a new instance with the given `filePath`.
  ///
  /// - Precondition: Initialization can fail if the given `filePath` is invalid.
  /// - Parameters:
  ///   - filePath: The local file path to a TensorFlow Lite model.
  init?(filePath: String) {
    guard !filePath.isEmpty, let cModel = TfLiteModelCreateFromFile(filePath) else { return nil }
    self.cModel = cModel
  }
  deinit {
    TfLiteModelDelete(cModel)
  }
}


Delegate

import TensorFlowLiteC
/// A delegate that the `Interpreter` uses to perform TensorFlow Lite model computations.
public protocol Delegate: AnyObject {
  /// The `TfLiteDelegate` C pointer type.
  typealias CDelegate = UnsafeMutablePointer<TfLiteDelegate>
  /// The delegate that performs model computations.
  var cDelegate: CDelegate { get }
}


InterpreterError

import Foundation
/// Errors thrown by the TensorFlow Lite `Interpreter`.
public enum InterpreterError: Error, Equatable, Hashable {
  case invalidTensorIndex(index: Int, maxIndex: Int)
  case invalidTensorDataCount(provided: Int, required: Int)
  case invalidTensorDataType
  case failedToLoadModel
  case failedToCreateInterpreter
  case failedToResizeInputTensor(index: Int)
  case failedToCopyDataToInputTensor
  case failedToAllocateTensors
  case allocateTensorsRequired
  case invokeInterpreterRequired
  case tensorFlowLiteError(String)
}
extension InterpreterError: LocalizedError {
  /// A localized description of the interpreter error.
  public var errorDescription: String? {
    switch self {
    case .invalidTensorIndex(let index, let maxIndex):
      return "Invalid tensor index \(index), max index is \(maxIndex)."
    case .invalidTensorDataCount(let provided, let required):
      return "Provided data count \(provided) must match the required count \(required)."
    case .invalidTensorDataType:
      return "Tensor data type is unsupported or could not be determined due to a model error."
    case .failedToLoadModel:
      return "Failed to load the given model."
    case .failedToCreateInterpreter:
      return "Failed to create the interpreter."
    case .failedToResizeInputTensor(let index):
      return "Failed to resize input tensor at index \(index)."
    case .failedToCopyDataToInputTensor:
      return "Failed to copy data to input tensor."
    case .failedToAllocateTensors:
      return "Failed to allocate memory for input tensors."
    case .allocateTensorsRequired:
      return "Must call allocateTensors()."
    case .invokeInterpreterRequired:
      return "Must call invoke()."
    case .tensorFlowLiteError(let message):
      return "TensorFlow Lite Error: \(message)"
    }
  }
}
extension InterpreterError: CustomStringConvertible {
  /// A textual representation of the TensorFlow Lite interpreter error.
  public var description: String { return errorDescription ?? "Unknown error." }
}


MetalDelegate

import TensorFlowLiteCMetal
/// A delegate that uses the `Metal` framework for performing TensorFlow Lite graph operations with
/// GPU acceleration.
///
/// - Important: This is an experimental interface that is subject to change.
public final class MetalDelegate: Delegate {
  /// The configuration options for the `MetalDelegate`.
  public let options: Options
  // Conformance to the `Delegate` protocol.
  public private(set) var cDelegate: CDelegate
  /// Creates a new instance configured with the given `options`.
  ///
  /// - Parameters:
  ///   - options: Configurations for the delegate. The default is a new instance of
  ///       `MetalDelegate.Options` with the default configuration values.
  public init(options: Options = Options()) {
    self.options = options
    var delegateOptions = TFLGpuDelegateOptions()
    delegateOptions.allow_precision_loss = options.isPrecisionLossAllowed
    delegateOptions.wait_type = options.waitType.cWaitType
    delegateOptions.enable_quantization = options.isQuantizationEnabled
    cDelegate = TFLGpuDelegateCreate(&delegateOptions)
  }
  deinit {
    TFLGpuDelegateDelete(cDelegate)
  }
}
extension MetalDelegate {
  /// Options for configuring the `MetalDelegate`.
  public struct Options: Equatable, Hashable {
    /// Indicates whether the GPU delegate allows precision loss, such as allowing `Float16`
    /// precision for a `Float32` computation. The default is `false`.
    public var isPrecisionLossAllowed = false
      *, deprecated, message: "Deprecated since TensorFlow Lite 2.4",
      renamed: "isPrecisionLossAllowed"
    )
    public var allowsPrecisionLoss: Bool {
      get { return isPrecisionLossAllowed }
      set(value) { isPrecisionLossAllowed = value }
    }
    /// A type indicating how the current thread should wait for work on the GPU to complete. The
    /// default is `passive`.
    public var waitType: ThreadWaitType = .passive
    /// Indicates whether the GPU delegate allows execution of an 8-bit quantized model. The default
    /// is `true`.
    public var isQuantizationEnabled = true
    /// Creates a new instance with the default values.
    public init() {}
  }
}
/// A type indicating how the current thread should wait for work scheduled on the GPU to complete.
public enum ThreadWaitType: Equatable, Hashable {
  /// The thread does not wait for the work to complete. Useful when the output of the work is used
  /// with the GPU pipeline.
  case none
  /// The thread waits until the work is complete.
  case passive
  /// The thread waits for the work to complete with minimal latency, which may require additional
  /// CPU resources.
  case active
  /// The thread waits for the work while trying to prevent the GPU from going into sleep mode.
  case aggressive
  /// The C `TFLGpuDelegateWaitType` for the current `ThreadWaitType`.
  var cWaitType: TFLGpuDelegateWaitType {
    switch self {
    case .none:
      return TFLGpuDelegateWaitTypeDoNotWait
    case .passive:
      return TFLGpuDelegateWaitTypePassive
    case .active:
      return TFLGpuDelegateWaitTypeActive
    case .aggressive:
      return TFLGpuDelegateWaitTypeAggressive
    }
  }
}


QuantizationParameters

/// Parameters that determine the mapping of quantized values to real values. Quantized values can
/// be mapped to float values using the following conversion:
/// `realValue = scale * (quantizedValue - zeroPoint)`.
public struct QuantizationParameters: Equatable, Hashable {
  /// The difference between real values corresponding to consecutive quantized values differing by
  /// 1. For example, the range of quantized values for `UInt8` data type is [0, 255].
  public let scale: Float
  /// The quantized value that corresponds to the real 0 value.
  public let zeroPoint: Int
  /// Creates a new instance with the given values.
  ///
  /// - Parameters:
  ///   - scale: The scale value for asymmetric quantization.
  ///   - zeroPoint: The zero point for asymmetric quantization.
  init(scale: Float, zeroPoint: Int) {
    self.scale = scale
    self.zeroPoint = zeroPoint
  }
}


SignatureRunnerError

import Foundation
/// Errors thrown by the TensorFlow Lite `SignatureRunner`.
public enum SignatureRunnerError: Error, Equatable, Hashable {
  case invalidTensorDataCount(provided: Int, required: Int)
  case invalidTensorDataType
  case failedToCreateSignatureRunner(signatureKey: String)
  case failedToGetTensor(tensorType: String, nameInSignature: String)
  case failedToResizeInputTensor(inputName: String)
  case failedToCopyDataToInputTensor
  case failedToAllocateTensors
  case failedToInvokeSignature(signatureKey: String)
  case allocateTensorsRequired
}
extension SignatureRunnerError: LocalizedError {
  /// A localized description of the signature runner error.
  public var errorDescription: String? {
    switch self {
    case .invalidTensorDataCount(let provided, let required):
      return "Provided data count \(provided) must match the required count \(required)."
    case .invalidTensorDataType:
      return "Tensor data type is unsupported or could not be determined due to a model error."
    case .failedToCreateSignatureRunner(let signatureKey):
      return "Failed to create a signature runner. Signature with key (\(signatureKey)) not found."
    case .failedToGetTensor(let tensorType, let nameInSignature):
      return "Failed to get \(tensorType) tensor with \(tensorType) name (\(nameInSignature))."
    case .failedToResizeInputTensor(let inputName):
      return "Failed to resize input tensor with input name (\(inputName))."
    case .failedToCopyDataToInputTensor:
      return "Failed to copy data to input tensor."
    case .failedToAllocateTensors:
      return "Failed to allocate memory for input tensors."
    case .failedToInvokeSignature(let signatureKey):
      return "Failed to invoke the signature runner with key (\(signatureKey))."
    case .allocateTensorsRequired:
      return "Must call allocateTensors()."
    }
  }
}
extension SignatureRunnerError: CustomStringConvertible {
  /// A textual representation of the TensorFlow Lite signature runner error.
  public var description: String { return errorDescription ?? "Unknown error." }
}