kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/serving/xrefs/columnar/columnar_encoding.go (about) 1 /* 2 * Copyright 2018 The Kythe Authors. 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 // Package columnar implements the columnar table format for a Kythe xrefs service. 18 package columnar // import "kythe.io/kythe/go/serving/xrefs/columnar" 19 20 import ( 21 "crypto/sha256" 22 "encoding/hex" 23 "fmt" 24 25 "kythe.io/kythe/go/util/keys" 26 "kythe.io/kythe/go/util/kytheuri" 27 28 "google.golang.org/protobuf/proto" 29 30 scpb "kythe.io/kythe/proto/schema_go_proto" 31 spb "kythe.io/kythe/proto/storage_go_proto" 32 xspb "kythe.io/kythe/proto/xref_serving_go_proto" 33 ) 34 35 var ( 36 // DecorationsKeyPrefix is the common key prefix for all Kythe columnar 37 // FileDecoration key-value entries. 38 DecorationsKeyPrefix, _ = keys.Append(nil, "fd") 39 40 // CrossReferencesKeyPrefix is the common key prefix for all Kythe columnar 41 // CrossReferences key-value entries. 42 CrossReferencesKeyPrefix, _ = keys.Append(nil, "xr") 43 ) 44 45 func init() { 46 // Restrict the capacity of the key prefixes to ensure appending to it creates a new array. 47 DecorationsKeyPrefix = DecorationsKeyPrefix[:len(DecorationsKeyPrefix):len(DecorationsKeyPrefix)] 48 CrossReferencesKeyPrefix = CrossReferencesKeyPrefix[:len(CrossReferencesKeyPrefix):len(CrossReferencesKeyPrefix)] 49 } 50 51 // Columnar file decorations group numbers. 52 // See: kythe/proto/xref_serving.proto 53 const ( 54 columnarDecorationsIndexGroup = -1 // no group number 55 columnarDecorationsTextGroup = 0 56 columnarDecorationsTargetGroup = 10 57 columnarDecorationsTargetOverrideGroup = 20 58 columnarDecorationsTargetNodeGroup = 30 59 columnarDecorationsTargetDefinitionGroup = 40 60 columnarDecorationsDefinitionLocationGroup = 50 61 columnarDecorationsOverrideGroup = 60 62 columnarDecorationsDiagnosticGroup = 70 63 ) 64 65 // KV is a single columnar key-value entry. 66 type KV struct{ Key, Value []byte } 67 68 // EncodeDecorationsEntry encodes a columnar FileDecorations entry. 69 func EncodeDecorationsEntry(keyPrefix []byte, fd *xspb.FileDecorations) (*KV, error) { 70 switch e := fd.Entry.(type) { 71 case *xspb.FileDecorations_Index_: 72 return encodeDecorIndex(keyPrefix, fd.File, e.Index) 73 case *xspb.FileDecorations_Text_: 74 return encodeDecorText(keyPrefix, fd.File, e.Text) 75 case *xspb.FileDecorations_Target_: 76 return encodeDecorTarget(keyPrefix, fd.File, e.Target) 77 case *xspb.FileDecorations_TargetOverride_: 78 return encodeDecorTargetOverride(keyPrefix, fd.File, e.TargetOverride) 79 case *xspb.FileDecorations_TargetNode_: 80 return encodeDecorTargetNode(keyPrefix, fd.File, e.TargetNode) 81 case *xspb.FileDecorations_TargetDefinition_: 82 return encodeDecorTargetDefinition(keyPrefix, fd.File, e.TargetDefinition) 83 case *xspb.FileDecorations_DefinitionLocation_: 84 return encodeDecorDefinitionLocation(keyPrefix, fd.File, e.DefinitionLocation) 85 case *xspb.FileDecorations_Override_: 86 return encodeDecorOverride(keyPrefix, fd.File, e.Override) 87 case *xspb.FileDecorations_Diagnostic_: 88 return encodeDecorDiagnostic(keyPrefix, fd.File, e.Diagnostic) 89 default: 90 return nil, fmt.Errorf("unknown FileDecorations entry: %T", e) 91 } 92 } 93 94 func encodeDecorIndex(prefix []byte, file *spb.VName, idx *xspb.FileDecorations_Index) (*KV, error) { 95 key, err := keys.Append(prefix, file) 96 if err != nil { 97 return nil, err 98 } 99 val, err := proto.Marshal(idx) 100 if err != nil { 101 return nil, err 102 } 103 return &KV{key, val}, nil 104 } 105 106 func encodeDecorText(prefix []byte, file *spb.VName, t *xspb.FileDecorations_Text) (*KV, error) { 107 key, err := keys.Append(prefix, file, columnarDecorationsTextGroup, t.StartOffset, t.EndOffset) 108 if err != nil { 109 return nil, err 110 } 111 // Encode the subset of the value proto not encoded in the key. 112 val, err := proto.Marshal(&xspb.FileDecorations_Text{Text: t.Text}) 113 if err != nil { 114 return nil, err 115 } 116 return &KV{key, val}, nil 117 } 118 119 func encodeDecorTarget(prefix []byte, file *spb.VName, t *xspb.FileDecorations_Target) (*KV, error) { 120 key, err := keys.Append(prefix, file, 121 columnarDecorationsTargetGroup, t.BuildConfig, t.StartOffset, t.EndOffset, 122 t.GetGenericKind(), int32(t.GetKytheKind()), t.Target) 123 if err != nil { 124 return nil, err 125 } 126 val, err := proto.Marshal(&xspb.FileDecorations_Target{}) 127 if err != nil { 128 return nil, err 129 } 130 return &KV{key, val}, nil 131 } 132 133 func encodeDecorTargetOverride(prefix []byte, file *spb.VName, to *xspb.FileDecorations_TargetOverride) (*KV, error) { 134 key, err := keys.Append(prefix, file, 135 columnarDecorationsTargetOverrideGroup, to.Overridden, int32(to.Kind), to.Overriding) 136 if err != nil { 137 return nil, err 138 } 139 val, err := proto.Marshal(to) 140 if err != nil { 141 return nil, err 142 } 143 return &KV{key, val}, nil 144 } 145 func encodeDecorTargetNode(prefix []byte, file *spb.VName, tn *xspb.FileDecorations_TargetNode) (*KV, error) { 146 key, err := keys.Append(prefix, file, columnarDecorationsTargetNodeGroup, tn.Node.Source) 147 if err != nil { 148 return nil, err 149 } 150 val, err := proto.Marshal(tn) 151 if err != nil { 152 return nil, err 153 } 154 return &KV{key, val}, nil 155 } 156 func encodeDecorTargetDefinition(prefix []byte, file *spb.VName, td *xspb.FileDecorations_TargetDefinition) (*KV, error) { 157 key, err := keys.Append(prefix, file, columnarDecorationsTargetDefinitionGroup, td.Target) 158 if err != nil { 159 return nil, err 160 } 161 // Encode the subset of the value proto not encoded in the key. 162 val, err := proto.Marshal(&xspb.FileDecorations_TargetDefinition{Definition: td.Definition}) 163 if err != nil { 164 return nil, err 165 } 166 return &KV{key, val}, nil 167 } 168 func encodeDecorDefinitionLocation(prefix []byte, file *spb.VName, def *xspb.FileDecorations_DefinitionLocation) (*KV, error) { 169 // TODO(schroederc): use VNames throughout pipeline 170 defVName, err := kytheuri.ToVName(def.Location.Ticket) 171 if err != nil { 172 return nil, err 173 } 174 key, err := keys.Append(prefix, file, columnarDecorationsDefinitionLocationGroup, defVName) 175 if err != nil { 176 return nil, err 177 } 178 val, err := proto.Marshal(def) 179 if err != nil { 180 return nil, err 181 } 182 return &KV{key, val}, nil 183 } 184 func encodeDecorOverride(prefix []byte, file *spb.VName, o *xspb.FileDecorations_Override) (*KV, error) { 185 key, err := keys.Append(prefix, file, columnarDecorationsOverrideGroup, o.Override) 186 if err != nil { 187 return nil, err 188 } 189 // Encode the subset of the value proto not encoded in the key. 190 val, err := proto.Marshal(&xspb.FileDecorations_Override{MarkedSource: o.MarkedSource}) 191 if err != nil { 192 return nil, err 193 } 194 return &KV{key, val}, nil 195 } 196 func encodeDecorDiagnostic(prefix []byte, file *spb.VName, d *xspb.FileDecorations_Diagnostic) (*KV, error) { 197 val, err := proto.Marshal(d) 198 if err != nil { 199 return nil, err 200 } 201 h := sha256.Sum224(val) 202 key, err := keys.Append(prefix, file, columnarDecorationsDiagnosticGroup, d.Diagnostic.Span.GetStart().GetByteOffset(), d.Diagnostic.Span.GetEnd().GetByteOffset(), hex.EncodeToString(h[:])) 203 if err != nil { 204 return nil, err 205 } 206 return &KV{key, val}, nil 207 } 208 209 // DecodeDecorationsEntry decodes a columnar FileDecorations entry. 210 func DecodeDecorationsEntry(file *spb.VName, key string, val []byte) (*xspb.FileDecorations, error) { 211 kind := columnarDecorationsIndexGroup 212 if key != "" { 213 var err error 214 key, err = keys.Parse(key, &kind) 215 if err != nil { 216 return nil, fmt.Errorf("invalid FileDecorations group kind: %v", err) 217 } 218 } 219 switch kind { 220 case columnarDecorationsIndexGroup: 221 return decodeDecorIndex(file, key, val) 222 case columnarDecorationsTextGroup: 223 return decodeDecorText(file, key, val) 224 case columnarDecorationsTargetGroup: 225 return decodeDecorTarget(file, key, val) 226 case columnarDecorationsTargetOverrideGroup: 227 return decodeDecorTargetOverride(file, key, val) 228 case columnarDecorationsTargetNodeGroup: 229 return decodeDecorTargetNode(file, key, val) 230 case columnarDecorationsTargetDefinitionGroup: 231 return decodeDecorTargetDefinition(file, key, val) 232 case columnarDecorationsDefinitionLocationGroup: 233 return decodeDecorDefinitionLocation(file, key, val) 234 case columnarDecorationsOverrideGroup: 235 return decodeDecorOverride(file, key, val) 236 case columnarDecorationsDiagnosticGroup: 237 return decodeDecorDiagnostic(file, key, val) 238 default: 239 return nil, fmt.Errorf("unknown group kind: %d", kind) 240 } 241 } 242 243 func decodeDecorIndex(file *spb.VName, key string, val []byte) (*xspb.FileDecorations, error) { 244 var idx xspb.FileDecorations_Index 245 if err := proto.Unmarshal(val, &idx); err != nil { 246 return nil, err 247 } 248 return &xspb.FileDecorations{ 249 File: file, 250 Entry: &xspb.FileDecorations_Index_{&idx}, 251 }, nil 252 } 253 254 func decodeDecorText(file *spb.VName, key string, val []byte) (*xspb.FileDecorations, error) { 255 var text xspb.FileDecorations_Text 256 if err := proto.Unmarshal(val, &text); err != nil { 257 return nil, err 258 } 259 return &xspb.FileDecorations{ 260 File: file, 261 Entry: &xspb.FileDecorations_Text_{&text}, 262 }, nil 263 } 264 265 func decodeDecorTarget(file *spb.VName, key string, val []byte) (*xspb.FileDecorations, error) { 266 target := &xspb.FileDecorations_Target{Target: &spb.VName{}} 267 var ( 268 kytheKindNum int32 269 genericKind string 270 ) 271 key, err := keys.Parse(key, 272 &target.BuildConfig, &target.StartOffset, &target.EndOffset, 273 &genericKind, &kytheKindNum, target.Target) 274 if err != nil { 275 return nil, err 276 } 277 278 if genericKind != "" { 279 target.Kind = &xspb.FileDecorations_Target_GenericKind{genericKind} 280 } else { 281 target.Kind = &xspb.FileDecorations_Target_KytheKind{scpb.EdgeKind(kytheKindNum)} 282 } 283 return &xspb.FileDecorations{ 284 File: file, 285 Entry: &xspb.FileDecorations_Target_{target}, 286 }, nil 287 } 288 289 func decodeDecorTargetOverride(file *spb.VName, key string, val []byte) (*xspb.FileDecorations, error) { 290 var overridden, overriding spb.VName 291 var kind int32 292 key, err := keys.Parse(key, &overridden, &kind, &overriding) 293 if err != nil { 294 return nil, err 295 } else if key != "" { 296 return nil, fmt.Errorf("unexpected TargetOverride key suffix: %q", key) 297 } 298 var to xspb.FileDecorations_TargetOverride 299 if err = proto.Unmarshal(val, &to); err != nil { 300 return nil, err 301 } 302 return &xspb.FileDecorations{ 303 File: file, 304 Entry: &xspb.FileDecorations_TargetOverride_{&to}, 305 }, nil 306 } 307 308 func decodeDecorTargetNode(file *spb.VName, key string, val []byte) (*xspb.FileDecorations, error) { 309 var tn xspb.FileDecorations_TargetNode 310 if err := proto.Unmarshal(val, &tn); err != nil { 311 return nil, err 312 } 313 return &xspb.FileDecorations{ 314 File: file, 315 Entry: &xspb.FileDecorations_TargetNode_{&tn}, 316 }, nil 317 } 318 319 func decodeDecorTargetDefinition(file *spb.VName, key string, val []byte) (*xspb.FileDecorations, error) { 320 var target spb.VName 321 key, err := keys.Parse(key, &target) 322 if err != nil { 323 return nil, err 324 } else if key != "" { 325 return nil, fmt.Errorf("unexpected TargetDefinition key suffix: %q", key) 326 } 327 var def xspb.FileDecorations_TargetDefinition 328 if err := proto.Unmarshal(val, &def); err != nil { 329 return nil, err 330 } 331 def.Target = &target 332 return &xspb.FileDecorations{ 333 File: file, 334 Entry: &xspb.FileDecorations_TargetDefinition_{&def}, 335 }, nil 336 } 337 338 func decodeDecorDefinitionLocation(file *spb.VName, key string, val []byte) (*xspb.FileDecorations, error) { 339 var loc xspb.FileDecorations_DefinitionLocation 340 if err := proto.Unmarshal(val, &loc); err != nil { 341 return nil, err 342 } 343 return &xspb.FileDecorations{ 344 File: file, 345 Entry: &xspb.FileDecorations_DefinitionLocation_{&loc}, 346 }, nil 347 } 348 349 func decodeDecorOverride(file *spb.VName, key string, val []byte) (*xspb.FileDecorations, error) { 350 var target spb.VName 351 key, err := keys.Parse(key, &target) 352 if err != nil { 353 return nil, err 354 } else if key != "" { 355 return nil, fmt.Errorf("unexpected Override key suffix: %q", key) 356 } 357 var o xspb.FileDecorations_Override 358 if err := proto.Unmarshal(val, &o); err != nil { 359 return nil, err 360 } 361 o.Override = &target 362 return &xspb.FileDecorations{ 363 File: file, 364 Entry: &xspb.FileDecorations_Override_{&o}, 365 }, nil 366 } 367 368 func decodeDecorDiagnostic(file *spb.VName, key string, val []byte) (*xspb.FileDecorations, error) { 369 var o xspb.FileDecorations_Diagnostic 370 if err := proto.Unmarshal(val, &o); err != nil { 371 return nil, err 372 } 373 return &xspb.FileDecorations{ 374 File: file, 375 Entry: &xspb.FileDecorations_Diagnostic_{&o}, 376 }, nil 377 } 378 379 // Columnar file decorations group numbers. 380 // See: kythe/proto/xref_serving.proto 381 const ( 382 columnarXRefsIndexGroup = -1 // no group number 383 columnarXRefsReferenceGroup = 0 384 columnarXRefsRelationGroup = 10 385 columnarXRefsCallerGroup = 20 386 columnarXRefsRelatedNodeGroup = 30 387 columnarXRefsNodeDefinitionGroup = 40 388 ) 389 390 // EncodeCrossReferencesEntry encodes a columnar CrossReferences entry. 391 func EncodeCrossReferencesEntry(keyPrefix []byte, xr *xspb.CrossReferences) (*KV, error) { 392 switch e := xr.Entry.(type) { 393 case *xspb.CrossReferences_Index_: 394 return encodeXRefIndex(keyPrefix, xr.Source, e.Index) 395 case *xspb.CrossReferences_Reference_: 396 return encodeXRefReference(keyPrefix, xr.Source, e.Reference) 397 case *xspb.CrossReferences_Relation_: 398 return encodeXRefRelation(keyPrefix, xr.Source, e.Relation) 399 case *xspb.CrossReferences_Caller_: 400 return encodeXRefCaller(keyPrefix, xr.Source, e.Caller) 401 case *xspb.CrossReferences_Callsite_: 402 return encodeXRefCallsite(keyPrefix, xr.Source, e.Callsite) 403 case *xspb.CrossReferences_RelatedNode_: 404 return encodeXRefRelatedNode(keyPrefix, xr.Source, e.RelatedNode) 405 case *xspb.CrossReferences_NodeDefinition_: 406 return encodeXRefNodeDefinition(keyPrefix, xr.Source, e.NodeDefinition) 407 default: 408 return nil, fmt.Errorf("unknown CrossReferences entry: %T", e) 409 } 410 } 411 412 func encodeXRefIndex(prefix []byte, src *spb.VName, idx *xspb.CrossReferences_Index) (*KV, error) { 413 key, err := keys.Append(prefix, src) 414 if err != nil { 415 return nil, err 416 } 417 val, err := proto.Marshal(idx) 418 if err != nil { 419 return nil, err 420 } 421 return &KV{key, val}, nil 422 } 423 424 func encodeXRefReference(prefix []byte, src *spb.VName, r *xspb.CrossReferences_Reference) (*KV, error) { 425 uri, err := kytheuri.Parse(r.Location.Ticket) 426 if err != nil { 427 return nil, err 428 } 429 file := &spb.VName{ 430 Corpus: uri.Corpus, 431 Root: uri.Root, 432 Path: uri.Path, 433 } 434 key, err := keys.Append(prefix, src, columnarXRefsReferenceGroup, 435 r.GetGenericKind(), int32(r.GetKytheKind()), file, 436 r.Location.Span.GetStart().GetByteOffset(), r.Location.Span.GetEnd().GetByteOffset()) 437 if err != nil { 438 return nil, err 439 } 440 val, err := proto.Marshal(&xspb.CrossReferences_Reference{Location: r.Location}) 441 if err != nil { 442 return nil, err 443 } 444 return &KV{key, val}, nil 445 } 446 447 func encodeXRefRelation(prefix []byte, src *spb.VName, r *xspb.CrossReferences_Relation) (*KV, error) { 448 key, err := keys.Append(prefix, src, columnarXRefsRelationGroup, 449 r.GetGenericKind(), int32(r.GetKytheKind()), r.Ordinal, r.Reverse, r.Node) 450 if err != nil { 451 return nil, err 452 } 453 val, err := proto.Marshal(&xspb.CrossReferences_Relation{}) 454 if err != nil { 455 return nil, err 456 } 457 return &KV{key, val}, nil 458 } 459 460 func encodeXRefCaller(prefix []byte, src *spb.VName, c *xspb.CrossReferences_Caller) (*KV, error) { 461 key, err := keys.Append(prefix, src, columnarXRefsCallerGroup, c.Caller) 462 if err != nil { 463 return nil, err 464 } 465 val, err := proto.Marshal(&xspb.CrossReferences_Caller{ 466 Location: c.Location, 467 MarkedSource: c.MarkedSource, 468 }) 469 if err != nil { 470 return nil, err 471 } 472 return &KV{key, val}, nil 473 } 474 475 func encodeXRefCallsite(prefix []byte, src *spb.VName, c *xspb.CrossReferences_Callsite) (*KV, error) { 476 uri, err := kytheuri.Parse(c.Location.Ticket) 477 if err != nil { 478 return nil, err 479 } 480 file := &spb.VName{ 481 Corpus: uri.Corpus, 482 Root: uri.Root, 483 Path: uri.Path, 484 } 485 key, err := keys.Append(prefix, src, columnarXRefsCallerGroup, 486 c.Caller, int32(c.Kind), file, 487 c.Location.Span.GetStart().GetByteOffset(), c.Location.Span.GetEnd().GetByteOffset()) 488 if err != nil { 489 return nil, err 490 } 491 val, err := proto.Marshal(&xspb.CrossReferences_Callsite{ 492 Location: c.Location, 493 }) 494 if err != nil { 495 return nil, err 496 } 497 return &KV{key, val}, nil 498 } 499 500 func encodeXRefRelatedNode(prefix []byte, src *spb.VName, n *xspb.CrossReferences_RelatedNode) (*KV, error) { 501 key, err := keys.Append(prefix, src, columnarXRefsRelatedNodeGroup, n.Node.Source) 502 if err != nil { 503 return nil, err 504 } 505 val, err := proto.Marshal(n) 506 if err != nil { 507 return nil, err 508 } 509 return &KV{key, val}, nil 510 } 511 512 func encodeXRefNodeDefinition(prefix []byte, src *spb.VName, def *xspb.CrossReferences_NodeDefinition) (*KV, error) { 513 key, err := keys.Append(prefix, src, columnarXRefsNodeDefinitionGroup, def.Node) 514 if err != nil { 515 return nil, err 516 } 517 val, err := proto.Marshal(&xspb.CrossReferences_NodeDefinition{Location: def.Location}) 518 if err != nil { 519 return nil, err 520 } 521 return &KV{key, val}, nil 522 } 523 524 // DecodeCrossReferencesEntry decodes a columnar CrossReferences entry. 525 func DecodeCrossReferencesEntry(src *spb.VName, key string, val []byte) (*xspb.CrossReferences, error) { 526 kind := columnarXRefsIndexGroup 527 if key != "" { 528 var err error 529 key, err = keys.Parse(key, &kind) 530 if err != nil { 531 return nil, fmt.Errorf("invalid CrossReferences group kind: %v", err) 532 } 533 } 534 switch kind { 535 case columnarXRefsIndexGroup: 536 return decodeXRefIndex(src, key, val) 537 case columnarXRefsReferenceGroup: 538 return decodeXRefReference(src, key, val) 539 case columnarXRefsRelationGroup: 540 return decodeXRefRelation(src, key, val) 541 case columnarXRefsCallerGroup: 542 return decodeXRefCallerOrCallsite(src, key, val) 543 case columnarXRefsRelatedNodeGroup: 544 return decodeXRefRelatedNode(src, key, val) 545 case columnarXRefsNodeDefinitionGroup: 546 return decodeXRefNodeDefinition(src, key, val) 547 default: 548 return nil, fmt.Errorf("unknown group kind: %d", kind) 549 } 550 } 551 552 func decodeXRefIndex(src *spb.VName, key string, val []byte) (*xspb.CrossReferences, error) { 553 var idx xspb.CrossReferences_Index 554 if err := proto.Unmarshal(val, &idx); err != nil { 555 return nil, err 556 } 557 return &xspb.CrossReferences{ 558 Source: src, 559 Entry: &xspb.CrossReferences_Index_{&idx}, 560 }, nil 561 } 562 563 func decodeXRefReference(src *spb.VName, key string, val []byte) (*xspb.CrossReferences, error) { 564 var ( 565 genericKind string 566 kytheKind int32 567 ) 568 key, err := keys.Parse(key, &genericKind, &kytheKind) 569 if err != nil { 570 return nil, err 571 } 572 var ref xspb.CrossReferences_Reference 573 if err := proto.Unmarshal(val, &ref); err != nil { 574 return nil, err 575 } 576 if genericKind != "" { 577 ref.Kind = &xspb.CrossReferences_Reference_GenericKind{genericKind} 578 } else { 579 ref.Kind = &xspb.CrossReferences_Reference_KytheKind{scpb.EdgeKind(kytheKind)} 580 } 581 return &xspb.CrossReferences{ 582 Source: src, 583 Entry: &xspb.CrossReferences_Reference_{&ref}, 584 }, nil 585 } 586 587 func decodeXRefRelation(src *spb.VName, key string, val []byte) (*xspb.CrossReferences, error) { 588 var ( 589 genericKind string 590 kytheKind int32 591 ordinal int32 592 reverse bool 593 node spb.VName 594 ) 595 key, err := keys.Parse(key, &genericKind, &kytheKind, &ordinal, &reverse, &node) 596 if err != nil { 597 return nil, err 598 } 599 var r xspb.CrossReferences_Relation 600 if err := proto.Unmarshal(val, &r); err != nil { 601 return nil, err 602 } 603 r.Reverse = reverse 604 r.Ordinal = ordinal 605 r.Node = &node 606 if genericKind != "" { 607 r.Kind = &xspb.CrossReferences_Relation_GenericKind{genericKind} 608 } else { 609 r.Kind = &xspb.CrossReferences_Relation_KytheKind{scpb.EdgeKind(kytheKind)} 610 } 611 return &xspb.CrossReferences{ 612 Source: src, 613 Entry: &xspb.CrossReferences_Relation_{&r}, 614 }, nil 615 } 616 617 func decodeXRefCallerOrCallsite(src *spb.VName, key string, val []byte) (*xspb.CrossReferences, error) { 618 var caller spb.VName 619 key, err := keys.Parse(key, &caller) 620 if err != nil { 621 return nil, err 622 } 623 624 if key == "" { 625 var c xspb.CrossReferences_Caller 626 if err := proto.Unmarshal(val, &c); err != nil { 627 return nil, err 628 } 629 c.Caller = &caller 630 return &xspb.CrossReferences{ 631 Source: src, 632 Entry: &xspb.CrossReferences_Caller_{&c}, 633 }, nil 634 } 635 636 var kind int32 637 key, err = keys.Parse(key, &kind) 638 if err != nil { 639 return nil, err 640 } 641 642 var c xspb.CrossReferences_Callsite 643 if err := proto.Unmarshal(val, &c); err != nil { 644 return nil, err 645 } 646 c.Caller = &caller 647 c.Kind = xspb.CrossReferences_Callsite_Kind(kind) 648 return &xspb.CrossReferences{ 649 Source: src, 650 Entry: &xspb.CrossReferences_Callsite_{&c}, 651 }, nil 652 } 653 654 func decodeXRefRelatedNode(src *spb.VName, key string, val []byte) (*xspb.CrossReferences, error) { 655 var rn xspb.CrossReferences_RelatedNode 656 if err := proto.Unmarshal(val, &rn); err != nil { 657 return nil, err 658 } 659 return &xspb.CrossReferences{ 660 Source: src, 661 Entry: &xspb.CrossReferences_RelatedNode_{&rn}, 662 }, nil 663 } 664 665 func decodeXRefNodeDefinition(src *spb.VName, key string, val []byte) (*xspb.CrossReferences, error) { 666 var node spb.VName 667 key, err := keys.Parse(key, &node) 668 if err != nil { 669 return nil, err 670 } 671 if len(key) != 0 { 672 return nil, fmt.Errorf("unexpected trailing key: %q", key) 673 } 674 var def xspb.CrossReferences_NodeDefinition 675 if err := proto.Unmarshal(val, &def); err != nil { 676 return nil, err 677 } 678 def.Node = &node 679 return &xspb.CrossReferences{ 680 Source: src, 681 Entry: &xspb.CrossReferences_NodeDefinition_{&def}, 682 }, nil 683 }