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

     1  /*
     2   * Copyright 2023 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 markedsource provides a utility for printing the resolved MarkedSource
    18  // for any ticket from a delimited stream of wire-encoded kythe.proto.Entry
    19  // messages.
    20  //
    21  // Example usages:
    22  //
    23  //	markedsource kythe://kythe#myTicket < entries
    24  //	markedsource --rewrite < entries > rewritten.entries
    25  package main
    26  
    27  import (
    28  	"bufio"
    29  	"flag"
    30  	"os"
    31  
    32  	"kythe.io/kythe/go/platform/delimited"
    33  	"kythe.io/kythe/go/storage/stream"
    34  	"kythe.io/kythe/go/util/log"
    35  	"kythe.io/kythe/go/util/markedsource"
    36  	"kythe.io/kythe/go/util/schema/facts"
    37  
    38  	"google.golang.org/protobuf/encoding/protojson"
    39  	"google.golang.org/protobuf/proto"
    40  
    41  	spb "kythe.io/kythe/proto/storage_go_proto"
    42  )
    43  
    44  var (
    45  	rewrite = flag.Bool("rewrite", false, "Rewrite all code facts to be fully resolved")
    46  
    47  	renderSignature         = flag.Bool("render_signatures", true, "Whether to emit /kythe/code/rendered/signature facts (requires --rewrite)")
    48  	renderCallsiteSignature = flag.Bool("render_callsite_signatures", true, "Whether to emit /kythe/code/rendered/callsite_signature facts (requires --rewrite)")
    49  	renderQualifiedName     = flag.Bool("render_qualified_names", true, "Whether to emit /kythe/code/rendered/qualified_name facts (requires --rewrite)")
    50  	renderSimpleName        = flag.Bool("render_simple_names", true, "Whether to emit /kythe/code/rendered/simple_name facts (requires --rewrite)")
    51  )
    52  
    53  const renderFactPrefix = facts.Code + "/rendered/"
    54  
    55  func main() {
    56  	flag.Parse()
    57  
    58  	in := bufio.NewReaderSize(os.Stdin, 2*4096)
    59  	rd := stream.NewReader(in)
    60  
    61  	var entries []*spb.Entry
    62  	if err := rd(func(e *spb.Entry) error {
    63  		entries = append(entries, e)
    64  		return nil
    65  	}); err != nil {
    66  		log.Exitf("Failed to read entrystream: %v", err)
    67  	}
    68  
    69  	r, err := markedsource.NewResolver(entries)
    70  	exitOnErrf("Failed to construct MarkedSource Resolver: %v", err)
    71  
    72  	if *rewrite {
    73  		var rewritten int
    74  		out := bufio.NewWriter(os.Stdout)
    75  		wr := delimited.NewWriter(out)
    76  		for _, e := range entries {
    77  			if e.GetFactName() == facts.Code || e.GetFactName() == facts.Code+"/json" {
    78  				resolved := r.Resolve(e.GetSource())
    79  				e = proto.Clone(e).(*spb.Entry)
    80  				e.FactName = facts.Code
    81  				rec, err := proto.Marshal(resolved)
    82  				exitOnErrf("Error marshalling resolved MarkedSource: %v", err)
    83  				e.FactValue = rec
    84  				rewritten++
    85  
    86  				if *renderSimpleName {
    87  					val := markedsource.RenderSimpleIdentifier(resolved, markedsource.PlaintextContent, nil)
    88  					exitOnErr(wr.PutProto(&spb.Entry{
    89  						Source:    e.Source,
    90  						FactName:  renderFactPrefix + "simple_name",
    91  						FactValue: []byte(val),
    92  					}))
    93  				}
    94  				if *renderQualifiedName {
    95  					val := markedsource.RenderSimpleQualifiedName(resolved, true, markedsource.PlaintextContent, nil)
    96  					exitOnErr(wr.PutProto(&spb.Entry{
    97  						Source:    e.Source,
    98  						FactName:  renderFactPrefix + "qualified_name",
    99  						FactValue: []byte(val),
   100  					}))
   101  				}
   102  				if *renderCallsiteSignature {
   103  					val := markedsource.RenderCallSiteSignature(resolved)
   104  					exitOnErr(wr.PutProto(&spb.Entry{
   105  						Source:    e.Source,
   106  						FactName:  renderFactPrefix + "callsite_signature",
   107  						FactValue: []byte(val),
   108  					}))
   109  				}
   110  				if *renderSignature {
   111  					val := markedsource.RenderSignature(resolved, markedsource.PlaintextContent, nil)
   112  					exitOnErr(wr.PutProto(&spb.Entry{
   113  						Source:    e.Source,
   114  						FactName:  renderFactPrefix + "signature",
   115  						FactValue: []byte(val),
   116  					}))
   117  				}
   118  			}
   119  			exitOnErr(wr.PutProto(e))
   120  		}
   121  		exitOnErr(out.Flush())
   122  		log.Infof("Rewrote %d code facts", rewritten)
   123  		return
   124  	}
   125  
   126  	wr := bufio.NewWriter(os.Stdout)
   127  	for _, ticket := range flag.Args() {
   128  		rec, err := protojson.Marshal(r.ResolveTicket(ticket))
   129  		exitOnErrf("Error encoding MarkedSource: %v", err)
   130  		if _, err := wr.Write(rec); err != nil {
   131  			log.Exitf("Error writing MarkedSource: %v", err)
   132  		}
   133  	}
   134  	exitOnErrf("Error flushing stdout: %v", wr.Flush())
   135  }
   136  
   137  func exitOnErrf(msg string, err error) {
   138  	if err != nil {
   139  		log.Exitf(msg, err)
   140  	}
   141  }
   142  
   143  func exitOnErr(err error) {
   144  	if err != nil {
   145  		log.Exit(err)
   146  	}
   147  }