// DO NOT EDIT.
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: github.com/googleapis/gnostic/OpenAPIv3/OpenAPIv3.proto
//
// For information on using the generated types, please see the documenation:
//   https://github.com/apple/swift-protobuf/

// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//    http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// THIS FILE IS AUTOMATICALLY GENERATED.

import Foundation
import SwiftProtobuf

// If the compiler emits an error on this type, it is because this file
// was generated by a version of the `protoc` Swift plug-in that is
// incompatible with the version of SwiftProtobuf to which you are linking.
// Please ensure that your are building against the same version of the API
// that was used to generate this file.
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
  struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
  typealias Version = _2
}

public struct Openapi_V3_AdditionalPropertiesItem: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".AdditionalPropertiesItem"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var schemaOrReference: Openapi_V3_SchemaOrReference {
    get {
      if case .schemaOrReference(let v)? = _storage._oneof {return v}
      return Openapi_V3_SchemaOrReference()
    }
    set {_uniqueStorage()._oneof = .schemaOrReference(newValue)}
  }

  public var boolean: Bool {
    get {
      if case .boolean(let v)? = _storage._oneof {return v}
      return false
    }
    set {_uniqueStorage()._oneof = .boolean(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case schemaOrReference(Openapi_V3_SchemaOrReference)
    case boolean(Bool)

    public static func ==(lhs: Openapi_V3_AdditionalPropertiesItem.OneOf_Oneof, rhs: Openapi_V3_AdditionalPropertiesItem.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.schemaOrReference(let l), .schemaOrReference(let r)): return l == r
      case (.boolean(let l), .boolean(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_SchemaOrReference?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .schemaOrReference(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .schemaOrReference(v)}
        case 2:
          if _storage._oneof != nil {try decoder.handleConflictingOneOf()}
          var v: Bool?
          try decoder.decodeSingularBoolField(value: &v)
          if let v = v {_storage._oneof = .boolean(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .schemaOrReference(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .boolean(let v)?:
        try visitor.visitSingularBoolField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_Any: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Any"

  public var value: SwiftProtobuf.Google_Protobuf_Any {
    get {return _storage._value ?? SwiftProtobuf.Google_Protobuf_Any()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var yaml: String {
    get {return _storage._yaml}
    set {_uniqueStorage()._yaml = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularMessageField(value: &_storage._value)
        case 2: try decoder.decodeSingularStringField(value: &_storage._yaml)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      }
      if !_storage._yaml.isEmpty {
        try visitor.visitSingularStringField(value: _storage._yaml, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_AnyOrExpression: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".AnyOrExpression"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var any: Openapi_V3_Any {
    get {
      if case .any(let v)? = _storage._oneof {return v}
      return Openapi_V3_Any()
    }
    set {_uniqueStorage()._oneof = .any(newValue)}
  }

  public var expression: Openapi_V3_Expression {
    get {
      if case .expression(let v)? = _storage._oneof {return v}
      return Openapi_V3_Expression()
    }
    set {_uniqueStorage()._oneof = .expression(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case any(Openapi_V3_Any)
    case expression(Openapi_V3_Expression)

    public static func ==(lhs: Openapi_V3_AnyOrExpression.OneOf_Oneof, rhs: Openapi_V3_AnyOrExpression.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.any(let l), .any(let r)): return l == r
      case (.expression(let l), .expression(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_Any?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .any(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .any(v)}
        case 2:
          var v: Openapi_V3_Expression?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .expression(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .expression(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .any(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .expression(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_AnysOrExpressions: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".AnysOrExpressions"

  public var additionalProperties: [Openapi_V3_NamedAnyOrExpression] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// A map of possible out-of band callbacks related to the parent operation. Each value in the map is a Path Item Object that describes a set of requests that may be initiated by the API provider and the expected responses. The key value used to identify the callback object is an expression, evaluated at runtime, that identifies a URL to use for the callback operation.
public struct Openapi_V3_Callback: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Callback"

  public var path: [Openapi_V3_NamedPathItem] = []

  public var specificationExtension: [Openapi_V3_NamedAny] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.path)
      case 2: try decoder.decodeRepeatedMessageField(value: &self.specificationExtension)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.path.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.path, fieldNumber: 1)
    }
    if !self.specificationExtension.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.specificationExtension, fieldNumber: 2)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

public struct Openapi_V3_CallbackOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".CallbackOrReference"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var callback: Openapi_V3_Callback {
    get {
      if case .callback(let v)? = _storage._oneof {return v}
      return Openapi_V3_Callback()
    }
    set {_uniqueStorage()._oneof = .callback(newValue)}
  }

  public var reference: Openapi_V3_Reference {
    get {
      if case .reference(let v)? = _storage._oneof {return v}
      return Openapi_V3_Reference()
    }
    set {_uniqueStorage()._oneof = .reference(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case callback(Openapi_V3_Callback)
    case reference(Openapi_V3_Reference)

    public static func ==(lhs: Openapi_V3_CallbackOrReference.OneOf_Oneof, rhs: Openapi_V3_CallbackOrReference.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.callback(let l), .callback(let r)): return l == r
      case (.reference(let l), .reference(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_Callback?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .callback(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .callback(v)}
        case 2:
          var v: Openapi_V3_Reference?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .reference(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .reference(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .callback(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .reference(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_CallbacksOrReferences: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".CallbacksOrReferences"

  public var additionalProperties: [Openapi_V3_NamedCallbackOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Holds a set of reusable objects for different aspects of the OAS. All objects defined within the components object will have no effect on the API unless they are explicitly referenced from properties outside the components object.
public struct Openapi_V3_Components: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Components"

  public var schemas: Openapi_V3_SchemasOrReferences {
    get {return _storage._schemas ?? Openapi_V3_SchemasOrReferences()}
    set {_uniqueStorage()._schemas = newValue}
  }
  /// Returns true if `schemas` has been explicitly set.
  public var hasSchemas: Bool {return _storage._schemas != nil}
  /// Clears the value of `schemas`. Subsequent reads from it will return its default value.
  public mutating func clearSchemas() {_storage._schemas = nil}

  public var responses: Openapi_V3_ResponsesOrReferences {
    get {return _storage._responses ?? Openapi_V3_ResponsesOrReferences()}
    set {_uniqueStorage()._responses = newValue}
  }
  /// Returns true if `responses` has been explicitly set.
  public var hasResponses: Bool {return _storage._responses != nil}
  /// Clears the value of `responses`. Subsequent reads from it will return its default value.
  public mutating func clearResponses() {_storage._responses = nil}

  public var parameters: Openapi_V3_ParametersOrReferences {
    get {return _storage._parameters ?? Openapi_V3_ParametersOrReferences()}
    set {_uniqueStorage()._parameters = newValue}
  }
  /// Returns true if `parameters` has been explicitly set.
  public var hasParameters: Bool {return _storage._parameters != nil}
  /// Clears the value of `parameters`. Subsequent reads from it will return its default value.
  public mutating func clearParameters() {_storage._parameters = nil}

  public var examples: Openapi_V3_ExamplesOrReferences {
    get {return _storage._examples ?? Openapi_V3_ExamplesOrReferences()}
    set {_uniqueStorage()._examples = newValue}
  }
  /// Returns true if `examples` has been explicitly set.
  public var hasExamples: Bool {return _storage._examples != nil}
  /// Clears the value of `examples`. Subsequent reads from it will return its default value.
  public mutating func clearExamples() {_storage._examples = nil}

  public var requestBodies: Openapi_V3_RequestBodiesOrReferences {
    get {return _storage._requestBodies ?? Openapi_V3_RequestBodiesOrReferences()}
    set {_uniqueStorage()._requestBodies = newValue}
  }
  /// Returns true if `requestBodies` has been explicitly set.
  public var hasRequestBodies: Bool {return _storage._requestBodies != nil}
  /// Clears the value of `requestBodies`. Subsequent reads from it will return its default value.
  public mutating func clearRequestBodies() {_storage._requestBodies = nil}

  public var headers: Openapi_V3_HeadersOrReferences {
    get {return _storage._headers ?? Openapi_V3_HeadersOrReferences()}
    set {_uniqueStorage()._headers = newValue}
  }
  /// Returns true if `headers` has been explicitly set.
  public var hasHeaders: Bool {return _storage._headers != nil}
  /// Clears the value of `headers`. Subsequent reads from it will return its default value.
  public mutating func clearHeaders() {_storage._headers = nil}

  public var securitySchemes: Openapi_V3_SecuritySchemesOrReferences {
    get {return _storage._securitySchemes ?? Openapi_V3_SecuritySchemesOrReferences()}
    set {_uniqueStorage()._securitySchemes = newValue}
  }
  /// Returns true if `securitySchemes` has been explicitly set.
  public var hasSecuritySchemes: Bool {return _storage._securitySchemes != nil}
  /// Clears the value of `securitySchemes`. Subsequent reads from it will return its default value.
  public mutating func clearSecuritySchemes() {_storage._securitySchemes = nil}

  public var links: Openapi_V3_LinksOrReferences {
    get {return _storage._links ?? Openapi_V3_LinksOrReferences()}
    set {_uniqueStorage()._links = newValue}
  }
  /// Returns true if `links` has been explicitly set.
  public var hasLinks: Bool {return _storage._links != nil}
  /// Clears the value of `links`. Subsequent reads from it will return its default value.
  public mutating func clearLinks() {_storage._links = nil}

  public var callbacks: Openapi_V3_CallbacksOrReferences {
    get {return _storage._callbacks ?? Openapi_V3_CallbacksOrReferences()}
    set {_uniqueStorage()._callbacks = newValue}
  }
  /// Returns true if `callbacks` has been explicitly set.
  public var hasCallbacks: Bool {return _storage._callbacks != nil}
  /// Clears the value of `callbacks`. Subsequent reads from it will return its default value.
  public mutating func clearCallbacks() {_storage._callbacks = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularMessageField(value: &_storage._schemas)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._responses)
        case 3: try decoder.decodeSingularMessageField(value: &_storage._parameters)
        case 4: try decoder.decodeSingularMessageField(value: &_storage._examples)
        case 5: try decoder.decodeSingularMessageField(value: &_storage._requestBodies)
        case 6: try decoder.decodeSingularMessageField(value: &_storage._headers)
        case 7: try decoder.decodeSingularMessageField(value: &_storage._securitySchemes)
        case 8: try decoder.decodeSingularMessageField(value: &_storage._links)
        case 9: try decoder.decodeSingularMessageField(value: &_storage._callbacks)
        case 10: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if let v = _storage._schemas {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      }
      if let v = _storage._responses {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
      if let v = _storage._parameters {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
      }
      if let v = _storage._examples {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
      }
      if let v = _storage._requestBodies {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
      }
      if let v = _storage._headers {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 6)
      }
      if let v = _storage._securitySchemes {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 7)
      }
      if let v = _storage._links {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 8)
      }
      if let v = _storage._callbacks {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 9)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 10)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Contact information for the exposed API.
public struct Openapi_V3_Contact: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Contact"

  public var name: String = String()

  public var url: String = String()

  public var email: String = String()

  public var specificationExtension: [Openapi_V3_NamedAny] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeSingularStringField(value: &self.name)
      case 2: try decoder.decodeSingularStringField(value: &self.url)
      case 3: try decoder.decodeSingularStringField(value: &self.email)
      case 4: try decoder.decodeRepeatedMessageField(value: &self.specificationExtension)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.name.isEmpty {
      try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
    }
    if !self.url.isEmpty {
      try visitor.visitSingularStringField(value: self.url, fieldNumber: 2)
    }
    if !self.email.isEmpty {
      try visitor.visitSingularStringField(value: self.email, fieldNumber: 3)
    }
    if !self.specificationExtension.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.specificationExtension, fieldNumber: 4)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

public struct Openapi_V3_DefaultType: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".DefaultType"

  public var oneof: Openapi_V3_DefaultType.OneOf_Oneof? = nil

  public var number: Double {
    get {
      if case .number(let v)? = oneof {return v}
      return 0
    }
    set {oneof = .number(newValue)}
  }

  public var boolean: Bool {
    get {
      if case .boolean(let v)? = oneof {return v}
      return false
    }
    set {oneof = .boolean(newValue)}
  }

  public var string: String {
    get {
      if case .string(let v)? = oneof {return v}
      return String()
    }
    set {oneof = .string(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case number(Double)
    case boolean(Bool)
    case string(String)

    public static func ==(lhs: Openapi_V3_DefaultType.OneOf_Oneof, rhs: Openapi_V3_DefaultType.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.number(let l), .number(let r)): return l == r
      case (.boolean(let l), .boolean(let r)): return l == r
      case (.string(let l), .string(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1:
        if self.oneof != nil {try decoder.handleConflictingOneOf()}
        var v: Double?
        try decoder.decodeSingularDoubleField(value: &v)
        if let v = v {self.oneof = .number(v)}
      case 2:
        if self.oneof != nil {try decoder.handleConflictingOneOf()}
        var v: Bool?
        try decoder.decodeSingularBoolField(value: &v)
        if let v = v {self.oneof = .boolean(v)}
      case 3:
        if self.oneof != nil {try decoder.handleConflictingOneOf()}
        var v: String?
        try decoder.decodeSingularStringField(value: &v)
        if let v = v {self.oneof = .string(v)}
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    switch self.oneof {
    case .number(let v)?:
      try visitor.visitSingularDoubleField(value: v, fieldNumber: 1)
    case .boolean(let v)?:
      try visitor.visitSingularBoolField(value: v, fieldNumber: 2)
    case .string(let v)?:
      try visitor.visitSingularStringField(value: v, fieldNumber: 3)
    case nil: break
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// When request bodies or response payloads may be one of a number of different schemas, a `discriminator` object can be used to aid in serialization, deserialization, and validation.  The discriminator is a specific object in a schema which is used to inform the consumer of the specification of an alternative schema based on the value associated with it.  When using the discriminator, _inline_ schemas will not be considered.
public struct Openapi_V3_Discriminator: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Discriminator"

  public var propertyName: String {
    get {return _storage._propertyName}
    set {_uniqueStorage()._propertyName = newValue}
  }

  public var mapping: Openapi_V3_Strings {
    get {return _storage._mapping ?? Openapi_V3_Strings()}
    set {_uniqueStorage()._mapping = newValue}
  }
  /// Returns true if `mapping` has been explicitly set.
  public var hasMapping: Bool {return _storage._mapping != nil}
  /// Clears the value of `mapping`. Subsequent reads from it will return its default value.
  public mutating func clearMapping() {_storage._mapping = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._propertyName)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._mapping)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._propertyName.isEmpty {
        try visitor.visitSingularStringField(value: _storage._propertyName, fieldNumber: 1)
      }
      if let v = _storage._mapping {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_Document: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Document"

  public var openapi: String {
    get {return _storage._openapi}
    set {_uniqueStorage()._openapi = newValue}
  }

  public var info: Openapi_V3_Info {
    get {return _storage._info ?? Openapi_V3_Info()}
    set {_uniqueStorage()._info = newValue}
  }
  /// Returns true if `info` has been explicitly set.
  public var hasInfo: Bool {return _storage._info != nil}
  /// Clears the value of `info`. Subsequent reads from it will return its default value.
  public mutating func clearInfo() {_storage._info = nil}

  public var servers: [Openapi_V3_Server] {
    get {return _storage._servers}
    set {_uniqueStorage()._servers = newValue}
  }

  public var paths: Openapi_V3_Paths {
    get {return _storage._paths ?? Openapi_V3_Paths()}
    set {_uniqueStorage()._paths = newValue}
  }
  /// Returns true if `paths` has been explicitly set.
  public var hasPaths: Bool {return _storage._paths != nil}
  /// Clears the value of `paths`. Subsequent reads from it will return its default value.
  public mutating func clearPaths() {_storage._paths = nil}

  public var components: Openapi_V3_Components {
    get {return _storage._components ?? Openapi_V3_Components()}
    set {_uniqueStorage()._components = newValue}
  }
  /// Returns true if `components` has been explicitly set.
  public var hasComponents: Bool {return _storage._components != nil}
  /// Clears the value of `components`. Subsequent reads from it will return its default value.
  public mutating func clearComponents() {_storage._components = nil}

  public var security: [Openapi_V3_SecurityRequirement] {
    get {return _storage._security}
    set {_uniqueStorage()._security = newValue}
  }

  public var tags: [Openapi_V3_Tag] {
    get {return _storage._tags}
    set {_uniqueStorage()._tags = newValue}
  }

  public var externalDocs: Openapi_V3_ExternalDocs {
    get {return _storage._externalDocs ?? Openapi_V3_ExternalDocs()}
    set {_uniqueStorage()._externalDocs = newValue}
  }
  /// Returns true if `externalDocs` has been explicitly set.
  public var hasExternalDocs: Bool {return _storage._externalDocs != nil}
  /// Clears the value of `externalDocs`. Subsequent reads from it will return its default value.
  public mutating func clearExternalDocs() {_storage._externalDocs = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._openapi)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._info)
        case 3: try decoder.decodeRepeatedMessageField(value: &_storage._servers)
        case 4: try decoder.decodeSingularMessageField(value: &_storage._paths)
        case 5: try decoder.decodeSingularMessageField(value: &_storage._components)
        case 6: try decoder.decodeRepeatedMessageField(value: &_storage._security)
        case 7: try decoder.decodeRepeatedMessageField(value: &_storage._tags)
        case 8: try decoder.decodeSingularMessageField(value: &_storage._externalDocs)
        case 9: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._openapi.isEmpty {
        try visitor.visitSingularStringField(value: _storage._openapi, fieldNumber: 1)
      }
      if let v = _storage._info {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
      if !_storage._servers.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._servers, fieldNumber: 3)
      }
      if let v = _storage._paths {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
      }
      if let v = _storage._components {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
      }
      if !_storage._security.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._security, fieldNumber: 6)
      }
      if !_storage._tags.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._tags, fieldNumber: 7)
      }
      if let v = _storage._externalDocs {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 8)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 9)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// A single encoding definition applied to a single schema property.
public struct Openapi_V3_Encoding: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Encoding"

  public var contentType: String {
    get {return _storage._contentType}
    set {_uniqueStorage()._contentType = newValue}
  }

  public var headers: Openapi_V3_HeadersOrReferences {
    get {return _storage._headers ?? Openapi_V3_HeadersOrReferences()}
    set {_uniqueStorage()._headers = newValue}
  }
  /// Returns true if `headers` has been explicitly set.
  public var hasHeaders: Bool {return _storage._headers != nil}
  /// Clears the value of `headers`. Subsequent reads from it will return its default value.
  public mutating func clearHeaders() {_storage._headers = nil}

  public var style: String {
    get {return _storage._style}
    set {_uniqueStorage()._style = newValue}
  }

  public var explode: Bool {
    get {return _storage._explode}
    set {_uniqueStorage()._explode = newValue}
  }

  public var allowReserved: Bool {
    get {return _storage._allowReserved}
    set {_uniqueStorage()._allowReserved = newValue}
  }

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._contentType)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._headers)
        case 3: try decoder.decodeSingularStringField(value: &_storage._style)
        case 4: try decoder.decodeSingularBoolField(value: &_storage._explode)
        case 5: try decoder.decodeSingularBoolField(value: &_storage._allowReserved)
        case 6: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._contentType.isEmpty {
        try visitor.visitSingularStringField(value: _storage._contentType, fieldNumber: 1)
      }
      if let v = _storage._headers {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
      if !_storage._style.isEmpty {
        try visitor.visitSingularStringField(value: _storage._style, fieldNumber: 3)
      }
      if _storage._explode != false {
        try visitor.visitSingularBoolField(value: _storage._explode, fieldNumber: 4)
      }
      if _storage._allowReserved != false {
        try visitor.visitSingularBoolField(value: _storage._allowReserved, fieldNumber: 5)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 6)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_Encodings: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Encodings"

  public var additionalProperties: [Openapi_V3_NamedEncoding] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

public struct Openapi_V3_Example: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Example"

  public var summary: String {
    get {return _storage._summary}
    set {_uniqueStorage()._summary = newValue}
  }

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var value: Openapi_V3_Any {
    get {return _storage._value ?? Openapi_V3_Any()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var externalValue: String {
    get {return _storage._externalValue}
    set {_uniqueStorage()._externalValue = newValue}
  }

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._summary)
        case 2: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 3: try decoder.decodeSingularMessageField(value: &_storage._value)
        case 4: try decoder.decodeSingularStringField(value: &_storage._externalValue)
        case 5: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._summary.isEmpty {
        try visitor.visitSingularStringField(value: _storage._summary, fieldNumber: 1)
      }
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 2)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
      }
      if !_storage._externalValue.isEmpty {
        try visitor.visitSingularStringField(value: _storage._externalValue, fieldNumber: 4)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 5)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_ExampleOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".ExampleOrReference"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var example: Openapi_V3_Example {
    get {
      if case .example(let v)? = _storage._oneof {return v}
      return Openapi_V3_Example()
    }
    set {_uniqueStorage()._oneof = .example(newValue)}
  }

  public var reference: Openapi_V3_Reference {
    get {
      if case .reference(let v)? = _storage._oneof {return v}
      return Openapi_V3_Reference()
    }
    set {_uniqueStorage()._oneof = .reference(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case example(Openapi_V3_Example)
    case reference(Openapi_V3_Reference)

    public static func ==(lhs: Openapi_V3_ExampleOrReference.OneOf_Oneof, rhs: Openapi_V3_ExampleOrReference.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.example(let l), .example(let r)): return l == r
      case (.reference(let l), .reference(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_Example?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .example(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .example(v)}
        case 2:
          var v: Openapi_V3_Reference?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .reference(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .reference(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .example(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .reference(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_Examples: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Examples"

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let _ = try decoder.nextFieldNumber() {
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try unknownFields.traverse(visitor: &visitor)
  }
}

public struct Openapi_V3_ExamplesOrReferences: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".ExamplesOrReferences"

  public var additionalProperties: [Openapi_V3_NamedExampleOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

public struct Openapi_V3_Expression: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Expression"

  public var additionalProperties: [Openapi_V3_NamedAny] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Allows referencing an external resource for extended documentation.
public struct Openapi_V3_ExternalDocs: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".ExternalDocs"

  public var description_p: String = String()

  public var url: String = String()

  public var specificationExtension: [Openapi_V3_NamedAny] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeSingularStringField(value: &self.description_p)
      case 2: try decoder.decodeSingularStringField(value: &self.url)
      case 3: try decoder.decodeRepeatedMessageField(value: &self.specificationExtension)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.description_p.isEmpty {
      try visitor.visitSingularStringField(value: self.description_p, fieldNumber: 1)
    }
    if !self.url.isEmpty {
      try visitor.visitSingularStringField(value: self.url, fieldNumber: 2)
    }
    if !self.specificationExtension.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.specificationExtension, fieldNumber: 3)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// The Header Object follows the structure of the Parameter Object with the following changes:  1. `name` MUST NOT be specified, it is given in the corresponding `headers` map. 1. `in` MUST NOT be specified, it is implicitly in `header`. 1. All traits that are affected by the location MUST be applicable to a location of `header` (for example, `style`).
public struct Openapi_V3_Header: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Header"

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var required: Bool {
    get {return _storage._required}
    set {_uniqueStorage()._required = newValue}
  }

  public var deprecated: Bool {
    get {return _storage._deprecated}
    set {_uniqueStorage()._deprecated = newValue}
  }

  public var allowEmptyValue: Bool {
    get {return _storage._allowEmptyValue}
    set {_uniqueStorage()._allowEmptyValue = newValue}
  }

  public var style: String {
    get {return _storage._style}
    set {_uniqueStorage()._style = newValue}
  }

  public var explode: Bool {
    get {return _storage._explode}
    set {_uniqueStorage()._explode = newValue}
  }

  public var allowReserved: Bool {
    get {return _storage._allowReserved}
    set {_uniqueStorage()._allowReserved = newValue}
  }

  public var schema: Openapi_V3_SchemaOrReference {
    get {return _storage._schema ?? Openapi_V3_SchemaOrReference()}
    set {_uniqueStorage()._schema = newValue}
  }
  /// Returns true if `schema` has been explicitly set.
  public var hasSchema: Bool {return _storage._schema != nil}
  /// Clears the value of `schema`. Subsequent reads from it will return its default value.
  public mutating func clearSchema() {_storage._schema = nil}

  public var example: Openapi_V3_Any {
    get {return _storage._example ?? Openapi_V3_Any()}
    set {_uniqueStorage()._example = newValue}
  }
  /// Returns true if `example` has been explicitly set.
  public var hasExample: Bool {return _storage._example != nil}
  /// Clears the value of `example`. Subsequent reads from it will return its default value.
  public mutating func clearExample() {_storage._example = nil}

  public var examples: Openapi_V3_ExamplesOrReferences {
    get {return _storage._examples ?? Openapi_V3_ExamplesOrReferences()}
    set {_uniqueStorage()._examples = newValue}
  }
  /// Returns true if `examples` has been explicitly set.
  public var hasExamples: Bool {return _storage._examples != nil}
  /// Clears the value of `examples`. Subsequent reads from it will return its default value.
  public mutating func clearExamples() {_storage._examples = nil}

  public var content: Openapi_V3_MediaTypes {
    get {return _storage._content ?? Openapi_V3_MediaTypes()}
    set {_uniqueStorage()._content = newValue}
  }
  /// Returns true if `content` has been explicitly set.
  public var hasContent: Bool {return _storage._content != nil}
  /// Clears the value of `content`. Subsequent reads from it will return its default value.
  public mutating func clearContent() {_storage._content = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 2: try decoder.decodeSingularBoolField(value: &_storage._required)
        case 3: try decoder.decodeSingularBoolField(value: &_storage._deprecated)
        case 4: try decoder.decodeSingularBoolField(value: &_storage._allowEmptyValue)
        case 5: try decoder.decodeSingularStringField(value: &_storage._style)
        case 6: try decoder.decodeSingularBoolField(value: &_storage._explode)
        case 7: try decoder.decodeSingularBoolField(value: &_storage._allowReserved)
        case 8: try decoder.decodeSingularMessageField(value: &_storage._schema)
        case 9: try decoder.decodeSingularMessageField(value: &_storage._example)
        case 10: try decoder.decodeSingularMessageField(value: &_storage._examples)
        case 11: try decoder.decodeSingularMessageField(value: &_storage._content)
        case 12: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 1)
      }
      if _storage._required != false {
        try visitor.visitSingularBoolField(value: _storage._required, fieldNumber: 2)
      }
      if _storage._deprecated != false {
        try visitor.visitSingularBoolField(value: _storage._deprecated, fieldNumber: 3)
      }
      if _storage._allowEmptyValue != false {
        try visitor.visitSingularBoolField(value: _storage._allowEmptyValue, fieldNumber: 4)
      }
      if !_storage._style.isEmpty {
        try visitor.visitSingularStringField(value: _storage._style, fieldNumber: 5)
      }
      if _storage._explode != false {
        try visitor.visitSingularBoolField(value: _storage._explode, fieldNumber: 6)
      }
      if _storage._allowReserved != false {
        try visitor.visitSingularBoolField(value: _storage._allowReserved, fieldNumber: 7)
      }
      if let v = _storage._schema {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 8)
      }
      if let v = _storage._example {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 9)
      }
      if let v = _storage._examples {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 10)
      }
      if let v = _storage._content {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 11)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 12)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_HeaderOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".HeaderOrReference"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var header: Openapi_V3_Header {
    get {
      if case .header(let v)? = _storage._oneof {return v}
      return Openapi_V3_Header()
    }
    set {_uniqueStorage()._oneof = .header(newValue)}
  }

  public var reference: Openapi_V3_Reference {
    get {
      if case .reference(let v)? = _storage._oneof {return v}
      return Openapi_V3_Reference()
    }
    set {_uniqueStorage()._oneof = .reference(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case header(Openapi_V3_Header)
    case reference(Openapi_V3_Reference)

    public static func ==(lhs: Openapi_V3_HeaderOrReference.OneOf_Oneof, rhs: Openapi_V3_HeaderOrReference.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.header(let l), .header(let r)): return l == r
      case (.reference(let l), .reference(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_Header?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .header(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .header(v)}
        case 2:
          var v: Openapi_V3_Reference?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .reference(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .reference(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .header(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .reference(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_HeadersOrReferences: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".HeadersOrReferences"

  public var additionalProperties: [Openapi_V3_NamedHeaderOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// The object provides metadata about the API. The metadata MAY be used by the clients if needed, and MAY be presented in editing or documentation generation tools for convenience.
public struct Openapi_V3_Info: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Info"

  public var title: String {
    get {return _storage._title}
    set {_uniqueStorage()._title = newValue}
  }

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var termsOfService: String {
    get {return _storage._termsOfService}
    set {_uniqueStorage()._termsOfService = newValue}
  }

  public var contact: Openapi_V3_Contact {
    get {return _storage._contact ?? Openapi_V3_Contact()}
    set {_uniqueStorage()._contact = newValue}
  }
  /// Returns true if `contact` has been explicitly set.
  public var hasContact: Bool {return _storage._contact != nil}
  /// Clears the value of `contact`. Subsequent reads from it will return its default value.
  public mutating func clearContact() {_storage._contact = nil}

  public var license: Openapi_V3_License {
    get {return _storage._license ?? Openapi_V3_License()}
    set {_uniqueStorage()._license = newValue}
  }
  /// Returns true if `license` has been explicitly set.
  public var hasLicense: Bool {return _storage._license != nil}
  /// Clears the value of `license`. Subsequent reads from it will return its default value.
  public mutating func clearLicense() {_storage._license = nil}

  public var version: String {
    get {return _storage._version}
    set {_uniqueStorage()._version = newValue}
  }

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._title)
        case 2: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 3: try decoder.decodeSingularStringField(value: &_storage._termsOfService)
        case 4: try decoder.decodeSingularMessageField(value: &_storage._contact)
        case 5: try decoder.decodeSingularMessageField(value: &_storage._license)
        case 6: try decoder.decodeSingularStringField(value: &_storage._version)
        case 7: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._title.isEmpty {
        try visitor.visitSingularStringField(value: _storage._title, fieldNumber: 1)
      }
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 2)
      }
      if !_storage._termsOfService.isEmpty {
        try visitor.visitSingularStringField(value: _storage._termsOfService, fieldNumber: 3)
      }
      if let v = _storage._contact {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
      }
      if let v = _storage._license {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
      }
      if !_storage._version.isEmpty {
        try visitor.visitSingularStringField(value: _storage._version, fieldNumber: 6)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 7)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_ItemsItem: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".ItemsItem"

  public var schemaOrReference: [Openapi_V3_SchemaOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.schemaOrReference)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.schemaOrReference.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.schemaOrReference, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// License information for the exposed API.
public struct Openapi_V3_License: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".License"

  public var name: String = String()

  public var url: String = String()

  public var specificationExtension: [Openapi_V3_NamedAny] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeSingularStringField(value: &self.name)
      case 2: try decoder.decodeSingularStringField(value: &self.url)
      case 3: try decoder.decodeRepeatedMessageField(value: &self.specificationExtension)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.name.isEmpty {
      try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
    }
    if !self.url.isEmpty {
      try visitor.visitSingularStringField(value: self.url, fieldNumber: 2)
    }
    if !self.specificationExtension.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.specificationExtension, fieldNumber: 3)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// The `Link object` represents a possible design-time link for a response. The presence of a link does not guarantee the caller's ability to successfully invoke it, rather it provides a known relationship and traversal mechanism between responses and other operations.  Unlike _dynamic_ links (i.e. links provided **in** the response payload), the OAS linking mechanism does not require link information in the runtime response.  For computing links, and providing instructions to execute them, a runtime expression is used for accessing values in an operation and using them as parameters while invoking the linked operation.
public struct Openapi_V3_Link: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Link"

  public var operationRef: String {
    get {return _storage._operationRef}
    set {_uniqueStorage()._operationRef = newValue}
  }

  public var operationID: String {
    get {return _storage._operationID}
    set {_uniqueStorage()._operationID = newValue}
  }

  public var parameters: Openapi_V3_AnysOrExpressions {
    get {return _storage._parameters ?? Openapi_V3_AnysOrExpressions()}
    set {_uniqueStorage()._parameters = newValue}
  }
  /// Returns true if `parameters` has been explicitly set.
  public var hasParameters: Bool {return _storage._parameters != nil}
  /// Clears the value of `parameters`. Subsequent reads from it will return its default value.
  public mutating func clearParameters() {_storage._parameters = nil}

  public var requestBody: Openapi_V3_AnyOrExpression {
    get {return _storage._requestBody ?? Openapi_V3_AnyOrExpression()}
    set {_uniqueStorage()._requestBody = newValue}
  }
  /// Returns true if `requestBody` has been explicitly set.
  public var hasRequestBody: Bool {return _storage._requestBody != nil}
  /// Clears the value of `requestBody`. Subsequent reads from it will return its default value.
  public mutating func clearRequestBody() {_storage._requestBody = nil}

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var server: Openapi_V3_Server {
    get {return _storage._server ?? Openapi_V3_Server()}
    set {_uniqueStorage()._server = newValue}
  }
  /// Returns true if `server` has been explicitly set.
  public var hasServer: Bool {return _storage._server != nil}
  /// Clears the value of `server`. Subsequent reads from it will return its default value.
  public mutating func clearServer() {_storage._server = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._operationRef)
        case 2: try decoder.decodeSingularStringField(value: &_storage._operationID)
        case 3: try decoder.decodeSingularMessageField(value: &_storage._parameters)
        case 4: try decoder.decodeSingularMessageField(value: &_storage._requestBody)
        case 5: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 6: try decoder.decodeSingularMessageField(value: &_storage._server)
        case 7: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._operationRef.isEmpty {
        try visitor.visitSingularStringField(value: _storage._operationRef, fieldNumber: 1)
      }
      if !_storage._operationID.isEmpty {
        try visitor.visitSingularStringField(value: _storage._operationID, fieldNumber: 2)
      }
      if let v = _storage._parameters {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
      }
      if let v = _storage._requestBody {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
      }
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 5)
      }
      if let v = _storage._server {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 6)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 7)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_LinkOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".LinkOrReference"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var link: Openapi_V3_Link {
    get {
      if case .link(let v)? = _storage._oneof {return v}
      return Openapi_V3_Link()
    }
    set {_uniqueStorage()._oneof = .link(newValue)}
  }

  public var reference: Openapi_V3_Reference {
    get {
      if case .reference(let v)? = _storage._oneof {return v}
      return Openapi_V3_Reference()
    }
    set {_uniqueStorage()._oneof = .reference(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case link(Openapi_V3_Link)
    case reference(Openapi_V3_Reference)

    public static func ==(lhs: Openapi_V3_LinkOrReference.OneOf_Oneof, rhs: Openapi_V3_LinkOrReference.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.link(let l), .link(let r)): return l == r
      case (.reference(let l), .reference(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_Link?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .link(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .link(v)}
        case 2:
          var v: Openapi_V3_Reference?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .reference(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .reference(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .link(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .reference(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_LinksOrReferences: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".LinksOrReferences"

  public var additionalProperties: [Openapi_V3_NamedLinkOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Each Media Type Object provides schema and examples for the media type identified by its key.
public struct Openapi_V3_MediaType: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".MediaType"

  public var schema: Openapi_V3_SchemaOrReference {
    get {return _storage._schema ?? Openapi_V3_SchemaOrReference()}
    set {_uniqueStorage()._schema = newValue}
  }
  /// Returns true if `schema` has been explicitly set.
  public var hasSchema: Bool {return _storage._schema != nil}
  /// Clears the value of `schema`. Subsequent reads from it will return its default value.
  public mutating func clearSchema() {_storage._schema = nil}

  public var example: Openapi_V3_Any {
    get {return _storage._example ?? Openapi_V3_Any()}
    set {_uniqueStorage()._example = newValue}
  }
  /// Returns true if `example` has been explicitly set.
  public var hasExample: Bool {return _storage._example != nil}
  /// Clears the value of `example`. Subsequent reads from it will return its default value.
  public mutating func clearExample() {_storage._example = nil}

  public var examples: Openapi_V3_ExamplesOrReferences {
    get {return _storage._examples ?? Openapi_V3_ExamplesOrReferences()}
    set {_uniqueStorage()._examples = newValue}
  }
  /// Returns true if `examples` has been explicitly set.
  public var hasExamples: Bool {return _storage._examples != nil}
  /// Clears the value of `examples`. Subsequent reads from it will return its default value.
  public mutating func clearExamples() {_storage._examples = nil}

  public var encoding: Openapi_V3_Encodings {
    get {return _storage._encoding ?? Openapi_V3_Encodings()}
    set {_uniqueStorage()._encoding = newValue}
  }
  /// Returns true if `encoding` has been explicitly set.
  public var hasEncoding: Bool {return _storage._encoding != nil}
  /// Clears the value of `encoding`. Subsequent reads from it will return its default value.
  public mutating func clearEncoding() {_storage._encoding = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularMessageField(value: &_storage._schema)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._example)
        case 3: try decoder.decodeSingularMessageField(value: &_storage._examples)
        case 4: try decoder.decodeSingularMessageField(value: &_storage._encoding)
        case 5: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if let v = _storage._schema {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      }
      if let v = _storage._example {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
      if let v = _storage._examples {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
      }
      if let v = _storage._encoding {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 5)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_MediaTypes: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".MediaTypes"

  public var additionalProperties: [Openapi_V3_NamedMediaType] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Automatically-generated message used to represent maps of Any as ordered (name,value) pairs.
public struct Openapi_V3_NamedAny: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedAny"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_Any {
    get {return _storage._value ?? Openapi_V3_Any()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of AnyOrExpression as ordered (name,value) pairs.
public struct Openapi_V3_NamedAnyOrExpression: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedAnyOrExpression"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_AnyOrExpression {
    get {return _storage._value ?? Openapi_V3_AnyOrExpression()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of CallbackOrReference as ordered (name,value) pairs.
public struct Openapi_V3_NamedCallbackOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedCallbackOrReference"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_CallbackOrReference {
    get {return _storage._value ?? Openapi_V3_CallbackOrReference()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of Encoding as ordered (name,value) pairs.
public struct Openapi_V3_NamedEncoding: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedEncoding"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_Encoding {
    get {return _storage._value ?? Openapi_V3_Encoding()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of ExampleOrReference as ordered (name,value) pairs.
public struct Openapi_V3_NamedExampleOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedExampleOrReference"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_ExampleOrReference {
    get {return _storage._value ?? Openapi_V3_ExampleOrReference()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of HeaderOrReference as ordered (name,value) pairs.
public struct Openapi_V3_NamedHeaderOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedHeaderOrReference"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_HeaderOrReference {
    get {return _storage._value ?? Openapi_V3_HeaderOrReference()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of LinkOrReference as ordered (name,value) pairs.
public struct Openapi_V3_NamedLinkOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedLinkOrReference"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_LinkOrReference {
    get {return _storage._value ?? Openapi_V3_LinkOrReference()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of MediaType as ordered (name,value) pairs.
public struct Openapi_V3_NamedMediaType: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedMediaType"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_MediaType {
    get {return _storage._value ?? Openapi_V3_MediaType()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of ParameterOrReference as ordered (name,value) pairs.
public struct Openapi_V3_NamedParameterOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedParameterOrReference"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_ParameterOrReference {
    get {return _storage._value ?? Openapi_V3_ParameterOrReference()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of PathItem as ordered (name,value) pairs.
public struct Openapi_V3_NamedPathItem: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedPathItem"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_PathItem {
    get {return _storage._value ?? Openapi_V3_PathItem()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of RequestBodyOrReference as ordered (name,value) pairs.
public struct Openapi_V3_NamedRequestBodyOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedRequestBodyOrReference"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_RequestBodyOrReference {
    get {return _storage._value ?? Openapi_V3_RequestBodyOrReference()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of ResponseOrReference as ordered (name,value) pairs.
public struct Openapi_V3_NamedResponseOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedResponseOrReference"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_ResponseOrReference {
    get {return _storage._value ?? Openapi_V3_ResponseOrReference()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of SchemaOrReference as ordered (name,value) pairs.
public struct Openapi_V3_NamedSchemaOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedSchemaOrReference"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_SchemaOrReference {
    get {return _storage._value ?? Openapi_V3_SchemaOrReference()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of SecuritySchemeOrReference as ordered (name,value) pairs.
public struct Openapi_V3_NamedSecuritySchemeOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedSecuritySchemeOrReference"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_SecuritySchemeOrReference {
    get {return _storage._value ?? Openapi_V3_SecuritySchemeOrReference()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of ServerVariable as ordered (name,value) pairs.
public struct Openapi_V3_NamedServerVariable: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedServerVariable"

  /// Map key
  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  /// Mapped value
  public var value: Openapi_V3_ServerVariable {
    get {return _storage._value ?? Openapi_V3_ServerVariable()}
    set {_uniqueStorage()._value = newValue}
  }
  /// Returns true if `value` has been explicitly set.
  public var hasValue: Bool {return _storage._value != nil}
  /// Clears the value of `value`. Subsequent reads from it will return its default value.
  public mutating func clearValue() {_storage._value = nil}

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._value)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if let v = _storage._value {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Automatically-generated message used to represent maps of string as ordered (name,value) pairs.
public struct Openapi_V3_NamedString: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".NamedString"

  /// Map key
  public var name: String = String()

  /// Mapped value
  public var value: String = String()

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeSingularStringField(value: &self.name)
      case 2: try decoder.decodeSingularStringField(value: &self.value)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.name.isEmpty {
      try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
    }
    if !self.value.isEmpty {
      try visitor.visitSingularStringField(value: self.value, fieldNumber: 2)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Configuration details for a supported OAuth Flow
public struct Openapi_V3_OauthFlow: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".OauthFlow"

  public var authorizationURL: String {
    get {return _storage._authorizationURL}
    set {_uniqueStorage()._authorizationURL = newValue}
  }

  public var tokenURL: String {
    get {return _storage._tokenURL}
    set {_uniqueStorage()._tokenURL = newValue}
  }

  public var refreshURL: String {
    get {return _storage._refreshURL}
    set {_uniqueStorage()._refreshURL = newValue}
  }

  public var scopes: Openapi_V3_Strings {
    get {return _storage._scopes ?? Openapi_V3_Strings()}
    set {_uniqueStorage()._scopes = newValue}
  }
  /// Returns true if `scopes` has been explicitly set.
  public var hasScopes: Bool {return _storage._scopes != nil}
  /// Clears the value of `scopes`. Subsequent reads from it will return its default value.
  public mutating func clearScopes() {_storage._scopes = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._authorizationURL)
        case 2: try decoder.decodeSingularStringField(value: &_storage._tokenURL)
        case 3: try decoder.decodeSingularStringField(value: &_storage._refreshURL)
        case 4: try decoder.decodeSingularMessageField(value: &_storage._scopes)
        case 5: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._authorizationURL.isEmpty {
        try visitor.visitSingularStringField(value: _storage._authorizationURL, fieldNumber: 1)
      }
      if !_storage._tokenURL.isEmpty {
        try visitor.visitSingularStringField(value: _storage._tokenURL, fieldNumber: 2)
      }
      if !_storage._refreshURL.isEmpty {
        try visitor.visitSingularStringField(value: _storage._refreshURL, fieldNumber: 3)
      }
      if let v = _storage._scopes {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 5)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Allows configuration of the supported OAuth Flows.
public struct Openapi_V3_OauthFlows: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".OauthFlows"

  public var implicit: Openapi_V3_OauthFlow {
    get {return _storage._implicit ?? Openapi_V3_OauthFlow()}
    set {_uniqueStorage()._implicit = newValue}
  }
  /// Returns true if `implicit` has been explicitly set.
  public var hasImplicit: Bool {return _storage._implicit != nil}
  /// Clears the value of `implicit`. Subsequent reads from it will return its default value.
  public mutating func clearImplicit() {_storage._implicit = nil}

  public var password: Openapi_V3_OauthFlow {
    get {return _storage._password ?? Openapi_V3_OauthFlow()}
    set {_uniqueStorage()._password = newValue}
  }
  /// Returns true if `password` has been explicitly set.
  public var hasPassword: Bool {return _storage._password != nil}
  /// Clears the value of `password`. Subsequent reads from it will return its default value.
  public mutating func clearPassword() {_storage._password = nil}

  public var clientCredentials: Openapi_V3_OauthFlow {
    get {return _storage._clientCredentials ?? Openapi_V3_OauthFlow()}
    set {_uniqueStorage()._clientCredentials = newValue}
  }
  /// Returns true if `clientCredentials` has been explicitly set.
  public var hasClientCredentials: Bool {return _storage._clientCredentials != nil}
  /// Clears the value of `clientCredentials`. Subsequent reads from it will return its default value.
  public mutating func clearClientCredentials() {_storage._clientCredentials = nil}

  public var authorizationCode: Openapi_V3_OauthFlow {
    get {return _storage._authorizationCode ?? Openapi_V3_OauthFlow()}
    set {_uniqueStorage()._authorizationCode = newValue}
  }
  /// Returns true if `authorizationCode` has been explicitly set.
  public var hasAuthorizationCode: Bool {return _storage._authorizationCode != nil}
  /// Clears the value of `authorizationCode`. Subsequent reads from it will return its default value.
  public mutating func clearAuthorizationCode() {_storage._authorizationCode = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularMessageField(value: &_storage._implicit)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._password)
        case 3: try decoder.decodeSingularMessageField(value: &_storage._clientCredentials)
        case 4: try decoder.decodeSingularMessageField(value: &_storage._authorizationCode)
        case 5: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if let v = _storage._implicit {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      }
      if let v = _storage._password {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
      if let v = _storage._clientCredentials {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
      }
      if let v = _storage._authorizationCode {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 5)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_Object: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Object"

  public var additionalProperties: [Openapi_V3_NamedAny] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Describes a single API operation on a path.
public struct Openapi_V3_Operation: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Operation"

  public var tags: [String] {
    get {return _storage._tags}
    set {_uniqueStorage()._tags = newValue}
  }

  public var summary: String {
    get {return _storage._summary}
    set {_uniqueStorage()._summary = newValue}
  }

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var externalDocs: Openapi_V3_ExternalDocs {
    get {return _storage._externalDocs ?? Openapi_V3_ExternalDocs()}
    set {_uniqueStorage()._externalDocs = newValue}
  }
  /// Returns true if `externalDocs` has been explicitly set.
  public var hasExternalDocs: Bool {return _storage._externalDocs != nil}
  /// Clears the value of `externalDocs`. Subsequent reads from it will return its default value.
  public mutating func clearExternalDocs() {_storage._externalDocs = nil}

  public var operationID: String {
    get {return _storage._operationID}
    set {_uniqueStorage()._operationID = newValue}
  }

  public var parameters: [Openapi_V3_ParameterOrReference] {
    get {return _storage._parameters}
    set {_uniqueStorage()._parameters = newValue}
  }

  public var requestBody: Openapi_V3_RequestBodyOrReference {
    get {return _storage._requestBody ?? Openapi_V3_RequestBodyOrReference()}
    set {_uniqueStorage()._requestBody = newValue}
  }
  /// Returns true if `requestBody` has been explicitly set.
  public var hasRequestBody: Bool {return _storage._requestBody != nil}
  /// Clears the value of `requestBody`. Subsequent reads from it will return its default value.
  public mutating func clearRequestBody() {_storage._requestBody = nil}

  public var responses: Openapi_V3_Responses {
    get {return _storage._responses ?? Openapi_V3_Responses()}
    set {_uniqueStorage()._responses = newValue}
  }
  /// Returns true if `responses` has been explicitly set.
  public var hasResponses: Bool {return _storage._responses != nil}
  /// Clears the value of `responses`. Subsequent reads from it will return its default value.
  public mutating func clearResponses() {_storage._responses = nil}

  public var callbacks: Openapi_V3_CallbacksOrReferences {
    get {return _storage._callbacks ?? Openapi_V3_CallbacksOrReferences()}
    set {_uniqueStorage()._callbacks = newValue}
  }
  /// Returns true if `callbacks` has been explicitly set.
  public var hasCallbacks: Bool {return _storage._callbacks != nil}
  /// Clears the value of `callbacks`. Subsequent reads from it will return its default value.
  public mutating func clearCallbacks() {_storage._callbacks = nil}

  public var deprecated: Bool {
    get {return _storage._deprecated}
    set {_uniqueStorage()._deprecated = newValue}
  }

  public var security: [Openapi_V3_SecurityRequirement] {
    get {return _storage._security}
    set {_uniqueStorage()._security = newValue}
  }

  public var servers: [Openapi_V3_Server] {
    get {return _storage._servers}
    set {_uniqueStorage()._servers = newValue}
  }

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeRepeatedStringField(value: &_storage._tags)
        case 2: try decoder.decodeSingularStringField(value: &_storage._summary)
        case 3: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 4: try decoder.decodeSingularMessageField(value: &_storage._externalDocs)
        case 5: try decoder.decodeSingularStringField(value: &_storage._operationID)
        case 6: try decoder.decodeRepeatedMessageField(value: &_storage._parameters)
        case 7: try decoder.decodeSingularMessageField(value: &_storage._requestBody)
        case 8: try decoder.decodeSingularMessageField(value: &_storage._responses)
        case 9: try decoder.decodeSingularMessageField(value: &_storage._callbacks)
        case 10: try decoder.decodeSingularBoolField(value: &_storage._deprecated)
        case 11: try decoder.decodeRepeatedMessageField(value: &_storage._security)
        case 12: try decoder.decodeRepeatedMessageField(value: &_storage._servers)
        case 13: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._tags.isEmpty {
        try visitor.visitRepeatedStringField(value: _storage._tags, fieldNumber: 1)
      }
      if !_storage._summary.isEmpty {
        try visitor.visitSingularStringField(value: _storage._summary, fieldNumber: 2)
      }
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 3)
      }
      if let v = _storage._externalDocs {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
      }
      if !_storage._operationID.isEmpty {
        try visitor.visitSingularStringField(value: _storage._operationID, fieldNumber: 5)
      }
      if !_storage._parameters.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._parameters, fieldNumber: 6)
      }
      if let v = _storage._requestBody {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 7)
      }
      if let v = _storage._responses {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 8)
      }
      if let v = _storage._callbacks {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 9)
      }
      if _storage._deprecated != false {
        try visitor.visitSingularBoolField(value: _storage._deprecated, fieldNumber: 10)
      }
      if !_storage._security.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._security, fieldNumber: 11)
      }
      if !_storage._servers.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._servers, fieldNumber: 12)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 13)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Describes a single operation parameter.  A unique parameter is defined by a combination of a name and location.
public struct Openapi_V3_Parameter: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Parameter"

  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  public var `in`: String {
    get {return _storage._in}
    set {_uniqueStorage()._in = newValue}
  }

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var required: Bool {
    get {return _storage._required}
    set {_uniqueStorage()._required = newValue}
  }

  public var deprecated: Bool {
    get {return _storage._deprecated}
    set {_uniqueStorage()._deprecated = newValue}
  }

  public var allowEmptyValue: Bool {
    get {return _storage._allowEmptyValue}
    set {_uniqueStorage()._allowEmptyValue = newValue}
  }

  public var style: String {
    get {return _storage._style}
    set {_uniqueStorage()._style = newValue}
  }

  public var explode: Bool {
    get {return _storage._explode}
    set {_uniqueStorage()._explode = newValue}
  }

  public var allowReserved: Bool {
    get {return _storage._allowReserved}
    set {_uniqueStorage()._allowReserved = newValue}
  }

  public var schema: Openapi_V3_SchemaOrReference {
    get {return _storage._schema ?? Openapi_V3_SchemaOrReference()}
    set {_uniqueStorage()._schema = newValue}
  }
  /// Returns true if `schema` has been explicitly set.
  public var hasSchema: Bool {return _storage._schema != nil}
  /// Clears the value of `schema`. Subsequent reads from it will return its default value.
  public mutating func clearSchema() {_storage._schema = nil}

  public var example: Openapi_V3_Any {
    get {return _storage._example ?? Openapi_V3_Any()}
    set {_uniqueStorage()._example = newValue}
  }
  /// Returns true if `example` has been explicitly set.
  public var hasExample: Bool {return _storage._example != nil}
  /// Clears the value of `example`. Subsequent reads from it will return its default value.
  public mutating func clearExample() {_storage._example = nil}

  public var examples: Openapi_V3_ExamplesOrReferences {
    get {return _storage._examples ?? Openapi_V3_ExamplesOrReferences()}
    set {_uniqueStorage()._examples = newValue}
  }
  /// Returns true if `examples` has been explicitly set.
  public var hasExamples: Bool {return _storage._examples != nil}
  /// Clears the value of `examples`. Subsequent reads from it will return its default value.
  public mutating func clearExamples() {_storage._examples = nil}

  public var content: Openapi_V3_MediaTypes {
    get {return _storage._content ?? Openapi_V3_MediaTypes()}
    set {_uniqueStorage()._content = newValue}
  }
  /// Returns true if `content` has been explicitly set.
  public var hasContent: Bool {return _storage._content != nil}
  /// Clears the value of `content`. Subsequent reads from it will return its default value.
  public mutating func clearContent() {_storage._content = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularStringField(value: &_storage._in)
        case 3: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 4: try decoder.decodeSingularBoolField(value: &_storage._required)
        case 5: try decoder.decodeSingularBoolField(value: &_storage._deprecated)
        case 6: try decoder.decodeSingularBoolField(value: &_storage._allowEmptyValue)
        case 7: try decoder.decodeSingularStringField(value: &_storage._style)
        case 8: try decoder.decodeSingularBoolField(value: &_storage._explode)
        case 9: try decoder.decodeSingularBoolField(value: &_storage._allowReserved)
        case 10: try decoder.decodeSingularMessageField(value: &_storage._schema)
        case 11: try decoder.decodeSingularMessageField(value: &_storage._example)
        case 12: try decoder.decodeSingularMessageField(value: &_storage._examples)
        case 13: try decoder.decodeSingularMessageField(value: &_storage._content)
        case 14: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if !_storage._in.isEmpty {
        try visitor.visitSingularStringField(value: _storage._in, fieldNumber: 2)
      }
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 3)
      }
      if _storage._required != false {
        try visitor.visitSingularBoolField(value: _storage._required, fieldNumber: 4)
      }
      if _storage._deprecated != false {
        try visitor.visitSingularBoolField(value: _storage._deprecated, fieldNumber: 5)
      }
      if _storage._allowEmptyValue != false {
        try visitor.visitSingularBoolField(value: _storage._allowEmptyValue, fieldNumber: 6)
      }
      if !_storage._style.isEmpty {
        try visitor.visitSingularStringField(value: _storage._style, fieldNumber: 7)
      }
      if _storage._explode != false {
        try visitor.visitSingularBoolField(value: _storage._explode, fieldNumber: 8)
      }
      if _storage._allowReserved != false {
        try visitor.visitSingularBoolField(value: _storage._allowReserved, fieldNumber: 9)
      }
      if let v = _storage._schema {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 10)
      }
      if let v = _storage._example {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 11)
      }
      if let v = _storage._examples {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 12)
      }
      if let v = _storage._content {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 13)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 14)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_ParameterOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".ParameterOrReference"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var parameter: Openapi_V3_Parameter {
    get {
      if case .parameter(let v)? = _storage._oneof {return v}
      return Openapi_V3_Parameter()
    }
    set {_uniqueStorage()._oneof = .parameter(newValue)}
  }

  public var reference: Openapi_V3_Reference {
    get {
      if case .reference(let v)? = _storage._oneof {return v}
      return Openapi_V3_Reference()
    }
    set {_uniqueStorage()._oneof = .reference(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case parameter(Openapi_V3_Parameter)
    case reference(Openapi_V3_Reference)

    public static func ==(lhs: Openapi_V3_ParameterOrReference.OneOf_Oneof, rhs: Openapi_V3_ParameterOrReference.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.parameter(let l), .parameter(let r)): return l == r
      case (.reference(let l), .reference(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_Parameter?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .parameter(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .parameter(v)}
        case 2:
          var v: Openapi_V3_Reference?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .reference(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .reference(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .parameter(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .reference(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_ParametersOrReferences: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".ParametersOrReferences"

  public var additionalProperties: [Openapi_V3_NamedParameterOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Describes the operations available on a single path. A Path Item MAY be empty, due to ACL constraints. The path itself is still exposed to the documentation viewer but they will not know which operations and parameters are available.
public struct Openapi_V3_PathItem: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".PathItem"

  public var ref: String {
    get {return _storage._ref}
    set {_uniqueStorage()._ref = newValue}
  }

  public var summary: String {
    get {return _storage._summary}
    set {_uniqueStorage()._summary = newValue}
  }

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var get: Openapi_V3_Operation {
    get {return _storage._get ?? Openapi_V3_Operation()}
    set {_uniqueStorage()._get = newValue}
  }
  /// Returns true if `get` has been explicitly set.
  public var hasGet: Bool {return _storage._get != nil}
  /// Clears the value of `get`. Subsequent reads from it will return its default value.
  public mutating func clearGet() {_storage._get = nil}

  public var put: Openapi_V3_Operation {
    get {return _storage._put ?? Openapi_V3_Operation()}
    set {_uniqueStorage()._put = newValue}
  }
  /// Returns true if `put` has been explicitly set.
  public var hasPut: Bool {return _storage._put != nil}
  /// Clears the value of `put`. Subsequent reads from it will return its default value.
  public mutating func clearPut() {_storage._put = nil}

  public var post: Openapi_V3_Operation {
    get {return _storage._post ?? Openapi_V3_Operation()}
    set {_uniqueStorage()._post = newValue}
  }
  /// Returns true if `post` has been explicitly set.
  public var hasPost: Bool {return _storage._post != nil}
  /// Clears the value of `post`. Subsequent reads from it will return its default value.
  public mutating func clearPost() {_storage._post = nil}

  public var delete: Openapi_V3_Operation {
    get {return _storage._delete ?? Openapi_V3_Operation()}
    set {_uniqueStorage()._delete = newValue}
  }
  /// Returns true if `delete` has been explicitly set.
  public var hasDelete: Bool {return _storage._delete != nil}
  /// Clears the value of `delete`. Subsequent reads from it will return its default value.
  public mutating func clearDelete() {_storage._delete = nil}

  public var options: Openapi_V3_Operation {
    get {return _storage._options ?? Openapi_V3_Operation()}
    set {_uniqueStorage()._options = newValue}
  }
  /// Returns true if `options` has been explicitly set.
  public var hasOptions: Bool {return _storage._options != nil}
  /// Clears the value of `options`. Subsequent reads from it will return its default value.
  public mutating func clearOptions() {_storage._options = nil}

  public var head: Openapi_V3_Operation {
    get {return _storage._head ?? Openapi_V3_Operation()}
    set {_uniqueStorage()._head = newValue}
  }
  /// Returns true if `head` has been explicitly set.
  public var hasHead: Bool {return _storage._head != nil}
  /// Clears the value of `head`. Subsequent reads from it will return its default value.
  public mutating func clearHead() {_storage._head = nil}

  public var patch: Openapi_V3_Operation {
    get {return _storage._patch ?? Openapi_V3_Operation()}
    set {_uniqueStorage()._patch = newValue}
  }
  /// Returns true if `patch` has been explicitly set.
  public var hasPatch: Bool {return _storage._patch != nil}
  /// Clears the value of `patch`. Subsequent reads from it will return its default value.
  public mutating func clearPatch() {_storage._patch = nil}

  public var trace: Openapi_V3_Operation {
    get {return _storage._trace ?? Openapi_V3_Operation()}
    set {_uniqueStorage()._trace = newValue}
  }
  /// Returns true if `trace` has been explicitly set.
  public var hasTrace: Bool {return _storage._trace != nil}
  /// Clears the value of `trace`. Subsequent reads from it will return its default value.
  public mutating func clearTrace() {_storage._trace = nil}

  public var servers: [Openapi_V3_Server] {
    get {return _storage._servers}
    set {_uniqueStorage()._servers = newValue}
  }

  public var parameters: [Openapi_V3_ParameterOrReference] {
    get {return _storage._parameters}
    set {_uniqueStorage()._parameters = newValue}
  }

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._ref)
        case 2: try decoder.decodeSingularStringField(value: &_storage._summary)
        case 3: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 4: try decoder.decodeSingularMessageField(value: &_storage._get)
        case 5: try decoder.decodeSingularMessageField(value: &_storage._put)
        case 6: try decoder.decodeSingularMessageField(value: &_storage._post)
        case 7: try decoder.decodeSingularMessageField(value: &_storage._delete)
        case 8: try decoder.decodeSingularMessageField(value: &_storage._options)
        case 9: try decoder.decodeSingularMessageField(value: &_storage._head)
        case 10: try decoder.decodeSingularMessageField(value: &_storage._patch)
        case 11: try decoder.decodeSingularMessageField(value: &_storage._trace)
        case 12: try decoder.decodeRepeatedMessageField(value: &_storage._servers)
        case 13: try decoder.decodeRepeatedMessageField(value: &_storage._parameters)
        case 14: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._ref.isEmpty {
        try visitor.visitSingularStringField(value: _storage._ref, fieldNumber: 1)
      }
      if !_storage._summary.isEmpty {
        try visitor.visitSingularStringField(value: _storage._summary, fieldNumber: 2)
      }
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 3)
      }
      if let v = _storage._get {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
      }
      if let v = _storage._put {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
      }
      if let v = _storage._post {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 6)
      }
      if let v = _storage._delete {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 7)
      }
      if let v = _storage._options {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 8)
      }
      if let v = _storage._head {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 9)
      }
      if let v = _storage._patch {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 10)
      }
      if let v = _storage._trace {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 11)
      }
      if !_storage._servers.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._servers, fieldNumber: 12)
      }
      if !_storage._parameters.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._parameters, fieldNumber: 13)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 14)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Holds the relative paths to the individual endpoints and their operations. The path is appended to the URL from the `Server Object` in order to construct the full URL.  The Paths MAY be empty, due to ACL constraints.
public struct Openapi_V3_Paths: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Paths"

  public var path: [Openapi_V3_NamedPathItem] = []

  public var specificationExtension: [Openapi_V3_NamedAny] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.path)
      case 2: try decoder.decodeRepeatedMessageField(value: &self.specificationExtension)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.path.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.path, fieldNumber: 1)
    }
    if !self.specificationExtension.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.specificationExtension, fieldNumber: 2)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

public struct Openapi_V3_Properties: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Properties"

  public var additionalProperties: [Openapi_V3_NamedSchemaOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// A simple object to allow referencing other components in the specification, internally and externally.  The Reference Object is defined by JSON Reference and follows the same structure, behavior and rules.   For this specification, reference resolution is accomplished as defined by the JSON Reference specification and not by the JSON Schema specification.
public struct Openapi_V3_Reference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Reference"

  public var ref: String = String()

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeSingularStringField(value: &self.ref)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.ref.isEmpty {
      try visitor.visitSingularStringField(value: self.ref, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

public struct Openapi_V3_RequestBodiesOrReferences: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".RequestBodiesOrReferences"

  public var additionalProperties: [Openapi_V3_NamedRequestBodyOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Describes a single request body.
public struct Openapi_V3_RequestBody: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".RequestBody"

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var content: Openapi_V3_MediaTypes {
    get {return _storage._content ?? Openapi_V3_MediaTypes()}
    set {_uniqueStorage()._content = newValue}
  }
  /// Returns true if `content` has been explicitly set.
  public var hasContent: Bool {return _storage._content != nil}
  /// Clears the value of `content`. Subsequent reads from it will return its default value.
  public mutating func clearContent() {_storage._content = nil}

  public var required: Bool {
    get {return _storage._required}
    set {_uniqueStorage()._required = newValue}
  }

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._content)
        case 3: try decoder.decodeSingularBoolField(value: &_storage._required)
        case 4: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 1)
      }
      if let v = _storage._content {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
      if _storage._required != false {
        try visitor.visitSingularBoolField(value: _storage._required, fieldNumber: 3)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 4)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_RequestBodyOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".RequestBodyOrReference"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var requestBody: Openapi_V3_RequestBody {
    get {
      if case .requestBody(let v)? = _storage._oneof {return v}
      return Openapi_V3_RequestBody()
    }
    set {_uniqueStorage()._oneof = .requestBody(newValue)}
  }

  public var reference: Openapi_V3_Reference {
    get {
      if case .reference(let v)? = _storage._oneof {return v}
      return Openapi_V3_Reference()
    }
    set {_uniqueStorage()._oneof = .reference(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case requestBody(Openapi_V3_RequestBody)
    case reference(Openapi_V3_Reference)

    public static func ==(lhs: Openapi_V3_RequestBodyOrReference.OneOf_Oneof, rhs: Openapi_V3_RequestBodyOrReference.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.requestBody(let l), .requestBody(let r)): return l == r
      case (.reference(let l), .reference(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_RequestBody?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .requestBody(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .requestBody(v)}
        case 2:
          var v: Openapi_V3_Reference?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .reference(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .reference(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .requestBody(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .reference(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// Describes a single response from an API Operation, including design-time, static  `links` to operations based on the response.
public struct Openapi_V3_Response: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Response"

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var headers: Openapi_V3_HeadersOrReferences {
    get {return _storage._headers ?? Openapi_V3_HeadersOrReferences()}
    set {_uniqueStorage()._headers = newValue}
  }
  /// Returns true if `headers` has been explicitly set.
  public var hasHeaders: Bool {return _storage._headers != nil}
  /// Clears the value of `headers`. Subsequent reads from it will return its default value.
  public mutating func clearHeaders() {_storage._headers = nil}

  public var content: Openapi_V3_MediaTypes {
    get {return _storage._content ?? Openapi_V3_MediaTypes()}
    set {_uniqueStorage()._content = newValue}
  }
  /// Returns true if `content` has been explicitly set.
  public var hasContent: Bool {return _storage._content != nil}
  /// Clears the value of `content`. Subsequent reads from it will return its default value.
  public mutating func clearContent() {_storage._content = nil}

  public var links: Openapi_V3_LinksOrReferences {
    get {return _storage._links ?? Openapi_V3_LinksOrReferences()}
    set {_uniqueStorage()._links = newValue}
  }
  /// Returns true if `links` has been explicitly set.
  public var hasLinks: Bool {return _storage._links != nil}
  /// Clears the value of `links`. Subsequent reads from it will return its default value.
  public mutating func clearLinks() {_storage._links = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._headers)
        case 3: try decoder.decodeSingularMessageField(value: &_storage._content)
        case 4: try decoder.decodeSingularMessageField(value: &_storage._links)
        case 5: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 1)
      }
      if let v = _storage._headers {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
      if let v = _storage._content {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
      }
      if let v = _storage._links {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 5)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_ResponseOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".ResponseOrReference"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var response: Openapi_V3_Response {
    get {
      if case .response(let v)? = _storage._oneof {return v}
      return Openapi_V3_Response()
    }
    set {_uniqueStorage()._oneof = .response(newValue)}
  }

  public var reference: Openapi_V3_Reference {
    get {
      if case .reference(let v)? = _storage._oneof {return v}
      return Openapi_V3_Reference()
    }
    set {_uniqueStorage()._oneof = .reference(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case response(Openapi_V3_Response)
    case reference(Openapi_V3_Reference)

    public static func ==(lhs: Openapi_V3_ResponseOrReference.OneOf_Oneof, rhs: Openapi_V3_ResponseOrReference.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.response(let l), .response(let r)): return l == r
      case (.reference(let l), .reference(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_Response?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .response(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .response(v)}
        case 2:
          var v: Openapi_V3_Reference?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .reference(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .reference(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .response(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .reference(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// A container for the expected responses of an operation. The container maps a HTTP response code to the expected response.  The documentation is not necessarily expected to cover all possible HTTP response codes because they may not be known in advance. However, documentation is expected to cover a successful operation response and any known errors.  The `default` MAY be used as a default response object for all HTTP codes  that are not covered individually by the specification.  The `Responses Object` MUST contain at least one response code, and it  SHOULD be the response for a successful operation call.
public struct Openapi_V3_Responses: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Responses"

  public var `default`: Openapi_V3_ResponseOrReference {
    get {return _storage._default ?? Openapi_V3_ResponseOrReference()}
    set {_uniqueStorage()._default = newValue}
  }
  /// Returns true if ``default`` has been explicitly set.
  public var hasDefault: Bool {return _storage._default != nil}
  /// Clears the value of ``default``. Subsequent reads from it will return its default value.
  public mutating func clearDefault() {_storage._default = nil}

  public var responseOrReference: [Openapi_V3_NamedResponseOrReference] {
    get {return _storage._responseOrReference}
    set {_uniqueStorage()._responseOrReference = newValue}
  }

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularMessageField(value: &_storage._default)
        case 2: try decoder.decodeRepeatedMessageField(value: &_storage._responseOrReference)
        case 3: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if let v = _storage._default {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      }
      if !_storage._responseOrReference.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._responseOrReference, fieldNumber: 2)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 3)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_ResponsesOrReferences: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".ResponsesOrReferences"

  public var additionalProperties: [Openapi_V3_NamedResponseOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// The Schema Object allows the definition of input and output data types. These types can be objects, but also primitives and arrays. This object is an extended subset of the JSON Schema Specification Wright Draft 00.  For more information about the properties, see JSON Schema Core and JSON Schema Validation. Unless stated otherwise, the property definitions follow the JSON Schema.
public struct Openapi_V3_Schema: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Schema"

  public var nullable: Bool {
    get {return _storage._nullable}
    set {_uniqueStorage()._nullable = newValue}
  }

  public var discriminator: Openapi_V3_Discriminator {
    get {return _storage._discriminator ?? Openapi_V3_Discriminator()}
    set {_uniqueStorage()._discriminator = newValue}
  }
  /// Returns true if `discriminator` has been explicitly set.
  public var hasDiscriminator: Bool {return _storage._discriminator != nil}
  /// Clears the value of `discriminator`. Subsequent reads from it will return its default value.
  public mutating func clearDiscriminator() {_storage._discriminator = nil}

  public var readOnly: Bool {
    get {return _storage._readOnly}
    set {_uniqueStorage()._readOnly = newValue}
  }

  public var writeOnly: Bool {
    get {return _storage._writeOnly}
    set {_uniqueStorage()._writeOnly = newValue}
  }

  public var xml: Openapi_V3_Xml {
    get {return _storage._xml ?? Openapi_V3_Xml()}
    set {_uniqueStorage()._xml = newValue}
  }
  /// Returns true if `xml` has been explicitly set.
  public var hasXml: Bool {return _storage._xml != nil}
  /// Clears the value of `xml`. Subsequent reads from it will return its default value.
  public mutating func clearXml() {_storage._xml = nil}

  public var externalDocs: Openapi_V3_ExternalDocs {
    get {return _storage._externalDocs ?? Openapi_V3_ExternalDocs()}
    set {_uniqueStorage()._externalDocs = newValue}
  }
  /// Returns true if `externalDocs` has been explicitly set.
  public var hasExternalDocs: Bool {return _storage._externalDocs != nil}
  /// Clears the value of `externalDocs`. Subsequent reads from it will return its default value.
  public mutating func clearExternalDocs() {_storage._externalDocs = nil}

  public var example: Openapi_V3_Any {
    get {return _storage._example ?? Openapi_V3_Any()}
    set {_uniqueStorage()._example = newValue}
  }
  /// Returns true if `example` has been explicitly set.
  public var hasExample: Bool {return _storage._example != nil}
  /// Clears the value of `example`. Subsequent reads from it will return its default value.
  public mutating func clearExample() {_storage._example = nil}

  public var deprecated: Bool {
    get {return _storage._deprecated}
    set {_uniqueStorage()._deprecated = newValue}
  }

  public var title: String {
    get {return _storage._title}
    set {_uniqueStorage()._title = newValue}
  }

  public var multipleOf: Double {
    get {return _storage._multipleOf}
    set {_uniqueStorage()._multipleOf = newValue}
  }

  public var maximum: Double {
    get {return _storage._maximum}
    set {_uniqueStorage()._maximum = newValue}
  }

  public var exclusiveMaximum: Bool {
    get {return _storage._exclusiveMaximum}
    set {_uniqueStorage()._exclusiveMaximum = newValue}
  }

  public var minimum: Double {
    get {return _storage._minimum}
    set {_uniqueStorage()._minimum = newValue}
  }

  public var exclusiveMinimum: Bool {
    get {return _storage._exclusiveMinimum}
    set {_uniqueStorage()._exclusiveMinimum = newValue}
  }

  public var maxLength: Int64 {
    get {return _storage._maxLength}
    set {_uniqueStorage()._maxLength = newValue}
  }

  public var minLength: Int64 {
    get {return _storage._minLength}
    set {_uniqueStorage()._minLength = newValue}
  }

  public var pattern: String {
    get {return _storage._pattern}
    set {_uniqueStorage()._pattern = newValue}
  }

  public var maxItems: Int64 {
    get {return _storage._maxItems}
    set {_uniqueStorage()._maxItems = newValue}
  }

  public var minItems: Int64 {
    get {return _storage._minItems}
    set {_uniqueStorage()._minItems = newValue}
  }

  public var uniqueItems: Bool {
    get {return _storage._uniqueItems}
    set {_uniqueStorage()._uniqueItems = newValue}
  }

  public var maxProperties: Int64 {
    get {return _storage._maxProperties}
    set {_uniqueStorage()._maxProperties = newValue}
  }

  public var minProperties: Int64 {
    get {return _storage._minProperties}
    set {_uniqueStorage()._minProperties = newValue}
  }

  public var required: [String] {
    get {return _storage._required}
    set {_uniqueStorage()._required = newValue}
  }

  public var `enum`: [Openapi_V3_Any] {
    get {return _storage._enum}
    set {_uniqueStorage()._enum = newValue}
  }

  public var type: String {
    get {return _storage._type}
    set {_uniqueStorage()._type = newValue}
  }

  public var allOf: [Openapi_V3_SchemaOrReference] {
    get {return _storage._allOf}
    set {_uniqueStorage()._allOf = newValue}
  }

  public var oneOf: [Openapi_V3_SchemaOrReference] {
    get {return _storage._oneOf}
    set {_uniqueStorage()._oneOf = newValue}
  }

  public var anyOf: [Openapi_V3_SchemaOrReference] {
    get {return _storage._anyOf}
    set {_uniqueStorage()._anyOf = newValue}
  }

  public var not: Openapi_V3_Schema {
    get {return _storage._not ?? Openapi_V3_Schema()}
    set {_uniqueStorage()._not = newValue}
  }
  /// Returns true if `not` has been explicitly set.
  public var hasNot: Bool {return _storage._not != nil}
  /// Clears the value of `not`. Subsequent reads from it will return its default value.
  public mutating func clearNot() {_storage._not = nil}

  public var items: Openapi_V3_ItemsItem {
    get {return _storage._items ?? Openapi_V3_ItemsItem()}
    set {_uniqueStorage()._items = newValue}
  }
  /// Returns true if `items` has been explicitly set.
  public var hasItems: Bool {return _storage._items != nil}
  /// Clears the value of `items`. Subsequent reads from it will return its default value.
  public mutating func clearItems() {_storage._items = nil}

  public var properties: Openapi_V3_Properties {
    get {return _storage._properties ?? Openapi_V3_Properties()}
    set {_uniqueStorage()._properties = newValue}
  }
  /// Returns true if `properties` has been explicitly set.
  public var hasProperties: Bool {return _storage._properties != nil}
  /// Clears the value of `properties`. Subsequent reads from it will return its default value.
  public mutating func clearProperties() {_storage._properties = nil}

  public var additionalProperties: Openapi_V3_AdditionalPropertiesItem {
    get {return _storage._additionalProperties ?? Openapi_V3_AdditionalPropertiesItem()}
    set {_uniqueStorage()._additionalProperties = newValue}
  }
  /// Returns true if `additionalProperties` has been explicitly set.
  public var hasAdditionalProperties: Bool {return _storage._additionalProperties != nil}
  /// Clears the value of `additionalProperties`. Subsequent reads from it will return its default value.
  public mutating func clearAdditionalProperties() {_storage._additionalProperties = nil}

  public var `default`: Openapi_V3_DefaultType {
    get {return _storage._default ?? Openapi_V3_DefaultType()}
    set {_uniqueStorage()._default = newValue}
  }
  /// Returns true if ``default`` has been explicitly set.
  public var hasDefault: Bool {return _storage._default != nil}
  /// Clears the value of ``default``. Subsequent reads from it will return its default value.
  public mutating func clearDefault() {_storage._default = nil}

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var format: String {
    get {return _storage._format}
    set {_uniqueStorage()._format = newValue}
  }

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularBoolField(value: &_storage._nullable)
        case 2: try decoder.decodeSingularMessageField(value: &_storage._discriminator)
        case 3: try decoder.decodeSingularBoolField(value: &_storage._readOnly)
        case 4: try decoder.decodeSingularBoolField(value: &_storage._writeOnly)
        case 5: try decoder.decodeSingularMessageField(value: &_storage._xml)
        case 6: try decoder.decodeSingularMessageField(value: &_storage._externalDocs)
        case 7: try decoder.decodeSingularMessageField(value: &_storage._example)
        case 8: try decoder.decodeSingularBoolField(value: &_storage._deprecated)
        case 9: try decoder.decodeSingularStringField(value: &_storage._title)
        case 10: try decoder.decodeSingularDoubleField(value: &_storage._multipleOf)
        case 11: try decoder.decodeSingularDoubleField(value: &_storage._maximum)
        case 12: try decoder.decodeSingularBoolField(value: &_storage._exclusiveMaximum)
        case 13: try decoder.decodeSingularDoubleField(value: &_storage._minimum)
        case 14: try decoder.decodeSingularBoolField(value: &_storage._exclusiveMinimum)
        case 15: try decoder.decodeSingularInt64Field(value: &_storage._maxLength)
        case 16: try decoder.decodeSingularInt64Field(value: &_storage._minLength)
        case 17: try decoder.decodeSingularStringField(value: &_storage._pattern)
        case 18: try decoder.decodeSingularInt64Field(value: &_storage._maxItems)
        case 19: try decoder.decodeSingularInt64Field(value: &_storage._minItems)
        case 20: try decoder.decodeSingularBoolField(value: &_storage._uniqueItems)
        case 21: try decoder.decodeSingularInt64Field(value: &_storage._maxProperties)
        case 22: try decoder.decodeSingularInt64Field(value: &_storage._minProperties)
        case 23: try decoder.decodeRepeatedStringField(value: &_storage._required)
        case 24: try decoder.decodeRepeatedMessageField(value: &_storage._enum)
        case 25: try decoder.decodeSingularStringField(value: &_storage._type)
        case 26: try decoder.decodeRepeatedMessageField(value: &_storage._allOf)
        case 27: try decoder.decodeRepeatedMessageField(value: &_storage._oneOf)
        case 28: try decoder.decodeRepeatedMessageField(value: &_storage._anyOf)
        case 29: try decoder.decodeSingularMessageField(value: &_storage._not)
        case 30: try decoder.decodeSingularMessageField(value: &_storage._items)
        case 31: try decoder.decodeSingularMessageField(value: &_storage._properties)
        case 32: try decoder.decodeSingularMessageField(value: &_storage._additionalProperties)
        case 33: try decoder.decodeSingularMessageField(value: &_storage._default)
        case 34: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 35: try decoder.decodeSingularStringField(value: &_storage._format)
        case 36: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if _storage._nullable != false {
        try visitor.visitSingularBoolField(value: _storage._nullable, fieldNumber: 1)
      }
      if let v = _storage._discriminator {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      }
      if _storage._readOnly != false {
        try visitor.visitSingularBoolField(value: _storage._readOnly, fieldNumber: 3)
      }
      if _storage._writeOnly != false {
        try visitor.visitSingularBoolField(value: _storage._writeOnly, fieldNumber: 4)
      }
      if let v = _storage._xml {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
      }
      if let v = _storage._externalDocs {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 6)
      }
      if let v = _storage._example {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 7)
      }
      if _storage._deprecated != false {
        try visitor.visitSingularBoolField(value: _storage._deprecated, fieldNumber: 8)
      }
      if !_storage._title.isEmpty {
        try visitor.visitSingularStringField(value: _storage._title, fieldNumber: 9)
      }
      if _storage._multipleOf != 0 {
        try visitor.visitSingularDoubleField(value: _storage._multipleOf, fieldNumber: 10)
      }
      if _storage._maximum != 0 {
        try visitor.visitSingularDoubleField(value: _storage._maximum, fieldNumber: 11)
      }
      if _storage._exclusiveMaximum != false {
        try visitor.visitSingularBoolField(value: _storage._exclusiveMaximum, fieldNumber: 12)
      }
      if _storage._minimum != 0 {
        try visitor.visitSingularDoubleField(value: _storage._minimum, fieldNumber: 13)
      }
      if _storage._exclusiveMinimum != false {
        try visitor.visitSingularBoolField(value: _storage._exclusiveMinimum, fieldNumber: 14)
      }
      if _storage._maxLength != 0 {
        try visitor.visitSingularInt64Field(value: _storage._maxLength, fieldNumber: 15)
      }
      if _storage._minLength != 0 {
        try visitor.visitSingularInt64Field(value: _storage._minLength, fieldNumber: 16)
      }
      if !_storage._pattern.isEmpty {
        try visitor.visitSingularStringField(value: _storage._pattern, fieldNumber: 17)
      }
      if _storage._maxItems != 0 {
        try visitor.visitSingularInt64Field(value: _storage._maxItems, fieldNumber: 18)
      }
      if _storage._minItems != 0 {
        try visitor.visitSingularInt64Field(value: _storage._minItems, fieldNumber: 19)
      }
      if _storage._uniqueItems != false {
        try visitor.visitSingularBoolField(value: _storage._uniqueItems, fieldNumber: 20)
      }
      if _storage._maxProperties != 0 {
        try visitor.visitSingularInt64Field(value: _storage._maxProperties, fieldNumber: 21)
      }
      if _storage._minProperties != 0 {
        try visitor.visitSingularInt64Field(value: _storage._minProperties, fieldNumber: 22)
      }
      if !_storage._required.isEmpty {
        try visitor.visitRepeatedStringField(value: _storage._required, fieldNumber: 23)
      }
      if !_storage._enum.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._enum, fieldNumber: 24)
      }
      if !_storage._type.isEmpty {
        try visitor.visitSingularStringField(value: _storage._type, fieldNumber: 25)
      }
      if !_storage._allOf.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._allOf, fieldNumber: 26)
      }
      if !_storage._oneOf.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._oneOf, fieldNumber: 27)
      }
      if !_storage._anyOf.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._anyOf, fieldNumber: 28)
      }
      if let v = _storage._not {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 29)
      }
      if let v = _storage._items {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 30)
      }
      if let v = _storage._properties {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 31)
      }
      if let v = _storage._additionalProperties {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 32)
      }
      if let v = _storage._default {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 33)
      }
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 34)
      }
      if !_storage._format.isEmpty {
        try visitor.visitSingularStringField(value: _storage._format, fieldNumber: 35)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 36)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_SchemaOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".SchemaOrReference"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var schema: Openapi_V3_Schema {
    get {
      if case .schema(let v)? = _storage._oneof {return v}
      return Openapi_V3_Schema()
    }
    set {_uniqueStorage()._oneof = .schema(newValue)}
  }

  public var reference: Openapi_V3_Reference {
    get {
      if case .reference(let v)? = _storage._oneof {return v}
      return Openapi_V3_Reference()
    }
    set {_uniqueStorage()._oneof = .reference(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case schema(Openapi_V3_Schema)
    case reference(Openapi_V3_Reference)

    public static func ==(lhs: Openapi_V3_SchemaOrReference.OneOf_Oneof, rhs: Openapi_V3_SchemaOrReference.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.schema(let l), .schema(let r)): return l == r
      case (.reference(let l), .reference(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_Schema?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .schema(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .schema(v)}
        case 2:
          var v: Openapi_V3_Reference?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .reference(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .reference(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .schema(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .reference(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_SchemasOrReferences: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".SchemasOrReferences"

  public var additionalProperties: [Openapi_V3_NamedSchemaOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Lists the required security schemes to execute this operation. The name used for each property MUST correspond to a security scheme declared in the Security Schemes under the Components Object.  Security Requirement Objects that contain multiple schemes require that all schemes MUST be satisfied for a request to be authorized. This enables support for scenarios where multiple query parameters or HTTP headers are required to convey security information.  When a list of Security Requirement Objects is defined on the Open API object or Operation Object, only one of Security Requirement Objects in the list needs to be satisfied to authorize the request.
public struct Openapi_V3_SecurityRequirement: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".SecurityRequirement"

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let _ = try decoder.nextFieldNumber() {
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Defines a security scheme that can be used by the operations. Supported schemes are HTTP authentication, an API key (either as a header or as a query parameter), OAuth2's common flows (implicit, password, application and access code) as defined in RFC6749, and OpenID Connect Discovery.
public struct Openapi_V3_SecurityScheme: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".SecurityScheme"

  public var type: String {
    get {return _storage._type}
    set {_uniqueStorage()._type = newValue}
  }

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  public var `in`: String {
    get {return _storage._in}
    set {_uniqueStorage()._in = newValue}
  }

  public var scheme: String {
    get {return _storage._scheme}
    set {_uniqueStorage()._scheme = newValue}
  }

  public var bearerFormat: String {
    get {return _storage._bearerFormat}
    set {_uniqueStorage()._bearerFormat = newValue}
  }

  public var flows: Openapi_V3_OauthFlows {
    get {return _storage._flows ?? Openapi_V3_OauthFlows()}
    set {_uniqueStorage()._flows = newValue}
  }
  /// Returns true if `flows` has been explicitly set.
  public var hasFlows: Bool {return _storage._flows != nil}
  /// Clears the value of `flows`. Subsequent reads from it will return its default value.
  public mutating func clearFlows() {_storage._flows = nil}

  public var openIDConnectURL: String {
    get {return _storage._openIDConnectURL}
    set {_uniqueStorage()._openIDConnectURL = newValue}
  }

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._type)
        case 2: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 3: try decoder.decodeSingularStringField(value: &_storage._name)
        case 4: try decoder.decodeSingularStringField(value: &_storage._in)
        case 5: try decoder.decodeSingularStringField(value: &_storage._scheme)
        case 6: try decoder.decodeSingularStringField(value: &_storage._bearerFormat)
        case 7: try decoder.decodeSingularMessageField(value: &_storage._flows)
        case 8: try decoder.decodeSingularStringField(value: &_storage._openIDConnectURL)
        case 9: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._type.isEmpty {
        try visitor.visitSingularStringField(value: _storage._type, fieldNumber: 1)
      }
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 2)
      }
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 3)
      }
      if !_storage._in.isEmpty {
        try visitor.visitSingularStringField(value: _storage._in, fieldNumber: 4)
      }
      if !_storage._scheme.isEmpty {
        try visitor.visitSingularStringField(value: _storage._scheme, fieldNumber: 5)
      }
      if !_storage._bearerFormat.isEmpty {
        try visitor.visitSingularStringField(value: _storage._bearerFormat, fieldNumber: 6)
      }
      if let v = _storage._flows {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 7)
      }
      if !_storage._openIDConnectURL.isEmpty {
        try visitor.visitSingularStringField(value: _storage._openIDConnectURL, fieldNumber: 8)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 9)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_SecuritySchemeOrReference: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".SecuritySchemeOrReference"

  public var oneof: OneOf_Oneof? {
    get {return _storage._oneof}
    set {_uniqueStorage()._oneof = newValue}
  }

  public var securityScheme: Openapi_V3_SecurityScheme {
    get {
      if case .securityScheme(let v)? = _storage._oneof {return v}
      return Openapi_V3_SecurityScheme()
    }
    set {_uniqueStorage()._oneof = .securityScheme(newValue)}
  }

  public var reference: Openapi_V3_Reference {
    get {
      if case .reference(let v)? = _storage._oneof {return v}
      return Openapi_V3_Reference()
    }
    set {_uniqueStorage()._oneof = .reference(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case securityScheme(Openapi_V3_SecurityScheme)
    case reference(Openapi_V3_Reference)

    public static func ==(lhs: Openapi_V3_SecuritySchemeOrReference.OneOf_Oneof, rhs: Openapi_V3_SecuritySchemeOrReference.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.securityScheme(let l), .securityScheme(let r)): return l == r
      case (.reference(let l), .reference(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1:
          var v: Openapi_V3_SecurityScheme?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .securityScheme(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .securityScheme(v)}
        case 2:
          var v: Openapi_V3_Reference?
          if let current = _storage._oneof {
            try decoder.handleConflictingOneOf()
            if case .reference(let m) = current {v = m}
          }
          try decoder.decodeSingularMessageField(value: &v)
          if let v = v {_storage._oneof = .reference(v)}
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      switch _storage._oneof {
      case .securityScheme(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
      case .reference(let v)?:
        try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
      case nil: break
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

public struct Openapi_V3_SecuritySchemesOrReferences: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".SecuritySchemesOrReferences"

  public var additionalProperties: [Openapi_V3_NamedSecuritySchemeOrReference] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// An object representing a Server.
public struct Openapi_V3_Server: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Server"

  public var url: String {
    get {return _storage._url}
    set {_uniqueStorage()._url = newValue}
  }

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var variables: Openapi_V3_ServerVariables {
    get {return _storage._variables ?? Openapi_V3_ServerVariables()}
    set {_uniqueStorage()._variables = newValue}
  }
  /// Returns true if `variables` has been explicitly set.
  public var hasVariables: Bool {return _storage._variables != nil}
  /// Clears the value of `variables`. Subsequent reads from it will return its default value.
  public mutating func clearVariables() {_storage._variables = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._url)
        case 2: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 3: try decoder.decodeSingularMessageField(value: &_storage._variables)
        case 4: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._url.isEmpty {
        try visitor.visitSingularStringField(value: _storage._url, fieldNumber: 1)
      }
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 2)
      }
      if let v = _storage._variables {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 4)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// An object representing a Server Variable for server URL template substitution.
public struct Openapi_V3_ServerVariable: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".ServerVariable"

  public var `enum`: [String] = []

  public var `default`: String = String()

  public var description_p: String = String()

  public var specificationExtension: [Openapi_V3_NamedAny] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedStringField(value: &self.`enum`)
      case 2: try decoder.decodeSingularStringField(value: &self.`default`)
      case 3: try decoder.decodeSingularStringField(value: &self.description_p)
      case 4: try decoder.decodeRepeatedMessageField(value: &self.specificationExtension)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.`enum`.isEmpty {
      try visitor.visitRepeatedStringField(value: self.`enum`, fieldNumber: 1)
    }
    if !self.`default`.isEmpty {
      try visitor.visitSingularStringField(value: self.`default`, fieldNumber: 2)
    }
    if !self.description_p.isEmpty {
      try visitor.visitSingularStringField(value: self.description_p, fieldNumber: 3)
    }
    if !self.specificationExtension.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.specificationExtension, fieldNumber: 4)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

public struct Openapi_V3_ServerVariables: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".ServerVariables"

  public var additionalProperties: [Openapi_V3_NamedServerVariable] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Any property starting with x- is valid.
public struct Openapi_V3_SpecificationExtension: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".SpecificationExtension"

  public var oneof: Openapi_V3_SpecificationExtension.OneOf_Oneof? = nil

  public var number: Double {
    get {
      if case .number(let v)? = oneof {return v}
      return 0
    }
    set {oneof = .number(newValue)}
  }

  public var boolean: Bool {
    get {
      if case .boolean(let v)? = oneof {return v}
      return false
    }
    set {oneof = .boolean(newValue)}
  }

  public var string: String {
    get {
      if case .string(let v)? = oneof {return v}
      return String()
    }
    set {oneof = .string(newValue)}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public enum OneOf_Oneof: Equatable {
    case number(Double)
    case boolean(Bool)
    case string(String)

    public static func ==(lhs: Openapi_V3_SpecificationExtension.OneOf_Oneof, rhs: Openapi_V3_SpecificationExtension.OneOf_Oneof) -> Bool {
      switch (lhs, rhs) {
      case (.number(let l), .number(let r)): return l == r
      case (.boolean(let l), .boolean(let r)): return l == r
      case (.string(let l), .string(let r)): return l == r
      default: return false
      }
    }
  }

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1:
        if self.oneof != nil {try decoder.handleConflictingOneOf()}
        var v: Double?
        try decoder.decodeSingularDoubleField(value: &v)
        if let v = v {self.oneof = .number(v)}
      case 2:
        if self.oneof != nil {try decoder.handleConflictingOneOf()}
        var v: Bool?
        try decoder.decodeSingularBoolField(value: &v)
        if let v = v {self.oneof = .boolean(v)}
      case 3:
        if self.oneof != nil {try decoder.handleConflictingOneOf()}
        var v: String?
        try decoder.decodeSingularStringField(value: &v)
        if let v = v {self.oneof = .string(v)}
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    switch self.oneof {
    case .number(let v)?:
      try visitor.visitSingularDoubleField(value: v, fieldNumber: 1)
    case .boolean(let v)?:
      try visitor.visitSingularBoolField(value: v, fieldNumber: 2)
    case .string(let v)?:
      try visitor.visitSingularStringField(value: v, fieldNumber: 3)
    case nil: break
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

public struct Openapi_V3_StringArray: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".StringArray"

  public var value: [String] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedStringField(value: &self.value)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.value.isEmpty {
      try visitor.visitRepeatedStringField(value: self.value, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

public struct Openapi_V3_Strings: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Strings"

  public var additionalProperties: [Openapi_V3_NamedString] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeRepeatedMessageField(value: &self.additionalProperties)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.additionalProperties.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.additionalProperties, fieldNumber: 1)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

/// Adds metadata to a single tag that is used by the Operation Object. It is not mandatory to have a Tag Object per tag defined in the Operation Object instances.
public struct Openapi_V3_Tag: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Tag"

  public var name: String {
    get {return _storage._name}
    set {_uniqueStorage()._name = newValue}
  }

  public var description_p: String {
    get {return _storage._description_p}
    set {_uniqueStorage()._description_p = newValue}
  }

  public var externalDocs: Openapi_V3_ExternalDocs {
    get {return _storage._externalDocs ?? Openapi_V3_ExternalDocs()}
    set {_uniqueStorage()._externalDocs = newValue}
  }
  /// Returns true if `externalDocs` has been explicitly set.
  public var hasExternalDocs: Bool {return _storage._externalDocs != nil}
  /// Clears the value of `externalDocs`. Subsequent reads from it will return its default value.
  public mutating func clearExternalDocs() {_storage._externalDocs = nil}

  public var specificationExtension: [Openapi_V3_NamedAny] {
    get {return _storage._specificationExtension}
    set {_uniqueStorage()._specificationExtension = newValue}
  }

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    _ = _uniqueStorage()
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      while let fieldNumber = try decoder.nextFieldNumber() {
        switch fieldNumber {
        case 1: try decoder.decodeSingularStringField(value: &_storage._name)
        case 2: try decoder.decodeSingularStringField(value: &_storage._description_p)
        case 3: try decoder.decodeSingularMessageField(value: &_storage._externalDocs)
        case 4: try decoder.decodeRepeatedMessageField(value: &_storage._specificationExtension)
        default: break
        }
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
      if !_storage._name.isEmpty {
        try visitor.visitSingularStringField(value: _storage._name, fieldNumber: 1)
      }
      if !_storage._description_p.isEmpty {
        try visitor.visitSingularStringField(value: _storage._description_p, fieldNumber: 2)
      }
      if let v = _storage._externalDocs {
        try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
      }
      if !_storage._specificationExtension.isEmpty {
        try visitor.visitRepeatedMessageField(value: _storage._specificationExtension, fieldNumber: 4)
      }
    }
    try unknownFields.traverse(visitor: &visitor)
  }

  fileprivate var _storage = _StorageClass.defaultInstance
}

/// A metadata object that allows for more fine-tuned XML model definitions.  When using arrays, XML element names are *not* inferred (for singular/plural forms) and the `name` property SHOULD be used to add that information. See examples for expected behavior.
public struct Openapi_V3_Xml: SwiftProtobuf.Message {
  public static let protoMessageName: String = _protobuf_package + ".Xml"

  public var name: String = String()

  public var namespace: String = String()

  public var prefix: String = String()

  public var attribute: Bool = false

  public var wrapped: Bool = false

  public var specificationExtension: [Openapi_V3_NamedAny] = []

  public var unknownFields = SwiftProtobuf.UnknownStorage()

  public init() {}

  /// Used by the decoding initializers in the SwiftProtobuf library, not generally
  /// used directly. `init(serializedData:)`, `init(jsonUTF8Data:)`, and other decoding
  /// initializers are defined in the SwiftProtobuf library. See the Message and
  /// Message+*Additions` files.
  public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
    while let fieldNumber = try decoder.nextFieldNumber() {
      switch fieldNumber {
      case 1: try decoder.decodeSingularStringField(value: &self.name)
      case 2: try decoder.decodeSingularStringField(value: &self.namespace)
      case 3: try decoder.decodeSingularStringField(value: &self.prefix)
      case 4: try decoder.decodeSingularBoolField(value: &self.attribute)
      case 5: try decoder.decodeSingularBoolField(value: &self.wrapped)
      case 6: try decoder.decodeRepeatedMessageField(value: &self.specificationExtension)
      default: break
      }
    }
  }

  /// Used by the encoding methods of the SwiftProtobuf library, not generally
  /// used directly. `Message.serializedData()`, `Message.jsonUTF8Data()`, and
  /// other serializer methods are defined in the SwiftProtobuf library. See the
  /// `Message` and `Message+*Additions` files.
  public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
    if !self.name.isEmpty {
      try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
    }
    if !self.namespace.isEmpty {
      try visitor.visitSingularStringField(value: self.namespace, fieldNumber: 2)
    }
    if !self.prefix.isEmpty {
      try visitor.visitSingularStringField(value: self.prefix, fieldNumber: 3)
    }
    if self.attribute != false {
      try visitor.visitSingularBoolField(value: self.attribute, fieldNumber: 4)
    }
    if self.wrapped != false {
      try visitor.visitSingularBoolField(value: self.wrapped, fieldNumber: 5)
    }
    if !self.specificationExtension.isEmpty {
      try visitor.visitRepeatedMessageField(value: self.specificationExtension, fieldNumber: 6)
    }
    try unknownFields.traverse(visitor: &visitor)
  }
}

// MARK: - Code below here is support for the SwiftProtobuf runtime.

fileprivate let _protobuf_package = "openapi.v3"

extension Openapi_V3_AdditionalPropertiesItem: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "schema_or_reference"),
    2: .same(proto: "boolean"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_AdditionalPropertiesItem.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_AdditionalPropertiesItem) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Any: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "value"),
    2: .same(proto: "yaml"),
  ]

  fileprivate class _StorageClass {
    var _value: SwiftProtobuf.Google_Protobuf_Any? = nil
    var _yaml: String = String()

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _value = source._value
      _yaml = source._yaml
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Any) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._value != other_storage._value {return false}
        if _storage._yaml != other_storage._yaml {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_AnyOrExpression: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "any"),
    2: .same(proto: "expression"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_AnyOrExpression.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_AnyOrExpression) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_AnysOrExpressions: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_AnysOrExpressions) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Callback: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "path"),
    2: .standard(proto: "specification_extension"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Callback) -> Bool {
    if self.path != other.path {return false}
    if self.specificationExtension != other.specificationExtension {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_CallbackOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "callback"),
    2: .same(proto: "reference"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_CallbackOrReference.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_CallbackOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_CallbacksOrReferences: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_CallbacksOrReferences) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Components: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "schemas"),
    2: .same(proto: "responses"),
    3: .same(proto: "parameters"),
    4: .same(proto: "examples"),
    5: .standard(proto: "request_bodies"),
    6: .same(proto: "headers"),
    7: .standard(proto: "security_schemes"),
    8: .same(proto: "links"),
    9: .same(proto: "callbacks"),
    10: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _schemas: Openapi_V3_SchemasOrReferences? = nil
    var _responses: Openapi_V3_ResponsesOrReferences? = nil
    var _parameters: Openapi_V3_ParametersOrReferences? = nil
    var _examples: Openapi_V3_ExamplesOrReferences? = nil
    var _requestBodies: Openapi_V3_RequestBodiesOrReferences? = nil
    var _headers: Openapi_V3_HeadersOrReferences? = nil
    var _securitySchemes: Openapi_V3_SecuritySchemesOrReferences? = nil
    var _links: Openapi_V3_LinksOrReferences? = nil
    var _callbacks: Openapi_V3_CallbacksOrReferences? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _schemas = source._schemas
      _responses = source._responses
      _parameters = source._parameters
      _examples = source._examples
      _requestBodies = source._requestBodies
      _headers = source._headers
      _securitySchemes = source._securitySchemes
      _links = source._links
      _callbacks = source._callbacks
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Components) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._schemas != other_storage._schemas {return false}
        if _storage._responses != other_storage._responses {return false}
        if _storage._parameters != other_storage._parameters {return false}
        if _storage._examples != other_storage._examples {return false}
        if _storage._requestBodies != other_storage._requestBodies {return false}
        if _storage._headers != other_storage._headers {return false}
        if _storage._securitySchemes != other_storage._securitySchemes {return false}
        if _storage._links != other_storage._links {return false}
        if _storage._callbacks != other_storage._callbacks {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Contact: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "url"),
    3: .same(proto: "email"),
    4: .standard(proto: "specification_extension"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Contact) -> Bool {
    if self.name != other.name {return false}
    if self.url != other.url {return false}
    if self.email != other.email {return false}
    if self.specificationExtension != other.specificationExtension {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_DefaultType: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "number"),
    2: .same(proto: "boolean"),
    3: .same(proto: "string"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_DefaultType) -> Bool {
    if self.oneof != other.oneof {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Discriminator: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "property_name"),
    2: .same(proto: "mapping"),
  ]

  fileprivate class _StorageClass {
    var _propertyName: String = String()
    var _mapping: Openapi_V3_Strings? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _propertyName = source._propertyName
      _mapping = source._mapping
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Discriminator) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._propertyName != other_storage._propertyName {return false}
        if _storage._mapping != other_storage._mapping {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Document: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "openapi"),
    2: .same(proto: "info"),
    3: .same(proto: "servers"),
    4: .same(proto: "paths"),
    5: .same(proto: "components"),
    6: .same(proto: "security"),
    7: .same(proto: "tags"),
    8: .standard(proto: "external_docs"),
    9: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _openapi: String = String()
    var _info: Openapi_V3_Info? = nil
    var _servers: [Openapi_V3_Server] = []
    var _paths: Openapi_V3_Paths? = nil
    var _components: Openapi_V3_Components? = nil
    var _security: [Openapi_V3_SecurityRequirement] = []
    var _tags: [Openapi_V3_Tag] = []
    var _externalDocs: Openapi_V3_ExternalDocs? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _openapi = source._openapi
      _info = source._info
      _servers = source._servers
      _paths = source._paths
      _components = source._components
      _security = source._security
      _tags = source._tags
      _externalDocs = source._externalDocs
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Document) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._openapi != other_storage._openapi {return false}
        if _storage._info != other_storage._info {return false}
        if _storage._servers != other_storage._servers {return false}
        if _storage._paths != other_storage._paths {return false}
        if _storage._components != other_storage._components {return false}
        if _storage._security != other_storage._security {return false}
        if _storage._tags != other_storage._tags {return false}
        if _storage._externalDocs != other_storage._externalDocs {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Encoding: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "content_type"),
    2: .same(proto: "headers"),
    3: .same(proto: "style"),
    4: .same(proto: "explode"),
    5: .standard(proto: "allow_reserved"),
    6: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _contentType: String = String()
    var _headers: Openapi_V3_HeadersOrReferences? = nil
    var _style: String = String()
    var _explode: Bool = false
    var _allowReserved: Bool = false
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _contentType = source._contentType
      _headers = source._headers
      _style = source._style
      _explode = source._explode
      _allowReserved = source._allowReserved
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Encoding) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._contentType != other_storage._contentType {return false}
        if _storage._headers != other_storage._headers {return false}
        if _storage._style != other_storage._style {return false}
        if _storage._explode != other_storage._explode {return false}
        if _storage._allowReserved != other_storage._allowReserved {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Encodings: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Encodings) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Example: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "summary"),
    2: .same(proto: "description"),
    3: .same(proto: "value"),
    4: .standard(proto: "external_value"),
    5: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _summary: String = String()
    var _description_p: String = String()
    var _value: Openapi_V3_Any? = nil
    var _externalValue: String = String()
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _summary = source._summary
      _description_p = source._description_p
      _value = source._value
      _externalValue = source._externalValue
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Example) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._summary != other_storage._summary {return false}
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._value != other_storage._value {return false}
        if _storage._externalValue != other_storage._externalValue {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_ExampleOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "example"),
    2: .same(proto: "reference"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_ExampleOrReference.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_ExampleOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Examples: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap = SwiftProtobuf._NameMap()

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Examples) -> Bool {
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_ExamplesOrReferences: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_ExamplesOrReferences) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Expression: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Expression) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_ExternalDocs: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "description"),
    2: .same(proto: "url"),
    3: .standard(proto: "specification_extension"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_ExternalDocs) -> Bool {
    if self.description_p != other.description_p {return false}
    if self.url != other.url {return false}
    if self.specificationExtension != other.specificationExtension {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Header: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "description"),
    2: .same(proto: "required"),
    3: .same(proto: "deprecated"),
    4: .standard(proto: "allow_empty_value"),
    5: .same(proto: "style"),
    6: .same(proto: "explode"),
    7: .standard(proto: "allow_reserved"),
    8: .same(proto: "schema"),
    9: .same(proto: "example"),
    10: .same(proto: "examples"),
    11: .same(proto: "content"),
    12: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _description_p: String = String()
    var _required: Bool = false
    var _deprecated: Bool = false
    var _allowEmptyValue: Bool = false
    var _style: String = String()
    var _explode: Bool = false
    var _allowReserved: Bool = false
    var _schema: Openapi_V3_SchemaOrReference? = nil
    var _example: Openapi_V3_Any? = nil
    var _examples: Openapi_V3_ExamplesOrReferences? = nil
    var _content: Openapi_V3_MediaTypes? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _description_p = source._description_p
      _required = source._required
      _deprecated = source._deprecated
      _allowEmptyValue = source._allowEmptyValue
      _style = source._style
      _explode = source._explode
      _allowReserved = source._allowReserved
      _schema = source._schema
      _example = source._example
      _examples = source._examples
      _content = source._content
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Header) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._required != other_storage._required {return false}
        if _storage._deprecated != other_storage._deprecated {return false}
        if _storage._allowEmptyValue != other_storage._allowEmptyValue {return false}
        if _storage._style != other_storage._style {return false}
        if _storage._explode != other_storage._explode {return false}
        if _storage._allowReserved != other_storage._allowReserved {return false}
        if _storage._schema != other_storage._schema {return false}
        if _storage._example != other_storage._example {return false}
        if _storage._examples != other_storage._examples {return false}
        if _storage._content != other_storage._content {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_HeaderOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "header"),
    2: .same(proto: "reference"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_HeaderOrReference.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_HeaderOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_HeadersOrReferences: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_HeadersOrReferences) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Info: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "title"),
    2: .same(proto: "description"),
    3: .standard(proto: "terms_of_service"),
    4: .same(proto: "contact"),
    5: .same(proto: "license"),
    6: .same(proto: "version"),
    7: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _title: String = String()
    var _description_p: String = String()
    var _termsOfService: String = String()
    var _contact: Openapi_V3_Contact? = nil
    var _license: Openapi_V3_License? = nil
    var _version: String = String()
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _title = source._title
      _description_p = source._description_p
      _termsOfService = source._termsOfService
      _contact = source._contact
      _license = source._license
      _version = source._version
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Info) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._title != other_storage._title {return false}
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._termsOfService != other_storage._termsOfService {return false}
        if _storage._contact != other_storage._contact {return false}
        if _storage._license != other_storage._license {return false}
        if _storage._version != other_storage._version {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_ItemsItem: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "schema_or_reference"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_ItemsItem) -> Bool {
    if self.schemaOrReference != other.schemaOrReference {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_License: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "url"),
    3: .standard(proto: "specification_extension"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_License) -> Bool {
    if self.name != other.name {return false}
    if self.url != other.url {return false}
    if self.specificationExtension != other.specificationExtension {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Link: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "operation_ref"),
    2: .standard(proto: "operation_id"),
    3: .same(proto: "parameters"),
    4: .standard(proto: "request_body"),
    5: .same(proto: "description"),
    6: .same(proto: "server"),
    7: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _operationRef: String = String()
    var _operationID: String = String()
    var _parameters: Openapi_V3_AnysOrExpressions? = nil
    var _requestBody: Openapi_V3_AnyOrExpression? = nil
    var _description_p: String = String()
    var _server: Openapi_V3_Server? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _operationRef = source._operationRef
      _operationID = source._operationID
      _parameters = source._parameters
      _requestBody = source._requestBody
      _description_p = source._description_p
      _server = source._server
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Link) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._operationRef != other_storage._operationRef {return false}
        if _storage._operationID != other_storage._operationID {return false}
        if _storage._parameters != other_storage._parameters {return false}
        if _storage._requestBody != other_storage._requestBody {return false}
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._server != other_storage._server {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_LinkOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "link"),
    2: .same(proto: "reference"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_LinkOrReference.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_LinkOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_LinksOrReferences: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_LinksOrReferences) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_MediaType: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "schema"),
    2: .same(proto: "example"),
    3: .same(proto: "examples"),
    4: .same(proto: "encoding"),
    5: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _schema: Openapi_V3_SchemaOrReference? = nil
    var _example: Openapi_V3_Any? = nil
    var _examples: Openapi_V3_ExamplesOrReferences? = nil
    var _encoding: Openapi_V3_Encodings? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _schema = source._schema
      _example = source._example
      _examples = source._examples
      _encoding = source._encoding
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_MediaType) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._schema != other_storage._schema {return false}
        if _storage._example != other_storage._example {return false}
        if _storage._examples != other_storage._examples {return false}
        if _storage._encoding != other_storage._encoding {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_MediaTypes: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_MediaTypes) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedAny: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_Any? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedAny) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedAnyOrExpression: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_AnyOrExpression? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedAnyOrExpression) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedCallbackOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_CallbackOrReference? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedCallbackOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedEncoding: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_Encoding? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedEncoding) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedExampleOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_ExampleOrReference? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedExampleOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedHeaderOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_HeaderOrReference? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedHeaderOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedLinkOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_LinkOrReference? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedLinkOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedMediaType: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_MediaType? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedMediaType) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedParameterOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_ParameterOrReference? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedParameterOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedPathItem: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_PathItem? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedPathItem) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedRequestBodyOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_RequestBodyOrReference? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedRequestBodyOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedResponseOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_ResponseOrReference? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedResponseOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedSchemaOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_SchemaOrReference? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedSchemaOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedSecuritySchemeOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_SecuritySchemeOrReference? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedSecuritySchemeOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedServerVariable: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _value: Openapi_V3_ServerVariable? = nil

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _value = source._value
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedServerVariable) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._value != other_storage._value {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_NamedString: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "value"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_NamedString) -> Bool {
    if self.name != other.name {return false}
    if self.value != other.value {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_OauthFlow: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "authorization_url"),
    2: .standard(proto: "token_url"),
    3: .standard(proto: "refresh_url"),
    4: .same(proto: "scopes"),
    5: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _authorizationURL: String = String()
    var _tokenURL: String = String()
    var _refreshURL: String = String()
    var _scopes: Openapi_V3_Strings? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _authorizationURL = source._authorizationURL
      _tokenURL = source._tokenURL
      _refreshURL = source._refreshURL
      _scopes = source._scopes
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_OauthFlow) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._authorizationURL != other_storage._authorizationURL {return false}
        if _storage._tokenURL != other_storage._tokenURL {return false}
        if _storage._refreshURL != other_storage._refreshURL {return false}
        if _storage._scopes != other_storage._scopes {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_OauthFlows: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "implicit"),
    2: .same(proto: "password"),
    3: .standard(proto: "client_credentials"),
    4: .standard(proto: "authorization_code"),
    5: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _implicit: Openapi_V3_OauthFlow? = nil
    var _password: Openapi_V3_OauthFlow? = nil
    var _clientCredentials: Openapi_V3_OauthFlow? = nil
    var _authorizationCode: Openapi_V3_OauthFlow? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _implicit = source._implicit
      _password = source._password
      _clientCredentials = source._clientCredentials
      _authorizationCode = source._authorizationCode
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_OauthFlows) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._implicit != other_storage._implicit {return false}
        if _storage._password != other_storage._password {return false}
        if _storage._clientCredentials != other_storage._clientCredentials {return false}
        if _storage._authorizationCode != other_storage._authorizationCode {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Object: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Object) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Operation: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "tags"),
    2: .same(proto: "summary"),
    3: .same(proto: "description"),
    4: .standard(proto: "external_docs"),
    5: .standard(proto: "operation_id"),
    6: .same(proto: "parameters"),
    7: .standard(proto: "request_body"),
    8: .same(proto: "responses"),
    9: .same(proto: "callbacks"),
    10: .same(proto: "deprecated"),
    11: .same(proto: "security"),
    12: .same(proto: "servers"),
    13: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _tags: [String] = []
    var _summary: String = String()
    var _description_p: String = String()
    var _externalDocs: Openapi_V3_ExternalDocs? = nil
    var _operationID: String = String()
    var _parameters: [Openapi_V3_ParameterOrReference] = []
    var _requestBody: Openapi_V3_RequestBodyOrReference? = nil
    var _responses: Openapi_V3_Responses? = nil
    var _callbacks: Openapi_V3_CallbacksOrReferences? = nil
    var _deprecated: Bool = false
    var _security: [Openapi_V3_SecurityRequirement] = []
    var _servers: [Openapi_V3_Server] = []
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _tags = source._tags
      _summary = source._summary
      _description_p = source._description_p
      _externalDocs = source._externalDocs
      _operationID = source._operationID
      _parameters = source._parameters
      _requestBody = source._requestBody
      _responses = source._responses
      _callbacks = source._callbacks
      _deprecated = source._deprecated
      _security = source._security
      _servers = source._servers
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Operation) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._tags != other_storage._tags {return false}
        if _storage._summary != other_storage._summary {return false}
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._externalDocs != other_storage._externalDocs {return false}
        if _storage._operationID != other_storage._operationID {return false}
        if _storage._parameters != other_storage._parameters {return false}
        if _storage._requestBody != other_storage._requestBody {return false}
        if _storage._responses != other_storage._responses {return false}
        if _storage._callbacks != other_storage._callbacks {return false}
        if _storage._deprecated != other_storage._deprecated {return false}
        if _storage._security != other_storage._security {return false}
        if _storage._servers != other_storage._servers {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Parameter: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "in"),
    3: .same(proto: "description"),
    4: .same(proto: "required"),
    5: .same(proto: "deprecated"),
    6: .standard(proto: "allow_empty_value"),
    7: .same(proto: "style"),
    8: .same(proto: "explode"),
    9: .standard(proto: "allow_reserved"),
    10: .same(proto: "schema"),
    11: .same(proto: "example"),
    12: .same(proto: "examples"),
    13: .same(proto: "content"),
    14: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _in: String = String()
    var _description_p: String = String()
    var _required: Bool = false
    var _deprecated: Bool = false
    var _allowEmptyValue: Bool = false
    var _style: String = String()
    var _explode: Bool = false
    var _allowReserved: Bool = false
    var _schema: Openapi_V3_SchemaOrReference? = nil
    var _example: Openapi_V3_Any? = nil
    var _examples: Openapi_V3_ExamplesOrReferences? = nil
    var _content: Openapi_V3_MediaTypes? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _in = source._in
      _description_p = source._description_p
      _required = source._required
      _deprecated = source._deprecated
      _allowEmptyValue = source._allowEmptyValue
      _style = source._style
      _explode = source._explode
      _allowReserved = source._allowReserved
      _schema = source._schema
      _example = source._example
      _examples = source._examples
      _content = source._content
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Parameter) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._in != other_storage._in {return false}
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._required != other_storage._required {return false}
        if _storage._deprecated != other_storage._deprecated {return false}
        if _storage._allowEmptyValue != other_storage._allowEmptyValue {return false}
        if _storage._style != other_storage._style {return false}
        if _storage._explode != other_storage._explode {return false}
        if _storage._allowReserved != other_storage._allowReserved {return false}
        if _storage._schema != other_storage._schema {return false}
        if _storage._example != other_storage._example {return false}
        if _storage._examples != other_storage._examples {return false}
        if _storage._content != other_storage._content {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_ParameterOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "parameter"),
    2: .same(proto: "reference"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_ParameterOrReference.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_ParameterOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_ParametersOrReferences: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_ParametersOrReferences) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_PathItem: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "_ref"),
    2: .same(proto: "summary"),
    3: .same(proto: "description"),
    4: .same(proto: "get"),
    5: .same(proto: "put"),
    6: .same(proto: "post"),
    7: .same(proto: "delete"),
    8: .same(proto: "options"),
    9: .same(proto: "head"),
    10: .same(proto: "patch"),
    11: .same(proto: "trace"),
    12: .same(proto: "servers"),
    13: .same(proto: "parameters"),
    14: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _ref: String = String()
    var _summary: String = String()
    var _description_p: String = String()
    var _get: Openapi_V3_Operation? = nil
    var _put: Openapi_V3_Operation? = nil
    var _post: Openapi_V3_Operation? = nil
    var _delete: Openapi_V3_Operation? = nil
    var _options: Openapi_V3_Operation? = nil
    var _head: Openapi_V3_Operation? = nil
    var _patch: Openapi_V3_Operation? = nil
    var _trace: Openapi_V3_Operation? = nil
    var _servers: [Openapi_V3_Server] = []
    var _parameters: [Openapi_V3_ParameterOrReference] = []
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _ref = source._ref
      _summary = source._summary
      _description_p = source._description_p
      _get = source._get
      _put = source._put
      _post = source._post
      _delete = source._delete
      _options = source._options
      _head = source._head
      _patch = source._patch
      _trace = source._trace
      _servers = source._servers
      _parameters = source._parameters
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_PathItem) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._ref != other_storage._ref {return false}
        if _storage._summary != other_storage._summary {return false}
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._get != other_storage._get {return false}
        if _storage._put != other_storage._put {return false}
        if _storage._post != other_storage._post {return false}
        if _storage._delete != other_storage._delete {return false}
        if _storage._options != other_storage._options {return false}
        if _storage._head != other_storage._head {return false}
        if _storage._patch != other_storage._patch {return false}
        if _storage._trace != other_storage._trace {return false}
        if _storage._servers != other_storage._servers {return false}
        if _storage._parameters != other_storage._parameters {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Paths: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "path"),
    2: .standard(proto: "specification_extension"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Paths) -> Bool {
    if self.path != other.path {return false}
    if self.specificationExtension != other.specificationExtension {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Properties: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Properties) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Reference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "_ref"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Reference) -> Bool {
    if self.ref != other.ref {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_RequestBodiesOrReferences: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_RequestBodiesOrReferences) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_RequestBody: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "description"),
    2: .same(proto: "content"),
    3: .same(proto: "required"),
    4: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _description_p: String = String()
    var _content: Openapi_V3_MediaTypes? = nil
    var _required: Bool = false
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _description_p = source._description_p
      _content = source._content
      _required = source._required
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_RequestBody) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._content != other_storage._content {return false}
        if _storage._required != other_storage._required {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_RequestBodyOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "request_body"),
    2: .same(proto: "reference"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_RequestBodyOrReference.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_RequestBodyOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Response: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "description"),
    2: .same(proto: "headers"),
    3: .same(proto: "content"),
    4: .same(proto: "links"),
    5: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _description_p: String = String()
    var _headers: Openapi_V3_HeadersOrReferences? = nil
    var _content: Openapi_V3_MediaTypes? = nil
    var _links: Openapi_V3_LinksOrReferences? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _description_p = source._description_p
      _headers = source._headers
      _content = source._content
      _links = source._links
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Response) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._headers != other_storage._headers {return false}
        if _storage._content != other_storage._content {return false}
        if _storage._links != other_storage._links {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_ResponseOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "response"),
    2: .same(proto: "reference"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_ResponseOrReference.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_ResponseOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Responses: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "default"),
    2: .standard(proto: "response_or_reference"),
    3: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _default: Openapi_V3_ResponseOrReference? = nil
    var _responseOrReference: [Openapi_V3_NamedResponseOrReference] = []
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _default = source._default
      _responseOrReference = source._responseOrReference
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Responses) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._default != other_storage._default {return false}
        if _storage._responseOrReference != other_storage._responseOrReference {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_ResponsesOrReferences: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_ResponsesOrReferences) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Schema: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "nullable"),
    2: .same(proto: "discriminator"),
    3: .standard(proto: "read_only"),
    4: .standard(proto: "write_only"),
    5: .same(proto: "xml"),
    6: .standard(proto: "external_docs"),
    7: .same(proto: "example"),
    8: .same(proto: "deprecated"),
    9: .same(proto: "title"),
    10: .standard(proto: "multiple_of"),
    11: .same(proto: "maximum"),
    12: .standard(proto: "exclusive_maximum"),
    13: .same(proto: "minimum"),
    14: .standard(proto: "exclusive_minimum"),
    15: .standard(proto: "max_length"),
    16: .standard(proto: "min_length"),
    17: .same(proto: "pattern"),
    18: .standard(proto: "max_items"),
    19: .standard(proto: "min_items"),
    20: .standard(proto: "unique_items"),
    21: .standard(proto: "max_properties"),
    22: .standard(proto: "min_properties"),
    23: .same(proto: "required"),
    24: .same(proto: "enum"),
    25: .same(proto: "type"),
    26: .standard(proto: "all_of"),
    27: .standard(proto: "one_of"),
    28: .standard(proto: "any_of"),
    29: .same(proto: "not"),
    30: .same(proto: "items"),
    31: .same(proto: "properties"),
    32: .standard(proto: "additional_properties"),
    33: .same(proto: "default"),
    34: .same(proto: "description"),
    35: .same(proto: "format"),
    36: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _nullable: Bool = false
    var _discriminator: Openapi_V3_Discriminator? = nil
    var _readOnly: Bool = false
    var _writeOnly: Bool = false
    var _xml: Openapi_V3_Xml? = nil
    var _externalDocs: Openapi_V3_ExternalDocs? = nil
    var _example: Openapi_V3_Any? = nil
    var _deprecated: Bool = false
    var _title: String = String()
    var _multipleOf: Double = 0
    var _maximum: Double = 0
    var _exclusiveMaximum: Bool = false
    var _minimum: Double = 0
    var _exclusiveMinimum: Bool = false
    var _maxLength: Int64 = 0
    var _minLength: Int64 = 0
    var _pattern: String = String()
    var _maxItems: Int64 = 0
    var _minItems: Int64 = 0
    var _uniqueItems: Bool = false
    var _maxProperties: Int64 = 0
    var _minProperties: Int64 = 0
    var _required: [String] = []
    var _enum: [Openapi_V3_Any] = []
    var _type: String = String()
    var _allOf: [Openapi_V3_SchemaOrReference] = []
    var _oneOf: [Openapi_V3_SchemaOrReference] = []
    var _anyOf: [Openapi_V3_SchemaOrReference] = []
    var _not: Openapi_V3_Schema? = nil
    var _items: Openapi_V3_ItemsItem? = nil
    var _properties: Openapi_V3_Properties? = nil
    var _additionalProperties: Openapi_V3_AdditionalPropertiesItem? = nil
    var _default: Openapi_V3_DefaultType? = nil
    var _description_p: String = String()
    var _format: String = String()
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _nullable = source._nullable
      _discriminator = source._discriminator
      _readOnly = source._readOnly
      _writeOnly = source._writeOnly
      _xml = source._xml
      _externalDocs = source._externalDocs
      _example = source._example
      _deprecated = source._deprecated
      _title = source._title
      _multipleOf = source._multipleOf
      _maximum = source._maximum
      _exclusiveMaximum = source._exclusiveMaximum
      _minimum = source._minimum
      _exclusiveMinimum = source._exclusiveMinimum
      _maxLength = source._maxLength
      _minLength = source._minLength
      _pattern = source._pattern
      _maxItems = source._maxItems
      _minItems = source._minItems
      _uniqueItems = source._uniqueItems
      _maxProperties = source._maxProperties
      _minProperties = source._minProperties
      _required = source._required
      _enum = source._enum
      _type = source._type
      _allOf = source._allOf
      _oneOf = source._oneOf
      _anyOf = source._anyOf
      _not = source._not
      _items = source._items
      _properties = source._properties
      _additionalProperties = source._additionalProperties
      _default = source._default
      _description_p = source._description_p
      _format = source._format
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Schema) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._nullable != other_storage._nullable {return false}
        if _storage._discriminator != other_storage._discriminator {return false}
        if _storage._readOnly != other_storage._readOnly {return false}
        if _storage._writeOnly != other_storage._writeOnly {return false}
        if _storage._xml != other_storage._xml {return false}
        if _storage._externalDocs != other_storage._externalDocs {return false}
        if _storage._example != other_storage._example {return false}
        if _storage._deprecated != other_storage._deprecated {return false}
        if _storage._title != other_storage._title {return false}
        if _storage._multipleOf != other_storage._multipleOf {return false}
        if _storage._maximum != other_storage._maximum {return false}
        if _storage._exclusiveMaximum != other_storage._exclusiveMaximum {return false}
        if _storage._minimum != other_storage._minimum {return false}
        if _storage._exclusiveMinimum != other_storage._exclusiveMinimum {return false}
        if _storage._maxLength != other_storage._maxLength {return false}
        if _storage._minLength != other_storage._minLength {return false}
        if _storage._pattern != other_storage._pattern {return false}
        if _storage._maxItems != other_storage._maxItems {return false}
        if _storage._minItems != other_storage._minItems {return false}
        if _storage._uniqueItems != other_storage._uniqueItems {return false}
        if _storage._maxProperties != other_storage._maxProperties {return false}
        if _storage._minProperties != other_storage._minProperties {return false}
        if _storage._required != other_storage._required {return false}
        if _storage._enum != other_storage._enum {return false}
        if _storage._type != other_storage._type {return false}
        if _storage._allOf != other_storage._allOf {return false}
        if _storage._oneOf != other_storage._oneOf {return false}
        if _storage._anyOf != other_storage._anyOf {return false}
        if _storage._not != other_storage._not {return false}
        if _storage._items != other_storage._items {return false}
        if _storage._properties != other_storage._properties {return false}
        if _storage._additionalProperties != other_storage._additionalProperties {return false}
        if _storage._default != other_storage._default {return false}
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._format != other_storage._format {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_SchemaOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "schema"),
    2: .same(proto: "reference"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_SchemaOrReference.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_SchemaOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_SchemasOrReferences: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_SchemasOrReferences) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_SecurityRequirement: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap = SwiftProtobuf._NameMap()

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_SecurityRequirement) -> Bool {
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_SecurityScheme: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "type"),
    2: .same(proto: "description"),
    3: .same(proto: "name"),
    4: .same(proto: "in"),
    5: .same(proto: "scheme"),
    6: .standard(proto: "bearer_format"),
    7: .same(proto: "flows"),
    8: .standard(proto: "open_id_connect_url"),
    9: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _type: String = String()
    var _description_p: String = String()
    var _name: String = String()
    var _in: String = String()
    var _scheme: String = String()
    var _bearerFormat: String = String()
    var _flows: Openapi_V3_OauthFlows? = nil
    var _openIDConnectURL: String = String()
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _type = source._type
      _description_p = source._description_p
      _name = source._name
      _in = source._in
      _scheme = source._scheme
      _bearerFormat = source._bearerFormat
      _flows = source._flows
      _openIDConnectURL = source._openIDConnectURL
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_SecurityScheme) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._type != other_storage._type {return false}
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._name != other_storage._name {return false}
        if _storage._in != other_storage._in {return false}
        if _storage._scheme != other_storage._scheme {return false}
        if _storage._bearerFormat != other_storage._bearerFormat {return false}
        if _storage._flows != other_storage._flows {return false}
        if _storage._openIDConnectURL != other_storage._openIDConnectURL {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_SecuritySchemeOrReference: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "security_scheme"),
    2: .same(proto: "reference"),
  ]

  fileprivate class _StorageClass {
    var _oneof: Openapi_V3_SecuritySchemeOrReference.OneOf_Oneof?

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _oneof = source._oneof
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_SecuritySchemeOrReference) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._oneof != other_storage._oneof {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_SecuritySchemesOrReferences: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_SecuritySchemesOrReferences) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Server: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "url"),
    2: .same(proto: "description"),
    3: .same(proto: "variables"),
    4: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _url: String = String()
    var _description_p: String = String()
    var _variables: Openapi_V3_ServerVariables? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _url = source._url
      _description_p = source._description_p
      _variables = source._variables
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Server) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._url != other_storage._url {return false}
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._variables != other_storage._variables {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_ServerVariable: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "enum"),
    2: .same(proto: "default"),
    3: .same(proto: "description"),
    4: .standard(proto: "specification_extension"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_ServerVariable) -> Bool {
    if self.`enum` != other.`enum` {return false}
    if self.`default` != other.`default` {return false}
    if self.description_p != other.description_p {return false}
    if self.specificationExtension != other.specificationExtension {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_ServerVariables: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_ServerVariables) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_SpecificationExtension: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "number"),
    2: .same(proto: "boolean"),
    3: .same(proto: "string"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_SpecificationExtension) -> Bool {
    if self.oneof != other.oneof {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_StringArray: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "value"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_StringArray) -> Bool {
    if self.value != other.value {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Strings: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .standard(proto: "additional_properties"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Strings) -> Bool {
    if self.additionalProperties != other.additionalProperties {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Tag: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "description"),
    3: .standard(proto: "external_docs"),
    4: .standard(proto: "specification_extension"),
  ]

  fileprivate class _StorageClass {
    var _name: String = String()
    var _description_p: String = String()
    var _externalDocs: Openapi_V3_ExternalDocs? = nil
    var _specificationExtension: [Openapi_V3_NamedAny] = []

    static let defaultInstance = _StorageClass()

    private init() {}

    init(copying source: _StorageClass) {
      _name = source._name
      _description_p = source._description_p
      _externalDocs = source._externalDocs
      _specificationExtension = source._specificationExtension
    }
  }

  fileprivate mutating func _uniqueStorage() -> _StorageClass {
    if !isKnownUniquelyReferenced(&_storage) {
      _storage = _StorageClass(copying: _storage)
    }
    return _storage
  }

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Tag) -> Bool {
    if _storage !== other._storage {
      let storagesAreEqual: Bool = withExtendedLifetime((_storage, other._storage)) { (_storage, other_storage) in
        if _storage._name != other_storage._name {return false}
        if _storage._description_p != other_storage._description_p {return false}
        if _storage._externalDocs != other_storage._externalDocs {return false}
        if _storage._specificationExtension != other_storage._specificationExtension {return false}
        return true
      }
      if !storagesAreEqual {return false}
    }
    if unknownFields != other.unknownFields {return false}
    return true
  }
}

extension Openapi_V3_Xml: SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
  public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
    1: .same(proto: "name"),
    2: .same(proto: "namespace"),
    3: .same(proto: "prefix"),
    4: .same(proto: "attribute"),
    5: .same(proto: "wrapped"),
    6: .standard(proto: "specification_extension"),
  ]

  public func _protobuf_generated_isEqualTo(other: Openapi_V3_Xml) -> Bool {
    if self.name != other.name {return false}
    if self.namespace != other.namespace {return false}
    if self.prefix != other.prefix {return false}
    if self.attribute != other.attribute {return false}
    if self.wrapped != other.wrapped {return false}
    if self.specificationExtension != other.specificationExtension {return false}
    if unknownFields != other.unknownFields {return false}
    return true
  }
}
