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

edition = "2023";

package optimization_guide.proto;

option java_outer_classname = "CommonFeatureDataProto";

option java_package = "org.chromium.components.optimization_guide.features.proto";

option optimize_for = LITE_RUNTIME;

// DO NOT EDIT THIS FILE DIRECTLY!
//
// This file is generated in g3 and then synced to Chrome. Instead, please refer to
// http://go/chrome-mqls-onboarding (Google-internal link), and then changes will
// be synced with Chrome automatically.

// Next ID: 2
message FloatArray {
  repeated float values = 1;
}

// Next ID: 2
message Embedding {
  // The embedding vector. Note that future versions of this proto might not
  // have this field set, as a new field may be added for quantized embeddings.
  FloatArray floats = 1 [features = { field_presence: EXPLICIT }];
}

// Accessibility tree snapshot
// See
// https://source.chromium.org/chromium/chromium/src/+/main:ui/accessibility/ax_tree_update.h
// for details of this and related messages.
//
// Next ID: 4
message AXTreeUpdate {
  AXTreeData tree_data = 1 [features = { field_presence: EXPLICIT }];

  uint32 root_id = 2 [features = { field_presence: EXPLICIT }];

  repeated AXNodeData nodes = 3;
}

// AX tree metadata, part of the a11y snapshot.
// Next ID: 16
message AXTreeData {
  string doctype = 1 [features = { field_presence: EXPLICIT }];

  bool loaded = 2 [features = { field_presence: EXPLICIT }];

  float loading_progress = 3 [features = { field_presence: EXPLICIT }];

  string mimetype = 4 [features = { field_presence: EXPLICIT }];

  string title = 5 [features = { field_presence: EXPLICIT }];

  uint32 focus_id = 6 [features = { field_presence: EXPLICIT }];

  bool sel_is_backward = 7 [features = { field_presence: EXPLICIT }];

  uint32 sel_anchor_object_id = 8 [features = { field_presence: EXPLICIT }];

  uint32 sel_anchor_offset = 9 [features = { field_presence: EXPLICIT }];

  AXTextAffinity sel_anchor_affinity = 10 [features = { field_presence: EXPLICIT }];

  uint32 sel_focus_object_id = 11 [features = { field_presence: EXPLICIT }];

  uint32 sel_focus_offset = 12 [features = { field_presence: EXPLICIT }];

  AXTextAffinity sel_focus_affinity = 13 [features = { field_presence: EXPLICIT }];

  uint32 root_scroller_id = 14 [features = { field_presence: EXPLICIT }];

  repeated string metadata = 15;
}

// Per node accessibility data, part of the a11y snapshot.
// Next ID: 8
message AXNodeData {
  uint32 id = 1 [features = { field_presence: EXPLICIT }];

  AXRole role = 2 [features = { field_presence: EXPLICIT }];

  uint32 state = 3 [features = { field_presence: EXPLICIT }];

  uint64 actions = 4 [features = { field_presence: EXPLICIT }];

  repeated AXAttribute attributes = 5;

  repeated int32 child_ids = 6;

  AXRelativeBounds relative_bounds = 7 [features = { field_presence: EXPLICIT }];
}

// AX node attribute, part of the a11y snapshot.
// Next ID: 15
message AXAttribute {
  oneof attribute_key {
    AXStringAttribute string_type = 1;

    AXIntAttribute int_type = 2;

    AXFloatAttribute float_type = 3;

    AXBoolAttribute bool_type = 4;

    AXIntListAttribute intlist_type = 5;

    AXStringListAttribute stringlist_type = 6;

    string html_attribute_name = 7;
  }

  oneof attribute_value {
    string string_value = 8;

    int32 int_value = 9;

    float float_value = 10;

    bool bool_value = 11;

    AXIntList int_list_value = 12;

    AXStringList string_list_value = 13;

    string html_attribute_value = 14;
  }
}

// Helper message for AX IntList.
message AXIntList {
  repeated int32 value = 1;
}

// Helper message for AX StringList.
message AXStringList {
  repeated string value = 1;
}

// AX Relative bounds.
// Next ID: 7
message AXRelativeBounds {
  int32 offset_container_id = 1 [features = { field_presence: EXPLICIT }];

  float x = 2 [features = { field_presence: EXPLICIT }];

  float y = 3 [features = { field_presence: EXPLICIT }];

  float width = 4 [features = { field_presence: EXPLICIT }];

  float height = 5 [features = { field_presence: EXPLICIT }];

  // If present, represents the transform as 16 floats.
  repeated float transform = 6;
}

// Next ID: 11
message PageContext {
  // The URL of the page that the form is on.
  string url = 1 [features = { field_presence: EXPLICIT }];

  // The title of the page that the form is on.
  string title = 2 [features = { field_presence: EXPLICIT }];

  // The AX tree representation of the page.
  AXTreeUpdate ax_tree_data = 3 [features = { field_presence: EXPLICIT }];

  // The inner text of the page the model is acting on (excluding x-origin
  // frames).
  string inner_text = 4 [features = { field_presence: EXPLICIT }];

  // The offset of the focused element into the |inner_text|.
  uint64 inner_text_offset = 5 [features = { field_presence: EXPLICIT }];

  // The text passages of the page. Those passages are the result of the
  // HtmlChunker algorithm implemented in Chrome (used by the History Search
  // feature). See
  // https://github.com/google/labs-prototypes/tree/main/seeds/chunker-python
  repeated string page_passages = 9;

  // A base64 encoded PNG of the tab screenshot.
  string tab_screenshot = 6 [features = { field_presence: EXPLICIT }];

  // The base64 encoded PDF representation of the page.
  string pdf_data = 7 [features = { field_presence: EXPLICIT }];

  // The page content represented as a tree of semantic chunks and (in the
  // future) annotated with additional information about the page.
  AnnotatedPageContent annotated_page_content = 8 [features = { field_presence: EXPLICIT }];
}

// The page content represented as a tree of semantic chunks and (in the
// future) annotated with additional information about the page.
// Next ID: 11
message AnnotatedPageContent {
  // The version of the proto. Each time a backwards incompatible change is made
  // to the proto, the version should be incremented.
  AnnotatedPageContentVersion version = 1 [features = { field_presence: EXPLICIT }];

  // The mode used to extract this proto. The data in the proto depends on the
  // mode. See comments to understand which data is available for each mode.
  AnnotatedPageContentMode mode = 6 [features = { field_presence: EXPLICIT }];

  // The root node of the ContentNode tree.
  ContentNode root_node = 2 [features = { field_presence: EXPLICIT }];

  // The data for the main frame of the page.
  FrameData main_frame_data = 3 [features = { field_presence: EXPLICIT }];

  // The interaction information for the page--the subtree represented by the
  // AnnotatedPageContent. This is for top-level interactions, such as the mouse
  // position and focused element, for which there can only be one unique value
  // for the entire page.
  // Currently this is only tracked for the main frame.
  PageInteractionInfo page_interaction_info = 4 [features = { field_presence: EXPLICIT }];

  // The rect of the viewport for the tab. i.e., screenshot dimensions.
  // Dimensions are in captured pixels.
  // This coordinate system should be used for coordinate based browser actions.
  // This uses device independent pixels, i.e., doesn't include the device
  // scale factor while other dimensions in APC are based on that.
  BoundingRect viewport_geometry = 5 [features = { field_presence: EXPLICIT }];

  // The id of the tab that the page content was extracted from. Guaranteed to
  // be unique within the browsing session.
  int32 tab_id = 7 [features = { field_presence: EXPLICIT }];

  // Provides APC for internal popup widgets created by elements like <select>
  // and <input type="color"> . Does not provide APC for separate windows opened
  // via window.open() or similar. A page can only have one popup window open at
  // a time. If one is open, its details are populated here. The popup window
  // draws on top of the tab and as such has a higher z order than the main
  // frame's Document.
  PopupWindow popup_window = 8 [features = { field_presence: EXPLICIT }];

  // Information that pertains to the user's profile, not the page.
  // TODO(crbug.com/454610456): This should be moved out of AnnotatedPageContent because
  // it does not semantically belong here.
  ProfileInformation profile_information = 9 [features = { field_presence: EXPLICIT }];

  // Metadata about the page when Gemini in Chrome captures Annotated Page
  // Content.
  // TODO(crbug.com/484011242): This should be moved out of AnnotatedPageContent because
  // it does not semantically belong here.
  GeminiInChromePageMetadata gemini_in_chrome_page_metadata = 10 [features = { field_presence: EXPLICIT }];
}

// The ContentNode tree is a sparse representation of the DOM tree for a web
// page, i.e., not every DOM node generates a ContentNode. For example, a `div`
// used only for styling or layout the subtree will not generate a ContentNode.
//
// The ContentNode is roughly 1:1 with a DOM node but there are exceptions:
//
// - Some DOM nodes can generate multiple ContentNodes. For example, a
//   `::before` pseudo-element would have text and image ContentNodes for it's
//   content specified in CSS.
//
// - A form with `<input type="image">` will have ContentNodes for the input
//   element and it's image.
//
// - We currently don't coalesce text content from multiple DOM nodes into a
//   single ContentNode but that maybe added in the future.
//
// Note: The ContentNode tree including content from all embedded iframes.
// Next ID: 3
message ContentNode {
  // Note: CONTENT_ATTRIBUTE_TEXT and CONTENT_ATTRIBUTE_IMAGE are leaf nodes
  // which don't have any children nodes.
  repeated ContentNode children_nodes = 1;

  ContentAttributes content_attributes = 2 [features = { field_presence: EXPLICIT }];
}

// Next ID: 30
message ContentAttributes {
  oneof content_data {
    // Only set if attribute_type is CONTENT_ATTRIBUTE_TEXT.
    TextInfo text_data = 10;

    // Only set if attribute_type is CONTENT_ATTRIBUTE_IMAGE.
    ImageInfo image_data = 11;

    // Only set if attribute_type is CONTENT_ATTRIBUTE_SVG_ROOT.
    SVGRootData svg_root_data = 23;

    // Only set if attribute_type is CONTENT_ATTRIBUTE_CANVAS.
    CanvasData canvas_data = 24;

    // Only set if attribute_type is CONTENT_ATTRIBUTE_VIDEO.
    VideoData video_data = 27;

    // Only set if attribute_type is CONTENT_ATTRIBUTE_ANCHOR.
    AnchorData anchor_data = 14;

    // Only set if attribute_type is CONTENT_ATTRIBUTE_FORM.
    FormInfo form_data = 19;

    // Only set if attribute_type is CONTENT_ATTRIBUTE_FORM_CONTROL.
    FormControlData form_control_data = 20;

    // Only set if attribute_type is CONTENT_ATTRIBUTE_TABLE.
    TableData table_data = 8;

    // Only set if attribute_type is CONTENT_ATTRIBUTE_IFRAME.
    IframeData iframe_data = 9;

    // Only set if attribute_type is CONTENT_ATTRIBUTE_TABLE_ROW.
    TableRowData table_row_data = 13;
  }

  // A unique identifier for the DOM node which generated this ContentNode.
  //
  // Note: This field is only set if the ContentNode corresponds to a DOM
  // node. There are cases where the browser generates layout nodes which don't
  // map to a single DOM node, such as pseudo elements. In such cases, this
  // field will not be set.
  //
  // The identifier's lifetime is tied to its Document's lifetime in the
  // browser's renderer process.
  int32 common_ancestor_dom_node_id = 2 [features = { field_presence: EXPLICIT }];

  ContentAttributeType attribute_type = 3 [features = { field_presence: EXPLICIT }];

  // This is the geometry of the common_ancestor_dom_node_id.
  //
  // In the default mode, this is only populated if this is the
  // `accessibility_focused_dom_node_id`.
  //
  // Populated for all nodes in
  // `ANNOTATED_PAGE_CONTENT_MODE_ACTIONABLE_ELEMENTS.`
  Geometry geometry = 4 [features = { field_presence: EXPLICIT }];

  // The interaction information for the content node.
  // Note: The information in InteractionInfo is configured based on the
  // AnnotatedPageContentMode. See comments on the message definition for
  // details.
  InteractionInfo interaction_info = 21 [features = { field_presence: EXPLICIT }];

  // These can come from the aria role, the html tag, or are assumed from some
  // properties of the page.
  repeated AnnotatedRole annotated_roles = 15;

  // A textual description of the content node from sources that may not be part
  // of the tree because the content is not rendered. For example, `aria-label`
  // and `aria-labelledby` attributes.
  //
  // Only populated for ANNOTATED_PAGE_CONTENT_MODE_ACTIONABLE_ELEMENTS.`
  string label = 16 [features = { field_presence: EXPLICIT }];

  // If this is a label node associated with an input node using `for`, provides
  // the DOM node ID of the input node. This will match the
  // `common_ancestor_dom_node_id` of the ContentNode of the input node, if it
  // exists.
  // Note: The label may be an ancestor of the input node.
  //
  // Only populated for ANNOTATED_PAGE_CONTENT_MODE_ACTIONABLE_ELEMENTS.
  int32 label_for_dom_node_id = 25 [features = { field_presence: EXPLICIT }];

  // The role of this ContentNode derived from the aria-role attribute.
  //
  // Only populated for ANNOTATED_PAGE_CONTENT_MODE_ACTIONABLE_ELEMENTS.
  AXRole aria_role = 26 [features = { field_presence: EXPLICIT }];

  // Whether the content node is from an ad.
  bool is_ad_related = 28 [features = { field_presence: EXPLICIT }];

  // Redaction decision for the node.
  RedactionDecision redaction_decision = 29 [features = { field_presence: EXPLICIT }];

  reserved 5, 6, 7, 17, 18, 1, 22;
}

