// @generated by protobuf-ts 2.8.2 with parameter long_type_string
// @generated from protobuf file "pb/config/config.proto" (syntax proto3)
// tslint:disable
import type { BinaryWriteOptions } from '@protobuf-ts/runtime';
import type { IBinaryWriter } from '@protobuf-ts/runtime';
import { WireType } from '@protobuf-ts/runtime';
import type { BinaryReadOptions } from '@protobuf-ts/runtime';
import type { IBinaryReader } from '@protobuf-ts/runtime';
import { UnknownFieldHandler } from '@protobuf-ts/runtime';
import type { PartialMessage } from '@protobuf-ts/runtime';
import { reflectionMergePartial } from '@protobuf-ts/runtime';
import { MESSAGE_TYPE } from '@protobuf-ts/runtime';
import { MessageType } from '@protobuf-ts/runtime';
import { RuleSet } from '../custom_evaluator/custom_evaluator';
/**
 * Specifies the test name, and its source
 *
 * @generated from protobuf message TestNameConfig
 */
export interface TestNameConfig {
  /**
   * The name elements specifying the target test name for this tab.
   *
   * @generated from protobuf field: repeated TestNameConfig.NameElement name_elements = 1;
   */
  nameElements: TestNameConfig_NameElement[];
  /**
   * Specifies a printf-style format string for name elements. The format
   * string should have as many conversions as there are name_elements.
   * For example, two name_elements could be used with name_format="%s: %s".
   *
   * @generated from protobuf field: string name_format = 2;
   */
  nameFormat: string;
}
/**
 * Specifies name elements to be selected from configuration values
 *
 * @generated from protobuf message TestNameConfig.NameElement
 */
export interface TestNameConfig_NameElement {
  /**
   * A space-delimited string of labels
   *
   * @generated from protobuf field: string labels = 1;
   */
  labels: string;
  /**
   * Configuration value to use.
   * Valid choice are:
   * 'Tests name': The name of a test case
   * 'Commit': The commit number of the build
   * 'Context', 'Thread': The info extracted from each junit files:
   *    - junit_core-os_01.xml -> Context: core-os, Thread: 01
   *    - junit_runner.xml -> Context: runner
   *    - junit_01.xml -> Thread: 01
   * or any metadata key from finished.json, which is copied from your test
   * suite.
   *
   * A valid sample TestNameConfig looks like:
   * test_name_config:
   *   name_elements:
   *   - target_config: Tests name
   *   - target_config: Context
   *   name_format: '%s [%s]'
   *
   * @generated from protobuf field: string target_config = 2;
   */
  targetConfig: string;
  /**
   * Whether to use the build-target name
   *
   * @generated from protobuf field: bool build_target = 3;
   */
  buildTarget: boolean;
  /**
   * A space-delimited string of Bazel build tags.
   *
   * @generated from protobuf field: string tags = 4;
   */
  tags: string;
  /**
   * The key of a test result's property.
   *
   * @generated from protobuf field: string test_property = 5;
   */
  testProperty: string;
}
/**
 * A single notification.
 *
 * @generated from protobuf message Notification
 */
export interface Notification {
  /**
   * Required: Text summary of the issue or notice.
   *
   * @generated from protobuf field: string summary = 1;
   */
  summary: string;
  /**
   * Optional: Link to further information, such as a bug, email, document, etc.
   *
   * @generated from protobuf field: string context_link = 2;
   */
  contextLink: string;
}
/**
 * Specifies a group of tests to gather.
 *
 * @generated from protobuf message TestGroup
 */
export interface TestGroup {
  /**
   * Name of this TestGroup, for mapping dashboard tabs to tests.
   *
   * @generated from protobuf field: string name = 1;
   */
  name: string;
  /**
   * Path to the test result stored in gcs (some-bucket/some/optional/path).
   *
   * @generated from protobuf field: string gcs_prefix = 2;
   */
  gcsPrefix: string;
  /**
   * Number of days of test results to gather and serve.
   *
   * @generated from protobuf field: int32 days_of_results = 3;
   */
  daysOfResults: number;
  /**
   * Whether to ignore pending (currently running) test results.
   *
   * @generated from protobuf field: bool ignore_pending = 4;
   */
  ignorePending: boolean;
  /**
   * Whether to ignore reported build results. It is recommended that tests
   * report BUILD_FAIL instead of relying on this being disabled.
   *
   * @generated from protobuf field: bool ignore_built = 5;
   */
  ignoreBuilt: boolean;
  /**
   * What to do with the 'Tests name' configuration value. It can replace the
   * name of the test, be appended to the name of the test, or ignored. If it is
   * ignored, then the name of the tests will be the build target.
   *
   * @generated from protobuf field: TestGroup.TestsName tests_name_policy = 6;
   */
  testsNamePolicy: TestGroup_TestsName;
  /**
   * Tests with names that include these substrings will be removed from the
   * table.
   *
   * @generated from protobuf field: repeated string ignore_test_substring = 8;
   */
  ignoreTestSubstring: string[];
  /**
   * @generated from protobuf field: repeated TestGroup.ColumnHeader column_header = 9;
   */
  columnHeader: TestGroup_ColumnHeader[];
  /**
   * A test grouping option used if not specified by primary_grouping (#29)
   *
   * @generated from protobuf field: TestGroup.FallbackGrouping fallback_grouping = 10;
   */
  fallbackGrouping: TestGroup_FallbackGrouping;
  /**
   * DEPRECATED: use DashboardTabAlertOptions > alert_stale_result_hours
   *
   * @deprecated
   * @generated from protobuf field: int32 alert_stale_results_hours = 11 [deprecated = true];
   */
  alertStaleResultsHours: number;
  /**
   * DEPRECATED: use DashboardTabAlertOptions > num_failures_to_alert
   *
   * @deprecated
   * @generated from protobuf field: int32 num_failures_to_alert = 12 [deprecated = true];
   */
  numFailuresToAlert: number;
  /**
   * DEPRECATED: use dashboard_tab.beta_autobug_options.beta_autobug_component
   * instead.
   *
   * @deprecated
   * @generated from protobuf field: int32 bug_component = 13 [deprecated = true];
   */
  bugComponent: number;
  /**
   * Default code search path for searching regressions. Overridden by
   * code_search_path in DashboardTab.
   *
   * @generated from protobuf field: string code_search_path = 14;
   */
  codeSearchPath: string;
  /**
   * The number of columns to consider "recent" for a variety of purposes.
   *
   * @generated from protobuf field: int32 num_columns_recent = 15;
   */
  numColumnsRecent: number;
  /**
   * Whether to read test metadata from the test results. Information
   * from the test metadata is used to determine where bugs are filed in
   * specific cases.
   *
   * @generated from protobuf field: bool use_test_metadata = 16;
   */
  useTestMetadata: boolean;
  /**
   * DEPRECATED: use DashboardTabAlertOptions > alert_mail_to_address instead
   *
   * @deprecated
   * @generated from protobuf field: string alert_mail_to_addresses = 17 [deprecated = true];
   */
  alertMailToAddresses: string;
  /**
   * DEPRECATED: use DashboardTabAlertOptions > subject
   *
   * @deprecated
   * @generated from protobuf field: string alert_mail_subject = 18 [deprecated = true];
   */
  alertMailSubject: string;
  /**
   * DEPRECATED: use DashboardTabAlertOptions > alert_mail_failure_message
   *
   * @deprecated
   * @generated from protobuf field: string alert_mail_failure_message = 19 [deprecated = true];
   */
  alertMailFailureMessage: string;
  /**
   * DEPRECATED: use DashboardTabAlertOptions > debug_url
   *
   * @deprecated
   * @generated from protobuf field: string alert_mail_debug_url = 20 [deprecated = true];
   */
  alertMailDebugUrl: string;
  /**
   * DEPRECATED: use DashboardTabAlertOptions > wait_minutes_between_emails
   *
   * @deprecated
   * @generated from protobuf field: int32 min_elapsed_minutes_between_mails = 21 [deprecated = true];
   */
  minElapsedMinutesBetweenMails: number;
  /**
   * Whether to treat a combination of passes and failures within one test as a
   * flaky status.
   *
   * @generated from protobuf field: bool enable_flaky_status = 23;
   */
  enableFlakyStatus: boolean;
  /**
   * disable_merged_status will restores deprecated behavior of
   * splitting multiple foo rows into foo [2], etc rather a single
   * potentially flaky row.
   *
   * @generated from protobuf field: bool disable_merged_status = 60;
   */
  disableMergedStatus: boolean;
  /**
   * deprecated - always set to true
   *
   * @deprecated
   * @generated from protobuf field: bool use_kubernetes_client = 24 [deprecated = true];
   */
  useKubernetesClient: boolean;
  /**
   * When use_kubernetes_client is on testgrid expects these results
   * to come from prow, which should include a prowjob.json and podinfo.json
   * to help debugging. If you do not expect these files to exist, you
   * can optionally disable this analysis.
   *
   * @generated from protobuf field: bool disable_prowjob_analysis = 62;
   */
  disableProwjobAnalysis: boolean;
  /**
   * deprecated - always set to true
   *
   * @generated from protobuf field: bool is_external = 25;
   */
  isExternal: boolean;
  /**
   * Specifies the test name for a test.
   *
   * @generated from protobuf field: TestNameConfig test_name_config = 26;
   */
  testNameConfig?: TestNameConfig;
  /**
   * A list of notifications attached to this test group.
   * This is displayed on any dashboard tab backed by this test group.
   *
   * @generated from protobuf field: repeated Notification notifications = 27;
   */
  notifications: Notification[];
  /**
   * A primary grouping strategy for grouping test results in columns.
   * If a primary grouping is specified, the fallback grouping is ignored.
   *
   * @generated from protobuf field: TestGroup.PrimaryGrouping primary_grouping = 29;
   */
  primaryGrouping: TestGroup_PrimaryGrouping;
  /**
   * Whether to collect pass-fail data for test methods. Additional test cases
   * will be added for each test method in a target.
   *
   * @generated from protobuf field: bool enable_test_methods = 30;
   */
  enableTestMethods: boolean;
  /**
   * Test annotations to look for. Adds custom icon to results.
   *
   * @generated from protobuf field: repeated TestGroup.TestAnnotation test_annotations = 31;
   */
  testAnnotations: TestGroup_TestAnnotation[];
  /**
   * Maximum number of individual test methods to collect for any given test
   * row. If a test has more than this many methods, no methods will be
   * displayed.
   *
   * @generated from protobuf field: int32 max_test_methods_per_test = 32;
   */
  maxTestMethodsPerTest: number;
  /**
   * Default metadata that should be applied for opening bugs, if a given regex
   * matches against a test's name.
   * Requires 'use_test_metadata = true'.
   *
   * @generated from protobuf field: repeated TestMetadataOptions test_metadata_options = 34;
   */
  testMetadataOptions: TestMetadataOptions[];
  /**
   * A space-delimited string of tags that are used to filter test targets.
   * A leading - before the tag means this tag should not be present
   * in the target.
   * Example:
   *  contains tag1, but not tag2: test_tag_pattern = 'tag1 -tag2'
   *
   * @generated from protobuf field: string test_tag_pattern = 35;
   */
  testTagPattern: string;
  /**
   * DEPRECATED: use dashboard_tab.beta_autobug_options instead.
   *
   * @deprecated
   * @generated from protobuf field: AutoBugOptions auto_bug_options = 36 [deprecated = true];
   */
  autoBugOptions?: AutoBugOptions;
  /**
   * Max number of days any single test can take.
   *
   * @generated from protobuf field: int32 max_test_runtime_hours = 37;
   */
  maxTestRuntimeHours: number;
  /**
   * The number of consecutive test passes to close the alert.
   *
   * @generated from protobuf field: int32 num_passes_to_disable_alert = 38;
   */
  numPassesToDisableAlert: number;
  /**
   * If true, also associate bugs with tests if the test result's overview/group
   * ID is in the bug.
   *
   * @generated from protobuf field: bool link_bugs_by_group = 39;
   */
  linkBugsByGroup: boolean;
  /**
   * Only show test methods with all required properties
   *
   * @generated from protobuf field: repeated TestGroup.KeyValue test_method_properties = 41;
   */
  testMethodProperties: TestGroup_KeyValue[];
  /**
   * If true, allows gathering and associating bugs with targets in the
   * dashboard. Required in order to auto-file bugs.
   *
   * @generated from protobuf field: bool gather_bugs = 42;
   */
  gatherBugs: boolean;
  /**
   * Numeric property metric value to be used for short text. If this property
   * is present, it will override all the other short text values.
   *
   * @generated from protobuf field: string short_text_metric = 43;
   */
  shortTextMetric: string;
  /**
   * The key of a key-value pair in metadata (a 'configuration value').
   * This overrides the default build with the value from the key-value pair.
   *
   * @generated from protobuf field: string build_override_configuration_value = 44;
   */
  buildOverrideConfigurationValue: string;
  /**
   * If true, only associate bugs with test methods if that test method is
   * mentioned in the bug. If false, bugs will be associated with all test
   * methods.
   *
   * @generated from protobuf field: bool link_bugs_by_test_methods = 45;
   */
  linkBugsByTestMethods: boolean;
  /**
   * Regex to match test methods. Only test methods with names that match
   * this regex will be included in the table.
   *
   * @generated from protobuf field: string test_method_match_regex = 46;
   */
  testMethodMatchRegex: string;
  /**
   * Regex to exclude test methods. Test methods with names that match
   * this regex will be excluded from the table, even if they match
   * test_method_match_regex.
   *
   * @generated from protobuf field: string test_method_unmatch_regex = 61;
   */
  testMethodUnmatchRegex: string;
  /**
   * If true, test method names are printed with the full class names.
   *
   * @generated from protobuf field: bool use_full_method_names = 47;
   */
  useFullMethodNames: boolean;
  /**
   * A configuration value that is used as a fallback grouping.
   * This is useful for cases where there are builds that shared the same
   * commit but are run at separate times of day.
   *
   * @generated from protobuf field: string fallback_grouping_configuration_value = 49;
   */
  fallbackGroupingConfigurationValue: string;
  /**
   * Configuration type of the result source.
   *
   * @generated from protobuf field: TestGroup.ResultSource result_source = 50;
   */
  resultSource?: TestGroup_ResultSource;
  /**
   * Set of rules that are evaluated with each test result. If an evaluation is
   * successful, the status of that test result will be whatever is specified
   * for a given rule. For more information, look at RuleSet documention
   *
   * @generated from protobuf field: RuleSet custom_evaluator_rule_set = 51;
   */
  customEvaluatorRuleSet?: RuleSet;
  /**
   * If true, instead of updating the group, read the state proto from storage
   * and update summary, alerts, etc. from that state.
   * This only applies to test group state, not bug state for a test group.
   * This assumes that the state proto is updated through other means (another
   * updater, manually, etc).
   *
   * @generated from protobuf field: bool read_state_from_storage = 52;
   */
  readStateFromStorage: boolean;
  /**
   * If true, only add the most recent result for a test when multiple results
   * for a test with the same name are encountered.
   *
   * @generated from protobuf field: bool ignore_old_results = 53;
   */
  ignoreOldResults: boolean;
  /**
   * If True, ignore the 'pass with skips' status (show as a blank cell).
   *
   * @generated from protobuf field: bool ignore_skip = 54;
   */
  ignoreSkip: boolean;
  /**
   * A string containing python formatting specifiers that overrides the
   * commit with the date formatted according to this string. This is useful
   * for aggregating multiple columns that don't have a matching commit.
   *
   * @generated from protobuf field: string build_override_strftime = 55;
   */
  buildOverrideStrftime: string;
  /**
   * Specify a property that will be read into state in the user_property field.
   * These can be substituted into LinkTemplates.
   *
   * @generated from protobuf field: string user_property = 56;
   */
  userProperty: string;
}
/**
 * Custom column headers for defining extra column-heading rows from values in
 * the test result.
 *
 * @generated from protobuf message TestGroup.ColumnHeader
 */
