https://github.com/truewebber/swift-protoreflect
SwiftProtoReflect is a dynamic Protocol Buffers library for Swift, enabling reflection-based message handling, serialization, and deserialization without the need for precompiled .proto files.
https://github.com/truewebber/swift-protoreflect
data-structures protobuf protocol-buffers reflection serialization serialization-deserialization swift swift-library
Last synced: about 2 hours ago
JSON representation
SwiftProtoReflect is a dynamic Protocol Buffers library for Swift, enabling reflection-based message handling, serialization, and deserialization without the need for precompiled .proto files.
- Host: GitHub
- URL: https://github.com/truewebber/swift-protoreflect
- Owner: truewebber
- License: mit
- Created: 2024-10-19T22:33:27.000Z (over 1 year ago)
- Default Branch: master
- Last Pushed: 2026-03-28T18:55:48.000Z (5 days ago)
- Last Synced: 2026-03-28T21:09:46.749Z (5 days ago)
- Topics: data-structures, protobuf, protocol-buffers, reflection, serialization, serialization-deserialization, swift, swift-library
- Language: Swift
- Homepage:
- Size: 1.95 MB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# SwiftProtoReflect
A Swift library for dynamic Protocol Buffers message manipulation without pre-compiled schemas.
[](https://swiftpackageindex.com/truewebber/swift-protoreflect)
[](https://swiftpackageindex.com/truewebber/swift-protoreflect)
[](LICENSE)
[](#quality-metrics)
[](https://deepwiki.com/truewebber/swift-protoreflect)
## Overview
SwiftProtoReflect enables runtime manipulation of Protocol Buffers messages without requiring code generation from `.proto` files. This is useful for building generic tools, API gateways, data processors, and other applications that need to work with protobuf schemas dynamically.
## Installation
Add to your `Package.swift`:
```swift
dependencies: [
.package(url: "https://github.com/truewebber/swift-protoreflect.git", from: "5.0.0")
]
```
> **Note:** If you are upgrading from 4.x, see the [Migration Guide](MIGRATION_GUIDE.md) for details on breaking changes.
## Basic Usage
### Creating Messages Dynamically
```swift
import SwiftProtoReflect
// Define a message schema at runtime
let personSchema = try MessageDescriptor.builder("Person")
.addField("name", number: 1, type: .string)
.addField("age", number: 2, type: .int32)
.addField("emails", number: 3, type: .string, label: .repeated)
.build()
// Create and populate a message
let message = try MessageFactory().createMessage(from: personSchema)
try message.set("name", value: "Alice")
try message.set("age", value: 25)
try message.set("emails", value: ["alice@example.com"])
// Serialize to binary or JSON
let binaryData = try BinarySerializer().serialize(message: message)
let jsonString = try JSONSerializer().serialize(message: message)
```
### Working with Well-Known Types
```swift
// Timestamps
let timestampMessage = try DynamicMessage.timestampMessage(from: Date())
let backToDate = try timestampMessage.toDate()
// JSON-like structures
let data: [String: Any] = ["user": "john", "active": true]
let structMessage = try DynamicMessage.structMessage(from: data)
// Type erasure
let anyMessage = try message.packIntoAny()
let unpackedMessage = try anyMessage.unpackFromAny(to: personSchema)
```
## Features
- **Dynamic Message Creation**: Create and manipulate protobuf messages at runtime
- **Schema Definition**: Build message descriptors programmatically
- **Proto3 Compliance**: Syntax tracking, zero defaults, optional presence, enum validation, unknown fields preservation
- **Canonical JSON**: int64/uint64 as strings, bytes as base64, enums as names, `includeDefaultValues`
- **Nested Messages**: Recursive binary serialization/deserialization with type resolution
- **Schema Evolution**: Safe field addition/removal/renaming with unknown field round-trip
- **Typed Options**: `DescriptorOption` enum for type-safe, `Sendable` descriptor options
- **Oneof Support**: First-class `OneofDescriptor` with full bridge round-trip
- **Serialization**: Binary and JSON serialization/deserialization
- **Well-Known Types**: 18 types — Timestamp, Duration, Empty, FieldMask, Struct, Value, Any, ListValue, NullValue, and 9 wrapper types
- **Swift Protobuf Compatibility**: Convert between static and dynamic messages, Visitor-based descriptor extraction
- **Type Registry**: Centralized type management and lookup
- **Swift 6 Ready**: All public types conform to `Sendable`
## Examples
The library includes 47 working examples demonstrating various use cases:
```bash
git clone https://github.com/truewebber/swift-protoreflect.git
cd swift-protoreflect/examples
# Basic examples
swift run HelloWorld
swift run FieldTypes
swift run TimestampDemo
# Proto3 compliance
swift run SyntaxAndDefaults
swift run OptionalPresence
swift run UnknownFields
swift run JsonCanonical
# Advanced examples
swift run ApiGateway
swift run MessageTransform
```
Examples are organized by topic:
- **Basic Usage** (4): Getting started
- **Dynamic Messages** (7): Message manipulation
- **Serialization** (5): Binary and JSON formats
- **Registry** (4): Type management
- **Well-Known Types** (10): Google standard types, wrapper types, ListValue
- **Advanced** (6): Complex patterns
- **Real-World** (5): Production scenarios
- **Proto3 Compliance** (6): Syntax, optional presence, unknown fields, canonical JSON, schema evolution, nested messages
## Requirements
- Swift 5.9+
- macOS 12.0+ / iOS 15.0+
- **Recommended:** SwiftProtoReflect 5.0.0+
## Dependencies
- [SwiftProtobuf](https://github.com/apple/swift-protobuf) 1.29.0+
## Documentation
- **[Architecture Guide](docs/ARCHITECTURE.md)**: Technical implementation details
- **[Migration Guide](MIGRATION_GUIDE.md)**: Migrating from static Swift Protobuf
## Use Cases
- Generic protobuf tools (viewers, debuggers, converters)
- API gateways with dynamic message routing
- Data processing pipelines with runtime schema handling
- Testing tools that generate data for arbitrary schemas
- Configuration systems using protobuf schemas
## Integration with Swift Protobuf
SwiftProtoReflect works alongside existing Swift Protobuf code:
```swift
// Convert static to dynamic
let staticMessage = Person.with { /* ... */ }
let dynamicMessage = try staticMessage.toDynamicMessage()
// Convert dynamic to static
let staticMessage: Person = try dynamicMessage.toStaticMessage()
```
## Testing
The library has comprehensive test coverage covering all functionality and edge cases.
### Quality metrics
Code coverage is measured with LLVM (`make coverage` after `make test`) over `Sources/SwiftProtoReflect/`:
| Metric | Coverage |
|--------|----------|
| Lines | **93.37%** |
| Regions | **95.69%** |
| Functions | **95.52%** |
Figures reflect the current test suite; re-run `make test` and `make coverage` locally for up-to-date numbers.
## License
MIT License. See [LICENSE](LICENSE) for details.