// The geometry of the content, in the page coordinate system.
// Next ID: 9
// NOTE: If `visible_bounding_box` is empty, i.e., the content is offscreen and
// it's in an iframe, the `outer_bounding_box` may be incorrect. See crbug.com/384996050
// for details.
//
// Only populated for ANNOTATED_PAGE_CONTENT_MODE_ACTIONABLE_ELEMENTS.
message Geometry {
  // The bounding box of the content node mapped to the viewport ignoring any
  // ancestor clips (including the viewport clip). This can be thought of as
  // where the element would be relative to the viewport if it "popped out" of
  // the page and was painted on top of all the content. A few use-case for this
  // are:
  //
  // - If empty, this implies the node is not hit-testable, even once
  //   scrolled onscreen.
  // - The rect's origin indicates whether it starts above or below the
  //   viewport. A negative y-coordinate means the node's content starts above
  //   the viewport.
  BoundingRect outer_bounding_box = 1 [features = { field_presence: EXPLICIT }];

  // The bounding box of the content node relative to the viewport including all
  // ancestor clipping. These are the element bounds visible to the user and
  // hit-testable in the DOM.
  BoundingRect visible_bounding_box = 2 [features = { field_presence: EXPLICIT }];

  // Multiple boxes are used when there are multiple rectangles belonging to
  // the same node, e.g.: across multiple lines, columns or pages. In layout
  // terms, a node that does this is called a fragmentainer.
  // Each rectangle represents a hit testable fragment belonging to the node.
  // An empty array indicates that the node is not fragmented or is entirely
  // offscreen. Relative to viewport origin.
  repeated BoundingRect fragment_visible_bounding_boxes = 6;

  // Whether the content node is fixed or sticky position. This may suggest
  // that the node is a header, footer, or sidebar.
  // TODO(crbug.com/490195093): Remove this field.
  bool is_fixed_or_sticky_position = 3 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  // The computed CSS position property.
  CssPosition css_position = 8 [features = { field_presence: EXPLICIT }];

  reserved 4, 5, 7;
}

message BoundingRect {
  int32 x = 1 [features = { field_presence: EXPLICIT }];

  int32 y = 2 [features = { field_presence: EXPLICIT }];

  int32 width = 3 [features = { field_presence: EXPLICIT }];

  int32 height = 4 [features = { field_presence: EXPLICIT }];

  // If true, the bounding box is in the coordinate space of the screenshot
  // bounds as specified in ScreenshotInfo > screenshot_size.
  bool is_screenshot_relative = 5 [features = { field_presence: EXPLICIT }];
}

// The interaction information for the content node. This indicates whether the
// node is interactive and what type of interaction it supports.
//
// Note: ScrollerInfo is populated for ANNOTATED_PAGE_CONTENT_MODE_DEFAULT. The
// rest of the fields are only populated for
// ANNOTATED_PAGE_CONTENT_MODE_ACTIONABLE_ELEMENTS.
// Next ID: 21
message InteractionInfo {
  // Set if the content node is scrollable.
  ScrollerInfo scroller_info = 12 [features = { field_presence: EXPLICIT }];

  // Whether the content node is selectable.
  // TODO(crbug.com/490195093): Remove this field.
  bool is_selectable = 3 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  // Whether the content node is editable; i.e. whether the user can type into
  // it. This refers to the text actually being editable, not whether the
  // content node is a text field.
  // TODO(crbug.com/490195093): Remove this field.
  bool is_editable = 4 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  // Whether the content node can be resized. This is relevant for scroll
  // containers and iframes which have the CSS resize behavior.
  // TODO(crbug.com/490195093): Remove these fields.
  bool can_resize_horizontal = 5 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  bool can_resize_vertical = 6 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  // Whether the content node is focusable. See also `is_tabbable`.
  // A node can be focusable even if it is not tabbable. For
  // example, every option in a long listbox might be focusable, but
  // only reachable using the arrow keys.
  bool is_focusable = 7 [features = { field_presence: EXPLICIT }];

  // Whether the content node is draggable.
  // TODO(crbug.com/490195093): Remove this field.
  bool is_draggable = 9 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  // Whether the content node is clickable. This checks for whether the node is
  // a clickable control (e.g. form control elements) or has activation
  // behavior. It also checks for whether the node has a click handler.
  // TODO(crbug.com/490195093): Remove this field.
  bool is_clickable = 10 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  // The z-order of the content node relative to other nodes in the same
  // Document. A higher value means the node is in front of other nodes with
  // lower values.
  //
  // Since all content within a Document is rendered as a single layer, nodes
  // behind the iframe in the embedder draw behind all nodes inside the
  // iframe's Document (similar for nodes on top of the iframe node).
  //
  // Note: This value is only set for nodes in the viewport.
  int32 document_scoped_z_order = 13 [features = { field_presence: EXPLICIT }];

  // If this node is detected to be is_clickable, provides the reason which
  // caused that.
  // Note: This may not capture all the reasons.
  // Deprecated: Use clickability_reasons instead.
  // TODO(crbug.com/490195093): Remove this field.
  repeated ClickabilityReason debug_clickability_reasons = 14 [deprecated = true];

  // Provides signals which indicate whether the node is actionable. The action
  // may be triggered by clicking or hovering on the element.
  repeated ClickabilityReason clickability_reasons = 15;

  // Whether the node is in a strong disabled state. When this is true, attempts
  // to generate a click action for the node are rejected.
  //
  // This is true for:
  // - A native control with `disabled`, such as `<button disabled>`.
  //
  // Some `interaction_disabled_reasons` are advisory and leave this false:
  // - A node with `aria-disabled="true"`, or a node inside such an ancestor.
  // - A node styled with `cursor: not-allowed`.
  // - A node hidden from the accessibility tree with `aria-hidden="true"`.
  // - A node with `role="presentation"` or `role="none"`.
  //
  // Advisory reasons tell consumers that an interaction on this node is likely
  // to be a no-op, but they do not prevent the action from being dispatched if
  // the node is targeted.
  //
  // A disabled node may still be hit-testable and consume events. Nodes that
  // cannot be hit-tested, such as those with `pointer-events: none`, do not
  // receive interaction info.
  bool is_disabled = 16 [features = { field_presence: EXPLICIT }];

  // Hints on why the interaction with the node is disabled.
  repeated InteractionDisabledReason interaction_disabled_reasons = 17;

  // Whether the content node is tabbable. This is determined by whether the
  // node is focusable and has a non-negative computed tab index (usually 0,
  // which indicates it fits into the tab cycle in its natural order).
  bool is_tabbable = 18 [features = { field_presence: EXPLICIT }];

  // Whether the content node has the aria-activedescendant attribute set. This
  // attribute is used to indicate which element in a set of child elements is
  // currently active.
  bool has_aria_activedescendant = 19 [features = { field_presence: EXPLICIT }];

  // Secondary-action targets for a container widget. This lets APC represent
  // cases like split buttons or tabs with close buttons where both the
  // container and the secondary action element are actionable.
  repeated int32 aria_action_target_node_ids = 20;

  reserved 8, 1, 2, 11;
}

// The coordinate space for the dimensions here is physical coordinates (not
// logical coordinates). This means it's the same irrespective of the writing
// mode.
// The dimensions also exclude non-overlay scrollbars.
message ScrollerInfo {
  // The complete layout dimensions of the scroller. This is the total area
  // that can be revealed through a scroll operation.
  BoundingSize scrolling_bounds = 1 [features = { field_presence: EXPLICIT }];

  // The subset of this scroller's content which is currently scrolled to. This
  // is relative to the origin of `scrolling_bounds`.
  BoundingRect visible_area = 2 [features = { field_presence: EXPLICIT }];

  // Indicates whether this can be scrolled by the user in horizontal or
  // vertical directions. These nodes can still be scrolled by script.
  bool user_scrollable_horizontal = 3 [features = { field_presence: EXPLICIT }];

  bool user_scrollable_vertical = 4 [features = { field_presence: EXPLICIT }];
}

message BoundingSize {
  int32 width = 1 [features = { field_presence: EXPLICIT }];

  int32 height = 2 [features = { field_presence: EXPLICIT }];
}

// Next ID: 5
message TextInfo {
  string text_content = 1 [features = { field_presence: EXPLICIT }];

  TextStyle text_style = 3 [features = { field_presence: EXPLICIT }];

  reserved 2, 4;
}

// Next ID: 5
message TextStyle {
  // A crude approximation of text size. The default is M. An ML model doesn't
  // need to know the precise size of the text; it just needs to know whether
  // it's relatively small or large. The default is M.
  TextSize text_size = 1 [features = { field_presence: EXPLICIT }];

  // Whether the text has inline semantics that denote emphasis. For example:
  // bold, italics, underline, super/subscript, etc. An ML model doesn't need
  // to know which specific semantic was used; only that the website author
  // chose to emphasize the text in some way. The default is false.
  bool has_emphasis = 2 [features = { field_presence: EXPLICIT }];

  // The color of the text in RGBA format.
  uint32 color = 3 [features = { field_presence: EXPLICIT }];
}

// Information about the image. In the future, this may include a pixmap.
// Next ID: 6
message ImageInfo {
  string image_caption = 2 [features = { field_presence: EXPLICIT }];

  // Provides the source origin for the image.
  SecurityOrigin security_origin = 4 [features = { field_presence: EXPLICIT }];

  // The image's source (`src`) URL. If redirected, this remains the original
  // URL, not the final resolved destination.
  string url = 5 [features = { field_presence: EXPLICIT }];

  reserved 1, 3;
}

// The source origin for the web content in AnnotatedPageContent. This maps to
// the origin concept in the spec: https://url.spec.whatwg.org/#origin.
//
// This is distinct from URLs. There are cases where the URL for a Document,
// example about:blank, is different from the origin that the Document's data
// should be attributed to.
//
// Next ID: 3
message SecurityOrigin {
  // Whether the origin is opaque.
  bool opaque = 1 [features = { field_presence: EXPLICIT }];

  // The raw value of the origin. It is set to the nonce for opaque origins and
  // scheme-host-port string for non-opaque origins.
  string value = 2 [features = { field_presence: EXPLICIT }];
}