export interface TestGroup_ColumnHeader {
  /**
   * @generated from protobuf field: string label = 1;
   */
  label: string;
  /**
   * @generated from protobuf field: string property = 2;
   */
  property: string;
  /**
   * @generated from protobuf field: string configuration_value = 3;
   */
  configurationValue: string;
  /**
   * If true, list all distinct values. Else, list multiple distinct values as
   * "*".
   *
   * @generated from protobuf field: bool list_all_values = 4;
   */
  listAllValues: boolean;
}
/**
 * Associates the presence of a named test property with a custom short text
 * displayed over the results. Short text must be <=5 characters long.
 *
 * @generated from protobuf message TestGroup.TestAnnotation
 */
export interface TestGroup_TestAnnotation {
  /**
   * @generated from protobuf field: string short_text = 1;
   */
  shortText: string;
  /**
   * @generated from protobuf oneof: short_text_message_source
   */
  shortTextMessageSource:
    | {
        oneofKind: 'propertyName';
        /**
         * @generated from protobuf field: string property_name = 2;
         */
        propertyName: string;
      }
    | {
        oneofKind: undefined;
      };
}
/**
 * A string key value pair message
 *
 * @generated from protobuf message TestGroup.KeyValue
 */
export interface TestGroup_KeyValue {
  /**
   * @generated from protobuf field: string key = 1;
   */
  key: string;
  /**
   * @generated from protobuf field: string value = 2;
   */
  value: string;
}
/**
 * @generated from protobuf message TestGroup.ResultSource
 */
export interface TestGroup_ResultSource {
  /**
   * @generated from protobuf oneof: result_source_config
   */
  resultSourceConfig:
    | {
        oneofKind: 'gcsConfig';
        /**
         * GCS buckets holding junit and json results, typically created by prow.
         *
         * @generated from protobuf field: GCSConfig gcs_config = 2;
         */
        gcsConfig: GCSConfig;
      }
    | {
        oneofKind: undefined;
      };
}
/**
 * @generated from protobuf enum TestGroup.TestsName
 */
export enum TestGroup_TestsName {
  /**
   * @generated from protobuf enum value: TESTS_NAME_UNSPECIFIED = 0;
   */
  UNSPECIFIED = 0,
  /**
   * @generated from protobuf enum value: TESTS_NAME_IGNORE = 1;
   */
  IGNORE = 1,
  /**
   * @generated from protobuf enum value: TESTS_NAME_REPLACE = 2;
   */
  REPLACE = 2,
  /**
   * @generated from protobuf enum value: TESTS_NAME_APPEND = 3;
   */
  APPEND = 3,
}
/**
 * @generated from protobuf enum TestGroup.FallbackGrouping
 */
export enum TestGroup_FallbackGrouping {
  /**
   * @generated from protobuf enum value: FALLBACK_GROUPING_NONE = 0;
   */
  NONE = 0,
  /**
   * @generated from protobuf enum value: FALLBACK_GROUPING_DATE = 1;
   */
  DATE = 1,
  /**
   * @generated from protobuf enum value: FALLBACK_GROUPING_LABELS = 2;
   */
  LABELS = 2,
  /**
   * @generated from protobuf enum value: FALLBACK_GROUPING_ID = 3;
   */
  ID = 3,
  /**
   * @generated from protobuf enum value: FALLBACK_GROUPING_BUILD = 4;
   */
  BUILD = 4,
  /**
   * When using this, ensure fallback_grouping_configuration_value is
   * also set.
   *
   * @generated from protobuf enum value: FALLBACK_GROUPING_CONFIGURATION_VALUE = 5;
   */
  CONFIGURATION_VALUE = 5,
}
/**
 * @generated from protobuf enum TestGroup.PrimaryGrouping
 */
export enum TestGroup_PrimaryGrouping {
  /**
   * @generated from protobuf enum value: PRIMARY_GROUPING_NONE = 0;
   */
  NONE = 0,
  /**
   * @generated from protobuf enum value: PRIMARY_GROUPING_BUILD = 1;
   */
  BUILD = 1,
}
/**
 * GCSConfig specifies results stored in GCS, typically created by prow.
 *
 * Each invocation is stored in a GCS path, containing json metadata files
 * as well as junit and other artifacts specifying the result of the run.
 *
 * More info:
 * https://github.com/GoogleCloudPlatform/testgrid/tree/master/metadata
 *
 * @generated from protobuf message GCSConfig
 */
export interface GCSConfig {
  /**
   * Path to the test result stored in gcs (some-bucket/some/optional/path).
   *
   * @generated from protobuf field: string gcs_prefix = 1;
   */
  gcsPrefix: string;
  /**
   * The GCP project where GCS sends notifications for the above prefix.
   *
   * @generated from protobuf field: string pubsub_project = 2;
   */
  pubsubProject: string;
  /**
   * The pubsub subscription ID in the above topic
   *
   * @generated from protobuf field: string pubsub_subscription = 3;
   */
  pubsubSubscription: string;
}
/**
 * Default metadata to apply when opening bugs.
 *
 * @generated from protobuf message TestMetadataOptions
 */
export interface TestMetadataOptions {
  /**
   * Apply the following metadata if this regex matches a test's name.
   *
   * @generated from protobuf field: string test_name_regex = 1;
   */
  testNameRegex: string;
  /**
   * Default bug component to open a bug in.
   *
   * @generated from protobuf field: int32 bug_component = 2;
   */
  bugComponent: number;
  /**
   * Default owner to assign a bug to.
   *
   * @generated from protobuf field: string owner = 3;
   */
  owner: string;
  /**
   * List of default users to CC a bug to.
   *
   * @generated from protobuf field: repeated string cc = 4;
   */
  cc: string[];
  /**
   * Apply following metadata if this regex matches a test’s failure message.
   *
   * @generated from protobuf field: string message_regex = 5;
   */
  messageRegex: string;
}
/**
 * @generated from protobuf message AutoBugOptions
 */
export interface AutoBugOptions {
  /**
   * [BETA] When specified, file bugs to this component, using the beta AutoBug.
   * If you do not want to opt into the beta, specify `bug_component` in your
   * TestGroup instead.
   * TODO(b/154866134): Rename to autobug_component once we've migrated.
   *
   * @generated from protobuf field: int32 beta_autobug_component = 10;
   */
  betaAutobugComponent: number;
  /**
   * Whether to auto-close auto-filed bugs.
   *
   * @generated from protobuf field: bool auto_close = 1;
   */
  autoClose: boolean;
  /**
   * A list of hotlist ids attached to auto-filed bugs.
   *
   * @generated from protobuf field: repeated int64 hotlist_ids = 2;
   */
  hotlistIds: string[];
  /**
   * The priority of the auto-filed bug. If provided, this will overwrite the
   * priority in the component default template
   *
   * @generated from protobuf field: AutoBugOptions.Priority priority = 3;
   */
  priority: AutoBugOptions_Priority;
  /**
   * A list of hotlist id sources
   * Corresponds with the list hotlist_ids (#2)
   *
   * @deprecated
   * @generated from protobuf field: repeated HotlistIdFromSource hotlist_ids_from_source = 4 [deprecated = true];
   */
  hotlistIdsFromSource: HotlistIdFromSource[];
  /**
   * If True, files separate bugs for each failing target, instead of one bug
   * for each set of targets failing at the same run.
   *
   * @generated from protobuf field: bool file_individual = 5;
   */
  fileIndividual: boolean;
  /**
   * If True; keep only one automantic bug per target, regardless of the number
   * of separate failures a target gets. This also requires `auto_close` and
   * `file_individual` to be True.
   * Consider setting `num_passes_to_disable_alert` instead if you're tracking
   * flaky tests.
   *
   * @generated from protobuf field: bool singleton_autobug = 6;
   */
  singletonAutobug: boolean;
  /**
   * If provided: only raise one bug if the number of failures for a single
   * query by testgrid for a single failure group exceeds this value. Requires
   * 'file_individual' to be True.
   *
   * @generated from protobuf field: int32 max_allowed_individual_bugs = 7;
   */
  maxAllowedIndividualBugs: number;
  /**
   * If True; file issues for the 'Overall' target, even if otherwise invalid.
   *
   * @generated from protobuf field: bool file_overall = 8;
   */
  fileOverall: boolean;
  /**
   * If provided: supplements `max_allowed_individual_bugs` field to raise a
   * single bug if the number of failures for a single query by testgrid exceeds
   * the max_allowed_individual_bugs` value, regardless of `TEST_METADATA`
   * configurations. This is useful for filing fewer suspected environmental
   * failure bugs and routing them to a specific location (i.e. an oncall).
   * Requires 'file_individual' to be true and `max_allowed_individual_bugs` to
   * not be empty.
   *
   * @generated from protobuf field: AutoBugOptions.DefaultTestMetadata default_test_metadata = 9;
   */
  defaultTestMetadata?: AutoBugOptions_DefaultTestMetadata;
  /**
   * [BETA] If True, query the test metadata API to get issue-routing metadata.
   * Enables routing issues using structured test failures.
   *
   * @generated from protobuf field: bool advanced_test_metadata = 11;
   */
  advancedTestMetadata: boolean;
  /**
   * If True, file a bug when the tab goes stale.
   * (Requires `alert_stale_results_hours` to be set.)
   *
   * @generated from protobuf field: bool file_stale = 12;
   */
  fileStale: boolean;
  /**
   * If True, ignore overall rows when auto-filing.
   *
   * @generated from protobuf field: bool ignore_overall = 13;
   */
  ignoreOverall: boolean;
  /**
   * [BETA] Extra text displayed in opened bugs. e.g., for including a link to a
   * playbook.
   *
   * @generated from protobuf field: string note = 14;
   */
  note: string;
}
/**
 * @generated from protobuf message AutoBugOptions.DefaultTestMetadata
 */
export interface AutoBugOptions_DefaultTestMetadata {
  /**
   * @generated from protobuf field: int32 bug_component = 1;
   */
  bugComponent: number;
  /**
   * @generated from protobuf field: string owner = 2;
   */
  owner: string;
  /**
   * @generated from protobuf field: repeated string cc = 3;
   */
  cc: string[];
}
/**
 * Scale of issue priority, used to indicate importance of issue.
 *
 * @generated from protobuf enum AutoBugOptions.Priority
 */
export enum AutoBugOptions_Priority {
  /**
   * Unspecified; may not set priority at all
   *
   * @generated from protobuf enum value: PRIORITY_UNSPECIFIED = 0;
   */
  PRIORITY_UNSPECIFIED = 0,
  /**
   * See https://developers.google.com/issue-tracker/concepts/issues
   *
   * @generated from protobuf enum value: P0 = 1;
   */
  P0 = 1,
  /**
   * @generated from protobuf enum value: P1 = 2;
   */
  P1 = 2,
  /**
   * @generated from protobuf enum value: P2 = 3;
   */
  P2 = 3,
  /**
   * @generated from protobuf enum value: P3 = 4;
   */
  P3 = 4,
  /**
   * @generated from protobuf enum value: P4 = 5;
   */
  P4 = 5,
}
/**
 * @generated from protobuf message HotlistIdFromSource
 */
export interface HotlistIdFromSource {
  /**
   * @generated from protobuf oneof: hotlist_id_source
   */
  hotlistIdSource:
    | {
        oneofKind: 'value';
        /**
         * ID value of hotlists
         *
         * @generated from protobuf field: int64 value = 1;
         */
        value: string;
      }
    | {
        oneofKind: 'label';
        /**
         * A label prefix
         *
         * @generated from protobuf field: string label = 2;
         */
        label: string;
      }
    | {
        oneofKind: undefined;
      };
}
/**
 * Specifies a dashboard.
 *
 * @generated from protobuf message Dashboard
 */
export interface Dashboard {
  /**
   * A list of the tabs on the dashboard.
   *
   * @generated from protobuf field: repeated DashboardTab dashboard_tab = 1;
   */
  dashboardTab: DashboardTab[];
  /**
   * A name for the Dashboard.
   *
   * @generated from protobuf field: string name = 2;
   */
  name: string;
  /**
   * A list of notifications attached to this dashboard.
   * This is displayed on any dashboard tab in this dashboard.
   *
   * @generated from protobuf field: repeated Notification notifications = 3;
   */
  notifications: Notification[];
  /**
   * Control which tab is displayed when first opening a dashboard.
   * Defaults to Summary
   *
   * @generated from protobuf field: string default_tab = 5;
   */
  defaultTab: string;
  /**
   * Controls whether to suppress highlighting of failing tabs.
   *
   * @generated from protobuf field: bool downplay_failing_tabs = 8;
   */
  downplayFailingTabs: boolean;
  /**
   * Deprecated: Invert of 'downplay_failing_tabs'
   *
   * @deprecated
   * @generated from protobuf field: bool highlight_failing_tabs = 6 [deprecated = true];
   */
  highlightFailingTabs: boolean;
  /**
   * Controls whether to apply special highlighting to result header columns for
   * the current day.
   *
   * @generated from protobuf field: bool highlight_today = 7;
   */
  highlightToday: boolean;
  /**
   * A description paragraph to be displayed.
   *
   * @generated from protobuf field: string description = 9;
   */
  description: string;
}
/**
 * @generated from protobuf message LinkTemplate
 */
export interface LinkTemplate {
  /**
   * The URL template.
   *
   * @generated from protobuf field: string url = 1;
   */
  url: string;
  /**
   * The options templates.
   *
   * @generated from protobuf field: repeated LinkOptionsTemplate options = 2;
   */
  options: LinkOptionsTemplate[];
  /**
   * An optional name, used for the context menu
   *
   * @generated from protobuf field: string name = 3;
   */
  name: string;
}
/**
 * A simple key/value pair for link options.
 *
 * @generated from protobuf message LinkOptionsTemplate
 */
export interface LinkOptionsTemplate {
  /**
   * The key for the option. This is not expanded.
   *
   * @generated from protobuf field: string key = 1;
   */
  key: string;
  /**
   * The value for the option. This is expanded the same as the LinkTemplate.
   *
   * @generated from protobuf field: string value = 2;
   */
  value: string;
}
/**
 * A single tab on a dashboard.
 *
 * @generated from protobuf message DashboardTab
 */
