// @generated by protobuf-ts 2.8.2 with parameter long_type_string
// @generated from protobuf file "pb/api/v1/data.proto" (package "testgrid.api.v1", syntax proto3)
// tslint:disable
import { ServiceType } from '@protobuf-ts/runtime-rpc';
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 { AlertInfo } from '../../state/state';
import { Timestamp } from '../../../google/protobuf/timestamp';
import { Notification } from '../../config/config';
/**
 * @generated from protobuf message testgrid.api.v1.ListDashboardRequest
 */
export interface ListDashboardRequest {
  /**
   * @generated from protobuf field: string scope = 1;
   */
  scope: string;
}
/**
 * @generated from protobuf message testgrid.api.v1.ListDashboardResponse
 */
export interface ListDashboardResponse {
  /**
   * @generated from protobuf field: repeated testgrid.api.v1.Resource dashboards = 1;
   */
  dashboards: Resource[];
}
/**
 * @generated from protobuf message testgrid.api.v1.ListDashboardGroupRequest
 */
export interface ListDashboardGroupRequest {
  /**
   * @generated from protobuf field: string scope = 1;
   */
  scope: string;
}
/**
 * @generated from protobuf message testgrid.api.v1.ListDashboardGroupResponse
 */
export interface ListDashboardGroupResponse {
  /**
   * @generated from protobuf field: repeated testgrid.api.v1.Resource dashboard_groups = 1;
   */
  dashboardGroups: Resource[];
}
/**
 * @generated from protobuf message testgrid.api.v1.ListDashboardTabsRequest
 */
export interface ListDashboardTabsRequest {
  /**
   * @generated from protobuf field: string scope = 1;
   */
  scope: string;
  /**
   * @generated from protobuf field: string dashboard = 2;
   */
  dashboard: string;
}
/**
 * @generated from protobuf message testgrid.api.v1.ListDashboardTabsResponse
 */
export interface ListDashboardTabsResponse {
  /**
   * @generated from protobuf field: repeated testgrid.api.v1.Resource dashboard_tabs = 1;
   */
  dashboardTabs: Resource[];
}
/**
 * @generated from protobuf message testgrid.api.v1.GetDashboardRequest
 */
export interface GetDashboardRequest {
  /**
   * @generated from protobuf field: string scope = 1;
   */
  scope: string;
  /**
   * @generated from protobuf field: string dashboard = 2;
   */
  dashboard: string;
}
/**
 * @generated from protobuf message testgrid.api.v1.GetDashboardResponse
 */
export interface GetDashboardResponse {
  /**
   * 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 = 1;
   */
  notifications: Notification[];
  /**
   * Control which tab is displayed when first opening a dashboard.
   * Defaults to Summary
   *
   * @generated from protobuf field: string default_tab = 2;
   */
  defaultTab: string;
  /**
   * Controls whether to suppress highlighting of failing tabs.
   *
   * @generated from protobuf field: bool suppress_failing_tabs = 3;
   */
  suppressFailingTabs: boolean;
  /**
   * Controls whether to apply special highlighting to result header columns for
   * the current day.
   *
   * @generated from protobuf field: bool highlight_today = 4;
   */
  highlightToday: boolean;
}
/**
 * @generated from protobuf message testgrid.api.v1.GetDashboardGroupRequest
 */
export interface GetDashboardGroupRequest {
  /**
   * @generated from protobuf field: string scope = 1;
   */
  scope: string;
  /**
   * @generated from protobuf field: string dashboard_group = 2;
   */
  dashboardGroup: string;
}
/**
 * @generated from protobuf message testgrid.api.v1.GetDashboardGroupResponse
 */
export interface GetDashboardGroupResponse {
  /**
   * @generated from protobuf field: repeated testgrid.api.v1.Resource dashboards = 1;
   */
  dashboards: Resource[];
}
/**
 * @generated from protobuf message testgrid.api.v1.ListHeadersRequest
 */
