Home | History | Annotate | Download | only in proto
      1 /*
      2  * Copyright 2014 Google Inc. All rights reserved.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *   http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 syntax = "proto3";
     18 
     19 package kythe.proto;
     20 
     21 // Design document: <link when written>
     22 // This proto represents a very preliminary attempt to define a cross-reference
     23 // service interface, based on Kythe data.
     24 //
     25 // Tickets are Kythe URIs (http://www.kythe.io/docs/kythe-uri-spec.html).
     26 
     27 // XRefService provides access to a Kythe graph for fast read-only access to
     28 // cross-reference relationships.  What constitutes a "Cross-reference" is not
     29 // precisely defined, but generally includes non-transitive (single-step)
     30 // relation like usage of a declaration, instantiation of a type, invocation of
     31 // a function, direct inheritance or overrides, and so forth.  Some transitive
     32 // relations can be converted into cross-references by precomputing a flattened
     33 // representation of a transitive relation.  In general, though, this service
     34 // is designed to be most efficient for single-step expansions.
     35 //
     36 // Key design principles:
     37 //  - All requests must be satisfied "quickly", e.g., in time proportional to
     38 //    the size of the returned set.
     39 //
     40 //  - The client should be able to batch related requests.
     41 //
     42 //  - The client specifies exactly what facts should be returned.
     43 //
     44 // There is no distinction made in the API between "node not found" and "no
     45 // facts/edges for node".  A node is extensionally defined by its facts and
     46 // edges, so a node without any facts or edges is not considered to exist.
     47 service XRefService {
     48 
     49   // TODO(schroederc): break off Nodes/Edges into a separate service
     50 
     51   // Nodes returns a subset of the facts for each of the requested nodes.
     52   rpc Nodes(NodesRequest) returns (NodesReply) {}
     53 
     54   // Edges returns a subset of the outbound edges for each of a set of
     55   // requested nodes.
     56   rpc Edges(EdgesRequest) returns (EdgesReply) {}
     57 
     58   // Decorations returns an index of the nodes and edges associated with a
     59   // particular file node.
     60   rpc Decorations(DecorationsRequest) returns (DecorationsReply) {}
     61 
     62   // CrossReferences returns the global references, definitions, and
     63   // documentation of a set of requested nodes.
     64   rpc CrossReferences(CrossReferencesRequest) returns (CrossReferencesReply) {}
     65 
     66   // Callers takes a set of tickets for semantic objects and returns the set
     67   // of places where those objects were called. For example, in the program
     68   //   void bar() { foo(); foo(); } void baz() { foo(); } void foo() { }
     69   // `Callers({foo})` would return:
     70   //   {(bar, {first-call-anchor, second-call-anchor}),
     71   //    (baz, {first-call-anchor})}
     72   // To walk further up the call graph, you can project the first field of
     73   // each tuple in the result set ({bar, baz}) and feed that set back in
     74   // to a new Callers request.
     75   //
     76   // The core of this query is specified in terms of graph operations in the
     77   // Kythe repository at //kythe/docs/schema/callgraph.txt.
     78   rpc Callers(CallersRequest) returns (CallersReply) {}
     79 
     80   // Documentation takes a set of tickets for semantic objects and returns
     81   // documentation about them, including generated signatures and
     82   // user-provided text. The documentation may refer to tickets for other
     83   // nodes in the graph.
     84   rpc Documentation(DocumentationRequest) returns (DocumentationReply) {}
     85 }
     86 
     87 message NodesRequest {
     88   // The tickets of the nodes to be looked up.
     89   repeated string ticket = 1;
     90 
     91   // A collection of filter globs that specify which facts (by name) should be
     92   // returned for each node.  If filter is empty or unset, all available facts
     93   // are returned for each matching node.  The filter applies to ALL requested
     94   // nodes.  For different filters per node, the client must issue separate
     95   // requests.  See EdgesRequest for the format of the filter globs.
     96   repeated string filter = 2;
     97 }
     98 
     99 message NodeInfo {
    100   // The matching facts known for that node, a map from fact name to value.
    101   map<string, bytes> facts = 2;
    102 
    103   // If known and unambiguous, an anchor ticket for this node's definition
    104   // location.
    105   string definition = 5;
    106 
    107   reserved 1;
    108   reserved "ticket";
    109 }
    110 
    111 message NodesReply {
    112   // One NodeInfo, keyed by its ticket, is returned for each requested node
    113   // that had a non-zero number of matching facts.  Each NodeInfo will not have
    114   // its ticket set since it would just be a copy of the map keys.
    115   map<string, NodeInfo> nodes = 1;
    116 }
    117 
    118 message EdgesRequest {
    119   // The tickets of the source nodes for which edges are requested.
    120   // The service will return an error if no tickets are specified.
    121   repeated string ticket = 1;
    122 
    123   // The kinds of outbound edges that should be returned for each matching
    124   // source node.  If empty, all available edge kinds are returned.
    125   repeated string kind = 2;
    126 
    127   // A collection of filter globs that specify which facts (by name) should be
    128   // returned for the target node of each matching edge.  If filter is empty,
    129   // no facts are returned.
    130   //
    131   // The supported glob operators are:
    132   //   *   zero or more non-slash characters ([^/]*)
    133   //   ?   any single non-slash character ([^/])
    134   //   **  zero or more of any character (.*)
    135   //
    136   // All other characters match literally, and the glob must consume the entire
    137   // name in order to match.  The facts returned are the union of those matched
    138   // by all the globs provided.
    139   repeated string filter = 3;
    140 
    141   // The edges matching a request are organized into logical pages.  The size
    142   // of each page is a number of distinct edges.  Notionally: All the matching
    143   // edges are ordered lexicographically by (start_ticket, kind, end_ticket);
    144   // the page_token determines where in the ordering to start, and page_size
    145   // determines how many edges should be returned.
    146   //
    147   // If page_token is empty, edges will be returned starting at the beginning
    148   // of the sequence; otherwise the starting point named by the page_token will
    149   // be used.  Legal values of page_token are returned by the server in the
    150   // next_page_token field of the EdgesReply.  A page token should be treated
    151   // as an opaque value by the client, and is valid only relative to a
    152   // particular set of tickets and kinds.  If an invalid page token is
    153   // requested, the server will return an error.
    154   //
    155   // If page_size > 0, at most that number of edges will be returned by the
    156   // service for this request (see EdgeSet and EdgesReply below).
    157   // If page_size = 0, the default, the server will assume a reasonable default
    158   // page size.  The server will return an error if page_size < 0.
    159   //
    160   // The server is allowed to return fewer edges than the requested page_size,
    161   // even if more are available, save that it must return at least 1 edge if
    162   // any are available at all.
    163   int32  page_size  = 8;
    164   string page_token = 9;
    165 
    166 
    167   // TODO(fromberger): Should this interface support automatic indirection
    168   // through "name" nodes?
    169   // For now, I'm assuming name-indirecting lookup will be a separate
    170   // API, and that the initial clients will just make two (batching)
    171   // calls if they need to.
    172 }
    173 
    174 // An EdgeSet represents a collection of edges outbound from a single node.  The
    175 // edges are organized into groups, each sharing a common edge kind.
    176 //
    177 // The number of edges represented by an EdgeSet es, denoted len(es), is the sum
    178 // of the lengths of the repeated edge fields for all the groups in the EdgeSet.
    179 // This count is used to determine page size in a request.
    180 message EdgeSet {
    181   message Group {
    182     message Edge {
    183       string target_ticket = 1;
    184 
    185       // An optional integer to give an ordering between multiple edges of same
    186       // source and kind to one or more targets.  See https://kythe.io/schema
    187       // for when ordinals are used for a given edge kind.
    188       int32 ordinal = 2;
    189     }
    190 
    191     repeated Edge edge = 2;
    192 
    193     reserved 1;
    194     reserved "kind";
    195   }
    196 
    197   // Each group is a collection of outbound edges from source node sharing a
    198   // given kind, the map's keys.  In a given EdgeSet, the server will not send
    199   // more than one group with the same kind label.
    200   map<string, Group> groups = 2;
    201 
    202   reserved 1;
    203   reserved "source_ticket";
    204 }
    205 
    206 message EdgesReply {
    207   // This field will contain one EdgeSet for each source node with one or more
    208   // matching outbound edges, keyed by the source node's ticket.  The number of
    209   // edges represented by an EdgesReply er, denoted len(er), is the sum of
    210   // len(es) for each es in edge_sets.  This count is used to determine the page
    211   // size.
    212   map<string, EdgeSet> edge_sets = 1;
    213 
    214   // This field will contain one entry, keyed by ticket, for each distinct node
    215   // referenced by some edge in edgesets, for which there is one or more
    216   // matching facts.
    217   //
    218   // Rationale: This prevents us from having to copy the data to all the end
    219   // nodes, but allows the client to have that information without making
    220   // additional requests.
    221   map<string, NodeInfo> nodes = 2;
    222 
    223   // Total number of edges on all pages matching requested kinds, by kind.
    224   map<string, int64> total_edges_by_kind = 5;
    225 
    226   // If there are additional pages of edges after the ones returned in this
    227   // reply, next_page_token is the page token that may be passed to fetch the
    228   // next page in sequence after this one.  If there are no additional edges,
    229   // this field will be empty.
    230   string next_page_token = 9;
    231 }
    232 
    233 // A Location represents a single span of zero or more contiguous bytes of a
    234 // file or buffer.  An empty LOCATION denotes the entirety of the referenced
    235 // file or buffer.
    236 //
    237 message Location {
    238   // TODO(schroederc): reuse Span from common.proto
    239 
    240   // The ticket of the file this location belongs to.  If the location
    241   // represents a memory buffer, the ticket should be omitted.
    242   string ticket = 1;
    243 
    244   enum Kind {
    245     // The entire file; the start and end fields are ignored.
    246     FILE = 0;
    247 
    248     // The point or span of file subtended by start and end.
    249     SPAN = 1;
    250   }
    251 
    252   // What kind of location this is.
    253   Kind kind = 2;
    254 
    255   // A Point represents a location within a file or buffer.
    256   //
    257   // If line_number  0, the line number and column offset are considered
    258   // unknown and will be ignored.
    259   //
    260   // A point with line_number > 0 is said to be _normalized_ if it satisfies
    261   // the constraint 0  column_offset  bytelen(line_number); that is, if the
    262   // column_offset is within the actual range of the corresponding line.  A
    263   // point can be normalized by adjusting line_number and column_offset so that
    264   // this constraint is satisfied.  This may be impossible if the column offset
    265   // exceeds the bounds of the file.
    266   message Point {
    267     // The offset in bytes from the beginning of the file.
    268     // Requires 0  byte_offset  len(file).
    269     int32 byte_offset = 1;
    270 
    271     // The line number containing the point, 1-based.
    272     int32 line_number = 2;
    273 
    274     // The byte offset of the point within its line.
    275     int32 column_offset = 3;
    276   }
    277 
    278   // The starting point of the location.
    279   Point start = 3;
    280 
    281   // The ending point of the location.
    282   Point end = 4;
    283 
    284   // A location is _valid_ if 0  start.offset  end.offset.  If a valid
    285   // location has start.offset = end.offset, it denotes a single point;
    286   // otherwise it denotes the half-closed interval [start.offset, end.offset).
    287   //
    288   // When kind = FILE, start and end should be unset or set to zero values.
    289 }
    290 
    291 message DecorationsRequest {
    292   // The location of the file to fetch decorations for.  The ticket of location
    293   // must be non-empty.  It is an error in any case if location is invalid.
    294   Location location = 1;
    295 
    296   enum SpanKind {
    297     // If the location is a SPAN, only decorations contained within the
    298     // specified window of the file are returned.  This is the default behavior.
    299     WITHIN_SPAN = 0;
    300 
    301     // If the location is a SPAN, any decorations that surround it are returned.
    302     AROUND_SPAN = 1;
    303   }
    304 
    305   // How to treat SPAN locations.
    306   SpanKind span_kind = 10;
    307 
    308   // If dirty_buffer is non-empty, the results will be adjusted (patched) to
    309   // account for the regions of the specified file differing from the contents
    310   // of the dirty buffer.
    311   bytes dirty_buffer = 2;
    312 
    313   // If true, return the encoded source text for the selected window.  Source
    314   // text is not affected by patching.
    315   bool source_text = 3;
    316 
    317   // If true, return reference edges whose source nodes are located in the
    318   // selected window.  References are affected by patching.
    319   bool references = 4;
    320 
    321   // If true, return definition locations, if possible, for each returned
    322   // reference target in the DecorationsReply.
    323   bool target_definitions = 6;
    324 
    325   // A collection of filter globs that specify which facts (by name) should be
    326   // returned for each node.  If filter is empty or unset, no node facts are
    327   // returned.  The filter applies to ALL referenced nodes.  See EdgesRequest
    328   // for the format of the filter globs.
    329   repeated string filter = 5;
    330 }
    331 
    332 message DecorationsReply {
    333   // The normalized location for which decorations are returned.
    334   Location location = 1;
    335 
    336   // The encoded source text for the selected window.
    337   bytes source_text = 2;
    338   string encoding = 3;
    339 
    340   // Represents a reference edge source ---KIND---> target.  Each source is an
    341   // anchor within the requested source location.
    342   message Reference {
    343     string source_ticket = 1;
    344     string target_ticket = 2;
    345     string kind = 3;
    346 
    347     // Starting byte offset of this references's anchor (source_ticket) span.
    348     Location.Point anchor_start = 10;
    349     // Ending byte offset of this references's anchor (source_ticket) span.
    350     Location.Point anchor_end = 11;
    351 
    352     // Anchor ticket of the target's definition.  Populated only if
    353     // target_definitions is true in the DecorationsRequest and the target has
    354     // a single unambiguous definition.  For each ticket, an Anchor will be
    355     // populated in the top-level definition_locations map.
    356     string target_definition = 4;
    357   }
    358 
    359   // The reference edges located in the specified window.
    360   repeated Reference reference = 4;
    361 
    362   // This field will contain one entry, keyed by ticket, for each distinct node
    363   // referenced by a reference edge that has at least 1 non-filtered fact.
    364   map<string, NodeInfo> nodes = 15;
    365 
    366   // Each anchor cited as a target definition in the references.  The map is
    367   // keyed by each anchor's ticket.
    368   map<string, Anchor> definition_locations = 16;
    369 
    370   // TODO(fromberger): Patch diff information.
    371 }
    372 
    373 message CrossReferencesRequest {
    374   // Set of nodes for which to return their cross-references.  Must be
    375   // non-empty.
    376   repeated string ticket = 1;
    377 
    378   enum DefinitionKind {
    379     // No definitions will be populated in the CrossReferencesReply.
    380     NO_DEFINITIONS = 0;
    381 
    382     // All known definition anchors reached by the "/kythe/edge/defines" edge
    383     // kind (or its variants) will be populated in the CrossReferencesReply.
    384     ALL_DEFINITIONS = 1;
    385 
    386     // Only definition anchors reached by the "/kythe/edge/defines" edge kind
    387     // will be populated in the CrossReferencesReply.
    388     FULL_DEFINITIONS = 2;
    389 
    390     // Only definition anchors reached by the "/kythe/edge/defines/binding" edge
    391     // kind will be populated in the CrossReferencesReply.
    392     BINDING_DEFINITIONS = 3;
    393   }
    394 
    395   // Determines what kind of definition anchors, if any, should be returned in
    396   // the response.  See the documentation for each DefinitionKind for more
    397   // information.
    398   DefinitionKind definition_kind = 2;
    399 
    400   enum DeclarationKind {
    401     // No declarations will be populated in the CrossDeclarationsReply.
    402     NO_DECLARATIONS = 0;
    403     // When the source node is incomplete, all known declaration anchors reached
    404     // by the "/kythe/edge/defines" edge kind (or its variants) will be
    405     // populated in the CrossDeclarationsReply.
    406     ALL_DECLARATIONS = 1;
    407   }
    408 
    409   // Determines what kind of declaration anchors, if any, should be returned in
    410   // the response.  See the documentation for each DeclarationKind for more
    411   // information.
    412   DeclarationKind declaration_kind = 7;
    413 
    414   enum ReferenceKind {
    415     // No references will be populated in the CrossReferencesReply.
    416     NO_REFERENCES = 0;
    417     // Only callgraph-related references as described in
    418     // http://www.kythe.io/docs/schema/callgraph.html
    419     CALL_REFERENCES = 1;
    420     // All references except those that are related to the callgraph.
    421     NON_CALL_REFERENCES = 2;
    422     // All known reference anchors reached by the "/kythe/edge/ref" edge kind
    423     // (or its variants) will be populated in the CrossReferencesReply.
    424     ALL_REFERENCES = 3;
    425   }
    426 
    427   // Determines what kind of reference anchors, if any, should be returned in
    428   // the response.  See the documentation for each ReferenceKind for more
    429   // information.
    430   ReferenceKind reference_kind = 3;
    431 
    432   enum DocumentationKind {
    433     // No documentation will be populated in the CrossReferencesReply.
    434     NO_DOCUMENTATION = 0;
    435     // All known documentation reached by the "/kythe/edge/documentation" edge
    436     // kind (or its variants) will be populated in the CrossReferencesReply.
    437     ALL_DOCUMENTATION = 1;
    438   }
    439 
    440   // Determines what kind of documentation anchors, if any, should be returned
    441   // in the response.  See the documentation for each DocumentationKind for more
    442   // information.
    443   DocumentationKind documentation_kind = 4;
    444 
    445   enum CallerKind {
    446     // No callgraph information will be populated in the CrossReferencesReply.
    447     NO_CALLERS = 0;
    448     // Callgraph information will be populated in the CrossReferencesReply.
    449     DIRECT_CALLERS = 1;
    450     // Callgraph information will be populated in the CrossReferencesReply.
    451     // Calls to override-related functions will also be considered.
    452     OVERRIDE_CALLERS = 2;
    453   }
    454 
    455   // Determines what kind of callgraph information, if any, should be returned
    456   // in the response.  See the documentation for each CallerKind for more
    457   // information.
    458   CallerKind caller_kind = 12;
    459 
    460   // Collection of filter globs that determines which facts will be returned for
    461   // the related nodes of each requested node.  If filter is empty or unset, no
    462   // node facts or related nodes are returned.  See EdgesRequest for the format
    463   // of the filter globs.
    464   repeated string filter = 5;
    465 
    466   // Determines whether each Anchor in the response should have its text field
    467   // populated.
    468   bool anchor_text = 6;
    469 
    470   // Determines whether each NodeInfo matching the above filters will have its
    471   // definition location populated, if known.
    472   bool node_definitions = 8;
    473 
    474   // Enable the experimental generation of signatures in the
    475   // CrossReferencesReply.  Enabling this currently causes multiple lookups and
    476   // can significantly impact latency.  Once latency concerns have been
    477   // addressed, this field will be removed and signatures will be returned by
    478   // default.
    479   // TODO(T156): remove this flag; always enable feature
    480   bool experimental_signatures = 100;
    481 
    482   // TODO(schroederc): snippet kinds (none, indexer-default, or always line-based)
    483 
    484   // The cross-references matching a request are organized into logical pages.
    485   // The size of each page is a number of distinct cross-references
    486   // (definitions, references, documentation, and related nodes).
    487   //
    488   // If page_token is empty, cross-references will be returned starting at the
    489   // beginning of the sequence; otherwise the starting point named by the
    490   // page_token will be used.  Legal values of page_token are returned by the
    491   // server in the next_page_token field of the CrossReferencesReply.  A page
    492   // token should be treated as an opaque value by the client, and is valid only
    493   // relative to a particular CrossReferencesRequest.  If an invalid page token
    494   // is requested, the server will return an error.
    495   //
    496   // If page_size > 0, at most that number of cross-references will be returned
    497   // by the service for this request (see ReferenceSet and CrossReferencesReply
    498   // below).  If page_size = 0, the default, the server will assume a reasonable
    499   // default page size.  The server will return an error if page_size < 0.
    500   //
    501   // The server is allowed to return fewer cross-references than the requested
    502   // page_size, even if more are available, save that it must return at least 1
    503   // edge if any are available at all.
    504   int32 page_size = 10;
    505   string page_token = 11;
    506 }
    507 
    508 // TODO(schroederc): eliminate duplicate serving.ExpandedAnchor message defintion
    509 
    510 message Anchor {
    511   // Ticket of the anchor node
    512   string ticket = 1;
    513   // Edge kind describing the anchor's relationship with its referenced node
    514   string kind = 2;
    515 
    516   // Parent ticket of the anchor; this is the file containing the anchor
    517   string parent = 3;
    518 
    519   // Starting location of the anchor within its parent's text
    520   Location.Point start = 4;
    521   // Ending location of the anchor within its parent's text
    522   Location.Point end = 5;
    523   // The anchor's spanning text within the anchor parent's text
    524   string text = 6;
    525 
    526   // User-readable snippet of the anchor parent's text at the location of this
    527   // anchor
    528   string snippet = 7;
    529   // Starting location of the anchor's snippet within its parent's text
    530   Location.Point snippet_start = 8;
    531   // Ending location of the anchor's snippet within its parent's text
    532   Location.Point snippet_end = 9;
    533 }
    534 
    535 message Link {
    536   // Definition sites found for some ticket.
    537   repeated Anchor definition = 1;
    538 }
    539 
    540 message Printable {
    541   // Raw text that can be displayed to the user (but may also contain
    542   // markup that can be interpreted, like Doxygen comments). Links are
    543   // marked using []. \ is an escape character (where possible escape
    544   // sequences are \[, \], and \\).
    545   string raw_text = 1;
    546   // Destinations for links in raw_text. The ith Link corresponds to the link
    547   // starting at the ith [.
    548   repeated Link link = 2;
    549 }
    550 
    551 message CrossReferencesReply {
    552   message RelatedNode {
    553     // Ticket of the node
    554     string ticket = 1;
    555     // Edge kind describing the node's relation
    556     string relation_kind = 2;
    557     // Optional ordinal for edges of the same relation_kind.
    558     int32 ordinal = 3;
    559   }
    560 
    561   message RelatedAnchor {
    562     // The anchor covering the related object.
    563     Anchor anchor = 1;
    564     // A name for the related object.
    565     Printable display_name = 2;
    566     // Specific locations, usually within the related object, that caused
    567     // the relationship to exist. This field is relevant to caller sets.
    568     repeated Anchor site = 3;
    569   }
    570 
    571   message CrossReferenceSet {
    572     string ticket = 1;
    573 
    574     // A name for the given node.
    575     Printable display_name = 7;
    576 
    577     // The set of definitions for the given node.
    578     repeated RelatedAnchor definition = 2;
    579     // The set of declarations for the given node.
    580     repeated RelatedAnchor declaration = 5;
    581     // The set of simple references for the given node.
    582     repeated RelatedAnchor reference = 3;
    583     // The set of documentation for the given node.
    584     repeated RelatedAnchor documentation = 4;
    585     // The set of callers for the given node.
    586     repeated RelatedAnchor caller = 6;
    587 
    588     // The set of related nodes to the given node.
    589     repeated RelatedNode related_node = 10;
    590   }
    591 
    592   message Total {
    593     int64 definitions = 1;
    594     int64 declarations = 2;
    595     int64 references = 3;
    596     int64 documentation = 4;
    597     int64 callers = 5;
    598 
    599     map<string, int64> related_nodes_by_relation = 6;
    600   }
    601   // Total number of cross-references on all pages matching requested filters.
    602   Total total = 5;
    603 
    604   // Sets of cross-references for each requested node
    605   map<string, CrossReferenceSet> cross_references = 1;
    606 
    607   // The facts left from the requested filters of the related node facts
    608   map<string, NodeInfo> nodes = 2;
    609 
    610   // Map from the definition tickets referred to in each NodeInfo to their
    611   // Anchor.  This map will only be returned if the
    612   // CrossReferencesRequest.node_definitions switch is true.
    613   map<string, Anchor> definition_locations = 3;
    614 
    615   // If there are additional pages of cross-references after the ones returned
    616   // in this reply, next_page_token is the page token that may be passed to
    617   // fetch the next page in sequence after this one.  If there are no additional
    618   // cross-references, this field will be empty.
    619   string next_page_token = 10;
    620 }
    621 
    622 message CallersRequest {
    623   // Semantic tickets for callees (e.g., function nodes).
    624   repeated string semantic_object = 1;
    625   // Expand the semantic_object set by including nodes that participate in
    626   // an `overrides` relationship (in either direction) with nodes in the set.
    627   //
    628   // In the program:
    629   //   struct A { virtual void f(); };
    630   //   struct B : public A { void f() override; };
    631   //   struct C : public B { void f() override; };
    632   //   void g(B* b) { b->f(); }
    633   //
    634   // we would return the following results (for queries on the singleton
    635   // semantic_object set containing A::f, B::f, or C::f):
    636   //
    637   // include_overrides  A::f  B::f  C::f
    638   //             false    {}   {g}    {}
    639   //              true   {g}   {g}   {g}
    640   bool include_overrides = 2;
    641 }
    642 
    643 message CallersReply {
    644   // Details common to all objects that participate in the call graph.
    645   message CallableDetail {
    646     // The definition site of the object called or being blamed for a call.
    647     // This would be the "bar" in "void bar()" for calls blamed on bar above
    648     // and the "foo" in "void foo()" if it refers to foo as a callee.
    649     Anchor definition = 1;
    650     // The ticket of the callable object. This would refer to the function node
    651     // for "bar" or "foo". This object may be the target of a `completes` edge
    652     // (e.g., if the call was made to a definition rather than a declaration).
    653     string semantic_object = 2;
    654     // The unqualified identifier for this object ("bar" or "foo" above,
    655     // even if they were defined in some namespace or record). This field
    656     // should be human-readable and can be displayed in a UI.
    657     string identifier = 4;
    658     // An unambiguous (as possible) identifier for this object ("bar()" or
    659     // "foo()" above; if it was defined in a namespace, "ns::bar()";
    660     // if it took arguments, "ns::bar(int *, void *)"). This field should
    661     // be human-readable and can be displayed in a UI.
    662     string display_name = 5;
    663     // A parameter bound by the object referred to by `definition` above.
    664     message Parameter {
    665       enum Kind {
    666         // A term-level binding (like the `x` in `void foo(int x)`).
    667         TERM = 0;
    668         // A type-level binding (like the `T` in
    669         // `template <typename T> void foo()`).
    670         TYPE = 1;
    671       }
    672       // The parameter's kind.
    673       Kind kind = 1;
    674       // The parameter's (unqualified) human-readable and displayable name.
    675       // May be empty. May also be non-unique; for example, the identifiers for
    676       // the (unnamed in the source language) parameters for the function
    677       // `void ignore_pair(int, int)` may be "int" and "int".
    678       string identifier = 2;
    679       // The ticket that refers to the parameter.
    680       string ticket = 3;
    681     }
    682     // The parameters bound by the object referred to by `definition` above.
    683     // There is no semantic meaning to the order of this array, but it should
    684     // be reasonable to surface the ordering in a UI (for example, term-level
    685     // parameters will not be capriciously reordered).
    686     repeated Parameter parameter = 6;
    687   }
    688   // An object that was blamed for making a call to an object in the set passed
    689   // to Callers, along with the syntactic locations that caused that blame to
    690   // be cast.
    691   message Caller {
    692     // The object (e.g., a function) responsible for making a call.
    693     CallableDetail detail = 1;
    694     message CallSite {
    695       // The location where a call was found inside the blamed object.
    696       Anchor anchor = 1;
    697       // This field will be set to true iff this call site was included in the
    698       // results because include_overrides was true in CallersRequest.
    699       bool call_to_override = 2;
    700     }
    701     repeated CallSite call_site = 2;
    702   }
    703   // All objects that were blamed for making calls.
    704   repeated Caller caller = 1;
    705   // Details for the semantic objects that were passed via a CallersRequest.
    706   repeated CallableDetail callee = 2;
    707 }
    708 
    709 message DocumentationRequest {
    710   // Semantic tickets about which documentation is sought.
    711   repeated string ticket = 1;
    712 }
    713 
    714 message DocumentationReply {
    715   message Document {
    716     // The ticket to which this Document refers.
    717     string ticket = 1;
    718     // Documentation that can be displayed to the user.
    719     Printable text = 2;
    720     // A signature that can be displayed to the user. For variables, this
    721     // may just be the variable name; for functions, this may be some version
    722     // of the function prototype.
    723     Printable signature = 3;
    724     // The type as a signature that can be displayed to the user.
    725     Printable type = 4;
    726     // The initialization value, if any.
    727     Printable initializer = 5;
    728     // The semantic parent of this value.
    729     Printable defined_by = 6;
    730     // The node kind being defined.
    731     string kind = 7;
    732   }
    733   repeated Document document = 1;
    734 }
    735