     // MARK: - Private Methods - Message Decoding
 
     /**
+     Decode an integer field.
+     This method is used in map decoding. For single and repeated integer field decoding
+     there are distinct implementations to avoid the performance cost of virtual function resolution.
+     */
+    private func decode<T: ProtoIntDecodable>(_ type: T.Type, encoding: ProtoIntEncoding = .variable) throws -> T {
+        return try T(from: self, encoding: encoding)
+    }
+
+    /**
      * Begin a nested message. A call to this method will restrict the reader so that [nextTag]
      * returns nil when the message is complete.
      *

        }
    }

    /** Decode a repeated integer field */
    public func decode<T: ProtoIntDecodable>(into array: inout [T], encoding: ProtoIntEncoding = .variable) throws {
        try decode(into: &array) {
            return try T(from: self, encoding: encoding)
        }
    }

    /** Decode a repeated field which has a single encoding mechanism, like messages, strings, and bytes. */
    public func decode<T: ProtoDecodable>(into array: inout [T]) throws {
        // These types do not support packing, so no need to test for it.
        try array.append(T(from: self))

        try decode(into: &array) {
            return try Bool(from: self)
        }
    }

    /** Decode a repeated `bytes` field */
    public func decode(into array: inout [Data]) throws {
        // Data fields do not support packing, so no need to test for it.
        try array.append(Data(from: self))
    }

    /**
