{"id":37103306,"url":"https://github.com/vedadiyan/protolizer","last_synced_at":"2026-01-14T12:30:42.910Z","repository":{"id":315277993,"uuid":"1058816915","full_name":"vedadiyan/protolizer","owner":"vedadiyan","description":"A Zero-Dependency Protobuffer Serializer ","archived":false,"fork":false,"pushed_at":"2025-11-13T09:21:30.000Z","size":2504,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2025-11-13T11:17:41.663Z","etag":null,"topics":["protobuf","protobuffer"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vedadiyan.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-17T15:31:50.000Z","updated_at":"2025-11-13T09:56:02.000Z","dependencies_parsed_at":"2025-10-29T13:13:42.241Z","dependency_job_id":"c6de4bdd-3703-474e-98c8-0a30aed4772a","html_url":"https://github.com/vedadiyan/protolizer","commit_stats":null,"previous_names":["vedadiyan/protolizer"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/vedadiyan/protolizer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vedadiyan%2Fprotolizer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vedadiyan%2Fprotolizer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vedadiyan%2Fprotolizer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vedadiyan%2Fprotolizer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vedadiyan","download_url":"https://codeload.github.com/vedadiyan/protolizer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vedadiyan%2Fprotolizer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28420773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["protobuf","protobuffer"],"created_at":"2026-01-14T12:30:42.240Z","updated_at":"2026-01-14T12:30:42.899Z","avatar_url":"https://github.com/vedadiyan.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Protolizer\n\nA zero-dependency, reflection-based Protocol Buffers library for Go that enables dynamic serialization and deserialization without requiring generated code or proto.reflect.\n\n## ✨ Features\n\n- **Zero Dependencies**: No external dependencies beyond Go's standard library\n- **Dynamic Serialization**: Serialize/deserialize protobuf messages without generated Go code\n- **Reflection-Based**: Uses Go's reflection to introspect struct tags and types\n- **Map Conversion**: Convert protobuf messages to `map[string]any` for inspection and manipulation\n- **Type Registry**: Built-in type registration and schema export/import\n- **Wire Format Compliant**: Full support for all protobuf wire types and encoding rules\n- **No proto.reflect**: Independent implementation that doesn't rely on Google's protobuf-go\n\n## 🚀 Installation\n\n```bash\ngo get github.com/vedadiyan/protolizer\n```\n\n## 📖 Quick Start\n\n### Basic Usage with Structs\n\n```go\npackage main\n\nimport (\n    \"fmt\"\n    \"github.com/vedadiyan/protolizer\"\n)\n\ntype Person struct {\n    Name  string `protobuf:\"bytes,1,opt,name=name,proto3\"`\n    Age   int32  `protobuf:\"varint,2,opt,name=age,proto3\"`\n    Email string `protobuf:\"bytes,3,opt,name=email,proto3\"`\n}\n\nfunc main() {\n    // Register the type\n    protolizer.RegisterTypeFor[Person]()\n    \n    // Create a person\n    person := Person{\n        Name:  \"John Doe\",\n        Age:   30,\n        Email: \"john@example.com\",\n    }\n    \n    // Marshal to protobuf bytes\n    data, err := protolizer.Marshal(\u0026person)\n    if err != nil {\n        panic(err)\n    }\n    \n    // Unmarshal back to struct\n    var decoded Person\n    err = protolizer.Unmarshal(data, \u0026decoded)\n    if err != nil {\n        panic(err)\n    }\n    \n    fmt.Printf(\"Original: %+v\\n\", person)\n    fmt.Printf(\"Decoded:  %+v\\n\", decoded)\n}\n```\n\n### Dynamic Map-Based Usage\n\n```go\n// Convert protobuf bytes to map for inspection\npersonMap, err := protolizer.Read(\"main.Person\", data)\nif err != nil {\n    panic(err)\n}\nfmt.Printf(\"As map: %+v\\n\", personMap)\n\n// Modify the map\npersonMap[\"Age\"] = float64(31)\npersonMap[\"Email\"] = \"john.doe@example.com\"\n\n// Convert map back to protobuf bytes\nnewData, err := protolizer.Write(\"main.Person\", personMap)\nif err != nil {\n    panic(err)\n}\n\n// Unmarshal the modified data\nvar modifiedPerson Person\nerr = protolizer.Unmarshal(newData, \u0026modifiedPerson)\nif err != nil {\n    panic(err)\n}\nfmt.Printf(\"Modified: %+v\\n\", modifiedPerson)\n```\n\n## 🏗️ Advanced Usage\n\n### Complex Types\n\n```go\ntype Address struct {\n    Street  string `protobuf:\"bytes,1,opt,name=street,proto3\"`\n    City    string `protobuf:\"bytes,2,opt,name=city,proto3\"`\n    Country string `protobuf:\"bytes,3,opt,name=country,proto3\"`\n}\n\ntype Contact struct {\n    Person    Person             `protobuf:\"bytes,1,opt,name=person,proto3\"`\n    Address   *Address           `protobuf:\"bytes,2,opt,name=address,proto3\"`\n    Phones    []string           `protobuf:\"bytes,3,rep,name=phones,proto3\"`\n    Metadata  map[string]string  `protobuf:\"bytes,4,rep,name=metadata,proto3\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n}\n\n// Register all types\nprotolizer.RegisterTypeFor[Address]()\nprotolizer.RegisterTypeFor[Contact]()\n```\n\n### Supported Field Types\n\n#### Primitive Types\n```go\ntype Primitives struct {\n    // Integer types\n    Int32Field  int32   `protobuf:\"varint,1,opt,name=int32_field,proto3\"`\n    Int64Field  int64   `protobuf:\"varint,2,opt,name=int64_field,proto3\"`\n    Uint32Field uint32  `protobuf:\"varint,3,opt,name=uint32_field,proto3\"`\n    Uint64Field uint64  `protobuf:\"varint,4,opt,name=uint64_field,proto3\"`\n    \n    // Fixed-width types\n    Fixed32     uint32  `protobuf:\"fixed32,5,opt,name=fixed32,proto3\"`\n    Fixed64     uint64  `protobuf:\"fixed64,6,opt,name=fixed64,proto3\"`\n    Sfixed32    int32   `protobuf:\"fixed32,7,opt,name=sfixed32,proto3\"`\n    Sfixed64    int64   `protobuf:\"fixed64,8,opt,name=sfixed64,proto3\"`\n    \n    // Float types\n    FloatField  float32 `protobuf:\"fixed32,9,opt,name=float_field,proto3\"`\n    DoubleField float64 `protobuf:\"fixed64,10,opt,name=double_field,proto3\"`\n    \n    // String and bytes\n    StringField string  `protobuf:\"bytes,11,opt,name=string_field,proto3\"`\n    BytesField  []byte  `protobuf:\"bytes,12,opt,name=bytes_field,proto3\"`\n    \n    // Boolean\n    BoolField   bool    `protobuf:\"varint,13,opt,name=bool_field,proto3\"`\n}\n```\n\n#### Collections\n```go\ntype Collections struct {\n    // Repeated fields\n    Numbers    []int32           `protobuf:\"varint,1,rep,packed,name=numbers,proto3\"`\n    Names      []string          `protobuf:\"bytes,2,rep,name=names,proto3\"`\n    \n    // Maps\n    StringMap  map[string]string `protobuf:\"bytes,3,rep,name=string_map,proto3\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n    IntMap     map[int32]string  `protobuf:\"bytes,4,rep,name=int_map,proto3\" protobuf_key:\"varint,1,opt,name=key\" protobuf_val:\"bytes,2,opt,name=value\"`\n}\n```\n\n### Schema Export/Import\n\n```go\n// Export type schema\nschemaBytes, err := protolizer.ExportType[Person]()\nif err != nil {\n    panic(err)\n}\n\n// Import type schema\nimportedType, err := protolizer.ImportType(schemaBytes)\nif err != nil {\n    panic(err)\n}\n\n// Export entire module (all related types)\nmoduleBytes, err := protolizer.ExportModule[Contact]()\nif err != nil {\n    panic(err)\n}\n\n// Import module\nmodule, err := protolizer.ImportModule(moduleBytes)\nif err != nil {\n    panic(err)\n}\n```\n\n## 🏷️ Protobuf Tag Format\n\nProtolizer uses standard protobuf struct tags with the following format:\n\n```go\n`protobuf:\"\u003cwire_type\u003e,\u003cfield_number\u003e,\u003clabel\u003e,name=\u003cfield_name\u003e,\u003csyntax\u003e\"`\n```\n\n### Wire Types\n- `varint` - Variable-length integers (int32, int64, uint32, uint64, bool)\n- `fixed64` - Fixed 64-bit values (double, fixed64, sfixed64)\n- `bytes` - Length-delimited (string, bytes, messages, packed repeated)\n- `fixed32` - Fixed 32-bit values (float, fixed32, sfixed32)\n\n### Labels\n- `opt` - Optional field\n- `req` - Required field (proto2)\n- `rep` - Repeated field\n\n### Map Fields\nFor map fields, specify key and value wire types:\n```go\nMapField map[string]int32 `protobuf:\"bytes,1,rep,name=map_field,proto3\" protobuf_key:\"bytes,1,opt,name=key\" protobuf_val:\"varint,2,opt,name=value\"`\n```\n\n## 🎯 API Reference\n\n### Core Functions\n\n#### `RegisterTypeFor[T any]()`\nRegisters a type in the global type registry for dynamic serialization.\n\n#### `Marshal(v any) ([]byte, error)`\nSerializes a Go struct to protobuf wire format.\n\n#### `Unmarshal(bytes []byte, v any) error`\nDeserializes protobuf bytes into a Go struct.\n\n#### `Read(typeName string, bytes []byte) (map[string]any, error)`\nConverts protobuf bytes to a map for dynamic inspection/manipulation.\n\n#### `Write(typeName string, v map[string]any) ([]byte, error)`\nConverts a map back to protobuf bytes.\n\n### Type Introspection\n\n#### `CaptureTypeFor[T any]() *Type`\nReturns type information for a registered type.\n\n#### `CaptureType(t reflect.Type) *Type`\nReturns type information for a reflect.Type.\n\n#### `CaptureTypeByName(typeName string) *Type`\nReturns type information by type name.\n\n### Schema Export/Import\n\n#### `ExportType[T any]() ([]byte, error)`\nExports a single type's schema as protobuf bytes.\n\n#### `ImportType(bytes []byte) (*Type, error)`\nImports a type schema from protobuf bytes.\n\n#### `ExportModule[T any]() ([]byte, error)`\nExports all related types as a module.\n\n#### `ImportModule(bytes []byte) (*Module, error)`\nImports a complete module with all types.\n\n## 🔧 Wire Format Details\n\nProtolizer implements the complete Protocol Buffers wire format specification:\n\n### Encoding Rules\n- **Varints**: Variable-length encoding for integers\n- **Fixed32/64**: Little-endian fixed-width encoding\n- **Length-Delimited**: Length-prefixed encoding for strings, bytes, and messages\n- **Packed Repeated**: Efficient encoding for repeated numeric fields\n\n### Tag Format\nEach field is prefixed with a tag containing:\n- Field number (bits 3+)\n- Wire type (bits 0-2)\n\n## ⚡ Performance Considerations\n\n- **Reflection Overhead**: Uses reflection for type introspection, which has some performance cost\n- **Memory Allocation**: Creates temporary objects during marshaling/unmarshaling\n- **Type Registration**: Types should be registered once at startup, not per operation\n- **Large Messages**: For very large messages, consider streaming approaches\n\n## 🤝 Contributing\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Commit your changes (`git commit -m 'Add amazing feature'`)\n4. Push to the branch (`git push origin feature/amazing-feature`)\n5. Open a Pull Request\n\n### Development Setup\n\n```bash\n# Clone the repo\ngit clone https://github.com/vedadiyan/protolizer.git\ncd protolizer\n\n# Run tests\ngo test ./...\n\n# Run benchmarks\ngo test -bench=. ./...\n```\n\n## 📋 Limitations\n\n- **No Proto Files**: Does not parse .proto files directly (struct tags define schema)\n- **No Code Generation**: Requires manual struct tag annotation\n- **Reflection Required**: Cannot eliminate reflection for type safety\n- **Go-Specific**: Designed specifically for Go, not cross-language compatible without schema export\n\n\n## 📄 License\n\nThis project is licensed under the Apache 2 License - see the [LICENSE](LICENSE) file for details.\n\n## 🙏 Acknowledgments\n\n- Protocol Buffers specification by Google\n- Go reflection and type system\n- The Go community for inspiration and best practices\n\n---\n\n**Made with ❤️ for dynamic protobuf handling in Go**","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvedadiyan%2Fprotolizer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvedadiyan%2Fprotolizer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvedadiyan%2Fprotolizer/lists"}