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

Json default #1

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Sources/SwiftProtobuf/JSONEncodingOptions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public struct JSONEncodingOptions {
/// Whether to preserve proto field names.
/// By default they are converted to JSON(lowerCamelCase) names.
public var preserveProtoFieldNames: Bool = false


public var preserveDefaultValues: Bool = false
public init() {}
}
63 changes: 63 additions & 0 deletions Sources/SwiftProtobuf/JSONEncodingVisitor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,56 +83,77 @@ internal struct JSONEncodingVisitor: Visitor {
}

mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
guard value != 0 || options.preserveDefaultValues else {return}
try startField(for: fieldNumber)
encoder.putFloatValue(value: value)
}

mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
guard value != 0 || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.putDoubleValue(value: value)
}

mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws {
guard value != 0 || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.putInt32(value: value)
}

mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
guard value != 0 || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.putInt64(value: value)
}

mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws {
guard value != 0 || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.putUInt32(value: value)
}

mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
guard value != 0 || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.putUInt64(value: value)
}

mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
guard value != 0 || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.putUInt32(value: value)
}

mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
guard value != 0 || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.putInt32(value: value)
}

mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
guard value != false || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.putBoolValue(value: value)
}

mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.putStringValue(value: value)
}

mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.putBytesValue(value: value)
}
Expand All @@ -156,6 +177,8 @@ internal struct JSONEncodingVisitor: Visitor {
}

mutating func visitSingularEnumField<E: Enum>(value: E, fieldNumber: Int) throws {
guard value.rawValue != 0 || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
if !options.alwaysPrintEnumsAsInts, let n = value.name {
encoder.appendQuoted(name: n)
Expand All @@ -175,93 +198,125 @@ internal struct JSONEncodingVisitor: Visitor {
}

mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Float) in
encoder.putFloatValue(value: v)
}
}

mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Double) in
encoder.putDoubleValue(value: v)
}
}

mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Int32) in
encoder.putInt32(value: v)
}
}

mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Int64) in
encoder.putInt64(value: v)
}
}

mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: UInt32) in
encoder.putUInt32(value: v)
}
}

mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: UInt64) in
encoder.putUInt64(value: v)
}
}

mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber)
}

mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber)
}

mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try visitRepeatedUInt32Field(value: value, fieldNumber: fieldNumber)
}

mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try visitRepeatedUInt64Field(value: value, fieldNumber: fieldNumber)
}

mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber)
}

mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber)
}

mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Bool) in
encoder.putBoolValue(value: v)
}
}

mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: String) in
encoder.putStringValue(value: v)
}
}

mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Data) in
encoder.putBytesValue(value: v)
}
}

mutating func visitRepeatedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

let alwaysPrintEnumsAsInts = options.alwaysPrintEnumsAsInts
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: E) throws in
Expand All @@ -274,6 +329,8 @@ internal struct JSONEncodingVisitor: Visitor {
}

mutating func visitRepeatedMessageField<M: Message>(value: [M], fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

let localOptions = options
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: M) throws in
Expand All @@ -292,6 +349,8 @@ internal struct JSONEncodingVisitor: Visitor {


mutating func visitMapField<KeyType, ValueType: MapValueType>(fieldType: _ProtobufMap<KeyType, ValueType>.Type, value: _ProtobufMap<KeyType, ValueType>.BaseType, fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.append(text: "{")
var mapVisitor = JSONMapEncodingVisitor(encoder: encoder, options: options)
Expand All @@ -304,6 +363,8 @@ internal struct JSONEncodingVisitor: Visitor {
}

mutating func visitMapField<KeyType, ValueType>(fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type, value: _ProtobufEnumMap<KeyType, ValueType>.BaseType, fieldNumber: Int) throws where ValueType.RawValue == Int {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.append(text: "{")
var mapVisitor = JSONMapEncodingVisitor(encoder: encoder, options: options)
Expand All @@ -316,6 +377,8 @@ internal struct JSONEncodingVisitor: Visitor {
}

mutating func visitMapField<KeyType, ValueType>(fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type, value: _ProtobufMessageMap<KeyType, ValueType>.BaseType, fieldNumber: Int) throws {
guard !value.isEmpty || options.preserveDefaultValues else {return}

try startField(for: fieldNumber)
encoder.append(text: "{")
var mapVisitor = JSONMapEncodingVisitor(encoder: encoder, options: options)
Expand Down
20 changes: 8 additions & 12 deletions Sources/protoc-gen-swift/MessageFieldGenerator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -196,21 +196,17 @@ class MessageFieldGenerator: FieldGeneratorBase, FieldGenerator {

let varName = hasFieldPresence ? "v" : storedProperty

let conditional: String
if isRepeated { // Also covers maps
var conditional: String? = nil

if isRepeated && fieldDescriptor.file.syntax != .proto3 { // Also covers maps
conditional = "!\(varName).isEmpty"
} else if hasFieldPresence {
conditional = "let v = \(storedProperty)"
} else {
// At this point, the fields would be a primative type, and should only
// be visted if it is the non default value.
assert(fieldDescriptor.file.syntax == .proto3)
switch fieldDescriptor.type {
case .string, .bytes:
conditional = ("!\(varName).isEmpty")
default:
conditional = ("\(varName) != \(swiftDefaultValue)")
}
}

guard let conditional = conditional else {
p.print("try visitor.\(visitMethod)(\(traitsArg)value: \(varName), fieldNumber: \(number))\n")
return
}

p.print("if \(conditional) {\n")
Expand Down