export interface ListHeadersRequest {
  /**
   * @generated from protobuf field: string scope = 1;
   */
  scope: string;
  /**
   * @generated from protobuf field: string dashboard = 2;
   */
  dashboard: string;
  /**
   * @generated from protobuf field: string tab = 3;
   */
  tab: string;
}
/**
 * @generated from protobuf message testgrid.api.v1.ListHeadersResponse
 */
export interface ListHeadersResponse {
  /**
   * @generated from protobuf field: repeated testgrid.api.v1.ListHeadersResponse.Header headers = 1;
   */
  headers: ListHeadersResponse_Header[];
}
/**
 * @generated from protobuf message testgrid.api.v1.ListHeadersResponse.Header
 */
export interface ListHeadersResponse_Header {
  /**
   * Unique instance of the job, typically BUILD_NUMBER from prow or a guid
   *
   * @generated from protobuf field: string build = 1;
   */
  build: string;
  /**
   * Name associated with the column (such as the run/invocation ID). No two
   * columns should have the same build_id and name. The name field allows the
   * display of multiple columns with the same build_id.
   *
   * @generated from protobuf field: string name = 2;
   */
  name: string;
  /**
   * When the build started running
   *
   * @generated from protobuf field: google.protobuf.Timestamp started = 3;
   */
  started?: Timestamp;
  /**
   * Additional custom headers like commit, image used, etc.
   *
   * @generated from protobuf field: repeated string extra = 4;
   */
  extra: string[];
  /**
   * Custom hotlist ids.
   *
   * @generated from protobuf field: string hotlist_ids = 5;
   */
  hotlistIds: string;
}
/**
 * @generated from protobuf message testgrid.api.v1.ListRowsRequest
 */
export interface ListRowsRequest {
  /**
   * @generated from protobuf field: string scope = 1;
   */
  scope: string;
  /**
   * @generated from protobuf field: string dashboard = 2;
   */
  dashboard: string;
  /**
   * @generated from protobuf field: string tab = 3;
   */
  tab: string;
}
/**
 * @generated from protobuf message testgrid.api.v1.ListRowsResponse
 */
export interface ListRowsResponse {
  /**
   * @generated from protobuf field: repeated testgrid.api.v1.ListRowsResponse.Row rows = 1;
   */
  rows: ListRowsResponse_Row[];
}
/**
 * @generated from protobuf message testgrid.api.v1.ListRowsResponse.Row
 */
export interface ListRowsResponse_Row {
  /**
   * Display name of the test case
   *
   * @generated from protobuf field: string name = 1;
   */
  name: string;
  /**
   * Historical results of the test case. Unencoded.
   *
   * @generated from protobuf field: repeated testgrid.api.v1.ListRowsResponse.Cell cells = 2;
   */
  cells: ListRowsResponse_Cell[];
  /**
   * Issue or Bug IDs associated with the test case
   *
   * @generated from protobuf field: repeated string issues = 3;
   */
  issues: string[];
  /**
   * Alert associated with the test case
   *
   * @generated from protobuf field: AlertInfo alert = 4;
   */
  alert?: AlertInfo;
}
/**
 * @generated from protobuf message testgrid.api.v1.ListRowsResponse.Cell
 */
export interface ListRowsResponse_Cell {
  /**
   * @generated from protobuf field: int32 result = 1;
   */
  result: number;
  /**
   * @generated from protobuf field: string cell_id = 2;
   */
  cellId: string;
  /**
   * @generated from protobuf field: string message = 3;
   */
  message: string;
  /**
   * @generated from protobuf field: string icon = 4;
   */
  icon: string;
}
/**
 * A Resource is a REST resource, often returned by a LIST command
 * It includes the name of the resource and a link to the resource
 *
 * @generated from protobuf message testgrid.api.v1.Resource
 */
