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
17syntax = "proto3";
18
19package 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.
47service 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
87message 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
99message 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
111message 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
118message 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.
180message 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
206message 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//
237message 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
291message 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
332message 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
373message 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
510message 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
535message Link {
536  // Definition sites found for some ticket.
537  repeated Anchor definition = 1;
538}
539
540message 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
551message 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
622message 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
643message 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
709message DocumentationRequest {
710  // Semantic tickets about which documentation is sought.
711  repeated string ticket = 1;
712}
713
714message 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