message SVGRootData {
  // The inner text for the SVG subtree.
  string inner_text = 1 [features = { field_presence: EXPLICIT }];
}

message CanvasData {
  int32 layout_width = 1 [features = { field_presence: EXPLICIT }];

  int32 layout_height = 2 [features = { field_presence: EXPLICIT }];
}

message VideoData {
  // The URL of the video.
  string url = 1 [features = { field_presence: EXPLICIT }];

  // The source origin for the video.
  SecurityOrigin security_origin = 2 [features = { field_presence: EXPLICIT }];
}

message AnchorData {
  string url = 1 [features = { field_presence: EXPLICIT }];

  // The relationship between the linked URL and the current document.
  repeated AnchorRel rel = 2;
}

// FormInfo is a mirror of AIPageContentFormData from
// third_party/blink/public/mojom/content_extraction/ai_page_content.mojom,
// in contrast with FormData, which is a mirror of autofill::FormData from
// components/autofill/core/common/mojom/autofill_types.mojom.
message FormInfo {
  // The name of the form.
  string form_name = 1 [features = { field_presence: EXPLICIT }];

  // The action URL of the form, if present. This is the resolved value
  // including the final origin.
  string action_url = 2 [features = { field_presence: EXPLICIT }];
}

// Next ID: 12
message FormControlData {
  // The name for the field.
  string field_name = 1 [features = { field_presence: EXPLICIT }];

  // The value of the field.
  string field_value = 2 [features = { field_presence: EXPLICIT }];

  // The type of control for this form field.
  FormControlType form_control_type = 3 [features = { field_presence: EXPLICIT }];

  // The options for a select field, if applicable.
  repeated SelectOption select_options = 4;

  // The placeholder text for the field. This is only applicable to text fields.
  string placeholder = 5 [features = { field_presence: EXPLICIT }];

  // Whether the field is checked. This is only applicable to checkbox and radio
  // button fields.
  bool is_checked = 6 [features = { field_presence: EXPLICIT }];

  // Whether the field is required.
  bool is_required = 7 [features = { field_presence: EXPLICIT }];

  // Redaction decision for form fields.
  // Deprecated in favor of redaction_decision on ContentAttributes.
  RedactionDecision redaction_decision = 8 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  // The types of data that can be autofilled this field. This does not imply
  // that the user has data to fill of this type on file.
  repeated CoarseAutofillFieldType coarse_autofill_field_type = 9;

  // Global identifier (across one AnnotatedPageContent) of an autofillable
  // section. Fields that belong to the same section are filled in one fill
  // operation. These fields share the same `autofill_section_id`.
  // The value may change over time if the page changes (IDs are generated
  // in AnnotatedPageContent traversal order according to Autofill's
  // understanding of forms).
  uint32 autofill_section_id = 10 [features = { field_presence: EXPLICIT }];

  // Whether the field is readonly.
  bool is_readonly = 11 [features = { field_presence: EXPLICIT }];
}

// Represents an option in a select field. See below for example.
//
// HTML                                      | value  | text
// ------------------------------------------+--------+------
// <option value=Foo label=Bar>Baz</option>  | "Foo"  | "Bar"
// <option value=Foo>Bar</option>            | "Foo"  | "Bar"
// <option label=Bar>Foo</option>            | "Foo"  | "Bar"
// <option>Foo</option>                      | "Foo"  | "Foo"
// <option value=Foo></option>               | "Foo"  | ""
// <option label=Bar></option>               | ""     | "Bar"
message SelectOption {
  string value = 1 [features = { field_presence: EXPLICIT }];

  string text = 2 [features = { field_presence: EXPLICIT }];

  // Whether the option is selected.
  // Not set for FormsAI purposes, but used in PCA.
  bool is_selected = 3 [features = { field_presence: EXPLICIT }];

  // Whether the option is disabled.
  // Not set for FormsAI purposes, but used in PCA.
  bool is_disabled = 4 [features = { field_presence: EXPLICIT }];
}

message TableData {
  // The name of the table, coming from the caption.
  // Note: this field has some quirks for backwards-compatibility reasons:
  // 1. It is only populated if the table name is an immediate child of the
  //    table element. Table names further down in the tree are skipped, leaving
  //    this field empty.
  // 2. The table name also will appear in a separate child text node.
  string table_name = 1 [features = { field_presence: EXPLICIT }];

  reserved 2, 3, 4;
}

message IframeData {
  oneof data {
    FrameData frame_data = 3;

    RedactedFrameMetadata redacted_frame_metadata = 4;
  }

  message RedactedFrameMetadata {
    Reason reason = 1 [features = { field_presence: EXPLICIT }];

    enum Reason {
      REASON_UNSPECIFIED = 0;

      // This iframe was redacted because it is not on the same eTLD+1 site as
      // the top-level frame.
      REASON_CROSS_SITE = 1;

      // This iframe was redacted because it is not on the same origin as the
      // top-level frame.
      REASON_CROSS_ORIGIN = 2;
    }
  }

  reserved 1, 2;
}

// The data for a frame in the web page. This is the common data structure for
// both the root frame and embedded iframes.
// Next ID: 13
message FrameData {
  // The security origin of the frame.
  SecurityOrigin security_origin = 1 [features = { field_presence: EXPLICIT }];

  // Interaction information for the frame.
  FrameInteractionInfo frame_interaction_info = 2 [features = { field_presence: EXPLICIT }];

  // Identifies the document in a frame.
  DocumentIdentifier document_identifier = 3 [features = { field_presence: EXPLICIT }];

  // The URL of the frame.
  string url = 4 [features = { field_presence: EXPLICIT }];

  // The title of the frame.
  string title = 5 [features = { field_presence: EXPLICIT }];

  // Information about paid content in the frame.  Only set
  // if paid content was checked.
  PaidContentMetadata paid_content_metadata = 6 [features = { field_presence: EXPLICIT }];

  // Information about the media in the frame. This information is only added
  // for the frame which controls the media session associated with this page.
  // Only one frame can control the media session at a time via the media
  // session web API.
  MediaData media_data = 8 [features = { field_presence: EXPLICIT }];

  // The set of tools supported by this Document.
  repeated ScriptTool script_tools = 9;

  // The results of executing script tools.
  // TODO: crbug.com/489841640 - Remove this field once all consumers move to using
  // the field in ActionsResult.
  repeated ScriptToolResult script_tool_results = 11;

  // Positive used line height in CSS px. Needed for scaling-proof
  // geometry rules (e.g. menu popup heuristics expecting a minimum size).
  uint32 default_line_height_px = 12 [features = { field_presence: EXPLICIT }];

  reserved 7, 10;
}

// The interaction information for the frame. This is for interactions that
// are specific to the frame, such as the current selection.
// Next ID: 4
message FrameInteractionInfo {
  // The current selection.
  Selection selection = 1 [features = { field_presence: EXPLICIT }];

  // The content node ID of the content node that is currently focused.
  int32 focused_node_id = 2 [features = { field_presence: EXPLICIT }];

  // The content node ID of the content node that is currently focused by a
  // screen reader. If this is set, it means that a screen reader is being used.
  int32 accessibility_focused_node_id = 3 [features = { field_presence: EXPLICIT }];
}

// Represents a selection in the page. This is a frame-level concept.
message Selection {
  // The content node ID of the start node. Note that this could be the same as
  // the end node ID. This node is always before or equal to the end node.
  int32 start_node_id = 1 [features = { field_presence: EXPLICIT }];

  // The character offset of the start of the selection from the start of the
  // text contained in start node.
  int32 start_offset = 2 [features = { field_presence: EXPLICIT }];

  // The content node ID of the end node. Note that this could be the same as
  // the start node ID. This node is always after or equal to the start node.
  int32 end_node_id = 3 [features = { field_presence: EXPLICIT }];

  // The character offset of the end of the selection from the start of the
  // text contained in end node.
  int32 end_offset = 4 [features = { field_presence: EXPLICIT }];

  // The selected text.
  string selected_text = 5 [features = { field_presence: EXPLICIT }];
}

// Directs the action to a specific Document in a frame in Chrome.
// Next ID: 3
message DocumentIdentifier {
  // A unique identifier for a Document loaded in the browser. This ID is
  // guaranteed to be unique across all Documents for the browser's lifetime.
  // The ID is also stable for the Document's lifetime. It can be used to
  // identify the Document across APC calls.
  string serialized_token = 1 [features = { field_presence: EXPLICIT }];
}

// Metadata about paid content in the frame.
// Next ID: 2
message PaidContentMetadata {
  // Whether the frame contains paid content.
  bool contains_paid_content = 1 [features = { field_presence: EXPLICIT }];
}

// The media data for a frame in the web page. If the frame has multiple media
// elements, only one of them is controlled by the media session. The
// transcripts are always attached if any have been generated for past media or
// current media in this frame, while other fields are only populated if there
// is an active media session in the frame.
// Next ID: 9
message MediaData {
  // Type of the media in the frame.
  MediaDataType media_data_type = 1 [features = { field_presence: EXPLICIT }];

  // A list of text segments which can be combined to represent the
  // transcriptions of the media content that have been heard by the user.
  // The transcripts are in ascending order by start timestamps.
  repeated MediaTranscript transcripts = 2;

  // The overall duration of the media.
  int64 duration_milliseconds = 3 [features = { field_presence: EXPLICIT }];

  // The current timestamp position of the media.
  int64 current_position_milliseconds = 4 [features = { field_presence: EXPLICIT }];

  // Whether the media is currently playing or paused.
  bool is_playing = 5 [features = { field_presence: EXPLICIT }];

  // The title of the media. Must be non-empty and set by the website or default
  // to the web page title.
  string title = 6 [features = { field_presence: EXPLICIT }];

  // The artist of the media. May be empty.
  string artist = 7 [features = { field_presence: EXPLICIT }];

  // The album of the media. May be empty.
  string album = 8 [features = { field_presence: EXPLICIT }];
}

// A segment of the media transcript.
// Next ID: 3
message MediaTranscript {
  // A segment of text for the media transcript.
  string text = 1 [features = { field_presence: EXPLICIT }];

  // Non-negative time since the start of the media.
  int64 start_timestamp_milliseconds = 2 [features = { field_presence: EXPLICIT }];
}

// The data for tools exposed by the Document.
message ScriptTool {
  // The name of the tool. This must be unique within the source Document's
  // scope.
  string name = 2 [features = { field_presence: EXPLICIT }];

  // A description of the tool used to understand the capabilities of the tool.
  string description = 3 [features = { field_presence: EXPLICIT }];

  // A JSON schema string describing the input expected by the tool.
  string input_schema = 4 [features = { field_presence: EXPLICIT }];

  // Annotations for the tool.
  ScriptToolAnnotations annotations = 5 [features = { field_presence: EXPLICIT }];
}

// Annotations for the script tool.
message ScriptToolAnnotations {
  bool read_only = 1 [features = { field_presence: EXPLICIT }];
}

// Result of executing a script tool.
// Next ID: 6
// TODO: crbug.com/489841640 - Move this to actions_data.proto.
message ScriptToolResult {
  // The index of the ScriptToolAction in the Actions proto. This is used to
  // match the result to the corresponding action.
  int32 index_of_script_tool_action = 1 [features = { field_presence: EXPLICIT }];

  // The result from executing the tool, if the execution was successful.
  string result = 2 [features = { field_presence: EXPLICIT }];

  // Provides the name and arguments the tool was invoked with. This is
  // populated to provide context for the result.
  string tool_name = 3 [features = { field_presence: EXPLICIT }];

  string input_arguments = 4 [features = { field_presence: EXPLICIT }];

  // The tool that was executed.
  ScriptTool tool = 5 [features = { field_presence: EXPLICIT }];
}

message TableRowData {
  TableRowType type = 1 [features = { field_presence: EXPLICIT }];
}

