1.6 Alternation, Aggregation, Encapsulation, and Enumeration
AllApplicationManualNameSummaryHelp

  • Documentation
    • Reference manual
    • Packages
      • Google's Protocol Buffers Library
        • Google's Protocol Buffers
          • Alternation, Aggregation, Encapsulation, and Enumeration
            • Alternation
            • Aggregation
            • Encapsulation and Enumeration
            • Heterogeneous Collections

1.6.3 Encapsulation and Enumeration

It is possible to embed one protocol buffer specification inside another using the embedded term. The following example shows a vector of numbers being placed in an envelope that contains a command enumeration.

Enumerations are a compact method of sending tokens from one system to another. Most occupy only two bytes in the wire-stream. An enumeration requires that you specify a callable predicate like commands/2, below. The first argument is an atom specifying the name of token, and the second is an non-negative integer that specifies the token's value. These must of course, match a corresponding enumeration in the .proto file.

Note: You must expose this predicate to the protobufs module by assigning it explicitly.


protobufs:commands(Key, Value) :-
        commands(Key, Value).

commands(square, 1).
commands(decimate, 2).
commands(transform, 3).
commands(inverse_transform, 4).

basic_vector(Type, Proto) :-
        vector_type(Type, Tag),

        Proto = protobuf([ repeated(Tag, Type) ]).

send_command(Command, Vector, Msg) :-

        basic_vector(Vector, Proto1),

        Proto = protobuf([enum(1, commands(Command)),
                          embedded(2, Proto1)]),

        protobuf_message(Proto, Msg).

Use it as follows:

?- send_command(square, double([1,22,3,4]), Msg).
Msg = [8, 1, 18, 36, 17, 0, 0, 0, 0, 0, 0, 240, 63, 17, 0, 0, 0, 0, 0,
0, 54, 64, 17, 0, 0, 0, 0, 0, 0, 8, 64, 17, 0, 0, 0, 0, 0, 0, 16, 64].

?- send_command(Cmd, V, $Msg).
Cmd = square,
V = double([1.0, 22.0, 3.0, 4.0]) .

Compatibility Note: The protobuf grammar (protobuf-2.1.0) permits enumerations to assume negative values. This requires them to be encoded as integers. But Google's own Golden Message unit-test framework has enumerations encoded as unsigned. Consequently, parsers that encode them as integers cannot properly parse the Golden Message. So it's probably a good idea to avoid negative values in enumerations. Our parser forbids it anyway.