Why you ask? One word: OOP.
There is one main component with the read write code, which is the main part of PB. Then every message has to have its own memory (a record or a class), and needs to uniquely get its data onto and off the wire. With OOP, we have one generic read write, that any sub class inherits from and uses that generic read / write. Furthermore, there is a lot of nested messages in nested messages in messages in PB, and often in different mixed up combinations. This lends itself to classes and inheritance.
Doing this approach, we have two files total, and that is for hundreds of proto messages. :-)
You don't like classes? A class is just a record with a handful of functions and some tables of pointers attached, and automated memory allocations. Not really that terrible.
If instead the messages were all stand alone records, then each message record needs its own read write code. I started out this way, but it became an unmanageable mess when hundreds of .proto files are involved.
Speaking of messes. The Google C++ supplied code requires / has hundreds of files compiled into the project, and this is a fine example of coding by committee. It adds MB's to the project. This is fine when server A talks to server B, but not for user applications. No, we will not be using the Google system as an example, thank you.