# proto

> Encode and decode Protocol Buffers wire format in Langoost using tag-to-type maps — varint, fixed, length-delimited, zigzag, and repeated fields.

# proto

The `proto` module reads and writes the Protocol Buffers **wire format**. You
supply a `types` map from field number to wire type; there's no `.proto` schema
compiler (that's a separate concern), but it's enough to talk to known
endpoints. Import it with `import proto`.

For a self-describing binary format that doesn't need type maps, see
**[serialize](/docs/stdlib/serialize)** (msgpack).

## Functions

| Function | Signature | Description |
| --- | --- | --- |
| `encode` | `proto.encode(fields: object, types: object) → string` | Encode field-number → value pairs into wire bytes |
| `decode` | `proto.decode(bytes: string, types: object) → object` | Decode wire bytes into a field-number → value object |

- `fields` and `types` are keyed by the field number as a string (`"1"`, `"2"`, …).
- Supported types: `int32`, `int64`, `uint32`, `uint64`, `sint32`, `sint64`
  (zigzag), `fixed32`, `fixed64`, `float`, `double`, `bool`, `string`, `bytes`.
- A field whose value is an array is encoded as a repeated field; on decode,
  repeated occurrences of a tag become an array.

```goost
import proto

let types = {"1": "int32", "2": "string", "3": "bool"}

let bytes = proto.encode({"1": 42, "2": "langoost", "3": true}, types)

let msg = proto.decode(bytes, types)
println(msg["2"])      // "langoost"
```

## Schema-based (.proto)

For real `.proto` files, load the schema once and work with **friendly field
names** instead of tag-to-type maps — no manual tag bookkeeping. This round-trips
strings, ints, bools, and repeated fields.

| Function | Signature | Description |
| --- | --- | --- |
| `loadSchema` | `proto.loadSchema(path \| paths[]) → object` | Parse one or more `.proto` files into a schema object |
| `encodeMessage` | `proto.encodeMessage(schema, messageName: string, value: object) → string` | Encode a message by name |
| `decodeMessage` | `proto.decodeMessage(schema, messageName: string, bytes: string) → object` | Decode a message by name |

```goost
import proto

let schema = proto.loadSchema("user.proto")

let bytes = proto.encodeMessage(schema, "User", {
    id: 42,
    name: "alice",
    roles: ["admin", "editor"],
})

let user = proto.decodeMessage(schema, "User", bytes)
println(user.name)     // "alice"
```