AWS SDK の各言語版がどのように生成されているのかちょっと見てみた

「スタバで注文するのはいつも Venti」でおなじみの fujimura です。

AWS SDK が JSON で書かれた定義ファイルから生成されたものという話を以前、聞いた記憶があったので、具体的にどのように生成されているのか、いくつかの repository をさっくりのぞいてみました。

Java

テンプレートファイルは /aws-java-sdk-code-generator/src/main/resources/templates 配下に見当たります。ファイル名の拡張子が ftl ということから FreeMarker を使用しているようです。

${fileHeader}

<#assign documentation = (metadata.documentation)!""/>

/**
 * ${documentation}
 */
package ${metadata.packageName};

pom.xml の dependencies にも freemarker があることを確認しました。

<dependency>
        <artifactId>freemarker</artifactId>
        <groupId>org.freemarker</groupId>
        <optional>false</optional>
        <version>2.3.24-incubating</version>
    </dependency>

C++

テンプレートファイルは /code-generation/generator/src/main/resources/com/amazonaws/util/awsclientgenerator/velocity 配下に見当たります。途中のディレクトリ名のあるとおり Velocity を使用しているようです。

#set($enumSize = $enumModel.members.size())
#set($count = 1)
  enum class ${enumModel.name}
  {
    NOT_SET,
#foreach($enumMember in $enumModel.members)
    ${enumMember.memberName}#if($count < $enumSize),${nl}#end
#set($count = $count + 1)
#end

  };

namespace ${enumModel.name}Mapper
{
${typeInfo.exportValue} ${enumModel.name} Get${enumModel.name}ForName(const Aws::String& name);

${typeInfo.exportValue} Aws::String GetNameFor${enumModel.name}(${enumModel.name} value);
} // namespace ${enumModel.name}Mapper

こちらも pom.xml の dependencies に velocity があることを確認しました。

<dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-tools</artifactId>
            <version>2.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity</artifactId>
            <version>1.7</version>
        </dependency>

Java とは異なるテンプレートエンジンなのはちょっと興味深いです。

Ruby

テンプレートファイルは /build_tools/aws-sdk-code-generator/templates に見当たります。こちらは Mustache を使用してるようです。

{{#generated_src_warning}}
{{generated_src_warning}}
{{/generated_src_warning}}
module {{module_name}}
  module Errors

    extend Aws::Errors::DynamicErrors

  end
end

Gemfile に mustache の記述がありました。

group :build do
  # using this to fix poorly formatted HTML in API docs
  gem 'kramdown', '1.14.0' # pinned to support Ruby 1.9.3
  gem 'mustache', '0.99.8' # pinned to support Ruby 1.9.3
end

PHP

テンプレートファイルはなく、コード生成のための php が /build 配下にあります。JSON を PHP で書かれた array に変換し、そこからさらに PHP のソースコードを生成しているようです。

まとめ

自分がさっくりわかる言語については軽く調べてみました。基本的には自身の処理系でコードを生成しているようです。(C++ は Java でしたが...。)

他にも js や go、.Net などもどのように生成されているのかは気になりますが、そちらはもっと詳しいメンバに任せたいと思います。

それではみなさん、良いお年を。