Swift Protobuf Documentation

repository·main·Indexed 26 days ago

https://github.com/apple/swift-protobuf

A command-line plugin for Google's protoc to generate Swift code from .proto files, featuring a high-performance runtime library for binary and JSON serialization and deserialization. Includes guides on installation via Homebrew or Swift Package Manager, handling MainActor isolation with NonisolatedDeclarations, and mapping protobuf basic types to Swift types.

Tokens
13.2K
Snippets
34
Records
72
Agent score
82%

What's inside Swift Protobuf

  1. Overview of upb features and limitations

    main

    upb (μpb) is a small, fast C implementation of Protocol Buffers. It is used as the core runtime for Ruby, PHP, and Python protobuf extensions.

    Supported Features

    • Generated API (in C)
    • Reflection
    • Binary & JSON wire formats
    • Text format serialization
    • Standard protobuf features (oneofs, maps, unknown fields, extensions, etc.)
    • Full conformance with protobuf conformance tests
    • Optional reflection: Generated messages are agnostic to whether reflection is linked.
    • No global state: No pre-main registration or other global state.
    • Fast reflection-based parsing: Runtime-loaded messages parse as fast as compiled-in messages.

    Unsupported Features

    • Text format parsing
    • Deep descriptor verification (validation is not as exhaustive as protoc)

    Important Note on C Usage

    While upb offers a C API, the C API & ABI are not stable. It is not generally intended to be used as a C library for direct consumption.

  2. Distinguish between proto2 and proto3 syntax

    main

    When working with SwiftProtobuf, distinguish between the protobuf language dialects (proto2 and proto3) and the versions of the protobuf project or the protoc software.

    • proto2 and proto3: These are dialects of the protobuf language.
    • protoc 3.x: This software version supports both the proto2 and proto3 language dialects.

    Users may choose to continue using the proto2 language dialect with protoc 3.x software to maintain compatibility with existing systems that require specific proto2 features.

  3. Organize Swift source files by type and purpose

    main

    Follow these naming and organization patterns for Swift files:

    • Single Type Files: Each file should ideally contain one type, with the filename matching the type name (e.g., Foo.swift for type Foo).
    • Grouped Types: If combining multiple small, related types, use a plural noun for the filename (e.g., ProtobufBinaryTypes.swift).
    • Protocol Extensions:
      • For a single type: Use Type+Protocol.swift (e.g., Foo+Encodable.swift).
      • For multiple related types: Use Types+Protocol.swift (e.g., Types+Encodable.swift).
  4. Handle fuzz testing failures and regressions

    main

    When a fuzzing issue is identified, follow these steps to ensure it is tracked and debuggable:

    1. Add a failure case: Add a file to the FailCases subdirectory. This allows the GitHub workflow to watch for regressions.
    2. Add to unit tests: Consider adding the case to Tests/SwiftProtobufTests/Test_FuzzTests.swift. This facilitates easier debugging and provides an additional layer of regression testing.

    Note: The address sanitizer is enabled in fuzz tests and may find different issues than running unit tests with the address sanitizer. Maintaining test cases in both locations is recommended.

  5. Configure Swift code-generation options

    main

    You can pass configuration options to the Swift code generator using the --swift_opt argument in your protoc command. You can specify multiple options by using the argument multiple times.

    Note for protoc 3.2.0 users: If protoc-gen-swift is on your PATH, --swift_opt might not be recognized. You must explicitly add --plugin=[PATH-TO-protoc-gen-swift] to your command. This is not required for protoc 3.2.1 or later.

    protoc --swift_opt=[NAME]=[VALUE] --swift_out:. foo/bar/*.proto mumble/*.proto
  6. Follow API naming conventions

    main

    API design should follow the Swift API Design Guidelines. Key patterns include:

    • Methods without side-effects (returning a value): Use nouns or noun phrases (e.g., serializedSize()).
    • Methods with side-effects (returning Void): Use imperative verbs or verb phrases (e.g., encode(value:)).
    • Non-Boolean properties: Use nouns or noun phrases (e.g., color, encodedSize).
    • Boolean properties: Use assertions, such as adjectival phrases starting with is (e.g., isEmpty) or indicative verb phrases (e.g., intersects).
    • Protocols (Identity): Use nouns for protocols describing what something is (e.g., Collection).
    • Protocols (Capability): Use gerunds (e.g., Encoding) or -able/-ible adjectives (e.g., Encodable) for protocols describing what something is capable of.
  7. Add SwiftProtobuf library to your project

    main

    After generating .pb.swift files, you must add the SwiftProtobuf runtime library to your project.

    1. Check your protoc-gen-swift version: protoc-gen-swift --version.
    2. Add the dependency to your Package.swift using a version matching your plugin version.
    3. If using Xcode, add the generated .pb.swift files to your project and add the SwiftProtobuf SwiftPM package as a dependency.
    // Example Package.swift dependency
    dependencies: [
        .package(name: "SwiftProtobuf", url: "https://github.com/apple/swift-protobuf.git", from: "1.6.0"),
    ]
  8. Add the SwiftProtobuf library to your project

    main

    After generating Swift code, you must include the SwiftProtobuf runtime library in your project. It is strongly recommended to use the version of the library that matches the version of protoc-gen-swift used for generation.

    Using Swift Package Manager (swift build)

    Add the dependency to your Package.swift file:

    dependencies: [
        .package(url: "https://github.com/apple/swift-protobuf.git", from: "1.27.0"),
    ],
    targets: [
        .target(
          name: "MyTarget",
          dependencies: [.product(name: "SwiftProtobuf", package: "swift-protobuf")]
        ),
    ]

    (Note: Replace 1.27.0 with your specific version tag.)

    Using Xcode

    1. Add the generated .pb.swift files directly to your Xcode project.
    2. Add the SwiftProtobuf SwiftPM package as a dependency via Xcode's package dependency management.

    Using CocoaPods

    Add the following to your Podfile (requires CocoaPods 1.7 or newer):

    pod 'SwiftProtobuf', '~> 1.0'

    Then run pod install. Adjust the :tag to match your plugin version.