export interface Resource {
  /**
   * @generated from protobuf field: string name = 1;
   */
  name: string;
  /**
   * @generated from protobuf field: string link = 2;
   */
  link: string;
}
// @generated message type with reflection information, may provide speed optimized methods
class ListDashboardRequest$Type extends MessageType<ListDashboardRequest> {
  constructor() {
    super('testgrid.api.v1.ListDashboardRequest', [
      { no: 1, name: 'scope', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(value?: PartialMessage<ListDashboardRequest>): ListDashboardRequest {
    const message = { scope: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListDashboardRequest>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListDashboardRequest
  ): ListDashboardRequest {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string scope */ 1:
          message.scope = 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: ListDashboardRequest,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string scope = 1; */
    if (message.scope !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.scope);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.ListDashboardRequest
 */
export const ListDashboardRequest = new ListDashboardRequest$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListDashboardResponse$Type extends MessageType<ListDashboardResponse> {
  constructor() {
    super('testgrid.api.v1.ListDashboardResponse', [
      {
        no: 1,
        name: 'dashboards',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => Resource,
      },
    ]);
  }
  create(value?: PartialMessage<ListDashboardResponse>): ListDashboardResponse {
    const message = { dashboards: [] };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListDashboardResponse>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListDashboardResponse
  ): ListDashboardResponse {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* repeated testgrid.api.v1.Resource dashboards */ 1:
          message.dashboards.push(
            Resource.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: ListDashboardResponse,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* repeated testgrid.api.v1.Resource dashboards = 1; */
    for (let i = 0; i < message.dashboards.length; i++)
      Resource.internalBinaryWrite(
        message.dashboards[i],
        writer.tag(1, 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 testgrid.api.v1.ListDashboardResponse
 */
export const ListDashboardResponse = new ListDashboardResponse$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListDashboardGroupRequest$Type extends MessageType<ListDashboardGroupRequest> {
  constructor() {
    super('testgrid.api.v1.ListDashboardGroupRequest', [
      { no: 1, name: 'scope', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(
    value?: PartialMessage<ListDashboardGroupRequest>
  ): ListDashboardGroupRequest {
    const message = { scope: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListDashboardGroupRequest>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListDashboardGroupRequest
  ): ListDashboardGroupRequest {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string scope */ 1:
          message.scope = 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: ListDashboardGroupRequest,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string scope = 1; */
    if (message.scope !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.scope);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.ListDashboardGroupRequest
 */
export const ListDashboardGroupRequest = new ListDashboardGroupRequest$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListDashboardGroupResponse$Type extends MessageType<ListDashboardGroupResponse> {
  constructor() {
    super('testgrid.api.v1.ListDashboardGroupResponse', [
      {
        no: 1,
        name: 'dashboard_groups',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => Resource,
      },
    ]);
  }
  create(
    value?: PartialMessage<ListDashboardGroupResponse>
  ): ListDashboardGroupResponse {
    const message = { dashboardGroups: [] };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListDashboardGroupResponse>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListDashboardGroupResponse
  ): ListDashboardGroupResponse {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* repeated testgrid.api.v1.Resource dashboard_groups */ 1:
          message.dashboardGroups.push(
            Resource.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: ListDashboardGroupResponse,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* repeated testgrid.api.v1.Resource dashboard_groups = 1; */
    for (let i = 0; i < message.dashboardGroups.length; i++)
      Resource.internalBinaryWrite(
        message.dashboardGroups[i],
        writer.tag(1, 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 testgrid.api.v1.ListDashboardGroupResponse
 */
export const ListDashboardGroupResponse = new ListDashboardGroupResponse$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListDashboardTabsRequest$Type extends MessageType<ListDashboardTabsRequest> {
  constructor() {
    super('testgrid.api.v1.ListDashboardTabsRequest', [
      { no: 1, name: 'scope', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 2, name: 'dashboard', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(
    value?: PartialMessage<ListDashboardTabsRequest>
  ): ListDashboardTabsRequest {
    const message = { scope: '', dashboard: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListDashboardTabsRequest>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListDashboardTabsRequest
  ): ListDashboardTabsRequest {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string scope */ 1:
          message.scope = reader.string();
          break;
        case /* string dashboard */ 2:
          message.dashboard = 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: ListDashboardTabsRequest,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string scope = 1; */
    if (message.scope !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.scope);
    /* string dashboard = 2; */
    if (message.dashboard !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.dashboard);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.ListDashboardTabsRequest
 */
export const ListDashboardTabsRequest = new ListDashboardTabsRequest$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListDashboardTabsResponse$Type extends MessageType<ListDashboardTabsResponse> {
  constructor() {
    super('testgrid.api.v1.ListDashboardTabsResponse', [
      {
        no: 1,
        name: 'dashboard_tabs',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => Resource,
      },
    ]);
  }
  create(
    value?: PartialMessage<ListDashboardTabsResponse>
  ): ListDashboardTabsResponse {
    const message = { dashboardTabs: [] };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListDashboardTabsResponse>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListDashboardTabsResponse
  ): ListDashboardTabsResponse {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* repeated testgrid.api.v1.Resource dashboard_tabs */ 1:
          message.dashboardTabs.push(
            Resource.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: ListDashboardTabsResponse,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* repeated testgrid.api.v1.Resource dashboard_tabs = 1; */
    for (let i = 0; i < message.dashboardTabs.length; i++)
      Resource.internalBinaryWrite(
        message.dashboardTabs[i],
        writer.tag(1, 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 testgrid.api.v1.ListDashboardTabsResponse
 */
export const ListDashboardTabsResponse = new ListDashboardTabsResponse$Type();
// @generated message type with reflection information, may provide speed optimized methods
class GetDashboardRequest$Type extends MessageType<GetDashboardRequest> {
  constructor() {
    super('testgrid.api.v1.GetDashboardRequest', [
      { no: 1, name: 'scope', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 2, name: 'dashboard', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(value?: PartialMessage<GetDashboardRequest>): GetDashboardRequest {
    const message = { scope: '', dashboard: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<GetDashboardRequest>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: GetDashboardRequest
  ): GetDashboardRequest {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string scope */ 1:
          message.scope = reader.string();
          break;
        case /* string dashboard */ 2:
          message.dashboard = 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: GetDashboardRequest,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string scope = 1; */
    if (message.scope !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.scope);
    /* string dashboard = 2; */
    if (message.dashboard !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.dashboard);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.GetDashboardRequest
 */
export const GetDashboardRequest = new GetDashboardRequest$Type();
// @generated message type with reflection information, may provide speed optimized methods
class GetDashboardResponse$Type extends MessageType<GetDashboardResponse> {
  constructor() {
    super('testgrid.api.v1.GetDashboardResponse', [
      {
        no: 1,
        name: 'notifications',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => Notification,
      },
      {
        no: 2,
        name: 'default_tab',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 3,
        name: 'suppress_failing_tabs',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
      {
        no: 4,
        name: 'highlight_today',
        kind: 'scalar',
        T: 8 /*ScalarType.BOOL*/,
      },
    ]);
  }
  create(value?: PartialMessage<GetDashboardResponse>): GetDashboardResponse {
    const message = {
      notifications: [],
      defaultTab: '',
      suppressFailingTabs: false,
      highlightToday: false,
    };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<GetDashboardResponse>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: GetDashboardResponse
  ): GetDashboardResponse {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* repeated Notification notifications */ 1:
          message.notifications.push(
            Notification.internalBinaryRead(reader, reader.uint32(), options)
          );
          break;
        case /* string default_tab */ 2:
          message.defaultTab = reader.string();
          break;
        case /* bool suppress_failing_tabs */ 3:
          message.suppressFailingTabs = reader.bool();
          break;
        case /* bool highlight_today */ 4:
          message.highlightToday = 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: GetDashboardResponse,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* repeated Notification notifications = 1; */
    for (let i = 0; i < message.notifications.length; i++)
      Notification.internalBinaryWrite(
        message.notifications[i],
        writer.tag(1, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* string default_tab = 2; */
    if (message.defaultTab !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.defaultTab);
    /* bool suppress_failing_tabs = 3; */
    if (message.suppressFailingTabs !== false)
      writer.tag(3, WireType.Varint).bool(message.suppressFailingTabs);
    /* bool highlight_today = 4; */
    if (message.highlightToday !== false)
      writer.tag(4, WireType.Varint).bool(message.highlightToday);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.GetDashboardResponse
 */
export const GetDashboardResponse = new GetDashboardResponse$Type();
// @generated message type with reflection information, may provide speed optimized methods
class GetDashboardGroupRequest$Type extends MessageType<GetDashboardGroupRequest> {
  constructor() {
    super('testgrid.api.v1.GetDashboardGroupRequest', [
      { no: 1, name: 'scope', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 2,
        name: 'dashboard_group',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(
    value?: PartialMessage<GetDashboardGroupRequest>
  ): GetDashboardGroupRequest {
    const message = { scope: '', dashboardGroup: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<GetDashboardGroupRequest>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: GetDashboardGroupRequest
  ): GetDashboardGroupRequest {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string scope */ 1:
          message.scope = reader.string();
          break;
        case /* string dashboard_group */ 2:
          message.dashboardGroup = 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: GetDashboardGroupRequest,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string scope = 1; */
    if (message.scope !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.scope);
    /* string dashboard_group = 2; */
    if (message.dashboardGroup !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.dashboardGroup);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.GetDashboardGroupRequest
 */
export const GetDashboardGroupRequest = new GetDashboardGroupRequest$Type();
// @generated message type with reflection information, may provide speed optimized methods
class GetDashboardGroupResponse$Type extends MessageType<GetDashboardGroupResponse> {
  constructor() {
    super('testgrid.api.v1.GetDashboardGroupResponse', [
      {
        no: 1,
        name: 'dashboards',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => Resource,
      },
    ]);
  }
  create(
    value?: PartialMessage<GetDashboardGroupResponse>
  ): GetDashboardGroupResponse {
    const message = { dashboards: [] };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<GetDashboardGroupResponse>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: GetDashboardGroupResponse
  ): GetDashboardGroupResponse {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* repeated testgrid.api.v1.Resource dashboards */ 1:
          message.dashboards.push(
            Resource.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: GetDashboardGroupResponse,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* repeated testgrid.api.v1.Resource dashboards = 1; */
    for (let i = 0; i < message.dashboards.length; i++)
      Resource.internalBinaryWrite(
        message.dashboards[i],
        writer.tag(1, 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 testgrid.api.v1.GetDashboardGroupResponse
 */
export const GetDashboardGroupResponse = new GetDashboardGroupResponse$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListHeadersRequest$Type extends MessageType<ListHeadersRequest> {
  constructor() {
    super('testgrid.api.v1.ListHeadersRequest', [
      { no: 1, name: 'scope', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 2, name: 'dashboard', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 3, name: 'tab', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(value?: PartialMessage<ListHeadersRequest>): ListHeadersRequest {
    const message = { scope: '', dashboard: '', tab: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListHeadersRequest>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListHeadersRequest
  ): ListHeadersRequest {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string scope */ 1:
          message.scope = reader.string();
          break;
        case /* string dashboard */ 2:
          message.dashboard = reader.string();
          break;
        case /* string tab */ 3:
          message.tab = 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: ListHeadersRequest,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string scope = 1; */
    if (message.scope !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.scope);
    /* string dashboard = 2; */
    if (message.dashboard !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.dashboard);
    /* string tab = 3; */
    if (message.tab !== '')
      writer.tag(3, WireType.LengthDelimited).string(message.tab);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.ListHeadersRequest
 */
export const ListHeadersRequest = new ListHeadersRequest$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListHeadersResponse$Type extends MessageType<ListHeadersResponse> {
  constructor() {
    super('testgrid.api.v1.ListHeadersResponse', [
      {
        no: 1,
        name: 'headers',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => ListHeadersResponse_Header,
      },
    ]);
  }
  create(value?: PartialMessage<ListHeadersResponse>): ListHeadersResponse {
    const message = { headers: [] };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListHeadersResponse>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListHeadersResponse
  ): ListHeadersResponse {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* repeated testgrid.api.v1.ListHeadersResponse.Header headers */ 1:
          message.headers.push(
            ListHeadersResponse_Header.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: ListHeadersResponse,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* repeated testgrid.api.v1.ListHeadersResponse.Header headers = 1; */
    for (let i = 0; i < message.headers.length; i++)
      ListHeadersResponse_Header.internalBinaryWrite(
        message.headers[i],
        writer.tag(1, 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 testgrid.api.v1.ListHeadersResponse
 */
export const ListHeadersResponse = new ListHeadersResponse$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListHeadersResponse_Header$Type extends MessageType<ListHeadersResponse_Header> {
  constructor() {
    super('testgrid.api.v1.ListHeadersResponse.Header', [
      { no: 1, name: 'build', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 2, name: 'name', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 3, name: 'started', kind: 'message', T: () => Timestamp },
      {
        no: 4,
        name: 'extra',
        kind: 'scalar',
        repeat: 2 /*RepeatType.UNPACKED*/,
        T: 9 /*ScalarType.STRING*/,
      },
      {
        no: 5,
        name: 'hotlist_ids',
        kind: 'scalar',
        T: 9 /*ScalarType.STRING*/,
      },
    ]);
  }
  create(
    value?: PartialMessage<ListHeadersResponse_Header>
  ): ListHeadersResponse_Header {
    const message = { build: '', name: '', extra: [], hotlistIds: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListHeadersResponse_Header>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListHeadersResponse_Header
  ): ListHeadersResponse_Header {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string build */ 1:
          message.build = reader.string();
          break;
        case /* string name */ 2:
          message.name = reader.string();
          break;
        case /* google.protobuf.Timestamp started */ 3:
          message.started = Timestamp.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.started
          );
          break;
        case /* repeated string extra */ 4:
          message.extra.push(reader.string());
          break;
        case /* string hotlist_ids */ 5:
          message.hotlistIds = 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: ListHeadersResponse_Header,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string build = 1; */
    if (message.build !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.build);
    /* string name = 2; */
    if (message.name !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.name);
    /* google.protobuf.Timestamp started = 3; */
    if (message.started)
      Timestamp.internalBinaryWrite(
        message.started,
        writer.tag(3, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* repeated string extra = 4; */
    for (let i = 0; i < message.extra.length; i++)
      writer.tag(4, WireType.LengthDelimited).string(message.extra[i]);
    /* string hotlist_ids = 5; */
    if (message.hotlistIds !== '')
      writer.tag(5, WireType.LengthDelimited).string(message.hotlistIds);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.ListHeadersResponse.Header
 */
export const ListHeadersResponse_Header = new ListHeadersResponse_Header$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListRowsRequest$Type extends MessageType<ListRowsRequest> {
  constructor() {
    super('testgrid.api.v1.ListRowsRequest', [
      { no: 1, name: 'scope', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 2, name: 'dashboard', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 3, name: 'tab', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(value?: PartialMessage<ListRowsRequest>): ListRowsRequest {
    const message = { scope: '', dashboard: '', tab: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListRowsRequest>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListRowsRequest
  ): ListRowsRequest {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* string scope */ 1:
          message.scope = reader.string();
          break;
        case /* string dashboard */ 2:
          message.dashboard = reader.string();
          break;
        case /* string tab */ 3:
          message.tab = 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: ListRowsRequest,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string scope = 1; */
    if (message.scope !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.scope);
    /* string dashboard = 2; */
    if (message.dashboard !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.dashboard);
    /* string tab = 3; */
    if (message.tab !== '')
      writer.tag(3, WireType.LengthDelimited).string(message.tab);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.ListRowsRequest
 */
export const ListRowsRequest = new ListRowsRequest$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListRowsResponse$Type extends MessageType<ListRowsResponse> {
  constructor() {
    super('testgrid.api.v1.ListRowsResponse', [
      {
        no: 1,
        name: 'rows',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => ListRowsResponse_Row,
      },
    ]);
  }
  create(value?: PartialMessage<ListRowsResponse>): ListRowsResponse {
    const message = { rows: [] };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListRowsResponse>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListRowsResponse
  ): ListRowsResponse {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* repeated testgrid.api.v1.ListRowsResponse.Row rows */ 1:
          message.rows.push(
            ListRowsResponse_Row.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: ListRowsResponse,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* repeated testgrid.api.v1.ListRowsResponse.Row rows = 1; */
    for (let i = 0; i < message.rows.length; i++)
      ListRowsResponse_Row.internalBinaryWrite(
        message.rows[i],
        writer.tag(1, 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 testgrid.api.v1.ListRowsResponse
 */
export const ListRowsResponse = new ListRowsResponse$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListRowsResponse_Row$Type extends MessageType<ListRowsResponse_Row> {
  constructor() {
    super('testgrid.api.v1.ListRowsResponse.Row', [
      { no: 1, name: 'name', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      {
        no: 2,
        name: 'cells',
        kind: 'message',
        repeat: 1 /*RepeatType.PACKED*/,
        T: () => ListRowsResponse_Cell,
      },
      {
        no: 3,
        name: 'issues',
        kind: 'scalar',
        repeat: 2 /*RepeatType.UNPACKED*/,
        T: 9 /*ScalarType.STRING*/,
      },
      { no: 4, name: 'alert', kind: 'message', T: () => AlertInfo },
    ]);
  }
  create(value?: PartialMessage<ListRowsResponse_Row>): ListRowsResponse_Row {
    const message = { name: '', cells: [], issues: [] };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListRowsResponse_Row>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListRowsResponse_Row
  ): ListRowsResponse_Row {
    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 testgrid.api.v1.ListRowsResponse.Cell cells */ 2:
          message.cells.push(
            ListRowsResponse_Cell.internalBinaryRead(
              reader,
              reader.uint32(),
              options
            )
          );
          break;
        case /* repeated string issues */ 3:
          message.issues.push(reader.string());
          break;
        case /* AlertInfo alert */ 4:
          message.alert = AlertInfo.internalBinaryRead(
            reader,
            reader.uint32(),
            options,
            message.alert
          );
          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: ListRowsResponse_Row,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string name = 1; */
    if (message.name !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.name);
    /* repeated testgrid.api.v1.ListRowsResponse.Cell cells = 2; */
    for (let i = 0; i < message.cells.length; i++)
      ListRowsResponse_Cell.internalBinaryWrite(
        message.cells[i],
        writer.tag(2, WireType.LengthDelimited).fork(),
        options
      ).join();
    /* repeated string issues = 3; */
    for (let i = 0; i < message.issues.length; i++)
      writer.tag(3, WireType.LengthDelimited).string(message.issues[i]);
    /* AlertInfo alert = 4; */
    if (message.alert)
      AlertInfo.internalBinaryWrite(
        message.alert,
        writer.tag(4, 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 testgrid.api.v1.ListRowsResponse.Row
 */
export const ListRowsResponse_Row = new ListRowsResponse_Row$Type();
// @generated message type with reflection information, may provide speed optimized methods
class ListRowsResponse_Cell$Type extends MessageType<ListRowsResponse_Cell> {
  constructor() {
    super('testgrid.api.v1.ListRowsResponse.Cell', [
      { no: 1, name: 'result', kind: 'scalar', T: 5 /*ScalarType.INT32*/ },
      { no: 2, name: 'cell_id', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 3, name: 'message', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 4, name: 'icon', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(value?: PartialMessage<ListRowsResponse_Cell>): ListRowsResponse_Cell {
    const message = { result: 0, cellId: '', message: '', icon: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<ListRowsResponse_Cell>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: ListRowsResponse_Cell
  ): ListRowsResponse_Cell {
    let message = target ?? this.create(),
      end = reader.pos + length;
    while (reader.pos < end) {
      let [fieldNo, wireType] = reader.tag();
      switch (fieldNo) {
        case /* int32 result */ 1:
          message.result = reader.int32();
          break;
        case /* string cell_id */ 2:
          message.cellId = reader.string();
          break;
        case /* string message */ 3:
          message.message = reader.string();
          break;
        case /* string icon */ 4:
          message.icon = 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: ListRowsResponse_Cell,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* int32 result = 1; */
    if (message.result !== 0)
      writer.tag(1, WireType.Varint).int32(message.result);
    /* string cell_id = 2; */
    if (message.cellId !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.cellId);
    /* string message = 3; */
    if (message.message !== '')
      writer.tag(3, WireType.LengthDelimited).string(message.message);
    /* string icon = 4; */
    if (message.icon !== '')
      writer.tag(4, WireType.LengthDelimited).string(message.icon);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.ListRowsResponse.Cell
 */
export const ListRowsResponse_Cell = new ListRowsResponse_Cell$Type();
// @generated message type with reflection information, may provide speed optimized methods
class Resource$Type extends MessageType<Resource> {
  constructor() {
    super('testgrid.api.v1.Resource', [
      { no: 1, name: 'name', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
      { no: 2, name: 'link', kind: 'scalar', T: 9 /*ScalarType.STRING*/ },
    ]);
  }
  create(value?: PartialMessage<Resource>): Resource {
    const message = { name: '', link: '' };
    globalThis.Object.defineProperty(message, MESSAGE_TYPE, {
      enumerable: false,
      value: this,
    });
    if (value !== undefined)
      reflectionMergePartial<Resource>(this, message, value);
    return message;
  }
  internalBinaryRead(
    reader: IBinaryReader,
    length: number,
    options: BinaryReadOptions,
    target?: Resource
  ): Resource {
    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 link */ 2:
          message.link = 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: Resource,
    writer: IBinaryWriter,
    options: BinaryWriteOptions
  ): IBinaryWriter {
    /* string name = 1; */
    if (message.name !== '')
      writer.tag(1, WireType.LengthDelimited).string(message.name);
    /* string link = 2; */
    if (message.link !== '')
      writer.tag(2, WireType.LengthDelimited).string(message.link);
    let u = options.writeUnknownFields;
    if (u !== false)
      (u == true ? UnknownFieldHandler.onWrite : u)(
        this.typeName,
        message,
        writer
      );
    return writer;
  }
}
/**
 * @generated MessageType for protobuf message testgrid.api.v1.Resource
 */
export const Resource = new Resource$Type();
/**
 * @generated ServiceType for protobuf service testgrid.api.v1.TestGridData
 */
export const TestGridData = new ServiceType('testgrid.api.v1.TestGridData', [
  {
    name: 'ListDashboard',
    options: {},
    I: ListDashboardRequest,
    O: ListDashboardResponse,
  },
  {
    name: 'ListDashboardGroup',
    options: {},
    I: ListDashboardGroupRequest,
    O: ListDashboardGroupResponse,
  },
  {
    name: 'ListDashboardTabs',
    options: {},
    I: ListDashboardTabsRequest,
    O: ListDashboardTabsResponse,
  },
  {
    name: 'GetDashboard',
    options: {},
    I: GetDashboardRequest,
    O: GetDashboardResponse,
  },
  {
    name: 'GetDashboardGroup',
    options: {},
    I: GetDashboardGroupRequest,
    O: GetDashboardGroupResponse,
  },
  {
    name: 'ListHeaders',
    options: {},
    I: ListHeadersRequest,
    O: ListHeadersResponse,
  },
  { name: 'ListRows', options: {}, I: ListRowsRequest, O: ListRowsResponse },
]);
