kythe.io@v0.0.68-0.20240422202219-7225dbc01741/kythe/go/languageserver/bin/main.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 kythe_languageserver provides a Language Server Protocol v3 18 // implementation for Kythe indexes that communicates via JSONRPC2.0 over stdio 19 package main 20 21 import ( 22 "context" 23 "flag" 24 "fmt" 25 "log" 26 "net" 27 "os" 28 "path/filepath" 29 "time" 30 31 "kythe.io/kythe/go/languageserver" 32 "kythe.io/kythe/go/services/xrefs" 33 34 "github.com/sourcegraph/jsonrpc2" 35 ) 36 37 var ( 38 pageSize = flag.Int("page_size", 0, "Set the default xrefs page size") 39 40 serverAddr = flag.String("server", "localhost:8080", 41 "The address of the Kythe service to use (:8080 allows access from other machines)") 42 ) 43 44 func main() { 45 flag.Parse() 46 if *serverAddr == "" { 47 log.Fatal("You must provide a --server address") 48 } 49 50 // Set up the log file 51 const openMode = os.O_CREATE | os.O_APPEND | os.O_WRONLY 52 logfile := fmt.Sprintf("kythe-ls-%s.log", time.Now().Format("20160102-150405")) 53 file, err := os.OpenFile(filepath.Join(os.TempDir(), logfile), openMode, os.ModePerm) 54 if err != nil { 55 log.Fatalf("Unable to create log file: %v", err) 56 } 57 log.SetOutput(file) 58 59 // Check to see that xref service is reachable. We won't hold open a 60 // connection to the server here, as the client manages the connection. 61 conn, err := net.DialTimeout("tcp", *serverAddr, 5*time.Second) 62 if err != nil { 63 log.Fatalf("Dialing Kythe service: %v", err) 64 } 65 conn.Close() 66 67 client := xrefs.WebClient("http://" + *serverAddr) 68 server := languageserver.NewServer(client, &languageserver.Options{ 69 PageSize: *pageSize, 70 }) 71 72 <-jsonrpc2.NewConn( 73 context.Background(), 74 jsonrpc2.NewBufferedStream(stdio{}, jsonrpc2.VSCodeObjectCodec{}), 75 languageserver.ServerHandler(&server), 76 ).DisconnectNotify() 77 } 78 79 type stdio struct{} 80 81 func (stdio) Read(data []byte) (int, error) { return os.Stdin.Read(data) } 82 func (stdio) Write(data []byte) (int, error) { return os.Stdout.Write(data) } 83 func (stdio) Close() error { return os.Stdout.Close() }