/*
 * DO NOT EDIT.
 *
 * Generated by the protocol buffer compiler.
 * Source: tensorflow/core/framework/graph.proto
 *
 */

import Foundation
import SwiftProtobuf


///   Represents the graph of operations
public struct Tensorflow_GraphDef: ProtobufGeneratedMessage {
  public var swiftClassName: String {return "Tensorflow_GraphDef"}
  public var protoMessageName: String {return "GraphDef"}
  public var protoPackageName: String {return "tensorflow"}
  public var jsonFieldNames: [String: Int] {return [
    "node": 1,
    "versions": 4,
    "version": 3,
    "library": 2,
  ]}
  public var protoFieldNames: [String: Int] {return [
    "node": 1,
    "versions": 4,
    "version": 3,
    "library": 2,
  ]}

  private class _StorageClass {
    typealias ProtobufExtendedMessage = Tensorflow_GraphDef
    var _node: [Tensorflow_NodeDef] = []
    var _versions: Tensorflow_VersionDef? = nil
    var _version: Int32 = 0
    var _library: Tensorflow_FunctionDefLibrary? = nil

    init() {}

    func decodeField(setter: inout ProtobufFieldDecoder, protoFieldNumber: Int) throws -> Bool {
      let handled: Bool
      switch protoFieldNumber {
      case 1: handled = try setter.decodeRepeatedMessageField(fieldType: Tensorflow_NodeDef.self, value: &_node)
      case 4: handled = try setter.decodeSingularMessageField(fieldType: Tensorflow_VersionDef.self, value: &_versions)
      case 3: handled = try setter.decodeSingularField(fieldType: ProtobufInt32.self, value: &_version)
      case 2: handled = try setter.decodeSingularMessageField(fieldType: Tensorflow_FunctionDefLibrary.self, value: &_library)
      default:
        handled = false
      }
      return handled
    }

    func traverse(visitor: inout ProtobufVisitor) throws {
      if !_node.isEmpty {
        try visitor.visitRepeatedMessageField(value: _node, protoFieldNumber: 1, protoFieldName: "node", jsonFieldName: "node", swiftFieldName: "node")
      }
      if let v = _library {
        try visitor.visitSingularMessageField(value: v, protoFieldNumber: 2, protoFieldName: "library", jsonFieldName: "library", swiftFieldName: "library")
      }
      if _version != 0 {
        try visitor.visitSingularField(fieldType: ProtobufInt32.self, value: _version, protoFieldNumber: 3, protoFieldName: "version", jsonFieldName: "version", swiftFieldName: "version")
      }
      if let v = _versions {
        try visitor.visitSingularMessageField(value: v, protoFieldNumber: 4, protoFieldName: "versions", jsonFieldName: "versions", swiftFieldName: "versions")
      }
    }

    var isEmpty: Bool {
      if !_node.isEmpty {return false}
      if _versions != nil {return false}
      if _version != 0 {return false}
      if _library != nil {return false}
      return true
    }

    func isEqualTo(other: _StorageClass) -> Bool {
      if _node != other._node {return false}
      if _versions != other._versions {return false}
      if _version != other._version {return false}
      if _library != other._library {return false}
      return true
    }

    func copy() -> _StorageClass {
      let clone = _StorageClass()
      clone._node = _node
      clone._versions = _versions
      clone._version = _version
      clone._library = _library
      return clone
    }
  }

  private var _storage: _StorageClass?

  public var node: [Tensorflow_NodeDef] {
    get {return _storage?._node ?? []}
    set {_uniqueStorage()._node = newValue}
  }

  ///   Compatibility versions of the graph.  See core/public/version.h for version
  ///   history.  The GraphDef version is distinct from the TensorFlow version, and
  ///   each release of TensorFlow will support a range of GraphDef versions.
  public var versions: Tensorflow_VersionDef {
    get {return _storage?._versions ?? Tensorflow_VersionDef()}
    set {_uniqueStorage()._versions = newValue}
  }

  ///   Deprecated single version field; use versions above instead.  Since all
  ///   GraphDef changes before "versions" was introduced were forward
  ///   compatible, this field is entirely ignored.
  public var version: Int32 {
    get {return _storage?._version ?? 0}
    set {_uniqueStorage()._version = newValue}
  }

  ///   EXPERIMENTAL. DO NOT USE OR DEPEND ON THIS YET.
  ///  
  ///   "library" provides user-defined functions.
  ///  
  ///   Naming:
  ///     * library.function.name are in a flat namespace.
  ///       NOTE: We may need to change it to be hierarchical to support
  ///       different orgs. E.g.,
  ///       { "/google/nn", { ... }},
  ///       { "/google/vision", { ... }}
  ///       { "/org_foo/module_bar", { ... }}
  ///       map<string, FunctionDefLib> named_lib;
  ///     * If node[i].op is the name of one function in "library",
  ///       node[i] is deemed as a function call. Otherwise, node[i].op
  ///       must be a primitive operation supported by the runtime.
  ///  
  ///  
  ///   Function call semantics:
  ///  
  ///     * The callee may start execution as soon as some of its inputs
  ///       are ready. The caller may want to use Tuple() mechanism to
  ///       ensure all inputs are ready in the same time.
  ///  
  ///     * The consumer of return values may start executing as soon as
  ///       the return values the consumer depends on are ready.  The
  ///       consumer may want to use Tuple() mechanism to ensure the
  ///       consumer does not start until all return values of the callee
  ///       function are ready.
  public var library: Tensorflow_FunctionDefLibrary {
    get {return _storage?._library ?? Tensorflow_FunctionDefLibrary()}
    set {_uniqueStorage()._library = newValue}
  }

  public init() {}

  public init(node: [Tensorflow_NodeDef] = [],
    versions: Tensorflow_VersionDef? = nil,
    version: Int32? = nil,
    library: Tensorflow_FunctionDefLibrary? = nil)
  {
    let storage = _uniqueStorage()
    if !node.isEmpty {
      storage._node = node
    }
    storage._versions = versions
    if let v = version {
      storage._version = v
    }
    storage._library = library
  }

  public mutating func _protoc_generated_decodeField(setter: inout ProtobufFieldDecoder, protoFieldNumber: Int) throws -> Bool {
    return try _uniqueStorage().decodeField(setter: &setter, protoFieldNumber: protoFieldNumber)
  }

  public func _protoc_generated_traverse(visitor: inout ProtobufVisitor) throws {
    try _storage?.traverse(visitor: &visitor)
  }

  public var _protoc_generated_isEmpty: Bool {return _storage?.isEmpty ?? true}

  public func _protoc_generated_isEqualTo(other: Tensorflow_GraphDef) -> Bool {
    if let s = _storage {
      if let os = other._storage {
        return s === os || s.isEqualTo(other: os)
      }
      return isEmpty // empty storage == nil storage
    } else if let os = other._storage {
      return os.isEmpty // nil storage == empty storage
    }
    return true // Both nil, both empty
  }

  private mutating func _uniqueStorage() -> _StorageClass {
    if _storage == nil {
      _storage = _StorageClass()
    } else if !isKnownUniquelyReferenced(&_storage) {
      _storage = _storage!.copy()
    }
    return _storage!
  }
}