// Represents the interaction information for the page. This is for top-level
// interactions, such as the mouse position and focused element, for which
// there can only be one unique value.
// Currently this is only tracked for the main frame. The IDs correspond to the
// DOM node IDs of the content nodes in the main frame.
// Next ID: 6
message PageInteractionInfo {
  // The content node ID of the content node that is currently focused.
  // TODO(linnan): Deprecate this field in favor of
  // FrameInteractionInfo.focused_node_id.
  int32 focused_node_id = 1 [features = { field_presence: EXPLICIT }];

  // The content node ID of the content node that is currently focused by a
  // screen reader. If this is set, it means that a screen reader is being used.
  // This is only tracked for the main frame.
  // TODO(linnan): Deprecate this field in favor of
  // FrameInteractionInfo.accessibility_focused_node_id.
  int32 accessibility_focused_node_id = 2 [features = { field_presence: EXPLICIT }];

  // The last known mouse position, in the page coordinate system.
  Point mouse_position = 3 [features = { field_presence: EXPLICIT }];

  // The identifier of the frame that currently has focus.
  DocumentIdentifier focused_frame = 4 [features = { field_presence: EXPLICIT }];

  // The identifier of the frame that currently has accessibility focus. If the
  // field is present but the identifier is empty, it means no frame has
  // accessibility focus. This could be main frame or an iframe.
  DocumentIdentifier accessibility_focused_frame = 5 [features = { field_presence: EXPLICIT }];
}

message Point {
  int32 x = 1 [features = { field_presence: EXPLICIT }];

  int32 y = 2 [features = { field_presence: EXPLICIT }];
}

// Represents a popup window that is open on a web page.
// Next ID: 6
message PopupWindow {
  // Root node for the document in the window.
  ContentNode root_node = 1 [features = { field_presence: EXPLICIT }];

  // The bounding box of the popup window relative to the viewport. The popup is
  // not clipped by any ancestor except the viewport clipping the screenshot.
  BoundingRect visible_bounding_box = 5 [features = { field_presence: EXPLICIT }];

  // Unique identifier for the document which opened this popup window.
  DocumentIdentifier opener_document_id = 3 [features = { field_presence: EXPLICIT }];

  // Unique identifier for the node which opened this popup window. Relies on
  // opener_document_id to determine which document contains the node.
  int32 opener_common_ancestor_dom_node_id = 4 [features = { field_presence: EXPLICIT }];

  reserved 2;
}

// Information that pertains the user's Chrome profile.
// Next ID: 2
message ProfileInformation {
  AutofillInformation autofill_information = 1 [features = { field_presence: EXPLICIT }];
}

// Autofill information that pertains to Autofill data on the client.
// Next ID: 2
message AutofillInformation {
  repeated FillableData fillable_data = 1;

  // The type of data that can be autofilled into a form because the client has
  // corresponding data on file. Note that this is coarse data: A user may have
  // an address on file that does not contain an email address. So the autofill
  // status may indicate that an address is fillable but autofill cannot be
  // triggered on an email field.
  enum FillableData {
    UNSPECIFIED = 0;

    // If reported, the user has at least one address on file.
    ADDRESS = 1;

    // The gap in numbering here exists to stay aligned with
    // FormFillingRequest.RequestedData.

    // If reported, the user has at least one credit card on file.
    CREDIT_CARD = 6;
  }
}

// Metadata about the page from Gemini in Chrome.
// Next ID: 2
message GeminiInChromePageMetadata {
  // Information about the associated screenshot.
  ScreenshotInfo screenshot_info = 1 [features = { field_presence: EXPLICIT }];
}

// The screenshot information for the page. While the screenshot is not
// conveyed in the parent message, this metadata should be used to inform the
// model about the screenshot.
// Next ID: 4
message ScreenshotInfo {
  // Whether the screenshot contains a selection region.
  bool has_selection_region_in_screenshot = 1 [features = { field_presence: EXPLICIT }];

  // Information about the iframes in the screenshot.
  repeated IframeInfo iframe_info = 2;

  // The size of the screenshot in pixels, when it was originally captured.
  BoundingSize screenshot_size = 3 [features = { field_presence: EXPLICIT }];
}

// Information about an iframe in the screenshot.
// Next ID: 4
message IframeInfo {
  // The security origin of the iframe.
  SecurityOrigin security_origin = 1 [features = { field_presence: EXPLICIT }];

  // The URL of the iframe.
  string url = 2 [features = { field_presence: EXPLICIT }];

  // The bounding box of the iframe node in the coordinate space of the
  // screenshot, including all ancestor clipping.
  BoundingRect bounding_box = 3 [features = { field_presence: EXPLICIT }];
}

// Uniquely identifies a DOM elements across all frames.
message AutofillGlobalId {
  string frame_token = 1 [features = { field_presence: EXPLICIT }];

  uint64 renderer_id = 2 [features = { field_presence: EXPLICIT }];
}

message FormData {
  // The name by which autofill knows this form. This is generally either the
  // name attribute or the id_attribute value, which-ever is non-empty with
  // priority given to the name_attribute.
  string form_name = 1 [features = { field_presence: EXPLICIT }];

  // The fields contained in this form.
  repeated FormFieldData fields = 2;

  // Only set during data collection, not in prediction requests.
  AutofillGlobalId global_id = 3 [features = { field_presence: EXPLICIT }];

  // Autofill's internal identifier for the form. Can change when the form
  // changes dynamically.
  // Only set during data collection, not in prediction requests.
  uint64 form_signature = 4 [features = { field_presence: EXPLICIT }];

  // The action URL of the form, if present. This is the resolved value
  // including the final origin.
  string action_url = 5 [features = { field_presence: EXPLICIT }];
}

// Next ID: 15
message FormFieldData {
  // The name for the field.
  string field_name = 1 [features = { field_presence: EXPLICIT }];

  // The label for the field.
  string field_label = 2 [features = { field_presence: EXPLICIT }];

  string field_value = 3 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  bool is_visible = 4 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  // Whether the field is focusable.
  // Only set during data collection, not in prediction requests.
  bool is_focusable = 5 [features = { field_presence: EXPLICIT }];

  // The type of control for this form field.
  FormControlType form_control_type = 6 [features = { field_presence: EXPLICIT }];

  // The options for a select field, if applicable.
  repeated SelectOption select_options = 7;

  // The placeholder text for the field.
  string placeholder = 8 [features = { field_presence: EXPLICIT }];

  // The AX node ID of the form control for this field.
  int32 form_control_ax_node_id = 9 [features = { field_presence: EXPLICIT }];

  bool is_eligible = 10 [
    deprecated = true,
    features = { field_presence: EXPLICIT }
  ];

  // Only set during data collection, not in prediction requests.
  AutofillGlobalId global_id = 11 [features = { field_presence: EXPLICIT }];

  // Autofill's internal identifier for the field. Can change when the form
  // changes dynamically.
  // Only set during data collection, not in prediction requests.
  uint32 field_signature = 12 [features = { field_presence: EXPLICIT }];

  // The text of the elements denoted by the aria-labelledby attribute of field
  // or the value of its aria-label attribute, with priority given to the
  // aria-labelledby attribute.
  string aria_label = 13 [features = { field_presence: EXPLICIT }];

  // The text of the elements denoted by the aria-describedby attribute of field
  // or the value of its aria-description attribute, with priority given to the
  // aria-describedby attribute.
  string aria_description = 14 [features = { field_presence: EXPLICIT }];
}

message TableRow {
  repeated ContentNode cells = 1;
}

// The minimal representation of a tab group.
// Next ID: 5
message TabGroupMinimal {
  // The label that describes this tab group.
  string label = 1 [features = { field_presence: EXPLICIT }];

  // The ids of the tabs that belong in this group.
  repeated int64 tab_ids = 2;

  // The id of the pre-existing tab group this corresponds to, if any.
  string group_id = 3 [features = { field_presence: EXPLICIT }];

  // The emoji that represents this tab group, encoded in UTF-8.
  string emoji = 4 [features = { field_presence: EXPLICIT }];
}

message TabGroup {
  // The label that describes this tab group.
  string label = 1 [features = { field_presence: EXPLICIT }];

  // The tabs that belong in this group.
  repeated Tab tabs = 2;

  // The id of the pre-existing tab group this corresponds to, if any.
  string group_id = 3 [features = { field_presence: EXPLICIT }];
}

// Next ID: 7
message Tab {
  // A unique identifier for the tab.
  int64 tab_id = 1 [features = { field_presence: EXPLICIT }];

  // The title of the tab.
  string title = 2 [features = { field_presence: EXPLICIT }];

  // The URL of the tab.
  string url = 3 [features = { field_presence: EXPLICIT }];

  // The page context of the tab.
  PageContext page_context = 4 [features = { field_presence: EXPLICIT }];

  // Timestamp of when the tab was last active (in milliseconds since epoch).
  int64 last_active_timestamp_ms = 5 [features = { field_presence: EXPLICIT }];

  // Duration in milliseconds the tab spent in the foreground.
  int64 last_foreground_duration_ms = 6
      [features = { field_presence: EXPLICIT }];
}

// The site engagement information for a single site.
message SiteEngagementEntry {
  // The URL of the site.
  string url = 1 [features = { field_presence: EXPLICIT }];

  // On a scale of 0 to 100, the relative score of engagement with the site.
  float score = 2 [features = { field_presence: EXPLICIT }];
}

// The site engagement information for the user.
message SiteEngagement {
  // The site engagement information for the user.
  repeated SiteEngagementEntry entries = 1;
}

// The coordinates of a point.
// Next ID: 4
message Coordinate {
  int32 x = 1 [features = { field_presence: EXPLICIT }];

  int32 y = 2 [features = { field_presence: EXPLICIT }];

  // The type of the coordinate. If not specified, the coordinate is assumed to
  // be relative to the viewport dimensions or screenshot dimensions depending
  // on the context.
  PixelType pixel_type = 3 [features = { field_presence: EXPLICIT }];

  enum PixelType {
    // The coordinate type is not specified. Assumed to be viewport.
    PIXEL_TYPE_UNSPECIFIED = 0;

    // Density independent pixels (DIPs).
    // The coordinate is in DIPs which are independent of OS-level UI scaling.
    // e.g., The coordinate is relative to the viewport dimensions set in APC.
    PIXEL_TYPE_DIPS = 1;

    // Physical pixels.
    // The coordinate is provided in physical screen pixels. Values provided in
    // physical pixels depend on UI scaling factor so must not be used when the
    // scaling factor changes (e.g. APC generated, window moved to a higher
    // density monitor; physical coordinate values must now be invalidated).
    // e.g., The coordinate is relative to the dimensions of the annotated page
    // content root node.
    PIXEL_TYPE_PHYSICAL_PIXELS = 2;
  }
}

// This is a mirror of google.protobuf.Duration.
// Next ID: 3
message TimeDuration {
  // Signed seconds of the span of time. Must be from -315,576,000,000
  // to +315,576,000,000 inclusive. Note: these bounds are computed from:
  // 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
  int64 seconds = 1 [features = { field_presence: EXPLICIT }];

  // Signed fractions of a second at nanosecond resolution of the span
  // of time. Durations less than one second are represented with a 0
  // `seconds` field and a positive or negative `nanos` field. For durations
  // of one second or more, a non-zero value for the `nanos` field must be
  // of the same sign as the `seconds` field. Must be from -999,999,999
  // to +999,999,999 inclusive.
  int32 nanos = 2 [features = { field_presence: EXPLICIT }];
}

// Represents a time zone from the
// [IANA Time Zone Database](https://www.iana.org/time-zones).
//
// This is a mirror of google.type.TimeZone.
// Next ID: 3
message TimeZone {
  // IANA Time Zone Database time zone. For example "America/New_York".
  string id = 1 [features = { field_presence: EXPLICIT }];

  // Optional. IANA Time Zone Database version number. For example "2019a".
  string version = 2 [features = { field_presence: EXPLICIT }];
}