export interface DashboardTab {
  /**
   * The name of the dashboard tab to display in the client.
   *
   * @generated from protobuf field: string name = 1;
   */
  name: string;
  /**
   * The name of the TestGroup specifying the test results for this tab.
   *
   * @generated from protobuf field: string test_group_name = 2;
   */
  testGroupName: string;
  /**
   * Default bug component for manually filing bugs from the dashboard
   *
   * @generated from protobuf field: int32 bug_component = 3;
   */
  bugComponent: number;
  /**
   * Default code search path for searching regressions. This value overrides
   * the default in the TestGroup config so that dashboards may be customized
   * separately.
   *
   * @generated from protobuf field: string code_search_path = 4;
   */
  codeSearchPath: string;
  /**
   * See TestGroup.num_columns_recent. This value overrides the default in the
   * TestGroup config so that dashboards may be customized separately.
   *
   * @generated from protobuf field: int32 num_columns_recent = 5;
   */
  numColumnsRecent: number;
  /**
   * Base options to always include, for example:
   * width=20&include-filter-by-regex=level_tests
   * This is taken from the #fragment part of the testgrid url.
   * Best way to create these is to setup the options on testgrid and then
   * copy the #fragment part.
   *
   * @generated from protobuf field: string base_options = 6;
   */
  baseOptions: string;
  /**
   * The URL template to visit after clicking on a cell.
   *
   * @generated from protobuf field: LinkTemplate open_test_template = 7;
   */
  openTestTemplate?: LinkTemplate;
  /**
   * The URL template to visit when filing a bug.
   *
   * @generated from protobuf field: LinkTemplate file_bug_template = 8;
   */
  fileBugTemplate?: LinkTemplate;
  /**
   * The URL template to visit when attaching a bug
   *
   * @generated from protobuf field: LinkTemplate attach_bug_template = 9;
   */
  attachBugTemplate?: LinkTemplate;
  /**
   * Text to show in the about menu as a link to another view of the results.
   *
   * @generated from protobuf field: string results_text = 10;
   */
  resultsText: string;
  /**
   * The URL template to visit after clicking.
   *
   * @generated from protobuf field: LinkTemplate results_url_template = 11;
   */
  resultsUrlTemplate?: LinkTemplate;
  /**
   * The URL template to visit when searching for code changes, such as pull
   * requests
   *
   * @generated from protobuf field: LinkTemplate code_search_url_template = 12;
   */
  codeSearchUrlTemplate?: LinkTemplate;
  /**
   * A description paragraph to be displayed.
   *
   * @generated from protobuf field: string description = 13;
   */
  description: string;
  /**
   * A regular expression that uses the named group syntax to specify how to
   * show names in a table.
   *
   * @generated from protobuf field: string tabular_names_regex = 14;
   */
  tabularNamesRegex: string;
  /**
   * Configuration options for dashboard tab alerts.
   *
   * @generated from protobuf field: DashboardTabAlertOptions alert_options = 15;
   */
  alertOptions?: DashboardTabAlertOptions;
  /**
   * Configuration options for dashboard tab flakiness alerts.
   *
   * @generated from protobuf field: DashboardTabFlakinessAlertOptions flakiness_alert_options = 24;
   */
  flakinessAlertOptions?: DashboardTabFlakinessAlertOptions;
  /**
   * Configuration options for customizing dashboard tab status calculation.
   *
   * @generated from protobuf field: DashboardTabStatusCustomizationOptions status_customization_options = 26;
   */
  statusCustomizationOptions?: DashboardTabStatusCustomizationOptions;
  /**
   * A URL for the "About this Dashboard" menu option
   *
   * @generated from protobuf field: string about_dashboard_url = 16;
   */
  aboutDashboardUrl: string;
  /**
   * The URL template to visit when viewing an associated bug.
   *
   * @generated from protobuf field: LinkTemplate open_bug_template = 17;
   */
  openBugTemplate?: LinkTemplate;
  /**
   * If true, auto-file bugs when new alerts occur. This requires that the
   * backing test group has `bug_component` set and uses the backing test
   * group's `auto_bug_options`.
   *
   * @generated from protobuf field: bool auto_file_bugs = 18;
   */
  autoFileBugs: boolean;
  /**
   * Display user local time on the dashboard when set to true (by default).
   * If false, uses Pacific Timezone for this DashboardTab.
   *
   * @generated from protobuf field: bool display_local_time = 19;
   */
  displayLocalTime: boolean;
  /**
   * A set of optional LinkTemplates that will become right-click context menu
   * items.
   * TODO(b/159042168) in the near future this should be re-implemented as a
   * generic list of repeated LinkTemplates which users may specify in their
   * reqpective configurations as right-click context menus with names and
   * actions upon being clicked.
   *
   * @generated from protobuf field: LinkTemplate context_menu_template = 20;
   */
  contextMenuTemplate?: LinkTemplate;
  /**
   * When specified, treat a tab as BROKEN as long as one of the most recent
   * columns are "broken" (ratio of failed to total tests exceeds <threshold>).
   *
   * @generated from protobuf field: float broken_column_threshold = 21;
   */
  brokenColumnThreshold: number;
  /**
   * Options for auto-filed bugs.
   * Using this for a dashboard tab requires specifying `beta_autobug_component`
   * and will opt you into the beta AutoBug.
   *
   * @generated from protobuf field: AutoBugOptions beta_autobug_options = 22;
   */
  betaAutobugOptions?: AutoBugOptions;
  /**
   * Options for the configuration of the flakiness analysis tool, per-tab.
   *
   * @generated from protobuf field: HealthAnalysisOptions health_analysis_options = 23;
   */
  healthAnalysisOptions?: HealthAnalysisOptions;
  /**
   * A set of optional Link Templates when search for diffs between columns.
   *
   * @generated from protobuf field: repeated LinkTemplate column_diff_link_templates = 25;
   */
  columnDiffLinkTemplates: LinkTemplate[];
}
/**
 * Configuration options for dashboard tab alerts.
 *
 * @generated from protobuf message DashboardTabAlertOptions
 */
export interface DashboardTabAlertOptions {
  /**
   * Time in hours before an alert will be added to a test results table if the
   * run date of the latest results are older than this time.  If zero, no
   * alerts are raised.
   *
   * @generated from protobuf field: int32 alert_stale_results_hours = 1;
   */
  alertStaleResultsHours: number;
  /**
   * The number of consecutive test result failures to see before alerting of
   * a consistent failure. If zero, no alerts are raised.
   *
   * @generated from protobuf field: int32 num_failures_to_alert = 2;
   */
  numFailuresToAlert: number;
  /**
   * The comma-separated addresses to send mail.
   *
   * @generated from protobuf field: string alert_mail_to_addresses = 3;
   */
  alertMailToAddresses: string;
  /**
   * The number of consecutive test passes to close the alert.
   *
   * @generated from protobuf field: int32 num_passes_to_disable_alert = 4;
   */
  numPassesToDisableAlert: number;
  /**
   * Custom subject for alert mails.
   *
   * @generated from protobuf field: string subject = 5;
   */
  subject: string;
  /**
   * Custom link for further help/instructions on debugging this alert.
   *
   * @generated from protobuf field: string debug_url = 6;
   */
  debugUrl: string;
  /**
   * Custom text to show for the debug link.
   *
   * @generated from protobuf field: string debug_message = 7;
   */
  debugMessage: string;
  /**
   * Wait time between emails. If unset or zero, an email will be sent only once
   * it becomes a consistent failure, and not again until it succeeds.
   * TestGrid does not pester about staleness
   *
   * @generated from protobuf field: int32 wait_minutes_between_emails = 8;
   */
  waitMinutesBetweenEmails: number;
  /**
   * A custom message
   *
   * @generated from protobuf field: string alert_mail_failure_message = 9;
   */
  alertMailFailureMessage: string;
}
/**
 * Configuration options for dashboard tab flakiness alerts.
 *
 * @generated from protobuf message DashboardTabFlakinessAlertOptions
 */
export interface DashboardTabFlakinessAlertOptions {
  /**
   * The minimum amount of flakiness needed to trigger a flakiness alert.
   * 0=Disable alerts
   * This is a percentage; expected values go from 0 to 100 (100 = 100% flaky)
   *
   * @generated from protobuf field: float minimum_flakiness_to_alert = 1;
   */
  minimumFlakinessToAlert: number;
  /**
   * The comma-separated addresses to send mail.
   *
   * @generated from protobuf field: string alert_mail_to_addresses = 2;
   */
  alertMailToAddresses: string;
  /**
   * Custom subject for alert mails.
   *
   * @generated from protobuf field: string subject = 3;
   */
  subject: string;
  /**
   * Minimum time between sending mails.
   *
   * @generated from protobuf field: int32 wait_minutes_between_emails = 4;
   */
  waitMinutesBetweenEmails: number;
  /**
   * A custom message
   * TODO(RonWeber): This should be a template
   *
   * @generated from protobuf field: string alert_mail_failure_message = 5;
   */
  alertMailFailureMessage: string;
}
/**
 * Configuration options for customizing the tab status calculation.
 *
 * @generated from protobuf message DashboardTabStatusCustomizationOptions
 */
export interface DashboardTabStatusCustomizationOptions {
  /**
   * Maximum amount of flakiness tolerated to categorize tab as acceptable.
   * Will supplement dashboard tab status message, and mark the tab as ACCEPTABLE in the dashboard group view.
   * 0 = Disable this option
   * This is configured as a percentage of valid (non-ignored) columns; expected values go
   * from 0.0 to 100.0 (100% = no passing columns is acceptable)
   *
   * @generated from protobuf field: float max_acceptable_flakiness = 1;
   */
  maxAcceptableFlakiness: number;
  /**
   * @generated from protobuf field: repeated DashboardTabStatusCustomizationOptions.IgnoredTestStatus ignored_test_statuses = 2;
   */
  ignoredTestStatuses: DashboardTabStatusCustomizationOptions_IgnoredTestStatus[];
  /**
   * Minimum number of runs required excluding ignored ones.
   * If the non-ignored columns is less than this, tab status will be PENDING.
   *
   * @generated from protobuf field: int32 min_acceptable_runs = 3;
   */
  minAcceptableRuns: number;
}
/**
 * Columns which contain cells with any status configure below will be ignored.
 * Ignored columns affect the computation of flakiness and non-ignored number of runs.
 *
 * @generated from protobuf enum DashboardTabStatusCustomizationOptions.IgnoredTestStatus
 */
export enum DashboardTabStatusCustomizationOptions_IgnoredTestStatus {
  /**
   * @generated from protobuf enum value: TEST_STATUS_UNSPECIFIED = 0;
   */
  TEST_STATUS_UNSPECIFIED = 0,
  /**
   * @generated from protobuf enum value: CATEGORIZED_ABORT = 1;
   */
  CATEGORIZED_ABORT = 1,
  /**
   * @generated from protobuf enum value: UNKNOWN = 2;
   */
  UNKNOWN = 2,
  /**
   * @generated from protobuf enum value: CANCEL = 3;
   */
  CANCEL = 3,
  /**
   * @generated from protobuf enum value: BLOCKED = 4;
   */
  BLOCKED = 4,
}
/**
 * Specifies a dashboard group.
 *
 * @generated from protobuf message DashboardGroup
 */
export interface DashboardGroup {
  /**
   * The name for the dashboard group.
   *
   * @generated from protobuf field: string name = 1;
   */
  name: string;
  /**
   * A list of names specifying dashboards to show links to in a separate tabbed
   * bar at the top of the page for each of the given dashboards.
   *
   * @generated from protobuf field: repeated string dashboard_names = 2;
   */
  dashboardNames: string[];
  /**
   * A description paragraph to be displayed.
   *
   * @generated from protobuf field: string description = 3;
   */
  description: string;
}
/**
 * A service configuration consisting of multiple test groups and dashboards.
 *
 * @generated from protobuf message Configuration
 */
export interface Configuration {
  /**
   * A list of groups of tests to gather.
   *
   * @generated from protobuf field: repeated TestGroup test_groups = 1;
   */
  testGroups: TestGroup[];
  /**
   * A list of all of the dashboards for a server.
   *
   * @generated from protobuf field: repeated Dashboard dashboards = 2;
   */
  dashboards: Dashboard[];
  /**
   * A list of all the dashboard groups for a server.
   *
   * @generated from protobuf field: repeated DashboardGroup dashboard_groups = 3;
   */
  dashboardGroups: DashboardGroup[];
}
/**
 * A grouping of configuration options for the flakiness analysis tool.
 * Later configuration options could include the ability to choose different
 * kinds of flakiness and choosing if and who to email a copy of the flakiness
 * report.
 *
 * @generated from protobuf message HealthAnalysisOptions
 */
export interface HealthAnalysisOptions {
  /**
   * Defaults to false; flakiness analysis is opt-in
   *
   * @generated from protobuf field: bool enable = 1;
   */
  enable: boolean;
  /**
   * Defines the number of days for one interval of analysis.
   * i.e. flakiness will be analyzed for the previous N days starting from Now,
   * and it will be compared to the calculated N days before that for trend
   * analysis.
   *
   * @generated from protobuf field: int32 days_of_analysis = 2;
   */
  daysOfAnalysis: number;
  /**
   * When to send healthiness emails out, uses cron string format.
   *
   * @generated from protobuf field: string email_schedule = 3;
   */
  emailSchedule: string;
  /**
   * A comma-separated list of healthiness email recipients.
   *
   * @generated from protobuf field: string email_recipients = 4;
   */
  emailRecipients: string;
  /**
   * A compilable regex string for grouping tests by name.
   * Works the same as the group-by-regex-mask option of base_options:
   * go/testgrid/users/dashboard_guide#grouping-tests
   * An empty string means no grouping.
   * e.g. test name: "//path/to/test - env", regex: ` - \w+`
   * The regex will match " - env" in the above test name and give a group of:
   * //path/to/test  <- Group Name
   *     - env       <- Group Member
   *
   * @generated from protobuf field: string grouping_regex = 5;
   */
  groupingRegex: string;
}
/**
 * The DefaultConfiguration Proto is deprecated, and will be deleted after Nov
 * 1, 2019. For defaulting behavior, use the yamlcfg library instead.
 *
 * @generated from protobuf message DefaultConfiguration
 */
