その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

openapi-generator を使って go のファイルを生成した時に出てくる `var _ context.Context` の謎

openapi-generator を使って go のコード生成をすると、

// Linger please
var (
	_ context.Context
)

という一見不要そうな変数宣言がコード中に出てきます。これはなんなのでしょうか? 「残しておいてね」とは書いてありますが……

TL;DR

たぶんこれ過去のワークアラウンドがそのまま残っている感じだと思われます。まあ特に気にする必要もなさそう……

<追記>
このワークアラウンドの残滓を消すパッチを送ってみた。
github.com

^ 送ってみたところマージされたのでこの謎は過去のものになりつつあります。
</追記>

詳しく見てみる

というわけでコードを掘ってみましょう。リビジョンについては今日 (2022-02-16) 現在の最新である 986446c1d5e7b2c16c667ed18b6c95b2679268f5 から遡っていきます。

なるほど、ここに該当するコードがありますね。blameしていきましょう。

openapi-generator/modules/openapi-generator/src/main/resources/go/api.mustache の一番古いコミットを見てみるとここになるようです:

ここにもこの変数宣言はまだありますね。つまりこれが最古のコミットで、そこに「ある」ってことは「ある」んだよ、ガタガタ言うな、ということでしょうか……
とまあそうではなく、というのもこのファイルは openapi-generator/modules/swagger-codegen/src/main/resources/go/api.mustache から改名されているので一見すると歴史が途絶えてしまっているようですが、これよりも古いコミットはちゃんとあります。更にこのファイルの歴史を辿ってみましょう。
しかし swagger から openapi に名前が変わっているのは歴史を感じますね。

で、掘っていくとこのコミットに行き当たります: 3ed1aa8e79687bed63dfa064de27317273080471

この diff を見ると、件の変数宣言はここが始祖のようです。それはそうとして golang.org/x/net/context が使われていたりしてなんだか懐しいですね。

で、このテンプレートファイルを読んでみると {{#hasAuthMethods}}ctx context.Context, {{/hasAuthMethods}} という条件分岐があるのがわかります。
つまり、この条件が false になるとこの部分が欠落し、そうなった時に import "golang.org/x/net/context" があるとコンパイラに未使用の import があると怒られるので、そのワークアラウンドに無名変数 (_ って無名変数って名前で良いんでしたっけ) として context.Context を変数宣言することで import 未使用コンパイルエラーを回避しているように読みとれます。なるほど〜。 *1


さて翻って最新のコードを再び見てみましょう。

このコードを読むと context.Context は常に使われているように見えるし、わざわざ var _ context.Context を付けておく必要もないように見えます。これパッと見不要そうに思えるんですが、今でも残しておく必要あるんですかね? 後でパッチでも投げてみようかしら……

結論

// Linger please
var (
	_ context.Context
)

はかつてのワークアラウンドの名残 (だと思われる)。

*1:とはいえコミットログにその旨は書いていない。コミットログの issue 番号も恐らく前の repository のものなのでどれと紐付いているかわからない、という感じなのであくまでコードを読んだ上での推察です