// Represents civil time (or occasionally physical time).
//
// This is a mirror of google.type.DateTime.
// Next ID: 10
message DateTime {
  // Optional. Specifies either the UTC offset or the time zone of the DateTime.
  oneof time_offset {
    // UTC offset. Must be whole seconds, between -18 hours and +18 hours.
    // For example, a UTC offset of -4:00 would be represented as
    // { seconds: -14400 }.
    TimeDuration utc_offset = 8;

    // Time zone.
    TimeZone time_zone = 9;
  }

  // Optional. Year of date. Must be from 1 to 9999, or 0 if specifying a
  // datetime without a year.
  int32 year = 1 [features = { field_presence: EXPLICIT }];

  // Optional. Month of year. Must be from 1 to 12, or 0 if specifying a
  // datetime without a month.
  int32 month = 2 [features = { field_presence: EXPLICIT }];

  // Optional. Day of month. Must be from 1 to 31 and valid for the year and
  // month, or 0 if specifying a datetime without a day.
  int32 day = 3 [features = { field_presence: EXPLICIT }];

  // Optional. Hours of day in 24 hour format. Should be from 0 to 23, defaults
  // to 0 (midnight). An API may choose to allow the value "24:00:00" for
  // scenarios like business closing time.
  int32 hours = 4 [features = { field_presence: EXPLICIT }];

  // Optional. Minutes of hour of day. Must be from 0 to 59, defaults to 0.
  int32 minutes = 5 [features = { field_presence: EXPLICIT }];

  // Optional. Seconds of minutes of the time. Must normally be from 0 to 59,
  // defaults to 0. An API may allow the value 60 if it allows leap-seconds.
  int32 seconds = 6 [features = { field_presence: EXPLICIT }];

  // Optional. Fractions of seconds in nanoseconds. Must be from 0 to
  // 999,999,999, defaults to 0.
  int32 nanos = 7 [features = { field_presence: EXPLICIT }];
}

// A meta tag (https://developer.mozilla.org/en-US/docs/Wecrbug.com/HTML/Element/meta).
// Next ID: 3
message MetaTag {
  // The name attribute of the meta tag.
  string name = 1 [features = { field_presence: EXPLICIT }];

  // The content attribute of the meta tag.
  string content = 2 [features = { field_presence: EXPLICIT }];
}

// Metadata about a frame.
// Next ID: 4
message FrameMetadata {
  // The URL of the frame.
  string url = 1 [features = { field_presence: EXPLICIT }];

  repeated MetaTag meta_tags = 2;

  bool has_media_transcripts = 3 [features = { field_presence: EXPLICIT }];
}

// Metadata (URL and meta tags) from page content. Includes data from meta tags
// for all frames on this page.
// Next ID: 2
message PageMetadata {
  // The main frame is the first entry in the array.
  repeated FrameMetadata frame_metadata = 1;
}

message DocumentSelection {
  // The document identifier of the document/frame that this selection is from.
  DocumentIdentifier document_identifier = 1 [features = { field_presence: EXPLICIT }];

  // The selection in the document.
  Selection selection = 2 [features = { field_presence: EXPLICIT }];
}

// Next ID: 2
message AgentContainerConfig {
  // If the same location is provided multiple times with different metadata,
  // it is undefined which one is actually used.
  //
  // Note: a global blocklist may be written by keeping this field empty.
  //
  // Any attempt to navigate/actuate on a location that has no matching
  // LocationRule will be disallowed.
  //
  // Note: location_rules may include a wildcard Location, to allow the agent
  // to visit any site (with a given set of resources and actuation level).
  repeated LocationRule location_rules = 1;
}

// A rule governing how a web location may or may not be used.
// Next ID: 4
message LocationRule {
  // The location (origin, site, etc.).
  Location location = 1 [features = { field_presence: EXPLICIT }];

  // Metadata/controls associated with this rule.
  RuleMetadata metadata = 2 [features = { field_presence: EXPLICIT }];

  // Navigations to this location must have one of these sources to match this
  // rule. If no sources are provided, then all navigations to this location
  // match this rule.
  repeated NavigationSource navigation_sources = 3;
}

// Locations that the agent may visit and/or actuate.
// May be scoped to an origin, site, or a wildcard token that matches any URL.
// Next ID: 4
message Location {
  oneof identifier_oneof {
    Origin origin = 1;

    Site site = 2;

    // Wildcard that matches any URL.
    AnySite wildcard = 3;
  }
}

// An origin is a combination of a protocol (scheme), host, and port. See
// https://web.dev/articles/same-site-same-origin.
//
// Next ID: 4
message Origin {
  Protocol protocol = 1 [features = { field_presence: EXPLICIT }];

  string host = 2 [features = { field_presence: EXPLICIT }];

  // Assumes the default port for the protocol, if absent.
  int32 port = 3 [features = { field_presence: EXPLICIT }];
}

// A site is a protocol (scheme) and an eTLD+1. Note that computing an eTLD+1
// relies on the Public Suffix List and is not necessarily the same as the host
// in an origin. See https://web.dev/articles/same-site-same-origin.
//
// Next ID: 3
message Site {
  Protocol protocol = 1 [features = { field_presence: EXPLICIT }];

  string domain = 2 [features = { field_presence: EXPLICIT }];
}

// This empty struct represents a wildcard token that matches any URL.
// Next ID: 1
message AnySite {
}

// Next ID: 3
message RuleMetadata {
  // The set of resources that the agent may access when visiting/actuating
  // according to this rule. May be empty if no resources are accessible.
  repeated AgentResource accessible_resources = 1;

  // How the agent may interact with the page.
  // The field is repeated to allow for multiple capabilities to be specified.
  // Empty list means no capabilities are allowed and the model is blocked
  // from interacting with this location.
  repeated ActuationCapability capabilities = 2;

  // Resources that may be accessible to the agent.
  // RESOURCE_UNKNOWN is ignored, RESOURCE_SESSION is the only meaningful value
  // right now.
  // Next ID: 2
  enum AgentResource {
    RESOURCE_UNKNOWN = 0;

    // The agent may use the user's existing session.
    RESOURCE_SESSION = 1;
  }

  // What capabilities the agent has permission for when visiting/actuating on
  // a location.
  // Next ID: 2
  enum ActuationCapability {
    CAPABILITY_UNKNOWN = 0;

    // The agent may navigate to and interact with the page. The agent may also
    // execute any tool.
    CAPABILITY_ALL = 1;
  }
}

// Next ID: 2
message NavigationSource {
  Location source = 1 [features = { field_presence: EXPLICIT }];
}

// Selection text affinity, part of the a11y snapshot.
// Next ID: 3
enum AXTextAffinity {
  AX_TEXT_AFFINITY_NONE = 0;

  AX_TEXT_AFFINITY_DOWNSTREAM = 1;

  AX_TEXT_AFFINITY_UPSTREAM = 2;
}

// AX Role.
// Next ID: 214
enum AXRole {
  AX_ROLE_NONE = 0;

  AX_ROLE_ABBR = 1;

  AX_ROLE_ALERT = 2;

  AX_ROLE_ALERTDIALOG = 3;

  AX_ROLE_APPLICATION = 4;

  AX_ROLE_ARTICLE = 5;

  AX_ROLE_AUDIO = 6;

  AX_ROLE_BANNER = 7;

  AX_ROLE_BLOCKQUOTE = 8;

  AX_ROLE_BUTTON = 9;

  AX_ROLE_CANVAS = 10;

  AX_ROLE_CAPTION = 11;

  AX_ROLE_CARET = 12;

  AX_ROLE_CELL = 13;

  AX_ROLE_CHECKBOX = 14;

  AX_ROLE_CLIENT = 15;

  AX_ROLE_CODE = 16;

  AX_ROLE_COLORWELL = 17;

  AX_ROLE_COLUMN = 18;

  AX_ROLE_COLUMNHEADER = 19;

  AX_ROLE_COMBOBOXGROUPING = 20;

  AX_ROLE_COMBOBOXMENUBUTTON = 21;

  AX_ROLE_COMPLEMENTARY = 22;

  AX_ROLE_COMMENT = 23;

  AX_ROLE_CONTENTDELETION = 24;

  AX_ROLE_CONTENTINSERTION = 25;

  AX_ROLE_CONTENTINFO = 26;

  AX_ROLE_DATE = 27;

  AX_ROLE_DATETIME = 28;

  AX_ROLE_DEFINITION = 29;

  AX_ROLE_DESCRIPTIONLIST = 30;

  AX_ROLE_DESCRIPTIONLISTDETAILDEPRECATED = 31;

  AX_ROLE_DESCRIPTIONLISTTERMDEPRECATED = 32;

  AX_ROLE_DESKTOP = 33;

  AX_ROLE_DETAILS = 34;

  AX_ROLE_DIALOG = 35;

  AX_ROLE_DIRECTORYDEPRECATED = 36;

  AX_ROLE_DISCLOSURETRIANGLE = 37;

  AX_ROLE_DOCABSTRACT = 38;

  AX_ROLE_DOCACKNOWLEDGMENTS = 39;

  AX_ROLE_DOCAFTERWORD = 40;

  AX_ROLE_DOCAPPENDIX = 41;

  AX_ROLE_DOCBACKLINK = 42;

  AX_ROLE_DOCBIBLIOENTRY = 43;

  AX_ROLE_DOCBIBLIOGRAPHY = 44;

  AX_ROLE_DOCBIBLIOREF = 45;

  AX_ROLE_DOCCHAPTER = 46;

  AX_ROLE_DOCCOLOPHON = 47;

  AX_ROLE_DOCCONCLUSION = 48;

  AX_ROLE_DOCCOVER = 49;

  AX_ROLE_DOCCREDIT = 50;

  AX_ROLE_DOCCREDITS = 51;

  AX_ROLE_DOCDEDICATION = 52;

  AX_ROLE_DOCENDNOTE = 53;

  AX_ROLE_DOCENDNOTES = 54;

  AX_ROLE_DOCEPIGRAPH = 55;

  AX_ROLE_DOCEPILOGUE = 56;

  AX_ROLE_DOCERRATA = 57;

  AX_ROLE_DOCEXAMPLE = 58;

  AX_ROLE_DOCFOOTNOTE = 59;

  AX_ROLE_DOCFOREWORD = 60;

  AX_ROLE_DOCGLOSSARY = 61;

  AX_ROLE_DOCGLOSSREF = 62;

  AX_ROLE_DOCINDEX = 63;

  AX_ROLE_DOCINTRODUCTION = 64;

  AX_ROLE_DOCNOTEREF = 65;

  AX_ROLE_DOCNOTICE = 66;

  AX_ROLE_DOCPAGEBREAK = 67;

  AX_ROLE_DOCPAGEFOOTER = 68;

  AX_ROLE_DOCPAGEHEADER = 69;

  AX_ROLE_DOCPAGELIST = 70;

  AX_ROLE_DOCPART = 71;

  AX_ROLE_DOCPREFACE = 72;

  AX_ROLE_DOCPROLOGUE = 73;

  AX_ROLE_DOCPULLQUOTE = 74;

  AX_ROLE_DOCQNA = 75;

  AX_ROLE_DOCSUBTITLE = 76;

  AX_ROLE_DOCTIP = 77;

  AX_ROLE_DOCTOC = 78;

  AX_ROLE_DOCUMENT = 79;

  AX_ROLE_EMBEDDEDOBJECT = 80;

  AX_ROLE_EMPHASIS = 81;

  AX_ROLE_FEED = 82;

  AX_ROLE_FIGCAPTION = 83;

  AX_ROLE_FIGURE = 84;

  AX_ROLE_FOOTER = 85;

  AX_ROLE_SECTIONFOOTER = 86;

  AX_ROLE_FORM = 87;

  AX_ROLE_GENERICCONTAINER = 88;

  AX_ROLE_GRAPHICSDOCUMENT = 89;

  AX_ROLE_GRAPHICSOBJECT = 90;

  AX_ROLE_GRAPHICSSYMBOL = 91;

