Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
gopls拡張によるマイクロサービス間の 実装ジャンプの改善
Search
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
Shotaro Yamasaki
September 28, 2025
400
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
gopls拡張によるマイクロサービス間の 実装ジャンプの改善
GoConference2025
Shotaro Yamasaki
September 28, 2025
More Decks by Shotaro Yamasaki
See All by Shotaro Yamasaki
noCopyとその展望
yadon3141
0
710
Featured
See All Featured
Design in an AI World
tapps
1
270
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.5k
Rails Girls Zürich Keynote
gr2m
96
14k
Typedesign – Prime Four
hannesfritz
42
3.1k
BBQ
matthewcrist
89
10k
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
670
Building an army of robots
kneath
306
46k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.6k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
350
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
450
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
2
4.2k
Transcript
gopls拡張による マイクロサービス間の 実装ジャンプの改善 株式会社サイバーエージェント 山﨑正大朗 Github @seipan Go Conference 2025
1.WINTICKET での課題 2.LSPについて 3.goplsについて 4.gopls拡張 5.拡張goplsの運用 6.感想
山﨑 正大朗/yadon 株式会社サイバーエージェント 株式会社WINTICKET 2025新卒入社 初登壇で緊張しています @seipan
はじめに
みなさんこんなことありませんか
ん〜 定義ジャンプで 実装にジャンプしたい のにinterfaceに飛ぶ
今回はそれを解決する話です
WINTICKETでの課題
WINTICKETについて 01
None
WINTICKETでの開発体制 WINTICKETは複数のマイクロサービスで構成されている Rsource Cloud Spanner Cloud BigQuery Cloud Storage Gateway-XXX
Pods Web Cloud Run Microservices Pods Logging Profiler Management Tools Cloud Pub/Sub User iOS Android Web Firebase Fastly CDN Cloud DNS Cloud Load Balancing d Live Elemental MediaPackage Elemental MediaLive CloudFront CloudWatch Event Secret Manager API Gateway Lambda ChateauAmeba Cloud Armor
・各マイクロサービス間の通信は gRPCで行われている。 ・全てのマイクロサービスのソースコードは単一の Github リポジ トリ で管理されている (モノレポ)。 ・各マイクロサービスは依存しあっている。 ・機能開発では複数のマイクロサービスを跨いだ開発をすることが あ る。
WINTICKETでの開発体制
・各マイクロサービス間の通信は gRPCで行われている。 ・全てのマイクロサービスのソースコードは単一の Github リポジ トリ で管理されている (モノレポ)。 ・各マイクロサービスは依存しあっている。 ・機能開発では複数のマイクロサービスを跨いだ開発をすることが あ る。
WINTICKETでの開発体制
WINTICKETでの開発 マイクロサービス A マイクロサービス B gRPC
WINTICKETでの開発 マイクロサービス A マイクロサービス B gRPC これらに変更を加えたい場合
WINTICKETでの開発 マイクロサービス A マイクロサービス B gRPC
WINTICKETでの開発 マイクロサービス A マイクロサービス B gRPC 定義ジャンプ!
WINTICKETでの開発 マイクロサービス A マイクロサービス B gRPC 定義ジャンプ!
WINTICKETでの開発 マイクロサービス A マイクロサービス B gRPC proto 生成 定義ジャンプ! **.pb.go
GoLandとか VSCodeでも Go to Implementations とかなら、、、、
GoLandとか VSCodeでも Go to Implementations とかなら、、、、
実装を探したい 関数名コピーして 実装のディレクトリに移動して grepして 実装探して、、、、
実装を探したい 関数名コピーして 実装のディレクトリに移動して grepして 実装探して、、、、
gopls VSCode拡張 解決したい
LSPとは
LanguageServerとは コード補完、定義ジャンプ、リファレンス検索、リントなどの機能 をIDEに提供するもの。 ・Rust: rust-analyzer ・Scala: metals ・Typescript: typescript-language-server など
goplsとは オープンソースの Go言語のLanguage Server
LSPとは LSP(Language Server Protocol)とは JSON-RPCベースのプロトコ ルで、IDEとLanguageServer間の通信の標準仕様 https://code.visualstudio.com/api/language-ext ensions/language-server-extension-guide
例 ・textDocument/definition カーソル位置のシンボルが定義されている場所を問い合わせる。 ・textDocument/completion カーソル位置で利用可能な補完候補を問い合わせる。 ・textDocument/implementation インターフェースや抽象メソッドなどの実装先を問い合わせる
goplsについて
定義ジャンプの大まかな流れ gopls 定義ジャンプしたい ジャンプ textDocument/definition 位置を返す LSP
goplsの実装を追ってみる JSON-RPCのメソッドで 処理を分岐させる ファイル種別で処理を 分岐させる
golang.Definitionを追ってみる① 以下のパターンだと別の処理 ・import文 ・package名 ・embed directive ・Linkname directive ・DocLink
golang.Definitionを追ってみる② 以下のパターンでも別の処理で ・return ・continue ・break ・goto
golang.Definitionを追ってみる③ その後通常の識別子として判別 ・referencedObject カーソル位置の types.Objectを取得 ASTを取得してき、 info.ObjectOfで 定義元のObjectを取得
golang.Definitionを追ってみる④ ・ObjectLocation ③のtypes.Objectの位置を取 得 start = obj.Pos() end = start
+ token.Pos(namelen) でLocationを組み立てている
問題の定義ジャンプ改善 通常の識別子上での位置を返す前に RPCの実装を見にけば解決できそう、、、、!
ここでクイズ ~定義ジャンプ何処に飛ぶでしょう ~ return break
ここでクイズ ~定義ジャンプ何処に飛ぶでしょう ~ return break
ここでクイズ ~定義ジャンプ何処に飛ぶでしょう ~ ASTを上に辿って、 関数が見つかったら停止 関数の戻り値の位置を返 している
ここでクイズ ~定義ジャンプ何処に飛ぶでしょう ~ for, range文の場合 breakなら 最後(“}“) continueなら 最初(“for”) の位置を返す
gopls拡張
goplsを拡張する 追加する
1. 定義元がproto配下であるか確認 v.microserviceA.GetUser ↑だと microserviceAが proto配下であるか importPath を見て確認する。
1. 定義元がproto配下であるか確認 ASTを取得 識別子の検証 importPath を確認
2. 定義元のマイクロサービス名を取得 microserviceA.GetUserやclient.GetUser microserviceA, clientのpathを確認。 WINTICKETでは/proto/{{マイクロサービス名 }}のように なっているので、 1と同じように、 imortPathからマイクロ
サービス名を取得してくる。
3. 2で取得したパッケージで RPCの実装を探索 WINTICKETでは/pkg/{{マイクロサービス名 }}となっている ので、マイクロサービスのディレクトリで探索を行う。
4. 位置を返す ファイルを 1行ずつ分割し、 正規表現で頑張る。 マッチしたら FindStringIndex , strings.Indexで正確な位置を 取得し、protocol.Locationを
組み立て返却する。
gopls拡張で思ったこと 愚直に頑張るしかない ・汎用的なものを作るのは難しい ・ディレクトリ構成は中々変わらない ・それよりも正確に飛ぶことを頑張る
拡張goplsの運用
拡張したgoplsをどう使っていくか
拡張goplsのコード管理 1. github.com/golang/tools をprivateリポジトリに forkする ・ドメイン固有のロジックが入っているため 2. submoduleでWINTICKETのソースコード配下に置く ・ソースコード配下で拡張 goplsをビルドするため
拡張したgoplsをどう使っていくか 1. デフォルトの goplsを拡張した goplsに置 き換える 2. RPCの実装に飛ぶ専用の定義ジャンプ を作って、そこでだけ拡張 goplsを使う
拡張したgoplsをどう使っていくか 1. goplsを拡張した goplsに置き換える 2. RPCの実装に飛ぶ専用の定義ジャンプ を作って、そこでだけ拡張 goplsを使う
理由 他のlanguageServerの機能も拡張 goplsに乗っかる ことになる →メンテナンスが大変。 textDocument/definitionが完全に置き換わってしま う。 →逆にinterfaceに飛びたい時に不便
普段 gopls 定義ジャンプしたい ジャンプ textDocument/definition 位置を返す LSP
新しい定義ジャンプ 拡張gopls gRPCの実装に 定義ジャンプしたい ジャンプ textDocument/definition 位置を返す LSP VSCode拡張
新しい定義ジャンプ 拡張gopls gRPCの実装に 定義ジャンプしたい ジャンプ textDocument/definition 位置を返す LSP VSCode拡張
新しい定義ジャンプ 拡張gopls gRPCの実装に 定義ジャンプしたい ジャンプ textDocument/definition 位置を返す LSP VSCode拡張 普段
gopls 定義ジャンプしたい ジャンプ textDocument/definition 位置を返す LSP 共存させる
gopls 拡張gopls 従来の操作 RPC の実装に飛びたい
VSCode拡張 Go to gRPC Definitionを追加
VSCode拡張 1. 呼び出されたら拡張 goplsを起動する 2. textDocument/definitionリクエスト 3. レスポンスを受け取ったらその位置に ジャンプする
飛べた!!!!
感想
1. 簡単に拡張はできる 2. 大切なのはジャンプの正確性と速さ
ありがとうございました