Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use heap-based storage only when a Protobuf has a singular transitive recursion #900

Merged
merged 10 commits into from
Oct 11, 2019
221 changes: 82 additions & 139 deletions Reference/conformance/conformance.pb.swift
Original file line number Diff line number Diff line change
Expand Up @@ -206,82 +206,67 @@ struct Conformance_ConformanceRequest {
/// TODO(haberman): if/when we expand the conformance tests to support proto2,
/// we will want to include a field that lets the payload/response be a
/// protobuf_test_messages.proto2.TestAllTypes message instead.
var payload: OneOf_Payload? {
get {return _storage._payload}
set {_uniqueStorage()._payload = newValue}
}
var payload: Conformance_ConformanceRequest.OneOf_Payload? = nil

var protobufPayload: Data {
get {
if case .protobufPayload(let v)? = _storage._payload {return v}
if case .protobufPayload(let v)? = payload {return v}
return SwiftProtobuf.Internal.emptyData
}
set {_uniqueStorage()._payload = .protobufPayload(newValue)}
set {payload = .protobufPayload(newValue)}
}

var jsonPayload: String {
get {
if case .jsonPayload(let v)? = _storage._payload {return v}
if case .jsonPayload(let v)? = payload {return v}
return String()
}
set {_uniqueStorage()._payload = .jsonPayload(newValue)}
set {payload = .jsonPayload(newValue)}
}

/// Google internal only. Opensource testees just skip it.
var jspbPayload: String {
get {
if case .jspbPayload(let v)? = _storage._payload {return v}
if case .jspbPayload(let v)? = payload {return v}
return String()
}
set {_uniqueStorage()._payload = .jspbPayload(newValue)}
set {payload = .jspbPayload(newValue)}
}

var textPayload: String {
get {
if case .textPayload(let v)? = _storage._payload {return v}
if case .textPayload(let v)? = payload {return v}
return String()
}
set {_uniqueStorage()._payload = .textPayload(newValue)}
set {payload = .textPayload(newValue)}
}

/// Which format should the testee serialize its message to?
var requestedOutputFormat: Conformance_WireFormat {
get {return _storage._requestedOutputFormat}
set {_uniqueStorage()._requestedOutputFormat = newValue}
}
var requestedOutputFormat: Conformance_WireFormat = .unspecified

/// The full name for the test message to use; for the moment, either:
/// protobuf_test_messages.proto3.TestAllTypesProto3 or
/// protobuf_test_messages.proto2.TestAllTypesProto2.
var messageType: String {
get {return _storage._messageType}
set {_uniqueStorage()._messageType = newValue}
}
var messageType: String = String()

/// Each test is given a specific test category. Some category may need
/// spedific support in testee programs. Refer to the defintion of TestCategory
/// for more information.
var testCategory: Conformance_TestCategory {
get {return _storage._testCategory}
set {_uniqueStorage()._testCategory = newValue}
}
var testCategory: Conformance_TestCategory = .unspecifiedTest

/// Specify details for how to encode jspb.
var jspbEncodingOptions: Conformance_JspbEncodingConfig {
get {return _storage._jspbEncodingOptions ?? Conformance_JspbEncodingConfig()}
set {_uniqueStorage()._jspbEncodingOptions = newValue}
get {return _jspbEncodingOptions ?? Conformance_JspbEncodingConfig()}
set {_jspbEncodingOptions = newValue}
}
/// Returns true if `jspbEncodingOptions` has been explicitly set.
var hasJspbEncodingOptions: Bool {return _storage._jspbEncodingOptions != nil}
var hasJspbEncodingOptions: Bool {return self._jspbEncodingOptions != nil}
/// Clears the value of `jspbEncodingOptions`. Subsequent reads from it will return its default value.
mutating func clearJspbEncodingOptions() {_uniqueStorage()._jspbEncodingOptions = nil}
mutating func clearJspbEncodingOptions() {self._jspbEncodingOptions = nil}

/// This can be used in json and text format. If true, testee should print
/// unknown fields instead of ignore. This feature is optional.
var printUnknownFields: Bool {
get {return _storage._printUnknownFields}
set {_uniqueStorage()._printUnknownFields = newValue}
}
var printUnknownFields: Bool = false

var unknownFields = SwiftProtobuf.UnknownStorage()

Expand All @@ -302,7 +287,7 @@ struct Conformance_ConformanceRequest {

init() {}

fileprivate var _storage = _StorageClass.defaultInstance
fileprivate var _jspbEncodingOptions: Conformance_JspbEncodingConfig? = nil
}

/// Represents a single test case's output.
Expand Down Expand Up @@ -519,123 +504,81 @@ extension Conformance_ConformanceRequest: SwiftProtobuf.Message, SwiftProtobuf._
9: .standard(proto: "print_unknown_fields"),
]