  AX_ROLE_GRID = 92;

  AX_ROLE_GROUP = 93;

  AX_ROLE_HEADER = 94;

  AX_ROLE_SECTIONHEADER = 95;

  AX_ROLE_HEADING = 96;

  AX_ROLE_IFRAME = 97;

  AX_ROLE_IFRAMEPRESENTATIONAL = 98;

  AX_ROLE_IMAGE = 99;

  AX_ROLE_IMECANDIDATE = 100;

  AX_ROLE_INLINETEXTBOX = 101;

  AX_ROLE_INPUTTIME = 102;

  AX_ROLE_KEYBOARD = 103;

  AX_ROLE_LABELTEXT = 104;

  AX_ROLE_LAYOUTTABLE = 105;

  AX_ROLE_LAYOUTTABLECELL = 106;

  AX_ROLE_LAYOUTTABLEROW = 107;

  AX_ROLE_LEGEND = 108;

  AX_ROLE_LINEBREAK = 109;

  AX_ROLE_LINK = 110;

  AX_ROLE_LIST = 111;

  AX_ROLE_LISTBOX = 112;

  AX_ROLE_LISTBOXOPTION = 113;

  AX_ROLE_LISTGRID = 114;

  AX_ROLE_LISTITEM = 115;

  AX_ROLE_LISTMARKER = 116;

  AX_ROLE_LOG = 117;

  AX_ROLE_MAIN = 118;

  AX_ROLE_MARK = 119;

  AX_ROLE_MARQUEE = 120;

  AX_ROLE_MATH = 121;

  AX_ROLE_MENU = 122;

  AX_ROLE_MENUBAR = 123;

  AX_ROLE_MENUITEM = 124;

  AX_ROLE_MENUITEMCHECKBOX = 125;

  AX_ROLE_MENUITEMRADIO = 126;

  AX_ROLE_MENUITEMSEPARATOR = 213;

  AX_ROLE_MENULISTOPTION = 127;

  AX_ROLE_MENULISTPOPUP = 128;

  AX_ROLE_METER = 129;

  AX_ROLE_NAVIGATION = 130;

  AX_ROLE_NOTE = 131;

  AX_ROLE_PANE = 132;

  AX_ROLE_PARAGRAPH = 133;

  AX_ROLE_PDFACTIONABLEHIGHLIGHT = 134;

  AX_ROLE_PDFROOT = 135;

  AX_ROLE_PLUGINOBJECT = 136;

  AX_ROLE_POPUPBUTTON = 137;

  AX_ROLE_PORTALDEPRECATED = 138;

  AX_ROLE_PREDEPRECATED = 139;

  AX_ROLE_PROGRESSINDICATOR = 140;

  AX_ROLE_RADIOBUTTON = 141;

  AX_ROLE_RADIOGROUP = 142;

  AX_ROLE_REGION = 143;

  AX_ROLE_ROOTWEBAREA = 144;

  AX_ROLE_ROW = 145;

  AX_ROLE_ROWGROUP = 146;

  AX_ROLE_ROWHEADER = 147;

  AX_ROLE_RUBY = 148;

  AX_ROLE_RUBYANNOTATION = 149;

  AX_ROLE_SCROLLBAR = 150;

  AX_ROLE_SCROLLVIEW = 151;

  AX_ROLE_SEARCH = 152;

  AX_ROLE_SEARCHBOX = 153;

  AX_ROLE_SECTION = 154;

  AX_ROLE_SLIDER = 155;

  AX_ROLE_SPINBUTTON = 156;

  AX_ROLE_SPLITTER = 157;

  AX_ROLE_STATICTEXT = 158;

  AX_ROLE_STATUS = 159;

  AX_ROLE_STRONG = 160;

  AX_ROLE_SUGGESTION = 161;

  AX_ROLE_SVGROOT = 162;

  AX_ROLE_SWITCH = 163;

  AX_ROLE_TAB = 164;

  AX_ROLE_TABLIST = 165;

  AX_ROLE_TABPANEL = 166;

  AX_ROLE_TABLE = 167;

  AX_ROLE_TABLEHEADERCONTAINER = 168;

  AX_ROLE_TERM = 169;

  AX_ROLE_TEXTFIELD = 170;

  AX_ROLE_TEXTFIELDWITHCOMBOBOX = 171;

  AX_ROLE_TIME = 172;

  AX_ROLE_TIMER = 173;

  AX_ROLE_TITLEBAR = 174;

  AX_ROLE_TOGGLEBUTTON = 175;

  AX_ROLE_TOOLBAR = 176;

  AX_ROLE_TOOLTIP = 177;

  AX_ROLE_TREE = 178;

  AX_ROLE_TREEGRID = 179;

  AX_ROLE_TREEITEM = 180;

  AX_ROLE_UNKNOWN = 181;

  AX_ROLE_VIDEO = 182;

  AX_ROLE_WEBVIEW = 183;

  AX_ROLE_WINDOW = 184;

  AX_ROLE_SUBSCRIPT = 185;

  AX_ROLE_SUPERSCRIPT = 186;

  AX_ROLE_MATHMLMATH = 187;

  AX_ROLE_MATHMLFRACTION = 188;

  AX_ROLE_MATHMLIDENTIFIER = 189;

  AX_ROLE_MATHMLMULTISCRIPTS = 190;

  AX_ROLE_MATHMLNONESCRIPT = 191;

  AX_ROLE_MATHMLNUMBER = 192;

  AX_ROLE_MATHMLOPERATOR = 193;

  AX_ROLE_MATHMLOVER = 194;

  AX_ROLE_MATHMLPRESCRIPTDELIMITER = 195;

  AX_ROLE_MATHMLROOT = 196;

  AX_ROLE_MATHMLROW = 197;

  AX_ROLE_MATHMLSQUAREROOT = 198;

  AX_ROLE_MATHMLSTRINGLITERAL = 199;

  AX_ROLE_MATHMLSUB = 200;

  AX_ROLE_MATHMLSUBSUP = 201;

  AX_ROLE_MATHMLSUP = 202;

  AX_ROLE_MATHMLTABLE = 203;

  AX_ROLE_MATHMLTABLECELL = 204;

  AX_ROLE_MATHMLTABLEROW = 205;

  AX_ROLE_MATHMLTEXT = 206;

  AX_ROLE_MATHMLUNDER = 207;

  AX_ROLE_MATHMLUNDEROVER = 208;

  AX_ROLE_COMBOBOXSELECT = 209;

  AX_ROLE_DISCLOSURETRIANGLEGROUPED = 210;

  AX_ROLE_SECTIONWITHOUTNAME = 211;

  AX_ROLE_GRIDCELL = 212;
}

// AX String attribute enum.
// Next ID: 47
enum AXStringAttribute {
  AX_SA_NONE = 0;

  AX_SA_ACCESSKEY = 1;

  AX_SA_APPID = 2;

  AX_SA_ARIAINVALIDVALUEDEPRECATED = 3;

  AX_SA_AUTOCOMPLETE = 4;

  AX_SA_CHECKEDSTATEDESCRIPTION = 5;

  AX_SA_CHILDTREEID = 6;

  AX_SA_CHILDTREENODEAPPID = 7;

  AX_SA_CLASSNAME = 8;

  AX_SA_CONTAINERLIVERELEVANT = 9;

  AX_SA_CONTAINERLIVESTATUS = 10;

  AX_SA_DESCRIPTION = 11;

  AX_SA_DISPLAY = 12;

  AX_SA_FONTFAMILY = 13;

  AX_SA_HTMLTAG = 14;

  AX_SA_IMAGEANNOTATION = 15;

  AX_SA_IMAGEDATAURL = 16;

  AX_SA_MATHCONTENT = 17;

  AX_SA_INPUTTYPE = 18;

  AX_SA_KEYSHORTCUTS = 19;

  AX_SA_LANGUAGE = 20;

  AX_SA_NAME = 21;

  AX_SA_LIVERELEVANT = 22;

  AX_SA_LIVESTATUS = 23;

  AX_SA_PLACEHOLDER = 24;

  AX_SA_ROLE = 25;

  AX_SA_ROLEDESCRIPTION = 26;

  AX_SA_TOOLTIP = 27;

  AX_SA_URL = 28;

  AX_SA_VALUE = 29;

  AX_SA_VIRTUALCONTENT = 30;

  AX_SA_DODEFAULTLABEL = 31;

  AX_SA_LONGCLICKLABEL = 32;

  AX_SA_ARIABRAILLELABEL = 33;

  AX_SA_ARIABRAILLEROLEDESCRIPTION = 34;

  AX_SA_LINKTARGET = 35;

  AX_SA_ARIANOTIFICATIONANNOUNCEMENTDEPRECATED = 36;

  AX_SA_ARIANOTIFICATIONIDDEPRECATED = 37;

  AX_SA_HTMLID = 38;

  AX_SA_ARIACELLCOLUMNINDEXTEXT = 39;

  AX_SA_ARIACELLROWINDEXTEXT = 40;

  AX_SA_DATETIME = 41;

  AX_SA_HTMLINPUTNAME = 42;

  AX_SA_MATHARG = 43;

  AX_SA_MATHINTENT = 44;

  AX_SA_CANVASANNOTATION = 45;

  AX_SA_ARIAVALUETEXT = 46;
}

// AX Int attribute enum.
// Next ID: 70
enum AXIntAttribute {
  AX_IA_NONE = 0;

  AX_IA_DEFAULTACTIONVERB = 1;

  AX_IA_SCROLLX = 2;

  AX_IA_SCROLLXMIN = 3;

  AX_IA_SCROLLXMAX = 4;

  AX_IA_SCROLLY = 5;

  AX_IA_SCROLLYMIN = 6;

  AX_IA_SCROLLYMAX = 7;

  AX_IA_TEXTSELSTART = 8;

  AX_IA_TEXTSELEND = 9;

  AX_IA_ARIACOLUMNCOUNT = 10;

  AX_IA_ARIACELLCOLUMNINDEX = 11;

  AX_IA_ARIACELLCOLUMNSPAN = 12;

  AX_IA_ARIAROWCOUNT = 13;

  AX_IA_ARIACELLROWINDEX = 14;

  AX_IA_ARIACELLROWSPAN = 15;

  AX_IA_TABLEROWCOUNT = 16;

  AX_IA_TABLECOLUMNCOUNT = 17;

  AX_IA_TABLEHEADERID = 18;

  AX_IA_TABLEROWINDEX = 19;

  AX_IA_TABLEROWHEADERID = 20;

  AX_IA_TABLECOLUMNINDEX = 21;

  AX_IA_TABLECOLUMNHEADERID = 22;

  AX_IA_TABLECELLCOLUMNINDEX = 23;

  AX_IA_TABLECELLCOLUMNSPAN = 24;

  AX_IA_TABLECELLROWINDEX = 25;

  AX_IA_TABLECELLROWSPAN = 26;

  AX_IA_SORTDIRECTION = 27;

  AX_IA_HIERARCHICALLEVEL = 28;

  AX_IA_NAMEFROM = 29;

  AX_IA_DESCRIPTIONFROM = 30;

  AX_IA_ACTIVEDESCENDANTID = 31;

  AX_IA_ERRORMESSAGEIDDEPRECATED = 32;

  AX_IA_INPAGELINKTARGETID = 33;

  AX_IA_MEMBEROFID = 34;

  AX_IA_NEXTONLINEID = 35;

  AX_IA_POPUPFORID = 36;

  AX_IA_PREVIOUSONLINEID = 37;

  AX_IA_RESTRICTION = 38;

  AX_IA_SETSIZE = 39;

  AX_IA_POSINSET = 40;

  AX_IA_COLORVALUE = 41;

  AX_IA_ARIACURRENTSTATE = 42;

  AX_IA_BACKGROUNDCOLOR = 43;

  AX_IA_COLOR = 44;

  AX_IA_HASPOPUP = 45;

