Decoder

Abstract protocol used by the generated code to deserialize data.

Decoder.swift:57
protocol Decoder
Browse conforming types

The generated code looks roughly like this:

  while fieldNumber = try decoder.nextFieldNumber() {
     switch fieldNumber {
     case 1: decoder.decodeRepeatedInt32Field(value: &_field)
     ... etc ...
  }

In particular, note that the decoder must provide field numbers corresponding to the numbers in the original proto file. For formats such as Protobuf Binary format that encode field numbers directly, this is trivial. Decoders for formats such as Protobuf Text Format or JSON must use auxiliary information attached to the message type to translate string field names to field numbers.

For performance, the field decoding provides three separate methods for every primitive type:

  • Repeated support accepts an inout Array for repeated fields

  • Singular support that accepts an inout Optional, for proto2

  • Singular support that accepts an inout non-Optional, for proto3

Note that we don’t distinguish “packed” here, since all existing decoders treat “packed” the same as “repeated” at this level. (That is, even when the serializer distinguishes packed and non-packed forms, the deserializer always accepts both.)

Generics come into play at only a few points: Enums and Messages use a generic type to locate the correct initializer. Maps and extensions use generics to avoid the method explosion of having to support a separate method for every map and extension type. Maps do distinguish Enum-valued and Message-valued maps to avoid polluting the generated Enum and Message types with all of the necessary generic methods to support this.