 /// additional requirements, including serialization extensions.
 /// This is used directly by hand-coded message implementations.
 ///
-public protocol ProtobufMessage: ProtobufMessageBase, ProtobufBinaryMessageBase, ProtobufJSONMessageBase, CustomReflectable {
-}
-
-public protocol ProtobufAbstractMessage: ProtobufMessage, Hashable, ProtobufMapValueType {
-    func isEqualTo(other: Self) -> Bool
+public protocol ProtobufMessage:
+  ProtobufMessageBase, ProtobufBinaryMessageBase, ProtobufJSONMessageBase,
+  CustomReflectable {}
+
+public protocol ProtobufAbstractMessage:
+  ProtobufMessage, Hashable, ProtobufMapValueType {
+
+  func isEqualTo(other: Self) -> Bool
 }
 
 public extension ProtobufAbstractMessage {
-    static func isEqual(_ lhs: Self, _ rhs: Self) -> Bool {
-        return lhs == rhs
-    }
-
-    public init(any: Google_Protobuf_Any) throws {
-        self.init()
-        try any.unpackTo(target: &self)
-    }
+  static func isEqual(_ lhs: Self, _ rhs: Self) -> Bool {
+    return lhs == rhs
+  }
+
+  public init(any: Google_Protobuf_Any) throws {
+    self.init()
+    try any.unpackTo(target: &self)
+  }
 }
 
 public func ==<M: ProtobufAbstractMessage>(lhs: M, rhs: M) -> Bool {
-    return lhs.isEqualTo(other: rhs)
-}
-
-///
-/// Base type for Generated message types
-///
-/// This provides some basic indirection so end users can override
-/// generated methods.
+  return lhs.isEqualTo(other: rhs)
+}
+
+///
+/// Base type for generated message types.
+///
+/// This provides some basic indirection so end users can override generated
+/// methods.
 ///
 public protocol ProtobufGeneratedMessage: ProtobufAbstractMessage {
-    // The compiler actually generates the following methods.
-    // Default implementations below redirect the standard names.
-    // This allows developers to override the standard names to
-    // customize the behavior.
-    mutating func _protoc_generated_decodeField(setter: inout ProtobufFieldDecoder, protoFieldNumber: Int) throws -> Bool
-    func _protoc_generated_traverse(visitor: inout ProtobufVisitor) throws
-    func _protoc_generated_isEqualTo(other: Self) -> Bool
+  // The compiler actually generates the following methods. Default
+  // implementations below redirect the standard names. This allows developers
+  // to override the standard names to customize the behavior.
+  mutating func _protoc_generated_decodeField(
+    setter: inout ProtobufFieldDecoder,
+    protoFieldNumber: Int) throws -> Bool
+
+  func _protoc_generated_traverse(visitor: inout ProtobufVisitor) throws
+
+  func _protoc_generated_isEqualTo(other: Self) -> Bool
 }
 
 public extension ProtobufGeneratedMessage {
-    // Default implementations simply redirect to the generated versions.
-    public func traverse(visitor: inout ProtobufVisitor) throws {
-        try _protoc_generated_traverse(visitor: &visitor)
-    }
-
-    mutating func decodeField(setter: inout ProtobufFieldDecoder, protoFieldNumber: Int) throws -> Bool {
-        return try _protoc_generated_decodeField(setter: &setter, protoFieldNumber: protoFieldNumber)
-    }
-
-    func isEqualTo(other: Self) -> Bool {
-        return _protoc_generated_isEqualTo(other: other)
-    }
+  // Default implementations simply redirect to the generated versions.
+  public func traverse(visitor: inout ProtobufVisitor) throws {
+    try _protoc_generated_traverse(visitor: &visitor)
+  }
+
+  mutating func decodeField(setter: inout ProtobufFieldDecoder,
+                            protoFieldNumber: Int) throws -> Bool {
+    return try _protoc_generated_decodeField(setter: &setter,
+                                             protoFieldNumber: protoFieldNumber)
+  }
+
+  func isEqualTo(other: Self) -> Bool {
+    return _protoc_generated_isEqualTo(other: other)
+  }
 }
 
 // TODO: This is a transition aid, remove this in August 2016.

