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
360
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
690
Featured
See All Featured
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
290
The untapped power of vector embeddings
frankvandijk
2
1.8k
Claude Code どこまでも/ Claude Code Everywhere
nwiizo
65
56k
Paper Plane
katiecoart
PRO
1
51k
Building Flexible Design Systems
yeseniaperezcruz
330
40k
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
2.9k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
160
Dealing with People You Can't Stand - Big Design 2015
cassininazir
367
27k
Chasing Engaging Ingredients in Design
codingconduct
0
220
Designing Powerful Visuals for Engaging Learning
tmiket
1
410
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
200
Typedesign – Prime Four
hannesfritz
42
3.1k
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. 大切なのはジャンプの正確性と速さ
ありがとうございました