// -*- mode: Swift -*-

// AUTOGENERATED BY glean_parser v8.1.1. DO NOT EDIT. DO NOT COMMIT.

#if canImport(Foundation)
    import Foundation
#endif

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


import Glean

// swiftlint:disable superfluous_disable_command
// swiftlint:disable nesting
// swiftlint:disable line_length
// swiftlint:disable identifier_name
// swiftlint:disable force_try

extension GleanMetrics {
    class GleanBuild {
        private init() {
            // Intentionally left private, no external user can instantiate a new global object.
        }

        public static let info = BuildInfo(buildDate: DateComponents(calendar: Calendar.current, timeZone: TimeZone(abbreviation: "UTC"), year: 2023, month: 9, day: 25, hour: 14, minute: 22, second: 46))
    }

    enum NimbusEvents {
        struct DisqualificationExtra: EventExtras {
            var branch: String?
            var enrollmentId: String?
            var experiment: String?

            func toExtraRecord() -> [String: String] {
                var record = [String: String]()

                if let branch = self.branch {
                    record["branch"] = String(branch)
                }
                if let enrollmentId = self.enrollmentId {
                    record["enrollment_id"] = String(enrollmentId)
                }
                if let experiment = self.experiment {
                    record["experiment"] = String(experiment)
                }

                return record
            }
        }

        struct EnrollFailedExtra: EventExtras {
            var branch: String?
            var experiment: String?
            var reason: String?

            func toExtraRecord() -> [String: String] {
                var record = [String: String]()

                if let branch = self.branch {
                    record["branch"] = String(branch)
                }
                if let experiment = self.experiment {
                    record["experiment"] = String(experiment)
                }
                if let reason = self.reason {
                    record["reason"] = String(reason)
                }

                return record
            }
        }

        struct EnrollmentExtra: EventExtras {
            var branch: String?
            var enrollmentId: String?
            var experiment: String?
            var experimentType: String?

            func toExtraRecord() -> [String: String] {
                var record = [String: String]()

                if let branch = self.branch {
                    record["branch"] = String(branch)
                }
                if let enrollmentId = self.enrollmentId {
                    record["enrollment_id"] = String(enrollmentId)
                }
                if let experiment = self.experiment {
                    record["experiment"] = String(experiment)
                }
                if let experimentType = self.experimentType {
                    record["experiment_type"] = String(experimentType)
                }

                return record
            }
        }

        struct ExposureExtra: EventExtras {
            var branch: String?
            var experiment: String?
            var featureId: String?

            func toExtraRecord() -> [String: String] {
                var record = [String: String]()

                if let branch = self.branch {
                    record["branch"] = String(branch)
                }
                if let experiment = self.experiment {
                    record["experiment"] = String(experiment)
                }
                if let featureId = self.featureId {
                    record["feature_id"] = String(featureId)
                }

                return record
            }
        }

        struct MalformedFeatureExtra: EventExtras {
            var branch: String?
            var experiment: String?
            var featureId: String?
            var partId: String?

            func toExtraRecord() -> [String: String] {
                var record = [String: String]()

                if let branch = self.branch {
                    record["branch"] = String(branch)
                }
                if let experiment = self.experiment {
                    record["experiment"] = String(experiment)
                }
                if let featureId = self.featureId {
                    record["feature_id"] = String(featureId)
                }
                if let partId = self.partId {
                    record["part_id"] = String(partId)
                }

                return record
            }
        }

        struct UnenrollFailedExtra: EventExtras {
            var experiment: String?
            var reason: String?

            func toExtraRecord() -> [String: String] {
                var record = [String: String]()

                if let experiment = self.experiment {
                    record["experiment"] = String(experiment)
                }
                if let reason = self.reason {
                    record["reason"] = String(reason)
                }

                return record
            }
        }

        struct UnenrollmentExtra: EventExtras {
            var branch: String?
            var enrollmentId: String?
            var experiment: String?
            var reason: String?

            func toExtraRecord() -> [String: String] {
                var record = [String: String]()

                if let branch = self.branch {
                    record["branch"] = String(branch)
                }
                if let enrollmentId = self.enrollmentId {
                    record["enrollment_id"] = String(enrollmentId)
                }
                if let experiment = self.experiment {
                    record["experiment"] = String(experiment)
                }
                if let reason = self.reason {
                    record["reason"] = String(reason)
                }

                return record
            }
        }

