Compiler and Runtime
In order to use Protobuf format, we need three things:
- The source
.proto
files. - A compiler that compiles the source files.
- A runtime that loads the compiled files.
Compiler
There is a
main compiler that can
compile .proto
files into Python
, Go
, Rust
, C#
, Java
and C++
. Once
installed its command is protoc
.
For JavaScript
, we have two options:
-
- This is the official way.
- Requires a build of the
protoc
source, with some modifications so theprotoc
command will become capable of compiling into JavaScript output. - Once installed its command is the same
protoc
as before but with a new--js-out
option available.
-
- This is a 3rd-party package.
- Requires no extra step.
- Once installed, its command is
pbjs
.
We will move forward with the option 2, mainly because it's simpler and requires less explanation.
Install Main Compiler
- Windows
- Linux
winget install protobuf
protoc --version # libprotoc 31.1
- Go to "Releases" page of the compiler's Github repository.
- Under "Assets", download the
protoc-31.1-win64.zip
file. - Extract the zip file into for example the
C:\protoc-31.1-win64
directory. - Add the path to the extracted files to your computer's path variable.
- Press
win + r
keys. - Type
rundll32.exe sysdm.cpl,EditEnvironmentVariables
- Under
User Variables
, selectPath
and clickEdit
button, and in opened form clickAdd
. - Put
C:\protoc-31.1-win64\bin
, and clickOK
, and anotherOK
.
- Press
apt install protobuf-compiler -y
protoc --version # libprotoc 31.1
Download the distribution matching your operating system from the compiler's repo and add it to path.
cd ~
wget https://github.com/protocolbuffers/protobuf/releases/download/v31.1/protoc-31.1-linux-x86_64.zip
unzip protoc-31.1-linux-x86_64.zip -d protoc
sudo chmod a+x ~/protoc/bin/protoc
nano .profile # in opened editor, add below line, save and exit
export PATH="$PATH:$HOME/protoc/bin/"
source .profile
Install JavaScript-Specific Compiler
npm install protobufjs -g
pbjs
Runtime
To load and use the compiled files in our code, we need to install the Protobuf runtime in our programming language environment, which is in the form of a library or package.
- JavaScript
- Python
npm i protobufjs
pbjs # to check version
# protobuf.js v1.1.3 CLI for JavaScript
# ...
pip install protobuf
pip show protobuf # to check version
# Version: 6.31.1 ...
# ...
Compiler and Runtime Versions
When working with Protobuf, there is a concept called Cross-Version Runtime. It simply means you cannot just use any version of the compiler with any version of the runtime willغ-nilly. The output of the compiler is called "Generated Code" or GenCode for short. The runtime has to be able to load this GenCode.
The compiler and the runtime have their own versions. You can think of the compiler as the one who writes some things, and the runtime as the one that has to read what's been written. Now imagine the writer in a newer version, writes in a way that only the reader of the same version can understand it.
Here is the officiall recommandation of the Protobuf itself. Altough you can get away with a new runtime and old GenCode, The simplest approach is to match both of their versions to a specific publish date. The below Node.js scripts shows how to find proper compiler version for a runtime.
// `protoc`
url =
'https://api.github.com/repos/protocolbuffers/protobuf/releases?per_page=100&page=1';
r = await (await fetch(url)).json();
a = r.map((i) => [i.tag_name, i.published_at]);
// `protobuf` pypi pkg
url = 'https://pypi.org/pypi/protobuf/json';
r = await (await fetch(url)).json();
b = Object.keys(r.releases).map((k) => [k, r.releases[k][0].upload_time]);
// find out proper compiler version for `protobuf` pypi pkg 3.20.1 (for example)
b.find((i) => i[0] === '3.20.1'); // ['3.20.1', '2022-04-22T02:03:01'] py pkg ver
a.find((i) => i[1].includes('2022-04')); // ['v3.20.1', '2022-04-22T02:27:33Z'] proper compiler ver
How to Check If Your Runtime is Ok with GenCode
In the Python case, you should compile your .proto
files, and then try to
import them in a script (that's it, just import them and nothing else), then try
to run the script. If there exists a version mismatch, you will see proper
warnings that say as such. If you don't see any warning, that means you have
done everything correctly.