kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/serving/pipeline/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 pipeline 18 19 import ( 20 "fmt" 21 "reflect" 22 23 gcolumnar "kythe.io/kythe/go/serving/graph/columnar" 24 "kythe.io/kythe/go/serving/xrefs/columnar" 25 "kythe.io/kythe/go/util/kytheuri" 26 27 "github.com/apache/beam/sdks/go/pkg/beam" 28 29 cpb "kythe.io/kythe/proto/common_go_proto" 30 gspb "kythe.io/kythe/proto/graph_serving_go_proto" 31 ppb "kythe.io/kythe/proto/pipeline_go_proto" 32 scpb "kythe.io/kythe/proto/schema_go_proto" 33 srvpb "kythe.io/kythe/proto/serving_go_proto" 34 spb "kythe.io/kythe/proto/storage_go_proto" 35 xspb "kythe.io/kythe/proto/xref_serving_go_proto" 36 ) 37 38 func init() { 39 beam.RegisterFunction(encodeCrossRef) 40 beam.RegisterFunction(encodeDecorPiece) 41 beam.RegisterFunction(encodeEdgeTarget) 42 beam.RegisterFunction(encodeEdges) 43 beam.RegisterFunction(encodeEdgesEntry) 44 beam.RegisterFunction(nodeToCrossRef) 45 beam.RegisterFunction(refToCrossRef) 46 beam.RegisterType(reflect.TypeOf((*gspb.Edges)(nil)).Elem()) 47 beam.RegisterType(reflect.TypeOf((*xspb.CrossReferences)(nil)).Elem()) 48 beam.RegisterType(reflect.TypeOf((*xspb.FileDecorations)(nil)).Elem()) 49 } 50 51 func encodeCrossRef(xr *xspb.CrossReferences, emit func([]byte, []byte)) error { 52 kv, err := columnar.EncodeCrossReferencesEntry(columnar.CrossReferencesKeyPrefix, xr) 53 if err != nil { 54 return err 55 } 56 emit(kv.Key, kv.Value) 57 return nil 58 } 59 60 func refToCrossRef(r *ppb.Reference) *xspb.CrossReferences { 61 ref := &xspb.CrossReferences_Reference{Location: r.Anchor} 62 if k := r.GetGenericKind(); k != "" { 63 ref.Kind = &xspb.CrossReferences_Reference_GenericKind{k} 64 } else { 65 ref.Kind = &xspb.CrossReferences_Reference_KytheKind{r.GetKytheKind()} 66 } 67 return &xspb.CrossReferences{ 68 Source: r.Source, 69 Entry: &xspb.CrossReferences_Reference_{ref}, 70 } 71 } 72 73 func nodeToCrossRef(key *spb.VName, nodeStream func(**scpb.Node) bool, msStream func(**cpb.MarkedSource) bool) *xspb.CrossReferences { 74 var n *scpb.Node 75 var ms *cpb.MarkedSource 76 nodeStream(&n) 77 msStream(&ms) 78 return &xspb.CrossReferences{ 79 Source: key, 80 Entry: &xspb.CrossReferences_Index_{&xspb.CrossReferences_Index{ 81 Node: n, 82 MarkedSource: ms, 83 }}, 84 } 85 } 86 87 func encodeDecorPiece(file *spb.VName, p *ppb.DecorationPiece, emit func([]byte, []byte)) error { 88 switch p := p.Piece.(type) { 89 case *ppb.DecorationPiece_File: 90 return encodeDecorFile(file, p.File, emit) 91 case *ppb.DecorationPiece_Reference: 92 return encodeDecorRef(file, p.Reference, emit) 93 case *ppb.DecorationPiece_Node: 94 return encodeDecorNode(file, p.Node, emit) 95 case *ppb.DecorationPiece_Definition_: 96 return encodeDecorDef(file, p.Definition, emit) 97 case *ppb.DecorationPiece_Diagnostic: 98 return encodeDecorDiagnostic(file, p.Diagnostic, emit) 99 case *ppb.DecorationPiece_TargetOverride: 100 return encodeDecorTargetOverride(file, p.TargetOverride, emit) 101 default: 102 return fmt.Errorf("unknown DecorationPiece: %T", p) 103 } 104 } 105 106 func encodeDecorTargetOverride(file *spb.VName, o *xspb.FileDecorations_TargetOverride, emit func([]byte, []byte)) error { 107 e, err := columnar.EncodeDecorationsEntry(columnar.DecorationsKeyPrefix, &xspb.FileDecorations{ 108 File: file, 109 Entry: &xspb.FileDecorations_TargetOverride_{ 110 TargetOverride: o, 111 }, 112 }) 113 if err != nil { 114 return err 115 } 116 emit(e.Key, e.Value) 117 return nil 118 } 119 120 func encodeDecorFile(file *spb.VName, f *srvpb.File, emit func([]byte, []byte)) error { 121 // Emit FileDecorations Index 122 e, err := columnar.EncodeDecorationsEntry(columnar.DecorationsKeyPrefix, &xspb.FileDecorations{ 123 File: file, 124 Entry: &xspb.FileDecorations_Index_{&xspb.FileDecorations_Index{ 125 TextEncoding: f.Encoding, 126 }}, 127 }) 128 if err != nil { 129 return err 130 } 131 emit(e.Key, e.Value) 132 133 // Encode file contents as single entry 134 // TODO(schroederc): chunk large file contents 135 e, err = columnar.EncodeDecorationsEntry(columnar.DecorationsKeyPrefix, &xspb.FileDecorations{ 136 File: file, 137 Entry: &xspb.FileDecorations_Text_{&xspb.FileDecorations_Text{ 138 StartOffset: 0, 139 EndOffset: int32(len(f.Text)), 140 Text: f.Text, 141 }}, 142 }) 143 if err != nil { 144 return err 145 } 146 emit(e.Key, e.Value) 147 return nil 148 } 149 150 func encodeDecorRef(file *spb.VName, ref *ppb.Reference, emit func([]byte, []byte)) error { 151 target := &xspb.FileDecorations_Target{ 152 StartOffset: ref.Anchor.Span.Start.ByteOffset, 153 EndOffset: ref.Anchor.Span.End.ByteOffset, 154 BuildConfig: ref.Anchor.BuildConfiguration, 155 Target: ref.Source, 156 } 157 if k := ref.GetGenericKind(); k != "" { 158 target.Kind = &xspb.FileDecorations_Target_GenericKind{k} 159 } else { 160 target.Kind = &xspb.FileDecorations_Target_KytheKind{ref.GetKytheKind()} 161 } 162 e, err := columnar.EncodeDecorationsEntry(columnar.DecorationsKeyPrefix, &xspb.FileDecorations{ 163 File: file, 164 Entry: &xspb.FileDecorations_Target_{target}, 165 }) 166 if err != nil { 167 return err 168 } 169 emit(e.Key, e.Value) 170 return nil 171 } 172 173 func encodeDecorNode(file *spb.VName, node *scpb.Node, emit func([]byte, []byte)) error { 174 e, err := columnar.EncodeDecorationsEntry(columnar.DecorationsKeyPrefix, &xspb.FileDecorations{ 175 File: file, 176 Entry: &xspb.FileDecorations_TargetNode_{&xspb.FileDecorations_TargetNode{ 177 Node: node, 178 }}, 179 }) 180 if err != nil { 181 return err 182 } 183 emit(e.Key, e.Value) 184 return nil 185 } 186 187 func encodeDecorDef(file *spb.VName, def *ppb.DecorationPiece_Definition, emit func([]byte, []byte)) error { 188 // TODO(schroederc): use VNames throughout pipeline 189 defVName, err := kytheuri.ToVName(def.Definition.Ticket) 190 if err != nil { 191 return err 192 } 193 e, err := columnar.EncodeDecorationsEntry(columnar.DecorationsKeyPrefix, &xspb.FileDecorations{ 194 File: file, 195 Entry: &xspb.FileDecorations_TargetDefinition_{&xspb.FileDecorations_TargetDefinition{ 196 Target: def.Node, 197 Definition: defVName, 198 }}, 199 }) 200 if err != nil { 201 return err 202 } 203 emit(e.Key, e.Value) 204 205 e, err = columnar.EncodeDecorationsEntry(columnar.DecorationsKeyPrefix, &xspb.FileDecorations{ 206 File: file, 207 Entry: &xspb.FileDecorations_DefinitionLocation_{&xspb.FileDecorations_DefinitionLocation{ 208 Location: def.Definition, 209 }}, 210 }) 211 if err != nil { 212 return err 213 } 214 emit(e.Key, e.Value) 215 return nil 216 } 217 218 func encodeDecorDiagnostic(file *spb.VName, d *cpb.Diagnostic, emit func([]byte, []byte)) error { 219 e, err := columnar.EncodeDecorationsEntry(columnar.DecorationsKeyPrefix, &xspb.FileDecorations{ 220 File: file, 221 Entry: &xspb.FileDecorations_Diagnostic_{&xspb.FileDecorations_Diagnostic{ 222 Diagnostic: d, 223 }}, 224 }) 225 if err != nil { 226 return err 227 } 228 emit(e.Key, e.Value) 229 return nil 230 } 231 232 func encodeEdgesEntry(e *gspb.Edges, emit func([]byte, []byte)) error { 233 kv, err := gcolumnar.EncodeEdgesEntry(gcolumnar.EdgesKeyPrefix, e) 234 if err != nil { 235 return err 236 } 237 emit(kv.Key, kv.Value) 238 return nil 239 } 240 241 func encodeEdgeTarget(src *spb.VName, nodeStream func(**scpb.Node) bool, targetStream func(**spb.VName) bool, emit func(*gspb.Edges)) { 242 var node *scpb.Node 243 if !nodeStream(&node) { 244 node = &scpb.Node{} 245 } else { 246 node = nodeWithoutEdges(node) 247 } 248 node.Source = src 249 250 var target *spb.VName 251 for targetStream(&target) { 252 emit(&gspb.Edges{ 253 Source: target, 254 Entry: &gspb.Edges_Target_{&gspb.Edges_Target{ 255 Node: node, 256 }}, 257 }) 258 } 259 } 260 261 func encodeEdges(n *scpb.Node, emit func(*gspb.Edges)) error { 262 for _, e := range n.Edge { 263 edge := &gspb.Edges_Edge{ 264 Target: e.Target, 265 Ordinal: e.Ordinal, 266 } 267 if k := e.GetGenericKind(); k != "" { 268 edge.Kind = &gspb.Edges_Edge_GenericKind{k} 269 } else { 270 edge.Kind = &gspb.Edges_Edge_KytheKind{e.GetKytheKind()} 271 } 272 emit(&gspb.Edges{ 273 Source: n.Source, 274 Entry: &gspb.Edges_Edge_{edge}, 275 }) 276 emit(&gspb.Edges{ 277 Source: e.Target, 278 Entry: &gspb.Edges_Edge_{&gspb.Edges_Edge{ 279 Target: n.Source, 280 Kind: edge.Kind, 281 Ordinal: e.Ordinal, 282 Reverse: true, 283 }}, 284 }) 285 } 286 return nil 287 }