blob: 11dd4e7bc418bbf41be58a1628a9c47551061f7c [file] [log] [blame]
Alexei Frolov9c2ed462020-01-13 15:35:42 -08001.. default-domain:: cpp
2
3.. highlight:: sh
4
5.. _chapter-protobuf:
6
7-----------
8pw_protobuf
9-----------
10The protobuf module provides a lightweight interface for encoding and decoding
11the Protocol Buffer wire format.
12
Alexei Frolov4a257c12020-03-02 14:09:42 -080013Design
14======
15Unlike other protobuf libraries, which typically provide in-memory data
16structures to represent protobuf messages, pw_protobuf operates directly on the
17wire format and leaves data storage to the user. This has a few benefits. The
18primary one is that it allows the library to be incredibly small, with the
19encoder and decoder each having a code size of around 1.5K and negligible RAM
20usage. Users can choose the tradeoffs most suitable for their product on top of
21this core implementation.
22
23pw_protobuf also provides zero-overhead C++ code generation which wraps its
24low-level wire format operations with a user-friendly API for processing
25specific protobuf messages. The code generation integrates with Pigweed's GN
26build system.
27
28Usage
29=====
30pw_protobuf splits wire format encoding and decoding operations. Links to the
31design and APIs of each are listed in below.
32
33See also :ref:`chapter-pw-protobuf-compiler` for details on pw_protobuf's build
34system integration.
35
36**pw_protobuf functionality**
37
Alexei Frolov9c2ed462020-01-13 15:35:42 -080038.. toctree::
39 :maxdepth: 1
40
Alexei Frolov4a257c12020-03-02 14:09:42 -080041 decoding
42
43Comparison with other protobuf libraries
44========================================
45
46protobuf-lite
47^^^^^^^^^^^^^
48protobuf-lite is the official reduced-size C++ implementation of protobuf. It
49uses a restricted subset of the protobuf library's features to minimize code
50size. However, is is still around 150K in size and requires dynamic memory
51allocation, making it unsuitable for many embedded systems.
52
53nanopb
54^^^^^^
55`nanopb <https://github.com/nanopb/nanopb>`_ is a commonly used embedded
56protobuf library with very small code size and full code generation. It provides
57both encoding/decoding functionality and in-memory C structs representing
58protobuf messages.
59
60nanopb works well for many embedded products; however, using its generated code
61can run into RAM usage issues when processing nontrivial protobuf messages due
62to the necessity of defining a struct capable of storing all configurations of
63the message, which can grow incredibly large. In one project, Pigweed developers
64encountered an 11K struct statically allocated for a single message---over twice
65the size of the final encoded output! (This was what prompted the development of
66pw_protobuf.)
67
68To avoid this issue, it is possible to use nanopb's low-level encode/decode
69functions to process individual message fields directly, but this loses all of
70the useful semantics of code generation. pw_protobuf is designed to optimize for
71this use case; it allows for efficient operations on the wire format with an
72intuitive user interface.
73
74Depending on the requirements of a project, either of these libraries could be
75suitable.