Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 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
260e5ca
Serializes to string
jbelkins Dec 17, 2025
2e73154
Serializes maps & lists to string
jbelkins Dec 17, 2025
0a3b8c6
Fix rendered string for structure
jbelkins Dec 18, 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 serializableStructsSwiftPath = outputDirectoryPath.appending("\(name)SerializableStructs.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,
"--serializable-structs-path", serializableStructsSwiftPath,
modelPath
],
inputFiles: [inputPath, modelPath],
outputFiles: [schemasSwiftPath]
outputFiles: [schemasSwiftPath, serializableStructsSwiftPath]
)
}
}
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.
24 changes: 10 additions & 14 deletions Sources/Smithy/Schema/Schema.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
// SPDX-License-Identifier: Apache-2.0
//

/// A class which describes selected Smithy model information for a Smithy model shape.
/// A class which describes selected, modeled information for a Smithy shape.
///
/// Typically, the Schema contains only modeled info & properties that are relevant to
/// serialization, transport bindings, and other functions performed by the SDK.
Expand All @@ -29,7 +29,13 @@ public final class Schema: Sendable {
public let members: [Schema]

/// The target schema for this schema. Will only be used when this is a member schema.
public let target: Schema?
public var target: Schema? {
_target()
}

/// Target schema is passed as an autoclosure so that schemas with self-referencing targets will not cause
/// an infinite loop when accessed.
private let _target: @Sendable () -> Schema?

/// The index of this schema, if it represents a Smithy member.
///
Expand All @@ -49,24 +55,14 @@ public final class Schema: Sendable {
type: ShapeType,
traits: [ShapeID: Node] = [:],
members: [Schema] = [],
target: Schema? = nil,
target: @Sendable @escaping @autoclosure () -> Schema? = nil,
index: Int = -1
) {
self.id = id
self.type = type
self.traits = traits
self.members = members
self.target = target
self._target = target
self.index = index
}
}

public extension Schema {

/// The member name for this schema, if any.
///
/// Member name is computed from the schema's ID.
var memberName: String? {
id.member
}
}
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.
13 changes: 10 additions & 3 deletions Sources/SmithyCodegenCLI/SmithyCodegenCLI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ struct SmithyCodegenCLI: AsyncParsableCommand {
@Option(help: "The full or relative path to write the schemas output file.")
var schemasPath: String?

@Option(help: "The full or relative path to write the struct consumers output file.")
var structConsumersPath: String?
@Option(help: "The full or relative path to write the SerializableStructs output file.")
var serializableStructsPath: String?

func run() async throws {
let currentWorkingDirectoryFileURL = currentWorkingDirectoryFileURL()
Expand All @@ -35,10 +35,17 @@ struct SmithyCodegenCLI: AsyncParsableCommand {
// If --schemas-path was supplied, create the schema file URL
let schemasFileURL = resolve(paramName: "--schemas-path", path: schemasPath)

// If --serializable-structs-path was supplied, create the serializable structs file URL
let serializableStructsFileURL = resolve(
paramName: "--serializable-structs-path",
path: serializableStructsPath
)

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

Expand Down
4 changes: 3 additions & 1 deletion Sources/SmithyCodegenCore/AST/ASTMember.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
// SPDX-License-Identifier: Apache-2.0
//

import enum Smithy.Node

// See https://smithy.io/2.0/spec/json-ast.html#ast-member
struct ASTMember: Decodable {
let target: String
let traits: [String: ASTNode]?
let traits: [String: Node]?
}
4 changes: 3 additions & 1 deletion Sources/SmithyCodegenCore/AST/ASTModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
// SPDX-License-Identifier: Apache-2.0
//

import enum Smithy.Node

// See https://smithy.io/2.0/spec/json-ast.html#top-level-properties
struct ASTModel: Decodable {
let smithy: String
let metadata: ASTNode?
let metadata: Node?
let shapes: [String: ASTShape]
}
4 changes: 3 additions & 1 deletion Sources/SmithyCodegenCore/AST/ASTShape.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@
// SPDX-License-Identifier: Apache-2.0
//

import enum Smithy.Node

// See https://smithy.io/2.0/spec/json-ast.html#json-ast
// This Swift type captures fields for all AST shape types
struct ASTShape: Decodable {
let type: ASTType
let traits: [String: ASTNode]?
let traits: [String: Node]?
let member: ASTMember?
let key: ASTMember?
let value: ASTMember?
Expand Down
Loading
Loading