export interface DefaultConfiguration {
  /**
   * A default testgroup with default initialization data
   *
   * @deprecated
   * @generated from protobuf field: TestGroup default_test_group = 1 [deprecated = true];
   */
  defaultTestGroup?: TestGroup;
  /**
   * A default dashboard tab with default initialization data
   *
   * @deprecated
   * @generated from protobuf field: DashboardTab default_dashboard_tab = 2 [deprecated = true];
   */
  defaultDashboardTab?: DashboardTab;
}
// @generated message type with reflection information, may provide speed optimized methods
class TestNameConfig$Type extends MessageType<TestNameConfig> {
  constructor() {
    super('TestNameConfig', [
      {
        no: 1,
        name: 'name_elements',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => TestNameConfig_NameElement,
      },
      {
        no: 2,
        name: 'name_format',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(value?: PartialMessage<TestNameConfig>): TestNameConfig {
    const message = { nameElements: [], nameFormat: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<TestNameConfig>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: TestNameConfig
  ): TestNameConfig {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* repeated TestNameConfig.NameElement name_elements */ 1:
          message.nameElements.push(
            TestNameConfig_NameElement.internalBinaryRead(
              reader,
              reader.uint32(),
              options
            )
          );
          break;
        case /* string name_format */ 2:
          message.nameFormat = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: TestNameConfig,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* repeated TestNameConfig.NameElement name_elements = 1; */
    for (let i = 0; i < message.nameElements.length; i++)
      TestNameConfig_NameElement.internalBinaryWrite(
        message.nameElements[i],
        writer.tag(1, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* string name_format = 2; */
    if (message.nameFormat !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.nameFormat);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message TestNameConfig
 */
export const TestNameConfig = new TestNameConfig$Type();
// @generated message type with reflection information, may provide speed optimized methods
class TestNameConfig_NameElement$Type extends MessageType<TestNameConfig_NameElement> {
  constructor() {
    super('TestNameConfig.NameElement', [
      { no: 1, name: 'labels', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 2,
        name: 'target_config',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      { no: 3, name: 'build_target', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
      { no: 4, name: 'tags', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 5,
        name: 'test_property',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(
    value?: PartialMessage<TestNameConfig_NameElement>
  ): TestNameConfig_NameElement {
    const message = {
      labels: '',
      targetConfig: '',
      buildTarget: false,
      tags: '',
      testProperty: '',
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<TestNameConfig_NameElement>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: TestNameConfig_NameElement
  ): TestNameConfig_NameElement {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string labels */ 1:
          message.labels = reader.string();
          break;
        case /* string target_config */ 2:
          message.targetConfig = reader.string();
          break;
        case /* bool build_target */ 3:
          message.buildTarget = reader.bool();
          break;
        case /* string tags */ 4:
          message.tags = reader.string();
          break;
        case /* string test_property */ 5:
          message.testProperty = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: TestNameConfig_NameElement,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string labels = 1; */
    if (message.labels !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.labels);
    /* string target_config = 2; */
    if (message.targetConfig !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.targetConfig);
    /* bool build_target = 3; */
    if (message.buildTarget !== false)
      writer.tag(3, WireType.Varint).bool(message.buildTarget);
    /* string tags = 4; */
    if (message.tags !== '')
      writer.tag(4, WireType.LengthDelimited).string(message.tags);
    /* string test_property = 5; */
    if (message.testProperty !== '')
      writer.tag(5, WireType.LengthDelimited).string(message.testProperty);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message TestNameConfig.NameElement
 */
export const TestNameConfig_NameElement = new TestNameConfig_NameElement$Type();
// @generated message type with reflection information, may provide speed optimized methods
class Notification$Type extends MessageType<Notification> {
  constructor() {
    super('Notification', [
      { no: 1, name: 'summary', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 2,
        name: 'context_link',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(value?: PartialMessage<Notification>): Notification {
    const message = { summary: '', contextLink: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<Notification>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: Notification
  ): Notification {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string summary */ 1:
          message.summary = reader.string();
          break;
        case /* string context_link */ 2:
          message.contextLink = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: Notification,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string summary = 1; */
    if (message.summary !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.summary);
    /* string context_link = 2; */
    if (message.contextLink !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.contextLink);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message Notification
 */
export const Notification = new Notification$Type();
// @generated message type with reflection information, may provide speed optimized methods
class TestGroup$Type extends MessageType<TestGroup> {
  constructor() {
    super('TestGroup', [
      { no: 1, name: 'name', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 2, name: 'gcs_prefix', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 3,
        name: 'days_of_results',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 4,
        name: 'ignore_pending',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      { no: 5, name: 'ignore_built', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
      {
        no: 6,
        name: 'tests_name_policy',
        kind: 'enum',
        T: () => ['TestGroup.TestsName', TestGroup_TestsName, 'TESTS_NAME_'],
      },
      {
        no: 8,
        name: 'ignore_test_substring',
        kind: 'scalar',
        repeat: 2 /*RepeatType.UNPACKED*/,
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 9,
        name: 'column_header',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => TestGroup_ColumnHeader,
      },
      {
        no: 10,
        name: 'fallback_grouping',
        kind: 'enum',
        T: () => [
          'TestGroup.FallbackGrouping',
          TestGroup_FallbackGrouping,
          'FALLBACK_GROUPING_',
        ],
      },
      {
        no: 11,
        name: 'alert_stale_results_hours',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 12,
        name: 'num_failures_to_alert',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 13,
        name: 'bug_component',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 14,
        name: 'code_search_path',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 15,
        name: 'num_columns_recent',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 16,
        name: 'use_test_metadata',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 17,
        name: 'alert_mail_to_addresses',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 18,
        name: 'alert_mail_subject',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 19,
        name: 'alert_mail_failure_message',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 20,
        name: 'alert_mail_debug_url',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 21,
        name: 'min_elapsed_minutes_between_mails',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 23,
        name: 'enable_flaky_status',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 60,
        name: 'disable_merged_status',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 24,
        name: 'use_kubernetes_client',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 62,
        name: 'disable_prowjob_analysis',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      { no: 25, name: 'is_external', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
      {
        no: 26,
        name: 'test_name_config',
        kind: 'message',
        T: () => TestNameConfig,
      },
      {
        no: 27,
        name: 'notifications',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => Notification,
      },
      {
        no: 29,
        name: 'primary_grouping',
        kind: 'enum',
        T: () => [
          'TestGroup.PrimaryGrouping',
          TestGroup_PrimaryGrouping,
          'PRIMARY_GROUPING_',
        ],
      },
      {
        no: 30,
        name: 'enable_test_methods',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 31,
        name: 'test_annotations',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => TestGroup_TestAnnotation,
      },
      {
        no: 32,
        name: 'max_test_methods_per_test',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 34,
        name: 'test_metadata_options',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => TestMetadataOptions,
      },
      {
        no: 35,
        name: 'test_tag_pattern',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 36,
        name: 'auto_bug_options',
        kind: 'message',
        T: () => AutoBugOptions,
      },
      {
        no: 37,
        name: 'max_test_runtime_hours',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 38,
        name: 'num_passes_to_disable_alert',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 39,
        name: 'link_bugs_by_group',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 41,
        name: 'test_method_properties',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => TestGroup_KeyValue,
      },
      { no: 42, name: 'gather_bugs', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
      {
        no: 43,
        name: 'short_text_metric',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 44,
        name: 'build_override_configuration_value',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 45,
        name: 'link_bugs_by_test_methods',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 46,
        name: 'test_method_match_regex',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 61,
        name: 'test_method_unmatch_regex',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 47,
        name: 'use_full_method_names',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 49,
        name: 'fallback_grouping_configuration_value',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 50,
        name: 'result_source',
        kind: 'message',
        T: () => TestGroup_ResultSource,
      },
      {
        no: 51,
        name: 'custom_evaluator_rule_set',
        kind: 'message',
        T: () => RuleSet,
      },
      {
        no: 52,
        name: 'read_state_from_storage',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 53,
        name: 'ignore_old_results',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      { no: 54, name: 'ignore_skip', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
      {
        no: 55,
        name: 'build_override_strftime',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 56,
        name: 'user_property',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(value?: PartialMessage<TestGroup>): TestGroup {
    const message = {
      name: '',
      gcsPrefix: '',
      daysOfResults: 0,
      ignorePending: false,
      ignoreBuilt: false,
      testsNamePolicy: 0,
      ignoreTestSubstring: [],
      columnHeader: [],
      fallbackGrouping: 0,
      alertStaleResultsHours: 0,
      numFailuresToAlert: 0,
      bugComponent: 0,
      codeSearchPath: '',
      numColumnsRecent: 0,
      useTestMetadata: false,
      alertMailToAddresses: '',
      alertMailSubject: '',
      alertMailFailureMessage: '',
      alertMailDebugUrl: '',
      minElapsedMinutesBetweenMails: 0,
      enableFlakyStatus: false,
      disableMergedStatus: false,
      useKubernetesClient: false,
      disableProwjobAnalysis: false,
      isExternal: false,
      notifications: [],
      primaryGrouping: 0,
      enableTestMethods: false,
      testAnnotations: [],
      maxTestMethodsPerTest: 0,
      testMetadataOptions: [],
      testTagPattern: '',
      maxTestRuntimeHours: 0,
      numPassesToDisableAlert: 0,
      linkBugsByGroup: false,
      testMethodProperties: [],
      gatherBugs: false,
      shortTextMetric: '',
      buildOverrideConfigurationValue: '',
      linkBugsByTestMethods: false,
      testMethodMatchRegex: '',
      testMethodUnmatchRegex: '',
      useFullMethodNames: false,
      fallbackGroupingConfigurationValue: '',
      readStateFromStorage: false,
      ignoreOldResults: false,
      ignoreSkip: false,
      buildOverrideStrftime: '',
      userProperty: '',
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<TestGroup>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: TestGroup
  ): TestGroup {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string name */ 1:
          message.name = reader.string();
          break;
        case /* string gcs_prefix */ 2:
          message.gcsPrefix = reader.string();
          break;
        case /* int32 days_of_results */ 3:
          message.daysOfResults = reader.int32();
          break;
        case /* bool ignore_pending */ 4:
          message.ignorePending = reader.bool();
          break;
        case /* bool ignore_built */ 5:
          message.ignoreBuilt = reader.bool();
          break;
        case /* TestGroup.TestsName tests_name_policy */ 6:
          message.testsNamePolicy = reader.int32();
          break;
        case /* repeated string ignore_test_substring */ 8:
          message.ignoreTestSubstring.push(reader.string());
          break;
        case /* repeated TestGroup.ColumnHeader column_header */ 9:
          message.columnHeader.push(
            TestGroup_ColumnHeader.internalBinaryRead(
              reader,
              reader.uint32(),
              options
            )
          );
          break;
        case /* TestGroup.FallbackGrouping fallback_grouping */ 10:
          message.fallbackGrouping = reader.int32();
          break;
        case /* int32 alert_stale_results_hours = 11 [deprecated = true];*/ 11:
          message.alertStaleResultsHours = reader.int32();
          break;
        case /* int32 num_failures_to_alert = 12 [deprecated = true];*/ 12:
          message.numFailuresToAlert = reader.int32();
          break;
        case /* int32 bug_component = 13 [deprecated = true];*/ 13:
          message.bugComponent = reader.int32();
          break;
        case /* string code_search_path */ 14:
          message.codeSearchPath = reader.string();
          break;
        case /* int32 num_columns_recent */ 15:
          message.numColumnsRecent = reader.int32();
          break;
        case /* bool use_test_metadata */ 16:
          message.useTestMetadata = reader.bool();
          break;
        case /* string alert_mail_to_addresses = 17 [deprecated = true];*/ 17:
          message.alertMailToAddresses = reader.string();
          break;
        case /* string alert_mail_subject = 18 [deprecated = true];*/ 18:
          message.alertMailSubject = reader.string();
          break;
        case /* string alert_mail_failure_message = 19 [deprecated = true];*/ 19:
          message.alertMailFailureMessage = reader.string();
          break;
        case /* string alert_mail_debug_url = 20 [deprecated = true];*/ 20:
          message.alertMailDebugUrl = reader.string();
          break;
        case /* int32 min_elapsed_minutes_between_mails = 21 [deprecated = true];*/ 21:
          message.minElapsedMinutesBetweenMails = reader.int32();
          break;
        case /* bool enable_flaky_status */ 23:
          message.enableFlakyStatus = reader.bool();
          break;
        case /* bool disable_merged_status */ 60:
          message.disableMergedStatus = reader.bool();
          break;
        case /* bool use_kubernetes_client = 24 [deprecated = true];*/ 24:
          message.useKubernetesClient = reader.bool();
          break;
        case /* bool disable_prowjob_analysis */ 62:
          message.disableProwjobAnalysis = reader.bool();
          break;
        case /* bool is_external */ 25:
          message.isExternal = reader.bool();
          break;
        case /* TestNameConfig test_name_config */ 26:
          message.testNameConfig = TestNameConfig.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.testNameConfig
          );
          break;
        case /* repeated Notification notifications */ 27:
          message.notifications.push(
            Notification.internalBinaryRead(reader, reader.uint32(), options)
          );
          break;
        case /* TestGroup.PrimaryGrouping primary_grouping */ 29:
          message.primaryGrouping = reader.int32();
          break;
        case /* bool enable_test_methods */ 30:
          message.enableTestMethods = reader.bool();
          break;
        case /* repeated TestGroup.TestAnnotation test_annotations */ 31:
          message.testAnnotations.push(
            TestGroup_TestAnnotation.internalBinaryRead(
              reader,
              reader.uint32(),
              options
            )
          );
          break;
        case /* int32 max_test_methods_per_test */ 32:
          message.maxTestMethodsPerTest = reader.int32();
          break;
        case /* repeated TestMetadataOptions test_metadata_options */ 34:
          message.testMetadataOptions.push(
            TestMetadataOptions.internalBinaryRead(
              reader,
              reader.uint32(),
              options
            )
          );
          break;
        case /* string test_tag_pattern */ 35:
          message.testTagPattern = reader.string();
          break;
        case /* AutoBugOptions auto_bug_options = 36 [deprecated = true];*/ 36:
          message.autoBugOptions = AutoBugOptions.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.autoBugOptions
          );
          break;
        case /* int32 max_test_runtime_hours */ 37:
          message.maxTestRuntimeHours = reader.int32();
          break;
        case /* int32 num_passes_to_disable_alert */ 38:
          message.numPassesToDisableAlert = reader.int32();
          break;
        case /* bool link_bugs_by_group */ 39:
          message.linkBugsByGroup = reader.bool();
          break;
        case /* repeated TestGroup.KeyValue test_method_properties */ 41:
          message.testMethodProperties.push(
            TestGroup_KeyValue.internalBinaryRead(
              reader,
              reader.uint32(),
              options
            )
          );
          break;
        case /* bool gather_bugs */ 42:
          message.gatherBugs = reader.bool();
          break;
        case /* string short_text_metric */ 43:
          message.shortTextMetric = reader.string();
          break;
        case /* string build_override_configuration_value */ 44:
          message.buildOverrideConfigurationValue = reader.string();
          break;
        case /* bool link_bugs_by_test_methods */ 45:
          message.linkBugsByTestMethods = reader.bool();
          break;
        case /* string test_method_match_regex */ 46:
          message.testMethodMatchRegex = reader.string();
          break;
        case /* string test_method_unmatch_regex */ 61:
          message.testMethodUnmatchRegex = reader.string();
          break;
        case /* bool use_full_method_names */ 47:
          message.useFullMethodNames = reader.bool();
          break;
        case /* string fallback_grouping_configuration_value */ 49:
          message.fallbackGroupingConfigurationValue = reader.string();
          break;
        case /* TestGroup.ResultSource result_source */ 50:
          message.resultSource = TestGroup_ResultSource.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.resultSource
          );
          break;
        case /* RuleSet custom_evaluator_rule_set */ 51:
          message.customEvaluatorRuleSet = RuleSet.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.customEvaluatorRuleSet
          );
          break;
        case /* bool read_state_from_storage */ 52:
          message.readStateFromStorage = reader.bool();
          break;
        case /* bool ignore_old_results */ 53:
          message.ignoreOldResults = reader.bool();
          break;
        case /* bool ignore_skip */ 54:
          message.ignoreSkip = reader.bool();
          break;
        case /* string build_override_strftime */ 55:
          message.buildOverrideStrftime = reader.string();
          break;
        case /* string user_property */ 56:
          message.userProperty = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: TestGroup,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string name = 1; */
    if (message.name !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.name);
    /* string gcs_prefix = 2; */
    if (message.gcsPrefix !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.gcsPrefix);
    /* int32 days_of_results = 3; */
    if (message.daysOfResults !== 0)
      writer.tag(3, WireType.Varint).int32(message.daysOfResults);
    /* bool ignore_pending = 4; */
    if (message.ignorePending !== false)
      writer.tag(4, WireType.Varint).bool(message.ignorePending);
    /* bool ignore_built = 5; */
    if (message.ignoreBuilt !== false)
      writer.tag(5, WireType.Varint).bool(message.ignoreBuilt);
    /* TestGroup.TestsName tests_name_policy = 6; */
    if (message.testsNamePolicy !== 0)
      writer.tag(6, WireType.Varint).int32(message.testsNamePolicy);
    /* repeated string ignore_test_substring = 8; */
    for (let i = 0; i < message.ignoreTestSubstring.length; i++)
      writer
        .tag(8, WireType.LengthDelimited)
        .string(message.ignoreTestSubstring[i]);
    /* repeated TestGroup.ColumnHeader column_header = 9; */
    for (let i = 0; i < message.columnHeader.length; i++)
      TestGroup_ColumnHeader.internalBinaryWrite(
        message.columnHeader[i],
        writer.tag(9, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* TestGroup.FallbackGrouping fallback_grouping = 10; */
    if (message.fallbackGrouping !== 0)
      writer.tag(10, WireType.Varint).int32(message.fallbackGrouping);
    /* int32 alert_stale_results_hours = 11 [deprecated = true]; */
    if (message.alertStaleResultsHours !== 0)
      writer.tag(11, WireType.Varint).int32(message.alertStaleResultsHours);
    /* int32 num_failures_to_alert = 12 [deprecated = true]; */
    if (message.numFailuresToAlert !== 0)
      writer.tag(12, WireType.Varint).int32(message.numFailuresToAlert);
    /* int32 bug_component = 13 [deprecated = true]; */
    if (message.bugComponent !== 0)
      writer.tag(13, WireType.Varint).int32(message.bugComponent);
    /* string code_search_path = 14; */
    if (message.codeSearchPath !== '')
      writer.tag(14, WireType.LengthDelimited).string(message.codeSearchPath);
    /* int32 num_columns_recent = 15; */
    if (message.numColumnsRecent !== 0)
      writer.tag(15, WireType.Varint).int32(message.numColumnsRecent);
    /* bool use_test_metadata = 16; */
    if (message.useTestMetadata !== false)
      writer.tag(16, WireType.Varint).bool(message.useTestMetadata);
    /* string alert_mail_to_addresses = 17 [deprecated = true]; */
    if (message.alertMailToAddresses !== '')
      writer
        .tag(17, WireType.LengthDelimited)
        .string(message.alertMailToAddresses);
    /* string alert_mail_subject = 18 [deprecated = true]; */
    if (message.alertMailSubject !== '')
      writer.tag(18, WireType.LengthDelimited).string(message.alertMailSubject);
    /* string alert_mail_failure_message = 19 [deprecated = true]; */
    if (message.alertMailFailureMessage !== '')
      writer
        .tag(19, WireType.LengthDelimited)
        .string(message.alertMailFailureMessage);
    /* string alert_mail_debug_url = 20 [deprecated = true]; */
    if (message.alertMailDebugUrl !== '')
      writer
        .tag(20, WireType.LengthDelimited)
        .string(message.alertMailDebugUrl);
    /* int32 min_elapsed_minutes_between_mails = 21 [deprecated = true]; */
    if (message.minElapsedMinutesBetweenMails !== 0)
      writer
        .tag(21, WireType.Varint)
        .int32(message.minElapsedMinutesBetweenMails);
    /* bool enable_flaky_status = 23; */
    if (message.enableFlakyStatus !== false)
      writer.tag(23, WireType.Varint).bool(message.enableFlakyStatus);
    /* bool disable_merged_status = 60; */
    if (message.disableMergedStatus !== false)
      writer.tag(60, WireType.Varint).bool(message.disableMergedStatus);
    /* bool use_kubernetes_client = 24 [deprecated = true]; */
    if (message.useKubernetesClient !== false)
      writer.tag(24, WireType.Varint).bool(message.useKubernetesClient);
    /* bool disable_prowjob_analysis = 62; */
    if (message.disableProwjobAnalysis !== false)
      writer.tag(62, WireType.Varint).bool(message.disableProwjobAnalysis);
    /* bool is_external = 25; */
    if (message.isExternal !== false)
      writer.tag(25, WireType.Varint).bool(message.isExternal);
    /* TestNameConfig test_name_config = 26; */
    if (message.testNameConfig)
      TestNameConfig.internalBinaryWrite(
        message.testNameConfig,
        writer.tag(26, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* repeated Notification notifications = 27; */
    for (let i = 0; i < message.notifications.length; i++)
      Notification.internalBinaryWrite(
        message.notifications[i],
        writer.tag(27, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* TestGroup.PrimaryGrouping primary_grouping = 29; */
    if (message.primaryGrouping !== 0)
      writer.tag(29, WireType.Varint).int32(message.primaryGrouping);
    /* bool enable_test_methods = 30; */
    if (message.enableTestMethods !== false)
      writer.tag(30, WireType.Varint).bool(message.enableTestMethods);
    /* repeated TestGroup.TestAnnotation test_annotations = 31; */
    for (let i = 0; i < message.testAnnotations.length; i++)
      TestGroup_TestAnnotation.internalBinaryWrite(
        message.testAnnotations[i],
        writer.tag(31, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* int32 max_test_methods_per_test = 32; */
    if (message.maxTestMethodsPerTest !== 0)
      writer.tag(32, WireType.Varint).int32(message.maxTestMethodsPerTest);
    /* repeated TestMetadataOptions test_metadata_options = 34; */
    for (let i = 0; i < message.testMetadataOptions.length; i++)
      TestMetadataOptions.internalBinaryWrite(
        message.testMetadataOptions[i],
        writer.tag(34, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* string test_tag_pattern = 35; */
    if (message.testTagPattern !== '')
      writer.tag(35, WireType.LengthDelimited).string(message.testTagPattern);
    /* AutoBugOptions auto_bug_options = 36 [deprecated = true]; */
    if (message.autoBugOptions)
      AutoBugOptions.internalBinaryWrite(
        message.autoBugOptions,
        writer.tag(36, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* int32 max_test_runtime_hours = 37; */
    if (message.maxTestRuntimeHours !== 0)
      writer.tag(37, WireType.Varint).int32(message.maxTestRuntimeHours);
    /* int32 num_passes_to_disable_alert = 38; */
    if (message.numPassesToDisableAlert !== 0)
      writer.tag(38, WireType.Varint).int32(message.numPassesToDisableAlert);
    /* bool link_bugs_by_group = 39; */
    if (message.linkBugsByGroup !== false)
      writer.tag(39, WireType.Varint).bool(message.linkBugsByGroup);
    /* repeated TestGroup.KeyValue test_method_properties = 41; */
    for (let i = 0; i < message.testMethodProperties.length; i++)
      TestGroup_KeyValue.internalBinaryWrite(
        message.testMethodProperties[i],
        writer.tag(41, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* bool gather_bugs = 42; */
    if (message.gatherBugs !== false)
      writer.tag(42, WireType.Varint).bool(message.gatherBugs);
    /* string short_text_metric = 43; */
    if (message.shortTextMetric !== '')
      writer.tag(43, WireType.LengthDelimited).string(message.shortTextMetric);
    /* string build_override_configuration_value = 44; */
    if (message.buildOverrideConfigurationValue !== '')
      writer
        .tag(44, WireType.LengthDelimited)
        .string(message.buildOverrideConfigurationValue);
    /* bool link_bugs_by_test_methods = 45; */
    if (message.linkBugsByTestMethods !== false)
      writer.tag(45, WireType.Varint).bool(message.linkBugsByTestMethods);
    /* string test_method_match_regex = 46; */
    if (message.testMethodMatchRegex !== '')
      writer
        .tag(46, WireType.LengthDelimited)
        .string(message.testMethodMatchRegex);
    /* string test_method_unmatch_regex = 61; */
    if (message.testMethodUnmatchRegex !== '')
      writer
        .tag(61, WireType.LengthDelimited)
        .string(message.testMethodUnmatchRegex);
    /* bool use_full_method_names = 47; */
    if (message.useFullMethodNames !== false)
      writer.tag(47, WireType.Varint).bool(message.useFullMethodNames);
    /* string fallback_grouping_configuration_value = 49; */
    if (message.fallbackGroupingConfigurationValue !== '')
      writer
        .tag(49, WireType.LengthDelimited)
        .string(message.fallbackGroupingConfigurationValue);
    /* TestGroup.ResultSource result_source = 50; */
    if (message.resultSource)
      TestGroup_ResultSource.internalBinaryWrite(
        message.resultSource,
        writer.tag(50, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* RuleSet custom_evaluator_rule_set = 51; */
    if (message.customEvaluatorRuleSet)
      RuleSet.internalBinaryWrite(
        message.customEvaluatorRuleSet,
        writer.tag(51, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* bool read_state_from_storage = 52; */
    if (message.readStateFromStorage !== false)
      writer.tag(52, WireType.Varint).bool(message.readStateFromStorage);
    /* bool ignore_old_results = 53; */
    if (message.ignoreOldResults !== false)
      writer.tag(53, WireType.Varint).bool(message.ignoreOldResults);
    /* bool ignore_skip = 54; */
    if (message.ignoreSkip !== false)
      writer.tag(54, WireType.Varint).bool(message.ignoreSkip);
    /* string build_override_strftime = 55; */
    if (message.buildOverrideStrftime !== '')
      writer
        .tag(55, WireType.LengthDelimited)
        .string(message.buildOverrideStrftime);
    /* string user_property = 56; */
    if (message.userProperty !== '')
      writer.tag(56, WireType.LengthDelimited).string(message.userProperty);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message TestGroup
 */
export const TestGroup = new TestGroup$Type();
// @generated message type with reflection information, may provide speed optimized methods
class TestGroup_ColumnHeader$Type extends MessageType<TestGroup_ColumnHeader> {
  constructor() {
    super('TestGroup.ColumnHeader', [
      { no: 1, name: 'label', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 2, name: 'property', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 3,
        name: 'configuration_value',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 4,
        name: 'list_all_values',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
    ]);
  }
  create(
    value?: PartialMessage<TestGroup_ColumnHeader>
  ): TestGroup_ColumnHeader {
    const message = {
      label: '',
      property: '',
      configurationValue: '',
      listAllValues: false,
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<TestGroup_ColumnHeader>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: TestGroup_ColumnHeader
  ): TestGroup_ColumnHeader {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string label */ 1:
          message.label = reader.string();
          break;
        case /* string property */ 2:
          message.property = reader.string();
          break;
        case /* string configuration_value */ 3:
          message.configurationValue = reader.string();
          break;
        case /* bool list_all_values */ 4:
          message.listAllValues = reader.bool();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: TestGroup_ColumnHeader,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string label = 1; */
    if (message.label !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.label);
    /* string property = 2; */
    if (message.property !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.property);
    /* string configuration_value = 3; */
    if (message.configurationValue !== '')
      writer
        .tag(3, WireType.LengthDelimited)
        .string(message.configurationValue);
    /* bool list_all_values = 4; */
    if (message.listAllValues !== false)
      writer.tag(4, WireType.Varint).bool(message.listAllValues);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message TestGroup.ColumnHeader
 */
export const TestGroup_ColumnHeader = new TestGroup_ColumnHeader$Type();
// @generated message type with reflection information, may provide speed optimized methods
class TestGroup_TestAnnotation$Type extends MessageType<TestGroup_TestAnnotation> {
  constructor() {
    super('TestGroup.TestAnnotation', [
      { no: 1, name: 'short_text', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 2,
        name: 'property_name',
        kind: 'scalar',
        oneof: 'shortTextMessageSource',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(
    value?: PartialMessage<TestGroup_TestAnnotation>
  ): TestGroup_TestAnnotation {
    const message = {
      shortText: '',
      shortTextMessageSource: { oneofKind: undefined },
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<TestGroup_TestAnnotation>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: TestGroup_TestAnnotation
  ): TestGroup_TestAnnotation {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string short_text */ 1:
          message.shortText = reader.string();
          break;
        case /* string property_name */ 2:
          message.shortTextMessageSource = {
            oneofKind: 'propertyName',
            propertyName: reader.string(),
          };
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: TestGroup_TestAnnotation,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string short_text = 1; */
    if (message.shortText !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.shortText);
    /* string property_name = 2; */
    if (message.shortTextMessageSource.oneofKind === 'propertyName')
      writer
        .tag(2, WireType.LengthDelimited)
        .string(message.shortTextMessageSource.propertyName);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message TestGroup.TestAnnotation
 */
export const TestGroup_TestAnnotation = new TestGroup_TestAnnotation$Type();
// @generated message type with reflection information, may provide speed optimized methods
class TestGroup_KeyValue$Type extends MessageType<TestGroup_KeyValue> {
  constructor() {
    super('TestGroup.KeyValue', [
      { no: 1, name: 'key', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 2, name: 'value', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(value?: PartialMessage<TestGroup_KeyValue>): TestGroup_KeyValue {
    const message = { key: '', value: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<TestGroup_KeyValue>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: TestGroup_KeyValue
  ): TestGroup_KeyValue {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string key */ 1:
          message.key = reader.string();
          break;
        case /* string value */ 2:
          message.value = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: TestGroup_KeyValue,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string key = 1; */
    if (message.key !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.key);
    /* string value = 2; */
    if (message.value !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.value);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message TestGroup.KeyValue
 */
export const TestGroup_KeyValue = new TestGroup_KeyValue$Type();
// @generated message type with reflection information, may provide speed optimized methods
class TestGroup_ResultSource$Type extends MessageType<TestGroup_ResultSource> {
  constructor() {
    super('TestGroup.ResultSource', [
      {
        no: 2,
        name: 'gcs_config',
        kind: 'message',
        oneof: 'resultSourceConfig',
        T: () => GCSConfig,
      },
    ]);
  }
  create(
    value?: PartialMessage<TestGroup_ResultSource>
  ): TestGroup_ResultSource {
    const message = { resultSourceConfig: { oneofKind: undefined } };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<TestGroup_ResultSource>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: TestGroup_ResultSource
  ): TestGroup_ResultSource {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* GCSConfig gcs_config */ 2:
          message.resultSourceConfig = {
            oneofKind: 'gcsConfig',
            gcsConfig: GCSConfig.internalBinaryRead(
              reader,
              reader.uint32(),
              options,
              (message.resultSourceConfig as any).gcsConfig
            ),
          };
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: TestGroup_ResultSource,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* GCSConfig gcs_config = 2; */
    if (message.resultSourceConfig.oneofKind === 'gcsConfig')
      GCSConfig.internalBinaryWrite(
        message.resultSourceConfig.gcsConfig,
        writer.tag(2, WireType.LengthDelimited).fork(),
        options
      ).join();
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message TestGroup.ResultSource
 */
export const TestGroup_ResultSource = new TestGroup_ResultSource$Type();
// @generated message type with reflection information, may provide speed optimized methods
class GCSConfig$Type extends MessageType<GCSConfig> {
  constructor() {
    super('GCSConfig', [
      { no: 1, name: 'gcs_prefix', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 2,
        name: 'pubsub_project',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 3,
        name: 'pubsub_subscription',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(value?: PartialMessage<GCSConfig>): GCSConfig {
    const message = {
      gcsPrefix: '',
      pubsubProject: '',
      pubsubSubscription: '',
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<GCSConfig>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: GCSConfig
  ): GCSConfig {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string gcs_prefix */ 1:
          message.gcsPrefix = reader.string();
          break;
        case /* string pubsub_project */ 2:
          message.pubsubProject = reader.string();
          break;
        case /* string pubsub_subscription */ 3:
          message.pubsubSubscription = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: GCSConfig,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string gcs_prefix = 1; */
    if (message.gcsPrefix !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.gcsPrefix);
    /* string pubsub_project = 2; */
    if (message.pubsubProject !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.pubsubProject);
    /* string pubsub_subscription = 3; */
    if (message.pubsubSubscription !== '')
      writer
        .tag(3, WireType.LengthDelimited)
        .string(message.pubsubSubscription);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message GCSConfig
 */
export const GCSConfig = new GCSConfig$Type();
// @generated message type with reflection information, may provide speed optimized methods
class TestMetadataOptions$Type extends MessageType<TestMetadataOptions> {
  constructor() {
    super('TestMetadataOptions', [
      {
        no: 1,
        name: 'test_name_regex',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 2,
        name: 'bug_component',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      { no: 3, name: 'owner', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 4,
        name: 'cc',
        kind: 'scalar',
        repeat: 2 /*RepeatType.UNPACKED*/,
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 5,
        name: 'message_regex',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(value?: PartialMessage<TestMetadataOptions>): TestMetadataOptions {
    const message = {
      testNameRegex: '',
      bugComponent: 0,
      owner: '',
      cc: [],
      messageRegex: '',
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<TestMetadataOptions>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: TestMetadataOptions
  ): TestMetadataOptions {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string test_name_regex */ 1:
          message.testNameRegex = reader.string();
          break;
        case /* int32 bug_component */ 2:
          message.bugComponent = reader.int32();
          break;
        case /* string owner */ 3:
          message.owner = reader.string();
          break;
        case /* repeated string cc */ 4:
          message.cc.push(reader.string());
          break;
        case /* string message_regex */ 5:
          message.messageRegex = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: TestMetadataOptions,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string test_name_regex = 1; */
    if (message.testNameRegex !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.testNameRegex);
    /* int32 bug_component = 2; */
    if (message.bugComponent !== 0)
      writer.tag(2, WireType.Varint).int32(message.bugComponent);
    /* string owner = 3; */
    if (message.owner !== '')
      writer.tag(3, WireType.LengthDelimited).string(message.owner);
    /* repeated string cc = 4; */
    for (let i = 0; i < message.cc.length; i++)
      writer.tag(4, WireType.LengthDelimited).string(message.cc[i]);
    /* string message_regex = 5; */
    if (message.messageRegex !== '')
      writer.tag(5, WireType.LengthDelimited).string(message.messageRegex);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message TestMetadataOptions
 */
export const TestMetadataOptions = new TestMetadataOptions$Type();
// @generated message type with reflection information, may provide speed optimized methods
class AutoBugOptions$Type extends MessageType<AutoBugOptions> {
  constructor() {
    super('AutoBugOptions', [
      {
        no: 10,
        name: 'beta_autobug_component',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      { no: 1, name: 'auto_close', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
      {
        no: 2,
        name: 'hotlist_ids',
        kind: 'scalar',
        repeat: 1 /*RepeatType.PACKED*/,
        T: 3 /*ScalarType.INT64*/,
      },
      {
        no: 3,
        name: 'priority',
        kind: 'enum',
        T: () => ['AutoBugOptions.Priority', AutoBugOptions_Priority],
      },
      {
        no: 4,
        name: 'hotlist_ids_from_source',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => HotlistIdFromSource,
      },
      {
        no: 5,
        name: 'file_individual',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 6,
        name: 'singleton_autobug',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 7,
        name: 'max_allowed_individual_bugs',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      { no: 8, name: 'file_overall', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
      {
        no: 9,
        name: 'default_test_metadata',
        kind: 'message',
        T: () => AutoBugOptions_DefaultTestMetadata,
      },
      {
        no: 11,
        name: 'advanced_test_metadata',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      { no: 12, name: 'file_stale', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
      {
        no: 13,
        name: 'ignore_overall',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      { no: 14, name: 'note', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(value?: PartialMessage<AutoBugOptions>): AutoBugOptions {
    const message = {
      betaAutobugComponent: 0,
      autoClose: false,
      hotlistIds: [],
      priority: 0,
      hotlistIdsFromSource: [],
      fileIndividual: false,
      singletonAutobug: false,
      maxAllowedIndividualBugs: 0,
      fileOverall: false,
      advancedTestMetadata: false,
      fileStale: false,
      ignoreOverall: false,
      note: '',
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<AutoBugOptions>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: AutoBugOptions
  ): AutoBugOptions {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* int32 beta_autobug_component */ 10:
          message.betaAutobugComponent = reader.int32();
          break;
        case /* bool auto_close */ 1:
          message.autoClose = reader.bool();
          break;
        case /* repeated int64 hotlist_ids */ 2:
          if (wireType === WireType.LengthDelimited)
            for (let e = reader.int32() + reader.pos; reader.pos < e; )
              message.hotlistIds.push(reader.int64().toString());
          else message.hotlistIds.push(reader.int64().toString());
          break;
        case /* AutoBugOptions.Priority priority */ 3:
          message.priority = reader.int32();
          break;
        case /* repeated HotlistIdFromSource hotlist_ids_from_source = 4 [deprecated = true];*/ 4:
          message.hotlistIdsFromSource.push(
            HotlistIdFromSource.internalBinaryRead(
              reader,
              reader.uint32(),
              options
            )
          );
          break;
        case /* bool file_individual */ 5:
          message.fileIndividual = reader.bool();
          break;
        case /* bool singleton_autobug */ 6:
          message.singletonAutobug = reader.bool();
          break;
        case /* int32 max_allowed_individual_bugs */ 7:
          message.maxAllowedIndividualBugs = reader.int32();
          break;
        case /* bool file_overall */ 8:
          message.fileOverall = reader.bool();
          break;
        case /* AutoBugOptions.DefaultTestMetadata default_test_metadata */ 9:
          message.defaultTestMetadata =
            AutoBugOptions_DefaultTestMetadata.internalBinaryRead(
              reader,
              reader.uint32(),
              options,
              message.defaultTestMetadata
            );
          break;
        case /* bool advanced_test_metadata */ 11:
          message.advancedTestMetadata = reader.bool();
          break;
        case /* bool file_stale */ 12:
          message.fileStale = reader.bool();
          break;
        case /* bool ignore_overall */ 13:
          message.ignoreOverall = reader.bool();
          break;
        case /* string note */ 14:
          message.note = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: AutoBugOptions,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* int32 beta_autobug_component = 10; */
    if (message.betaAutobugComponent !== 0)
      writer.tag(10, WireType.Varint).int32(message.betaAutobugComponent);
    /* bool auto_close = 1; */
    if (message.autoClose !== false)
      writer.tag(1, WireType.Varint).bool(message.autoClose);
    /* repeated int64 hotlist_ids = 2; */
    if (message.hotlistIds.length) {
      writer.tag(2, WireType.LengthDelimited).fork();
      for (let i = 0; i < message.hotlistIds.length; i++)
        writer.int64(message.hotlistIds[i]);
      writer.join();
    }
    /* AutoBugOptions.Priority priority = 3; */
    if (message.priority !== 0)
      writer.tag(3, WireType.Varint).int32(message.priority);
    /* repeated HotlistIdFromSource hotlist_ids_from_source = 4 [deprecated = true]; */
    for (let i = 0; i < message.hotlistIdsFromSource.length; i++)
      HotlistIdFromSource.internalBinaryWrite(
        message.hotlistIdsFromSource[i],
        writer.tag(4, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* bool file_individual = 5; */
    if (message.fileIndividual !== false)
      writer.tag(5, WireType.Varint).bool(message.fileIndividual);
    /* bool singleton_autobug = 6; */
    if (message.singletonAutobug !== false)
      writer.tag(6, WireType.Varint).bool(message.singletonAutobug);
    /* int32 max_allowed_individual_bugs = 7; */
    if (message.maxAllowedIndividualBugs !== 0)
      writer.tag(7, WireType.Varint).int32(message.maxAllowedIndividualBugs);
    /* bool file_overall = 8; */
    if (message.fileOverall !== false)
      writer.tag(8, WireType.Varint).bool(message.fileOverall);
    /* AutoBugOptions.DefaultTestMetadata default_test_metadata = 9; */
    if (message.defaultTestMetadata)
      AutoBugOptions_DefaultTestMetadata.internalBinaryWrite(
        message.defaultTestMetadata,
        writer.tag(9, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* bool advanced_test_metadata = 11; */
    if (message.advancedTestMetadata !== false)
      writer.tag(11, WireType.Varint).bool(message.advancedTestMetadata);
    /* bool file_stale = 12; */
    if (message.fileStale !== false)
      writer.tag(12, WireType.Varint).bool(message.fileStale);
    /* bool ignore_overall = 13; */
    if (message.ignoreOverall !== false)
      writer.tag(13, WireType.Varint).bool(message.ignoreOverall);
    /* string note = 14; */
    if (message.note !== '')
      writer.tag(14, WireType.LengthDelimited).string(message.note);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message AutoBugOptions
 */
export const AutoBugOptions = new AutoBugOptions$Type();
// @generated message type with reflection information, may provide speed optimized methods
class AutoBugOptions_DefaultTestMetadata$Type extends MessageType<AutoBugOptions_DefaultTestMetadata> {
  constructor() {
    super('AutoBugOptions.DefaultTestMetadata', [
      {
        no: 1,
        name: 'bug_component',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      { no: 2, name: 'owner', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 3,
        name: 'cc',
        kind: 'scalar',
        repeat: 2 /*RepeatType.UNPACKED*/,
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(
    value?: PartialMessage<AutoBugOptions_DefaultTestMetadata>
  ): AutoBugOptions_DefaultTestMetadata {
    const message = { bugComponent: 0, owner: '', cc: [] };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<AutoBugOptions_DefaultTestMetadata>(
        this,
        message,
        value
      );
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: AutoBugOptions_DefaultTestMetadata
  ): AutoBugOptions_DefaultTestMetadata {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* int32 bug_component */ 1:
          message.bugComponent = reader.int32();
          break;
        case /* string owner */ 2:
          message.owner = reader.string();
          break;
        case /* repeated string cc */ 3:
          message.cc.push(reader.string());
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: AutoBugOptions_DefaultTestMetadata,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* int32 bug_component = 1; */
    if (message.bugComponent !== 0)
      writer.tag(1, WireType.Varint).int32(message.bugComponent);
    /* string owner = 2; */
    if (message.owner !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.owner);
    /* repeated string cc = 3; */
    for (let i = 0; i < message.cc.length; i++)
      writer.tag(3, WireType.LengthDelimited).string(message.cc[i]);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message AutoBugOptions.DefaultTestMetadata
 */
export const AutoBugOptions_DefaultTestMetadata =
  new AutoBugOptions_DefaultTestMetadata$Type();
// @generated message type with reflection information, may provide speed optimized methods
class HotlistIdFromSource$Type extends MessageType<HotlistIdFromSource> {
  constructor() {
    super('HotlistIdFromSource', [
      {
        no: 1,
        name: 'value',
        kind: 'scalar',
        oneof: 'hotlistIdSource',
        T: 3 /*ScalarType.INT64*/,
      },
      {
        no: 2,
        name: 'label',
        kind: 'scalar',
        oneof: 'hotlistIdSource',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(value?: PartialMessage<HotlistIdFromSource>): HotlistIdFromSource {
    const message = { hotlistIdSource: { oneofKind: undefined } };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<HotlistIdFromSource>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: HotlistIdFromSource
  ): HotlistIdFromSource {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* int64 value */ 1:
          message.hotlistIdSource = {
            oneofKind: 'value',
            value: reader.int64().toString(),
          };
          break;
        case /* string label */ 2:
          message.hotlistIdSource = {
            oneofKind: 'label',
            label: reader.string(),
          };
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: HotlistIdFromSource,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* int64 value = 1; */
    if (message.hotlistIdSource.oneofKind === 'value')
      writer.tag(1, WireType.Varint).int64(message.hotlistIdSource.value);
    /* string label = 2; */
    if (message.hotlistIdSource.oneofKind === 'label')
      writer
        .tag(2, WireType.LengthDelimited)
        .string(message.hotlistIdSource.label);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message HotlistIdFromSource
 */
export const HotlistIdFromSource = new HotlistIdFromSource$Type();
// @generated message type with reflection information, may provide speed optimized methods
class Dashboard$Type extends MessageType<Dashboard> {
  constructor() {
    super('Dashboard', [
      {
        no: 1,
        name: 'dashboard_tab',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => DashboardTab,
      },
      { no: 2, name: 'name', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 3,
        name: 'notifications',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => Notification,
      },
      {
        no: 5,
        name: 'default_tab',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 8,
        name: 'downplay_failing_tabs',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 6,
        name: 'highlight_failing_tabs',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 7,
        name: 'highlight_today',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 9,
        name: 'description',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(value?: PartialMessage<Dashboard>): Dashboard {
    const message = {
      dashboardTab: [],
      name: '',
      notifications: [],
      defaultTab: '',
      downplayFailingTabs: false,
      highlightFailingTabs: false,
      highlightToday: false,
      description: '',
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<Dashboard>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: Dashboard
  ): Dashboard {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* repeated DashboardTab dashboard_tab */ 1:
          message.dashboardTab.push(
            DashboardTab.internalBinaryRead(reader, reader.uint32(), options)
          );
          break;
        case /* string name */ 2:
          message.name = reader.string();
          break;
        case /* repeated Notification notifications */ 3:
          message.notifications.push(
            Notification.internalBinaryRead(reader, reader.uint32(), options)
          );
          break;
        case /* string default_tab */ 5:
          message.defaultTab = reader.string();
          break;
        case /* bool downplay_failing_tabs */ 8:
          message.downplayFailingTabs = reader.bool();
          break;
        case /* bool highlight_failing_tabs = 6 [deprecated = true];*/ 6:
          message.highlightFailingTabs = reader.bool();
          break;
        case /* bool highlight_today */ 7:
          message.highlightToday = reader.bool();
          break;
        case /* string description */ 9:
          message.description = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: Dashboard,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* repeated DashboardTab dashboard_tab = 1; */
    for (let i = 0; i < message.dashboardTab.length; i++)
      DashboardTab.internalBinaryWrite(
        message.dashboardTab[i],
        writer.tag(1, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* string name = 2; */
    if (message.name !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.name);
    /* repeated Notification notifications = 3; */
    for (let i = 0; i < message.notifications.length; i++)
      Notification.internalBinaryWrite(
        message.notifications[i],
        writer.tag(3, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* string default_tab = 5; */
    if (message.defaultTab !== '')
      writer.tag(5, WireType.LengthDelimited).string(message.defaultTab);
    /* bool downplay_failing_tabs = 8; */
    if (message.downplayFailingTabs !== false)
      writer.tag(8, WireType.Varint).bool(message.downplayFailingTabs);
    /* bool highlight_failing_tabs = 6 [deprecated = true]; */
    if (message.highlightFailingTabs !== false)
      writer.tag(6, WireType.Varint).bool(message.highlightFailingTabs);
    /* bool highlight_today = 7; */
    if (message.highlightToday !== false)
      writer.tag(7, WireType.Varint).bool(message.highlightToday);
    /* string description = 9; */
    if (message.description !== '')
      writer.tag(9, WireType.LengthDelimited).string(message.description);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message Dashboard
 */
export const Dashboard = new Dashboard$Type();
// @generated message type with reflection information, may provide speed optimized methods
class LinkTemplate$Type extends MessageType<LinkTemplate> {
  constructor() {
    super('LinkTemplate', [
      { no: 1, name: 'url', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 2,
        name: 'options',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => LinkOptionsTemplate,
      },
      { no: 3, name: 'name', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(value?: PartialMessage<LinkTemplate>): LinkTemplate {
    const message = { url: '', options: [], name: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<LinkTemplate>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: LinkTemplate
  ): LinkTemplate {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string url */ 1:
          message.url = reader.string();
          break;
        case /* repeated LinkOptionsTemplate options */ 2:
          message.options.push(
            LinkOptionsTemplate.internalBinaryRead(
              reader,
              reader.uint32(),
              options
            )
          );
          break;
        case /* string name */ 3:
          message.name = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: LinkTemplate,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string url = 1; */
    if (message.url !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.url);
    /* repeated LinkOptionsTemplate options = 2; */
    for (let i = 0; i < message.options.length; i++)
      LinkOptionsTemplate.internalBinaryWrite(
        message.options[i],
        writer.tag(2, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* string name = 3; */
    if (message.name !== '')
      writer.tag(3, WireType.LengthDelimited).string(message.name);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message LinkTemplate
 */
export const LinkTemplate = new LinkTemplate$Type();
// @generated message type with reflection information, may provide speed optimized methods
class LinkOptionsTemplate$Type extends MessageType<LinkOptionsTemplate> {
  constructor() {
    super('LinkOptionsTemplate', [
      { no: 1, name: 'key', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 2, name: 'value', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(value?: PartialMessage<LinkOptionsTemplate>): LinkOptionsTemplate {
    const message = { key: '', value: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<LinkOptionsTemplate>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: LinkOptionsTemplate
  ): LinkOptionsTemplate {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string key */ 1:
          message.key = reader.string();
          break;
        case /* string value */ 2:
          message.value = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: LinkOptionsTemplate,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string key = 1; */
    if (message.key !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.key);
    /* string value = 2; */
    if (message.value !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.value);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message LinkOptionsTemplate
 */
export const LinkOptionsTemplate = new LinkOptionsTemplate$Type();
// @generated message type with reflection information, may provide speed optimized methods
class DashboardTab$Type extends MessageType<DashboardTab> {
  constructor() {
    super('DashboardTab', [
      { no: 1, name: 'name', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 2,
        name: 'test_group_name',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 3,
        name: 'bug_component',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 4,
        name: 'code_search_path',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 5,
        name: 'num_columns_recent',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 6,
        name: 'base_options',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 7,
        name: 'open_test_template',
        kind: 'message',
        T: () => LinkTemplate,
      },
      {
        no: 8,
        name: 'file_bug_template',
        kind: 'message',
        T: () => LinkTemplate,
      },
      {
        no: 9,
        name: 'attach_bug_template',
        kind: 'message',
        T: () => LinkTemplate,
      },
      {
        no: 10,
        name: 'results_text',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 11,
        name: 'results_url_template',
        kind: 'message',
        T: () => LinkTemplate,
      },
      {
        no: 12,
        name: 'code_search_url_template',
        kind: 'message',
        T: () => LinkTemplate,
      },
      {
        no: 13,
        name: 'description',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 14,
        name: 'tabular_names_regex',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 15,
        name: 'alert_options',
        kind: 'message',
        T: () => DashboardTabAlertOptions,
      },
      {
        no: 24,
        name: 'flakiness_alert_options',
        kind: 'message',
        T: () => DashboardTabFlakinessAlertOptions,
      },
      {
        no: 26,
        name: 'status_customization_options',
        kind: 'message',
        T: () => DashboardTabStatusCustomizationOptions,
      },
      {
        no: 16,
        name: 'about_dashboard_url',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 17,
        name: 'open_bug_template',
        kind: 'message',
        T: () => LinkTemplate,
      },
      {
        no: 18,
        name: 'auto_file_bugs',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 19,
        name: 'display_local_time',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 20,
        name: 'context_menu_template',
        kind: 'message',
        T: () => LinkTemplate,
      },
      {
        no: 21,
        name: 'broken_column_threshold',
        kind: 'scalar',
        T: 2 /*ScalarType.FLOAT*/,
      },
      {
        no: 22,
        name: 'beta_autobug_options',
        kind: 'message',
        T: () => AutoBugOptions,
      },
      {
        no: 23,
        name: 'health_analysis_options',
        kind: 'message',
        T: () => HealthAnalysisOptions,
      },
      {
        no: 25,
        name: 'column_diff_link_templates',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => LinkTemplate,
      },
    ]);
  }
  create(value?: PartialMessage<DashboardTab>): DashboardTab {
    const message = {
      name: '',
      testGroupName: '',
      bugComponent: 0,
      codeSearchPath: '',
      numColumnsRecent: 0,
      baseOptions: '',
      resultsText: '',
      description: '',
      tabularNamesRegex: '',
      aboutDashboardUrl: '',
      autoFileBugs: false,
      displayLocalTime: false,
      brokenColumnThreshold: 0,
      columnDiffLinkTemplates: [],
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<DashboardTab>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: DashboardTab
  ): DashboardTab {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string name */ 1:
          message.name = reader.string();
          break;
        case /* string test_group_name */ 2:
          message.testGroupName = reader.string();
          break;
        case /* int32 bug_component */ 3:
          message.bugComponent = reader.int32();
          break;
        case /* string code_search_path */ 4:
          message.codeSearchPath = reader.string();
          break;
        case /* int32 num_columns_recent */ 5:
          message.numColumnsRecent = reader.int32();
          break;
        case /* string base_options */ 6:
          message.baseOptions = reader.string();
          break;
        case /* LinkTemplate open_test_template */ 7:
          message.openTestTemplate = LinkTemplate.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.openTestTemplate
          );
          break;
        case /* LinkTemplate file_bug_template */ 8:
          message.fileBugTemplate = LinkTemplate.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.fileBugTemplate
          );
          break;
        case /* LinkTemplate attach_bug_template */ 9:
          message.attachBugTemplate = LinkTemplate.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.attachBugTemplate
          );
          break;
        case /* string results_text */ 10:
          message.resultsText = reader.string();
          break;
        case /* LinkTemplate results_url_template */ 11:
          message.resultsUrlTemplate = LinkTemplate.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.resultsUrlTemplate
          );
          break;
        case /* LinkTemplate code_search_url_template */ 12:
          message.codeSearchUrlTemplate = LinkTemplate.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.codeSearchUrlTemplate
          );
          break;
        case /* string description */ 13:
          message.description = reader.string();
          break;
        case /* string tabular_names_regex */ 14:
          message.tabularNamesRegex = reader.string();
          break;
        case /* DashboardTabAlertOptions alert_options */ 15:
          message.alertOptions = DashboardTabAlertOptions.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.alertOptions
          );
          break;
        case /* DashboardTabFlakinessAlertOptions flakiness_alert_options */ 24:
          message.flakinessAlertOptions =
            DashboardTabFlakinessAlertOptions.internalBinaryRead(
              reader,
              reader.uint32(),
              options,
              message.flakinessAlertOptions
            );
          break;
        case /* DashboardTabStatusCustomizationOptions status_customization_options */ 26:
          message.statusCustomizationOptions =
            DashboardTabStatusCustomizationOptions.internalBinaryRead(
              reader,
              reader.uint32(),
              options,
              message.statusCustomizationOptions
            );
          break;
        case /* string about_dashboard_url */ 16:
          message.aboutDashboardUrl = reader.string();
          break;
        case /* LinkTemplate open_bug_template */ 17:
          message.openBugTemplate = LinkTemplate.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.openBugTemplate
          );
          break;
        case /* bool auto_file_bugs */ 18:
          message.autoFileBugs = reader.bool();
          break;
        case /* bool display_local_time */ 19:
          message.displayLocalTime = reader.bool();
          break;
        case /* LinkTemplate context_menu_template */ 20:
          message.contextMenuTemplate = LinkTemplate.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.contextMenuTemplate
          );
          break;
        case /* float broken_column_threshold */ 21:
          message.brokenColumnThreshold = reader.float();
          break;
        case /* AutoBugOptions beta_autobug_options */ 22:
          message.betaAutobugOptions = AutoBugOptions.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.betaAutobugOptions
          );
          break;
        case /* HealthAnalysisOptions health_analysis_options */ 23:
          message.healthAnalysisOptions =
            HealthAnalysisOptions.internalBinaryRead(
              reader,
              reader.uint32(),
              options,
              message.healthAnalysisOptions
            );
          break;
        case /* repeated LinkTemplate column_diff_link_templates */ 25:
          message.columnDiffLinkTemplates.push(
            LinkTemplate.internalBinaryRead(reader, reader.uint32(), options)
          );
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: DashboardTab,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string name = 1; */
    if (message.name !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.name);
    /* string test_group_name = 2; */
    if (message.testGroupName !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.testGroupName);
    /* int32 bug_component = 3; */
    if (message.bugComponent !== 0)
      writer.tag(3, WireType.Varint).int32(message.bugComponent);
    /* string code_search_path = 4; */
    if (message.codeSearchPath !== '')
      writer.tag(4, WireType.LengthDelimited).string(message.codeSearchPath);
    /* int32 num_columns_recent = 5; */
    if (message.numColumnsRecent !== 0)
      writer.tag(5, WireType.Varint).int32(message.numColumnsRecent);
    /* string base_options = 6; */
    if (message.baseOptions !== '')
      writer.tag(6, WireType.LengthDelimited).string(message.baseOptions);
    /* LinkTemplate open_test_template = 7; */
    if (message.openTestTemplate)
      LinkTemplate.internalBinaryWrite(
        message.openTestTemplate,
        writer.tag(7, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* LinkTemplate file_bug_template = 8; */
    if (message.fileBugTemplate)
      LinkTemplate.internalBinaryWrite(
        message.fileBugTemplate,
        writer.tag(8, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* LinkTemplate attach_bug_template = 9; */
    if (message.attachBugTemplate)
      LinkTemplate.internalBinaryWrite(
        message.attachBugTemplate,
        writer.tag(9, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* string results_text = 10; */
    if (message.resultsText !== '')
      writer.tag(10, WireType.LengthDelimited).string(message.resultsText);
    /* LinkTemplate results_url_template = 11; */
    if (message.resultsUrlTemplate)
      LinkTemplate.internalBinaryWrite(
        message.resultsUrlTemplate,
        writer.tag(11, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* LinkTemplate code_search_url_template = 12; */
    if (message.codeSearchUrlTemplate)
      LinkTemplate.internalBinaryWrite(
        message.codeSearchUrlTemplate,
        writer.tag(12, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* string description = 13; */
    if (message.description !== '')
      writer.tag(13, WireType.LengthDelimited).string(message.description);
    /* string tabular_names_regex = 14; */
    if (message.tabularNamesRegex !== '')
      writer
        .tag(14, WireType.LengthDelimited)
        .string(message.tabularNamesRegex);
    /* DashboardTabAlertOptions alert_options = 15; */
    if (message.alertOptions)
      DashboardTabAlertOptions.internalBinaryWrite(
        message.alertOptions,
        writer.tag(15, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* DashboardTabFlakinessAlertOptions flakiness_alert_options = 24; */
    if (message.flakinessAlertOptions)
      DashboardTabFlakinessAlertOptions.internalBinaryWrite(
        message.flakinessAlertOptions,
        writer.tag(24, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* DashboardTabStatusCustomizationOptions status_customization_options = 26; */
    if (message.statusCustomizationOptions)
      DashboardTabStatusCustomizationOptions.internalBinaryWrite(
        message.statusCustomizationOptions,
        writer.tag(26, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* string about_dashboard_url = 16; */
    if (message.aboutDashboardUrl !== '')
      writer
        .tag(16, WireType.LengthDelimited)
        .string(message.aboutDashboardUrl);
    /* LinkTemplate open_bug_template = 17; */
    if (message.openBugTemplate)
      LinkTemplate.internalBinaryWrite(
        message.openBugTemplate,
        writer.tag(17, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* bool auto_file_bugs = 18; */
    if (message.autoFileBugs !== false)
      writer.tag(18, WireType.Varint).bool(message.autoFileBugs);
    /* bool display_local_time = 19; */
    if (message.displayLocalTime !== false)
      writer.tag(19, WireType.Varint).bool(message.displayLocalTime);
    /* LinkTemplate context_menu_template = 20; */
    if (message.contextMenuTemplate)
      LinkTemplate.internalBinaryWrite(
        message.contextMenuTemplate,
        writer.tag(20, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* float broken_column_threshold = 21; */
    if (message.brokenColumnThreshold !== 0)
      writer.tag(21, WireType.Bit32).float(message.brokenColumnThreshold);
    /* AutoBugOptions beta_autobug_options = 22; */
    if (message.betaAutobugOptions)
      AutoBugOptions.internalBinaryWrite(
        message.betaAutobugOptions,
        writer.tag(22, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* HealthAnalysisOptions health_analysis_options = 23; */
    if (message.healthAnalysisOptions)
      HealthAnalysisOptions.internalBinaryWrite(
        message.healthAnalysisOptions,
        writer.tag(23, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* repeated LinkTemplate column_diff_link_templates = 25; */
    for (let i = 0; i < message.columnDiffLinkTemplates.length; i++)
      LinkTemplate.internalBinaryWrite(
        message.columnDiffLinkTemplates[i],
        writer.tag(25, WireType.LengthDelimited).fork(),
        options
      ).join();
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message DashboardTab
 */
export const DashboardTab = new DashboardTab$Type();
// @generated message type with reflection information, may provide speed optimized methods
class DashboardTabAlertOptions$Type extends MessageType<DashboardTabAlertOptions> {
  constructor() {
    super('DashboardTabAlertOptions', [
      {
        no: 1,
        name: 'alert_stale_results_hours',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 2,
        name: 'num_failures_to_alert',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 3,
        name: 'alert_mail_to_addresses',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 4,
        name: 'num_passes_to_disable_alert',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      { no: 5, name: 'subject', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 6, name: 'debug_url', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 7,
        name: 'debug_message',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 8,
        name: 'wait_minutes_between_emails',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 9,
        name: 'alert_mail_failure_message',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(
    value?: PartialMessage<DashboardTabAlertOptions>
  ): DashboardTabAlertOptions {
    const message = {
      alertStaleResultsHours: 0,
      numFailuresToAlert: 0,
      alertMailToAddresses: '',
      numPassesToDisableAlert: 0,
      subject: '',
      debugUrl: '',
      debugMessage: '',
      waitMinutesBetweenEmails: 0,
      alertMailFailureMessage: '',
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<DashboardTabAlertOptions>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: DashboardTabAlertOptions
  ): DashboardTabAlertOptions {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* int32 alert_stale_results_hours */ 1:
          message.alertStaleResultsHours = reader.int32();
          break;
        case /* int32 num_failures_to_alert */ 2:
          message.numFailuresToAlert = reader.int32();
          break;
        case /* string alert_mail_to_addresses */ 3:
          message.alertMailToAddresses = reader.string();
          break;
        case /* int32 num_passes_to_disable_alert */ 4:
          message.numPassesToDisableAlert = reader.int32();
          break;
        case /* string subject */ 5:
          message.subject = reader.string();
          break;
        case /* string debug_url */ 6:
          message.debugUrl = reader.string();
          break;
        case /* string debug_message */ 7:
          message.debugMessage = reader.string();
          break;
        case /* int32 wait_minutes_between_emails */ 8:
          message.waitMinutesBetweenEmails = reader.int32();
          break;
        case /* string alert_mail_failure_message */ 9:
          message.alertMailFailureMessage = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: DashboardTabAlertOptions,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* int32 alert_stale_results_hours = 1; */
    if (message.alertStaleResultsHours !== 0)
      writer.tag(1, WireType.Varint).int32(message.alertStaleResultsHours);
    /* int32 num_failures_to_alert = 2; */
    if (message.numFailuresToAlert !== 0)
      writer.tag(2, WireType.Varint).int32(message.numFailuresToAlert);
    /* string alert_mail_to_addresses = 3; */
    if (message.alertMailToAddresses !== '')
      writer
        .tag(3, WireType.LengthDelimited)
        .string(message.alertMailToAddresses);
    /* int32 num_passes_to_disable_alert = 4; */
    if (message.numPassesToDisableAlert !== 0)
      writer.tag(4, WireType.Varint).int32(message.numPassesToDisableAlert);
    /* string subject = 5; */
    if (message.subject !== '')
      writer.tag(5, WireType.LengthDelimited).string(message.subject);
    /* string debug_url = 6; */
    if (message.debugUrl !== '')
      writer.tag(6, WireType.LengthDelimited).string(message.debugUrl);
    /* string debug_message = 7; */
    if (message.debugMessage !== '')
      writer.tag(7, WireType.LengthDelimited).string(message.debugMessage);
    /* int32 wait_minutes_between_emails = 8; */
    if (message.waitMinutesBetweenEmails !== 0)
      writer.tag(8, WireType.Varint).int32(message.waitMinutesBetweenEmails);
    /* string alert_mail_failure_message = 9; */
    if (message.alertMailFailureMessage !== '')
      writer
        .tag(9, WireType.LengthDelimited)
        .string(message.alertMailFailureMessage);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message DashboardTabAlertOptions
 */
export const DashboardTabAlertOptions = new DashboardTabAlertOptions$Type();
// @generated message type with reflection information, may provide speed optimized methods
class DashboardTabFlakinessAlertOptions$Type extends MessageType<DashboardTabFlakinessAlertOptions> {
  constructor() {
    super('DashboardTabFlakinessAlertOptions', [
      {
        no: 1,
        name: 'minimum_flakiness_to_alert',
        kind: 'scalar',
        T: 2 /*ScalarType.FLOAT*/,
      },
      {
        no: 2,
        name: 'alert_mail_to_addresses',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      { no: 3, name: 'subject', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 4,
        name: 'wait_minutes_between_emails',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 5,
        name: 'alert_mail_failure_message',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(
    value?: PartialMessage<DashboardTabFlakinessAlertOptions>
  ): DashboardTabFlakinessAlertOptions {
    const message = {
      minimumFlakinessToAlert: 0,
      alertMailToAddresses: '',
      subject: '',
      waitMinutesBetweenEmails: 0,
      alertMailFailureMessage: '',
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<DashboardTabFlakinessAlertOptions>(
        this,
        message,
        value
      );
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: DashboardTabFlakinessAlertOptions
  ): DashboardTabFlakinessAlertOptions {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* float minimum_flakiness_to_alert */ 1:
          message.minimumFlakinessToAlert = reader.float();
          break;
        case /* string alert_mail_to_addresses */ 2:
          message.alertMailToAddresses = reader.string();
          break;
        case /* string subject */ 3:
          message.subject = reader.string();
          break;
        case /* int32 wait_minutes_between_emails */ 4:
          message.waitMinutesBetweenEmails = reader.int32();
          break;
        case /* string alert_mail_failure_message */ 5:
          message.alertMailFailureMessage = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: DashboardTabFlakinessAlertOptions,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* float minimum_flakiness_to_alert = 1; */
    if (message.minimumFlakinessToAlert !== 0)
      writer.tag(1, WireType.Bit32).float(message.minimumFlakinessToAlert);
    /* string alert_mail_to_addresses = 2; */
    if (message.alertMailToAddresses !== '')
      writer
        .tag(2, WireType.LengthDelimited)
        .string(message.alertMailToAddresses);
    /* string subject = 3; */
    if (message.subject !== '')
      writer.tag(3, WireType.LengthDelimited).string(message.subject);
    /* int32 wait_minutes_between_emails = 4; */
    if (message.waitMinutesBetweenEmails !== 0)
      writer.tag(4, WireType.Varint).int32(message.waitMinutesBetweenEmails);
    /* string alert_mail_failure_message = 5; */
    if (message.alertMailFailureMessage !== '')
      writer
        .tag(5, WireType.LengthDelimited)
        .string(message.alertMailFailureMessage);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message DashboardTabFlakinessAlertOptions
 */
export const DashboardTabFlakinessAlertOptions =
  new DashboardTabFlakinessAlertOptions$Type();
// @generated message type with reflection information, may provide speed optimized methods
class DashboardTabStatusCustomizationOptions$Type extends MessageType<DashboardTabStatusCustomizationOptions> {
  constructor() {
    super('DashboardTabStatusCustomizationOptions', [
      {
        no: 1,
        name: 'max_acceptable_flakiness',
        kind: 'scalar',
        T: 2 /*ScalarType.FLOAT*/,
      },
      {
        no: 2,
        name: 'ignored_test_statuses',
        kind: 'enum',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => [
          'DashboardTabStatusCustomizationOptions.IgnoredTestStatus',
          DashboardTabStatusCustomizationOptions_IgnoredTestStatus,
        ],
      },
      {
        no: 3,
        name: 'min_acceptable_runs',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
    ]);
  }
  create(
    value?: PartialMessage<DashboardTabStatusCustomizationOptions>
  ): DashboardTabStatusCustomizationOptions {
    const message = {
      maxAcceptableFlakiness: 0,
      ignoredTestStatuses: [],
      minAcceptableRuns: 0,
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<DashboardTabStatusCustomizationOptions>(
        this,
        message,
        value
      );
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: DashboardTabStatusCustomizationOptions
  ): DashboardTabStatusCustomizationOptions {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* float max_acceptable_flakiness */ 1:
          message.maxAcceptableFlakiness = reader.float();
          break;
        case /* repeated DashboardTabStatusCustomizationOptions.IgnoredTestStatus ignored_test_statuses */ 2:
          if (wireType === WireType.LengthDelimited)
            for (let e = reader.int32() + reader.pos; reader.pos < e; )
              message.ignoredTestStatuses.push(reader.int32());
          else message.ignoredTestStatuses.push(reader.int32());
          break;
        case /* int32 min_acceptable_runs */ 3:
          message.minAcceptableRuns = reader.int32();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: DashboardTabStatusCustomizationOptions,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* float max_acceptable_flakiness = 1; */
    if (message.maxAcceptableFlakiness !== 0)
      writer.tag(1, WireType.Bit32).float(message.maxAcceptableFlakiness);
    /* repeated DashboardTabStatusCustomizationOptions.IgnoredTestStatus ignored_test_statuses = 2; */
    if (message.ignoredTestStatuses.length) {
      writer.tag(2, WireType.LengthDelimited).fork();
      for (let i = 0; i < message.ignoredTestStatuses.length; i++)
        writer.int32(message.ignoredTestStatuses[i]);
      writer.join();
    }
    /* int32 min_acceptable_runs = 3; */
    if (message.minAcceptableRuns !== 0)
      writer.tag(3, WireType.Varint).int32(message.minAcceptableRuns);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message DashboardTabStatusCustomizationOptions
 */
export const DashboardTabStatusCustomizationOptions =
  new DashboardTabStatusCustomizationOptions$Type();
// @generated message type with reflection information, may provide speed optimized methods
class DashboardGroup$Type extends MessageType<DashboardGroup> {
  constructor() {
    super('DashboardGroup', [
      { no: 1, name: 'name', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 2,
        name: 'dashboard_names',
        kind: 'scalar',
        repeat: 2 /*RepeatType.UNPACKED*/,
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 3,
        name: 'description',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(value?: PartialMessage<DashboardGroup>): DashboardGroup {
    const message = { name: '', dashboardNames: [], description: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<DashboardGroup>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: DashboardGroup
  ): DashboardGroup {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string name */ 1:
          message.name = reader.string();
          break;
        case /* repeated string dashboard_names */ 2:
          message.dashboardNames.push(reader.string());
          break;
        case /* string description */ 3:
          message.description = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: DashboardGroup,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string name = 1; */
    if (message.name !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.name);
    /* repeated string dashboard_names = 2; */
    for (let i = 0; i < message.dashboardNames.length; i++)
      writer.tag(2, WireType.LengthDelimited).string(message.dashboardNames[i]);
    /* string description = 3; */
    if (message.description !== '')
      writer.tag(3, WireType.LengthDelimited).string(message.description);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message DashboardGroup
 */
export const DashboardGroup = new DashboardGroup$Type();
// @generated message type with reflection information, may provide speed optimized methods
class Configuration$Type extends MessageType<Configuration> {
  constructor() {
    super('Configuration', [
      {
        no: 1,
        name: 'test_groups',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => TestGroup,
      },
      {
        no: 2,
        name: 'dashboards',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => Dashboard,
      },
      {
        no: 3,
        name: 'dashboard_groups',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => DashboardGroup,
      },
    ]);
  }
  create(value?: PartialMessage<Configuration>): Configuration {
    const message = { testGroups: [], dashboards: [], dashboardGroups: [] };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<Configuration>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: Configuration
  ): Configuration {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* repeated TestGroup test_groups */ 1:
          message.testGroups.push(
            TestGroup.internalBinaryRead(reader, reader.uint32(), options)
          );
          break;
        case /* repeated Dashboard dashboards */ 2:
          message.dashboards.push(
            Dashboard.internalBinaryRead(reader, reader.uint32(), options)
          );
          break;
        case /* repeated DashboardGroup dashboard_groups */ 3:
          message.dashboardGroups.push(
            DashboardGroup.internalBinaryRead(reader, reader.uint32(), options)
          );
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: Configuration,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* repeated TestGroup test_groups = 1; */
    for (let i = 0; i < message.testGroups.length; i++)
      TestGroup.internalBinaryWrite(
        message.testGroups[i],
        writer.tag(1, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* repeated Dashboard dashboards = 2; */
    for (let i = 0; i < message.dashboards.length; i++)
      Dashboard.internalBinaryWrite(
        message.dashboards[i],
        writer.tag(2, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* repeated DashboardGroup dashboard_groups = 3; */
    for (let i = 0; i < message.dashboardGroups.length; i++)
      DashboardGroup.internalBinaryWrite(
        message.dashboardGroups[i],
        writer.tag(3, WireType.LengthDelimited).fork(),
        options
      ).join();
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message Configuration
 */
export const Configuration = new Configuration$Type();
// @generated message type with reflection information, may provide speed optimized methods
class HealthAnalysisOptions$Type extends MessageType<HealthAnalysisOptions> {
  constructor() {
    super('HealthAnalysisOptions', [
      { no: 1, name: 'enable', kind: 'scalar', T: 8 /*ScalarType.BOOL*/ },
      {
        no: 2,
        name: 'days_of_analysis',
        kind: 'scalar',
        T: 5 /*ScalarType.INT32*/,
      },
      {
        no: 3,
        name: 'email_schedule',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 4,
        name: 'email_recipients',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 5,
        name: 'grouping_regex',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(value?: PartialMessage<HealthAnalysisOptions>): HealthAnalysisOptions {
    const message = {
      enable: false,
      daysOfAnalysis: 0,
      emailSchedule: '',
      emailRecipients: '',
      groupingRegex: '',
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<HealthAnalysisOptions>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: HealthAnalysisOptions
  ): HealthAnalysisOptions {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* bool enable */ 1:
          message.enable = reader.bool();
          break;
        case /* int32 days_of_analysis */ 2:
          message.daysOfAnalysis = reader.int32();
          break;
        case /* string email_schedule */ 3:
          message.emailSchedule = reader.string();
          break;
        case /* string email_recipients */ 4:
          message.emailRecipients = reader.string();
          break;
        case /* string grouping_regex */ 5:
          message.groupingRegex = reader.string();
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: HealthAnalysisOptions,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* bool enable = 1; */
    if (message.enable !== false)
      writer.tag(1, WireType.Varint).bool(message.enable);
    /* int32 days_of_analysis = 2; */
    if (message.daysOfAnalysis !== 0)
      writer.tag(2, WireType.Varint).int32(message.daysOfAnalysis);
    /* string email_schedule = 3; */
    if (message.emailSchedule !== '')
      writer.tag(3, WireType.LengthDelimited).string(message.emailSchedule);
    /* string email_recipients = 4; */
    if (message.emailRecipients !== '')
      writer.tag(4, WireType.LengthDelimited).string(message.emailRecipients);
    /* string grouping_regex = 5; */
    if (message.groupingRegex !== '')
      writer.tag(5, WireType.LengthDelimited).string(message.groupingRegex);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message HealthAnalysisOptions
 */
export const HealthAnalysisOptions = new HealthAnalysisOptions$Type();
// @generated message type with reflection information, may provide speed optimized methods
class DefaultConfiguration$Type extends MessageType<DefaultConfiguration> {
  constructor() {
    super('DefaultConfiguration', [
      {
        no: 1,
        name: 'default_test_group',
        kind: 'message',
        T: () => TestGroup,
      },
      {
        no: 2,
        name: 'default_dashboard_tab',
        kind: 'message',
        T: () => DashboardTab,
      },
    ]);
  }
  create(value?: PartialMessage<DefaultConfiguration>): DefaultConfiguration {
    const message = {};
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<DefaultConfiguration>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: DefaultConfiguration
  ): DefaultConfiguration {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* TestGroup default_test_group = 1 [deprecated = true];*/ 1:
          message.defaultTestGroup = TestGroup.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.defaultTestGroup
          );
          break;
        case /* DashboardTab default_dashboard_tab = 2 [deprecated = true];*/ 2:
          message.defaultDashboardTab = DashboardTab.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.defaultDashboardTab
          );
          break;
        default:
          let u = options.readUnknownField;
          if (u === 'throw')
            throw new globalThis.Error(
              `Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`
            );
          let d = reader.skip(wireType);
          if (u !== false)
            (u === true ? UnknownFieldHandler.onRead : u)(
              this.typeName,
              message,
              fieldNo,
              wireType,
              d
            );
      }
    }
    return message;
  }
  internalBinaryWrite(
    message: DefaultConfiguration,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* TestGroup default_test_group = 1 [deprecated = true]; */
    if (message.defaultTestGroup)
      TestGroup.internalBinaryWrite(
        message.defaultTestGroup,
        writer.tag(1, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* DashboardTab default_dashboard_tab = 2 [deprecated = true]; */
    if (message.defaultDashboardTab)
      DashboardTab.internalBinaryWrite(
        message.defaultDashboardTab,
        writer.tag(2, WireType.LengthDelimited).fork(),
        options
      ).join();
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message DefaultConfiguration
 */
export const DefaultConfiguration = new DefaultConfiguration$Type();
