本文整理汇总了Golang中kythe/io/kythe/go/util/kytheuri.Parse函数的典型用法代码示例。如果您正苦于以下问题:Golang Parse函数的具体用法?Golang Parse怎么用?Golang Parse使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了Parse函数的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的Golang代码示例。
示例1: displayDirectory
func displayDirectory(d *ftpb.DirectoryReply) error {
if *displayJSON {
return jsonMarshaler.Marshal(out, d)
}
for _, d := range d.Subdirectory {
if !lsURIs {
uri, err := kytheuri.Parse(d)
if err != nil {
return fmt.Errorf("received invalid directory uri %q: %v", d, err)
}
d = filepath.Base(uri.Path) + "/"
}
if _, err := fmt.Fprintln(out, d); err != nil {
return err
}
}
for _, f := range d.File {
if !lsURIs {
uri, err := kytheuri.Parse(f)
if err != nil {
return fmt.Errorf("received invalid file ticket %q: %v", f, err)
}
f = filepath.Base(uri.Path)
}
if _, err := fmt.Fprintln(out, f); err != nil {
return err
}
}
return nil
}
示例2: init
func init() {
testVNames = make([]*spb.VName, len(testNodes))
for i, n := range testNodes {
uri, _ := kytheuri.Parse(n.Ticket)
testVNames[i] = uri.VName()
}
}
示例3: displayRelatedAnchors
func displayRelatedAnchors(kind string, anchors []*xpb.CrossReferencesReply_RelatedAnchor) error {
if len(anchors) > 0 {
if _, err := fmt.Fprintf(out, " %s:\n", kind); err != nil {
return err
}
for _, a := range anchors {
pURI, err := kytheuri.Parse(a.Anchor.Parent)
if err != nil {
return err
}
if _, err := fmt.Fprintf(out, " %s\t%s\t[%d:%d-%d:%d)\n %q\n",
pURI.Path, showPrintable(a.DisplayName),
a.Anchor.Start.LineNumber, a.Anchor.Start.ColumnOffset, a.Anchor.End.LineNumber, a.Anchor.End.ColumnOffset,
string(a.Anchor.Snippet)); err != nil {
return err
}
for _, site := range a.Site {
if _, err := fmt.Fprintf(out, " [%d:%d-%d-%d)\n %q\n",
site.Start.LineNumber, site.Start.ColumnOffset, site.End.LineNumber, site.End.ColumnOffset,
string(site.Snippet)); err != nil {
return err
}
}
}
}
return nil
}
示例4: createFileTree
func (d *DB) createFileTree() error {
if _, err := d.Exec(createFilesTable); err != nil {
return fmt.Errorf("error creating files table: %v", err)
}
rs, err := d.Query("SELECT ticket FROM Nodes WHERE node_kind = 'file';")
if err != nil {
return fmt.Errorf("error creating files query: %v", err)
}
insert, err := d.Prepare(`INSERT INTO Files (corpus, root, path, ticket, file) VALUES ($1, $2, $3, $4, $5);`)
if err != nil {
return fmt.Errorf("error preparing statement: %v", err)
}
for rs.Next() {
var ticket string
if err := rs.Scan(&ticket); err != nil {
return fmt.Errorf("scan error: %v", err)
}
uri, err := kytheuri.Parse(ticket)
if err != nil {
return fmt.Errorf("error parsing node ticket %q: %v", ticket, err)
}
path, _ := filepath.Split(filepath.Join("/", uri.Path))
if _, err := insert.Exec(uri.Corpus, uri.Root, path, ticket, true); err != nil {
return fmt.Errorf("error inserting file: %v", err)
}
uri.Signature, uri.Language = "", ""
for {
uri.Path = path
path, _ = filepath.Split(strings.TrimSuffix(path, "/"))
if path == "" {
break
}
if _, err := insert.Exec(uri.Corpus, uri.Root, path, uri.String(), false); err != nil {
if err, ok := err.(*pq.Error); ok && err.Code == pqUniqueViolationErrorCode {
// Since we've found the current directory, we can stop recursively
// adding parent directories now
break
}
return fmt.Errorf("error inserting directory: %v", err)
}
}
}
return nil
}
示例5: IndexNode
// IndexNode writes each of n's VName components and facts to t as search index
// entries. MaxIndexedFactValueSize limits fact values written to the index.
func IndexNode(ctx context.Context, t table.Inverted, n *srvpb.Node) error {
uri, err := kytheuri.Parse(n.Ticket)
if err != nil {
return err
}
key := []byte(n.Ticket)
if uri.Signature != "" {
if err := t.Put(ctx, key, vNameVal("signature", uri.Signature)); err != nil {
return err
}
}
if uri.Corpus != "" {
if err := t.Put(ctx, key, vNameVal("corpus", uri.Corpus)); err != nil {
return err
}
}
if uri.Root != "" {
if err := t.Put(ctx, key, vNameVal("root", uri.Root)); err != nil {
return err
}
}
if uri.Path != "" {
if err := t.Put(ctx, key, vNameVal("path", uri.Path)); err != nil {
return err
}
}
if uri.Language != "" {
if err := t.Put(ctx, key, vNameVal("language", uri.Language)); err != nil {
return err
}
}
for _, f := range n.Fact {
if len(f.Value) <= MaxIndexedFactValueSize {
if err := t.Put(ctx, key, factVal(f.Name, f.Value)); err != nil {
return err
}
}
}
return nil
}
示例6: displayAnchors
func displayAnchors(kind string, anchors []*xpb.Anchor) error {
if len(anchors) > 0 {
if _, err := fmt.Fprintf(out, " %s:\n", kind); err != nil {
return err
}
for _, a := range anchors {
pURI, err := kytheuri.Parse(a.Parent)
if err != nil {
return err
}
if _, err := fmt.Fprintf(out, " %s\t[%d:%d-%d:%d)\n %q\n",
pURI.Path,
a.Start.LineNumber, a.Start.ColumnOffset, a.End.LineNumber, a.End.ColumnOffset,
string(a.Snippet)); err != nil {
return err
}
}
}
return nil
}
示例7: Nodes
// Nodes implements part of the xrefs.Service interface.
func (db *DB) Nodes(req *xpb.NodesRequest) (*xpb.NodesReply, error) {
reply := &xpb.NodesReply{}
patterns := xrefs.ConvertFilters(req.Filter)
for _, t := range req.Ticket {
uri, err := kytheuri.Parse(t)
if err != nil {
return nil, fmt.Errorf("invalid ticket %q: %v", t, err)
}
rows, err := db.nodeFactsStmt.Query(uri.Signature, uri.Corpus, uri.Root, uri.Language, uri.Path)
if err != nil {
return nil, fmt.Errorf("sql select error for node %q: %v", t, err)
}
var facts []*xpb.Fact
for rows.Next() {
var fact xpb.Fact
err = rows.Scan(&fact.Name, &fact.Value)
if err != nil {
rows.Close()
return nil, fmt.Errorf("sql scan error for node %q: %v", t, err)
}
if len(patterns) == 0 || xrefs.MatchesAny(fact.Name, patterns) {
facts = append(facts, &fact)
}
}
if err := rows.Close(); err != nil {
return nil, fmt.Errorf("error closing rows for node %q: %v", t, err)
}
if len(facts) != 0 {
reply.Node = append(reply.Node, &xpb.NodeInfo{
Ticket: t,
Fact: facts,
})
}
}
return reply, nil
}
示例8: completeDefinition
func completeDefinition(definesAnchor string) (*definition, error) {
parentReply, err := xs.Edges(ctx, &xpb.EdgesRequest{
Ticket: []string{definesAnchor},
Kind: []string{schema.ChildOfEdge},
Filter: []string{schema.NodeKindFact, schema.AnchorLocFilter},
})
if err != nil {
return nil, err
}
parentNodes := xrefs.NodesMap(parentReply.Node)
var files []string
for _, parent := range xrefs.EdgesMap(parentReply.EdgeSet)[definesAnchor][schema.ChildOfEdge] {
if string(parentNodes[parent][schema.NodeKindFact]) == schema.FileKind {
files = append(files, parent)
}
}
if len(files) == 0 {
return nil, nil
} else if len(files) > 1 {
return nil, fmt.Errorf("anchor has multiple file parents %q: %v", definesAnchor, files)
}
vName, err := kytheuri.Parse(files[0])
if err != nil {
return nil, err
}
start, end := parseAnchorSpan(parentNodes[definesAnchor])
return &definition{
File: vName.VName(),
Start: start,
End: end,
}, nil
}
示例9: main
func main() {
flag.Parse()
if *offset < 0 {
flagutil.UsageError("non-negative --offset required")
} else if *signature == "" && *path == "" {
flagutil.UsageError("must provide at least --path or --signature")
}
if strings.HasPrefix(*remoteAPI, "http://") || strings.HasPrefix(*remoteAPI, "https://") {
xs = xrefs.WebClient(*remoteAPI)
idx = search.WebClient(*remoteAPI)
} else {
conn, err := grpc.Dial(*remoteAPI)
if err != nil {
log.Fatalf("Error connecting to remote API %q: %v", *remoteAPI, err)
}
defer conn.Close()
xs = xrefs.GRPC(xpb.NewXRefServiceClient(conn))
idx = search.GRPC(spb.NewSearchServiceClient(conn))
}
relPath := *path
if !*ignoreLocalRepo {
if _, err := os.Stat(relPath); err == nil {
absPath, err := filepath.Abs(relPath)
if err != nil {
log.Fatal(err)
}
kytheRoot := findKytheRoot(filepath.Dir(absPath))
if kytheRoot != "" {
relPath, err = filepath.Rel(filepath.Join(kytheRoot, *root), absPath)
if err != nil {
log.Fatal(err)
}
}
}
}
partialFile := &spb.VName{
Signature: *signature,
Corpus: *corpus,
Root: *root,
Path: relPath,
Language: *language,
}
reply, err := idx.Search(ctx, &spb.SearchRequest{
Partial: partialFile,
Fact: fileFacts,
})
if err != nil {
log.Fatalf("Error locating file {%v}: %v", partialFile, err)
}
if len(reply.Ticket) == 0 {
log.Fatalf("Could not locate file {%v}", partialFile)
} else if len(reply.Ticket) > 1 {
log.Fatalf("Ambiguous file {%v}; multiple results: %v", partialFile, reply.Ticket)
}
fileTicket := reply.Ticket[0]
decor, err := xs.Decorations(ctx, &xpb.DecorationsRequest{
// TODO(schroederc): limit Location to a SPAN around *offset
Location: &xpb.Location{Ticket: fileTicket},
References: true,
SourceText: true,
DirtyBuffer: readDirtyBuffer(ctx),
})
if err != nil {
log.Fatal(err)
}
nodes := xrefs.NodesMap(decor.Node)
en := json.NewEncoder(os.Stdout)
for _, ref := range decor.Reference {
start, end := parseAnchorSpan(nodes[ref.SourceTicket])
if start <= *offset && *offset < end {
var r reference
r.Span.Start = start
r.Span.End = end
r.Span.Text = string(decor.SourceText[start:end])
r.Kind = strings.TrimPrefix(ref.Kind, schema.EdgePrefix)
r.Node.Ticket = ref.TargetTicket
node := nodes[ref.TargetTicket]
r.Node.Kind = string(node[schema.NodeKindFact])
r.Node.Subkind = string(node[schema.SubkindFact])
if eReply, err := xs.Edges(ctx, &xpb.EdgesRequest{
Ticket: []string{ref.TargetTicket},
Kind: []string{schema.NamedEdge, definedAtEdge},
}); err != nil {
log.Printf("WARNING: error getting edges for %q: %v", ref.TargetTicket, err)
} else {
edges := xrefs.EdgesMap(eReply.EdgeSet)[ref.TargetTicket]
for _, name := range edges[schema.NamedEdge] {
if uri, err := kytheuri.Parse(name); err != nil {
log.Printf("WARNING: named node ticket (%q) could not be parsed: %v", name, err)
} else {
r.Node.Names = append(r.Node.Names, uri.Signature)
}
}
//.........这里部分代码省略.........
示例10: main
func main() {
flag.Parse()
if flag.NArg() > 0 {
flagutil.UsageErrorf("unknown non-flag argument(s): %v", flag.Args())
} else if *offset < 0 && (*lineNumber < 0 || *columnOffset < 0) {
flagutil.UsageError("non-negative --offset (or --line and --column) required")
} else if *signature == "" && *path == "" {
flagutil.UsageError("must provide at least --path or --signature")
}
defer (*apiFlag).Close()
xs, idx = *apiFlag, *apiFlag
relPath := *path
if *localRepoRoot != "NONE" {
if _, err := os.Stat(relPath); err == nil {
absPath, err := filepath.Abs(relPath)
if err != nil {
log.Fatal(err)
}
if *dirtyBuffer == "" {
*dirtyBuffer = absPath
}
kytheRoot := *localRepoRoot
if kytheRoot == "" {
kytheRoot = findKytheRoot(filepath.Dir(absPath))
}
if kytheRoot != "" {
relPath, err = filepath.Rel(filepath.Join(kytheRoot, *root), absPath)
if err != nil {
log.Fatal(err)
}
}
}
}
partialFile := &spb.VName{
Signature: *signature,
Corpus: *corpus,
Root: *root,
Path: relPath,
Language: *language,
}
reply, err := idx.Search(ctx, &spb.SearchRequest{
Partial: partialFile,
Fact: fileFacts,
})
if err != nil {
log.Fatalf("Error locating file {%v}: %v", partialFile, err)
}
if len(reply.Ticket) == 0 {
log.Fatalf("Could not locate file {%v}", partialFile)
} else if len(reply.Ticket) > 1 {
log.Fatalf("Ambiguous file {%v}; multiple results: %v", partialFile, reply.Ticket)
}
fileTicket := reply.Ticket[0]
text := readDirtyBuffer(ctx)
decor, err := xs.Decorations(ctx, &xpb.DecorationsRequest{
// TODO(schroederc): limit Location to a SPAN around *offset
Location: &xpb.Location{Ticket: fileTicket},
References: true,
SourceText: true,
DirtyBuffer: text,
Filter: []string{
schema.NodeKindFact,
schema.SubkindFact,
schema.AnchorLocFilter, // TODO(schroederc): remove once backwards-compatibility fix below is removed
},
})
if err != nil {
log.Fatal(err)
}
if text == nil {
text = decor.SourceText
}
nodes := xrefs.NodesMap(decor.Node)
// Normalize point within source text
point := normalizedPoint(text)
en := json.NewEncoder(os.Stdout)
for _, ref := range decor.Reference {
var start, end int
if ref.AnchorStart == nil || ref.AnchorEnd == nil {
// TODO(schroederc): remove this backwards-compatibility fix
start, end = parseAnchorSpan(nodes[ref.SourceTicket])
} else {
start, end = int(ref.AnchorStart.ByteOffset), int(ref.AnchorEnd.ByteOffset)
}
if start <= point && point < end {
var r reference
r.Span.Start = start
r.Span.End = end
r.Span.Text = string(text[start:end])
r.Kind = strings.TrimPrefix(ref.Kind, schema.EdgePrefix)
r.Node.Ticket = ref.TargetTicket
node := nodes[ref.TargetTicket]
//.........这里部分代码省略.........
示例11: main
func main() {
flag.Parse()
if flag.NArg() > 0 {
flagutil.UsageErrorf("unknown non-flag argument(s): %v", flag.Args())
} else if *offset < 0 && (*lineNumber < 0 || *columnOffset < 0) {
flagutil.UsageError("non-negative --offset (or --line and --column) required")
} else if *path == "" {
flagutil.UsageError("must provide --path")
}
defer (*apiFlag).Close()
xs = *apiFlag
relPath := *path
if *localRepoRoot != "NONE" {
if _, err := os.Stat(relPath); err == nil {
absPath, err := filepath.Abs(relPath)
if err != nil {
log.Fatal(err)
}
if *dirtyBuffer == "" {
*dirtyBuffer = absPath
}
kytheRoot := *localRepoRoot
if kytheRoot == "" {
kytheRoot = findKytheRoot(filepath.Dir(absPath))
}
if kytheRoot != "" {
relPath, err = filepath.Rel(filepath.Join(kytheRoot, *root), absPath)
if err != nil {
log.Fatal(err)
}
}
}
}
fileTicket := (&kytheuri.URI{Corpus: *corpus, Root: *root, Path: relPath}).String()
point := &xpb.Location_Point{
ByteOffset: int32(*offset),
LineNumber: int32(*lineNumber),
ColumnOffset: int32(*columnOffset),
}
dirtyBuffer := readDirtyBuffer(ctx)
decor, err := xs.Decorations(ctx, &xpb.DecorationsRequest{
Location: &xpb.Location{
Ticket: fileTicket,
Kind: xpb.Location_SPAN,
Start: point,
End: point,
},
SpanKind: xpb.DecorationsRequest_AROUND_SPAN,
References: true,
SourceText: true,
DirtyBuffer: dirtyBuffer,
Filter: []string{
facts.NodeKind,
facts.Subkind,
},
})
if err != nil {
log.Fatal(err)
}
nodes := xrefs.NodesMap(decor.Nodes)
en := json.NewEncoder(os.Stdout)
for _, ref := range decor.Reference {
start, end := int(ref.AnchorStart.ByteOffset), int(ref.AnchorEnd.ByteOffset)
var r reference
r.Span.Start = start
r.Span.End = end
if len(dirtyBuffer) > 0 {
r.Span.Text = string(dirtyBuffer[start:end])
} // TODO(schroederc): add option to get anchor text from DecorationsReply
r.Kind = strings.TrimPrefix(ref.Kind, edges.Prefix)
r.Node.Ticket = ref.TargetTicket
node := nodes[ref.TargetTicket]
r.Node.Kind = string(node[facts.NodeKind])
r.Node.Subkind = string(node[facts.Subkind])
// TODO(schroederc): use CrossReferences method
if eReply, err := xrefs.AllEdges(ctx, xs, &gpb.EdgesRequest{
Ticket: []string{ref.TargetTicket},
Kind: []string{edges.Named, edges.Typed, definedAtEdge, definedBindingAtEdge},
}); err != nil {
log.Printf("WARNING: error getting edges for %q: %v", ref.TargetTicket, err)
} else {
matching := xrefs.EdgesMap(eReply.EdgeSets)[ref.TargetTicket]
for name := range matching[edges.Named] {
if uri, err := kytheuri.Parse(name); err != nil {
log.Printf("WARNING: named node ticket (%q) could not be parsed: %v", name, err)
} else {
r.Node.Names = append(r.Node.Names, uri.Signature)
}
}
for typed := range matching[edges.Typed] {
r.Node.Typed = typed
//.........这里部分代码省略.........
示例12:
return errors.New("--files and --dirs are mutually exclusive")
}
if len(flag.Args()) == 0 {
req := &ftpb.CorpusRootsRequest{}
logRequest(req)
cr, err := ft.CorpusRoots(ctx, req)
if err != nil {
return err
}
return displayCorpusRoots(cr)
}
var corpus, root, path string
switch len(flag.Args()) {
case 1:
uri, err := kytheuri.Parse(flag.Arg(0))
if err != nil {
log.Fatalf("invalid uri %q: %v", flag.Arg(0), err)
}
corpus = uri.Corpus
root = uri.Root
path = uri.Path
default:
flag.Usage()
os.Exit(1)
}
path = filepath.Join("/", path)
req := &ftpb.DirectoryRequest{
Corpus: corpus,
Root: root,
Path: path,
示例13: Edges
// Edges implements part of the xrefs.Service interface.
func (db *DB) Edges(req *xpb.EdgesRequest) (*xpb.EdgesReply, error) {
if req.PageSize != 0 || req.PageToken != "" {
return nil, errors.New("edge pages unimplemented for SQL DB")
}
reply := &xpb.EdgesReply{}
allowedKinds := stringset.New(req.Kind...)
nodeTickets := stringset.New()
for _, t := range req.Ticket {
uri, err := kytheuri.Parse(t)
if err != nil {
return nil, err
}
edges := make(map[string]stringset.Set)
var (
target kytheuri.URI
kind string
)
rows, err := db.edgesStmt.Query(uri.Signature, uri.Corpus, uri.Root, uri.Path, uri.Language)
if err != nil {
rows.Close()
return nil, fmt.Errorf("forward edges query error: %v", err)
}
for rows.Next() {
if err := rows.Scan(&target.Signature, &target.Corpus, &target.Root, &target.Path, &target.Language, &kind); err != nil {
rows.Close()
return nil, fmt.Errorf("forward edges scan error: %v", err)
} else if len(allowedKinds) != 0 && !allowedKinds.Contains(kind) {
continue
}
targets, ok := edges[kind]
if !ok {
targets = stringset.New()
edges[kind] = targets
}
ticket := target.String()
targets.Add(ticket)
nodeTickets.Add(ticket)
}
if err := rows.Close(); err != nil {
return nil, err
}
rows, err = db.revEdgesStmt.Query(uri.Signature, uri.Corpus, uri.Root, uri.Path, uri.Language)
if err != nil {
rows.Close()
return nil, fmt.Errorf("reverse edges query error: %v", err)
}
for rows.Next() {
if err := rows.Scan(&target.Signature, &target.Corpus, &target.Root, &target.Path, &target.Language, &kind); err != nil {
rows.Close()
return nil, fmt.Errorf("reverse edges scan error: %v", err)
}
kind = schema.MirrorEdge(kind)
if len(allowedKinds) != 0 && !allowedKinds.Contains(kind) {
continue
}
targets, ok := edges[kind]
if !ok {
targets = stringset.New()
edges[kind] = targets
}
ticket := target.String()
targets.Add(ticket)
nodeTickets.Add(ticket)
}
if err := rows.Close(); err != nil {
return nil, err
}
var g []*xpb.EdgeSet_Group
for kind, targets := range edges {
g = append(g, &xpb.EdgeSet_Group{
Kind: kind,
TargetTicket: targets.Slice(),
})
}
if len(g) != 0 {
reply.EdgeSet = append(reply.EdgeSet, &xpb.EdgeSet{
SourceTicket: t,
Group: g,
})
}
}
nodesReply, err := db.Nodes(&xpb.NodesRequest{
Ticket: nodeTickets.Slice(),
Filter: req.Filter,
})
if err != nil {
//.........这里部分代码省略.........
示例14: Decorations
// Decorations implements part of the xrefs.Service interface.
func (db *DB) Decorations(req *xpb.DecorationsRequest) (*xpb.DecorationsReply, error) {
if req.GetLocation() == nil {
return nil, errors.New("missing location")
} else if req.Location.Kind != xpb.Location_FILE {
return nil, fmt.Errorf("%s location kind unimplemented", req.Location.Kind)
} else if len(req.DirtyBuffer) != 0 {
return nil, errors.New("dirty buffers unimplemented")
}
fileTicket := req.Location.Ticket
edgesReply, err := db.Edges(&xpb.EdgesRequest{
Ticket: []string{fileTicket},
Kind: []string{revChildOfEdge},
Filter: []string{schema.NodeKindFact, schema.TextFact, schema.TextEncodingFact},
})
if err != nil {
return nil, err
}
reply := &xpb.DecorationsReply{
Location: &xpb.Location{
Ticket: fileTicket,
},
}
nodes := xrefs.NodesMap(edgesReply.Node)
if req.SourceText {
if nodes[fileTicket] == nil {
nodesReply, err := db.Nodes(&xpb.NodesRequest{Ticket: []string{fileTicket}})
if err != nil {
return nil, err
}
nodes = xrefs.NodesMap(nodesReply.Node)
}
reply.SourceText = nodes[fileTicket][schema.TextFact]
reply.Encoding = string(nodes[fileTicket][schema.TextEncodingFact])
}
nodeTickets := stringset.New()
if req.References {
// Traverse the following chain of edges:
// file --%/kythe/edge/childof-> []anchor --forwardEdgeKind-> []target
edges := xrefs.EdgesMap(edgesReply.EdgeSet)
for _, anchor := range edges[fileTicket][revChildOfEdge] {
if string(nodes[anchor][schema.NodeKindFact]) != schema.AnchorKind {
continue
}
uri, err := kytheuri.Parse(anchor)
if err != nil {
return nil, fmt.Errorf("invalid anchor ticket found %q: %v", anchor, err)
}
rows, err := db.anchorEdgesStmt.Query(schema.ChildOfEdge, uri.Signature, uri.Corpus, uri.Root, uri.Path, uri.Language)
if err != nil {
return nil, fmt.Errorf("anchor %q edge query error: %v", anchor, err)
}
for rows.Next() {
var target kytheuri.URI
var kind string
if err := rows.Scan(&target.Signature, &target.Corpus, &target.Root, &target.Path, &target.Language, &kind); err != nil {
return nil, fmt.Errorf("anchor %q edge scan error: %v", anchor, err)
}
ticket := target.String()
reply.Reference = append(reply.Reference, &xpb.DecorationsReply_Reference{
SourceTicket: anchor,
Kind: kind,
TargetTicket: ticket,
})
nodeTickets.Add(anchor, ticket)
}
}
}
nodesReply, err := db.Nodes(&xpb.NodesRequest{Ticket: nodeTickets.Slice()})
if err != nil {
return nil, err
}
reply.Node = nodesReply.Node
return reply, nil
}