  AX_IA_IMAGEANNOTATIONSTATUS = 46;

  AX_IA_INVALIDSTATE = 47;

  AX_IA_CHECKEDSTATE = 48;

  AX_IA_LISTSTYLE = 49;

  AX_IA_TEXTALIGN = 50;

  AX_IA_TEXTDIRECTION = 51;

  AX_IA_TEXTPOSITION = 52;

  AX_IA_TEXTSTYLE = 53;

  AX_IA_TEXTOVERLINESTYLE = 54;

  AX_IA_TEXTSTRIKETHROUGHSTYLE = 55;

  AX_IA_TEXTUNDERLINESTYLE = 56;

  AX_IA_PREVIOUSFOCUSID = 57;

  AX_IA_NEXTFOCUSID = 58;

  AX_IA_DROPEFFECTDEPRECATED = 59;

  AX_IA_DOMNODEIDDEPRECATED = 60;

  AX_IA_ISPOPUP = 61;

  AX_IA_NEXTWINDOWFOCUSID = 62;

  AX_IA_PREVIOUSWINDOWFOCUSID = 63;

  AX_IA_ARIANOTIFICATIONINTERRUPTDEPRECATED = 64;

  AX_IA_ARIANOTIFICATIONPRIORITYDEPRECATED = 65;

  AX_IA_DETAILSFROM = 66;

  AX_IA_MAXLENGTH = 67;

  AX_IA_PAINTORDER = 68;

  AX_IA_COMMITTEDTEXTLENGTH = 69;
}

// AX Float attribute enum.
// Next ID: 9
enum AXFloatAttribute {
  AX_FA_NONE = 0;

  AX_FA_VALUEFORRANGE = 1;

  AX_FA_MINVALUEFORRANGE = 2;

  AX_FA_MAXVALUEFORRANGE = 3;

  AX_FA_STEPVALUEFORRANGE = 4;

  AX_FA_FONTSIZE = 5;

  AX_FA_FONTWEIGHT = 6;

  AX_FA_TEXTINDENT = 7;

  AX_FA_CHILDTREESCALE = 8;
}

// AX Bool attribute enum.
// Next ID: 26
enum AXBoolAttribute {
  AX_BA_NONE = 0;

  AX_BA_BUSY = 1;

  AX_BA_NONATOMICTEXTFIELDROOT = 2;

  AX_BA_CONTAINERLIVEATOMIC = 3;

  AX_BA_CONTAINERLIVEBUSY = 4;

  AX_BA_LIVEATOMIC = 5;

  AX_BA_MODAL = 6;

  AX_BA_UPDATELOCATIONONLY = 7;

  AX_BA_CANVASHASFALLBACK = 8;

  AX_BA_SCROLLABLE = 9;

  AX_BA_CLICKABLE = 10;

  AX_BA_CLIPSCHILDREN = 11;

  AX_BA_NOTUSERSELECTABLESTYLE = 12;

  AX_BA_SELECTED = 13;

  AX_BA_SELECTEDFROMFOCUS = 14;

  AX_BA_SUPPORTSTEXTLOCATION = 15;

  AX_BA_GRABBEDDEPRECATED = 16;

  AX_BA_ISLINEBREAKINGOBJECT = 17;

  AX_BA_ISPAGEBREAKINGOBJECT = 18;

  AX_BA_HASARIAATTRIBUTE = 19;

  AX_BA_TOUCHPASSTHROUGHDEPRECATED = 20;

  AX_BA_LONGCLICKABLE = 21;

  AX_BA_HASHIDDENOFFSCREENNODES = 22;

  AX_BA_HASCOMPOSITION = 23;

  AX_BA_COMMITTEDBYIME = 24;

  AX_BA_TEXTSUGGESTIONSELECTEDBYIME = 25;
}

// AX IntList attribute enum.
// Next ID: 30
enum AXIntListAttribute {
  AX_ILA_NONE = 0;

  AX_ILA_INDIRECTCHILDIDS = 1;

  AX_ILA_ACTIONSIDS = 29;

  AX_ILA_CONTROLSIDS = 2;

  AX_ILA_DETAILSIDS = 3;

  AX_ILA_DESCRIBEDBYIDS = 4;

  AX_ILA_FLOWTOIDS = 5;

  AX_ILA_LABELLEDBYIDS = 6;

  AX_ILA_RADIOGROUPIDS = 7;

  AX_ILA_MARKERTYPES = 8;

  AX_ILA_MARKERSTARTS = 9;

  AX_ILA_MARKERENDS = 10;

  AX_ILA_CHARACTEROFFSETS = 11;

  AX_ILA_LINESTARTS = 12;

  AX_ILA_WORDSTARTS = 13;

  AX_ILA_WORDENDS = 14;

  AX_ILA_CUSTOMACTIONIDS = 15;

  AX_ILA_CARETBOUNDS = 16;

  AX_ILA_LINEENDS = 17;

  AX_ILA_SENTENCESTARTS = 18;

  AX_ILA_SENTENCEENDS = 19;

  AX_ILA_HIGHLIGHTTYPES = 20;

  AX_ILA_TEXTOPERATIONSTARTANCHORIDS = 21;

  AX_ILA_TEXTOPERATIONSTARTOFFSETS = 22;

  AX_ILA_TEXTOPERATIONENDANCHORIDS = 23;

  AX_ILA_TEXTOPERATIONENDOFFSETS = 24;

  AX_ILA_TEXTOPERATIONS = 25;

  AX_ILA_ERRORMESSAGEIDS = 26;

  AX_ILA_ARIANOTIFICATIONINTERRUPTPROPERTIES = 27;

  AX_ILA_ARIANOTIFICATIONPRIORITYPROPERTIES = 28;
}

// AX StringList attribute enum.
// Next ID: 5
enum AXStringListAttribute {
  AX_SLA_NONE = 0;

  AX_SLA_CUSTOMACTIONDESCRIPTIONS = 1;

  AX_SLA_ARIANOTIFICATIONANNOUNCEMENTS = 2;

  AX_SLA_ARIANOTIFICATIONTYPES = 3;

  AX_SLA_TEXTOPERATIONREPLACEMENTSTRINGS = 4;
}

// This will be updated when there is a significant change in the parsing logic.
// Next ID: 3
enum AnnotatedPageContentVersion {
  option allow_alias = true;

  ANNOTATED_PAGE_CONTENT_VERSION_UNKNOWN = 0;

  ANNOTATED_PAGE_CONTENT_VERSION_1_0 = 1;

  // DEPRECATED: Use AnnotatedPageContentMode mode instead.
  // TODO(crbug.com/490195093): Maintain both on the client until all users have been
  // switched over.
  ANNOTATED_PAGE_CONTENT_VERSION_ONLY_ACTIONABLE_ELEMENTS_1_0 = 2 [deprecated = true];

  // The maximum valid version of the proto. This value includes deprecated
  // versions to ensure backward compatibility with older clients.
  ANNOTATED_PAGE_CONTENT_VERSION_MAX_VALID = 2;
}

// The extraction on the client can be configured to a specific mode. This
// tracks the mode used to extract this proto.
enum AnnotatedPageContentMode {
  ANNOTATED_PAGE_CONTENT_MODE_DEFAULT = 0;

  // This mode is strictly a superset of the default mode. It includes
  // additional information to understand which content a user can interact
  // with.
  //
  // Note: This mode is under active development and backwards incompatible
  // changes are expected.
  ANNOTATED_PAGE_CONTENT_MODE_ACTIONABLE_ELEMENTS = 1;
}

// Indicates the structure of the ContentNode. Suggests which type of
// content_data will be found in the ContentNode.
// When adding new types, please also update AIPageContentAttributeType in
// third_party/blink/public/mojom/content_extraction/ai_page_content.mojom.
// See crrev.com/c/6072788 for an example.
// Next ID: 30
enum ContentAttributeType {
  // Unknown is not a valid attribute type and should never be used by the
  // client. You can consider discarding ContentNodes with this attribute type.
  CONTENT_ATTRIBUTE_UNKNOWN = 0;

  CONTENT_ATTRIBUTE_ROOT = 1;

  CONTENT_ATTRIBUTE_CONTAINER = 2;

  CONTENT_ATTRIBUTE_IFRAME = 3;

  // Text chunks.
  CONTENT_ATTRIBUTE_PARAGRAPH = 4;

  CONTENT_ATTRIBUTE_HEADING = 5;

  CONTENT_ATTRIBUTE_TEXT = 20;

  CONTENT_ATTRIBUTE_ANCHOR = 22;

  // Image chunks.
  CONTENT_ATTRIBUTE_IMAGE = 9;

  // Root SVG nodes.
  CONTENT_ATTRIBUTE_SVG_ROOT = 25;

  CONTENT_ATTRIBUTE_CANVAS = 26;

  CONTENT_ATTRIBUTE_VIDEO = 27;

  // Structured chunks.
  CONTENT_ATTRIBUTE_ORDERED_LIST = 6;

  CONTENT_ATTRIBUTE_UNORDERED_LIST = 7;

  CONTENT_ATTRIBUTE_LIST_ITEM = 23;

  CONTENT_ATTRIBUTE_FORM = 8;

  CONTENT_ATTRIBUTE_FORM_CONTROL = 24;

  CONTENT_ATTRIBUTE_TABLE = 10;

  CONTENT_ATTRIBUTE_TABLE_ROW = 21;

  CONTENT_ATTRIBUTE_TABLE_CELL = 11;

  // Dialog/modal containers.
  CONTENT_ATTRIBUTE_DIALOG_MODAL = 28;

  CONTENT_ATTRIBUTE_DIALOG_MODELESS = 29;

  reserved 12, 13, 14, 15, 16, 17, 18, 19;
}

// CSS position property values.
enum CssPosition {
  CSS_POSITION_STATIC_DEFAULT = 0;

  CSS_POSITION_RELATIVE = 1;

  CSS_POSITION_ABSOLUTE = 2;

  CSS_POSITION_FIXED = 3;

  CSS_POSITION_STICKY = 4;
}

// The reason why a node is clickable.
// Next ID: 17
enum ClickabilityReason {
  // The node is a native form control.
  CLICKABILITY_REASON_CLICKABLE_CONTROL = 0;

  // The node has a click event handler.
  CLICKABILITY_REASON_CLICK_HANDLER = 1;

  // The node has mouse event handlers like mouseup, mousedown, mouseover and
  // mouseenter. Deprecated in favor of
  // CLICKABILITY_REASON_MOUSE_CLICK and CLICKABILITY_REASON_MOUSE_HOVER.
  // TODO(crbug.com/490195093): Remove this value.
  CLICKABILITY_REASON_MOUSE_EVENTS = 2 [deprecated = true];

  // The node has keyboard event handlers like keydown, keypress, keyup.
  CLICKABILITY_REASON_KEY_EVENTS = 3;

  // The node's text can be edited.
  CLICKABILITY_REASON_EDITABLE = 4;

  // The node uses cursor css to indicate the element is interactive.
  CLICKABILITY_REASON_CURSOR_POINTER = 5;

  // The node has a clickable aria role.
  CLICKABILITY_REASON_ARIA_ROLE = 6;

  // The node has the aria-haspopup attribute indicating it opens a popup on
  // activation.
  CLICKABILITY_REASON_ARIA_HAS_POPUP = 7;

  // The node has the aria-expanded attribute indicating it controls the
  // visibility of other elements. This reason implies that the associated
  // control is currently expanded.
  CLICKABILITY_REASON_ARIA_EXPANDED_TRUE = 8;

  // The node has the aria-expanded attribute indicating it controls the
  // visibility of other elements. This reason implies that the associated
  // control is currently collapsed.
  CLICKABILITY_REASON_ARIA_EXPANDED_FALSE = 9;

  // The node has the tabIndex attribute set to a valid value.
  CLICKABILITY_REASON_TAB_INDEX = 10;

  // The node has autocomplete, as indicated by the same-named attribute or
  // aria-autocomplete.
  CLICKABILITY_REASON_AUTOCOMPLETE = 11;

