Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
495f2e1
Disable input/output serializers
jbelkins Nov 4, 2025
ca5b331
add ShapeID, doc comments
jbelkins Nov 5, 2025
212120e
Re-enable serde code
jbelkins Nov 5, 2025
fcdf1bf
Cleanup
jbelkins Nov 5, 2025
b2152c2
Merge branch 'main' into jbe/add_schema
jbelkins Nov 7, 2025
88f7be9
Merge branch 'main' into jbe/add_schema
jbelkins Nov 8, 2025
aa823be
feat: Add Swift-native codegen plugin
jbelkins Nov 9, 2025
e817d55
Fix lint
jbelkins Nov 9, 2025
6a9c537
Make service trait optional
jbelkins Nov 9, 2025
33cc093
Fix ktlint again
jbelkins Nov 9, 2025
6b54575
Refactor code generator plugin
jbelkins Nov 9, 2025
ae474f1
Convert smithy model info file to .json
jbelkins Nov 9, 2025
70f7669
Fix Swift 5.9 URL initializer
jbelkins Nov 9, 2025
3d623e6
Code cleanup
jbelkins Nov 9, 2025
d535e66
Revert disabling of schemas
jbelkins Nov 9, 2025
52f9532
Schemas generate for entire SDK
jbelkins Nov 15, 2025
1fa7fbd
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Nov 19, 2025
70e8a15
Fix method name renderSchema
jbelkins Nov 19, 2025
b1548a7
Fix swiftlint
jbelkins Nov 19, 2025
94a901d
Fix ktlint
jbelkins Nov 19, 2025
54a4300
Fix SmithyCodegenCoreTests
jbelkins Nov 19, 2025
6b860df
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Nov 22, 2025
1eb996b
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Nov 26, 2025
3fd9854
Cleanup
jbelkins Dec 5, 2025
64dd13a
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Dec 9, 2025
6a65655
Fixes
jbelkins Dec 9, 2025
db5b76a
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Dec 12, 2025
64eeff9
More codegen added
jbelkins Dec 12, 2025
953e1d9
Merge branch 'epic/sbs' into jbe/swift_codegen_schema
jbelkins Dec 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -308,7 +308,9 @@ let package = Package(
]
),
.target(
name: "SmithyCodegenCore"
name: "SmithyCodegenCore",
dependencies: ["SmithySerialization"],
resources: [ .process("Resources") ]
),
.testTarget(
name: "ClientRuntimeTests",
Expand Down Expand Up @@ -397,5 +399,9 @@ let package = Package(
name: "SmithyStreamsTests",
dependencies: ["SmithyStreams", "Smithy"]
),
.testTarget(
name: "SmithyCodegenCoreTests",
dependencies: ["SmithyCodegenCore"]
),
].compactMap { $0 }
)
6 changes: 5 additions & 1 deletion Plugins/SmithyCodeGenerator/SmithyCodeGeneratorPlugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,20 @@ struct SmithyCodeGeneratorPlugin: BuildToolPlugin {
// Construct the schemas.swift path.
let schemasSwiftPath = outputDirectoryPath.appending("\(name)Schemas.swift")

// Construct the structconsumers.swift path.
let structConsumersSwiftPath = outputDirectoryPath.appending("\(name)StructConsumers.swift")

// Construct the build command that invokes SmithyCodegenCLI.
return .buildCommand(
displayName: "Generating Swift source files from model file \(smithyModelInfo.path)",
executable: generatorToolPath,
arguments: [
"--schemas-path", schemasSwiftPath,
"--struct-consumers-path", structConsumersSwiftPath,
modelPath
],
inputFiles: [inputPath, modelPath],
outputFiles: [schemasSwiftPath]
outputFiles: [schemasSwiftPath, structConsumersSwiftPath]
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ import protocol SmithyHTTPAuthAPI.AuthSchemeResolver
import protocol SmithyHTTPAuthAPI.AuthSchemeResolverParameters
import struct SmithyRetries.DefaultRetryStrategy
import struct SmithyRetries.ExponentialBackoffStrategy
import SmithyTelemetryAPI
import protocol SmithyRetriesAPI.RetryErrorInfoProvider
import protocol SmithyRetriesAPI.RetryStrategy
import struct SmithyRetriesAPI.RetryStrategyOptions
import SmithyTelemetryAPI

public struct DefaultSDKRuntimeConfiguration<DefaultSDKRuntimeRetryStrategy: RetryStrategy,
DefaultSDKRuntimeRetryErrorInfoProvider: RetryErrorInfoProvider> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ import protocol SmithyHTTPAPI.HTTPClient
import class SmithyHTTPAPI.HTTPRequest
import class SmithyHTTPAPI.HTTPResponse
import enum SmithyHTTPAPI.HTTPStatusCode
import class SmithyHTTPClientAPI.HttpTelemetry
import enum SmithyHTTPClientAPI.HttpMetricsAttributesKeys
import class SmithyHTTPClientAPI.HttpTelemetry
import class SmithyStreams.BufferedStream
import SmithyTelemetryAPI
#if os(Linux)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
import AwsCommonRuntimeKit
import struct Smithy.Attributes
import enum Smithy.ByteStream
import class SmithyHTTPClientAPI.HttpTelemetry
import enum SmithyHTTPClientAPI.HttpMetricsAttributesKeys
import class SmithyHTTPClientAPI.HttpTelemetry

extension HTTP2Stream {
/// Returns the recommended size, in bytes, for the data to write
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ import class Foundation.DispatchQueue
import class Foundation.InputStream
import class Foundation.NSObject
import class Foundation.OutputStream
import class SmithyHTTPClientAPI.HttpTelemetry
import enum SmithyHTTPClientAPI.HttpMetricsAttributesKeys
import class Foundation.RunLoop
import class Foundation.Stream
import protocol Foundation.StreamDelegate
Expand All @@ -24,6 +22,8 @@ import class Foundation.Timer
import struct Smithy.Attributes
import protocol Smithy.LogAgent
import protocol Smithy.ReadableStream
import enum SmithyHTTPClientAPI.HttpMetricsAttributesKeys
import class SmithyHTTPClientAPI.HttpTelemetry

/// Reads data from a smithy-swift native `ReadableStream` and streams the data through to a Foundation `InputStream`.
///
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@ import class Foundation.NSRecursiveLock
import var Foundation.NSURLAuthenticationMethodClientCertificate
import var Foundation.NSURLAuthenticationMethodServerTrust
import struct Foundation.TimeInterval
import class SmithyHTTPClientAPI.HttpTelemetry
import enum SmithyHTTPClientAPI.HttpMetricsAttributesKeys
import class Foundation.URLAuthenticationChallenge
import struct Foundation.URLComponents
import class Foundation.URLCredential
Expand All @@ -29,7 +27,6 @@ import class Foundation.URLResponse
import class Foundation.URLSession
import class Foundation.URLSessionConfiguration
import protocol Foundation.URLSessionDataDelegate
import SmithyTelemetryAPI
import class Foundation.URLSessionDataTask
import class Foundation.URLSessionTask
import class Foundation.URLSessionTaskMetrics
Expand All @@ -44,7 +41,10 @@ import protocol SmithyHTTPAPI.HTTPClient
import class SmithyHTTPAPI.HTTPRequest
import class SmithyHTTPAPI.HTTPResponse
import enum SmithyHTTPAPI.HTTPStatusCode
import enum SmithyHTTPClientAPI.HttpMetricsAttributesKeys
import class SmithyHTTPClientAPI.HttpTelemetry
import class SmithyStreams.BufferedStream
import SmithyTelemetryAPI

/// A client that can be used to make requests to AWS services using `Foundation`'s `URLSession` HTTP client.
///
Expand Down
File renamed without changes.
42 changes: 0 additions & 42 deletions Sources/Smithy/Schema/ShapeID.swift

This file was deleted.

90 changes: 90 additions & 0 deletions Sources/Smithy/ShapeID.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

/// Represents a Smithy shape ID.
///
/// The id that ShapeID is created from is presumed to be properly formed, since this type will usually
/// be constructed from previously validated models.
///
/// Shape ID is described in the Smithy 2.0 spec [here](https://smithy.io/2.0/spec/model.html#shape-id).
public struct ShapeID: Hashable, Sendable {
public let namespace: String
public let name: String
public let member: String?

/// Creates a Shape ID for a Smithy shape.
///
/// This initializer does no validation of length or of allowed characters in the Shape ID;
/// that is to be ensured by the caller (typically calls to this initializer will be code-generated
/// from previously validated Smithy models.)
/// - Parameters:
/// - namespace: The namespace for this shape, i.e. `smithy.api`.
/// - name: The name for this shape, i.e. `Integer`.
/// - member: The optional member name for this shape.
public init(_ namespace: String, _ name: String, _ member: String? = nil) {
self.namespace = namespace
self.name = name
self.member = member
}

public init(_ id: String) throws {
let splitOnPound = id.split(separator: "#")
guard splitOnPound.count == 2 else {
throw ShapeIDError("id \"\(id)\" does not have a #")
}
guard let namespace = splitOnPound.first, !namespace.isEmpty else {
throw ShapeIDError("id \"\(id)\" does not have a nonempty namespace")
}
self.namespace = String(namespace)
let splitOnDollar = splitOnPound.last!.split(separator: "$")
switch splitOnDollar.count {
case 2:
self.name = String(splitOnDollar.first!)
self.member = String(splitOnDollar.last!)
case 1:
self.name = String(splitOnDollar.first!)
self.member = nil
default:
throw ShapeIDError("id \"\(id)\" has more than one $")
}
}

public init(id: ShapeID, member: String) {
self.namespace = id.namespace
self.name = id.name
self.member = member
}

public var id: String {
if let member {
return "\(namespace)#\(name)$\(member)"
} else {
return "\(namespace)#\(name)"
}
}
}

extension ShapeID: Comparable {

public static func < (lhs: ShapeID, rhs: ShapeID) -> Bool {
return lhs.id.lowercased() < rhs.id.lowercased()
}
}

extension ShapeID: CustomStringConvertible {

/// Returns the absolute Shape ID in a single, printable string.
public var description: String { id }
}

public struct ShapeIDError: Error {
public let localizedDescription: String

init(_ localizedDescription: String) {
self.localizedDescription = localizedDescription
}
}
File renamed without changes.
6 changes: 5 additions & 1 deletion Sources/SmithyCodegenCLI/SmithyCodegenCLI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@ struct SmithyCodegenCLI: AsyncParsableCommand {
// If --schemas-path was supplied, create the schema file URL
let schemasFileURL = resolve(paramName: "--schemas-path", path: schemasPath)

// If --struct-consumers-path was supplied, create the struct consumers file URL
let structConsumersFileURL = resolve(paramName: "--struct-consumers-path", path: structConsumersPath)

// Use resolved file URLs to run code generator
try CodeGenerator(
modelFileURL: modelFileURL,
schemasFileURL: schemasFileURL
schemasFileURL: schemasFileURL,
structConsumersFileURL: structConsumersFileURL
).run()
}

Expand Down
25 changes: 16 additions & 9 deletions Sources/SmithyCodegenCore/CodeGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,43 @@
//

import struct Foundation.Data
import class Foundation.FileManager
import class Foundation.JSONDecoder
import struct Foundation.URL


Check failure on line 12 in Sources/SmithyCodegenCore/CodeGenerator.swift

View workflow job for this annotation

GitHub Actions / swiftlint

Limit vertical whitespace to a single empty line; currently 2 (vertical_whitespace)
public struct CodeGenerator {
let modelFileURL: URL
let schemasFileURL: URL?
let structConsumersFileURL: URL?

public init(
modelFileURL: URL,
schemasFileURL: URL?
schemasFileURL: URL?,
structConsumersFileURL: URL?
) {
self.modelFileURL = modelFileURL
self.schemasFileURL = schemasFileURL
self.structConsumersFileURL = structConsumersFileURL
}

public func run() throws {
// Load the AST from the model file
let modelData = try Data(contentsOf: modelFileURL)
let astModel = try JSONDecoder().decode(ASTModel.self, from: modelData)

// In the future, AST will be used to create a Model.
// Model will be used to generate code.
// Create the model from the AST
let model = try Model(astModel: astModel)

// This code simply writes an empty schemas file, since it is expected to exist after the
// code generator plugin runs.
//
// Actual code generation will be implemented here later.
// If a schema file URL was provided, generate it
if let schemasFileURL {
FileManager.default.createFile(atPath: schemasFileURL.path, contents: Data())
let schemaContents = try SmithySchemaCodegen().generate(model: model)
try Data(schemaContents.utf8).write(to: schemasFileURL)
}

// If a struct consumers file URL was provided, generate it
if let structConsumersFileURL {
let structConsumersContents = try StructConsumersCodegen().generate(model: model)
try Data(structConsumersContents.utf8).write(to: structConsumersFileURL)
}
}
}
14 changes: 14 additions & 0 deletions Sources/SmithyCodegenCore/CodegenError.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// Copyright Amazon.com Inc. or its affiliates.
// All Rights Reserved.
//
// SPDX-License-Identifier: Apache-2.0
//

struct CodegenError: Error {
let localizedDescription: String

init(_ localizedDescription: String) {
self.localizedDescription = localizedDescription
}
}
Loading
Loading