An open API service indexing awesome lists of open source software.

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.

Awesome Lists containing this project

README

          

# SwiftProtoReflect

A Swift library for dynamic Protocol Buffers message manipulation without pre-compiled schemas.

[![Platform](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Ftruewebber%2Fswift-protoreflect%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/truewebber/swift-protoreflect)
[![Swift Package Index](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Ftruewebber%2Fswift-protoreflect%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/truewebber/swift-protoreflect)
[![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat)](LICENSE)
[![Coverage](https://img.shields.io/badge/line%20coverage-93.4%25-green.svg?style=flat)](#quality-metrics)
[![Ask DeepWiki](https://deepwiki.com/badge.svg)](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.