protobuf_segment_message(+Segments:list, -WireStream:list(int)) is det[private]
protobuf_segment_message(-Segments:list, +WireStream:list(int)) is det[private]
Low level marshalling and unmarshalling of byte streams. The processing is independent of the .proto description, similar to the processing done by protoc --decode_raw. This means that field names aren't shown, only field numbers.

For unmarshalling, a simple heuristic is used on length-delimited segments: first interpret it as a message; if that fails, try to interpret as a UTF8 string; otherwise, leave it as a "blob" (if the heuristic was wrong, you can convert to a string or a blob by using protobuf_segment_convert/2). 32-bit and 64-bit numbers are left as codes because they could be either integers or floating point (use int32_codes_when/2, float32_codes_when/2, int64_codes_when/2, uint32_codes_when/2, uint64_codes_when/2, float64_codes_when/2 as appropriate); variable-length numbers ("varint" in the Protocol Buffers encoding documentation), might require "zigzag" conversion, int64_zigzag_when/2.

For marshalling, use the predicates int32_codes_when/2, float32_codes_when/2, int64_codes_when/2, uint32_codes_when/2, uint64_codes_when/2, float64_codes_when/2, int64_zigzag_when/2 to put integer and floating point values into the appropriate form.

Segments- a list containing terms of the following form (Tag is the field number; Codes is a list of integers):
  • varint(Tag,Varint) - Varint may need int64_zigzag_when/2
  • fixed64(Tag,Int) - Int signed, derived from the 8 codes
  • fixed32(Tag,Codes) - Int is signed, derived from the 4 codes
  • message(Tag,Segments)
  • group(Tag,Segments)
  • string(Tag,String) - String is a SWI-Prolog string
  • packed(Tag,Type(Scalars)) - Type is one of varint, fixed64, fixed32; Scalars is a list of Varint or Codes, which should be interpreted as described under those items. Note that the protobuf specification does not allow packed repeated string.
  • length_delimited(Tag,Codes)
  • repeated(List) - List of segments

Of these, group is deprecated in the protobuf documentation and shouldn't appear in modern code, having been superseded by nested message types.

For deciding how to interpret a length-delimited item (when Segments is a variable), an attempt is made to parse the item in the following order (although code should not rely on this order):

  • message
  • string (it must be in the form of a UTF string)
  • packed (which can backtrack through the various Types)
  • length_delimited - which always is possible.

The interpretation of length-delimited items can sometimes guess wrong; the interpretation can be undone by either backtracking or by using protobuf_segment_convert/2 to convert the incorrect segment to a string or a list of codes. Backtracking through all the possibilities is not recommended, because of combinatoric explosion (there is an example in the unit tests); instead, it is suggested that you take the first result and iterate through its items, calling protobuf_segment_convert/2 as needed to reinterpret incorrectly guessed segments.

WireStream- a code list that was generated by a protobuf endoder.
See also
- This predicate is preliminary and may change as additional functionality is added.