ARCHIVED from builddistributedsystem.com on 2026-04-28 — URL: https://builddistributedsystem.com/tracks/networker/tasks/task-5-3-1-protobuf-schema
TASK

Implementation

Protocol Buffers use a schema definition (.proto file) and a compact binary wire format. Each field has a number, type, and wire encoding.

Wire format: each field is (field_number << 3 | wire_type) followed by the value.

Implement a protobuf encoder/decoder for a simple message:

message Person {
    string name = 1;
    int32 age = 2;
    string email = 3;
}

Implement handlers:

Request:  {"type": "proto_define", "msg_id": 1, "schema": {"name": "Person", "fields": [
    {"name": "name", "number": 1, "type": "string"},
    {"name": "age", "number": 2, "type": "int32"},
    {"name": "email", "number": 3, "type": "string"}
]}}
Response: {"type": "proto_define_ok", "in_reply_to": 1, "message_name": "Person", "field_count": 3}

Request:  {"type": "proto_encode", "msg_id": 2, "message": "Person", "data": {"name": "Alice", "age": 30, "email": "alice@example.com"}}
Response: {"type": "proto_encode_ok", "in_reply_to": 2, "encoded_hex": "...", "size_bytes": 28}

Sample Test Cases

Define a protobuf schemaTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1"]}}
{"src":"c1","dest":"n1","body":{"type":"proto_define","msg_id":2,"schema":{"name":"Person","fields":[{"name":"name","number":1,"type":"string"},{"name":"age","number":2,"type":"int32"}]}}}
Expected Output
{"src": "n1", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}
{"src": "n1", "dest": "c1", "body": {"type": "proto_define_ok", "in_reply_to": 2, "message_name": "Person", "field_count": 2, "msg_id": 1}}
Encode a protobuf messageTimeout: 5000ms
Input
{"src":"c0","dest":"n1","body":{"type":"init","msg_id":1,"node_id":"n1","node_ids":["n1"]}}
{"src":"c1","dest":"n1","body":{"type":"proto_define","msg_id":2,"schema":{"name":"Person","fields":[{"name":"name","number":1,"type":"string"},{"name":"age","number":2,"type":"int32"}]}}}
{"src":"c1","dest":"n1","body":{"type":"proto_encode","msg_id":3,"message":"Person","data":{"name":"Alice","age":30}}}
Expected Output
{"src": "n1", "dest": "c0", "body": {"type": "init_ok", "in_reply_to": 1, "msg_id": 0}}

Hints

Hint 1
Protobuf uses field numbers instead of field names on the wire
Hint 2
Varint encoding uses 7 bits per byte with MSB continuation flag
Hint 3
Wire types: 0=varint, 1=64-bit, 2=length-delimited, 5=32-bit
Hint 4
Each field is encoded as (field_number << 3 | wire_type)
Hint 5
String fields use wire type 2: tag + length + bytes
OVERVIEW

Theoretical Hub

Concept overview coming soon

Key Concepts

Protocol Buffersschema definitionfield numberingvarint encoding
main.py
python
Define and Encode Protocol Buffer Messages - The Networker | Build Distributed Systems