-
Notifications
You must be signed in to change notification settings - Fork 35
feat: Add Swift-native codegen plugin #993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: jbe/add_schema
Are you sure you want to change the base?
Conversation
...main/kotlin/software/amazon/smithy/swift/codegen/integration/HTTPBindingProtocolGenerator.kt
Outdated
Show resolved
Hide resolved
| import software.amazon.smithy.aws.traits.ServiceTrait | ||
| import software.amazon.smithy.swift.codegen.integration.ProtocolGenerator | ||
| import software.amazon.smithy.swift.codegen.model.getTrait | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This just generates a very simple JSON file named smithy-model-info.json into the directory where the Swift source files go. Its purpose is to tell the Swift code generator where it can find the JSON model file for this service client, relative to project root. Example contents:
{"path":"codegen/sdk-codegen/aws-models/s3.json"}| import ArgumentParser | ||
| import Foundation | ||
| import SmithyCodegenCore | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a very simple code generator that:
- Reads the Smithy JSON model file into memory.
- Generates a Swift source file with a public variable
modelCount: Intthat contains the number of bytes in the model file. - Adds a simple doc comment to the variable.
While this example codegen is trivial and not useful in itself, it does prove that:
- A Swift build plugin code generator can read from our model files elsewhere in the project.
- It can generate a Swift file that is added to the target.
- Doc comments in generated code get picked up with the rest of the target's doc comments.
Follow-on development would code-generate more substantial content from the model.
|
|
||
| import struct Foundation.Data | ||
| import struct Foundation.URL | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All this type does right now is record the number of bytes in the model file. In the future it would read the model into an in-memory tree for use during code generation.
| dependencies: { | ||
| var dependencies: [Package.Dependency] = [ | ||
| .package(url: "https://github.com/awslabs/aws-crt-swift.git", exact: "0.54.2"), | ||
| .package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.0.0"), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
swift-argument-parser is added as a dependency because the SmithyCodegenCLI target is essentially a command-line tool, and argument-parser makes the API for that tool easier to manage & use.
aws-crt-swift already imports this dependency so the effect on customers' dependencies at compile time is zero add.
| .library(name: "SmithyCBOR", targets: ["SmithyCBOR"]), | ||
| .library(name: "SmithyWaitersAPI", targets: ["SmithyWaitersAPI"]), | ||
| .library(name: "SmithyTestUtil", targets: ["SmithyTestUtil"]), | ||
| .plugin(name: "SmithyCodeGenerator", targets: ["SmithyCodeGenerator"]), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The SmithyCodeGenerator plugin is exported so that service clients in aws-sdk-swift can add it to their target definitions.
| ), | ||
| .target( | ||
| name: "SmithyCodegenCore" | ||
| ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
3 targets are added above:
SmithyCodeGeneratorwhich is the build plugin that directs code generation at build time.SmithyCodegenCLIwhich is the executable that performs code generation.SmithyCodegenCorewhich contains components for reading the Smithy model. In the future it will provide features comparable to existing Smithy codegen.
|
|
||
| LOGGER.info("Generating Smithy model file info") | ||
| SmithyModelFileInfoGenerator(ctx).writeSmithyModelFileInfo() | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Initiates generation of the smithy-model-info.json file.
| import class Foundation.JSONDecoder | ||
| import struct Foundation.URL | ||
| import PackagePlugin | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This type implements the Swift build tool plugin.
Essentially, all the build plugin does is:
- Receives a list of all files in this target, and a "working directory" it can write its output to.
- Iterates over the files to decide what executable tool(s) to run on each of them.
- All source files except for
smithy-model-info.jsonare ignored & no action is taken on them. smithy-model-info.jsonis read to get the model file location, then the code generatorSmithyCodegenCLIis run with the model as the input.
- All source files except for
- Code-generated Swift files are written to the working directory, and after the build plugin finishes all its work, the Swift compiler compiles generated Swift files along with the rest of the target.
Description of changes
Adds the framework for a native-Swift code generator, in the form of a Swift build tool plugin plus a CLI tool.
The plugin is added to the service client target by adding it to the service client target's
pluginsparam. (Foraws-sdk-swift, this is performed in companion PR awslabs/aws-sdk-swift#2053).Using existing code generation, the
smithy-model-info.jsonis added to theSourcesin each service client. That file contains the path in the project to the Smithy JSON model for that service. Example contents ofsmithy-model-info.json:{"path":"codegen/sdk-codegen/aws-models/sts.json"}The code generator:
smithy-model-info.jsonfile for that client, then uses thepathfrom that file to load the model.ModelCount.swiftwith a global variablemodelCountholding the size of the model file in bytes (this proves that the code generator can access the model.)modelCountvar has a documentation comment, to show that doc comments in generated Swift files get picked up.Example of generated code (for
AWSSTS):This example code generation is trivial, but it does prove that code generation from a model is possible using Swift build plugins.
Dependency changes:
SmithyCodegenCLI, defined below) to benefit from the utilityswift-argument-parserprovides.aws-crt-swift, so no change in development footprint.Scope
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.