        /// Recorded when a user becomes ineligible to continue receiving the treatment for
        /// an enrolled experiment, for reasons such as the user opting out of the
        /// experiment or no longer matching targeting for the experiment.
        static let disqualification = EventMetricType<DisqualificationExtra>( // generated from nimbus_events.disqualification
            CommonMetricData(
                category: "nimbus_events",
                name: "disqualification",
                sendInPings: ["events"],
                lifetime: .ping,
                disabled: false
            )
            , ["branch", "enrollment_id", "experiment"]
        )

        /// Recorded when an enrollment fails, including the reason for the failure.
        static let enrollFailed = EventMetricType<EnrollFailedExtra>( // generated from nimbus_events.enroll_failed
            CommonMetricData(
                category: "nimbus_events",
                name: "enroll_failed",
                sendInPings: ["background-update", "events"],
                lifetime: .ping,
                disabled: false
            )
            , ["branch", "experiment", "reason"]
        )

        /// Recorded when a user has met the conditions and is first bucketed into an
        /// experiment (i.e. targeting matched and they were randomized into a bucket and
        /// branch of the experiment). Expected a maximum of once per experiment per user.
        static let enrollment = EventMetricType<EnrollmentExtra>( // generated from nimbus_events.enrollment
            CommonMetricData(
                category: "nimbus_events",
                name: "enrollment",
                sendInPings: ["events"],
                lifetime: .ping,
                disabled: false
            )
            , ["branch", "enrollment_id", "experiment", "experiment_type"]
        )

        /// Recorded when a user actually observes an experimental treatment, or would have
        /// observed an experimental treatment if they had been in a branch that would have
        /// shown one.
        static let exposure = EventMetricType<ExposureExtra>( // generated from nimbus_events.exposure
            CommonMetricData(
                category: "nimbus_events",
                name: "exposure",
                sendInPings: ["events"],
                lifetime: .ping,
                disabled: false
            )
            , ["branch", "experiment", "feature_id"]
        )

        /// Recorded when feature code detects a problem with some part of the feature
        /// configuration.
        static let malformedFeature = EventMetricType<MalformedFeatureExtra>( // generated from nimbus_events.malformed_feature
            CommonMetricData(
                category: "nimbus_events",
                name: "malformed_feature",
                sendInPings: ["events"],
                lifetime: .ping,
                disabled: false
            )
            , ["branch", "experiment", "feature_id", "part_id"]
        )

        /// Recorded when an unenrollment fails, including the reason for the failure.
        static let unenrollFailed = EventMetricType<UnenrollFailedExtra>( // generated from nimbus_events.unenroll_failed
            CommonMetricData(
                category: "nimbus_events",
                name: "unenroll_failed",
                sendInPings: ["background-update", "events"],
                lifetime: .ping,
                disabled: false
            )
            , ["experiment", "reason"]
        )

        /// Recorded when either telemetry is disabled, or the experiment has run for its
        /// designed duration (i.e. it is no longer present in the Nimbus Remote Settings
        /// collection)
        static let unenrollment = EventMetricType<UnenrollmentExtra>( // generated from nimbus_events.unenrollment
            CommonMetricData(
                category: "nimbus_events",
                name: "unenrollment",
                sendInPings: ["events"],
                lifetime: .ping,
                disabled: false
            )
            , ["branch", "enrollment_id", "experiment", "reason"]
        )

    }

    enum NimbusHealth {
        struct CacheNotReadyForFeatureExtra: EventExtras {
            var featureId: String?

            func toExtraRecord() -> [String: String] {
                var record = [String: String]()

                if let featureId = self.featureId {
                    record["feature_id"] = String(featureId)
                }

                return record
            }
        }