fileprivate class _StorageClass {
var _payload: Conformance_ConformanceRequest.OneOf_Payload?
var _requestedOutputFormat: Conformance_WireFormat = .unspecified
var _messageType: String = String()
var _testCategory: Conformance_TestCategory = .unspecifiedTest
var _jspbEncodingOptions: Conformance_JspbEncodingConfig? = nil
var _printUnknownFields: Bool = false

static let defaultInstance = _StorageClass()

private init() {}

init(copying source: _StorageClass) {
_payload = source._payload
_requestedOutputFormat = source._requestedOutputFormat
_messageType = source._messageType
_testCategory = source._testCategory
_jspbEncodingOptions = source._jspbEncodingOptions
_printUnknownFields = source._printUnknownFields
}
}

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

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:
if _storage._payload != nil {try decoder.handleConflictingOneOf()}
var v: Data?
try decoder.decodeSingularBytesField(value: &v)
if let v = v {_storage._payload = .protobufPayload(v)}
case 2:
if _storage._payload != nil {try decoder.handleConflictingOneOf()}
var v: String?
try decoder.decodeSingularStringField(value: &v)
if let v = v {_storage._payload = .jsonPayload(v)}
case 3: try decoder.decodeSingularEnumField(value: &_storage._requestedOutputFormat)
case 4: try decoder.decodeSingularStringField(value: &_storage._messageType)
case 5: try decoder.decodeSingularEnumField(value: &_storage._testCategory)
case 6: try decoder.decodeSingularMessageField(value: &_storage._jspbEncodingOptions)
case 7:
if _storage._payload != nil {try decoder.handleConflictingOneOf()}
var v: String?
try decoder.decodeSingularStringField(value: &v)
if let v = v {_storage._payload = .jspbPayload(v)}
case 8:
if _storage._payload != nil {try decoder.handleConflictingOneOf()}
var v: String?
try decoder.decodeSingularStringField(value: &v)
if let v = v {_storage._payload = .textPayload(v)}
case 9: try decoder.decodeSingularBoolField(value: &_storage._printUnknownFields)
default: break
}
while let fieldNumber = try decoder.nextFieldNumber() {
switch fieldNumber {
case 1:
if self.payload != nil {try decoder.handleConflictingOneOf()}
var v: Data?
try decoder.decodeSingularBytesField(value: &v)
if let v = v {self.payload = .protobufPayload(v)}
case 2:
if self.payload != nil {try decoder.handleConflictingOneOf()}
var v: String?
try decoder.decodeSingularStringField(value: &v)
if let v = v {self.payload = .jsonPayload(v)}
case 3: try decoder.decodeSingularEnumField(value: &self.requestedOutputFormat)
case 4: try decoder.decodeSingularStringField(value: &self.messageType)
case 5: try decoder.decodeSingularEnumField(value: &self.testCategory)
case 6: try decoder.decodeSingularMessageField(value: &self._jspbEncodingOptions)
case 7:
if self.payload != nil {try decoder.handleConflictingOneOf()}
var v: String?
try decoder.decodeSingularStringField(value: &v)
if let v = v {self.payload = .jspbPayload(v)}
case 8:
if self.payload != nil {try decoder.handleConflictingOneOf()}
var v: String?
try decoder.decodeSingularStringField(value: &v)
if let v = v {self.payload = .textPayload(v)}
case 9: try decoder.decodeSingularBoolField(value: &self.printUnknownFields)
default: break
}
}
}