  // The node has mouse event handlers like mouseup and mousedown.
  CLICKABILITY_REASON_MOUSE_CLICK = 12;

  // The node has mouse event handlers like mouseover and mouseenter.
  CLICKABILITY_REASON_MOUSE_HOVER = 13;

  // The node has a CSS :hover pseudo-class, which indicates that it changes
  // state when a mouse hovers over it. This should be relatively low-priority
  // compared to stronger clickability signals. There's not enough granularity
  // in Chrome to know what properties the rule might effect, so this reason
  // just indicates that a :hover rule is defined.
  CLICKABILITY_REASON_HOVER_PSEUDO_CLASS = 14;

  // The node has the aria-checked or aria-pressed attribute indicating it can
  // be toggled.
  CLICKABILITY_REASON_ARIA_TOGGLE = 15;

  // The node has the aria-selected attribute indicating it can be selected or
  // unselected.
  CLICKABILITY_REASON_ARIA_SELECTABLE = 16;
}

// Provides hints that indicate that interaction with this node is disabled.
// Next ID: 6
enum InteractionDisabledReason {
  INTERACTION_DISABLED_REASON_UNSPECIFIED = 0;

  // The node is disabled by the `disabled` attribute.
  INTERACTION_DISABLED_REASON_DISABLED = 1;

  // The node is disabled by the `aria-disabled` attribute.
  INTERACTION_DISABLED_REASON_ARIA_DISABLED = 2;

  // The node has the style `cursor: not-allowed`.
  INTERACTION_DISABLED_REASON_CURSOR_NOT_ALLOWED = 3;

  // The node is hidden from the accessibility tree via `aria-hidden="true"`
  // on an ancestor node or itself.
  INTERACTION_DISABLED_REASON_ARIA_HIDDEN = 4;

  // The node has an ARIA Role of `presentation` or `none`.
  INTERACTION_DISABLED_REASON_ARIA_ROLE_PRESENTATIONAL = 5;
}

// Next ID: 5
enum TextSize {
  TEXT_SIZE_M_DEFAULT = 0;

  TEXT_SIZE_XS = 1;

  TEXT_SIZE_S = 2;

  TEXT_SIZE_L = 3;

  TEXT_SIZE_XL = 4;
}

// The relationship between the linked URL and the current document.
// https://html.spec.whatwg.org/multipage/links.html#linkTypes
enum AnchorRel {
  ANCHOR_REL_UNKNOWN = 0;

  ANCHOR_REL_NO_REFERRER = 1;

  ANCHOR_REL_NO_OPENER = 2;

  ANCHOR_REL_OPENER = 3;

  ANCHOR_REL_PRIVACY_POLICY = 4;

  ANCHOR_REL_TERMS_OF_SERVICE = 5;
}

// Matches FormControlType in mojo, but off by one, because this list contains
// an "UNSPECIFIED" value at 0.
// https://source.chromium.org/chromium/chromium/src/+/main:components/autofill/core/common/mojom/autofill_types.mojom;l=17;drc=105770df485ace262780d95126bb60b1a16ec340;bpv=1;bpt=1
// Next ID: 34
enum FormControlType {
  FORM_CONTROL_TYPE_UNSPECIFIED = 0;

  FORM_CONTROL_TYPE_CONTENT_EDITABLE = 1;

  FORM_CONTROL_TYPE_INPUT_CHECKBOX = 2;

  FORM_CONTROL_TYPE_INPUT_EMAIL = 3;

  FORM_CONTROL_TYPE_INPUT_MONTH = 4;

  FORM_CONTROL_TYPE_INPUT_NUMBER = 5;

  FORM_CONTROL_TYPE_INPUT_PASSWORD = 6;

  FORM_CONTROL_TYPE_INPUT_RADIO = 7;

  FORM_CONTROL_TYPE_INPUT_SEARCH = 8;

  FORM_CONTROL_TYPE_INPUT_TELEPHONE = 9;

  FORM_CONTROL_TYPE_INPUT_TEXT = 10;

  FORM_CONTROL_TYPE_INPUT_URL = 11;

  FORM_CONTROL_TYPE_SELECT_ONE = 12;

  FORM_CONTROL_TYPE_SELECT_MULTIPLE = 13;

  FORM_CONTROL_TYPE_TEXT_AREA = 15;

  FORM_CONTROL_TYPE_BUTTON_BUTTON = 16;

  FORM_CONTROL_TYPE_BUTTON_SUBMIT = 17;

  FORM_CONTROL_TYPE_BUTTON_RESET = 18;

  FORM_CONTROL_TYPE_BUTTON_POPOVER = 19;

  FORM_CONTROL_TYPE_FIELDSET = 20;

  FORM_CONTROL_TYPE_INPUT_BUTTON = 21;

  FORM_CONTROL_TYPE_INPUT_COLOR = 22;

  FORM_CONTROL_TYPE_INPUT_DATE = 23;

  FORM_CONTROL_TYPE_INPUT_DATETIME_LOCAL = 24;

  FORM_CONTROL_TYPE_INPUT_FILE = 25;

  FORM_CONTROL_TYPE_INPUT_HIDDEN = 26;

  FORM_CONTROL_TYPE_INPUT_IMAGE = 27;

  FORM_CONTROL_TYPE_INPUT_RANGE = 28;

  FORM_CONTROL_TYPE_INPUT_RESET = 29;

  FORM_CONTROL_TYPE_INPUT_SUBMIT = 30;

  FORM_CONTROL_TYPE_INPUT_TIME = 31;

  FORM_CONTROL_TYPE_INPUT_WEEK = 32;

  FORM_CONTROL_TYPE_OUTPUT = 33;
}

enum RedactionDecision {
  // No redaction necessary for this node type.
  REDACTION_DECISION_NO_REDACTION_NECESSARY = 0;

  // Empty password inputs are not redacted.
  REDACTION_DECISION_UNREDACTED_EMPTY_PASSWORD = 1;

  // Is a password input or was in the past.
  REDACTION_DECISION_REDACTED_HAS_BEEN_PASSWORD = 2;

  // Empty payment fields are not redacted.
  REDACTION_DECISION_UNREDACTED_EMPTY_PAYMENT_FIELD = 3;

  // Is a non-empty field that autofill recognized as a sensitive payment field
  // type and so must be redacted.
  REDACTION_DECISION_REDACTED_IS_SENSITIVE_PAYMENT_FIELD = 4;

  // Empty inputs which have been classified as password-like by heuristic
  // redaction (e.g. `-webkit-text-security`). These are not redacted since they
  // contain no sensitive content, but the classification is preserved.
  REDACTION_DECISION_UNREDACTED_EMPTY_CUSTOM_PASSWORD = 5;

  // Is a password-like input detected by heuristic redaction based on CSS
  // masking (e.g. `-webkit-text-security` set to a masking value, not `none`).
  REDACTION_DECISION_REDACTED_CUSTOM_PASSWORD_CSS = 6;

  // Is a password-like input detected by heuristic redaction based on a
  // JavaScript-masked value (e.g. mostly bullet-like masking characters).
  REDACTION_DECISION_REDACTED_CUSTOM_PASSWORD_JS = 7;

  // Is a non-empty field that autofill recognized as an OTP field and so must
  // be redacted.
  REDACTION_DECISION_REDACTED_IS_OTP = 8;

  // Is a empty field that autofill recognized as an OTP field.
  REDACTION_DECISION_UNREDACTED_EMPTY_OTP_FIELD = 9;
}

// The type of data that can be autofilled into a form.
enum CoarseAutofillFieldType {
  COARSE_AUTOFILL_FIELD_TYPE_UNSUPPORTED = 0;

  COARSE_AUTOFILL_FIELD_TYPE_ADDRESS = 1;

  COARSE_AUTOFILL_FIELD_TYPE_CREDIT_CARD = 2;

  COARSE_AUTOFILL_FIELD_TYPE_OTP = 3;
}

// Indicates the type of media in the media data.
// Next ID: 3
enum MediaDataType {
  MEDIA_DATA_TYPE_UNKNOWN = 0;

  MEDIA_DATA_TYPE_VIDEO = 1;

  MEDIA_DATA_TYPE_AUDIO = 2;
}

enum TableRowType {
  TABLE_ROW_TYPE_UNKNOWN = 0;

  TABLE_ROW_TYPE_HEADER = 1;

  TABLE_ROW_TYPE_BODY = 2;

  TABLE_ROW_TYPE_FOOTER = 3;
}

// Indicates the semantic role of the content. These can come from the aria
// role, the html tag, or are assumed from some properties of the page.
// When adding new roles, please also update AIPageContentAnnotatedRole in
// third_party/blink/public/mojom/content_extraction/ai_page_content.mojom.
// Next ID: 15
enum AnnotatedRole {
  ANNOTATED_ROLE_UNKNOWN = 0;

  // Landmark/section chunks.
  ANNOTATED_ROLE_HEADER = 5;

  ANNOTATED_ROLE_NAV = 6;

  ANNOTATED_ROLE_SEARCH = 7;

  ANNOTATED_ROLE_MAIN = 8;

  ANNOTATED_ROLE_ARTICLE = 9;

  ANNOTATED_ROLE_SECTION = 10;

  ANNOTATED_ROLE_ASIDE = 11;

  ANNOTATED_ROLE_FOOTER = 12;

  // Indicates that the subtree for this ContentNode is hidden from the user but
  // accessible via features like find-in-page. See `hidden=until-found` in
  // https://developer.mozilla.org/en-US/docs/Wecrbug.com/HTML/Global_attributes/hidden
  // for details.
  //
  // Note: This is different from Geometry.visible_bounding_box being empty
  // which indicates whether the content is offscreen. The visible_bounding_box
  // for nodes in a hidden subtree may be non-empty, depending on whether the
  // content would be in the viewport if the user searched for it.
  ANNOTATED_ROLE_CONTENT_HIDDEN = 13;

  // Indicates that the subtree for this ContentNode contains content marked as
  // isAccessibleForFree=false by a schema.org CreativeWork declaration, as
  // described at
  // https://developers.google.com/search/docs/appearance/structured-data/paywalled-content.
  ANNOTATED_ROLE_PAID_CONTENT = 14;

  reserved 1 to 4;
}

// Next ID: 5
enum Protocol {
  PROTOCOL_UNKNOWN = 0;

  PROTOCOL_HTTP = 1;

  PROTOCOL_HTTPS = 2;

  PROTOCOL_WS = 3;

  PROTOCOL_WSS = 4;
}

// Whether or not status of the model's output is a success (i.e "is good") or
// is a failure (i.e "is bad").
// Next ID: 3
enum FinalModelStatus {
  FINAL_MODEL_STATUS_UNSPECIFIED = 0;

  FINAL_MODEL_STATUS_SUCCESS = 1;

  FINAL_MODEL_STATUS_FAILURE = 2;
}

// Next ID: 3
enum UserFeedback {
  USER_FEEDBACK_UNSPECIFIED = 0;

  USER_FEEDBACK_THUMBS_DOWN = 1;

  USER_FEEDBACK_THUMBS_UP = 2;
}

// The platform for the user's Chrome on which the request was made. Roughly
// matches the same platforms that are available via UMA.
enum ChromePlatform {
  // Unknown is used when the user's platform cannot be resolved.
  CHROME_PLATFORM_UNKNOWN = 0;

  // Android based platforms.
  CHROME_PLATFORM_ANDROID = 1;

  // ChromeOS platforms including all architectures.
  CHROME_PLATFORM_CHROMEOS = 2;

  // IOS based platforms.
  CHROME_PLATFORM_IOS = 3;

  // Linux platforms including all architectures.
  CHROME_PLATFORM_LINUX = 4;

  // Mac based platforms.
  CHROME_PLATFORM_MAC = 5;

  // Windows based platforms.
  CHROME_PLATFORM_WINDOWS = 6;
}