        /// Measure how long `applyPendingExperiments` takes.
        /// `applyPendingExperiments` uses disk I/O, and happens at
        /// startup, as part of the initialization sequence.
        static let applyPendingExperimentsTime = TimingDistributionMetricType( // generated from nimbus_health.apply_pending_experiments_time
            CommonMetricData(
                category: "nimbus_health",
                name: "apply_pending_experiments_time",
                sendInPings: ["metrics"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        /// Recorded when an application or library requests a feature configuration before
        /// the in memory cache has been populated from the database
        static let cacheNotReadyForFeature = EventMetricType<CacheNotReadyForFeatureExtra>( // generated from nimbus_health.cache_not_ready_for_feature
            CommonMetricData(
                category: "nimbus_health",
                name: "cache_not_ready_for_feature",
                sendInPings: ["events"],
                lifetime: .ping,
                disabled: true
            )
            , ["feature_id"]
        )

        /// Measures how long `fetchExperiments` takes.
        static let fetchExperimentsTime = TimingDistributionMetricType( // generated from nimbus_health.fetch_experiments_time
            CommonMetricData(
                category: "nimbus_health",
                name: "fetch_experiments_time",
                sendInPings: ["metrics"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

    }

    enum AddressesSyncV2 {
        private static let failureReasonLabel = StringMetricType( // generated from addresses_sync_v2.failure_reason
            CommonMetricData(
                category: "addresses_sync_v2",
                name: "failure_reason",
                sendInPings: ["addresses-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records why the addresses sync failed: either due to an authentication error,
        /// unexpected exception, or other error. The error strings are truncated and
        /// sanitized to omit PII, like URLs and file system paths.
        static let failureReason = try! LabeledMetricType<StringMetricType>( // generated from addresses_sync_v2.failure_reason
            category: "addresses_sync_v2",
            name: "failure_reason",
            sendInPings: ["addresses-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: failureReasonLabel,
            labels: ["auth", "other", "unexpected"]
        )

        /// Records when the addresses sync finished. This includes the time to download,
        /// apply, and upload all records.
        static let finishedAt = DatetimeMetricType( // generated from addresses_sync_v2.finished_at
            CommonMetricData(
                category: "addresses_sync_v2",
                name: "finished_at",
                sendInPings: ["addresses-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        private static let incomingLabel = CounterMetricType( // generated from addresses_sync_v2.incoming
            CommonMetricData(
                category: "addresses_sync_v2",
                name: "incoming",
                sendInPings: ["addresses-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records incoming addresses record counts. `applied` is the number of incoming
        /// records that were successfully stored or updated in the local database.
        /// `failed_to_apply` is the number of records that were ignored due to errors.
        /// `reconciled` is the number of merged records.
        static let incoming = try! LabeledMetricType<CounterMetricType>( // generated from addresses_sync_v2.incoming
            category: "addresses_sync_v2",
            name: "incoming",
            sendInPings: ["addresses-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: incomingLabel,
            labels: ["applied", "failed_to_apply", "reconciled"]
        )

        private static let outgoingLabel = CounterMetricType( // generated from addresses_sync_v2.outgoing
            CommonMetricData(
                category: "addresses_sync_v2",
                name: "outgoing",
                sendInPings: ["addresses-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records outgoing addresses record counts. `uploaded` is the number of records
        /// that were successfully sent to the server. `failed_to_upload` is the number of
        /// records that weren't uploaded, and will be retried on the next sync.
        static let outgoing = try! LabeledMetricType<CounterMetricType>( // generated from addresses_sync_v2.outgoing
            category: "addresses_sync_v2",
            name: "outgoing",
            sendInPings: ["addresses-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: outgoingLabel,
            labels: ["failed_to_upload", "uploaded"]
        )

        /// Records the number of batches needed to upload all outgoing records. The Sync
        /// server has a hard limit on the number of records (and request body bytes) on
        /// the number of records that can fit into a single batch, and large syncs may
        /// require multiple batches.
        static let outgoingBatches = CounterMetricType( // generated from addresses_sync_v2.outgoing_batches
            CommonMetricData(
                category: "addresses_sync_v2",
                name: "outgoing_batches",
                sendInPings: ["addresses-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records when the addresses sync started.
        static let startedAt = DatetimeMetricType( // generated from addresses_sync_v2.started_at
            CommonMetricData(
                category: "addresses_sync_v2",
                name: "started_at",
                sendInPings: ["addresses-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        /// The user's hashed Firefox Account ID.
        static let uid = StringMetricType( // generated from addresses_sync_v2.uid
            CommonMetricData(
                category: "addresses_sync_v2",
                name: "uid",
                sendInPings: ["addresses-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

    }

    enum BookmarksSyncV2 {
        private static let failureReasonLabel = StringMetricType( // generated from bookmarks_sync_v2.failure_reason
            CommonMetricData(
                category: "bookmarks_sync_v2",
                name: "failure_reason",
                sendInPings: ["bookmarks-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records bookmark sync failure reasons.
        static let failureReason = try! LabeledMetricType<StringMetricType>( // generated from bookmarks_sync_v2.failure_reason
            category: "bookmarks_sync_v2",
            name: "failure_reason",
            sendInPings: ["bookmarks-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: failureReasonLabel,
            labels: ["auth", "other", "unexpected"]
        )

        /// Records when the bookmark sync finished.
        static let finishedAt = DatetimeMetricType( // generated from bookmarks_sync_v2.finished_at
            CommonMetricData(
                category: "bookmarks_sync_v2",
                name: "finished_at",
                sendInPings: ["bookmarks-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        private static let incomingLabel = CounterMetricType( // generated from bookmarks_sync_v2.incoming
            CommonMetricData(
                category: "bookmarks_sync_v2",
                name: "incoming",
                sendInPings: ["bookmarks-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records incoming bookmark record counts.
        static let incoming = try! LabeledMetricType<CounterMetricType>( // generated from bookmarks_sync_v2.incoming
            category: "bookmarks_sync_v2",
            name: "incoming",
            sendInPings: ["bookmarks-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: incomingLabel,
            labels: ["applied", "failed_to_apply", "reconciled"]
        )

        private static let outgoingLabel = CounterMetricType( // generated from bookmarks_sync_v2.outgoing
            CommonMetricData(
                category: "bookmarks_sync_v2",
                name: "outgoing",
                sendInPings: ["bookmarks-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records outgoing bookmark record counts.
        static let outgoing = try! LabeledMetricType<CounterMetricType>( // generated from bookmarks_sync_v2.outgoing
            category: "bookmarks_sync_v2",
            name: "outgoing",
            sendInPings: ["bookmarks-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: outgoingLabel,
            labels: ["failed_to_upload", "uploaded"]
        )

        /// Records the number of batches needed to upload all outgoing records.
        static let outgoingBatches = CounterMetricType( // generated from bookmarks_sync_v2.outgoing_batches
            CommonMetricData(
                category: "bookmarks_sync_v2",
                name: "outgoing_batches",
                sendInPings: ["bookmarks-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        private static let remoteTreeProblemsLabel = CounterMetricType( // generated from bookmarks_sync_v2.remote_tree_problems
            CommonMetricData(
                category: "bookmarks_sync_v2",
                name: "remote_tree_problems",
                sendInPings: ["bookmarks-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records counts for structure problems and divergences in the remote bookmarks
        /// tree. These are documented in https://github.com/mozilla/dogear/blob/fbade15f2a
        /// 4f11215e30b8f428a0a8df3defeaec/src/tree.rs#L1273-L1294.
        static let remoteTreeProblems = try! LabeledMetricType<CounterMetricType>( // generated from bookmarks_sync_v2.remote_tree_problems
            category: "bookmarks_sync_v2",
            name: "remote_tree_problems",
            sendInPings: ["bookmarks-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: remoteTreeProblemsLabel,
            labels: ["misparented_roots", "missing_children", "missing_parent_guids", "multiple_parents_by_children", "non_folder_parent_guids", "orphans", "parent_child_disagreements"]
        )

        /// Records when the bookmark sync started.
        static let startedAt = DatetimeMetricType( // generated from bookmarks_sync_v2.started_at
            CommonMetricData(
                category: "bookmarks_sync_v2",
                name: "started_at",
                sendInPings: ["bookmarks-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        /// The user's hashed Firefox Account ID.
        static let uid = StringMetricType( // generated from bookmarks_sync_v2.uid
            CommonMetricData(
                category: "bookmarks_sync_v2",
                name: "uid",
                sendInPings: ["bookmarks-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

    }

    enum CreditcardsSyncV2 {
        private static let failureReasonLabel = StringMetricType( // generated from creditcards_sync_v2.failure_reason
            CommonMetricData(
                category: "creditcards_sync_v2",
                name: "failure_reason",
                sendInPings: ["creditcards-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records why the credit cards sync failed: either due to an authentication
        /// error, unexpected exception, or other error. The error strings are truncated
        /// and sanitized to omit PII, like URLs and file system paths.
        static let failureReason = try! LabeledMetricType<StringMetricType>( // generated from creditcards_sync_v2.failure_reason
            category: "creditcards_sync_v2",
            name: "failure_reason",
            sendInPings: ["creditcards-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: failureReasonLabel,
            labels: ["auth", "other", "unexpected"]
        )

        /// Records when the credit cards sync finished. This includes the time to
        /// download, apply, and upload all records.
        static let finishedAt = DatetimeMetricType( // generated from creditcards_sync_v2.finished_at
            CommonMetricData(
                category: "creditcards_sync_v2",
                name: "finished_at",
                sendInPings: ["creditcards-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        private static let incomingLabel = CounterMetricType( // generated from creditcards_sync_v2.incoming
            CommonMetricData(
                category: "creditcards_sync_v2",
                name: "incoming",
                sendInPings: ["creditcards-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records incoming credit cards record counts. `applied` is the number of
        /// incoming records that were successfully stored or updated in the local
        /// database. `failed_to_apply` is the number of records that were ignored due to
        /// errors. `reconciled` is the number of merged records.
        static let incoming = try! LabeledMetricType<CounterMetricType>( // generated from creditcards_sync_v2.incoming
            category: "creditcards_sync_v2",
            name: "incoming",
            sendInPings: ["creditcards-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: incomingLabel,
            labels: ["applied", "failed_to_apply", "reconciled"]
        )

        private static let outgoingLabel = CounterMetricType( // generated from creditcards_sync_v2.outgoing
            CommonMetricData(
                category: "creditcards_sync_v2",
                name: "outgoing",
                sendInPings: ["creditcards-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records outgoing credit cards record counts. `uploaded` is the number of
        /// records that were successfully sent to the server. `failed_to_upload` is the
        /// number of records that weren't uploaded, and will be retried on the next sync.
        static let outgoing = try! LabeledMetricType<CounterMetricType>( // generated from creditcards_sync_v2.outgoing
            category: "creditcards_sync_v2",
            name: "outgoing",
            sendInPings: ["creditcards-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: outgoingLabel,
            labels: ["failed_to_upload", "uploaded"]
        )

        /// Records the number of batches needed to upload all outgoing records. The Sync
        /// server has a hard limit on the number of records (and request body bytes) on
        /// the number of records that can fit into a single batch, and large syncs may
        /// require multiple batches.
        static let outgoingBatches = CounterMetricType( // generated from creditcards_sync_v2.outgoing_batches
            CommonMetricData(
                category: "creditcards_sync_v2",
                name: "outgoing_batches",
                sendInPings: ["creditcards-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records when the credit cards sync started.
        static let startedAt = DatetimeMetricType( // generated from creditcards_sync_v2.started_at
            CommonMetricData(
                category: "creditcards_sync_v2",
                name: "started_at",
                sendInPings: ["creditcards-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        /// The user's hashed Firefox Account ID.
        static let uid = StringMetricType( // generated from creditcards_sync_v2.uid
            CommonMetricData(
                category: "creditcards_sync_v2",
                name: "uid",
                sendInPings: ["creditcards-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

    }

    enum FxaTabV2 {
        struct ReceivedExtra: EventExtras {
            var flowId: String?
            var reason: String?
            var streamId: String?

            func toExtraRecord() -> [String: String] {
                var record = [String: String]()

                if let flowId = self.flowId {
                    record["flow_id"] = String(flowId)
                }
                if let reason = self.reason {
                    record["reason"] = String(reason)
                }
                if let streamId = self.streamId {
                    record["stream_id"] = String(streamId)
                }

                return record
            }
        }

        struct SentExtra: EventExtras {
            var flowId: String?
            var streamId: String?

            func toExtraRecord() -> [String: String] {
                var record = [String: String]()

                if let flowId = self.flowId {
                    record["flow_id"] = String(flowId)
                }
                if let streamId = self.streamId {
                    record["stream_id"] = String(streamId)
                }

                return record
            }
        }

        /// Recorded when a tab is received.  Also sent by desktop - see also the docs at
        /// https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/data/sync-
        /// ping.html
        static let received = EventMetricType<ReceivedExtra>( // generated from fxa_tab_v2.received
            CommonMetricData(
                category: "fxa_tab_v2",
                name: "received",
                sendInPings: ["sync"],
                lifetime: .ping,
                disabled: false
            )
            , ["flow_id", "reason", "stream_id"]
        )

        /// Recorded when a tab is sent. Also sent by desktop - see also the docs at
        /// https://firefox-source-docs.mozilla.org/toolkit/components/telemetry/data/sync-
        /// ping.html
        static let sent = EventMetricType<SentExtra>( // generated from fxa_tab_v2.sent
            CommonMetricData(
                category: "fxa_tab_v2",
                name: "sent",
                sendInPings: ["sync"],
                lifetime: .ping,
                disabled: false
            )
            , ["flow_id", "stream_id"]
        )

    }

    enum HistorySyncV2 {
        private static let failureReasonLabel = StringMetricType( // generated from history_sync_v2.failure_reason
            CommonMetricData(
                category: "history_sync_v2",
                name: "failure_reason",
                sendInPings: ["history-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records why the history sync failed: either due to an authentication error,
        /// unexpected exception, or other error. The error strings are truncated and
        /// sanitized to omit PII, like URLs and file system paths.
        static let failureReason = try! LabeledMetricType<StringMetricType>( // generated from history_sync_v2.failure_reason
            category: "history_sync_v2",
            name: "failure_reason",
            sendInPings: ["history-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: failureReasonLabel,
            labels: ["auth", "other", "unexpected"]
        )

        /// Records when the history sync finished. This includes the time to download,
        /// apply, and upload all records.
        static let finishedAt = DatetimeMetricType( // generated from history_sync_v2.finished_at
            CommonMetricData(
                category: "history_sync_v2",
                name: "finished_at",
                sendInPings: ["history-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        private static let incomingLabel = CounterMetricType( // generated from history_sync_v2.incoming
            CommonMetricData(
                category: "history_sync_v2",
                name: "incoming",
                sendInPings: ["history-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records incoming history record counts. `applied` is the number of incoming
        /// history pages that were successfully stored or updated in the local database.
        /// `failed_to_apply` is the number of pages that were ignored due to errors.
        /// `reconciled` is the number of pages with new visits locally and remotely, and
        /// had their visits merged.
        static let incoming = try! LabeledMetricType<CounterMetricType>( // generated from history_sync_v2.incoming
            category: "history_sync_v2",
            name: "incoming",
            sendInPings: ["history-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: incomingLabel,
            labels: ["applied", "failed_to_apply", "reconciled"]
        )

        private static let outgoingLabel = CounterMetricType( // generated from history_sync_v2.outgoing
            CommonMetricData(
                category: "history_sync_v2",
                name: "outgoing",
                sendInPings: ["history-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records outgoing history record counts. `uploaded` is the number of records
        /// that were successfully sent to the server. `failed_to_upload` is the number of
        /// records that weren't uploaded, and will be retried on the next sync.
        static let outgoing = try! LabeledMetricType<CounterMetricType>( // generated from history_sync_v2.outgoing
            category: "history_sync_v2",
            name: "outgoing",
            sendInPings: ["history-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: outgoingLabel,
            labels: ["failed_to_upload", "uploaded"]
        )

        /// Records the number of batches needed to upload all outgoing records. The Sync
        /// server has a hard limit on the number of records (and request body bytes) on
        /// the number of records that can fit into a single batch, and large syncs may
        /// require multiple batches.
        static let outgoingBatches = CounterMetricType( // generated from history_sync_v2.outgoing_batches
            CommonMetricData(
                category: "history_sync_v2",
                name: "outgoing_batches",
                sendInPings: ["history-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records when the history sync started.
        static let startedAt = DatetimeMetricType( // generated from history_sync_v2.started_at
            CommonMetricData(
                category: "history_sync_v2",
                name: "started_at",
                sendInPings: ["history-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        /// The user's hashed Firefox Account ID.
        static let uid = StringMetricType( // generated from history_sync_v2.uid
            CommonMetricData(
                category: "history_sync_v2",
                name: "uid",
                sendInPings: ["history-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

    }

    enum LoginsSyncV2 {
        private static let failureReasonLabel = StringMetricType( // generated from logins_sync_v2.failure_reason
            CommonMetricData(
                category: "logins_sync_v2",
                name: "failure_reason",
                sendInPings: ["logins-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records why the passwords sync failed: either due to an authentication error,
        /// unexpected exception, or other error. The error strings are truncated and
        /// sanitized to omit PII, like usernames and passwords.
        static let failureReason = try! LabeledMetricType<StringMetricType>( // generated from logins_sync_v2.failure_reason
            category: "logins_sync_v2",
            name: "failure_reason",
            sendInPings: ["logins-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: failureReasonLabel,
            labels: ["auth", "other", "unexpected"]
        )

        /// Records when the passwords sync finished. This includes the time to download,
        /// apply, and upload all records.
        static let finishedAt = DatetimeMetricType( // generated from logins_sync_v2.finished_at
            CommonMetricData(
                category: "logins_sync_v2",
                name: "finished_at",
                sendInPings: ["logins-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        private static let incomingLabel = CounterMetricType( // generated from logins_sync_v2.incoming
            CommonMetricData(
                category: "logins_sync_v2",
                name: "incoming",
                sendInPings: ["logins-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records incoming passwords record counts. `applied` is the number of incoming
        /// passwords entries that were successfully stored or updated in the local
        /// database. `failed_to_apply` is the number of entries that were ignored due to
        /// errors. `reconciled` is the number of entries with changes both locally and
        /// remotely that were merged.
        static let incoming = try! LabeledMetricType<CounterMetricType>( // generated from logins_sync_v2.incoming
            category: "logins_sync_v2",
            name: "incoming",
            sendInPings: ["logins-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: incomingLabel,
            labels: ["applied", "failed_to_apply", "reconciled"]
        )

        private static let outgoingLabel = CounterMetricType( // generated from logins_sync_v2.outgoing
            CommonMetricData(
                category: "logins_sync_v2",
                name: "outgoing",
                sendInPings: ["logins-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records outgoing passwords record counts. `uploaded` is the number of records
        /// that were successfully sent to the server. `failed_to_upload` is the number of
        /// records that weren't uploaded, and will be retried on the next sync.
        static let outgoing = try! LabeledMetricType<CounterMetricType>( // generated from logins_sync_v2.outgoing
            category: "logins_sync_v2",
            name: "outgoing",
            sendInPings: ["logins-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: outgoingLabel,
            labels: ["failed_to_upload", "uploaded"]
        )

        /// Records the number of batches needed to upload all outgoing records. The Sync
        /// server has a hard limit on the number of records (and request body bytes) on
        /// the number of records that can fit into a single batch, and large syncs may
        /// require multiple batches.
        static let outgoingBatches = CounterMetricType( // generated from logins_sync_v2.outgoing_batches
            CommonMetricData(
                category: "logins_sync_v2",
                name: "outgoing_batches",
                sendInPings: ["logins-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records when the passwords sync started.
        static let startedAt = DatetimeMetricType( // generated from logins_sync_v2.started_at
            CommonMetricData(
                category: "logins_sync_v2",
                name: "started_at",
                sendInPings: ["logins-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        /// The user's hashed Firefox Account ID.
        static let uid = StringMetricType( // generated from logins_sync_v2.uid
            CommonMetricData(
                category: "logins_sync_v2",
                name: "uid",
                sendInPings: ["logins-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

    }

    enum SyncV2 {
        private static let failureReasonLabel = StringMetricType( // generated from sync_v2.failure_reason
            CommonMetricData(
                category: "sync_v2",
                name: "failure_reason",
                sendInPings: ["sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records a global sync failure: either due to an authentication error,
        /// unexpected exception, or other error that caused the sync to fail. Error
        /// strings are truncated and sanitized to omit PII, like URLs and file system
        /// paths.
        static let failureReason = try! LabeledMetricType<StringMetricType>( // generated from sync_v2.failure_reason
            category: "sync_v2",
            name: "failure_reason",
            sendInPings: ["sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: failureReasonLabel,
            labels: ["auth", "other", "unexpected"]
        )

        /// Unique identifier for this sync, used to correlate together individual pings
        /// for data types that were synchronized together (history, bookmarks, logins). If
        /// a data type is synchronized by itself via the legacy 'sync' API (as opposed to
        /// the Sync Manager), then this field will not be set on the corresponding ping.
        static let syncUuid = UuidMetricType( // generated from sync_v2.sync_uuid
            CommonMetricData(
                category: "sync_v2",
                name: "sync_uuid",
                sendInPings: ["bookmarks-sync", "history-sync", "logins-sync", "sync"],
                lifetime: .ping,
                disabled: false
            )
        )

    }

    enum TabsSyncV2 {
        private static let failureReasonLabel = StringMetricType( // generated from tabs_sync_v2.failure_reason
            CommonMetricData(
                category: "tabs_sync_v2",
                name: "failure_reason",
                sendInPings: ["tabs-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records why the tabs sync failed: either due to an authentication error,
        /// unexpected exception, or other error. The error strings are truncated and
        /// sanitized to omit PII, like URLs and file system paths.
        static let failureReason = try! LabeledMetricType<StringMetricType>( // generated from tabs_sync_v2.failure_reason
            category: "tabs_sync_v2",
            name: "failure_reason",
            sendInPings: ["tabs-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: failureReasonLabel,
            labels: ["auth", "other", "unexpected"]
        )

        /// Records when the tabs sync finished. This includes the time to download, apply,
        /// and upload all records.
        static let finishedAt = DatetimeMetricType( // generated from tabs_sync_v2.finished_at
            CommonMetricData(
                category: "tabs_sync_v2",
                name: "finished_at",
                sendInPings: ["tabs-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        private static let incomingLabel = CounterMetricType( // generated from tabs_sync_v2.incoming
            CommonMetricData(
                category: "tabs_sync_v2",
                name: "incoming",
                sendInPings: ["tabs-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records incoming tabs record counts. `applied` is the number of incoming
        /// records that were successfully stored or updated in the local database.
        /// `failed_to_apply` is the number of records that were ignored due to errors.
        /// `reconciled` is the number of merged records.
        static let incoming = try! LabeledMetricType<CounterMetricType>( // generated from tabs_sync_v2.incoming
            category: "tabs_sync_v2",
            name: "incoming",
            sendInPings: ["tabs-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: incomingLabel,
            labels: ["applied", "failed_to_apply", "reconciled"]
        )

        private static let outgoingLabel = CounterMetricType( // generated from tabs_sync_v2.outgoing
            CommonMetricData(
                category: "tabs_sync_v2",
                name: "outgoing",
                sendInPings: ["tabs-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records outgoing tabs record counts. `uploaded` is the number of records that
        /// were successfully sent to the server. `failed_to_upload` is the number of
        /// records that weren't uploaded, and will be retried on the next sync.
        static let outgoing = try! LabeledMetricType<CounterMetricType>( // generated from tabs_sync_v2.outgoing
            category: "tabs_sync_v2",
            name: "outgoing",
            sendInPings: ["tabs-sync"],
            lifetime: .ping,
            disabled: false,
            subMetric: outgoingLabel,
            labels: ["failed_to_upload", "uploaded"]
        )

        /// Records the number of batches needed to upload all outgoing records. The Sync
        /// server has a hard limit on the number of records (and request body bytes) on
        /// the number of records that can fit into a single batch, and large syncs may
        /// require multiple batches.
        static let outgoingBatches = CounterMetricType( // generated from tabs_sync_v2.outgoing_batches
            CommonMetricData(
                category: "tabs_sync_v2",
                name: "outgoing_batches",
                sendInPings: ["tabs-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

        /// Records when the tabs sync started.
        static let startedAt = DatetimeMetricType( // generated from tabs_sync_v2.started_at
            CommonMetricData(
                category: "tabs_sync_v2",
                name: "started_at",
                sendInPings: ["tabs-sync"],
                lifetime: .ping,
                disabled: false
            )
            , .millisecond
        )

        /// The user's hashed Firefox Account ID.
        static let uid = StringMetricType( // generated from tabs_sync_v2.uid
            CommonMetricData(
                category: "tabs_sync_v2",
                name: "uid",
                sendInPings: ["tabs-sync"],
                lifetime: .ping,
                disabled: false
            )
        )

    }

    class Pings {
        public static let shared = Pings()
        private init() {
            // Intentionally left private, no external user can instantiate a new global object.
        }

        /// A ping sent for every Addresses engine sync. It doesn't include the `client_id`
        /// because it reports a hashed version of the user's Firefox Account ID.
        let addressesSync = Ping<NoReasonCodes>(
            name: "addresses-sync",
            includeClientId: false,
            sendIfEmpty: false,
            reasonCodes: []
        )

        /// A ping sent for every bookmarks sync. It doesn't include the `client_id`
        /// because it reports a hashed version of the user's Firefox Account ID.
        let bookmarksSync = Ping<NoReasonCodes>(
            name: "bookmarks-sync",
            includeClientId: false,
            sendIfEmpty: false,
            reasonCodes: []
        )

        /// A ping sent for every Credit Cards engine sync. It doesn't include the
        /// `client_id` because it reports a hashed version of the user's Firefox Account
        /// ID.
        let creditcardsSync = Ping<NoReasonCodes>(
            name: "creditcards-sync",
            includeClientId: false,
            sendIfEmpty: false,
            reasonCodes: []
        )

        /// A ping sent for every history sync. It doesn't include the `client_id` because
        /// it reports a hashed version of the user's Firefox Account ID.
        let historySync = Ping<NoReasonCodes>(
            name: "history-sync",
            includeClientId: false,
            sendIfEmpty: false,
            reasonCodes: []
        )

        /// A ping sent for every logins/passwords sync. It doesn't include the `client_id`
        /// because it reports a hashed version of the user's Firefox Account ID.
        let loginsSync = Ping<NoReasonCodes>(
            name: "logins-sync",
            includeClientId: false,
            sendIfEmpty: false,
            reasonCodes: []
        )

        /// A summary ping, sent every time a sync is performed. During each Sync one or
        /// more data types could be synchronized, depending on which data types user
        /// configured to sync. Alongside with 'sync' ping one or more individual data type
        /// specific pings will be sent. For example, if history and bookmarks data types
        /// are configured to be synchronized, the following pings will be sent: 'sync',
        /// 'history-sync' and 'bookmarks-sync'. Alternatively, if only history is
        /// configured to be synchronized then 'sync' and 'history-sync' pings will be
        /// sent. In case of a "global failure" where none of the data type syncs could
        /// even start, e.g. device is offline, only the 'sync' ping will be sent. This
        /// ping doesn't include the `client_id` because it reports a hashed version of the
        /// user's Firefox Account ID.
        let sync = Ping<NoReasonCodes>(
            name: "sync",
            includeClientId: false,
            sendIfEmpty: false,
            reasonCodes: []
        )

        /// A ping sent for every Tabs engine sync. It doesn't include the `client_id`
        /// because it reports a hashed version of the user's Firefox Account ID.
        let tabsSync = Ping<NoReasonCodes>(
            name: "tabs-sync",
            includeClientId: false,
            sendIfEmpty: false,
            reasonCodes: []
        )

    }

}