func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
switch _storage._payload {
case .protobufPayload(let v)?:
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
case .jsonPayload(let v)?:
try visitor.visitSingularStringField(value: v, fieldNumber: 2)
case nil: break
default: break
}
if _storage._requestedOutputFormat != .unspecified {
try visitor.visitSingularEnumField(value: _storage._requestedOutputFormat, fieldNumber: 3)
}
if !_storage._messageType.isEmpty {
try visitor.visitSingularStringField(value: _storage._messageType, fieldNumber: 4)
}
if _storage._testCategory != .unspecifiedTest {
try visitor.visitSingularEnumField(value: _storage._testCategory, fieldNumber: 5)
}
if let v = _storage._jspbEncodingOptions {
try visitor.visitSingularMessageField(value: v, fieldNumber: 6)
}
switch _storage._payload {
case .jspbPayload(let v)?:
try visitor.visitSingularStringField(value: v, fieldNumber: 7)
case .textPayload(let v)?:
try visitor.visitSingularStringField(value: v, fieldNumber: 8)
case nil: break
default: break
}
if _storage._printUnknownFields != false {
try visitor.visitSingularBoolField(value: _storage._printUnknownFields, fieldNumber: 9)
}
switch self.payload {
case .protobufPayload(let v)?:
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
case .jsonPayload(let v)?:
try visitor.visitSingularStringField(value: v, fieldNumber: 2)
case nil: break
default: break
}
if self.requestedOutputFormat != .unspecified {
try visitor.visitSingularEnumField(value: self.requestedOutputFormat, fieldNumber: 3)
}
if !self.messageType.isEmpty {
try visitor.visitSingularStringField(value: self.messageType, fieldNumber: 4)
}
if self.testCategory != .unspecifiedTest {
try visitor.visitSingularEnumField(value: self.testCategory, fieldNumber: 5)
}
if let v = self._jspbEncodingOptions {
try visitor.visitSingularMessageField(value: v, fieldNumber: 6)
}
switch self.payload {
case .jspbPayload(let v)?:
try visitor.visitSingularStringField(value: v, fieldNumber: 7)
case .textPayload(let v)?:
try visitor.visitSingularStringField(value: v, fieldNumber: 8)
case nil: break
default: break
}
if self.printUnknownFields != false {
try visitor.visitSingularBoolField(value: self.printUnknownFields, fieldNumber: 9)
}
try unknownFields.traverse(visitor: &visitor)
}

static func ==(lhs: Conformance_ConformanceRequest, rhs: Conformance_ConformanceRequest) -> Bool {
if lhs._storage !== rhs._storage {
let storagesAreEqual: Bool = withExtendedLifetime((lhs._storage, rhs._storage)) { (_args: (_StorageClass, _StorageClass)) in
let _storage = _args.0
let rhs_storage = _args.1
if _storage._payload != rhs_storage._payload {return false}
if _storage._requestedOutputFormat != rhs_storage._requestedOutputFormat {return false}
if _storage._messageType != rhs_storage._messageType {return false}
if _storage._testCategory != rhs_storage._testCategory {return false}
if _storage._jspbEncodingOptions != rhs_storage._jspbEncodingOptions {return false}
if _storage._printUnknownFields != rhs_storage._printUnknownFields {return false}
return true
}
if !storagesAreEqual {return false}
}
if lhs.payload != rhs.payload {return false}
if lhs.requestedOutputFormat != rhs.requestedOutputFormat {return false}
if lhs.messageType != rhs.messageType {return false}
if lhs.testCategory != rhs.testCategory {return false}
if lhs._jspbEncodingOptions != rhs._jspbEncodingOptions {return false}
if lhs.printUnknownFields != rhs.printUnknownFields {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
Expand Down
Loading