{"id":24196522,"url":"https://github.com/dedis/protobuf","last_synced_at":"2025-07-14T12:36:44.026Z","repository":{"id":23726191,"uuid":"27099385","full_name":"dedis/protobuf","owner":"dedis","description":"Reflection-based Protocol Buffers for Go","archived":false,"fork":false,"pushed_at":"2019-11-25T15:43:28.000Z","size":178,"stargazers_count":79,"open_issues_count":6,"forks_count":15,"subscribers_count":16,"default_branch":"master","last_synced_at":"2025-06-27T11:17:14.017Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dedis.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-11-24T23:05:22.000Z","updated_at":"2025-04-17T21:37:21.000Z","dependencies_parsed_at":"2022-08-22T03:31:12.603Z","dependency_job_id":null,"html_url":"https://github.com/dedis/protobuf","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/dedis/protobuf","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dedis%2Fprotobuf","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dedis%2Fprotobuf/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dedis%2Fprotobuf/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dedis%2Fprotobuf/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dedis","download_url":"https://codeload.github.com/dedis/protobuf/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dedis%2Fprotobuf/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265293332,"owners_count":23742279,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":[],"created_at":"2025-01-13T19:35:42.815Z","updated_at":"2025-07-14T12:36:43.987Z","avatar_url":"https://github.com/dedis.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Reflection-based Protocol Buffers\n\nPackage protobuf implements Protocol Buffers reflectively using Go types to\ndefine message formats. This approach provides convenience similar to Gob\nencoding, but with a widely-used and language-neutral wire format.\nFor detailed API documentation see https://godoc.org/go.dedis.ch/protobuf.\nFor general information on Protocol buffers see\nhttps://developers.google.com/protocol-buffers.\n\n## Features\n\n- Reflection-based encoding and decoding to/from protocol buffer wire format.\n- Use Go struct field tags to control protobuf fields (ID, optional/required, names).\n- Generate `.proto` files from Go structures.\n- Encode `time.Time` as an `sfixed64` UnixNano.\n- Support for enums.\n\n## Details\n\nIn contrast with goprotobuf, this package does not require users to write or\ncompile .proto files; you just define the message formats you want as Go\nstruct types. Consider for example this example message format definition from\nthe Protocol Buffers overview:\n\n```protobuf\nmessage Person {\n  required string name = 1;\n  required int32  id = 2;\n  optional string email = 3;\n\n  enum PhoneType {\n    MOBILE = 0;\n    HOME = 1;\n    WORK = 2;\n  }\n\n  message PhoneNumber {\n    required string    number = 1;\n    optional PhoneType type = 2;\n  }\n\n  repeated PhoneNumber phone = 4;\n}\n```\n\nThe following Go type and const definitions express exactly the same format,\nfor purposes of encoding and decoding with this protobuf package:\n\n```go\ntype Person struct {\n  Name  string\n  Id    int32\n  Email *string\n  Phone []PhoneNumber\n}\n\ntype PhoneType uint32\nconst (\n  MobilePhone PhoneType = iota\n  HomePhone\n  WorkPhone\n)\n\ntype PhoneNumber struct {\n  Number string\n  Type *PhoneType\n}\n```\n\nTo encode a message, you simply call the Encode() function\nwith a pointer to the struct you wish to encode, and\nEncode() returns a []byte slice containing the protobuf-encoded struct:\n\n```go\nperson := Person{...}\nbuf := Encode(\u0026person)\noutput.Write(buf)\n```\n\nTo decode an encoded message, simply call Decode() on the byte-slice:\n\n```go\nerr := Decode(buf,\u0026person)\nif err != nil {\n  panic(\"Decode failed: \"+err.Error())\n}\n```\n\nIf you want to interoperate with code in other languages\nusing the same message formats, you may of course still end up writing\n.proto files for the code in those other languages.\n\nHowever, defining message formats with native Go types enables these types\nto be tailored to the code using them without affecting wire compatibility,\nsuch as by attaching useful methods to these struct types.\n\n## Translation Rules\n\nThe translation between a Go struct definition and a basic Protocol Buffers\nmessage format definition is straightforward; the rules are as follows.\n\nGo [field tags](https://golang.org/ref/spec#Struct_types) with the key\n\"protobuf\" may be used to control naming, IDs, and optional/required state.\nThe options are comma-separated like so:\n\n```go\ntype Tags struct {\n  Field1 string `protobuf:\"10,req,field_1\"`\n  Field2 int32  `protobuf:\"20,opt,field_2\"`\n}\n```\n\nA message definition in a .proto file translates to a Go struct, whose fields\nare implicitly assigned consecutive numbers starting from 1.\n\n```go\ntype Padded struct {\n  Field1 string                  // = 1\n  Field2 int32  `protobuf:\"3\"`   // = 3\n}\n```\n\nA 'required' protobuf field translates to a plain field of a corresponding\ntype in the Go struct. The following table summarizes the correspondence\nbetween .proto definition types and Go field types:\n\nProtobuf  |  Go\n----------|---------\nbool      | bool\nenum      | Enum\nint32     | uint32\nint64     | uint64\nuint32    | uint32\nuint64    | uint64\nsint32    | int32\nsint64    | int64\nfixed32   | Ufixed32\nfixed64   | Ufixed64\nsfixed32  | Sfixed32\nsfixed64  | Sfixed64\nfloat     | float32\ndouble    | float64\nstring    | string\nbytes     | []byte\nmessage   | struct\n\nAn 'optional' protobuf field is expressed as a pointer field in Go.\nEncode() will transmit the field only if the pointer is non-nil.\nDecode() will instantiate the pointed-to type and fill in the pointer\nif the field is present in the message being decoded,\nleaving the pointer unmodified (usually nil) if the field is not present.\n\nA 'repeated' protobuf field translates to a slice field in Go.\nSlices of primitive bool, integer, and float types are encoded\nand decoded in packed format, as if the [packed=true] option\nwas declared for the field in the .proto file.\n\nFor flexibility and convenience, struct fields may have interface types,\nwhich this package interprets as having dynamic types to be bound at runtime.\nEncode() follows the interface's implicit pointer and uses reflection\nto determine the referred-to object's actual type for encoding\nDecode() takes an optional map of interface types to constructor functions,\nwhich it uses to instantiate concrete types for interfaces while decoding.\nFurthermore, if the instantiated types support the Encoding interface,\nEncode() and Decode() will invoke the methods of that interface,\nallowing objects to implement their own custom encoding/decoding methods.\n\nThis package does not try to support all possible protobuf formats. It\ncurrently does not support nonzero default value declarations for enums, the\nlegacy unpacked formats for repeated numeric fields, messages with extremely\nsparse field numbering, or other more exotic features like extensions or\noneof. If you need to interoperate with existing protobuf code using these\nfeatures, then you should probably use goprotobuf, at least for those\nparticular message formats.\nMany of these limitations could be fixed by creative use of\nstruct tag metadata (see https://golang.org/ref/spec#Struct_types).\n\nAnother downside of this reflective approach to protobuf implementation is\nthat reflective code is generally less efficient than statically generated\ncode, as gogoprotobuf produces for example. If we decide we want the\nconvenience of format definitions in Go with the runtime performance of static\ncode generation, we could in principle achieve that by adding a \"Go-format\"\nmessage format compiler frontend to goprotobuf or gogoprotobuf - but we leave\nthis as an exercise for the reader.\n\n\n## Generating .proto files\n\n`.proto` files can be generated from Go structs using the\n`GenerateProtobufDefinition()` function. The following:\n\n```go\ntypes := []interface{}{\n  Person{},\n  PhoneNumber{},\n}\nenums := EnumMap{\n  \"MobilePhone\": MobilePhone,\n  \"HomePhone\": HomePhone,\n  \"WorkPhone\": WorkPhone,\n}\nGenerateProtobufDefinition(w, types, enums, nil)\n```\n\nWill generate:\n\n```protobuf\nmessage Person {\n  required string name = 1;\n  required sint32 id = 2;\n  optional string email = 3;\n  repeated PhoneNumber phone = 4;\n}\n\nmessage PhoneNumber {\n  required string number = 1;\n  optional uint32 type = 2;\n}\n```\n\nNote: It can be quite tedious to manually synchronise the type and enum maps with the types in your package. I've found [pkgreflect](https://github.com/ungerik/pkgreflect) very useful for automating this.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdedis%2Fprotobuf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdedis%2Fprotobuf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdedis%2Fprotobuf/lists"}