     // 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.
      *

        return enumValue
    }

    /** Decode an integer field */
    public func decode<T: ProtoIntDecodable>(_ type: T.Type, encoding: ProtoIntEncoding = .variable) throws -> T {
        return try T(from: self, encoding: encoding)
    }

    /** Decode a field which has a single encoding mechanism, like messages, strings, and bytes. */
    public func decode<T: ProtoDecodable>(_ type: T.Type) throws -> T {
        return try T(from: self)
    }

        }
    }

    /** Decode a repeated `int32` field */
    public func decode(into array: inout [Int32], encoding: ProtoIntEncoding = .variable) throws {
        try decode(into: &array) {
            return try Int32(from: self, encoding: encoding)
        }
    }

    /** Decode a repeated `int64` field */
    public func decode(into array: inout [Int64], encoding: ProtoIntEncoding = .variable) throws {
        try decode(into: &array) {
            return try Int64(from: self, encoding: encoding)
        }
    }

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

    /** Decode a repeated `uint32` field */
    public func decode(into array: inout [UInt32], encoding: ProtoIntEncoding = .variable) throws {
        try decode(into: &array) {
            return try UInt32(from: self, encoding: encoding)
        }
    }

    /** Decode a repeated `uint64` field */
    public func decode(into array: inout [UInt64], encoding: ProtoIntEncoding = .variable) throws {
        try decode(into: &array) {
            return try UInt64(from: self, encoding: encoding)
        }
    }

    /** Decode a repeated message field. */
    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))