///

///
/// The core protocol implemented by all messages, whether generated
/// or hand-coded.
///
/// In particular, this has no associated types or self references
/// so can be used as a variable or argument type.
///
public protocol ProtobufMessageBase: CustomDebugStringConvertible, ProtobufTraversable {
    init()

    // Basic facts about this class and the proto message it was generated from
    // Used by various encoders and decoders
    var swiftClassName: String { get }
    var protoMessageName: String { get }
    var protoPackageName: String { get }
    var anyTypePrefix: String { get }
    var anyTypeURL: String { get }
    var jsonFieldNames: [String: Int] {get}
    var protoFieldNames: [String: Int] {get}

    /// Decode a field identified by a field number (as given in the .proto file).
    ///
    /// This is the core method used by the deserialization machinery.
    ///
    /// Note that this is not specific to protobuf encoding; formats
    /// that use textual identifiers translate those to protoFieldNumbers and
    /// then invoke this to decode the field value.
    mutating func decodeField(setter: inout ProtobufFieldDecoder, protoFieldNumber: Int) throws -> Bool

    // The corresponding serialization support is the traverse() method
    // declared in ProtobufTraversable

    // Decode from an Any (which might itself have been decoded from JSON,
    // protobuf, or another Any)
    init(any: Google_Protobuf_Any) throws

    /// Serialize as an Any object in JSON format
    /// For generated message types, this generates the same JSON object
    /// as serializeJSON() except it adds an additional `@type` field.
    func serializeAnyJSON() throws -> String

    // Standard utility properties and methods.
    // Most of these are simple wrappers on top of the visitor machinery.
    // They are implemented in the protocol, not in the generated structs,
    // so can be overridden in user code by defining custom extensions to
    // the generated struct.
    var hashValue: Int { get }
    var debugDescription: String { get }
    var customMirror: Mirror { get }
}

public extension ProtobufMessageBase {
    var hashValue: Int {return ProtobufHashVisitor(message: self).hashValue}

    var debugDescription: String {return ProtobufDebugDescriptionVisitor(message: self).description}

    var customMirror: Mirror {return ProtobufMirrorVisitor(message: self).mirror}

    // TODO:  Add an option to the generator to override this in particular messages.
    // TODO:  It would be nice if this could default to "" instead; that would save ~20
    // bytes on every serialized Any.
    var anyTypePrefix: String {return "type.googleapis.com"}

    var anyTypeURL: String {
        var url = anyTypePrefix
        if anyTypePrefix == "" || anyTypePrefix.characters.last! != "/" {
            url += "/"
        }
        if protoPackageName != "" {
            url += protoPackageName
            url += "."
        }
        url += protoMessageName
        return url
    }

    /// Creates an instance of the message type on which this method is called,
    /// executes the given block passing the message in as its sole `inout`
    /// argument, and then returns the message.
    ///
    /// This method acts essentially as a "builder" in that the initialization
    /// of the message is captured within the block, allowing the returned value
    /// to be set in an immutable variable. For example,
    ///
    ///     let msg = MyMessage.with { $0.myField = "foo" }
    ///     msg.myOtherField = 5  // error: msg is immutable
    ///
    /// - Parameter populator: A block or function that populates the new
    ///   message, which is passed into the block as an `inout` argument.
    /// - Returns: The message after execution of the block.
    public static func with(populator: (inout Self) -> ()) -> Self {
        var message = Self()
        populator(&message)
        return message
    }
}

///

/// by protoc implement ProtobufGeneratedMessageType, hand-coded messages often
/// implement ProtobufAbstractMessage.  The protocol heirarchy here is
/// a little involved due to the variety of requirements and the need to
/// mix in JSON and binary support (see ProtobufBinaryTypes and
/// ProtobufJSONTypes for extensions that support binary and JSON coding).
///
// -----------------------------------------------------------------------------

