1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
# Bootstrap for the protoc plugin
## Installing protobuf (on Ubuntu)
You can use the Ubuntu package `protobuf-compiler`, but it's dated
Jul 31, 2018. Instead, you can clone from
https://github.com/protocolbuffers/protobuf and build using the
instructions in `protobuf/src/README.md`. For the `./configure`
command you may wish to use `./configure --prefix=$HOME/.local` and
`make -j4` (where "4" should be replaced by the number of cores on
your machine).
There are some additional notes on this in the `Makefile`.
TODO: These notes reflect an older stage of the bootstrap process.
Both the notes and the Makefile need to be cleaned up, to remove
stuff that's no longer needed.
## Overview of the original bootstrap process
The original bootstrap was done by using `protoc --decode` to get the
".wiredump" files (in `gen_pb/google/protobuf/**`).
These were then parsed by a simple DCG in
`parse_descriptor_proto_dump.pl` to produce the ".proto.parse"
files. The term expansion logic is in `descriptor_proto_expand.pl`,
which was then copied to `protoc-gen-swipl`. At this point,
`gen_pb/google/protobuf/descriptor_pb.pl` and
`gen_pb/google/protobuf/compiler/plugin_pb.pl` could be
generated, and the original bootstrap code no longer needed.
The tests are fairly minimal. For proper testing, see directory `interop`.
## descriptor.proto and friends
Naming conventions:
| x.proto | protobuf definition: used as input to protoc |
| x.wire | wire-format encoding of data (e.g., produced by SerializeToString()) |
| x.proto.wire | `protoc --descriptor_set_out=x.proto.wire` |
| x_pb2.py | generated by protoc from x.proto (for Python) |
| x.pb.{h,cc} | generated by protoc from x.proto (for C++) |
| x.wiredump | readable form of x.wire, using `protoc --decode` and the appropriate .proto file |
| x.wirerawdump | readable from of x.wire, using `protoc --decode_raw` (no .proto file) |
| x.segment | Prolog term that contains a segmentation of the data in a .wire file (see also x.wiredump) |
| descriptor.proto.parse | Output from `parse_descriptor_proto_dump.pl`, which is hand-edited into `descriptor_proto.pl` (`descriptor_proto/1`). |
`plugin.proto` and `descriptor.proto` encode all `.proto` files created by
the protobuf compiler (`protoc`). Their meta-data have been bootstrapped into
`gen_pb/plugin_pb.pl` and
`gen_pb/descriptor_pb.pl`.
* `descriptor.proto.wire` contains a protobuf encoding of
`descriptor.proto`; it was generated by
`protoc --descriptor_set_out=descriptor.proto.wire`
* `descriptor.proto.wiredump` is generated by `protoc
--decode=FileDescriptorSet descriptor.proto.wire`
It is included here, to avoid a submodule dependency on
git@github.com:protocolbuffers/protobuf.git
* `parse_descriptor_proto_dump.pl` is used to process `descriptor.proto.wiredump`
into a Prolog term.
* `descriptor_proto.pl` is the term created by `parse_descriptor_proto_dump.pl`,
in the clause `descriptor_proto/1`.
* `descriptor.proto.segment` is the "golden" output from rule `descriptor.segment`.
TODO: delete this file.
TODO: use `protobuf\_segment\_message/2` to process
`descriptor.proto.wire` and any other `descriptor\_set\_out`, and then
generate Prolog code for easy handling of protobufs.
## protoc plugin
We can create a plugin by having an executable named `protoc-gen-swipl`
that is in the `PATH`, which reads a `CodeGeneratorRequest` from stdin
(defined in `src/protobuf/src/google/protobuf/compiler/plugin.proto`)
and outputs to stdout a `CodeGeneratorResponse` ... to get this
plugin, use `protoc --swipl_out=DIR`.
If you make an incompatible change to `protoc-gen-swipl`, you should
increment the version and also `protobufs:verify_version/0`. (Also
`descriptor_proto.pl`, which is mostly obsolete.)
See also
[https://chromium.googlesource.com/external/github.com/protocolbuffers/protobuf/+/refs/heads/master/docs/implementing_proto3_presence.md](How To Implement Field Presence for Proto3).
|