kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/test/tools/xrefs_atomizer/xrefs_atomizer.go (about)

     1  /*
     2   * Copyright 2017 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  // Binary xrefs_atomizer shatters the file decorations and cross-references
    18  // responses from a xrefs.Service into GraphStore entries.
    19  
    20  // Each non-flag argument is a file ticket that will be used in a
    21  // DecorationsRequest to the --api service.  Each file decoration target will
    22  // then be used in a CrossReferencesRequest.  Both the DecorationsReply and
    23  // CrossReferencesReply messages will be shattered into GraphStore entries as a
    24  // delimited stream on standard-output.
    25  //
    26  // See kythe.io/kythe/go/test/xrefs package for details.
    27  //
    28  // Example:
    29  //
    30  //	xrefs_atomizer --api http://localhost:8080 kythe://kythe?path=kythe/go/util/kytheuri/uri.go
    31  package main
    32  
    33  import (
    34  	"context"
    35  	"flag"
    36  	"os"
    37  
    38  	"kythe.io/kythe/go/platform/delimited"
    39  	"kythe.io/kythe/go/services/xrefs"
    40  	"kythe.io/kythe/go/serving/api"
    41  	txrefs "kythe.io/kythe/go/test/services/xrefs"
    42  	"kythe.io/kythe/go/util/log"
    43  	"kythe.io/kythe/go/util/schema/facts"
    44  	spb "kythe.io/kythe/proto/storage_go_proto"
    45  	xpb "kythe.io/kythe/proto/xref_go_proto"
    46  )
    47  
    48  func main() {
    49  	ctx := context.Background()
    50  	xs := api.Flag("api", api.CommonDefault, api.CommonFlagUsage)
    51  	flag.Parse()
    52  	defer (*xs).Close(ctx)
    53  
    54  	wr := delimited.NewWriter(os.Stdout)
    55  	var count int
    56  	atomizer := txrefs.Atomizer(func(_ context.Context, e *spb.Entry) error {
    57  		count++
    58  		return wr.PutProto(e)
    59  	})
    60  
    61  	for _, ticket := range flag.Args() {
    62  		log.Infof("Atomizing: %q", ticket)
    63  		if err := atomizeFileDecorations(ctx, *xs, ticket, atomizer); err != nil {
    64  			log.Fatalf("Error atomizing file %q: %v", ticket, err)
    65  		}
    66  	}
    67  	log.Infof("Emitted %d entries for %d files", count, flag.NArg())
    68  }
    69  
    70  var defaultFilters = []string{facts.NodeKind, facts.Subkind}
    71  
    72  func atomizeFileDecorations(ctx context.Context, xs xrefs.Service, ticket string, a txrefs.Atomizer) error {
    73  	reply, err := xs.Decorations(ctx, &xpb.DecorationsRequest{
    74  		Location:   &xpb.Location{Ticket: ticket},
    75  		SourceText: true,
    76  		References: true,
    77  		Filter:     defaultFilters,
    78  	})
    79  	if err != nil {
    80  		return err
    81  	}
    82  	if err := a.Decorations(ctx, reply); err != nil {
    83  		return err
    84  	}
    85  	for _, ref := range reply.Reference {
    86  		if err := atomizeCrossReferences(ctx, xs, ref.TargetTicket, a); err != nil {
    87  			return err
    88  		}
    89  	}
    90  	return nil
    91  }
    92  
    93  func atomizeCrossReferences(ctx context.Context, xs xrefs.Service, ticket string, a txrefs.Atomizer) error {
    94  	reply, err := xs.CrossReferences(ctx, &xpb.CrossReferencesRequest{
    95  		Ticket: []string{ticket},
    96  
    97  		DefinitionKind:  xpb.CrossReferencesRequest_BINDING_DEFINITIONS,
    98  		DeclarationKind: xpb.CrossReferencesRequest_ALL_DECLARATIONS,
    99  		ReferenceKind:   xpb.CrossReferencesRequest_ALL_REFERENCES,
   100  
   101  		Filter: defaultFilters,
   102  	})
   103  	if err != nil {
   104  		return err
   105  	}
   106  	return a.CrossReferences(ctx, reply)
   107  }