Add LND test wallet

This commit is contained in:
adrianaepure
2023-06-08 09:36:06 +03:00
commit 1313d727cf
251 changed files with 57518 additions and 0 deletions

View File

@ -0,0 +1,476 @@
// Sources/SwiftProtobuf/AnyMessageStorage.swift - Custom stroage for Any WKT
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Hand written storage class for Google_Protobuf_Any to support on demand
/// transforms between the formats.
///
// -----------------------------------------------------------------------------
import Foundation
#if !swift(>=4.2)
private let i_2166136261 = Int(bitPattern: 2166136261)
private let i_16777619 = Int(16777619)
#endif
fileprivate func serializeAnyJSON(
for message: Message,
typeURL: String,
options: JSONEncodingOptions
) throws -> String {
var visitor = try JSONEncodingVisitor(type: type(of: message), options: options)
visitor.startObject(message: message)
visitor.encodeField(name: "@type", stringValue: typeURL)
if let m = message as? _CustomJSONCodable {
let value = try m.encodedJSONString(options: options)
visitor.encodeField(name: "value", jsonText: value)
} else {
try message.traverse(visitor: &visitor)
}
visitor.endObject()
return visitor.stringResult
}
fileprivate func emitVerboseTextForm(visitor: inout TextFormatEncodingVisitor, message: Message, typeURL: String) {
let url: String
if typeURL.isEmpty {
url = buildTypeURL(forMessage: message, typePrefix: defaultAnyTypeURLPrefix)
} else {
url = typeURL
}
visitor.visitAnyVerbose(value: message, typeURL: url)
}
fileprivate func asJSONObject(body: Data) -> Data {
let asciiOpenCurlyBracket = UInt8(ascii: "{")
let asciiCloseCurlyBracket = UInt8(ascii: "}")
var result = Data([asciiOpenCurlyBracket])
result.append(body)
result.append(asciiCloseCurlyBracket)
return result
}
fileprivate func unpack(contentJSON: Data,
extensions: ExtensionMap,
options: JSONDecodingOptions,
as messageType: Message.Type) throws -> Message {
guard messageType is _CustomJSONCodable.Type else {
let contentJSONAsObject = asJSONObject(body: contentJSON)
return try messageType.init(jsonUTF8Data: contentJSONAsObject, extensions: extensions, options: options)
}
var value = String()
try contentJSON.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
if body.count > 0 {
var scanner = JSONScanner(source: body, options: options, extensions: extensions)
let key = try scanner.nextQuotedString()
if key != "value" {
// The only thing within a WKT should be "value".
throw AnyUnpackError.malformedWellKnownTypeJSON
}
try scanner.skipRequiredColon() // Can't fail
value = try scanner.skip()
if !scanner.complete {
// If that wasn't the end, then there was another key,
// and WKTs should only have the one.
throw AnyUnpackError.malformedWellKnownTypeJSON
}
}
}
return try messageType.init(jsonString: value, extensions: extensions, options: options)
}
internal class AnyMessageStorage {
// The two properties generated Google_Protobuf_Any will reference.
var _typeURL = String()
var _value: Data {
// Remapped to the internal `state`.
get {
switch state {
case .binary(let value):
return value
case .message(let message):
do {
return try message.serializedData(partial: true)
} catch {
return Data()
}
case .contentJSON(let contentJSON, let options):
guard let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) else {
return Data()
}
do {
let m = try unpack(contentJSON: contentJSON,
extensions: SimpleExtensionMap(),
options: options,
as: messageType)
return try m.serializedData(partial: true)
} catch {
return Data()
}
}
}
set {
state = .binary(newValue)
}
}
enum InternalState {
// a serialized binary
// Note: Unlike contentJSON below, binary does not bother to capture the
// decoding options. This is because the actual binary format is the binary
// blob, i.e. - when decoding from binary, the spec doesn't include decoding
// the binary blob, it is pass through. Instead there is a public api for
// unpacking that takes new options when a developer decides to decode it.
case binary(Data)
// a message
case message(Message)
// parsed JSON with the @type removed and the decoding options.
case contentJSON(Data, JSONDecodingOptions)
}
var state: InternalState = .binary(Data())
static let defaultInstance = AnyMessageStorage()
private init() {}
init(copying source: AnyMessageStorage) {
_typeURL = source._typeURL
state = source.state
}
func isA<M: Message>(_ type: M.Type) -> Bool {
if _typeURL.isEmpty {
return false
}
let encodedType = typeName(fromURL: _typeURL)
return encodedType == M.protoMessageName
}
// This is only ever called with the expectation that target will be fully
// replaced during the unpacking and never as a merge.
func unpackTo<M: Message>(
target: inout M,
extensions: ExtensionMap?,
options: BinaryDecodingOptions
) throws {
guard isA(M.self) else {
throw AnyUnpackError.typeMismatch
}
switch state {
case .binary(let data):
target = try M(serializedData: data, extensions: extensions, partial: true, options: options)
case .message(let msg):
if let message = msg as? M {
// Already right type, copy it over.
target = message
} else {
// Different type, serialize and parse.
let data = try msg.serializedData(partial: true)
target = try M(serializedData: data, extensions: extensions, partial: true)
}
case .contentJSON(let contentJSON, let options):
target = try unpack(contentJSON: contentJSON,
extensions: extensions ?? SimpleExtensionMap(),
options: options,
as: M.self) as! M
}
}
// Called before the message is traversed to do any error preflights.
// Since traverse() will use _value, this is our chance to throw
// when _value can't.
func preTraverse() throws {
switch state {
case .binary:
// Nothing to be checked.
break
case .message:
// When set from a developer provided message, partial support
// is done. Any message that comes in from another format isn't
// checked, and transcoding the isInitialized requirement is
// never inserted.
break
case .contentJSON(let contentJSON, let options):
// contentJSON requires we have the type available for decoding
guard let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) else {
throw BinaryEncodingError.anyTranscodeFailure
}
do {
// Decodes the full JSON and then discard the result.
// The regular traversal will decode this again by querying the
// `value` field, but that has no way to fail. As a result,
// we need this to accurately handle decode errors.
_ = try unpack(contentJSON: contentJSON,
extensions: SimpleExtensionMap(),
options: options,
as: messageType)
} catch {
throw BinaryEncodingError.anyTranscodeFailure
}
}
}
}
/// Custom handling for Text format.
extension AnyMessageStorage {
func decodeTextFormat(typeURL url: String, decoder: inout TextFormatDecoder) throws {
// Decoding the verbose form requires knowing the type.
_typeURL = url
guard let messageType = Google_Protobuf_Any.messageType(forTypeURL: url) else {
// The type wasn't registered, can't parse it.
throw TextFormatDecodingError.malformedText
}
let terminator = try decoder.scanner.skipObjectStart()
var subDecoder = try TextFormatDecoder(messageType: messageType, scanner: decoder.scanner, terminator: terminator)
if messageType == Google_Protobuf_Any.self {
var any = Google_Protobuf_Any()
try any.decodeTextFormat(decoder: &subDecoder)
state = .message(any)
} else {
var m = messageType.init()
try m.decodeMessage(decoder: &subDecoder)
state = .message(m)
}
decoder.scanner = subDecoder.scanner
if try decoder.nextFieldNumber() != nil {
// Verbose any can never have additional keys.
throw TextFormatDecodingError.malformedText
}
}
// Specialized traverse for writing out a Text form of the Any.
// This prefers the more-legible "verbose" format if it can
// use it, otherwise will fall back to simpler forms.
internal func textTraverse(visitor: inout TextFormatEncodingVisitor) {
switch state {
case .binary(let valueData):
if let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) {
// If we can decode it, we can write the readable verbose form:
do {
let m = try messageType.init(serializedData: valueData, partial: true)
emitVerboseTextForm(visitor: &visitor, message: m, typeURL: _typeURL)
return
} catch {
// Fall through to just print the type and raw binary data
}
}
if !_typeURL.isEmpty {
try! visitor.visitSingularStringField(value: _typeURL, fieldNumber: 1)
}
if !valueData.isEmpty {
try! visitor.visitSingularBytesField(value: valueData, fieldNumber: 2)
}
case .message(let msg):
emitVerboseTextForm(visitor: &visitor, message: msg, typeURL: _typeURL)
case .contentJSON(let contentJSON, let options):
// If we can decode it, we can write the readable verbose form:
if let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) {
do {
let m = try unpack(contentJSON: contentJSON,
extensions: SimpleExtensionMap(),
options: options,
as: messageType)
emitVerboseTextForm(visitor: &visitor, message: m, typeURL: _typeURL)
return
} catch {
// Fall through to just print the raw JSON data
}
}
if !_typeURL.isEmpty {
try! visitor.visitSingularStringField(value: _typeURL, fieldNumber: 1)
}
// Build a readable form of the JSON:
let contentJSONAsObject = asJSONObject(body: contentJSON)
visitor.visitAnyJSONDataField(value: contentJSONAsObject)
}
}
}
/// The obvious goal for Hashable/Equatable conformance would be for
/// hash and equality to behave as if we always decoded the inner
/// object and hashed or compared that. Unfortunately, Any typically
/// stores serialized contents and we don't always have the ability to
/// deserialize it. Since none of our supported serializations are
/// fully deterministic, we can't even ensure that equality will
/// behave this way when the Any contents are in the same
/// serialization.
///
/// As a result, we can only really perform a "best effort" equality
/// test. Of course, regardless of the above, we must guarantee that
/// hashValue is compatible with equality.
extension AnyMessageStorage {
#if swift(>=4.2)
// Can't use _valueData for a few reasons:
// 1. Since decode is done on demand, two objects could be equal
// but created differently (one from JSON, one for Message, etc.),
// and the hash values have to be equal even if we don't have data
// yet.
// 2. map<> serialization order is undefined. At the time of writing
// the Swift, Objective-C, and Go runtimes all tend to have random
// orders, so the messages could be identical, but in binary form
// they could differ.
public func hash(into hasher: inout Hasher) {
if !_typeURL.isEmpty {
hasher.combine(_typeURL)
}
}
#else // swift(>=4.2)
var hashValue: Int {
var hash: Int = i_2166136261
if !_typeURL.isEmpty {
hash = (hash &* i_16777619) ^ _typeURL.hashValue
}
return hash
}
#endif // swift(>=4.2)
func isEqualTo(other: AnyMessageStorage) -> Bool {
if (_typeURL != other._typeURL) {
return false
}
// Since the library does lazy Any decode, equality is a very hard problem.
// It things exactly match, that's pretty easy, otherwise, one ends up having
// to error on saying they aren't equal.
//
// The best option would be to have Message forms and compare those, as that
// removes issues like map<> serialization order, some other protocol buffer
// implementation details/bugs around serialized form order, etc.; but that
// would also greatly slow down equality tests.
//
// Do our best to compare what is present have...
// If both have messages, check if they are the same.
if case .message(let myMsg) = state, case .message(let otherMsg) = other.state, type(of: myMsg) == type(of: otherMsg) {
// Since the messages are known to be same type, we can claim both equal and
// not equal based on the equality comparison.
return myMsg.isEqualTo(message: otherMsg)
}
// If both have serialized data, and they exactly match; the messages are equal.
// Because there could be map in the message, the fact that the data isn't the
// same doesn't always mean the messages aren't equal. Likewise, the binary could
// have been created by a library that doesn't order the fields, or the binary was
// created using the appending ability in of the binary format.
if case .binary(let myValue) = state, case .binary(let otherValue) = other.state, myValue == otherValue {
return true
}
// If both have contentJSON, and they exactly match; the messages are equal.
// Because there could be map in the message (or the JSON could just be in a different
// order), the fact that the JSON isn't the same doesn't always mean the messages
// aren't equal.
if case .contentJSON(let myJSON, _) = state,
case .contentJSON(let otherJSON, _) = other.state,
myJSON == otherJSON {
return true
}
// Out of options. To do more compares, the states conversions would have to be
// done to do comparisions; and since equality can be used somewhat removed from
// a developer (if they put protos in a Set, use them as keys to a Dictionary, etc),
// the conversion cost might be to high for those uses. Give up and say they aren't equal.
return false
}
}
// _CustomJSONCodable support for Google_Protobuf_Any
extension AnyMessageStorage {
// Override the traversal-based JSON encoding
// This builds an Any JSON representation from one of:
// * The message we were initialized with,
// * The JSON fields we last deserialized, or
// * The protobuf field we were deserialized from.
// The last case requires locating the type, deserializing
// into an object, then reserializing back to JSON.
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
switch state {
case .binary(let valueData):
// Transcode by decoding the binary data to a message object
// and then recode back into JSON.
guard let messageType = Google_Protobuf_Any.messageType(forTypeURL: _typeURL) else {
// If we don't have the type available, we can't decode the
// binary value, so we're stuck. (The Google spec does not
// provide a way to just package the binary value for someone
// else to decode later.)
throw JSONEncodingError.anyTranscodeFailure
}
let m = try messageType.init(serializedData: valueData, partial: true)
return try serializeAnyJSON(for: m, typeURL: _typeURL, options: options)
case .message(let msg):
// We should have been initialized with a typeURL, but
// ensure it wasn't cleared.
let url = !_typeURL.isEmpty ? _typeURL : buildTypeURL(forMessage: msg, typePrefix: defaultAnyTypeURLPrefix)
return try serializeAnyJSON(for: msg, typeURL: url, options: options)
case .contentJSON(let contentJSON, _):
var jsonEncoder = JSONEncoder()
jsonEncoder.startObject()
jsonEncoder.startField(name: "@type")
jsonEncoder.putStringValue(value: _typeURL)
if !contentJSON.isEmpty {
jsonEncoder.append(staticText: ",")
// NOTE: This doesn't really take `options` into account since it is
// just reflecting out what was taken in originally.
jsonEncoder.append(utf8Data: contentJSON)
}
jsonEncoder.endObject()
return jsonEncoder.stringResult
}
}
// TODO: If the type is well-known or has already been registered,
// we should consider decoding eagerly. Eager decoding would
// catch certain errors earlier (good) but would probably be
// a performance hit if the Any contents were never accessed (bad).
// Of course, we can't always decode eagerly (we don't always have the
// message type available), so the deferred logic here is still needed.
func decodeJSON(from decoder: inout JSONDecoder) throws {
try decoder.scanner.skipRequiredObjectStart()
// Reset state
_typeURL = String()
state = .binary(Data())
if decoder.scanner.skipOptionalObjectEnd() {
return
}
var jsonEncoder = JSONEncoder()
while true {
let key = try decoder.scanner.nextQuotedString()
try decoder.scanner.skipRequiredColon()
if key == "@type" {
_typeURL = try decoder.scanner.nextQuotedString()
} else {
jsonEncoder.startField(name: key)
let keyValueJSON = try decoder.scanner.skip()
jsonEncoder.append(text: keyValueJSON)
}
if decoder.scanner.skipOptionalObjectEnd() {
// Capture the options, but set the messageDepthLimit to be what
// was left right now, as that is the limit when the JSON is finally
// parsed.
var updatedOptions = decoder.options
updatedOptions.messageDepthLimit = decoder.scanner.recursionBudget
state = .contentJSON(jsonEncoder.dataResult, updatedOptions)
return
}
try decoder.scanner.skipRequiredComma()
}
}
}

View File

@ -0,0 +1,37 @@
// Sources/SwiftProtobuf/AnyUnpackError.swift - Any Unpacking Errors
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Errors that can be throw when unpacking a Google_Protobuf_Any.
///
// -----------------------------------------------------------------------------
/// Describes errors that can occur when unpacking an `Google_Protobuf_Any`
/// message.
///
/// `Google_Protobuf_Any` messages can be decoded from protobuf binary, text
/// format, or JSON. The contents are not parsed immediately; the raw data is
/// held in the `Google_Protobuf_Any` message until you `unpack()` it into a
/// message. At this time, any error can occur that might have occurred from a
/// regular decoding operation. There are also other errors that can occur due
/// to problems with the `Any` value's structure.
public enum AnyUnpackError: Error {
/// The `type_url` field in the `Google_Protobuf_Any` message did not match
/// the message type provided to the `unpack()` method.
case typeMismatch
/// Well-known types being decoded from JSON must have only two fields: the
/// `@type` field and a `value` field containing the specialized JSON coding
/// of the well-known type.
case malformedWellKnownTypeJSON
/// The `Google_Protobuf_Any` message was malformed in some other way not
/// covered by the other error cases.
case malformedAnyField
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,44 @@
// Sources/SwiftProtobuf/BinaryDecodingError.swift - Protobuf binary decoding errors
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Protobuf binary format decoding errors
///
// -----------------------------------------------------------------------------
/// Describes errors that can occur when decoding a message from binary format.
public enum BinaryDecodingError: Error {
/// Extraneous data remained after decoding should have been complete.
case trailingGarbage
/// The decoder unexpectedly reached the end of the data before it was
/// expected.
case truncated
/// A string field was not encoded as valid UTF-8.
case invalidUTF8
/// The binary data was malformed in some way, such as an invalid wire format
/// or field tag.
case malformedProtobuf
/// The definition of the message or one of its nested messages has required
/// fields but the binary data did not include values for them. You must pass
/// `partial: true` during decoding if you wish to explicitly ignore missing
/// required fields.
case missingRequiredFields
/// An internal error happened while decoding. If this is ever encountered,
/// please file an issue with SwiftProtobuf with as much details as possible
/// for what happened (proto definitions, bytes being decoded (if possible)).
case internalExtensionError
/// Reached the nesting limit for messages within messages while decoding.
case messageDepthLimit
}

View File

@ -0,0 +1,39 @@
// Sources/SwiftProtobuf/BinaryDecodingOptions.swift - Binary decoding options
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Binary decoding options
///
// -----------------------------------------------------------------------------
/// Options for JSONDecoding.
public struct BinaryDecodingOptions {
/// The maximum nesting of message with messages. The default is 100.
///
/// To prevent corrupt or malicious messages from causing stack overflows,
/// this controls how deep messages can be nested within other messages
/// while parsing.
public var messageDepthLimit: Int = 100
/// Discard unknown fields while parsing. The default is false, so parsering
/// does not discard unknown fields.
///
/// The Protobuf binary format allows unknown fields to be still parsed
/// so the schema can be expanded without requiring all readers to be updated.
/// This works in part by haivng any unknown fields preserved so they can
/// be relayed on without loss. For a while the proto3 syntax definition
/// called for unknown fields to be dropped, but that lead to problems in
/// some case. The default is to follow the spec and keep them, but setting
/// this option to `true` allows a developer to strip them during a parse
/// in case they have a specific need to drop the unknown fields from the
/// object graph being created.
public var discardUnknownFields: Bool = false
public init() {}
}

View File

@ -0,0 +1,232 @@
// Sources/SwiftProtobuf/BinaryDelimited.swift - Delimited support
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Helpers to read/write message with a length prefix.
///
// -----------------------------------------------------------------------------
import Foundation
/// Helper methods for reading/writing messages with a length prefix.
public enum BinaryDelimited {
/// Additional errors for delimited message handing.
public enum Error: Swift.Error {
/// If a read/write to the stream fails, but the stream's `streamError` is nil,
/// this error will be throw instead since the stream didn't provide anything
/// more specific. A common cause for this can be failing to open the stream
/// before trying to read/write to it.
case unknownStreamError
/// While reading/writing to the stream, less than the expected bytes was
/// read/written.
case truncated
}
/// Serialize a single size-delimited message from the given stream. Delimited
/// format allows a single file or stream to contain multiple messages,
/// whereas normally writing multiple non-delimited messages to the same
/// stream would cause them to be merged. A delimited message is a varint
/// encoding the message size followed by a message of exactly that size.
///
/// - Parameters:
/// - message: The message to be written.
/// - to: The `OutputStream` to write the message to. The stream is
/// is assumed to be ready to be written to.
/// - partial: If `false` (the default), this method will check
/// `Message.isInitialized` before encoding to verify that all required
/// fields are present. If any are missing, this method throws
/// `BinaryEncodingError.missingRequiredFields`.
/// - Throws: `BinaryEncodingError` if encoding fails, throws
/// `BinaryDelimited.Error` for some writing errors, or the
/// underlying `OutputStream.streamError` for a stream error.
public static func serialize(
message: Message,
to stream: OutputStream,
partial: Bool = false
) throws {
// TODO: Revisit to avoid the extra buffering when encoding is streamed in general.
let serialized = try message.serializedData(partial: partial)
let totalSize = Varint.encodedSize(of: UInt64(serialized.count)) + serialized.count
var data = Data(count: totalSize)
data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in
if let baseAddress = body.baseAddress, body.count > 0 {
var encoder = BinaryEncoder(forWritingInto: baseAddress)
encoder.putBytesValue(value: serialized)
}
}
var written: Int = 0
data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
if let baseAddress = body.baseAddress, body.count > 0 {
// This assumingMemoryBound is technically unsafe, but without SR-11078
// (https://bugs.swift.org/browse/SR-11087) we don't have another option.
// It should be "safe enough".
let pointer = baseAddress.assumingMemoryBound(to: UInt8.self)
written = stream.write(pointer, maxLength: totalSize)
}
}
if written != totalSize {
if written == -1 {
if let streamError = stream.streamError {
throw streamError
}
throw BinaryDelimited.Error.unknownStreamError
}
throw BinaryDelimited.Error.truncated
}
}
/// Reads a single size-delimited message from the given stream. Delimited
/// format allows a single file or stream to contain multiple messages,
/// whereas normally parsing consumes the entire input. A delimited message
/// is a varint encoding the message size followed by a message of exactly
/// exactly that size.
///
/// - Parameters:
/// - messageType: The type of message to read.
/// - from: The `InputStream` to read the data from. The stream is assumed
/// to be ready to read from.
/// - extensions: An `ExtensionMap` used to look up and decode any
/// extensions in this message or messages nested within this message's
/// fields.
/// - partial: If `false` (the default), this method will check
/// `Message.isInitialized` before encoding to verify that all required
/// fields are present. If any are missing, this method throws
/// `BinaryEncodingError.missingRequiredFields`.
/// - options: The BinaryDecodingOptions to use.
/// - Returns: The message read.
/// - Throws: `BinaryDecodingError` if decoding fails, throws
/// `BinaryDelimited.Error` for some reading errors, and the
/// underlying InputStream.streamError for a stream error.
public static func parse<M: Message>(
messageType: M.Type,
from stream: InputStream,
extensions: ExtensionMap? = nil,
partial: Bool = false,
options: BinaryDecodingOptions = BinaryDecodingOptions()
) throws -> M {
var message = M()
try merge(into: &message,
from: stream,
extensions: extensions,
partial: partial,
options: options)
return message
}
/// Updates the message by reading a single size-delimited message from
/// the given stream. Delimited format allows a single file or stream to
/// contain multiple messages, whereas normally parsing consumes the entire
/// input. A delimited message is a varint encoding the message size
/// followed by a message of exactly that size.
///
/// - Note: If this method throws an error, the message may still have been
/// partially mutated by the binary data that was decoded before the error
/// occurred.
///
/// - Parameters:
/// - mergingTo: The message to merge the data into.
/// - from: The `InputStream` to read the data from. The stream is assumed
/// to be ready to read from.
/// - extensions: An `ExtensionMap` used to look up and decode any
/// extensions in this message or messages nested within this message's
/// fields.
/// - partial: If `false` (the default), this method will check
/// `Message.isInitialized` before encoding to verify that all required
/// fields are present. If any are missing, this method throws
/// `BinaryEncodingError.missingRequiredFields`.
/// - options: The BinaryDecodingOptions to use.
/// - Throws: `BinaryDecodingError` if decoding fails, throws
/// `BinaryDelimited.Error` for some reading errors, and the
/// underlying InputStream.streamError for a stream error.
public static func merge<M: Message>(
into message: inout M,
from stream: InputStream,
extensions: ExtensionMap? = nil,
partial: Bool = false,
options: BinaryDecodingOptions = BinaryDecodingOptions()
) throws {
let length = try Int(decodeVarint(stream))
if length == 0 {
// The message was all defaults, nothing to actually read.
return
}
var data = Data(count: length)
var bytesRead: Int = 0
data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in
if let baseAddress = body.baseAddress, body.count > 0 {
// This assumingMemoryBound is technically unsafe, but without SR-11078
// (https://bugs.swift.org/browse/SR-11087) we don't have another option.
// It should be "safe enough".
let pointer = baseAddress.assumingMemoryBound(to: UInt8.self)
bytesRead = stream.read(pointer, maxLength: length)
}
}
if bytesRead != length {
if bytesRead == -1 {
if let streamError = stream.streamError {
throw streamError
}
throw BinaryDelimited.Error.unknownStreamError
}
throw BinaryDelimited.Error.truncated
}
try message.merge(serializedData: data,
extensions: extensions,
partial: partial,
options: options)
}
}
// TODO: This should go away when encoding/decoding are more stream based
// as that should provide a more direct way to do this. This is basically
// a rewrite of BinaryDecoder.decodeVarint().
internal func decodeVarint(_ stream: InputStream) throws -> UInt64 {
// Buffer to reuse within nextByte.
let readBuffer = UnsafeMutablePointer<UInt8>.allocate(capacity: 1)
#if swift(>=4.1)
defer { readBuffer.deallocate() }
#else
defer { readBuffer.deallocate(capacity: 1) }
#endif
func nextByte() throws -> UInt8 {
let bytesRead = stream.read(readBuffer, maxLength: 1)
if bytesRead != 1 {
if bytesRead == -1 {
if let streamError = stream.streamError {
throw streamError
}
throw BinaryDelimited.Error.unknownStreamError
}
throw BinaryDelimited.Error.truncated
}
return readBuffer[0]
}
var value: UInt64 = 0
var shift: UInt64 = 0
while true {
let c = try nextByte()
value |= UInt64(c & 0x7f) << shift
if c & 0x80 == 0 {
return value
}
shift += 7
if shift > 63 {
throw BinaryDecodingError.malformedProtobuf
}
}
}

View File

@ -0,0 +1,155 @@
// Sources/SwiftProtobuf/BinaryEncoder.swift - Binary encoding support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Core support for protobuf binary encoding. Note that this is built
/// on the general traversal machinery.
///
// -----------------------------------------------------------------------------
import Foundation
/*
* Encoder for Binary Protocol Buffer format
*/
internal struct BinaryEncoder {
private var pointer: UnsafeMutableRawPointer
init(forWritingInto pointer: UnsafeMutableRawPointer) {
self.pointer = pointer
}
private mutating func append(_ byte: UInt8) {
pointer.storeBytes(of: byte, as: UInt8.self)
pointer = pointer.advanced(by: 1)
}
private mutating func append(contentsOf data: Data) {
data.withUnsafeBytes { dataPointer in
if let baseAddress = dataPointer.baseAddress, dataPointer.count > 0 {
pointer.copyMemory(from: baseAddress, byteCount: dataPointer.count)
pointer = pointer.advanced(by: dataPointer.count)
}
}
}
@discardableResult
private mutating func append(contentsOf bufferPointer: UnsafeRawBufferPointer) -> Int {
let count = bufferPointer.count
if let baseAddress = bufferPointer.baseAddress, count > 0 {
memcpy(pointer, baseAddress, count)
}
pointer = pointer.advanced(by: count)
return count
}
func distance(pointer: UnsafeMutableRawPointer) -> Int {
return pointer.distance(to: self.pointer)
}
mutating func appendUnknown(data: Data) {
append(contentsOf: data)
}
mutating func startField(fieldNumber: Int, wireFormat: WireFormat) {
startField(tag: FieldTag(fieldNumber: fieldNumber, wireFormat: wireFormat))
}
mutating func startField(tag: FieldTag) {
putVarInt(value: UInt64(tag.rawValue))
}
mutating func putVarInt(value: UInt64) {
var v = value
while v > 127 {
append(UInt8(v & 0x7f | 0x80))
v >>= 7
}
append(UInt8(v))
}
mutating func putVarInt(value: Int64) {
putVarInt(value: UInt64(bitPattern: value))
}
mutating func putVarInt(value: Int) {
putVarInt(value: Int64(value))
}
mutating func putZigZagVarInt(value: Int64) {
let coded = ZigZag.encoded(value)
putVarInt(value: coded)
}
mutating func putBoolValue(value: Bool) {
append(value ? 1 : 0)
}
mutating func putFixedUInt64(value: UInt64) {
var v = value.littleEndian
let n = MemoryLayout<UInt64>.size
memcpy(pointer, &v, n)
pointer = pointer.advanced(by: n)
}
mutating func putFixedUInt32(value: UInt32) {
var v = value.littleEndian
let n = MemoryLayout<UInt32>.size
memcpy(pointer, &v, n)
pointer = pointer.advanced(by: n)
}
mutating func putFloatValue(value: Float) {
let n = MemoryLayout<Float>.size
var v = value
var nativeBytes: UInt32 = 0
memcpy(&nativeBytes, &v, n)
var littleEndianBytes = nativeBytes.littleEndian
memcpy(pointer, &littleEndianBytes, n)
pointer = pointer.advanced(by: n)
}
mutating func putDoubleValue(value: Double) {
let n = MemoryLayout<Double>.size
var v = value
var nativeBytes: UInt64 = 0
memcpy(&nativeBytes, &v, n)
var littleEndianBytes = nativeBytes.littleEndian
memcpy(pointer, &littleEndianBytes, n)
pointer = pointer.advanced(by: n)
}
// Write a string field, including the leading index/tag value.
mutating func putStringValue(value: String) {
let utf8 = value.utf8
#if swift(>=5.0)
// If the String does not support an internal representation in a form
// of contiguous storage, body is not called and nil is returned.
let isAvailable = utf8.withContiguousStorageIfAvailable { (body: UnsafeBufferPointer<UInt8>) -> Int in
putVarInt(value: body.count)
return append(contentsOf: UnsafeRawBufferPointer(body))
}
#else
let isAvailable: Int? = nil
#endif
if isAvailable == nil {
let count = utf8.count
putVarInt(value: count)
for b in utf8 {
pointer.storeBytes(of: b, as: UInt8.self)
pointer = pointer.advanced(by: 1)
}
}
}
mutating func putBytesValue(value: Data) {
putVarInt(value: value.count)
append(contentsOf: value)
}
}

View File

@ -0,0 +1,27 @@
// Sources/SwiftProtobuf/BinaryEncodingError.swift - Error constants
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Enum constants that identify the particular error.
///
// -----------------------------------------------------------------------------
/// Describes errors that can occur when decoding a message from binary format.
public enum BinaryEncodingError: Error {
/// `Any` fields that were decoded from JSON cannot be re-encoded to binary
/// unless the object they hold is a well-known type or a type registered via
/// `Google_Protobuf_Any.register()`.
case anyTranscodeFailure
/// The definition of the message or one of its nested messages has required
/// fields but the message being encoded did not include values for them. You
/// must pass `partial: true` during encoding if you wish to explicitly ignore
/// missing required fields.
case missingRequiredFields
}

View File

@ -0,0 +1,473 @@
// Sources/SwiftProtobuf/BinaryEncodingSizeVisitor.swift - Binary size calculation support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Visitor used during binary encoding that precalcuates the size of a
/// serialized message.
///
// -----------------------------------------------------------------------------
import Foundation
/// Visitor that calculates the binary-encoded size of a message so that a
/// properly sized `Data` or `UInt8` array can be pre-allocated before
/// serialization.
internal struct BinaryEncodingSizeVisitor: Visitor {
/// Accumulates the required size of the message during traversal.
var serializedSize: Int = 0
init() {}
mutating func visitUnknown(bytes: Data) throws {
serializedSize += bytes.count
}
mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize
serializedSize += tagSize + MemoryLayout<Float>.size
}
mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize
serializedSize += tagSize + MemoryLayout<Double>.size
}
mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws {
try visitSingularInt64Field(value: Int64(value), fieldNumber: fieldNumber)
}
mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
serializedSize += tagSize + Varint.encodedSize(of: value)
}
mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws {
try visitSingularUInt64Field(value: UInt64(value), fieldNumber: fieldNumber)
}
mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
serializedSize += tagSize + Varint.encodedSize(of: value)
}
mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
serializedSize += tagSize + Varint.encodedSize(of: ZigZag.encoded(value))
}
mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
serializedSize += tagSize + Varint.encodedSize(of: ZigZag.encoded(value))
}
mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize
serializedSize += tagSize + MemoryLayout<UInt32>.size
}
mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize
serializedSize += tagSize + MemoryLayout<UInt64>.size
}
mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize
serializedSize += tagSize + MemoryLayout<Int32>.size
}
mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize
serializedSize += tagSize + MemoryLayout<Int64>.size
}
mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
serializedSize += tagSize + 1
}
mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let count = value.utf8.count
serializedSize += tagSize + Varint.encodedSize(of: Int64(count)) + count
}
mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let count = value.count
serializedSize += tagSize + Varint.encodedSize(of: Int64(count)) + count
}
// The default impls for visitRepeated*Field would work, but by implementing
// these directly, the calculation for the tag overhead can be optimized and
// the fixed width fields can be simple multiplication.
mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize
serializedSize += tagSize * value.count + MemoryLayout<Float>.size * value.count
}
mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize
serializedSize += tagSize * value.count + MemoryLayout<Double>.size * value.count
}
mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
serializedSize += tagSize * value.count + dataSize
}
mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
serializedSize += tagSize * value.count + dataSize
}
mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
serializedSize += tagSize * value.count + dataSize
}
mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
serializedSize += tagSize * value.count + dataSize
}
mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) }
serializedSize += tagSize * value.count + dataSize
}
mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) }
serializedSize += tagSize * value.count + dataSize
}
mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize
serializedSize += tagSize * value.count + MemoryLayout<UInt32>.size * value.count
}
mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize
serializedSize += tagSize * value.count + MemoryLayout<UInt64>.size * value.count
}
mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed32).encodedSize
serializedSize += tagSize * value.count + MemoryLayout<Int32>.size * value.count
}
mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .fixed64).encodedSize
serializedSize += tagSize * value.count + MemoryLayout<Int64>.size * value.count
}
mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .varint).encodedSize
serializedSize += tagSize * value.count + 1 * value.count
}
mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.reduce(0) {
let count = $1.utf8.count
return $0 + Varint.encodedSize(of: Int64(count)) + count
}
serializedSize += tagSize * value.count + dataSize
}
mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.reduce(0) {
let count = $1.count
return $0 + Varint.encodedSize(of: Int64(count)) + count
}
serializedSize += tagSize * value.count + dataSize
}
// Packed field handling.
mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.count * MemoryLayout<Float>.size
serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.count * MemoryLayout<Double>.size
serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
serializedSize +=
tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
serializedSize +=
tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) }
serializedSize +=
tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) }
serializedSize +=
tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
serializedSize +=
tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
serializedSize +=
tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.count * MemoryLayout<UInt32>.size
serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.count * MemoryLayout<UInt64>.size
serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.count * MemoryLayout<Int32>.size
serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.count * MemoryLayout<Int64>.size
serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber, wireFormat: .lengthDelimited).encodedSize
let dataSize = value.count
serializedSize += tagSize + Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitSingularEnumField<E: Enum>(value: E,
fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber,
wireFormat: .varint).encodedSize
serializedSize += tagSize
let dataSize = Varint.encodedSize(of: Int32(truncatingIfNeeded: value.rawValue))
serializedSize += dataSize
}
mutating func visitRepeatedEnumField<E: Enum>(value: [E],
fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber,
wireFormat: .varint).encodedSize
serializedSize += value.count * tagSize
let dataSize = value.reduce(0) {
$0 + Varint.encodedSize(of: Int32(truncatingIfNeeded: $1.rawValue))
}
serializedSize += dataSize
}
mutating func visitPackedEnumField<E: Enum>(value: [E],
fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber,
wireFormat: .varint).encodedSize
serializedSize += tagSize
let dataSize = value.reduce(0) {
$0 + Varint.encodedSize(of: Int32(truncatingIfNeeded: $1.rawValue))
}
serializedSize += Varint.encodedSize(of: Int64(dataSize)) + dataSize
}
mutating func visitSingularMessageField<M: Message>(value: M,
fieldNumber: Int) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber,
wireFormat: .lengthDelimited).encodedSize
let messageSize = try value.serializedDataSize()
serializedSize +=
tagSize + Varint.encodedSize(of: UInt64(messageSize)) + messageSize
}
mutating func visitRepeatedMessageField<M: Message>(value: [M],
fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber,
wireFormat: .lengthDelimited).encodedSize
serializedSize += value.count * tagSize
let dataSize = try value.reduce(0) {
let messageSize = try $1.serializedDataSize()
return $0 + Varint.encodedSize(of: UInt64(messageSize)) + messageSize
}
serializedSize += dataSize
}
mutating func visitSingularGroupField<G: Message>(value: G, fieldNumber: Int) throws {
// The wire format doesn't matter here because the encoded size of the
// integer won't change based on the low three bits.
let tagSize = FieldTag(fieldNumber: fieldNumber,
wireFormat: .startGroup).encodedSize
serializedSize += 2 * tagSize
try value.traverse(visitor: &self)
}
mutating func visitRepeatedGroupField<G: Message>(value: [G],
fieldNumber: Int) throws {
assert(!value.isEmpty)
let tagSize = FieldTag(fieldNumber: fieldNumber,
wireFormat: .startGroup).encodedSize
serializedSize += 2 * value.count * tagSize
for v in value {
try v.traverse(visitor: &self)
}
}
mutating func visitMapField<KeyType, ValueType: MapValueType>(
fieldType: _ProtobufMap<KeyType, ValueType>.Type,
value: _ProtobufMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber,
wireFormat: .lengthDelimited).encodedSize
for (k,v) in value {
var sizer = BinaryEncodingSizeVisitor()
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer)
try ValueType.visitSingular(value: v, fieldNumber: 2, with: &sizer)
let entrySize = sizer.serializedSize
serializedSize += Varint.encodedSize(of: Int64(entrySize)) + entrySize
}
serializedSize += value.count * tagSize
}
mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
value: _ProtobufEnumMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws where ValueType.RawValue == Int {
let tagSize = FieldTag(fieldNumber: fieldNumber,
wireFormat: .lengthDelimited).encodedSize
for (k,v) in value {
var sizer = BinaryEncodingSizeVisitor()
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer)
try sizer.visitSingularEnumField(value: v, fieldNumber: 2)
let entrySize = sizer.serializedSize
serializedSize += Varint.encodedSize(of: Int64(entrySize)) + entrySize
}
serializedSize += value.count * tagSize
}
mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
value: _ProtobufMessageMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws {
let tagSize = FieldTag(fieldNumber: fieldNumber,
wireFormat: .lengthDelimited).encodedSize
for (k,v) in value {
var sizer = BinaryEncodingSizeVisitor()
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer)
try sizer.visitSingularMessageField(value: v, fieldNumber: 2)
let entrySize = sizer.serializedSize
serializedSize += Varint.encodedSize(of: Int64(entrySize)) + entrySize
}
serializedSize += value.count * tagSize
}
mutating func visitExtensionFieldsAsMessageSet(
fields: ExtensionFieldValueSet,
start: Int,
end: Int
) throws {
var sizer = BinaryEncodingMessageSetSizeVisitor()
try fields.traverse(visitor: &sizer, start: start, end: end)
serializedSize += sizer.serializedSize
}
}
extension BinaryEncodingSizeVisitor {
// Helper Visitor to compute the sizes when writing out the extensions as MessageSets.
internal struct BinaryEncodingMessageSetSizeVisitor: SelectiveVisitor {
var serializedSize: Int = 0
init() {}
mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) throws {
var groupSize = WireFormat.MessageSet.itemTagsEncodedSize
groupSize += Varint.encodedSize(of: Int32(fieldNumber))
let messageSize = try value.serializedDataSize()
groupSize += Varint.encodedSize(of: UInt64(messageSize)) + messageSize
serializedSize += groupSize
}
// SelectiveVisitor handles the rest.
}
}

View File

@ -0,0 +1,355 @@
// Sources/SwiftProtobuf/BinaryEncodingVisitor.swift - Binary encoding support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Core support for protobuf binary encoding. Note that this is built
/// on the general traversal machinery.
///
// -----------------------------------------------------------------------------
import Foundation
/// Visitor that encodes a message graph in the protobuf binary wire format.
internal struct BinaryEncodingVisitor: Visitor {
var encoder: BinaryEncoder
/// Creates a new visitor that writes the binary-coded message into the memory
/// at the given pointer.
///
/// - Precondition: `pointer` must point to an allocated block of memory that
/// is large enough to hold the entire encoded message. For performance
/// reasons, the encoder does not make any attempts to verify this.
init(forWritingInto pointer: UnsafeMutableRawPointer) {
encoder = BinaryEncoder(forWritingInto: pointer)
}
init(encoder: BinaryEncoder) {
self.encoder = encoder
}
mutating func visitUnknown(bytes: Data) throws {
encoder.appendUnknown(data: bytes)
}
mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .fixed32)
encoder.putFloatValue(value: value)
}
mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .fixed64)
encoder.putDoubleValue(value: value)
}
mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
try visitSingularUInt64Field(value: UInt64(bitPattern: value), fieldNumber: fieldNumber)
}
mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .varint)
encoder.putVarInt(value: value)
}
mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws {
try visitSingularSInt64Field(value: Int64(value), fieldNumber: fieldNumber)
}
mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws {
try visitSingularUInt64Field(value: ZigZag.encoded(value), fieldNumber: fieldNumber)
}
mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .fixed32)
encoder.putFixedUInt32(value: value)
}
mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .fixed64)
encoder.putFixedUInt64(value: value)
}
mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
try visitSingularFixed32Field(value: UInt32(bitPattern: value), fieldNumber: fieldNumber)
}
mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws {
try visitSingularFixed64Field(value: UInt64(bitPattern: value), fieldNumber: fieldNumber)
}
mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
try visitSingularUInt64Field(value: value ? 1 : 0, fieldNumber: fieldNumber)
}
mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
encoder.putStringValue(value: value)
}
mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
encoder.putBytesValue(value: value)
}
mutating func visitSingularEnumField<E: Enum>(value: E,
fieldNumber: Int) throws {
try visitSingularUInt64Field(value: UInt64(bitPattern: Int64(value.rawValue)),
fieldNumber: fieldNumber)
}
mutating func visitSingularMessageField<M: Message>(value: M,
fieldNumber: Int) throws {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
let length = try value.serializedDataSize()
encoder.putVarInt(value: length)
try value.traverse(visitor: &self)
}
mutating func visitSingularGroupField<G: Message>(value: G, fieldNumber: Int) throws {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .startGroup)
try value.traverse(visitor: &self)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .endGroup)
}
// Repeated fields are handled by the default implementations in Visitor.swift
// Packed Fields
mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
encoder.putVarInt(value: value.count * MemoryLayout<Float>.size)
for v in value {
encoder.putFloatValue(value: v)
}
}
mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
encoder.putVarInt(value: value.count * MemoryLayout<Double>.size)
for v in value {
encoder.putDoubleValue(value: v)
}
}
mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
encoder.putVarInt(value: packedSize)
for v in value {
encoder.putVarInt(value: Int64(v))
}
}
mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
encoder.putVarInt(value: packedSize)
for v in value {
encoder.putVarInt(value: v)
}
}
mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) }
encoder.putVarInt(value: packedSize)
for v in value {
encoder.putZigZagVarInt(value: Int64(v))
}
}
mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: ZigZag.encoded($1)) }
encoder.putVarInt(value: packedSize)
for v in value {
encoder.putZigZagVarInt(value: v)
}
}
mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
encoder.putVarInt(value: packedSize)
for v in value {
encoder.putVarInt(value: UInt64(v))
}
}
mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
let packedSize = value.reduce(0) { $0 + Varint.encodedSize(of: $1) }
encoder.putVarInt(value: packedSize)
for v in value {
encoder.putVarInt(value: v)
}
}
mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
encoder.putVarInt(value: value.count * MemoryLayout<UInt32>.size)
for v in value {
encoder.putFixedUInt32(value: v)
}
}
mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
encoder.putVarInt(value: value.count * MemoryLayout<UInt64>.size)
for v in value {
encoder.putFixedUInt64(value: v)
}
}
mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
encoder.putVarInt(value: value.count * MemoryLayout<Int32>.size)
for v in value {
encoder.putFixedUInt32(value: UInt32(bitPattern: v))
}
}
mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
encoder.putVarInt(value: value.count * MemoryLayout<Int64>.size)
for v in value {
encoder.putFixedUInt64(value: UInt64(bitPattern: v))
}
}
mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
encoder.putVarInt(value: value.count)
for v in value {
encoder.putVarInt(value: v ? 1 : 0)
}
}
mutating func visitPackedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws {
assert(!value.isEmpty)
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
let packedSize = value.reduce(0) {
$0 + Varint.encodedSize(of: Int32(truncatingIfNeeded: $1.rawValue))
}
encoder.putVarInt(value: packedSize)
for v in value {
encoder.putVarInt(value: v.rawValue)
}
}
mutating func visitMapField<KeyType, ValueType: MapValueType>(
fieldType: _ProtobufMap<KeyType, ValueType>.Type,
value: _ProtobufMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws {
for (k,v) in value {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
var sizer = BinaryEncodingSizeVisitor()
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer)
try ValueType.visitSingular(value: v, fieldNumber: 2, with: &sizer)
let entrySize = sizer.serializedSize
encoder.putVarInt(value: entrySize)
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &self)
try ValueType.visitSingular(value: v, fieldNumber: 2, with: &self)
}
}
mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
value: _ProtobufEnumMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws where ValueType.RawValue == Int {
for (k,v) in value {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
var sizer = BinaryEncodingSizeVisitor()
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer)
try sizer.visitSingularEnumField(value: v, fieldNumber: 2)
let entrySize = sizer.serializedSize
encoder.putVarInt(value: entrySize)
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &self)
try visitSingularEnumField(value: v, fieldNumber: 2)
}
}
mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
value: _ProtobufMessageMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws {
for (k,v) in value {
encoder.startField(fieldNumber: fieldNumber, wireFormat: .lengthDelimited)
var sizer = BinaryEncodingSizeVisitor()
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &sizer)
try sizer.visitSingularMessageField(value: v, fieldNumber: 2)
let entrySize = sizer.serializedSize
encoder.putVarInt(value: entrySize)
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &self)
try visitSingularMessageField(value: v, fieldNumber: 2)
}
}
mutating func visitExtensionFieldsAsMessageSet(
fields: ExtensionFieldValueSet,
start: Int,
end: Int
) throws {
var subVisitor = BinaryEncodingMessageSetVisitor(encoder: encoder)
try fields.traverse(visitor: &subVisitor, start: start, end: end)
encoder = subVisitor.encoder
}
}
extension BinaryEncodingVisitor {
// Helper Visitor to when writing out the extensions as MessageSets.
internal struct BinaryEncodingMessageSetVisitor: SelectiveVisitor {
var encoder: BinaryEncoder
init(encoder: BinaryEncoder) {
self.encoder = encoder
}
mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) throws {
encoder.putVarInt(value: Int64(WireFormat.MessageSet.Tags.itemStart.rawValue))
encoder.putVarInt(value: Int64(WireFormat.MessageSet.Tags.typeId.rawValue))
encoder.putVarInt(value: fieldNumber)
encoder.putVarInt(value: Int64(WireFormat.MessageSet.Tags.message.rawValue))
// Use a normal BinaryEncodingVisitor so any message fields end up in the
// normal wire format (instead of MessageSet format).
let length = try value.serializedDataSize()
encoder.putVarInt(value: length)
// Create the sub encoder after writing the length.
var subVisitor = BinaryEncodingVisitor(encoder: encoder)
try value.traverse(visitor: &subVisitor)
encoder = subVisitor.encoder
encoder.putVarInt(value: Int64(WireFormat.MessageSet.Tags.itemEnd.rawValue))
}
// SelectiveVisitor handles the rest.
}
}

View File

@ -0,0 +1,36 @@
// Sources/SwiftProtobuf/CustomJSONCodable.swift - Custom JSON support for WKTs
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Custom protocol for the WKTs to support their custom JSON encodings.
///
// -----------------------------------------------------------------------------
/// Allows WKTs to provide their custom JSON encodings.
internal protocol _CustomJSONCodable {
func encodedJSONString(options: JSONEncodingOptions) throws -> String
mutating func decodeJSON(from: inout JSONDecoder) throws
/// Called when the JSON `null` literal is encountered in a position where
/// a message of the conforming type is expected. The message type can then
/// handle the `null` value differently, if needed; for example,
/// `Google_Protobuf_Value` returns a special instance whose `kind` is set to
/// `.nullValue(.nullValue)`.
///
/// The default behavior is to return `nil`, which indicates that `null`
/// should be treated as the absence of a message.
static func decodedFromJSONNull() throws -> Self?
}
extension _CustomJSONCodable {
internal static func decodedFromJSONNull() -> Self? {
// Return nil by default. Concrete types can provide custom logic.
return nil
}
}

View File

@ -0,0 +1,34 @@
// Sources/SwiftProtobuf/Data+Extensions.swift - Extension exposing new Data API
//
// Copyright (c) 2014 - 2019 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extension exposing new Data API to Swift versions < 5.0.
///
// -----------------------------------------------------------------------------
import Foundation
#if !swift(>=5.0)
internal extension Data {
@usableFromInline
func withUnsafeBytes<T>(_ body: (UnsafeRawBufferPointer) throws -> T) rethrows -> T {
let c = count
return try withUnsafeBytes { (p: UnsafePointer<UInt8>) throws -> T in
try body(UnsafeRawBufferPointer(start: p, count: c))
}
}
mutating func withUnsafeMutableBytes<T>(_ body: (UnsafeMutableRawBufferPointer) throws -> T) rethrows -> T {
let c = count
return try withUnsafeMutableBytes { (p: UnsafeMutablePointer<UInt8>) throws -> T in
try body(UnsafeMutableRawBufferPointer(start: p, count: c))
}
}
}
#endif

View File

@ -0,0 +1,150 @@
// Sources/SwiftProtobuf/Decoder.swift - Basic field setting
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// In this way, the generated code only knows about schema
/// information; the decoder logic knows how to decode particular
/// wire types based on that information.
///
// -----------------------------------------------------------------------------
import Foundation
/// This is the abstract protocol used by the generated code
/// to deserialize data.
///
/// The generated code looks roughly like this:
///
/// ```
/// while fieldNumber = try decoder.nextFieldNumber() {
/// switch fieldNumber {
/// case 1: decoder.decodeRepeatedInt32Field(value: &_field)
/// ... etc ...
/// }
/// ```
///
/// For performance, this is mostly broken out into a separate method
/// for singular/repeated fields of every supported type. Note that
/// we don't distinguish "packed" here, since all existing decoders
/// treat "packed" the same as "repeated" at this level. (That is,
/// even when the serializer distinguishes packed and non-packed
/// forms, the deserializer always accepts both.)
///
/// Generics come into play at only a few points: `Enum`s and `Message`s
/// use a generic type to locate the correct initializer. Maps and
/// extensions use generics to avoid the method explosion of having to
/// support a separate method for every map and extension type. Maps
/// do distinguish `Enum`-valued and `Message`-valued maps to avoid
/// polluting the generated `Enum` and `Message` types with all of the
/// necessary generic methods to support this.
public protocol Decoder {
/// Called by a `oneof` when it already has a value and is being asked to
/// accept a new value. Some formats require `oneof` decoding to fail in this
/// case.
mutating func handleConflictingOneOf() throws
/// Returns the next field number, or nil when the end of the input is
/// reached.
///
/// For JSON and text format, the decoder translates the field name to a
/// number at this point, based on information it obtained from the message
/// when it was initialized.
mutating func nextFieldNumber() throws -> Int?
// Primitive field decoders
mutating func decodeSingularFloatField(value: inout Float) throws
mutating func decodeSingularFloatField(value: inout Float?) throws
mutating func decodeRepeatedFloatField(value: inout [Float]) throws
mutating func decodeSingularDoubleField(value: inout Double) throws
mutating func decodeSingularDoubleField(value: inout Double?) throws
mutating func decodeRepeatedDoubleField(value: inout [Double]) throws
mutating func decodeSingularInt32Field(value: inout Int32) throws
mutating func decodeSingularInt32Field(value: inout Int32?) throws
mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws
mutating func decodeSingularInt64Field(value: inout Int64) throws
mutating func decodeSingularInt64Field(value: inout Int64?) throws
mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws
mutating func decodeSingularUInt32Field(value: inout UInt32) throws
mutating func decodeSingularUInt32Field(value: inout UInt32?) throws
mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws
mutating func decodeSingularUInt64Field(value: inout UInt64) throws
mutating func decodeSingularUInt64Field(value: inout UInt64?) throws
mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws
mutating func decodeSingularSInt32Field(value: inout Int32) throws
mutating func decodeSingularSInt32Field(value: inout Int32?) throws
mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws
mutating func decodeSingularSInt64Field(value: inout Int64) throws
mutating func decodeSingularSInt64Field(value: inout Int64?) throws
mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws
mutating func decodeSingularFixed32Field(value: inout UInt32) throws
mutating func decodeSingularFixed32Field(value: inout UInt32?) throws
mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws
mutating func decodeSingularFixed64Field(value: inout UInt64) throws
mutating func decodeSingularFixed64Field(value: inout UInt64?) throws
mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws
mutating func decodeSingularSFixed32Field(value: inout Int32) throws
mutating func decodeSingularSFixed32Field(value: inout Int32?) throws
mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws
mutating func decodeSingularSFixed64Field(value: inout Int64) throws
mutating func decodeSingularSFixed64Field(value: inout Int64?) throws
mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws
mutating func decodeSingularBoolField(value: inout Bool) throws
mutating func decodeSingularBoolField(value: inout Bool?) throws
mutating func decodeRepeatedBoolField(value: inout [Bool]) throws
mutating func decodeSingularStringField(value: inout String) throws
mutating func decodeSingularStringField(value: inout String?) throws
mutating func decodeRepeatedStringField(value: inout [String]) throws
mutating func decodeSingularBytesField(value: inout Data) throws
mutating func decodeSingularBytesField(value: inout Data?) throws
mutating func decodeRepeatedBytesField(value: inout [Data]) throws
// Decode Enum fields
mutating func decodeSingularEnumField<E: Enum>(value: inout E) throws where E.RawValue == Int
mutating func decodeSingularEnumField<E: Enum>(value: inout E?) throws where E.RawValue == Int
mutating func decodeRepeatedEnumField<E: Enum>(value: inout [E]) throws where E.RawValue == Int
// Decode Message fields
mutating func decodeSingularMessageField<M: Message>(value: inout M?) throws
mutating func decodeRepeatedMessageField<M: Message>(value: inout [M]) throws
// Decode Group fields
mutating func decodeSingularGroupField<G: Message>(value: inout G?) throws
mutating func decodeRepeatedGroupField<G: Message>(value: inout [G]) throws
// Decode Map fields.
// This is broken into separate methods depending on whether the value
// type is primitive (_ProtobufMap), enum (_ProtobufEnumMap), or message
// (_ProtobufMessageMap)
mutating func decodeMapField<KeyType, ValueType: MapValueType>(fieldType: _ProtobufMap<KeyType, ValueType>.Type, value: inout _ProtobufMap<KeyType, ValueType>.BaseType) throws
mutating func decodeMapField<KeyType, ValueType>(fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type, value: inout _ProtobufEnumMap<KeyType, ValueType>.BaseType) throws where ValueType.RawValue == Int
mutating func decodeMapField<KeyType, ValueType>(fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type, value: inout _ProtobufMessageMap<KeyType, ValueType>.BaseType) throws
// Decode extension fields
mutating func decodeExtensionField(values: inout ExtensionFieldValueSet, messageType: Message.Type, fieldNumber: Int) throws
// Run a decode loop decoding the MessageSet format for Extensions.
mutating func decodeExtensionFieldsAsMessageSet(values: inout ExtensionFieldValueSet,
messageType: Message.Type) throws
}
/// Most Decoders won't care about Extension handing as in MessageSet
/// format, so provide a default implementation simply looping on the
/// fieldNumbers and feeding through to extension decoding.
extension Decoder {
public mutating func decodeExtensionFieldsAsMessageSet(
values: inout ExtensionFieldValueSet,
messageType: Message.Type
) throws {
while let fieldNumber = try self.nextFieldNumber() {
try self.decodeExtensionField(values: &values,
messageType: messageType,
fieldNumber: fieldNumber)
}
}
}

View File

@ -0,0 +1,61 @@
// Sources/SwiftProtobuf/DoubleParser.swift - Generally useful mathematical functions
//
// Copyright (c) 2014 - 2019 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Numeric parsing helper for float and double strings
///
// -----------------------------------------------------------------------------
import Foundation
/// Support parsing float/double values from UTF-8
internal class DoubleParser {
// Temporary buffer so we can null-terminate the UTF-8 string
// before calling the C standard libray to parse it.
// In theory, JSON writers should be able to represent any IEEE Double
// in at most 25 bytes, but many writers will emit more digits than
// necessary, so we size this generously.
private var work =
UnsafeMutableBufferPointer<Int8>.allocate(capacity: 128)
deinit {
work.deallocate()
}
func utf8ToDouble(bytes: UnsafeRawBufferPointer,
start: UnsafeRawBufferPointer.Index,
end: UnsafeRawBufferPointer.Index) -> Double? {
return utf8ToDouble(bytes: UnsafeRawBufferPointer(rebasing: bytes[start..<end]))
}
func utf8ToDouble(bytes: UnsafeRawBufferPointer) -> Double? {
// Reject unreasonably long or short UTF8 number
if work.count <= bytes.count || bytes.count < 1 {
return nil
}
#if swift(>=4.1)
UnsafeMutableRawBufferPointer(work).copyMemory(from: bytes)
#else
UnsafeMutableRawBufferPointer(work).copyBytes(from: bytes)
#endif
work[bytes.count] = 0
// Use C library strtod() to parse it
var e: UnsafeMutablePointer<Int8>? = work.baseAddress
let d = strtod(work.baseAddress!, &e)
// Fail if strtod() did not consume everything we expected
// or if strtod() thought the number was out of range.
if e != work.baseAddress! + bytes.count || !d.isFinite {
return nil
}
return d
}
}

View File

@ -0,0 +1,93 @@
// Sources/SwiftProtobuf/Enum.swift - Enum support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Generated enums conform to SwiftProtobuf.Enum
///
/// See ProtobufTypes and JSONTypes for extension
/// methods to support binary and JSON coding.
///
// -----------------------------------------------------------------------------
/// Generated enum types conform to this protocol.
public protocol Enum: RawRepresentable, Hashable {
/// Creates a new instance of the enum initialized to its default value.
init()
/// Creates a new instance of the enum from the given raw integer value.
///
/// For proto2 enums, this initializer will fail if the raw value does not
/// correspond to a valid enum value. For proto3 enums, this initializer never
/// fails; unknown values are created as instances of the `UNRECOGNIZED` case.
///
/// - Parameter rawValue: The raw integer value from which to create the enum
/// value.
init?(rawValue: Int)
/// The raw integer value of the enum value.
///
/// For a recognized enum case, this is the integer value of the case as
/// defined in the .proto file. For `UNRECOGNIZED` cases in proto3, this is
/// the value that was originally decoded.
var rawValue: Int { get }
}
extension Enum {
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
hasher.combine(rawValue)
}
#else // swift(>=4.2)
public var hashValue: Int {
return rawValue
}
#endif // swift(>=4.2)
/// Internal convenience property representing the name of the enum value (or
/// `nil` if it is an `UNRECOGNIZED` value or doesn't provide names).
///
/// Since the text format and JSON names are always identical, we don't need
/// to distinguish them.
internal var name: _NameMap.Name? {
guard let nameProviding = Self.self as? _ProtoNameProviding.Type else {
return nil
}
return nameProviding._protobuf_nameMap.names(for: rawValue)?.proto
}
/// Internal convenience initializer that returns the enum value with the
/// given name, if it provides names.
///
/// Since the text format and JSON names are always identical, we don't need
/// to distinguish them.
///
/// - Parameter name: The name of the enum case.
internal init?(name: String) {
guard let nameProviding = Self.self as? _ProtoNameProviding.Type,
let number = nameProviding._protobuf_nameMap.number(forJSONName: name) else {
return nil
}
self.init(rawValue: number)
}
/// Internal convenience initializer that returns the enum value with the
/// given name, if it provides names.
///
/// Since the text format and JSON names are always identical, we don't need
/// to distinguish them.
///
/// - Parameter name: Buffer holding the UTF-8 bytes of the desired name.
internal init?(rawUTF8: UnsafeRawBufferPointer) {
guard let nameProviding = Self.self as? _ProtoNameProviding.Type,
let number = nameProviding._protobuf_nameMap.number(forJSONName: rawUTF8) else {
return nil
}
self.init(rawValue: number)
}
}

View File

@ -0,0 +1,73 @@
// Sources/SwiftProtobuf/ExtensibleMessage.swift - Extension support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Additional capabilities needed by messages that allow extensions.
///
// -----------------------------------------------------------------------------
// Messages that support extensions implement this protocol
public protocol ExtensibleMessage: Message {
var _protobuf_extensionFieldValues: ExtensionFieldValueSet { get set }
}
extension ExtensibleMessage {
public mutating func setExtensionValue<F: ExtensionField>(ext: MessageExtension<F, Self>, value: F.ValueType) {
_protobuf_extensionFieldValues[ext.fieldNumber] = F(protobufExtension: ext, value: value)
}
public func getExtensionValue<F: ExtensionField>(ext: MessageExtension<F, Self>) -> F.ValueType? {
if let fieldValue = _protobuf_extensionFieldValues[ext.fieldNumber] as? F {
return fieldValue.value
}
return nil
}
public func hasExtensionValue<F: ExtensionField>(ext: MessageExtension<F, Self>) -> Bool {
return _protobuf_extensionFieldValues[ext.fieldNumber] is F
}
public mutating func clearExtensionValue<F: ExtensionField>(ext: MessageExtension<F, Self>) {
_protobuf_extensionFieldValues[ext.fieldNumber] = nil
}
}
// Additional specializations for the different types of repeated fields so
// setting them to an empty array clears them from the map.
extension ExtensibleMessage {
public mutating func setExtensionValue<T>(ext: MessageExtension<RepeatedExtensionField<T>, Self>, value: [T.BaseType]) {
_protobuf_extensionFieldValues[ext.fieldNumber] =
value.isEmpty ? nil : RepeatedExtensionField<T>(protobufExtension: ext, value: value)
}
public mutating func setExtensionValue<T>(ext: MessageExtension<PackedExtensionField<T>, Self>, value: [T.BaseType]) {
_protobuf_extensionFieldValues[ext.fieldNumber] =
value.isEmpty ? nil : PackedExtensionField<T>(protobufExtension: ext, value: value)
}
public mutating func setExtensionValue<E>(ext: MessageExtension<RepeatedEnumExtensionField<E>, Self>, value: [E]) {
_protobuf_extensionFieldValues[ext.fieldNumber] =
value.isEmpty ? nil : RepeatedEnumExtensionField<E>(protobufExtension: ext, value: value)
}
public mutating func setExtensionValue<E>(ext: MessageExtension<PackedEnumExtensionField<E>, Self>, value: [E]) {
_protobuf_extensionFieldValues[ext.fieldNumber] =
value.isEmpty ? nil : PackedEnumExtensionField<E>(protobufExtension: ext, value: value)
}
public mutating func setExtensionValue<M>(ext: MessageExtension<RepeatedMessageExtensionField<M>, Self>, value: [M]) {
_protobuf_extensionFieldValues[ext.fieldNumber] =
value.isEmpty ? nil : RepeatedMessageExtensionField<M>(protobufExtension: ext, value: value)
}
public mutating func setExtensionValue<M>(ext: MessageExtension<RepeatedGroupExtensionField<M>, Self>, value: [M]) {
_protobuf_extensionFieldValues[ext.fieldNumber] =
value.isEmpty ? nil : RepeatedGroupExtensionField<M>(protobufExtension: ext, value: value)
}
}

View File

@ -0,0 +1,89 @@
// Sources/SwiftProtobuf/ExtensionFieldValueSet.swift - Extension support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// A collection of extension field values on a particular object.
/// This is only used within messages to manage the values of extension fields;
/// it does not need to be very sophisticated.
///
// -----------------------------------------------------------------------------
public struct ExtensionFieldValueSet: Hashable {
fileprivate var values = [Int : AnyExtensionField]()
public static func ==(lhs: ExtensionFieldValueSet,
rhs: ExtensionFieldValueSet) -> Bool {
guard lhs.values.count == rhs.values.count else {
return false
}
for (index, l) in lhs.values {
if let r = rhs.values[index] {
if type(of: l) != type(of: r) {
return false
}
if !l.isEqual(other: r) {
return false
}
} else {
return false
}
}
return true
}
public init() {}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
// AnyExtensionField is not Hashable, and the Self constraint that would
// add breaks some of the uses of it; so the only choice is to manually
// mix things in. However, one must remember to do things in an order
// independent manner.
var hash = 16777619
for (fieldNumber, v) in values {
var localHasher = hasher
localHasher.combine(fieldNumber)
v.hash(into: &localHasher)
hash = hash &+ localHasher.finalize()
}
hasher.combine(hash)
}
#else // swift(>=4.2)
public var hashValue: Int {
var hash = 16777619
for (fieldNumber, v) in values {
// Note: This calculation cannot depend on the order of the items.
hash = hash &+ fieldNumber &+ v.hashValue
}
return hash
}
#endif // swift(>=4.2)
public func traverse<V: Visitor>(visitor: inout V, start: Int, end: Int) throws {
let validIndexes = values.keys.filter {$0 >= start && $0 < end}
for i in validIndexes.sorted() {
let value = values[i]!
try value.traverse(visitor: &visitor)
}
}
public subscript(index: Int) -> AnyExtensionField? {
get { return values[index] }
set { values[index] = newValue }
}
public var isInitialized: Bool {
for (_, v) in values {
if !v.isInitialized {
return false
}
}
return true
}
}

View File

@ -0,0 +1,708 @@
// Sources/SwiftProtobuf/ExtensionFields.swift - Extension support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Core protocols implemented by generated extensions.
///
// -----------------------------------------------------------------------------
#if !swift(>=4.2)
private let i_2166136261 = Int(bitPattern: 2166136261)
private let i_16777619 = Int(16777619)
#endif
//
// Type-erased Extension field implementation.
// Note that it has no "self or associated type" references, so can
// be used as a protocol type. (In particular, although it does have
// a hashValue property, it cannot be Hashable.)
//
// This can encode, decode, return a hashValue and test for
// equality with some other extension field; but it's type-sealed
// so you can't actually access the contained value itself.
//
public protocol AnyExtensionField: CustomDebugStringConvertible {
#if swift(>=4.2)
func hash(into hasher: inout Hasher)
#else
var hashValue: Int { get }
#endif
var protobufExtension: AnyMessageExtension { get }
func isEqual(other: AnyExtensionField) -> Bool
/// Merging field decoding
mutating func decodeExtensionField<T: Decoder>(decoder: inout T) throws
/// Fields know their own type, so can dispatch to a visitor
func traverse<V: Visitor>(visitor: inout V) throws
/// Check if the field is initialized.
var isInitialized: Bool { get }
}
extension AnyExtensionField {
// Default implementation for extensions fields. The message types below provide
// custom versions.
public var isInitialized: Bool { return true }
}
///
/// The regular ExtensionField type exposes the value directly.
///
public protocol ExtensionField: AnyExtensionField, Hashable {
associatedtype ValueType
var value: ValueType { get set }
init(protobufExtension: AnyMessageExtension, value: ValueType)
init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws
}
///
/// Singular field
///
public struct OptionalExtensionField<T: FieldType>: ExtensionField {
public typealias BaseType = T.BaseType
public typealias ValueType = BaseType
public var value: ValueType
public var protobufExtension: AnyMessageExtension
public static func ==(lhs: OptionalExtensionField,
rhs: OptionalExtensionField) -> Bool {
return lhs.value == rhs.value
}
public init(protobufExtension: AnyMessageExtension, value: ValueType) {
self.protobufExtension = protobufExtension
self.value = value
}
public var debugDescription: String {
get {
return String(reflecting: value)
}
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
#else // swift(>=4.2)
public var hashValue: Int {
get { return value.hashValue }
}
#endif // swift(>=4.2)
public func isEqual(other: AnyExtensionField) -> Bool {
let o = other as! OptionalExtensionField<T>
return self == o
}
public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
var v: ValueType?
try T.decodeSingular(value: &v, from: &decoder)
if let v = v {
value = v
}
}
public init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws {
var v: ValueType?
try T.decodeSingular(value: &v, from: &decoder)
if let v = v {
self.init(protobufExtension: protobufExtension, value: v)
} else {
return nil
}
}
public func traverse<V: Visitor>(visitor: inout V) throws {
try T.visitSingular(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor)
}
}
///
/// Repeated fields
///
public struct RepeatedExtensionField<T: FieldType>: ExtensionField {
public typealias BaseType = T.BaseType
public typealias ValueType = [BaseType]
public var value: ValueType
public var protobufExtension: AnyMessageExtension
public static func ==(lhs: RepeatedExtensionField,
rhs: RepeatedExtensionField) -> Bool {
return lhs.value == rhs.value
}
public init(protobufExtension: AnyMessageExtension, value: ValueType) {
self.protobufExtension = protobufExtension
self.value = value
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
#else // swift(>=4.2)
public var hashValue: Int {
get {
var hash = i_2166136261
for e in value {
hash = (hash &* i_16777619) ^ e.hashValue
}
return hash
}
}
#endif // swift(>=4.2)
public func isEqual(other: AnyExtensionField) -> Bool {
let o = other as! RepeatedExtensionField<T>
return self == o
}
public var debugDescription: String {
return "[" + value.map{String(reflecting: $0)}.joined(separator: ",") + "]"
}
public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
try T.decodeRepeated(value: &value, from: &decoder)
}
public init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws {
var v: ValueType = []
try T.decodeRepeated(value: &v, from: &decoder)
self.init(protobufExtension: protobufExtension, value: v)
}
public func traverse<V: Visitor>(visitor: inout V) throws {
if value.count > 0 {
try T.visitRepeated(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor)
}
}
}
///
/// Packed Repeated fields
///
/// TODO: This is almost (but not quite) identical to RepeatedFields;
/// find a way to collapse the implementations.
///
public struct PackedExtensionField<T: FieldType>: ExtensionField {
public typealias BaseType = T.BaseType
public typealias ValueType = [BaseType]
public var value: ValueType
public var protobufExtension: AnyMessageExtension
public static func ==(lhs: PackedExtensionField,
rhs: PackedExtensionField) -> Bool {
return lhs.value == rhs.value
}
public init(protobufExtension: AnyMessageExtension, value: ValueType) {
self.protobufExtension = protobufExtension
self.value = value
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
#else // swift(>=4.2)
public var hashValue: Int {
get {
var hash = i_2166136261
for e in value {
hash = (hash &* i_16777619) ^ e.hashValue
}
return hash
}
}
#endif // swift(>=4.2)
public func isEqual(other: AnyExtensionField) -> Bool {
let o = other as! PackedExtensionField<T>
return self == o
}
public var debugDescription: String {
return "[" + value.map{String(reflecting: $0)}.joined(separator: ",") + "]"
}
public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
try T.decodeRepeated(value: &value, from: &decoder)
}
public init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws {
var v: ValueType = []
try T.decodeRepeated(value: &v, from: &decoder)
self.init(protobufExtension: protobufExtension, value: v)
}
public func traverse<V: Visitor>(visitor: inout V) throws {
if value.count > 0 {
try T.visitPacked(value: value, fieldNumber: protobufExtension.fieldNumber, with: &visitor)
}
}
}
///
/// Enum extensions
///
public struct OptionalEnumExtensionField<E: Enum>: ExtensionField where E.RawValue == Int {
public typealias BaseType = E
public typealias ValueType = E
public var value: ValueType
public var protobufExtension: AnyMessageExtension
public static func ==(lhs: OptionalEnumExtensionField,
rhs: OptionalEnumExtensionField) -> Bool {
return lhs.value == rhs.value
}
public init(protobufExtension: AnyMessageExtension, value: ValueType) {
self.protobufExtension = protobufExtension
self.value = value
}
public var debugDescription: String {
get {
return String(reflecting: value)
}
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
#else // swift(>=4.2)
public var hashValue: Int {
get { return value.hashValue }
}
#endif // swift(>=4.2)
public func isEqual(other: AnyExtensionField) -> Bool {
let o = other as! OptionalEnumExtensionField<E>
return self == o
}
public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
var v: ValueType?
try decoder.decodeSingularEnumField(value: &v)
if let v = v {
value = v
}
}
public init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws {
var v: ValueType?
try decoder.decodeSingularEnumField(value: &v)
if let v = v {
self.init(protobufExtension: protobufExtension, value: v)
} else {
return nil
}
}
public func traverse<V: Visitor>(visitor: inout V) throws {
try visitor.visitSingularEnumField(
value: value,
fieldNumber: protobufExtension.fieldNumber)
}
}
///
/// Repeated Enum fields
///
public struct RepeatedEnumExtensionField<E: Enum>: ExtensionField where E.RawValue == Int {
public typealias BaseType = E
public typealias ValueType = [E]
public var value: ValueType
public var protobufExtension: AnyMessageExtension
public static func ==(lhs: RepeatedEnumExtensionField,
rhs: RepeatedEnumExtensionField) -> Bool {
return lhs.value == rhs.value
}
public init(protobufExtension: AnyMessageExtension, value: ValueType) {
self.protobufExtension = protobufExtension
self.value = value
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
#else // swift(>=4.2)
public var hashValue: Int {
get {
var hash = i_2166136261
for e in value {
hash = (hash &* i_16777619) ^ e.hashValue
}
return hash
}
}
#endif // swift(>=4.2)
public func isEqual(other: AnyExtensionField) -> Bool {
let o = other as! RepeatedEnumExtensionField<E>
return self == o
}
public var debugDescription: String {
return "[" + value.map{String(reflecting: $0)}.joined(separator: ",") + "]"
}
public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
try decoder.decodeRepeatedEnumField(value: &value)
}
public init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws {
var v: ValueType = []
try decoder.decodeRepeatedEnumField(value: &v)
self.init(protobufExtension: protobufExtension, value: v)
}
public func traverse<V: Visitor>(visitor: inout V) throws {
if value.count > 0 {
try visitor.visitRepeatedEnumField(
value: value,
fieldNumber: protobufExtension.fieldNumber)
}
}
}
///
/// Packed Repeated Enum fields
///
/// TODO: This is almost (but not quite) identical to RepeatedEnumFields;
/// find a way to collapse the implementations.
///
public struct PackedEnumExtensionField<E: Enum>: ExtensionField where E.RawValue == Int {
public typealias BaseType = E
public typealias ValueType = [E]
public var value: ValueType
public var protobufExtension: AnyMessageExtension
public static func ==(lhs: PackedEnumExtensionField,
rhs: PackedEnumExtensionField) -> Bool {
return lhs.value == rhs.value
}
public init(protobufExtension: AnyMessageExtension, value: ValueType) {
self.protobufExtension = protobufExtension
self.value = value
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
#else // swift(>=4.2)
public var hashValue: Int {
get {
var hash = i_2166136261
for e in value {
hash = (hash &* i_16777619) ^ e.hashValue
}
return hash
}
}
#endif // swift(>=4.2)
public func isEqual(other: AnyExtensionField) -> Bool {
let o = other as! PackedEnumExtensionField<E>
return self == o
}
public var debugDescription: String {
return "[" + value.map{String(reflecting: $0)}.joined(separator: ",") + "]"
}
public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
try decoder.decodeRepeatedEnumField(value: &value)
}
public init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws {
var v: ValueType = []
try decoder.decodeRepeatedEnumField(value: &v)
self.init(protobufExtension: protobufExtension, value: v)
}
public func traverse<V: Visitor>(visitor: inout V) throws {
if value.count > 0 {
try visitor.visitPackedEnumField(
value: value,
fieldNumber: protobufExtension.fieldNumber)
}
}
}
//
// ========== Message ==========
//
public struct OptionalMessageExtensionField<M: Message & Equatable>:
ExtensionField {
public typealias BaseType = M
public typealias ValueType = BaseType
public var value: ValueType
public var protobufExtension: AnyMessageExtension
public static func ==(lhs: OptionalMessageExtensionField,
rhs: OptionalMessageExtensionField) -> Bool {
return lhs.value == rhs.value
}
public init(protobufExtension: AnyMessageExtension, value: ValueType) {
self.protobufExtension = protobufExtension
self.value = value
}
public var debugDescription: String {
get {
return String(reflecting: value)
}
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
value.hash(into: &hasher)
}
#else // swift(>=4.2)
public var hashValue: Int {return value.hashValue}
#endif // swift(>=4.2)
public func isEqual(other: AnyExtensionField) -> Bool {
let o = other as! OptionalMessageExtensionField<M>
return self == o
}
public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
var v: ValueType? = value
try decoder.decodeSingularMessageField(value: &v)
if let v = v {
self.value = v
}
}
public init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws {
var v: ValueType?
try decoder.decodeSingularMessageField(value: &v)
if let v = v {
self.init(protobufExtension: protobufExtension, value: v)
} else {
return nil
}
}
public func traverse<V: Visitor>(visitor: inout V) throws {
try visitor.visitSingularMessageField(
value: value, fieldNumber: protobufExtension.fieldNumber)
}
public var isInitialized: Bool {
return value.isInitialized
}
}
public struct RepeatedMessageExtensionField<M: Message & Equatable>:
ExtensionField {
public typealias BaseType = M
public typealias ValueType = [BaseType]
public var value: ValueType
public var protobufExtension: AnyMessageExtension
public static func ==(lhs: RepeatedMessageExtensionField,
rhs: RepeatedMessageExtensionField) -> Bool {
return lhs.value == rhs.value
}
public init(protobufExtension: AnyMessageExtension, value: ValueType) {
self.protobufExtension = protobufExtension
self.value = value
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
for e in value {
e.hash(into: &hasher)
}
}
#else // swift(>=4.2)
public var hashValue: Int {
get {
var hash = i_2166136261
for e in value {
hash = (hash &* i_16777619) ^ e.hashValue
}
return hash
}
}
#endif // swift(>=4.2)
public func isEqual(other: AnyExtensionField) -> Bool {
let o = other as! RepeatedMessageExtensionField<M>
return self == o
}
public var debugDescription: String {
return "[" + value.map{String(reflecting: $0)}.joined(separator: ",") + "]"
}
public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
try decoder.decodeRepeatedMessageField(value: &value)
}
public init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws {
var v: ValueType = []
try decoder.decodeRepeatedMessageField(value: &v)
self.init(protobufExtension: protobufExtension, value: v)
}
public func traverse<V: Visitor>(visitor: inout V) throws {
if value.count > 0 {
try visitor.visitRepeatedMessageField(
value: value, fieldNumber: protobufExtension.fieldNumber)
}
}
public var isInitialized: Bool {
return Internal.areAllInitialized(value)
}
}
//
// ======== Groups within Messages ========
//
// Protoc internally treats groups the same as messages, but
// they serialize very differently, so we have separate serialization
// handling here...
public struct OptionalGroupExtensionField<G: Message & Hashable>:
ExtensionField {
public typealias BaseType = G
public typealias ValueType = BaseType
public var value: G
public var protobufExtension: AnyMessageExtension
public static func ==(lhs: OptionalGroupExtensionField,
rhs: OptionalGroupExtensionField) -> Bool {
return lhs.value == rhs.value
}
public init(protobufExtension: AnyMessageExtension, value: ValueType) {
self.protobufExtension = protobufExtension
self.value = value
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
#else // swift(>=4.2)
public var hashValue: Int {return value.hashValue}
#endif // swift(>=4.2)
public var debugDescription: String { get {return value.debugDescription} }
public func isEqual(other: AnyExtensionField) -> Bool {
let o = other as! OptionalGroupExtensionField<G>
return self == o
}
public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
var v: ValueType? = value
try decoder.decodeSingularGroupField(value: &v)
if let v = v {
value = v
}
}
public init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws {
var v: ValueType?
try decoder.decodeSingularGroupField(value: &v)
if let v = v {
self.init(protobufExtension: protobufExtension, value: v)
} else {
return nil
}
}
public func traverse<V: Visitor>(visitor: inout V) throws {
try visitor.visitSingularGroupField(
value: value, fieldNumber: protobufExtension.fieldNumber)
}
public var isInitialized: Bool {
return value.isInitialized
}
}
public struct RepeatedGroupExtensionField<G: Message & Hashable>:
ExtensionField {
public typealias BaseType = G
public typealias ValueType = [BaseType]
public var value: ValueType
public var protobufExtension: AnyMessageExtension
public static func ==(lhs: RepeatedGroupExtensionField,
rhs: RepeatedGroupExtensionField) -> Bool {
return lhs.value == rhs.value
}
public init(protobufExtension: AnyMessageExtension, value: ValueType) {
self.protobufExtension = protobufExtension
self.value = value
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
hasher.combine(value)
}
#else // swift(>=4.2)
public var hashValue: Int {
get {
var hash = i_2166136261
for e in value {
hash = (hash &* i_16777619) ^ e.hashValue
}
return hash
}
}
#endif // swift(>=4.2)
public var debugDescription: String {
return "[" + value.map{$0.debugDescription}.joined(separator: ",") + "]"
}
public func isEqual(other: AnyExtensionField) -> Bool {
let o = other as! RepeatedGroupExtensionField<G>
return self == o
}
public mutating func decodeExtensionField<D: Decoder>(decoder: inout D) throws {
try decoder.decodeRepeatedGroupField(value: &value)
}
public init?<D: Decoder>(protobufExtension: AnyMessageExtension, decoder: inout D) throws {
var v: ValueType = []
try decoder.decodeRepeatedGroupField(value: &v)
self.init(protobufExtension: protobufExtension, value: v)
}
public func traverse<V: Visitor>(visitor: inout V) throws {
if value.count > 0 {
try visitor.visitRepeatedGroupField(
value: value, fieldNumber: protobufExtension.fieldNumber)
}
}
public var isInitialized: Bool {
return Internal.areAllInitialized(value)
}
}

View File

@ -0,0 +1,38 @@
// Sources/SwiftProtobuf/ExtensionMap.swift - Extension support
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// A set of extensions that can be passed into deserializers
/// to provide details of the particular extensions that should
/// be recognized.
///
// -----------------------------------------------------------------------------
/// A collection of extension objects.
///
/// An `ExtensionMap` is used during decoding to look up
/// extension objects corresponding to the serialized data.
///
/// This is a protocol so that developers can build their own
/// extension handling if they need something more complex than the
/// standard `SimpleExtensionMap` implementation.
public protocol ExtensionMap {
/// Returns the extension object describing an extension or nil
subscript(messageType: Message.Type, fieldNumber: Int) -> AnyMessageExtension? { get }
/// Returns the field number for a message with a specific field name
///
/// The field name here matches the format used by the protobuf
/// Text serialization: it typically looks like
/// `package.message.field_name`, where `package` is the package
/// for the proto file and `message` is the name of the message in
/// which the extension was defined. (This is different from the
/// message that is being extended!)
func fieldNumberForProto(messageType: Message.Type, protoFieldName: String) -> Int?
}

View File

@ -0,0 +1,69 @@
// Sources/SwiftProtobuf/FieldTag.swift - Describes a binary field tag
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Types related to binary encoded tags (field numbers and wire formats).
///
// -----------------------------------------------------------------------------
/// Encapsulates the number and wire format of a field, which together form the
/// "tag".
///
/// This type also validates tags in that it will never allow a tag with an
/// improper field number (such as zero) or wire format (such as 6 or 7) to
/// exist. In other words, a `FieldTag`'s properties never need to be tested
/// for validity because they are guaranteed correct at initialization time.
internal struct FieldTag: RawRepresentable {
typealias RawValue = UInt32
/// The raw numeric value of the tag, which contains both the field number and
/// wire format.
let rawValue: UInt32
/// The field number component of the tag.
var fieldNumber: Int {
return Int(rawValue >> 3)
}
/// The wire format component of the tag.
var wireFormat: WireFormat {
// This force-unwrap is safe because there are only two initialization
// paths: one that takes a WireFormat directly (and is guaranteed valid at
// compile-time), or one that takes a raw value but which only lets valid
// wire formats through.
return WireFormat(rawValue: UInt8(rawValue & 7))!
}
/// A helper property that returns the number of bytes required to
/// varint-encode this tag.
var encodedSize: Int {
return Varint.encodedSize(of: rawValue)
}
/// Creates a new tag from its raw numeric representation.
///
/// Note that if the raw value given here is not a valid tag (for example, it
/// has an invalid wire format), this initializer will fail.
init?(rawValue: UInt32) {
// Verify that the field number and wire format are valid and fail if they
// are not.
guard rawValue & ~0x07 != 0,
let _ = WireFormat(rawValue: UInt8(rawValue % 8)) else {
return nil
}
self.rawValue = rawValue
}
/// Creates a new tag by composing the given field number and wire format.
init(fieldNumber: Int, wireFormat: WireFormat) {
self.rawValue = UInt32(truncatingIfNeeded: fieldNumber) << 3 |
UInt32(wireFormat.rawValue)
}
}

View File

@ -0,0 +1,412 @@
// Sources/SwiftProtobuf/FieldTypes.swift - Proto data types
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Serialization/deserialization support for each proto field type.
///
/// Note that we cannot just extend the standard Int32, etc, types
/// with serialization information since proto language supports
/// distinct types (with different codings) that use the same
/// in-memory representation. For example, proto "sint32" and
/// "sfixed32" both are represented in-memory as Int32.
///
/// These types are used generically and also passed into
/// various coding/decoding functions to provide type-specific
/// information.
///
// -----------------------------------------------------------------------------
import Foundation
// Note: The protobuf- and JSON-specific methods here are defined
// in ProtobufTypeAdditions.swift and JSONTypeAdditions.swift
public protocol FieldType {
// The Swift type used to store data for this field. For example,
// proto "sint32" fields use Swift "Int32" type.
associatedtype BaseType: Hashable
// The default value for this field type before it has been set.
// This is also used, for example, when JSON decodes a "null"
// value for a field.
static var proto3DefaultValue: BaseType { get }
// Generic reflector methods for looking up the correct
// encoding/decoding for extension fields, map keys, and map
// values.
static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws
static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws
static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws
static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws
static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws
}
///
/// Marker protocol for types that can be used as map keys
///
public protocol MapKeyType: FieldType {
}
///
/// Marker Protocol for types that can be used as map values.
///
public protocol MapValueType: FieldType {
}
//
// We have a struct for every basic proto field type which provides
// serialization/deserialization support as static methods.
//
///
/// Float traits
///
public struct ProtobufFloat: FieldType, MapValueType {
public typealias BaseType = Float
public static var proto3DefaultValue: Float {return 0.0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularFloatField(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedFloatField(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularFloatField(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedFloatField(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedFloatField(value: value, fieldNumber: fieldNumber)
}
}
///
/// Double
///
public struct ProtobufDouble: FieldType, MapValueType {
public typealias BaseType = Double
public static var proto3DefaultValue: Double {return 0.0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularDoubleField(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedDoubleField(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularDoubleField(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedDoubleField(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedDoubleField(value: value, fieldNumber: fieldNumber)
}
}
///
/// Int32
///
public struct ProtobufInt32: FieldType, MapKeyType, MapValueType {
public typealias BaseType = Int32
public static var proto3DefaultValue: Int32 {return 0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularInt32Field(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedInt32Field(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedInt32Field(value: value, fieldNumber: fieldNumber)
}
}
///
/// Int64
///
public struct ProtobufInt64: FieldType, MapKeyType, MapValueType {
public typealias BaseType = Int64
public static var proto3DefaultValue: Int64 {return 0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularInt64Field(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedInt64Field(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedInt64Field(value: value, fieldNumber: fieldNumber)
}
}
///
/// UInt32
///
public struct ProtobufUInt32: FieldType, MapKeyType, MapValueType {
public typealias BaseType = UInt32
public static var proto3DefaultValue: UInt32 {return 0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularUInt32Field(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedUInt32Field(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularUInt32Field(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedUInt32Field(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedUInt32Field(value: value, fieldNumber: fieldNumber)
}
}
///
/// UInt64
///
public struct ProtobufUInt64: FieldType, MapKeyType, MapValueType {
public typealias BaseType = UInt64
public static var proto3DefaultValue: UInt64 {return 0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularUInt64Field(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedUInt64Field(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularUInt64Field(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedUInt64Field(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedUInt64Field(value: value, fieldNumber: fieldNumber)
}
}
///
/// SInt32
///
public struct ProtobufSInt32: FieldType, MapKeyType, MapValueType {
public typealias BaseType = Int32
public static var proto3DefaultValue: Int32 {return 0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularSInt32Field(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedSInt32Field(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularSInt32Field(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedSInt32Field(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedSInt32Field(value: value, fieldNumber: fieldNumber)
}
}
///
/// SInt64
///
public struct ProtobufSInt64: FieldType, MapKeyType, MapValueType {
public typealias BaseType = Int64
public static var proto3DefaultValue: Int64 {return 0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularSInt64Field(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedSInt64Field(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularSInt64Field(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedSInt64Field(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedSInt64Field(value: value, fieldNumber: fieldNumber)
}
}
///
/// Fixed32
///
public struct ProtobufFixed32: FieldType, MapKeyType, MapValueType {
public typealias BaseType = UInt32
public static var proto3DefaultValue: UInt32 {return 0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularFixed32Field(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedFixed32Field(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularFixed32Field(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedFixed32Field(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedFixed32Field(value: value, fieldNumber: fieldNumber)
}
}
///
/// Fixed64
///
public struct ProtobufFixed64: FieldType, MapKeyType, MapValueType {
public typealias BaseType = UInt64
public static var proto3DefaultValue: UInt64 {return 0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularFixed64Field(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedFixed64Field(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularFixed64Field(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedFixed64Field(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedFixed64Field(value: value, fieldNumber: fieldNumber)
}
}
///
/// SFixed32
///
public struct ProtobufSFixed32: FieldType, MapKeyType, MapValueType {
public typealias BaseType = Int32
public static var proto3DefaultValue: Int32 {return 0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularSFixed32Field(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedSFixed32Field(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularSFixed32Field(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedSFixed32Field(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedSFixed32Field(value: value, fieldNumber: fieldNumber)
}
}
///
/// SFixed64
///
public struct ProtobufSFixed64: FieldType, MapKeyType, MapValueType {
public typealias BaseType = Int64
public static var proto3DefaultValue: Int64 {return 0}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularSFixed64Field(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedSFixed64Field(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularSFixed64Field(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedSFixed64Field(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedSFixed64Field(value: value, fieldNumber: fieldNumber)
}
}
///
/// Bool
///
public struct ProtobufBool: FieldType, MapKeyType, MapValueType {
public typealias BaseType = Bool
public static var proto3DefaultValue: Bool {return false}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularBoolField(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedBoolField(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularBoolField(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedBoolField(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitPackedBoolField(value: value, fieldNumber: fieldNumber)
}
}
///
/// String
///
public struct ProtobufString: FieldType, MapKeyType, MapValueType {
public typealias BaseType = String
public static var proto3DefaultValue: String {return String()}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularStringField(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedStringField(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularStringField(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedStringField(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
assert(false)
}
}
///
/// Bytes
///
public struct ProtobufBytes: FieldType, MapValueType {
public typealias BaseType = Data
public static var proto3DefaultValue: Data {return Data()}
public static func decodeSingular<D: Decoder>(value: inout BaseType?, from decoder: inout D) throws {
try decoder.decodeSingularBytesField(value: &value)
}
public static func decodeRepeated<D: Decoder>(value: inout [BaseType], from decoder: inout D) throws {
try decoder.decodeRepeatedBytesField(value: &value)
}
public static func visitSingular<V: Visitor>(value: BaseType, fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitSingularBytesField(value: value, fieldNumber: fieldNumber)
}
public static func visitRepeated<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
try visitor.visitRepeatedBytesField(value: value, fieldNumber: fieldNumber)
}
public static func visitPacked<V: Visitor>(value: [BaseType], fieldNumber: Int, with visitor: inout V) throws {
assert(false)
}
}

View File

@ -0,0 +1,143 @@
// Sources/SwiftProtobuf/Google_Protobuf_Any+Extensions.swift - Well-known Any type
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extends the `Google_Protobuf_Any` type with various custom behaviors.
///
// -----------------------------------------------------------------------------
// Explicit import of Foundation is necessary on Linux,
// don't remove unless obsolete on all platforms
import Foundation
public let defaultAnyTypeURLPrefix: String = "type.googleapis.com"
extension Google_Protobuf_Any {
/// Initialize an Any object from the provided message.
///
/// This corresponds to the `pack` operation in the C++ API.
///
/// Unlike the C++ implementation, the message is not immediately
/// serialized; it is merely stored until the Any object itself
/// needs to be serialized. This design avoids unnecessary
/// decoding/recoding when writing JSON format.
///
/// - Parameters:
/// - partial: If `false` (the default), this method will check
/// `Message.isInitialized` before encoding to verify that all required
/// fields are present. If any are missing, this method throws
/// `BinaryEncodingError.missingRequiredFields`.
/// - typePrefix: The prefix to be used when building the `type_url`.
/// Defaults to "type.googleapis.com".
/// - Throws: `BinaryEncodingError.missingRequiredFields` if `partial` is
/// false and `message` wasn't fully initialized.
public init(
message: Message,
partial: Bool = false,
typePrefix: String = defaultAnyTypeURLPrefix
) throws {
if !partial && !message.isInitialized {
throw BinaryEncodingError.missingRequiredFields
}
self.init()
typeURL = buildTypeURL(forMessage:message, typePrefix: typePrefix)
_storage.state = .message(message)
}
/// Creates a new `Google_Protobuf_Any` by decoding the given string
/// containing a serialized message in Protocol Buffer text format.
///
/// - Parameters:
/// - textFormatString: The text format string to decode.
/// - extensions: An `ExtensionMap` used to look up and decode any
/// extensions in this message or messages nested within this message's
/// fields.
/// - Throws: an instance of `TextFormatDecodingError` on failure.
public init(
textFormatString: String,
extensions: ExtensionMap? = nil
) throws {
self.init()
if !textFormatString.isEmpty {
if let data = textFormatString.data(using: String.Encoding.utf8) {
try data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
if let baseAddress = body.baseAddress, body.count > 0 {
var textDecoder = try TextFormatDecoder(
messageType: Google_Protobuf_Any.self,
utf8Pointer: baseAddress,
count: body.count,
extensions: extensions)
try decodeTextFormat(decoder: &textDecoder)
if !textDecoder.complete {
throw TextFormatDecodingError.trailingGarbage
}
}
}
}
}
}
/// Returns true if this `Google_Protobuf_Any` message contains the given
/// message type.
///
/// The check is performed by looking at the passed `Message.Type` and the
/// `typeURL` of this message.
///
/// - Parameter type: The concrete message type.
/// - Returns: True if the receiver contains the given message type.
public func isA<M: Message>(_ type: M.Type) -> Bool {
return _storage.isA(type)
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
_storage.hash(into: &hasher)
}
#else // swift(>=4.2)
public var hashValue: Int {
return _storage.hashValue
}
#endif // swift(>=4.2)
}
extension Google_Protobuf_Any {
internal func textTraverse(visitor: inout TextFormatEncodingVisitor) {
_storage.textTraverse(visitor: &visitor)
try! unknownFields.traverse(visitor: &visitor)
}
}
extension Google_Protobuf_Any: _CustomJSONCodable {
// Custom text format decoding support for Any objects.
// (Note: This is not a part of any protocol; it's invoked
// directly from TextFormatDecoder whenever it sees an attempt
// to decode an Any object)
internal mutating func decodeTextFormat(
decoder: inout TextFormatDecoder
) throws {
// First, check if this uses the "verbose" Any encoding.
// If it does, and we have the type available, we can
// eagerly decode the contained Message object.
if let url = try decoder.scanner.nextOptionalAnyURL() {
try _uniqueStorage().decodeTextFormat(typeURL: url, decoder: &decoder)
} else {
// This is not using the specialized encoding, so we can use the
// standard path to decode the binary value.
try decodeMessage(decoder: &decoder)
}
}
internal func encodedJSONString(options: JSONEncodingOptions) throws -> String {
return try _storage.encodedJSONString(options: options)
}
internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
try _uniqueStorage().decodeJSON(from: &decoder)
}
}

View File

@ -0,0 +1,135 @@
// Sources/SwiftProtobuf/Google_Protobuf_Any+Registry.swift - Registry for JSON support
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Support for registering and looking up Message types. Used
/// in support of Google_Protobuf_Any.
///
// -----------------------------------------------------------------------------
import Foundation
import Dispatch
// TODO: Should these first four be exposed as methods to go with
// the general registry support?
internal func buildTypeURL(forMessage message: Message, typePrefix: String) -> String {
var url = typePrefix
let needsSlash = typePrefix.isEmpty || typePrefix.last != "/"
if needsSlash {
url += "/"
}
return url + typeName(fromMessage: message)
}
internal func typeName(fromMessage message: Message) -> String {
let messageType = type(of: message)
return messageType.protoMessageName
}
internal func typeName(fromURL s: String) -> String {
var typeStart = s.startIndex
var i = typeStart
while i < s.endIndex {
let c = s[i]
i = s.index(after: i)
if c == "/" {
typeStart = i
}
}
return String(s[typeStart..<s.endIndex])
}
fileprivate var serialQueue = DispatchQueue(label: "org.swift.protobuf.typeRegistry")
// All access to this should be done on `serialQueue`.
fileprivate var knownTypes: [String:Message.Type] = [
// Seeded with the Well Known Types.
"google.protobuf.Any": Google_Protobuf_Any.self,
"google.protobuf.BoolValue": Google_Protobuf_BoolValue.self,
"google.protobuf.BytesValue": Google_Protobuf_BytesValue.self,
"google.protobuf.DoubleValue": Google_Protobuf_DoubleValue.self,
"google.protobuf.Duration": Google_Protobuf_Duration.self,
"google.protobuf.Empty": Google_Protobuf_Empty.self,
"google.protobuf.FieldMask": Google_Protobuf_FieldMask.self,
"google.protobuf.FloatValue": Google_Protobuf_FloatValue.self,
"google.protobuf.Int32Value": Google_Protobuf_Int32Value.self,
"google.protobuf.Int64Value": Google_Protobuf_Int64Value.self,
"google.protobuf.ListValue": Google_Protobuf_ListValue.self,
"google.protobuf.StringValue": Google_Protobuf_StringValue.self,
"google.protobuf.Struct": Google_Protobuf_Struct.self,
"google.protobuf.Timestamp": Google_Protobuf_Timestamp.self,
"google.protobuf.UInt32Value": Google_Protobuf_UInt32Value.self,
"google.protobuf.UInt64Value": Google_Protobuf_UInt64Value.self,
"google.protobuf.Value": Google_Protobuf_Value.self,
]
extension Google_Protobuf_Any {
/// Register a message type so that Any objects can use
/// them for decoding contents.
///
/// This is currently only required in two cases:
///
/// * When decoding Protobuf Text format. Currently,
/// Any objects do not defer deserialization from Text
/// format. Depending on how the Any objects are stored
/// in text format, the Any object may need to look up
/// the message type in order to deserialize itself.
///
/// * When re-encoding an Any object into a different
/// format than it was decoded from. For example, if
/// you decode a message containing an Any object from
/// JSON format and then re-encode the message into Protobuf
/// Binary format, the Any object will need to complete the
/// deferred deserialization of the JSON object before it
/// can re-encode.
///
/// Note that well-known types are pre-registered for you and
/// you do not need to register them from your code.
///
/// Also note that this is not needed if you only decode and encode
/// to and from the same format.
///
/// Returns: true if the type was registered, false if something
/// else was already registered for the messageName.
@discardableResult public static func register(messageType: Message.Type) -> Bool {
let messageTypeName = messageType.protoMessageName
var result: Bool = false
serialQueue.sync {
if let alreadyRegistered = knownTypes[messageTypeName] {
// Success/failure when something was already registered is
// based on if they are registering the same class or trying
// to register a different type
result = alreadyRegistered == messageType
} else {
knownTypes[messageTypeName] = messageType
result = true
}
}
return result
}
/// Returns the Message.Type expected for the given type URL.
public static func messageType(forTypeURL url: String) -> Message.Type? {
let messageTypeName = typeName(fromURL: url)
return messageType(forMessageName: messageTypeName)
}
/// Returns the Message.Type expected for the given proto message name.
public static func messageType(forMessageName name: String) -> Message.Type? {
var result: Message.Type?
serialQueue.sync {
result = knownTypes[name]
}
return result
}
}

View File

@ -0,0 +1,234 @@
// Sources/SwiftProtobuf/Google_Protobuf_Duration+Extensions.swift - Extensions for Duration type
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extends the generated Duration struct with various custom behaviors:
/// * JSON coding and decoding
/// * Arithmetic operations
///
// -----------------------------------------------------------------------------
import Foundation
private let minDurationSeconds: Int64 = -maxDurationSeconds
private let maxDurationSeconds: Int64 = 315576000000
private func parseDuration(text: String) throws -> (Int64, Int32) {
var digits = [Character]()
var digitCount = 0
var total = 0
var chars = text.makeIterator()
var seconds: Int64?
var nanos: Int32 = 0
while let c = chars.next() {
switch c {
case "-":
// Only accept '-' as very first character
if total > 0 {
throw JSONDecodingError.malformedDuration
}
digits.append(c)
case "0", "1", "2", "3", "4", "5", "6", "7", "8", "9":
digits.append(c)
digitCount += 1
case ".":
if let _ = seconds {
throw JSONDecodingError.malformedDuration
}
let digitString = String(digits)
if let s = Int64(digitString),
s >= minDurationSeconds && s <= maxDurationSeconds {
seconds = s
} else {
throw JSONDecodingError.malformedDuration
}
digits.removeAll()
digitCount = 0
case "s":
if let seconds = seconds {
// Seconds already set, digits holds nanos
while (digitCount < 9) {
digits.append(Character("0"))
digitCount += 1
}
while digitCount > 9 {
digits.removeLast()
digitCount -= 1
}
let digitString = String(digits)
if let rawNanos = Int32(digitString) {
if seconds < 0 {
nanos = -rawNanos
} else {
nanos = rawNanos
}
} else {
throw JSONDecodingError.malformedDuration
}
} else {
// No fraction, we just have an integral number of seconds
let digitString = String(digits)
if let s = Int64(digitString),
s >= minDurationSeconds && s <= maxDurationSeconds {
seconds = s
} else {
throw JSONDecodingError.malformedDuration
}
}
// Fail if there are characters after 's'
if chars.next() != nil {
throw JSONDecodingError.malformedDuration
}
return (seconds!, nanos)
default:
throw JSONDecodingError.malformedDuration
}
total += 1
}
throw JSONDecodingError.malformedDuration
}
private func formatDuration(seconds: Int64, nanos: Int32) -> String? {
let (seconds, nanos) = normalizeForDuration(seconds: seconds, nanos: nanos)
guard seconds >= minDurationSeconds && seconds <= maxDurationSeconds else {
return nil
}
if nanos == 0 {
return String(format: "%llds", seconds)
} else if nanos % 1000000 == 0 {
return String(format: "%lld.%03ds", seconds, abs(nanos) / 1000000)
} else if nanos % 1000 == 0 {
return String(format: "%lld.%06ds", seconds, abs(nanos) / 1000)
} else {
return String(format: "%lld.%09ds", seconds, abs(nanos))
}
}
extension Google_Protobuf_Duration {
/// Creates a new `Google_Protobuf_Duration` equal to the given number of
/// seconds and nanoseconds.
///
/// - Parameter seconds: The number of seconds.
/// - Parameter nanos: The number of nanoseconds.
public init(seconds: Int64 = 0, nanos: Int32 = 0) {
self.init()
self.seconds = seconds
self.nanos = nanos
}
}
extension Google_Protobuf_Duration: _CustomJSONCodable {
mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
let s = try decoder.scanner.nextQuotedString()
(seconds, nanos) = try parseDuration(text: s)
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
if let formatted = formatDuration(seconds: seconds, nanos: nanos) {
return "\"\(formatted)\""
} else {
throw JSONEncodingError.durationRange
}
}
}
extension Google_Protobuf_Duration: ExpressibleByFloatLiteral {
public typealias FloatLiteralType = Double
/// Creates a new `Google_Protobuf_Duration` from a floating point literal
/// that is interpreted as a duration in seconds, rounded to the nearest
/// nanosecond.
public init(floatLiteral value: Double) {
let sd = trunc(value)
let nd = round((value - sd) * TimeInterval(nanosPerSecond))
let (s, n) = normalizeForDuration(seconds: Int64(sd), nanos: Int32(nd))
self.init(seconds: s, nanos: n)
}
}
extension Google_Protobuf_Duration {
/// Creates a new `Google_Protobuf_Duration` that is equal to the given
/// `TimeInterval` (measured in seconds), rounded to the nearest nanosecond.
///
/// - Parameter timeInterval: The `TimeInterval`.
public init(timeInterval: TimeInterval) {
let sd = trunc(timeInterval)
let nd = round((timeInterval - sd) * TimeInterval(nanosPerSecond))
let (s, n) = normalizeForDuration(seconds: Int64(sd), nanos: Int32(nd))
self.init(seconds: s, nanos: n)
}
/// The `TimeInterval` (measured in seconds) equal to this duration.
public var timeInterval: TimeInterval {
return TimeInterval(self.seconds) +
TimeInterval(self.nanos) / TimeInterval(nanosPerSecond)
}
}
private func normalizeForDuration(
seconds: Int64,
nanos: Int32
) -> (seconds: Int64, nanos: Int32) {
var s = seconds
var n = nanos
// If the magnitude of n exceeds a second then
// we need to factor it into s instead.
if n >= nanosPerSecond || n <= -nanosPerSecond {
s += Int64(n / nanosPerSecond)
n = n % nanosPerSecond
}
// The Duration spec says that when s != 0, s and
// n must have the same sign.
if s > 0 && n < 0 {
n += nanosPerSecond
s -= 1
} else if s < 0 && n > 0 {
n -= nanosPerSecond
s += 1
}
return (seconds: s, nanos: n)
}
public prefix func - (
operand: Google_Protobuf_Duration
) -> Google_Protobuf_Duration {
let (s, n) = normalizeForDuration(seconds: -operand.seconds,
nanos: -operand.nanos)
return Google_Protobuf_Duration(seconds: s, nanos: n)
}
public func + (
lhs: Google_Protobuf_Duration,
rhs: Google_Protobuf_Duration
) -> Google_Protobuf_Duration {
let (s, n) = normalizeForDuration(seconds: lhs.seconds + rhs.seconds,
nanos: lhs.nanos + rhs.nanos)
return Google_Protobuf_Duration(seconds: s, nanos: n)
}
public func - (
lhs: Google_Protobuf_Duration,
rhs: Google_Protobuf_Duration
) -> Google_Protobuf_Duration {
let (s, n) = normalizeForDuration(seconds: lhs.seconds - rhs.seconds,
nanos: lhs.nanos - rhs.nanos)
return Google_Protobuf_Duration(seconds: s, nanos: n)
}
public func - (
lhs: Google_Protobuf_Timestamp,
rhs: Google_Protobuf_Timestamp
) -> Google_Protobuf_Duration {
let (s, n) = normalizeForDuration(seconds: lhs.seconds - rhs.seconds,
nanos: lhs.nanos - rhs.nanos)
return Google_Protobuf_Duration(seconds: s, nanos: n)
}

View File

@ -0,0 +1,163 @@
// Sources/SwiftProtobuf/Google_Protobuf_FieldMask+Extensions.swift - Fieldmask extensions
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extend the generated FieldMask message with customized JSON coding and
/// convenience methods.
///
// -----------------------------------------------------------------------------
// TODO: We should have utilities to apply a fieldmask to an arbitrary
// message, intersect two fieldmasks, etc.
private func ProtoToJSON(name: String) -> String? {
var jsonPath = String()
var chars = name.makeIterator()
while let c = chars.next() {
switch c {
case "_":
if let toupper = chars.next() {
switch toupper {
case "a"..."z":
jsonPath.append(String(toupper).uppercased())
default:
return nil
}
} else {
return nil
}
case "A"..."Z":
return nil
default:
jsonPath.append(c)
}
}
return jsonPath
}
private func JSONToProto(name: String) -> String? {
var path = String()
for c in name {
switch c {
case "_":
return nil
case "A"..."Z":
path.append(Character("_"))
path.append(String(c).lowercased())
default:
path.append(c)
}
}
return path
}
private func parseJSONFieldNames(names: String) -> [String]? {
// An empty field mask is the empty string (no paths).
guard !names.isEmpty else { return [] }
var fieldNameCount = 0
var fieldName = String()
var split = [String]()
for c in names {
switch c {
case ",":
if fieldNameCount == 0 {
return nil
}
if let pbName = JSONToProto(name: fieldName) {
split.append(pbName)
} else {
return nil
}
fieldName = String()
fieldNameCount = 0
default:
fieldName.append(c)
fieldNameCount += 1
}
}
if fieldNameCount == 0 { // Last field name can't be empty
return nil
}
if let pbName = JSONToProto(name: fieldName) {
split.append(pbName)
} else {
return nil
}
return split
}
extension Google_Protobuf_FieldMask {
/// Creates a new `Google_Protobuf_FieldMask` from the given array of paths.
///
/// The paths should match the names used in the .proto file, which may be
/// different than the corresponding Swift property names.
///
/// - Parameter protoPaths: The paths from which to create the field mask,
/// defined using the .proto names for the fields.
public init(protoPaths: [String]) {
self.init()
paths = protoPaths
}
/// Creates a new `Google_Protobuf_FieldMask` from the given paths.
///
/// The paths should match the names used in the .proto file, which may be
/// different than the corresponding Swift property names.
///
/// - Parameter protoPaths: The paths from which to create the field mask,
/// defined using the .proto names for the fields.
public init(protoPaths: String...) {
self.init(protoPaths: protoPaths)
}
/// Creates a new `Google_Protobuf_FieldMask` from the given paths.
///
/// The paths should match the JSON names of the fields, which may be
/// different than the corresponding Swift property names.
///
/// - Parameter jsonPaths: The paths from which to create the field mask,
/// defined using the JSON names for the fields.
public init?(jsonPaths: String...) {
// TODO: This should fail if any of the conversions from JSON fails
#if swift(>=4.1)
self.init(protoPaths: jsonPaths.compactMap(JSONToProto))
#else
self.init(protoPaths: jsonPaths.flatMap(JSONToProto))
#endif
}
// It would be nice if to have an initializer that accepted Swift property
// names, but translating between swift and protobuf/json property
// names is not entirely deterministic.
}
extension Google_Protobuf_FieldMask: _CustomJSONCodable {
mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
let s = try decoder.scanner.nextQuotedString()
if let names = parseJSONFieldNames(names: s) {
paths = names
} else {
throw JSONDecodingError.malformedFieldMask
}
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
// Note: Proto requires alphanumeric field names, so there
// cannot be a ',' or '"' character to mess up this formatting.
var jsonPaths = [String]()
for p in paths {
if let jsonPath = ProtoToJSON(name: p) {
jsonPaths.append(jsonPath)
} else {
throw JSONEncodingError.fieldMaskConversion
}
}
return "\"" + jsonPaths.joined(separator: ",") + "\""
}
}

View File

@ -0,0 +1,80 @@
// Sources/SwiftProtobuf/Google_Protobuf_ListValue+Extensions.swift - ListValue extensions
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// ListValue is a well-known message type that can be used to parse or encode
/// arbitrary JSON arrays without a predefined schema.
///
// -----------------------------------------------------------------------------
extension Google_Protobuf_ListValue: ExpressibleByArrayLiteral {
// TODO: Give this a direct array interface by proxying the interesting
// bits down to values
public typealias Element = Google_Protobuf_Value
/// Creates a new `Google_Protobuf_ListValue` from an array literal containing
/// `Google_Protobuf_Value` elements.
public init(arrayLiteral elements: Element...) {
self.init(values: elements)
}
}
extension Google_Protobuf_ListValue: _CustomJSONCodable {
internal func encodedJSONString(options: JSONEncodingOptions) throws -> String {
var jsonEncoder = JSONEncoder()
jsonEncoder.append(text: "[")
var separator: StaticString = ""
for v in values {
jsonEncoder.append(staticText: separator)
try v.serializeJSONValue(to: &jsonEncoder, options: options)
separator = ","
}
jsonEncoder.append(text: "]")
return jsonEncoder.stringResult
}
internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
if decoder.scanner.skipOptionalNull() {
return
}
try decoder.scanner.skipRequiredArrayStart()
if decoder.scanner.skipOptionalArrayEnd() {
return
}
while true {
var v = Google_Protobuf_Value()
try v.decodeJSON(from: &decoder)
values.append(v)
if decoder.scanner.skipOptionalArrayEnd() {
return
}
try decoder.scanner.skipRequiredComma()
}
}
}
extension Google_Protobuf_ListValue {
/// Creates a new `Google_Protobuf_ListValue` from the given array of
/// `Google_Protobuf_Value` elements.
///
/// - Parameter values: The list of `Google_Protobuf_Value` messages from
/// which to create the `Google_Protobuf_ListValue`.
public init(values: [Google_Protobuf_Value]) {
self.init()
self.values = values
}
/// Accesses the `Google_Protobuf_Value` at the specified position.
///
/// - Parameter index: The position of the element to access.
public subscript(index: Int) -> Google_Protobuf_Value {
get {return values[index]}
set(newValue) {values[index] = newValue}
}
}

View File

@ -0,0 +1,28 @@
// Sources/SwiftProtobuf/Google_Protobuf_NullValue+Extensions.swift - NullValue extensions
//
// Copyright (c) 2014 - 2020 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// NullValue is a well-known message type that can be used to parse or encode
/// JSON Null values.
///
// -----------------------------------------------------------------------------
extension Google_Protobuf_NullValue: _CustomJSONCodable {
internal func encodedJSONString(options: JSONEncodingOptions) throws -> String {
return "null"
}
internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
if decoder.scanner.skipOptionalNull() {
return
}
}
static func decodedFromJSONNull() -> Google_Protobuf_NullValue? {
return .nullValue
}
}

View File

@ -0,0 +1,85 @@
// Sources/SwiftProtobuf/Google_Protobuf_Struct+Extensions.swift - Struct extensions
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Struct is a well-known message type that can be used to parse or encode
/// arbitrary JSON objects without a predefined schema.
///
// -----------------------------------------------------------------------------
extension Google_Protobuf_Struct: ExpressibleByDictionaryLiteral {
public typealias Key = String
public typealias Value = Google_Protobuf_Value
/// Creates a new `Google_Protobuf_Struct` from a dictionary of string keys to
/// values of type `Google_Protobuf_Value`.
public init(dictionaryLiteral: (String, Google_Protobuf_Value)...) {
self.init()
for (k,v) in dictionaryLiteral {
fields[k] = v
}
}
}
extension Google_Protobuf_Struct: _CustomJSONCodable {
internal func encodedJSONString(options: JSONEncodingOptions) throws -> String {
var jsonEncoder = JSONEncoder()
jsonEncoder.startObject()
var mapVisitor = JSONMapEncodingVisitor(encoder: jsonEncoder, options: options)
for (k,v) in fields {
try mapVisitor.visitSingularStringField(value: k, fieldNumber: 1)
try mapVisitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
mapVisitor.encoder.endObject()
return mapVisitor.encoder.stringResult
}
internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
try decoder.scanner.skipRequiredObjectStart()
if decoder.scanner.skipOptionalObjectEnd() {
return
}
while true {
let key = try decoder.scanner.nextQuotedString()
try decoder.scanner.skipRequiredColon()
var value = Google_Protobuf_Value()
try value.decodeJSON(from: &decoder)
fields[key] = value
if decoder.scanner.skipOptionalObjectEnd() {
return
}
try decoder.scanner.skipRequiredComma()
}
}
}
extension Google_Protobuf_Struct {
/// Creates a new `Google_Protobuf_Struct` from a dictionary of string keys to
/// values of type `Google_Protobuf_Value`.
///
/// - Parameter fields: The dictionary from field names to
/// `Google_Protobuf_Value` messages that should be used to create the
/// `Struct`.
public init(fields: [String: Google_Protobuf_Value]) {
self.init()
self.fields = fields
}
/// Accesses the `Google_Protobuf_Value` with the given key for reading and
/// writing.
///
/// This key-based subscript returns the `Value` for the given key if the key
/// is found in the `Struct`, or nil if the key is not found. If you assign
/// nil as the `Value` for the given key, the `Struct` removes that key and
/// its associated `Value`.
public subscript(key: String) -> Google_Protobuf_Value? {
get {return fields[key]}
set(newValue) {fields[key] = newValue}
}
}

View File

@ -0,0 +1,337 @@
// Sources/SwiftProtobuf/Google_Protobuf_Timestamp+Extensions.swift - Timestamp extensions
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extend the generated Timestamp message with customized JSON coding,
/// arithmetic operations, and convenience methods.
///
// -----------------------------------------------------------------------------
import Foundation
private let minTimestampSeconds: Int64 = -62135596800 // 0001-01-01T00:00:00Z
private let maxTimestampSeconds: Int64 = 253402300799 // 9999-12-31T23:59:59Z
// TODO: Add convenience methods to interoperate with standard
// date/time classes: an initializer that accepts Unix timestamp as
// Int or Double, an easy way to convert to/from Foundation's
// NSDateTime (on Apple platforms only?), others?
// Parse an RFC3339 timestamp into a pair of seconds-since-1970 and nanos.
private func parseTimestamp(s: String) throws -> (Int64, Int32) {
// Convert to an array of integer character values
let value = s.utf8.map{Int($0)}
if value.count < 20 {
throw JSONDecodingError.malformedTimestamp
}
// Since the format is fixed-layout, we can just decode
// directly as follows.
let zero = Int(48)
let nine = Int(57)
let dash = Int(45)
let colon = Int(58)
let plus = Int(43)
let letterT = Int(84)
let letterZ = Int(90)
let period = Int(46)
func fromAscii2(_ digit0: Int, _ digit1: Int) throws -> Int {
if digit0 < zero || digit0 > nine || digit1 < zero || digit1 > nine {
throw JSONDecodingError.malformedTimestamp
}
return digit0 * 10 + digit1 - 528
}
func fromAscii4(
_ digit0: Int,
_ digit1: Int,
_ digit2: Int,
_ digit3: Int
) throws -> Int {
if (digit0 < zero || digit0 > nine
|| digit1 < zero || digit1 > nine
|| digit2 < zero || digit2 > nine
|| digit3 < zero || digit3 > nine) {
throw JSONDecodingError.malformedTimestamp
}
return digit0 * 1000 + digit1 * 100 + digit2 * 10 + digit3 - 53328
}
// Year: 4 digits followed by '-'
let year = try fromAscii4(value[0], value[1], value[2], value[3])
if value[4] != dash || year < Int(1) || year > Int(9999) {
throw JSONDecodingError.malformedTimestamp
}
// Month: 2 digits followed by '-'
let month = try fromAscii2(value[5], value[6])
if value[7] != dash || month < Int(1) || month > Int(12) {
throw JSONDecodingError.malformedTimestamp
}
// Day: 2 digits followed by 'T'
let mday = try fromAscii2(value[8], value[9])
if value[10] != letterT || mday < Int(1) || mday > Int(31) {
throw JSONDecodingError.malformedTimestamp
}
// Hour: 2 digits followed by ':'
let hour = try fromAscii2(value[11], value[12])
if value[13] != colon || hour > Int(23) {
throw JSONDecodingError.malformedTimestamp
}
// Minute: 2 digits followed by ':'
let minute = try fromAscii2(value[14], value[15])
if value[16] != colon || minute > Int(59) {
throw JSONDecodingError.malformedTimestamp
}
// Second: 2 digits (following char is checked below)
let second = try fromAscii2(value[17], value[18])
if second > Int(61) {
throw JSONDecodingError.malformedTimestamp
}
// timegm() is almost entirely useless. It's nonexistent on
// some platforms, broken on others. Everything else I've tried
// is even worse. Hence the code below.
// (If you have a better way to do this, try it and see if it
// passes the test suite on both Linux and OS X.)
// Day of year
let mdayStart: [Int] = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]
var yday = Int64(mdayStart[month - 1])
let isleap = (year % 400 == 0) || ((year % 100 != 0) && (year % 4 == 0))
if isleap && (month > 2) {
yday += 1
}
yday += Int64(mday - 1)
// Days since start of epoch (including leap days)
var daysSinceEpoch = yday
daysSinceEpoch += Int64(365 * year) - Int64(719527)
daysSinceEpoch += Int64((year - 1) / 4)
daysSinceEpoch -= Int64((year - 1) / 100)
daysSinceEpoch += Int64((year - 1) / 400)
// Second within day
var daySec = Int64(hour)
daySec *= 60
daySec += Int64(minute)
daySec *= 60
daySec += Int64(second)
// Seconds since start of epoch
let t = daysSinceEpoch * Int64(86400) + daySec
// After seconds, comes various optional bits
var pos = 19
var nanos: Int32 = 0
if value[pos] == period { // "." begins fractional seconds
pos += 1
var digitValue = 100000000
while pos < value.count && value[pos] >= zero && value[pos] <= nine {
nanos += Int32(digitValue * (value[pos] - zero))
digitValue /= 10
pos += 1
}
}
var seconds: Int64 = 0
// "+" or "-" starts Timezone offset
if value[pos] == plus || value[pos] == dash {
if pos + 6 > value.count {
throw JSONDecodingError.malformedTimestamp
}
let hourOffset = try fromAscii2(value[pos + 1], value[pos + 2])
let minuteOffset = try fromAscii2(value[pos + 4], value[pos + 5])
if hourOffset > Int(13) || minuteOffset > Int(59) || value[pos + 3] != colon {
throw JSONDecodingError.malformedTimestamp
}
var adjusted: Int64 = t
if value[pos] == plus {
adjusted -= Int64(hourOffset) * Int64(3600)
adjusted -= Int64(minuteOffset) * Int64(60)
} else {
adjusted += Int64(hourOffset) * Int64(3600)
adjusted += Int64(minuteOffset) * Int64(60)
}
if adjusted < minTimestampSeconds || adjusted > maxTimestampSeconds {
throw JSONDecodingError.malformedTimestamp
}
seconds = adjusted
pos += 6
} else if value[pos] == letterZ { // "Z" indicator for UTC
seconds = t
pos += 1
} else {
throw JSONDecodingError.malformedTimestamp
}
if pos != value.count {
throw JSONDecodingError.malformedTimestamp
}
return (seconds, nanos)
}
private func formatTimestamp(seconds: Int64, nanos: Int32) -> String? {
let (seconds, nanos) = normalizeForTimestamp(seconds: seconds, nanos: nanos)
guard seconds >= minTimestampSeconds && seconds <= maxTimestampSeconds else {
return nil
}
let (hh, mm, ss) = timeOfDayFromSecondsSince1970(seconds: seconds)
let (YY, MM, DD) = gregorianDateFromSecondsSince1970(seconds: seconds)
if nanos == 0 {
return String(format: "%04d-%02d-%02dT%02d:%02d:%02dZ",
YY, MM, DD, hh, mm, ss)
} else if nanos % 1000000 == 0 {
return String(format: "%04d-%02d-%02dT%02d:%02d:%02d.%03dZ",
YY, MM, DD, hh, mm, ss, nanos / 1000000)
} else if nanos % 1000 == 0 {
return String(format: "%04d-%02d-%02dT%02d:%02d:%02d.%06dZ",
YY, MM, DD, hh, mm, ss, nanos / 1000)
} else {
return String(format: "%04d-%02d-%02dT%02d:%02d:%02d.%09dZ",
YY, MM, DD, hh, mm, ss, nanos)
}
}
extension Google_Protobuf_Timestamp {
/// Creates a new `Google_Protobuf_Timestamp` equal to the given number of
/// seconds and nanoseconds.
///
/// - Parameter seconds: The number of seconds.
/// - Parameter nanos: The number of nanoseconds.
public init(seconds: Int64 = 0, nanos: Int32 = 0) {
self.init()
self.seconds = seconds
self.nanos = nanos
}
}
extension Google_Protobuf_Timestamp: _CustomJSONCodable {
mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
let s = try decoder.scanner.nextQuotedString()
(seconds, nanos) = try parseTimestamp(s: s)
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
if let formatted = formatTimestamp(seconds: seconds, nanos: nanos) {
return "\"\(formatted)\""
} else {
throw JSONEncodingError.timestampRange
}
}
}
extension Google_Protobuf_Timestamp {
/// Creates a new `Google_Protobuf_Timestamp` initialized relative to 00:00:00
/// UTC on 1 January 1970 by a given number of seconds.
///
/// - Parameter timeIntervalSince1970: The `TimeInterval`, interpreted as
/// seconds relative to 00:00:00 UTC on 1 January 1970.
public init(timeIntervalSince1970: TimeInterval) {
let sd = floor(timeIntervalSince1970)
let nd = round((timeIntervalSince1970 - sd) * TimeInterval(nanosPerSecond))
let (s, n) = normalizeForTimestamp(seconds: Int64(sd), nanos: Int32(nd))
self.init(seconds: s, nanos: n)
}
/// Creates a new `Google_Protobuf_Timestamp` initialized relative to 00:00:00
/// UTC on 1 January 2001 by a given number of seconds.
///
/// - Parameter timeIntervalSinceReferenceDate: The `TimeInterval`,
/// interpreted as seconds relative to 00:00:00 UTC on 1 January 2001.
public init(timeIntervalSinceReferenceDate: TimeInterval) {
let sd = floor(timeIntervalSinceReferenceDate)
let nd = round(
(timeIntervalSinceReferenceDate - sd) * TimeInterval(nanosPerSecond))
// The addition of timeIntervalBetween1970And... is deliberately delayed
// until the input is separated into an integer part and a fraction
// part, so that we don't unnecessarily lose precision.
let (s, n) = normalizeForTimestamp(
seconds: Int64(sd) + Int64(Date.timeIntervalBetween1970AndReferenceDate),
nanos: Int32(nd))
self.init(seconds: s, nanos: n)
}
/// Creates a new `Google_Protobuf_Timestamp` initialized to the same time as
/// the given `Date`.
///
/// - Parameter date: The `Date` with which to initialize the timestamp.
public init(date: Date) {
// Note: Internally, Date uses the "reference date," not the 1970 date.
// We use it when interacting with Dates so that Date doesn't perform
// any double arithmetic on our behalf, which might cost us precision.
self.init(
timeIntervalSinceReferenceDate: date.timeIntervalSinceReferenceDate)
}
/// The interval between the timestamp and 00:00:00 UTC on 1 January 1970.
public var timeIntervalSince1970: TimeInterval {
return TimeInterval(self.seconds) +
TimeInterval(self.nanos) / TimeInterval(nanosPerSecond)
}
/// The interval between the timestamp and 00:00:00 UTC on 1 January 2001.
public var timeIntervalSinceReferenceDate: TimeInterval {
return TimeInterval(
self.seconds - Int64(Date.timeIntervalBetween1970AndReferenceDate)) +
TimeInterval(self.nanos) / TimeInterval(nanosPerSecond)
}
/// A `Date` initialized to the same time as the timestamp.
public var date: Date {
return Date(
timeIntervalSinceReferenceDate: self.timeIntervalSinceReferenceDate)
}
}
private func normalizeForTimestamp(
seconds: Int64,
nanos: Int32
) -> (seconds: Int64, nanos: Int32) {
// The Timestamp spec says that nanos must be in the range [0, 999999999),
// as in actual modular arithmetic.
let s = seconds + Int64(div(nanos, nanosPerSecond))
let n = mod(nanos, nanosPerSecond)
return (seconds: s, nanos: n)
}
public func + (
lhs: Google_Protobuf_Timestamp,
rhs: Google_Protobuf_Duration
) -> Google_Protobuf_Timestamp {
let (s, n) = normalizeForTimestamp(seconds: lhs.seconds + rhs.seconds,
nanos: lhs.nanos + rhs.nanos)
return Google_Protobuf_Timestamp(seconds: s, nanos: n)
}
public func + (
lhs: Google_Protobuf_Duration,
rhs: Google_Protobuf_Timestamp
) -> Google_Protobuf_Timestamp {
let (s, n) = normalizeForTimestamp(seconds: lhs.seconds + rhs.seconds,
nanos: lhs.nanos + rhs.nanos)
return Google_Protobuf_Timestamp(seconds: s, nanos: n)
}
public func - (
lhs: Google_Protobuf_Timestamp,
rhs: Google_Protobuf_Duration
) -> Google_Protobuf_Timestamp {
let (s, n) = normalizeForTimestamp(seconds: lhs.seconds - rhs.seconds,
nanos: lhs.nanos - rhs.nanos)
return Google_Protobuf_Timestamp(seconds: s, nanos: n)
}

View File

@ -0,0 +1,163 @@
// Sources/SwiftProtobuf/Google_Protobuf_Value+Extensions.swift - Value extensions
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Value is a well-known message type that can be used to parse or encode
/// arbitrary JSON without a predefined schema.
///
// -----------------------------------------------------------------------------
extension Google_Protobuf_Value: ExpressibleByIntegerLiteral {
public typealias IntegerLiteralType = Int64
/// Creates a new `Google_Protobuf_Value` from an integer literal.
public init(integerLiteral value: Int64) {
self.init(kind: .numberValue(Double(value)))
}
}
extension Google_Protobuf_Value: ExpressibleByFloatLiteral {
public typealias FloatLiteralType = Double
/// Creates a new `Google_Protobuf_Value` from a floating point literal.
public init(floatLiteral value: Double) {
self.init(kind: .numberValue(value))
}
}
extension Google_Protobuf_Value: ExpressibleByBooleanLiteral {
public typealias BooleanLiteralType = Bool
/// Creates a new `Google_Protobuf_Value` from a boolean literal.
public init(booleanLiteral value: Bool) {
self.init(kind: .boolValue(value))
}
}
extension Google_Protobuf_Value: ExpressibleByStringLiteral {
public typealias StringLiteralType = String
public typealias ExtendedGraphemeClusterLiteralType = String
public typealias UnicodeScalarLiteralType = String
/// Creates a new `Google_Protobuf_Value` from a string literal.
public init(stringLiteral value: String) {
self.init(kind: .stringValue(value))
}
/// Creates a new `Google_Protobuf_Value` from a Unicode scalar literal.
public init(unicodeScalarLiteral value: String) {
self.init(kind: .stringValue(value))
}
/// Creates a new `Google_Protobuf_Value` from a character literal.
public init(extendedGraphemeClusterLiteral value: String) {
self.init(kind: .stringValue(value))
}
}
extension Google_Protobuf_Value: ExpressibleByNilLiteral {
/// Creates a new `Google_Protobuf_Value` from the nil literal.
public init(nilLiteral: ()) {
self.init(kind: .nullValue(.nullValue))
}
}
extension Google_Protobuf_Value: _CustomJSONCodable {
internal func encodedJSONString(options: JSONEncodingOptions) throws -> String {
var jsonEncoder = JSONEncoder()
try serializeJSONValue(to: &jsonEncoder, options: options)
return jsonEncoder.stringResult
}
internal mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
let c = try decoder.scanner.peekOneCharacter()
switch c {
case "n":
if !decoder.scanner.skipOptionalNull() {
throw JSONDecodingError.failure
}
kind = .nullValue(.nullValue)
case "[":
var l = Google_Protobuf_ListValue()
try l.decodeJSON(from: &decoder)
kind = .listValue(l)
case "{":
var s = Google_Protobuf_Struct()
try s.decodeJSON(from: &decoder)
kind = .structValue(s)
case "t", "f":
let b = try decoder.scanner.nextBool()
kind = .boolValue(b)
case "\"":
let s = try decoder.scanner.nextQuotedString()
kind = .stringValue(s)
default:
let d = try decoder.scanner.nextDouble()
kind = .numberValue(d)
}
}
internal static func decodedFromJSONNull() -> Google_Protobuf_Value? {
return Google_Protobuf_Value(kind: .nullValue(.nullValue))
}
}
extension Google_Protobuf_Value {
/// Creates a new `Google_Protobuf_Value` with the given kind.
fileprivate init(kind: OneOf_Kind) {
self.init()
self.kind = kind
}
/// Creates a new `Google_Protobuf_Value` whose `kind` is `numberValue` with
/// the given floating-point value.
public init(numberValue: Double) {
self.init(kind: .numberValue(numberValue))
}
/// Creates a new `Google_Protobuf_Value` whose `kind` is `stringValue` with
/// the given string value.
public init(stringValue: String) {
self.init(kind: .stringValue(stringValue))
}
/// Creates a new `Google_Protobuf_Value` whose `kind` is `boolValue` with the
/// given boolean value.
public init(boolValue: Bool) {
self.init(kind: .boolValue(boolValue))
}
/// Creates a new `Google_Protobuf_Value` whose `kind` is `structValue` with
/// the given `Google_Protobuf_Struct` value.
public init(structValue: Google_Protobuf_Struct) {
self.init(kind: .structValue(structValue))
}
/// Creates a new `Google_Protobuf_Value` whose `kind` is `listValue` with the
/// given `Google_Struct_ListValue` value.
public init(listValue: Google_Protobuf_ListValue) {
self.init(kind: .listValue(listValue))
}
/// Writes out the JSON representation of the value to the given encoder.
internal func serializeJSONValue(
to encoder: inout JSONEncoder,
options: JSONEncodingOptions
) throws {
switch kind {
case .nullValue?: encoder.putNullValue()
case .numberValue(let v)?: encoder.putDoubleValue(value: v)
case .stringValue(let v)?: encoder.putStringValue(value: v)
case .boolValue(let v)?: encoder.putBoolValue(value: v)
case .structValue(let v)?: encoder.append(text: try v.jsonString(options: options))
case .listValue(let v)?: encoder.append(text: try v.jsonString(options: options))
case nil: throw JSONEncodingError.missingValue
}
}
}

View File

@ -0,0 +1,247 @@
// Sources/SwiftProtobuf/Google_Protobuf_Wrappers+Extensions.swift - Well-known wrapper type extensions
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extensions to the well-known types in wrapper.proto that customize the JSON
/// format of those messages and provide convenience initializers from literals.
///
// -----------------------------------------------------------------------------
import Foundation
/// Internal protocol that minimizes the code duplication across the multiple
/// wrapper types extended below.
protocol ProtobufWrapper {
/// The wrapped protobuf type (for example, `ProtobufDouble`).
associatedtype WrappedType: FieldType
/// Exposes the generated property to the extensions here.
var value: WrappedType.BaseType { get set }
/// Exposes the parameterless initializer to the extensions here.
init()
/// Creates a new instance of the wrapper with the given value.
init(_ value: WrappedType.BaseType)
}
extension ProtobufWrapper {
mutating func decodeJSON(from decoder: inout JSONDecoder) throws {
var v: WrappedType.BaseType?
try WrappedType.decodeSingular(value: &v, from: &decoder)
value = v ?? WrappedType.proto3DefaultValue
}
}
extension Google_Protobuf_DoubleValue:
ProtobufWrapper, ExpressibleByFloatLiteral, _CustomJSONCodable {
public typealias WrappedType = ProtobufDouble
public typealias FloatLiteralType = WrappedType.BaseType
public init(_ value: WrappedType.BaseType) {
self.init()
self.value = value
}
public init(floatLiteral: FloatLiteralType) {
self.init(floatLiteral)
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
if value.isFinite {
// Swift 4.2 and later guarantees that this is accurate
// enough to parse back to the exact value on the other end.
return value.description
} else {
// Protobuf-specific handling of NaN and infinities
var encoder = JSONEncoder()
encoder.putDoubleValue(value: value)
return encoder.stringResult
}
}
}
extension Google_Protobuf_FloatValue:
ProtobufWrapper, ExpressibleByFloatLiteral, _CustomJSONCodable {
public typealias WrappedType = ProtobufFloat
public typealias FloatLiteralType = Float
public init(_ value: WrappedType.BaseType) {
self.init()
self.value = value
}
public init(floatLiteral: FloatLiteralType) {
self.init(floatLiteral)
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
if value.isFinite {
// Swift 4.2 and later guarantees that this is accurate
// enough to parse back to the exact value on the other end.
return value.description
} else {
// Protobuf-specific handling of NaN and infinities
var encoder = JSONEncoder()
encoder.putFloatValue(value: value)
return encoder.stringResult
}
}
}
extension Google_Protobuf_Int64Value:
ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable {
public typealias WrappedType = ProtobufInt64
public typealias IntegerLiteralType = WrappedType.BaseType
public init(_ value: WrappedType.BaseType) {
self.init()
self.value = value
}
public init(integerLiteral: IntegerLiteralType) {
self.init(integerLiteral)
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
return "\"" + String(value) + "\""
}
}
extension Google_Protobuf_UInt64Value:
ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable {
public typealias WrappedType = ProtobufUInt64
public typealias IntegerLiteralType = WrappedType.BaseType
public init(_ value: WrappedType.BaseType) {
self.init()
self.value = value
}
public init(integerLiteral: IntegerLiteralType) {
self.init(integerLiteral)
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
return "\"" + String(value) + "\""
}
}
extension Google_Protobuf_Int32Value:
ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable {
public typealias WrappedType = ProtobufInt32
public typealias IntegerLiteralType = WrappedType.BaseType
public init(_ value: WrappedType.BaseType) {
self.init()
self.value = value
}
public init(integerLiteral: IntegerLiteralType) {
self.init(integerLiteral)
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
return String(value)
}
}
extension Google_Protobuf_UInt32Value:
ProtobufWrapper, ExpressibleByIntegerLiteral, _CustomJSONCodable {
public typealias WrappedType = ProtobufUInt32
public typealias IntegerLiteralType = WrappedType.BaseType
public init(_ value: WrappedType.BaseType) {
self.init()
self.value = value
}
public init(integerLiteral: IntegerLiteralType) {
self.init(integerLiteral)
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
return String(value)
}
}
extension Google_Protobuf_BoolValue:
ProtobufWrapper, ExpressibleByBooleanLiteral, _CustomJSONCodable {
public typealias WrappedType = ProtobufBool
public typealias BooleanLiteralType = Bool
public init(_ value: WrappedType.BaseType) {
self.init()
self.value = value
}
public init(booleanLiteral: Bool) {
self.init(booleanLiteral)
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
return value ? "true" : "false"
}
}
extension Google_Protobuf_StringValue:
ProtobufWrapper, ExpressibleByStringLiteral, _CustomJSONCodable {
public typealias WrappedType = ProtobufString
public typealias StringLiteralType = String
public typealias ExtendedGraphemeClusterLiteralType = String
public typealias UnicodeScalarLiteralType = String
public init(_ value: WrappedType.BaseType) {
self.init()
self.value = value
}
public init(stringLiteral: String) {
self.init(stringLiteral)
}
public init(extendedGraphemeClusterLiteral: String) {
self.init(extendedGraphemeClusterLiteral)
}
public init(unicodeScalarLiteral: String) {
self.init(unicodeScalarLiteral)
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
var encoder = JSONEncoder()
encoder.putStringValue(value: value)
return encoder.stringResult
}
}
extension Google_Protobuf_BytesValue: ProtobufWrapper, _CustomJSONCodable {
public typealias WrappedType = ProtobufBytes
public init(_ value: WrappedType.BaseType) {
self.init()
self.value = value
}
func encodedJSONString(options: JSONEncodingOptions) throws -> String {
var encoder = JSONEncoder()
encoder.putBytesValue(value: value)
return encoder.stringResult
}
}

View File

@ -0,0 +1,426 @@
// Sources/SwiftProtobuf/HashVisitor.swift - Hashing support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Hashing is basically a serialization problem, so we can leverage the
/// generated traversal methods for that.
///
// -----------------------------------------------------------------------------
import Foundation
private let i_2166136261 = Int(bitPattern: 2166136261)
private let i_16777619 = Int(16777619)
/// Computes the hash of a message by visiting its fields recursively.
///
/// Note that because this visits every field, it has the potential to be slow
/// for large or deeply nested messages. Users who need to use such messages as
/// dictionary keys or set members can use a wrapper struct around the message
/// and use a custom Hashable implementation that looks at the subset of the
/// message fields they want to include.
internal struct HashVisitor: Visitor {
#if swift(>=4.2)
internal private(set) var hasher: Hasher
#else // swift(>=4.2)
// Roughly based on FNV hash: http://tools.ietf.org/html/draft-eastlake-fnv-03
private(set) var hashValue = i_2166136261
private mutating func mix(_ hash: Int) {
hashValue = (hashValue ^ hash) &* i_16777619
}
private mutating func mixMap<K, V: Hashable>(map: Dictionary<K,V>) {
var mapHash = 0
for (k, v) in map {
// Note: This calculation cannot depend on the order of the items.
mapHash = mapHash &+ (k.hashValue ^ v.hashValue)
}
mix(mapHash)
}
#endif // swift(>=4.2)
#if swift(>=4.2)
init(_ hasher: Hasher) {
self.hasher = hasher
}
#else
init() {}
#endif
mutating func visitUnknown(bytes: Data) throws {
#if swift(>=4.2)
hasher.combine(bytes)
#else
mix(bytes.hashValue)
#endif
}
mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
mix(value.hashValue)
#endif
}
mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
mix(value.hashValue)
#endif
}
mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
mix(value.hashValue)
#endif
}
mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
mix(value.hashValue)
#endif
}
mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
mix(value.hashValue)
#endif
}
mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
mix(value.hashValue)
#endif
}
mutating func visitSingularEnumField<E: Enum>(value: E,
fieldNumber: Int) {
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
mix(value.hashValue)
#endif
}
mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) {
#if swift(>=4.2)
hasher.combine(fieldNumber)
value.hash(into: &hasher)
#else
mix(fieldNumber)
mix(value.hashValue)
#endif
}
mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedMessageField<M: Message>(value: [M], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
for v in value {
v.hash(into: &hasher)
}
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitRepeatedGroupField<G: Message>(value: [G], fieldNumber: Int) throws {
assert(!value.isEmpty)
#if swift(>=4.2)
hasher.combine(fieldNumber)
for v in value {
v.hash(into: &hasher)
}
#else
mix(fieldNumber)
for v in value {
mix(v.hashValue)
}
#endif
}
mutating func visitMapField<KeyType, ValueType: MapValueType>(
fieldType: _ProtobufMap<KeyType, ValueType>.Type,
value: _ProtobufMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws {
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
mixMap(map: value)
#endif
}
mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
value: _ProtobufEnumMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws where ValueType.RawValue == Int {
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
mixMap(map: value)
#endif
}
mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
value: _ProtobufMessageMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws {
#if swift(>=4.2)
hasher.combine(fieldNumber)
hasher.combine(value)
#else
mix(fieldNumber)
mixMap(map: value)
#endif
}
}

View File

@ -0,0 +1,51 @@
// Sources/SwiftProtobuf/Internal.swift - Message support
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Internal helpers on Messages for the library. These are public
/// just so the generated code can call them, but shouldn't be called
/// by developers directly.
///
// -----------------------------------------------------------------------------
import Foundation
/// Functions that are public only because they are used by generated message
/// implementations. NOT INTENDED TO BE CALLED BY CLIENTS.
public enum Internal {
/// A singleton instance of an empty data that is used by the generated code
/// for default values. This is a performance enhancement to work around the
/// fact that the `Data` type in Swift involves a new heap allocation every
/// time an empty instance is initialized, instead of sharing a common empty
/// backing storage.
public static let emptyData = Data()
/// Helper to loop over a list of Messages to see if they are all
/// initialized (see Message.isInitialized for what that means).
public static func areAllInitialized(_ listOfMessages: [Message]) -> Bool {
for msg in listOfMessages {
if !msg.isInitialized {
return false
}
}
return true
}
/// Helper to loop over dictionary with values that are Messages to see if
/// they are all initialized (see Message.isInitialized for what that means).
public static func areAllInitialized<K>(_ mapToMessages: [K: Message]) -> Bool {
for (_, msg) in mapToMessages {
if !msg.isInitialized {
return false
}
}
return true
}
}

View File

@ -0,0 +1,735 @@
// Sources/SwiftProtobuf/JSONDecoder.swift - JSON format decoding
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// JSON format decoding engine.
///
// -----------------------------------------------------------------------------
import Foundation
internal struct JSONDecoder: Decoder {
internal var scanner: JSONScanner
internal var messageType: Message.Type
private var fieldCount = 0
private var isMapKey = false
private var fieldNameMap: _NameMap?
internal var options: JSONDecodingOptions {
return scanner.options
}
mutating func handleConflictingOneOf() throws {
throw JSONDecodingError.conflictingOneOf
}
internal init(source: UnsafeRawBufferPointer, options: JSONDecodingOptions,
messageType: Message.Type, extensions: ExtensionMap?) {
let scanner = JSONScanner(source: source,
options: options,
extensions: extensions)
self.init(scanner: scanner, messageType: messageType)
}
private init(scanner: JSONScanner, messageType: Message.Type) {
self.scanner = scanner
self.messageType = messageType
}
mutating func nextFieldNumber() throws -> Int? {
if scanner.skipOptionalObjectEnd() {
return nil
}
if fieldCount > 0 {
try scanner.skipRequiredComma()
}
let fieldNumber = try scanner.nextFieldNumber(names: fieldNameMap!,
messageType: messageType)
if let fieldNumber = fieldNumber {
fieldCount += 1
return fieldNumber
}
return nil
}
mutating func decodeSingularFloatField(value: inout Float) throws {
if scanner.skipOptionalNull() {
value = 0
return
}
value = try scanner.nextFloat()
}
mutating func decodeSingularFloatField(value: inout Float?) throws {
if scanner.skipOptionalNull() {
value = nil
return
}
value = try scanner.nextFloat()
}
mutating func decodeRepeatedFloatField(value: inout [Float]) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
while true {
let n = try scanner.nextFloat()
value.append(n)
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeSingularDoubleField(value: inout Double) throws {
if scanner.skipOptionalNull() {
value = 0
return
}
value = try scanner.nextDouble()
}
mutating func decodeSingularDoubleField(value: inout Double?) throws {
if scanner.skipOptionalNull() {
value = nil
return
}
value = try scanner.nextDouble()
}
mutating func decodeRepeatedDoubleField(value: inout [Double]) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
while true {
let n = try scanner.nextDouble()
value.append(n)
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeSingularInt32Field(value: inout Int32) throws {
if scanner.skipOptionalNull() {
value = 0
return
}
let n = try scanner.nextSInt()
if n > Int64(Int32.max) || n < Int64(Int32.min) {
throw JSONDecodingError.numberRange
}
value = Int32(truncatingIfNeeded: n)
}
mutating func decodeSingularInt32Field(value: inout Int32?) throws {
if scanner.skipOptionalNull() {
value = nil
return
}
let n = try scanner.nextSInt()
if n > Int64(Int32.max) || n < Int64(Int32.min) {
throw JSONDecodingError.numberRange
}
value = Int32(truncatingIfNeeded: n)
}
mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
while true {
let n = try scanner.nextSInt()
if n > Int64(Int32.max) || n < Int64(Int32.min) {
throw JSONDecodingError.numberRange
}
value.append(Int32(truncatingIfNeeded: n))
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeSingularInt64Field(value: inout Int64) throws {
if scanner.skipOptionalNull() {
value = 0
return
}
value = try scanner.nextSInt()
}
mutating func decodeSingularInt64Field(value: inout Int64?) throws {
if scanner.skipOptionalNull() {
value = nil
return
}
value = try scanner.nextSInt()
}
mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
while true {
let n = try scanner.nextSInt()
value.append(n)
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeSingularUInt32Field(value: inout UInt32) throws {
if scanner.skipOptionalNull() {
value = 0
return
}
let n = try scanner.nextUInt()
if n > UInt64(UInt32.max) {
throw JSONDecodingError.numberRange
}
value = UInt32(truncatingIfNeeded: n)
}
mutating func decodeSingularUInt32Field(value: inout UInt32?) throws {
if scanner.skipOptionalNull() {
value = nil
return
}
let n = try scanner.nextUInt()
if n > UInt64(UInt32.max) {
throw JSONDecodingError.numberRange
}
value = UInt32(truncatingIfNeeded: n)
}
mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
while true {
let n = try scanner.nextUInt()
if n > UInt64(UInt32.max) {
throw JSONDecodingError.numberRange
}
value.append(UInt32(truncatingIfNeeded: n))
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeSingularUInt64Field(value: inout UInt64) throws {
if scanner.skipOptionalNull() {
value = 0
return
}
value = try scanner.nextUInt()
}
mutating func decodeSingularUInt64Field(value: inout UInt64?) throws {
if scanner.skipOptionalNull() {
value = nil
return
}
value = try scanner.nextUInt()
}
mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
while true {
let n = try scanner.nextUInt()
value.append(n)
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeSingularSInt32Field(value: inout Int32) throws {
try decodeSingularInt32Field(value: &value)
}
mutating func decodeSingularSInt32Field(value: inout Int32?) throws {
try decodeSingularInt32Field(value: &value)
}
mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws {
try decodeRepeatedInt32Field(value: &value)
}
mutating func decodeSingularSInt64Field(value: inout Int64) throws {
try decodeSingularInt64Field(value: &value)
}
mutating func decodeSingularSInt64Field(value: inout Int64?) throws {
try decodeSingularInt64Field(value: &value)
}
mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws {
try decodeRepeatedInt64Field(value: &value)
}
mutating func decodeSingularFixed32Field(value: inout UInt32) throws {
try decodeSingularUInt32Field(value: &value)
}
mutating func decodeSingularFixed32Field(value: inout UInt32?) throws {
try decodeSingularUInt32Field(value: &value)
}
mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws {
try decodeRepeatedUInt32Field(value: &value)
}
mutating func decodeSingularFixed64Field(value: inout UInt64) throws {
try decodeSingularUInt64Field(value: &value)
}
mutating func decodeSingularFixed64Field(value: inout UInt64?) throws {
try decodeSingularUInt64Field(value: &value)
}
mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws {
try decodeRepeatedUInt64Field(value: &value)
}
mutating func decodeSingularSFixed32Field(value: inout Int32) throws {
try decodeSingularInt32Field(value: &value)
}
mutating func decodeSingularSFixed32Field(value: inout Int32?) throws {
try decodeSingularInt32Field(value: &value)
}
mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws {
try decodeRepeatedInt32Field(value: &value)
}
mutating func decodeSingularSFixed64Field(value: inout Int64) throws {
try decodeSingularInt64Field(value: &value)
}
mutating func decodeSingularSFixed64Field(value: inout Int64?) throws {
try decodeSingularInt64Field(value: &value)
}
mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws {
try decodeRepeatedInt64Field(value: &value)
}
mutating func decodeSingularBoolField(value: inout Bool) throws {
if scanner.skipOptionalNull() {
value = false
return
}
if isMapKey {
value = try scanner.nextQuotedBool()
} else {
value = try scanner.nextBool()
}
}
mutating func decodeSingularBoolField(value: inout Bool?) throws {
if scanner.skipOptionalNull() {
value = nil
return
}
if isMapKey {
value = try scanner.nextQuotedBool()
} else {
value = try scanner.nextBool()
}
}
mutating func decodeRepeatedBoolField(value: inout [Bool]) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
while true {
let n = try scanner.nextBool()
value.append(n)
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeSingularStringField(value: inout String) throws {
if scanner.skipOptionalNull() {
value = String()
return
}
value = try scanner.nextQuotedString()
}
mutating func decodeSingularStringField(value: inout String?) throws {
if scanner.skipOptionalNull() {
value = nil
return
}
value = try scanner.nextQuotedString()
}
mutating func decodeRepeatedStringField(value: inout [String]) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
while true {
let n = try scanner.nextQuotedString()
value.append(n)
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeSingularBytesField(value: inout Data) throws {
if scanner.skipOptionalNull() {
value = Data()
return
}
value = try scanner.nextBytesValue()
}
mutating func decodeSingularBytesField(value: inout Data?) throws {
if scanner.skipOptionalNull() {
value = nil
return
}
value = try scanner.nextBytesValue()
}
mutating func decodeRepeatedBytesField(value: inout [Data]) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
while true {
let n = try scanner.nextBytesValue()
value.append(n)
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeSingularEnumField<E: Enum>(value: inout E?) throws
where E.RawValue == Int {
if scanner.skipOptionalNull() {
if let customDecodable = E.self as? _CustomJSONCodable.Type {
value = try customDecodable.decodedFromJSONNull() as? E
return
}
value = nil
return
}
value = try scanner.nextEnumValue() as E
}
mutating func decodeSingularEnumField<E: Enum>(value: inout E) throws
where E.RawValue == Int {
if scanner.skipOptionalNull() {
if let customDecodable = E.self as? _CustomJSONCodable.Type {
value = try customDecodable.decodedFromJSONNull() as! E
return
}
value = E()
return
}
value = try scanner.nextEnumValue()
}
mutating func decodeRepeatedEnumField<E: Enum>(value: inout [E]) throws
where E.RawValue == Int {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
let maybeCustomDecodable = E.self as? _CustomJSONCodable.Type
while true {
if scanner.skipOptionalNull() {
if let customDecodable = maybeCustomDecodable {
let e = try customDecodable.decodedFromJSONNull() as! E
value.append(e)
} else {
throw JSONDecodingError.illegalNull
}
} else {
let e: E = try scanner.nextEnumValue()
value.append(e)
}
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
internal mutating func decodeFullObject<M: Message>(message: inout M) throws {
guard let nameProviding = (M.self as? _ProtoNameProviding.Type) else {
throw JSONDecodingError.missingFieldNames
}
fieldNameMap = nameProviding._protobuf_nameMap
if let m = message as? _CustomJSONCodable {
var customCodable = m
try customCodable.decodeJSON(from: &self)
message = customCodable as! M
} else {
try scanner.skipRequiredObjectStart()
if scanner.skipOptionalObjectEnd() {
return
}
try message.decodeMessage(decoder: &self)
}
}
mutating func decodeSingularMessageField<M: Message>(value: inout M?) throws {
if scanner.skipOptionalNull() {
if M.self is _CustomJSONCodable.Type {
value =
try (M.self as! _CustomJSONCodable.Type).decodedFromJSONNull() as? M
return
}
// All other message field types treat 'null' as an unset
value = nil
return
}
if value == nil {
value = M()
}
var subDecoder = JSONDecoder(scanner: scanner, messageType: M.self)
try subDecoder.decodeFullObject(message: &value!)
assert(scanner.recursionBudget == subDecoder.scanner.recursionBudget)
scanner = subDecoder.scanner
}
mutating func decodeRepeatedMessageField<M: Message>(
value: inout [M]
) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredArrayStart()
if scanner.skipOptionalArrayEnd() {
return
}
while true {
if scanner.skipOptionalNull() {
var appended = false
if M.self is _CustomJSONCodable.Type {
if let message = try (M.self as! _CustomJSONCodable.Type)
.decodedFromJSONNull() as? M {
value.append(message)
appended = true
}
}
if !appended {
throw JSONDecodingError.illegalNull
}
} else {
var message = M()
var subDecoder = JSONDecoder(scanner: scanner, messageType: M.self)
try subDecoder.decodeFullObject(message: &message)
value.append(message)
assert(scanner.recursionBudget == subDecoder.scanner.recursionBudget)
scanner = subDecoder.scanner
}
if scanner.skipOptionalArrayEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeSingularGroupField<G: Message>(value: inout G?) throws {
throw JSONDecodingError.schemaMismatch
}
mutating func decodeRepeatedGroupField<G: Message>(value: inout [G]) throws {
throw JSONDecodingError.schemaMismatch
}
mutating func decodeMapField<KeyType, ValueType: MapValueType>(
fieldType: _ProtobufMap<KeyType, ValueType>.Type,
value: inout _ProtobufMap<KeyType, ValueType>.BaseType
) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredObjectStart()
if scanner.skipOptionalObjectEnd() {
return
}
while true {
// Next character must be double quote, because
// map keys must always be quoted strings.
let c = try scanner.peekOneCharacter()
if c != "\"" {
throw JSONDecodingError.unquotedMapKey
}
isMapKey = true
var keyField: KeyType.BaseType?
try KeyType.decodeSingular(value: &keyField, from: &self)
isMapKey = false
try scanner.skipRequiredColon()
var valueField: ValueType.BaseType?
try ValueType.decodeSingular(value: &valueField, from: &self)
if let keyField = keyField, let valueField = valueField {
value[keyField] = valueField
} else {
throw JSONDecodingError.malformedMap
}
if scanner.skipOptionalObjectEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeMapField<KeyType, ValueType>(
fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
value: inout _ProtobufEnumMap<KeyType, ValueType>.BaseType
) throws where ValueType.RawValue == Int {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredObjectStart()
if scanner.skipOptionalObjectEnd() {
return
}
while true {
// Next character must be double quote, because
// map keys must always be quoted strings.
let c = try scanner.peekOneCharacter()
if c != "\"" {
throw JSONDecodingError.unquotedMapKey
}
isMapKey = true
var keyField: KeyType.BaseType?
try KeyType.decodeSingular(value: &keyField, from: &self)
isMapKey = false
try scanner.skipRequiredColon()
var valueField: ValueType?
try decodeSingularEnumField(value: &valueField)
if let keyField = keyField, let valueField = valueField {
value[keyField] = valueField
} else {
throw JSONDecodingError.malformedMap
}
if scanner.skipOptionalObjectEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeMapField<KeyType, ValueType>(
fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
value: inout _ProtobufMessageMap<KeyType, ValueType>.BaseType
) throws {
if scanner.skipOptionalNull() {
return
}
try scanner.skipRequiredObjectStart()
if scanner.skipOptionalObjectEnd() {
return
}
while true {
// Next character must be double quote, because
// map keys must always be quoted strings.
let c = try scanner.peekOneCharacter()
if c != "\"" {
throw JSONDecodingError.unquotedMapKey
}
isMapKey = true
var keyField: KeyType.BaseType?
try KeyType.decodeSingular(value: &keyField, from: &self)
isMapKey = false
try scanner.skipRequiredColon()
var valueField: ValueType?
try decodeSingularMessageField(value: &valueField)
if let keyField = keyField, let valueField = valueField {
value[keyField] = valueField
} else {
throw JSONDecodingError.malformedMap
}
if scanner.skipOptionalObjectEnd() {
return
}
try scanner.skipRequiredComma()
}
}
mutating func decodeExtensionField(
values: inout ExtensionFieldValueSet,
messageType: Message.Type,
fieldNumber: Int
) throws {
// Force-unwrap: we can only get here if the extension exists.
let ext = scanner.extensions[messageType, fieldNumber]!
var fieldValue = values[fieldNumber]
if fieldValue != nil {
try fieldValue!.decodeExtensionField(decoder: &self)
} else {
fieldValue = try ext._protobuf_newField(decoder: &self)
}
values[fieldNumber] = fieldValue!
}
}

View File

@ -0,0 +1,62 @@
// Sources/SwiftProtobuf/JSONDecodingError.swift - JSON decoding errors
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// JSON decoding errors
///
// -----------------------------------------------------------------------------
public enum JSONDecodingError: Error {
/// Something was wrong
case failure
/// A number could not be parsed
case malformedNumber
/// Numeric value was out of range or was not an integer value when expected
case numberRange
/// A map could not be parsed
case malformedMap
/// A bool could not be parsed
case malformedBool
/// We expected a quoted string, or a quoted string has a malformed backslash sequence
case malformedString
/// We encountered malformed UTF8
case invalidUTF8
/// The message does not have fieldName information
case missingFieldNames
/// The data type does not match the schema description
case schemaMismatch
/// A value (text or numeric) for an enum was not found on the enum
case unrecognizedEnumValue
/// A 'null' token appeared in an illegal location.
/// For example, Protobuf JSON does not allow 'null' tokens to appear
/// in lists.
case illegalNull
/// A map key was not quoted
case unquotedMapKey
/// JSON RFC 7519 does not allow numbers to have extra leading zeros
case leadingZero
/// We hit the end of the JSON string and expected something more...
case truncated
/// A JSON Duration could not be parsed
case malformedDuration
/// A JSON Timestamp could not be parsed
case malformedTimestamp
/// A FieldMask could not be parsed
case malformedFieldMask
/// Extraneous data remained after decoding should have been complete
case trailingGarbage
/// More than one value was specified for the same oneof field
case conflictingOneOf
/// Reached the nesting limit for messages within messages while decoding.
case messageDepthLimit
/// Encountered an unknown field with the given name. When parsing JSON, you
/// can instead instruct the library to ignore this via
/// JSONDecodingOptions.ignoreUnknownFields.
case unknownField(String)
}

View File

@ -0,0 +1,29 @@
// Sources/SwiftProtobuf/JSONDecodingOptions.swift - JSON decoding options
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// JSON decoding options
///
// -----------------------------------------------------------------------------
/// Options for JSONDecoding.
public struct JSONDecodingOptions {
/// The maximum nesting of message with messages. The default is 100.
///
/// To prevent corrupt or malicious messages from causing stack overflows,
/// this controls how deep messages can be nested within other messages
/// while parsing.
public var messageDepthLimit: Int = 100
/// If unknown fields in the JSON should be ignored. If they aren't
/// ignored, an error will be raised if one is encountered.
public var ignoreUnknownFields: Bool = false
public init() {}
}

View File

@ -0,0 +1,386 @@
// Sources/SwiftProtobuf/JSONEncoder.swift - JSON Encoding support
//
// Copyright (c) 2014 - 2019 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// JSON serialization engine.
///
// -----------------------------------------------------------------------------
import Foundation
private let asciiZero = UInt8(ascii: "0")
private let asciiOne = UInt8(ascii: "1")
private let asciiTwo = UInt8(ascii: "2")
private let asciiThree = UInt8(ascii: "3")
private let asciiFour = UInt8(ascii: "4")
private let asciiFive = UInt8(ascii: "5")
private let asciiSix = UInt8(ascii: "6")
private let asciiSeven = UInt8(ascii: "7")
private let asciiEight = UInt8(ascii: "8")
private let asciiNine = UInt8(ascii: "9")
private let asciiMinus = UInt8(ascii: "-")
private let asciiPlus = UInt8(ascii: "+")
private let asciiEquals = UInt8(ascii: "=")
private let asciiColon = UInt8(ascii: ":")
private let asciiComma = UInt8(ascii: ",")
private let asciiDoubleQuote = UInt8(ascii: "\"")
private let asciiBackslash = UInt8(ascii: "\\")
private let asciiForwardSlash = UInt8(ascii: "/")
private let asciiOpenSquareBracket = UInt8(ascii: "[")
private let asciiCloseSquareBracket = UInt8(ascii: "]")
private let asciiOpenCurlyBracket = UInt8(ascii: "{")
private let asciiCloseCurlyBracket = UInt8(ascii: "}")
private let asciiUpperA = UInt8(ascii: "A")
private let asciiUpperB = UInt8(ascii: "B")
private let asciiUpperC = UInt8(ascii: "C")
private let asciiUpperD = UInt8(ascii: "D")
private let asciiUpperE = UInt8(ascii: "E")
private let asciiUpperF = UInt8(ascii: "F")
private let asciiUpperZ = UInt8(ascii: "Z")
private let asciiLowerA = UInt8(ascii: "a")
private let asciiLowerZ = UInt8(ascii: "z")
private let base64Digits: [UInt8] = {
var digits = [UInt8]()
digits.append(contentsOf: asciiUpperA...asciiUpperZ)
digits.append(contentsOf: asciiLowerA...asciiLowerZ)
digits.append(contentsOf: asciiZero...asciiNine)
digits.append(asciiPlus)
digits.append(asciiForwardSlash)
return digits
}()
private let hexDigits: [UInt8] = {
var digits = [UInt8]()
digits.append(contentsOf: asciiZero...asciiNine)
digits.append(contentsOf: asciiUpperA...asciiUpperF)
return digits
}()
internal struct JSONEncoder {
private var data = [UInt8]()
private var separator: UInt8?
internal init() {}
internal var dataResult: Data { return Data(data) }
internal var stringResult: String {
get {
return String(bytes: data, encoding: String.Encoding.utf8)!
}
}
/// Append a `StaticString` to the JSON text. Because
/// `StaticString` is already UTF8 internally, this is faster
/// than appending a regular `String`.
internal mutating func append(staticText: StaticString) {
let buff = UnsafeBufferPointer(start: staticText.utf8Start, count: staticText.utf8CodeUnitCount)
data.append(contentsOf: buff)
}
/// Append a `_NameMap.Name` to the JSON text surrounded by quotes.
/// As with StaticString above, a `_NameMap.Name` provides pre-converted
/// UTF8 bytes, so this is much faster than appending a regular
/// `String`.
internal mutating func appendQuoted(name: _NameMap.Name) {
data.append(asciiDoubleQuote)
data.append(contentsOf: name.utf8Buffer)
data.append(asciiDoubleQuote)
}
/// Append a `String` to the JSON text.
internal mutating func append(text: String) {
data.append(contentsOf: text.utf8)
}
/// Append a raw utf8 in a `Data` to the JSON text.
internal mutating func append(utf8Data: Data) {
data.append(contentsOf: utf8Data)
}
/// Begin a new field whose name is given as a `_NameMap.Name`
internal mutating func startField(name: _NameMap.Name) {
if let s = separator {
data.append(s)
}
appendQuoted(name: name)
data.append(asciiColon)
separator = asciiComma
}
/// Begin a new field whose name is given as a `String`.
internal mutating func startField(name: String) {
if let s = separator {
data.append(s)
}
data.append(asciiDoubleQuote)
// Can avoid overhead of putStringValue, since
// the JSON field names are always clean ASCII.
data.append(contentsOf: name.utf8)
append(staticText: "\":")
separator = asciiComma
}
/// Begin a new extension field
internal mutating func startExtensionField(name: String) {
if let s = separator {
data.append(s)
}
append(staticText: "\"[")
data.append(contentsOf: name.utf8)
append(staticText: "]\":")
separator = asciiComma
}
/// Append an open square bracket `[` to the JSON.
internal mutating func startArray() {
data.append(asciiOpenSquareBracket)
separator = nil
}
/// Append a close square bracket `]` to the JSON.
internal mutating func endArray() {
data.append(asciiCloseSquareBracket)
separator = asciiComma
}
/// Append a comma `,` to the JSON.
internal mutating func comma() {
data.append(asciiComma)
}
/// Append an open curly brace `{` to the JSON.
/// Assumes this object is part of an array of objects.
internal mutating func startArrayObject() {
if let s = separator {
data.append(s)
}
data.append(asciiOpenCurlyBracket)
separator = nil
}
/// Append an open curly brace `{` to the JSON.
internal mutating func startObject() {
data.append(asciiOpenCurlyBracket)
separator = nil
}
/// Append a close curly brace `}` to the JSON.
internal mutating func endObject() {
data.append(asciiCloseCurlyBracket)
separator = asciiComma
}
/// Write a JSON `null` token to the output.
internal mutating func putNullValue() {
append(staticText: "null")
}
/// Append a float value to the output.
/// This handles Nan and infinite values by
/// writing well-known string values.
internal mutating func putFloatValue(value: Float) {
if value.isNaN {
append(staticText: "\"NaN\"")
} else if !value.isFinite {
if value < 0 {
append(staticText: "\"-Infinity\"")
} else {
append(staticText: "\"Infinity\"")
}
} else {
data.append(contentsOf: value.debugDescription.utf8)
}
}
/// Append a double value to the output.
/// This handles Nan and infinite values by
/// writing well-known string values.
internal mutating func putDoubleValue(value: Double) {
if value.isNaN {
append(staticText: "\"NaN\"")
} else if !value.isFinite {
if value < 0 {
append(staticText: "\"-Infinity\"")
} else {
append(staticText: "\"Infinity\"")
}
} else {
data.append(contentsOf: value.debugDescription.utf8)
}
}
/// Append a UInt64 to the output (without quoting).
private mutating func appendUInt(value: UInt64) {
if value >= 10 {
appendUInt(value: value / 10)
}
data.append(asciiZero + UInt8(value % 10))
}
/// Append an Int64 to the output (without quoting).
private mutating func appendInt(value: Int64) {
if value < 0 {
data.append(asciiMinus)
// This is the twos-complement negation of value,
// computed in a way that won't overflow a 64-bit
// signed integer.
appendUInt(value: 1 + ~UInt64(bitPattern: value))
} else {
appendUInt(value: UInt64(bitPattern: value))
}
}
/// Write an Enum as an int.
internal mutating func putEnumInt(value: Int) {
appendInt(value: Int64(value))
}
/// Write an `Int64` using protobuf JSON quoting conventions.
internal mutating func putInt64(value: Int64) {
data.append(asciiDoubleQuote)
appendInt(value: value)
data.append(asciiDoubleQuote)
}
/// Write an `Int32` with quoting suitable for
/// using the value as a map key.
internal mutating func putQuotedInt32(value: Int32) {
data.append(asciiDoubleQuote)
appendInt(value: Int64(value))
data.append(asciiDoubleQuote)
}
/// Write an `Int32` in the default format.
internal mutating func putInt32(value: Int32) {
appendInt(value: Int64(value))
}
/// Write a `UInt64` using protobuf JSON quoting conventions.
internal mutating func putUInt64(value: UInt64) {
data.append(asciiDoubleQuote)
appendUInt(value: value)
data.append(asciiDoubleQuote)
}
/// Write a `UInt32` with quoting suitable for
/// using the value as a map key.
internal mutating func putQuotedUInt32(value: UInt32) {
data.append(asciiDoubleQuote)
appendUInt(value: UInt64(value))
data.append(asciiDoubleQuote)
}
/// Write a `UInt32` in the default format.
internal mutating func putUInt32(value: UInt32) {
appendUInt(value: UInt64(value))
}
/// Write a `Bool` with quoting suitable for
/// using the value as a map key.
internal mutating func putQuotedBoolValue(value: Bool) {
data.append(asciiDoubleQuote)
putBoolValue(value: value)
data.append(asciiDoubleQuote)
}
/// Write a `Bool` in the default format.
internal mutating func putBoolValue(value: Bool) {
if value {
append(staticText: "true")
} else {
append(staticText: "false")
}
}
/// Append a string value escaping special characters as needed.
internal mutating func putStringValue(value: String) {
data.append(asciiDoubleQuote)
for c in value.unicodeScalars {
switch c.value {
// Special two-byte escapes
case 8: append(staticText: "\\b")
case 9: append(staticText: "\\t")
case 10: append(staticText: "\\n")
case 12: append(staticText: "\\f")
case 13: append(staticText: "\\r")
case 34: append(staticText: "\\\"")
case 92: append(staticText: "\\\\")
case 0...31, 127...159: // Hex form for C0 control chars
append(staticText: "\\u00")
data.append(hexDigits[Int(c.value / 16)])
data.append(hexDigits[Int(c.value & 15)])
case 23...126:
data.append(UInt8(truncatingIfNeeded: c.value))
case 0x80...0x7ff:
data.append(0xc0 + UInt8(truncatingIfNeeded: c.value >> 6))
data.append(0x80 + UInt8(truncatingIfNeeded: c.value & 0x3f))
case 0x800...0xffff:
data.append(0xe0 + UInt8(truncatingIfNeeded: c.value >> 12))
data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 6) & 0x3f))
data.append(0x80 + UInt8(truncatingIfNeeded: c.value & 0x3f))
default:
data.append(0xf0 + UInt8(truncatingIfNeeded: c.value >> 18))
data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 12) & 0x3f))
data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 6) & 0x3f))
data.append(0x80 + UInt8(truncatingIfNeeded: c.value & 0x3f))
}
}
data.append(asciiDoubleQuote)
}
/// Append a bytes value using protobuf JSON Base-64 encoding.
internal mutating func putBytesValue(value: Data) {
data.append(asciiDoubleQuote)
if value.count > 0 {
value.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
if let p = body.baseAddress, body.count > 0 {
var t: Int = 0
var bytesInGroup: Int = 0
for i in 0..<body.count {
if bytesInGroup == 3 {
data.append(base64Digits[(t >> 18) & 63])
data.append(base64Digits[(t >> 12) & 63])
data.append(base64Digits[(t >> 6) & 63])
data.append(base64Digits[t & 63])
t = 0
bytesInGroup = 0
}
t = (t << 8) + Int(p[i])
bytesInGroup += 1
}
switch bytesInGroup {
case 3:
data.append(base64Digits[(t >> 18) & 63])
data.append(base64Digits[(t >> 12) & 63])
data.append(base64Digits[(t >> 6) & 63])
data.append(base64Digits[t & 63])
case 2:
t <<= 8
data.append(base64Digits[(t >> 18) & 63])
data.append(base64Digits[(t >> 12) & 63])
data.append(base64Digits[(t >> 6) & 63])
data.append(asciiEquals)
case 1:
t <<= 16
data.append(base64Digits[(t >> 18) & 63])
data.append(base64Digits[(t >> 12) & 63])
data.append(asciiEquals)
data.append(asciiEquals)
default:
break
}
}
}
}
data.append(asciiDoubleQuote)
}
}

View File

@ -0,0 +1,35 @@
// Sources/SwiftProtobuf/JSONEncodingError.swift - Error constants
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Enum constants that identify the particular error.
///
// -----------------------------------------------------------------------------
public enum JSONEncodingError: Error {
/// Any fields that were decoded from binary format cannot be
/// re-encoded into JSON unless the object they hold is a
/// well-known type or a type registered with via
/// Google_Protobuf_Any.register()
case anyTranscodeFailure
/// Timestamp values can only be JSON encoded if they hold a value
/// between 0001-01-01Z00:00:00 and 9999-12-31Z23:59:59.
case timestampRange
/// Duration values can only be JSON encoded if they hold a value
/// less than +/- 100 years.
case durationRange
/// Field masks get edited when converting between JSON and protobuf
case fieldMaskConversion
/// Field names were not compiled into the binary
case missingFieldNames
/// Instances of `Google_Protobuf_Value` can only be encoded if they have a
/// valid `kind` (that is, they represent a null value, number, boolean,
/// string, struct, or list).
case missingValue
}

View File

@ -0,0 +1,26 @@
// Sources/SwiftProtobuf/JSONEncodingOptions.swift - JSON encoding options
//
// Copyright (c) 2014 - 2018 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// JSON encoding options
///
// -----------------------------------------------------------------------------
/// Options for JSONEncoding.
public struct JSONEncodingOptions {
/// Always print enums as ints. By default they are printed as strings.
public var alwaysPrintEnumsAsInts: Bool = false
/// Whether to preserve proto field names.
/// By default they are converted to JSON(lowerCamelCase) names.
public var preserveProtoFieldNames: Bool = false
public init() {}
}

View File

@ -0,0 +1,404 @@
// Sources/SwiftProtobuf/JSONEncodingVisitor.swift - JSON encoding visitor
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Visitor that writes a message in JSON format.
///
// -----------------------------------------------------------------------------
import Foundation
/// Visitor that serializes a message into JSON format.
internal struct JSONEncodingVisitor: Visitor {
private var encoder = JSONEncoder()
private var nameMap: _NameMap
private var extensions: ExtensionFieldValueSet?
private let options: JSONEncodingOptions
/// The JSON text produced by the visitor, as raw UTF8 bytes.
var dataResult: Data {
return encoder.dataResult
}
/// The JSON text produced by the visitor, as a String.
internal var stringResult: String {
return encoder.stringResult
}
/// Creates a new visitor for serializing a message of the given type to JSON
/// format.
init(type: Message.Type, options: JSONEncodingOptions) throws {
if let nameProviding = type as? _ProtoNameProviding.Type {
self.nameMap = nameProviding._protobuf_nameMap
} else {
throw JSONEncodingError.missingFieldNames
}
self.options = options
}
mutating func startArray() {
encoder.startArray()
}
mutating func endArray() {
encoder.endArray()
}
mutating func startObject(message: Message) {
self.extensions = (message as? ExtensibleMessage)?._protobuf_extensionFieldValues
encoder.startObject()
}
mutating func startArrayObject(message: Message) {
self.extensions = (message as? ExtensibleMessage)?._protobuf_extensionFieldValues
encoder.startArrayObject()
}
mutating func endObject() {
encoder.endObject()
}
mutating func encodeField(name: String, stringValue value: String) {
encoder.startField(name: name)
encoder.putStringValue(value: value)
}
mutating func encodeField(name: String, jsonText text: String) {
encoder.startField(name: name)
encoder.append(text: text)
}
mutating func visitUnknown(bytes: Data) throws {
// JSON encoding has no provision for carrying proto2 unknown fields.
}
mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putFloatValue(value: value)
}
mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putDoubleValue(value: value)
}
mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putInt32(value: value)
}
mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putInt64(value: value)
}
mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putUInt32(value: value)
}
mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putUInt64(value: value)
}
mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putUInt32(value: value)
}
mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putInt32(value: value)
}
mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putBoolValue(value: value)
}
mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putStringValue(value: value)
}
mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.putBytesValue(value: value)
}
private mutating func _visitRepeated<T>(
value: [T],
fieldNumber: Int,
encode: (inout JSONEncoder, T) throws -> ()
) throws {
assert(!value.isEmpty)
try startField(for: fieldNumber)
var comma = false
encoder.startArray()
for v in value {
if comma {
encoder.comma()
}
comma = true
try encode(&encoder, v)
}
encoder.endArray()
}
mutating func visitSingularEnumField<E: Enum>(value: E, fieldNumber: Int) throws {
try startField(for: fieldNumber)
if let e = value as? _CustomJSONCodable {
let json = try e.encodedJSONString(options: options)
encoder.append(text: json)
} else if !options.alwaysPrintEnumsAsInts, let n = value.name {
encoder.appendQuoted(name: n)
} else {
encoder.putEnumInt(value: value.rawValue)
}
}
mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) throws {
try startField(for: fieldNumber)
if let m = value as? _CustomJSONCodable {
let json = try m.encodedJSONString(options: options)
encoder.append(text: json)
} else if let newNameMap = (M.self as? _ProtoNameProviding.Type)?._protobuf_nameMap {
// Preserve outer object's name and extension maps; restore them before returning
let oldNameMap = self.nameMap
let oldExtensions = self.extensions
defer {
self.nameMap = oldNameMap
self.extensions = oldExtensions
}
// Install inner object's name and extension maps
self.nameMap = newNameMap
startObject(message: value)
try value.traverse(visitor: &self)
endObject()
} else {
throw JSONEncodingError.missingFieldNames
}
}
mutating func visitSingularGroupField<G: Message>(value: G, fieldNumber: Int) throws {
// Google does not serialize groups into JSON
}
mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws {
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Float) in
encoder.putFloatValue(value: v)
}
}
mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws {
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Double) in
encoder.putDoubleValue(value: v)
}
}
mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws {
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Int32) in
encoder.putInt32(value: v)
}
}
mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws {
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Int64) in
encoder.putInt64(value: v)
}
}
mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: UInt32) in
encoder.putUInt32(value: v)
}
}
mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: UInt64) in
encoder.putUInt64(value: v)
}
}
mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws {
try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws {
try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
try visitRepeatedUInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
try visitRepeatedUInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws {
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: Bool) in
encoder.putBoolValue(value: v)
}
}
mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws {
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: String) in
encoder.putStringValue(value: v)
}
}
mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws {
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 {
if let _ = E.self as? _CustomJSONCodable.Type {
let options = self.options
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: E) throws in
let e = v as! _CustomJSONCodable
let json = try e.encodedJSONString(options: options)
encoder.append(text: json)
}
} else {
let alwaysPrintEnumsAsInts = options.alwaysPrintEnumsAsInts
try _visitRepeated(value: value, fieldNumber: fieldNumber) {
(encoder: inout JSONEncoder, v: E) throws in
if !alwaysPrintEnumsAsInts, let n = v.name {
encoder.appendQuoted(name: n)
} else {
encoder.putEnumInt(value: v.rawValue)
}
}
}
}
mutating func visitRepeatedMessageField<M: Message>(value: [M], fieldNumber: Int) throws {
assert(!value.isEmpty)
try startField(for: fieldNumber)
var comma = false
encoder.startArray()
if let _ = M.self as? _CustomJSONCodable.Type {
for v in value {
if comma {
encoder.comma()
}
comma = true
let json = try v.jsonString(options: options)
encoder.append(text: json)
}
} else if let newNameMap = (M.self as? _ProtoNameProviding.Type)?._protobuf_nameMap {
// Preserve name and extension maps for outer object
let oldNameMap = self.nameMap
let oldExtensions = self.extensions
// Restore outer object's name and extension maps before returning
defer {
self.nameMap = oldNameMap
self.extensions = oldExtensions
}
self.nameMap = newNameMap
for v in value {
startArrayObject(message: v)
try v.traverse(visitor: &self)
encoder.endObject()
}
} else {
throw JSONEncodingError.missingFieldNames
}
encoder.endArray()
}
mutating func visitRepeatedGroupField<G: Message>(value: [G], fieldNumber: Int) throws {
assert(!value.isEmpty)
// Google does not serialize groups into JSON
}
// Packed fields are handled the same as non-packed fields, so JSON just
// relies on the default implementations in Visitor.swift
mutating func visitMapField<KeyType, ValueType: MapValueType>(fieldType: _ProtobufMap<KeyType, ValueType>.Type, value: _ProtobufMap<KeyType, ValueType>.BaseType, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.append(text: "{")
var mapVisitor = JSONMapEncodingVisitor(encoder: encoder, options: options)
for (k,v) in value {
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &mapVisitor)
try ValueType.visitSingular(value: v, fieldNumber: 2, with: &mapVisitor)
}
encoder = mapVisitor.encoder
encoder.append(text: "}")
}
mutating func visitMapField<KeyType, ValueType>(fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type, value: _ProtobufEnumMap<KeyType, ValueType>.BaseType, fieldNumber: Int) throws where ValueType.RawValue == Int {
try startField(for: fieldNumber)
encoder.append(text: "{")
var mapVisitor = JSONMapEncodingVisitor(encoder: encoder, options: options)
for (k, v) in value {
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &mapVisitor)
try mapVisitor.visitSingularEnumField(value: v, fieldNumber: 2)
}
encoder = mapVisitor.encoder
encoder.append(text: "}")
}
mutating func visitMapField<KeyType, ValueType>(fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type, value: _ProtobufMessageMap<KeyType, ValueType>.BaseType, fieldNumber: Int) throws {
try startField(for: fieldNumber)
encoder.append(text: "{")
var mapVisitor = JSONMapEncodingVisitor(encoder: encoder, options: options)
for (k,v) in value {
try KeyType.visitSingular(value: k, fieldNumber: 1, with: &mapVisitor)
try mapVisitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
encoder = mapVisitor.encoder
encoder.append(text: "}")
}
/// Helper function that throws an error if the field number could not be
/// resolved.
private mutating func startField(for number: Int) throws {
let name: _NameMap.Name?
if options.preserveProtoFieldNames {
name = nameMap.names(for: number)?.proto
} else {
name = nameMap.names(for: number)?.json
}
if let name = name {
encoder.startField(name: name)
} else if let name = extensions?[number]?.protobufExtension.fieldName {
encoder.startExtensionField(name: name)
} else {
throw JSONEncodingError.missingFieldNames
}
}
}

View File

@ -0,0 +1,174 @@
// Sources/SwiftProtobuf/JSONMapEncodingVisitor.swift - JSON map encoding visitor
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Visitor that writes out the key/value pairs for a JSON map.
///
// -----------------------------------------------------------------------------
import Foundation
/// Visitor that serializes a message into JSON map format.
///
/// This expects to alternately visit the keys and values for a JSON
/// map. It only accepts singular values. Keys should be identified
/// as `fieldNumber:1`, values should be identified as `fieldNumber:2`
///
internal struct JSONMapEncodingVisitor: SelectiveVisitor {
private var separator: StaticString?
internal var encoder: JSONEncoder
private let options: JSONEncodingOptions
init(encoder: JSONEncoder, options: JSONEncodingOptions) {
self.encoder = encoder
self.options = options
}
private mutating func startKey() {
if let s = separator {
encoder.append(staticText: s)
} else {
separator = ","
}
}
private mutating func startValue() {
encoder.append(staticText: ":")
}
mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
// Doubles/Floats can never be map keys, only values
assert(fieldNumber == 2)
startValue()
encoder.putFloatValue(value: value)
}
mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
// Doubles/Floats can never be map keys, only values
assert(fieldNumber == 2)
startValue()
encoder.putDoubleValue(value: value)
}
mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws {
if fieldNumber == 1 {
startKey()
encoder.putQuotedInt32(value: value)
} else {
startValue()
encoder.putInt32(value: value)
}
}
mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
if fieldNumber == 1 {
startKey()
} else {
startValue()
}
// Int64 fields are always quoted anyway
encoder.putInt64(value: value)
}
mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws {
if fieldNumber == 1 {
startKey()
encoder.putQuotedUInt32(value: value)
} else {
startValue()
encoder.putUInt32(value: value)
}
}
mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
if fieldNumber == 1 {
startKey()
} else {
startValue()
}
encoder.putUInt64(value: value)
}
mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws {
try visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws {
try visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
try visitSingularUInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws {
try visitSingularUInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
try visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws {
try visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
if fieldNumber == 1 {
startKey()
encoder.putQuotedBoolValue(value: value)
} else {
startValue()
encoder.putBoolValue(value: value)
}
}
mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
if fieldNumber == 1 {
startKey()
} else {
startValue()
}
encoder.putStringValue(value: value)
}
mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
// Bytes can only be map values, never keys
assert(fieldNumber == 2)
startValue()
encoder.putBytesValue(value: value)
}
mutating func visitSingularEnumField<E: Enum>(value: E, fieldNumber: Int) throws {
// Enums can only be map values, never keys
assert(fieldNumber == 2)
startValue()
if !options.alwaysPrintEnumsAsInts, let n = value.name {
encoder.putStringValue(value: String(describing: n))
} else {
encoder.putEnumInt(value: value.rawValue)
}
}
mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) throws {
// Messages can only be map values, never keys
assert(fieldNumber == 2)
startValue()
let json = try value.jsonString(options: options)
encoder.append(text: json)
}
// SelectiveVisitor will block:
// - single Groups
// - everything repeated
// - everything packed
// - all maps
// - unknown fields
// - extensions
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
// Sources/SwiftProtobuf/MathUtils.swift - Generally useful mathematical functions
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Generally useful mathematical and arithmetic functions.
///
// -----------------------------------------------------------------------------
import Foundation
/// Remainder in standard modular arithmetic (modulo). This coincides with (%)
/// when a > 0.
///
/// - Parameters:
/// - a: The dividend. Can be positive, 0 or negative.
/// - b: The divisor. This must be positive, and is an error if 0 or negative.
/// - Returns: The unique value r such that 0 <= r < b and b * q + r = a for some q.
internal func mod<T : SignedInteger>(_ a: T, _ b: T) -> T {
assert(b > 0)
let r = a % b
return r >= 0 ? r : r + b
}
/// Quotient in standard modular arithmetic (Euclidean division). This coincides
/// with (/) when a > 0.
///
/// - Parameters:
/// - a: The dividend. Can be positive, 0 or negative.
/// - b: The divisor. This must be positive, and is an error if 0 or negative.
/// - Returns: The unique value q such that for some 0 <= r < b, b * q + r = a.
internal func div<T : SignedInteger>(_ a: T, _ b: T) -> T {
assert(b > 0)
return a >= 0 ? a / b : (a + 1) / b - 1
}

View File

@ -0,0 +1,45 @@
// Sources/SwiftProtobuf/Message+AnyAdditions.swift - Any-related Message extensions
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extends the `Message` type with `Google_Protobuf_Any`-specific behavior.
///
// -----------------------------------------------------------------------------
extension Message {
/// Initialize this message from the provided `google.protobuf.Any`
/// well-known type.
///
/// This corresponds to the `unpack` method in the Google C++ API.
///
/// If the Any object was decoded from Protobuf Binary or JSON
/// format, then the enclosed field data was stored and is not
/// fully decoded until you unpack the Any object into a message.
/// As such, this method will typically need to perform a full
/// deserialization of the enclosed data and can fail for any
/// reason that deserialization can fail.
///
/// See `Google_Protobuf_Any.unpackTo()` for more discussion.
///
/// - Parameter unpackingAny: the message to decode.
/// - Parameter extensions: An `ExtensionMap` used to look up and decode any
/// extensions in this message or messages nested within this message's
/// fields.
/// - Parameter options: The BinaryDecodingOptions to use.
/// - Throws: an instance of `AnyUnpackError`, `JSONDecodingError`, or
/// `BinaryDecodingError` on failure.
public init(
unpackingAny: Google_Protobuf_Any,
extensions: ExtensionMap? = nil,
options: BinaryDecodingOptions = BinaryDecodingOptions()
) throws {
self.init()
try unpackingAny._storage.unpackTo(target: &self, extensions: extensions, options: options)
}
}

View File

@ -0,0 +1,204 @@
// Sources/SwiftProtobuf/Message+BinaryAdditions.swift - Per-type binary coding
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extensions to `Message` to provide binary coding and decoding.
///
// -----------------------------------------------------------------------------
import Foundation
/// Binary encoding and decoding methods for messages.
extension Message {
/// Returns a `Data` value containing the Protocol Buffer binary format
/// serialization of the message.
///
/// - Parameters:
/// - partial: If `false` (the default), this method will check
/// `Message.isInitialized` before encoding to verify that all required
/// fields are present. If any are missing, this method throws
/// `BinaryEncodingError.missingRequiredFields`.
/// - Returns: A `Data` value containing the binary serialization of the
/// message.
/// - Throws: `BinaryEncodingError` if encoding fails.
public func serializedData(partial: Bool = false) throws -> Data {
if !partial && !isInitialized {
throw BinaryEncodingError.missingRequiredFields
}
let requiredSize = try serializedDataSize()
var data = Data(count: requiredSize)
try data.withUnsafeMutableBytes { (body: UnsafeMutableRawBufferPointer) in
if let baseAddress = body.baseAddress, body.count > 0 {
var visitor = BinaryEncodingVisitor(forWritingInto: baseAddress)
try traverse(visitor: &visitor)
// Currently not exposing this from the api because it really would be
// an internal error in the library and should never happen.
assert(requiredSize == visitor.encoder.distance(pointer: baseAddress))
}
}
return data
}
/// Returns the size in bytes required to encode the message in binary format.
/// This is used by `serializedData()` to precalculate the size of the buffer
/// so that encoding can proceed without bounds checks or reallocation.
internal func serializedDataSize() throws -> Int {
// Note: since this api is internal, it doesn't currently worry about
// needing a partial argument to handle proto2 syntax required fields.
// If this become public, it will need that added.
var visitor = BinaryEncodingSizeVisitor()
try traverse(visitor: &visitor)
return visitor.serializedSize
}
/// Creates a new message by decoding the given `Data` value containing a
/// serialized message in Protocol Buffer binary format.
///
/// - Parameters:
/// - serializedData: The binary-encoded message data to decode.
/// - extensions: An `ExtensionMap` used to look up and decode any
/// extensions in this message or messages nested within this message's
/// fields.
/// - partial: If `false` (the default), this method will check
/// `Message.isInitialized` before encoding to verify that all required
/// fields are present. If any are missing, this method throws
/// `BinaryEncodingError.missingRequiredFields`.
/// - options: The BinaryDecodingOptions to use.
/// - Throws: `BinaryDecodingError` if decoding fails.
@inlinable
public init(
serializedData data: Data,
extensions: ExtensionMap? = nil,
partial: Bool = false,
options: BinaryDecodingOptions = BinaryDecodingOptions()
) throws {
self.init()
#if swift(>=5.0)
try merge(contiguousBytes: data, extensions: extensions, partial: partial, options: options)
#else
try merge(serializedData: data, extensions: extensions, partial: partial, options: options)
#endif
}
#if swift(>=5.0)
/// Creates a new message by decoding the given `ContiguousBytes` value
/// containing a serialized message in Protocol Buffer binary format.
///
/// - Parameters:
/// - contiguousBytes: The binary-encoded message data to decode.
/// - extensions: An `ExtensionMap` used to look up and decode any
/// extensions in this message or messages nested within this message's
/// fields.
/// - partial: If `false` (the default), this method will check
/// `Message.isInitialized` before encoding to verify that all required
/// fields are present. If any are missing, this method throws
/// `BinaryEncodingError.missingRequiredFields`.
/// - options: The BinaryDecodingOptions to use.
/// - Throws: `BinaryDecodingError` if decoding fails.
@inlinable
public init<Bytes: ContiguousBytes>(
contiguousBytes bytes: Bytes,
extensions: ExtensionMap? = nil,
partial: Bool = false,
options: BinaryDecodingOptions = BinaryDecodingOptions()
) throws {
self.init()
try merge(contiguousBytes: bytes, extensions: extensions, partial: partial, options: options)
}
#endif // #if swift(>=5.0)
/// Updates the message by decoding the given `Data` value containing a
/// serialized message in Protocol Buffer binary format into the receiver.
///
/// - Note: If this method throws an error, the message may still have been
/// partially mutated by the binary data that was decoded before the error
/// occurred.
///
/// - Parameters:
/// - serializedData: The binary-encoded message data to decode.
/// - extensions: An `ExtensionMap` used to look up and decode any
/// extensions in this message or messages nested within this message's
/// fields.
/// - partial: If `false` (the default), this method will check
/// `Message.isInitialized` before encoding to verify that all required
/// fields are present. If any are missing, this method throws
/// `BinaryEncodingError.missingRequiredFields`.
/// - options: The BinaryDecodingOptions to use.
/// - Throws: `BinaryDecodingError` if decoding fails.
@inlinable
public mutating func merge(
serializedData data: Data,
extensions: ExtensionMap? = nil,
partial: Bool = false,
options: BinaryDecodingOptions = BinaryDecodingOptions()
) throws {
#if swift(>=5.0)
try merge(contiguousBytes: data, extensions: extensions, partial: partial, options: options)
#else
try data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
try _merge(rawBuffer: body, extensions: extensions, partial: partial, options: options)
}
#endif // swift(>=5.0)
}
#if swift(>=5.0)
/// Updates the message by decoding the given `ContiguousBytes` value
/// containing a serialized message in Protocol Buffer binary format into the
/// receiver.
///
/// - Note: If this method throws an error, the message may still have been
/// partially mutated by the binary data that was decoded before the error
/// occurred.
///
/// - Parameters:
/// - contiguousBytes: The binary-encoded message data to decode.
/// - extensions: An `ExtensionMap` used to look up and decode any
/// extensions in this message or messages nested within this message's
/// fields.
/// - partial: If `false` (the default), this method will check
/// `Message.isInitialized` before encoding to verify that all required
/// fields are present. If any are missing, this method throws
/// `BinaryEncodingError.missingRequiredFields`.
/// - options: The BinaryDecodingOptions to use.
/// - Throws: `BinaryDecodingError` if decoding fails.
@inlinable
public mutating func merge<Bytes: ContiguousBytes>(
contiguousBytes bytes: Bytes,
extensions: ExtensionMap? = nil,
partial: Bool = false,
options: BinaryDecodingOptions = BinaryDecodingOptions()
) throws {
try bytes.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
try _merge(rawBuffer: body, extensions: extensions, partial: partial, options: options)
}
}
#endif // swift(>=5.0)
// Helper for `merge()`s to keep the Decoder internal to SwiftProtobuf while
// allowing the generic over ContiguousBytes to get better codegen from the
// compiler by being `@inlinable`.
@usableFromInline
internal mutating func _merge(
rawBuffer body: UnsafeRawBufferPointer,
extensions: ExtensionMap?,
partial: Bool,
options: BinaryDecodingOptions
) throws {
if let baseAddress = body.baseAddress, body.count > 0 {
var decoder = BinaryDecoder(forReadingFrom: baseAddress,
count: body.count,
options: options,
extensions: extensions)
try decoder.decodeFullMessage(message: &self)
}
if !partial && !isInitialized {
throw BinaryDecodingError.missingRequiredFields
}
}
}

View File

@ -0,0 +1,150 @@
// Sources/SwiftProtobuf/Message+JSONAdditions.swift - JSON format primitive types
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extensions to `Message` to support JSON encoding/decoding.
///
// -----------------------------------------------------------------------------
import Foundation
/// JSON encoding and decoding methods for messages.
extension Message {
/// Returns a string containing the JSON serialization of the message.
///
/// Unlike binary encoding, presence of required fields is not enforced when
/// serializing to JSON.
///
/// - Returns: A string containing the JSON serialization of the message.
/// - Parameters:
/// - options: The JSONEncodingOptions to use.
/// - Throws: `JSONEncodingError` if encoding fails.
public func jsonString(
options: JSONEncodingOptions = JSONEncodingOptions()
) throws -> String {
if let m = self as? _CustomJSONCodable {
return try m.encodedJSONString(options: options)
}
let data = try jsonUTF8Data(options: options)
return String(data: data, encoding: String.Encoding.utf8)!
}
/// Returns a Data containing the UTF-8 JSON serialization of the message.
///
/// Unlike binary encoding, presence of required fields is not enforced when
/// serializing to JSON.
///
/// - Returns: A Data containing the JSON serialization of the message.
/// - Parameters:
/// - options: The JSONEncodingOptions to use.
/// - Throws: `JSONEncodingError` if encoding fails.
public func jsonUTF8Data(
options: JSONEncodingOptions = JSONEncodingOptions()
) throws -> Data {
if let m = self as? _CustomJSONCodable {
let string = try m.encodedJSONString(options: options)
let data = string.data(using: String.Encoding.utf8)! // Cannot fail!
return data
}
var visitor = try JSONEncodingVisitor(type: Self.self, options: options)
visitor.startObject(message: self)
try traverse(visitor: &visitor)
visitor.endObject()
return visitor.dataResult
}
/// Creates a new message by decoding the given string containing a
/// serialized message in JSON format.
///
/// - Parameter jsonString: The JSON-formatted string to decode.
/// - Parameter options: The JSONDecodingOptions to use.
/// - Throws: `JSONDecodingError` if decoding fails.
public init(
jsonString: String,
options: JSONDecodingOptions = JSONDecodingOptions()
) throws {
try self.init(jsonString: jsonString, extensions: nil, options: options)
}
/// Creates a new message by decoding the given string containing a
/// serialized message in JSON format.
///
/// - Parameter jsonString: The JSON-formatted string to decode.
/// - Parameter extensions: An ExtensionMap for looking up extensions by name
/// - Parameter options: The JSONDecodingOptions to use.
/// - Throws: `JSONDecodingError` if decoding fails.
public init(
jsonString: String,
extensions: ExtensionMap? = nil,
options: JSONDecodingOptions = JSONDecodingOptions()
) throws {
if jsonString.isEmpty {
throw JSONDecodingError.truncated
}
if let data = jsonString.data(using: String.Encoding.utf8) {
try self.init(jsonUTF8Data: data, extensions: extensions, options: options)
} else {
throw JSONDecodingError.truncated
}
}
/// Creates a new message by decoding the given `Data` containing a
/// serialized message in JSON format, interpreting the data as UTF-8 encoded
/// text.
///
/// - Parameter jsonUTF8Data: The JSON-formatted data to decode, represented
/// as UTF-8 encoded text.
/// - Parameter options: The JSONDecodingOptions to use.
/// - Throws: `JSONDecodingError` if decoding fails.
public init(
jsonUTF8Data: Data,
options: JSONDecodingOptions = JSONDecodingOptions()
) throws {
try self.init(jsonUTF8Data: jsonUTF8Data, extensions: nil, options: options)
}
/// Creates a new message by decoding the given `Data` containing a
/// serialized message in JSON format, interpreting the data as UTF-8 encoded
/// text.
///
/// - Parameter jsonUTF8Data: The JSON-formatted data to decode, represented
/// as UTF-8 encoded text.
/// - Parameter extensions: The extension map to use with this decode
/// - Parameter options: The JSONDecodingOptions to use.
/// - Throws: `JSONDecodingError` if decoding fails.
public init(
jsonUTF8Data: Data,
extensions: ExtensionMap? = nil,
options: JSONDecodingOptions = JSONDecodingOptions()
) throws {
self.init()
try jsonUTF8Data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
// Empty input is valid for binary, but not for JSON.
guard body.count > 0 else {
throw JSONDecodingError.truncated
}
var decoder = JSONDecoder(source: body, options: options,
messageType: Self.self, extensions: extensions)
if decoder.scanner.skipOptionalNull() {
if let customCodable = Self.self as? _CustomJSONCodable.Type,
let message = try customCodable.decodedFromJSONNull() {
self = message as! Self
} else {
throw JSONDecodingError.illegalNull
}
} else {
try decoder.decodeFullObject(message: &self)
}
if !decoder.scanner.complete {
throw JSONDecodingError.trailingGarbage
}
}
}
}

View File

@ -0,0 +1,146 @@
// Sources/SwiftProtobuf/Array+JSONAdditions.swift - JSON format primitive types
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extensions to `Array` to support JSON encoding/decoding.
///
// -----------------------------------------------------------------------------
import Foundation
/// JSON encoding and decoding methods for arrays of messages.
extension Message {
/// Returns a string containing the JSON serialization of the messages.
///
/// Unlike binary encoding, presence of required fields is not enforced when
/// serializing to JSON.
///
/// - Returns: A string containing the JSON serialization of the messages.
/// - Parameters:
/// - collection: The list of messages to encode.
/// - options: The JSONEncodingOptions to use.
/// - Throws: `JSONEncodingError` if encoding fails.
public static func jsonString<C: Collection>(
from collection: C,
options: JSONEncodingOptions = JSONEncodingOptions()
) throws -> String where C.Iterator.Element == Self {
let data = try jsonUTF8Data(from: collection, options: options)
return String(data: data, encoding: String.Encoding.utf8)!
}
/// Returns a Data containing the UTF-8 JSON serialization of the messages.
///
/// Unlike binary encoding, presence of required fields is not enforced when
/// serializing to JSON.
///
/// - Returns: A Data containing the JSON serialization of the messages.
/// - Parameters:
/// - collection: The list of messages to encode.
/// - options: The JSONEncodingOptions to use.
/// - Throws: `JSONEncodingError` if encoding fails.
public static func jsonUTF8Data<C: Collection>(
from collection: C,
options: JSONEncodingOptions = JSONEncodingOptions()
) throws -> Data where C.Iterator.Element == Self {
var visitor = try JSONEncodingVisitor(type: Self.self, options: options)
visitor.startArray()
for message in collection {
visitor.startArrayObject(message: message)
try message.traverse(visitor: &visitor)
visitor.endObject()
}
visitor.endArray()
return visitor.dataResult
}
/// Creates a new array of messages by decoding the given string containing a
/// serialized array of messages in JSON format.
///
/// - Parameter jsonString: The JSON-formatted string to decode.
/// - Parameter options: The JSONDecodingOptions to use.
/// - Throws: `JSONDecodingError` if decoding fails.
public static func array(
fromJSONString jsonString: String,
options: JSONDecodingOptions = JSONDecodingOptions()
) throws -> [Self] {
return try self.array(fromJSONString: jsonString,
extensions: SimpleExtensionMap(),
options: options)
}
/// Creates a new array of messages by decoding the given string containing a
/// serialized array of messages in JSON format.
///
/// - Parameter jsonString: The JSON-formatted string to decode.
/// - Parameter extensions: The extension map to use with this decode
/// - Parameter options: The JSONDecodingOptions to use.
/// - Throws: `JSONDecodingError` if decoding fails.
public static func array(
fromJSONString jsonString: String,
extensions: ExtensionMap = SimpleExtensionMap(),
options: JSONDecodingOptions = JSONDecodingOptions()
) throws -> [Self] {
if jsonString.isEmpty {
throw JSONDecodingError.truncated
}
if let data = jsonString.data(using: String.Encoding.utf8) {
return try array(fromJSONUTF8Data: data, extensions: extensions, options: options)
} else {
throw JSONDecodingError.truncated
}
}
/// Creates a new array of messages by decoding the given `Data` containing a
/// serialized array of messages in JSON format, interpreting the data as
/// UTF-8 encoded text.
///
/// - Parameter jsonUTF8Data: The JSON-formatted data to decode, represented
/// as UTF-8 encoded text.
/// - Parameter options: The JSONDecodingOptions to use.
/// - Throws: `JSONDecodingError` if decoding fails.
public static func array(
fromJSONUTF8Data jsonUTF8Data: Data,
options: JSONDecodingOptions = JSONDecodingOptions()
) throws -> [Self] {
return try self.array(fromJSONUTF8Data: jsonUTF8Data,
extensions: SimpleExtensionMap(),
options: options)
}
/// Creates a new array of messages by decoding the given `Data` containing a
/// serialized array of messages in JSON format, interpreting the data as
/// UTF-8 encoded text.
///
/// - Parameter jsonUTF8Data: The JSON-formatted data to decode, represented
/// as UTF-8 encoded text.
/// - Parameter extensions: The extension map to use with this decode
/// - Parameter options: The JSONDecodingOptions to use.
/// - Throws: `JSONDecodingError` if decoding fails.
public static func array(
fromJSONUTF8Data jsonUTF8Data: Data,
extensions: ExtensionMap = SimpleExtensionMap(),
options: JSONDecodingOptions = JSONDecodingOptions()
) throws -> [Self] {
return try jsonUTF8Data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
var array = [Self]()
if body.count > 0 {
var decoder = JSONDecoder(source: body, options: options,
messageType: Self.self, extensions: extensions)
try decoder.decodeRepeatedMessageField(value: &array)
if !decoder.scanner.complete {
throw JSONDecodingError.trailingGarbage
}
}
return array
}
}
}

View File

@ -0,0 +1,88 @@
// Sources/SwiftProtobuf/Message+TextFormatAdditions.swift - Text format primitive types
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Extensions to `Message` to support text format encoding/decoding.
///
// -----------------------------------------------------------------------------
import Foundation
/// Text format encoding and decoding methods for messages.
extension Message {
/// Returns a string containing the Protocol Buffer text format serialization
/// of the message.
///
/// Unlike binary encoding, presence of required fields is not enforced when
/// serializing to text format.
///
/// - Returns: A string containing the text format serialization of the
/// message.
public func textFormatString() -> String {
// This is implemented as a separate zero-argument function
// to preserve binary compatibility.
return textFormatString(options: TextFormatEncodingOptions())
}
/// Returns a string containing the Protocol Buffer text format serialization
/// of the message.
///
/// Unlike binary encoding, presence of required fields is not enforced when
/// serializing to JSON.
///
/// - Returns: A string containing the text format serialization of the message.
/// - Parameters:
/// - options: The TextFormatEncodingOptions to use.
public func textFormatString(
options: TextFormatEncodingOptions
) -> String {
var visitor = TextFormatEncodingVisitor(message: self, options: options)
if let any = self as? Google_Protobuf_Any {
any._storage.textTraverse(visitor: &visitor)
} else {
// Although the general traversal/encoding infrastructure supports
// throwing errors (needed for JSON/Binary WKTs support, binary format
// missing required fields); TextEncoding never actually does throw.
try! traverse(visitor: &visitor)
}
return visitor.result
}
/// Creates a new message by decoding the given string containing a
/// serialized message in Protocol Buffer text format.
///
/// - Parameters:
/// - textFormatString: The text format string to decode.
/// - extensions: An `ExtensionMap` used to look up and decode any
/// extensions in this message or messages nested within this message's
/// fields.
/// - Throws: an instance of `TextFormatDecodingError` on failure.
public init(
textFormatString: String,
extensions: ExtensionMap? = nil
) throws {
self.init()
if !textFormatString.isEmpty {
if let data = textFormatString.data(using: String.Encoding.utf8) {
try data.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
if let baseAddress = body.baseAddress, body.count > 0 {
var decoder = try TextFormatDecoder(messageType: Self.self,
utf8Pointer: baseAddress,
count: body.count,
extensions: extensions)
try decodeMessage(decoder: &decoder)
if !decoder.complete {
throw TextFormatDecodingError.trailingGarbage
}
}
}
}
}
}
}

View File

@ -0,0 +1,216 @@
// Sources/SwiftProtobuf/Message.swift - Message support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
/// The protocol which all generated protobuf messages implement.
/// `Message` is the protocol type you should use whenever
/// you need an argument or variable which holds "some message".
///
/// Generated messages also implement `Hashable`, and thus `Equatable`.
/// However, the protocol conformance is declared on a different protocol.
/// This allows you to use `Message` as a type directly:
///
/// func consume(message: Message) { ... }
///
/// Instead of needing to use it as a type constraint on a generic declaration:
///
/// func consume<M: Message>(message: M) { ... }
///
/// If you need to convince the compiler that your message is `Hashable` so
/// you can insert it into a `Set` or use it as a `Dictionary` key, use
/// a generic declaration with a type constraint:
///
/// func insertIntoSet<M: Message & Hashable>(message: M) {
/// mySet.insert(message)
/// }
///
/// The actual functionality is implemented either in the generated code or in
/// default implementations of the below methods and properties.
public protocol Message: CustomDebugStringConvertible {
/// Creates a new message with all of its fields initialized to their default
/// values.
init()
// Metadata
// Basic facts about this class and the proto message it was generated from
// Used by various encoders and decoders
/// The fully-scoped name of the message from the original .proto file,
/// including any relevant package name.
static var protoMessageName: String { get }
/// True if all required fields (if any) on this message and any nested
/// messages (recursively) have values set; otherwise, false.
var isInitialized: Bool { get }
/// Some formats include enough information to transport fields that were
/// not known at generation time. When encountered, they are stored here.
var unknownFields: UnknownStorage { get set }
//
// General serialization/deserialization machinery
//
/// Decode all of the fields from the given decoder.
///
/// This is a simple loop that repeatedly gets the next field number
/// from `decoder.nextFieldNumber()` and then uses the number returned
/// and the type information from the original .proto file to decide
/// what type of data should be decoded for that field. The corresponding
/// method on the decoder is then called to get the field value.
///
/// This is the core method used by the deserialization machinery. It is
/// `public` to enable users to implement their own encoding formats by
/// conforming to `Decoder`; it should not be called otherwise.
///
/// Note that this is not specific to binary encodng; formats that use
/// textual identifiers translate those to field numbers and also go
/// through this to decode messages.
///
/// - Parameters:
/// - decoder: a `Decoder`; the `Message` will call the method
/// corresponding to the type of this field.
/// - Throws: an error on failure or type mismatch. The type of error
/// thrown depends on which decoder is used.
mutating func decodeMessage<D: Decoder>(decoder: inout D) throws
/// Traverses the fields of the message, calling the appropriate methods
/// of the passed `Visitor` object.
///
/// This is used internally by:
///
/// * Protobuf binary serialization
/// * JSON serialization (with some twists to account for specialty JSON)
/// * Protobuf Text serialization
/// * `Hashable` computation
///
/// Conceptually, serializers create visitor objects that are
/// then passed recursively to every message and field via generated
/// `traverse` methods. The details get a little involved due to
/// the need to allow particular messages to override particular
/// behaviors for specific encodings, but the general idea is quite simple.
func traverse<V: Visitor>(visitor: inout V) throws
// Standard utility properties and methods.
// Most of these are simple wrappers on top of the visitor machinery.
// They are implemented in the protocol, not in the generated structs,
// so can be overridden in user code by defining custom extensions to
// the generated struct.
#if swift(>=4.2)
/// An implementation of hash(into:) to provide conformance with the
/// `Hashable` protocol.
func hash(into hasher: inout Hasher)
#else // swift(>=4.2)
/// The hash value generated from this message's contents, for conformance
/// with the `Hashable` protocol.
var hashValue: Int { get }
#endif // swift(>=4.2)
/// Helper to compare `Message`s when not having a specific type to use
/// normal `Equatable`. `Equatable` is provided with specific generated
/// types.
func isEqualTo(message: Message) -> Bool
}
extension Message {
/// Generated proto2 messages that contain required fields, nested messages
/// that contain required fields, and/or extensions will provide their own
/// implementation of this property that tests that all required fields are
/// set. Users of the generated code SHOULD NOT override this property.
public var isInitialized: Bool {
// The generated code will include a specialization as needed.
return true
}
/// A hash based on the message's full contents.
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
var visitor = HashVisitor(hasher)
try? traverse(visitor: &visitor)
hasher = visitor.hasher
}
#else // swift(>=4.2)
public var hashValue: Int {
var visitor = HashVisitor()
try? traverse(visitor: &visitor)
return visitor.hashValue
}
#endif // swift(>=4.2)
/// A description generated by recursively visiting all fields in the message,
/// including messages.
public var debugDescription: String {
// TODO Ideally there would be something like serializeText() that can
// take a prefix so we could do something like:
// [class name](
// [text format]
// )
let className = String(reflecting: type(of: self))
let header = "\(className):\n"
return header + textFormatString()
}
/// Creates an instance of the message type on which this method is called,
/// executes the given block passing the message in as its sole `inout`
/// argument, and then returns the message.
///
/// This method acts essentially as a "builder" in that the initialization of
/// the message is captured within the block, allowing the returned value to
/// be set in an immutable variable. For example,
///
/// let msg = MyMessage.with { $0.myField = "foo" }
/// msg.myOtherField = 5 // error: msg is immutable
///
/// - Parameter populator: A block or function that populates the new message,
/// which is passed into the block as an `inout` argument.
/// - Returns: The message after execution of the block.
public static func with(
_ populator: (inout Self) throws -> ()
) rethrows -> Self {
var message = Self()
try populator(&message)
return message
}
}
/// Implementation base for all messages; not intended for client use.
///
/// In general, use `SwiftProtobuf.Message` instead when you need a variable or
/// argument that can hold any type of message. Occasionally, you can use
/// `SwiftProtobuf.Message & Equatable` or `SwiftProtobuf.Message & Hashable` as
/// generic constraints if you need to write generic code that can be applied to
/// multiple message types that uses equality tests, puts messages in a `Set`,
/// or uses them as `Dictionary` keys.
public protocol _MessageImplementationBase: Message, Hashable {
// Legacy function; no longer used, but left to maintain source compatibility.
func _protobuf_generated_isEqualTo(other: Self) -> Bool
}
extension _MessageImplementationBase {
public func isEqualTo(message: Message) -> Bool {
guard let other = message as? Self else {
return false
}
return self == other
}
// Legacy default implementation that is used by old generated code, current
// versions of the plugin/generator provide this directly, but this is here
// just to avoid breaking source compatibility.
public static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs._protobuf_generated_isEqualTo(other: rhs)
}
// Legacy function that is generated by old versions of the plugin/generator,
// defaulted to keep things simple without changing the api surface.
public func _protobuf_generated_isEqualTo(other: Self) -> Bool {
return self == other
}
}

View File

@ -0,0 +1,41 @@
// Sources/SwiftProtobuf/MessageExtension.swift - Extension support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// A 'Message Extension' is an immutable class object that describes
/// a particular extension field, including string and number
/// identifiers, serialization details, and the identity of the
/// message that is being extended.
///
// -----------------------------------------------------------------------------
/// Type-erased MessageExtension field implementation.
public protocol AnyMessageExtension {
var fieldNumber: Int { get }
var fieldName: String { get }
var messageType: Message.Type { get }
func _protobuf_newField<D: Decoder>(decoder: inout D) throws -> AnyExtensionField?
}
/// A "Message Extension" relates a particular extension field to
/// a particular message. The generic constraints allow
/// compile-time compatibility checks.
public class MessageExtension<FieldType: ExtensionField, MessageType: Message>: AnyMessageExtension {
public let fieldNumber: Int
public let fieldName: String
public let messageType: Message.Type
public init(_protobuf_fieldNumber: Int, fieldName: String) {
self.fieldNumber = _protobuf_fieldNumber
self.fieldName = fieldName
self.messageType = MessageType.self
}
public func _protobuf_newField<D: Decoder>(decoder: inout D) throws -> AnyExtensionField? {
return try FieldType(protobufExtension: self, decoder: &decoder)
}
}

View File

@ -0,0 +1,310 @@
// Sources/SwiftProtobuf/NameMap.swift - Bidirectional number/name mapping
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
/// TODO: Right now, only the NameMap and the NameDescription enum
/// (which are directly used by the generated code) are public.
/// This means that code outside the library has no way to actually
/// use this data. We should develop and publicize a suitable API
/// for that purpose. (Which might be the same as the internal API.)
/// This must be exactly the same as the corresponding code in the
/// protoc-gen-swift code generator. Changing it will break
/// compatibility of the library with older generated code.
///
/// It does not necessarily need to match protoc's JSON field naming
/// logic, however.
private func toJsonFieldName(_ s: String) -> String {
var result = String()
var capitalizeNext = false
for c in s {
if c == "_" {
capitalizeNext = true
} else if capitalizeNext {
result.append(String(c).uppercased())
capitalizeNext = false
} else {
result.append(String(c))
}
}
return result
}
/// Allocate static memory buffers to intern UTF-8
/// string data. Track the buffers and release all of those buffers
/// in case we ever get deallocated.
fileprivate class InternPool {
private var interned = [UnsafeRawBufferPointer]()
func intern(utf8: String.UTF8View) -> UnsafeRawBufferPointer {
#if swift(>=4.1)
let mutable = UnsafeMutableRawBufferPointer.allocate(byteCount: utf8.count,
alignment: MemoryLayout<UInt8>.alignment)
#else
let mutable = UnsafeMutableRawBufferPointer.allocate(count: utf8.count)
#endif
mutable.copyBytes(from: utf8)
let immutable = UnsafeRawBufferPointer(mutable)
interned.append(immutable)
return immutable
}
func intern(utf8Ptr: UnsafeBufferPointer<UInt8>) -> UnsafeRawBufferPointer {
#if swift(>=4.1)
let mutable = UnsafeMutableRawBufferPointer.allocate(byteCount: utf8Ptr.count,
alignment: MemoryLayout<UInt8>.alignment)
#else
let mutable = UnsafeMutableRawBufferPointer.allocate(count: utf8.count)
#endif
mutable.copyBytes(from: utf8Ptr)
let immutable = UnsafeRawBufferPointer(mutable)
interned.append(immutable)
return immutable
}
deinit {
for buff in interned {
#if swift(>=4.1)
buff.deallocate()
#else
let p = UnsafeMutableRawPointer(mutating: buff.baseAddress)!
p.deallocate(bytes: buff.count, alignedTo: 1)
#endif
}
}
}
#if !swift(>=4.2)
// Constants for FNV hash http://tools.ietf.org/html/draft-eastlake-fnv-03
private let i_2166136261 = Int(bitPattern: 2166136261)
private let i_16777619 = Int(16777619)
#endif
/// An immutable bidirectional mapping between field/enum-case names
/// and numbers, used to record field names for text-based
/// serialization (JSON and text). These maps are lazily instantiated
/// for each message as needed, so there is no run-time overhead for
/// users who do not use text-based serialization formats.
public struct _NameMap: ExpressibleByDictionaryLiteral {
/// An immutable interned string container. The `utf8Start` pointer
/// is guaranteed valid for the lifetime of the `NameMap` that you
/// fetched it from. Since `NameMap`s are only instantiated as
/// immutable static values, that should be the lifetime of the
/// program.
///
/// Internally, this uses `StaticString` (which refers to a fixed
/// block of UTF-8 data) where possible. In cases where the string
/// has to be computed, it caches the UTF-8 bytes in an
/// unmovable and immutable heap area.
internal struct Name: Hashable, CustomStringConvertible {
// This should not be used outside of this file, as it requires
// coordinating the lifecycle with the lifecycle of the pool
// where the raw UTF8 gets interned.
fileprivate init(staticString: StaticString, pool: InternPool) {
self.nameString = .staticString(staticString)
if staticString.hasPointerRepresentation {
self.utf8Buffer = UnsafeRawBufferPointer(start: staticString.utf8Start,
count: staticString.utf8CodeUnitCount)
} else {
self.utf8Buffer = staticString.withUTF8Buffer { pool.intern(utf8Ptr: $0) }
}
}
// This should not be used outside of this file, as it requires
// coordinating the lifecycle with the lifecycle of the pool
// where the raw UTF8 gets interned.
fileprivate init(string: String, pool: InternPool) {
let utf8 = string.utf8
self.utf8Buffer = pool.intern(utf8: utf8)
self.nameString = .string(string)
}
// This is for building a transient `Name` object sufficient for lookup purposes.
// It MUST NOT be exposed outside of this file.
fileprivate init(transientUtf8Buffer: UnsafeRawBufferPointer) {
self.nameString = .staticString("")
self.utf8Buffer = transientUtf8Buffer
}
private(set) var utf8Buffer: UnsafeRawBufferPointer
private enum NameString {
case string(String)
case staticString(StaticString)
}
private var nameString: NameString
public var description: String {
switch nameString {
case .string(let s): return s
case .staticString(let s): return s.description
}
}
#if swift(>=4.2)
public func hash(into hasher: inout Hasher) {
for byte in utf8Buffer {
hasher.combine(byte)
}
}
#else // swift(>=4.2)
public var hashValue: Int {
var h = i_2166136261
for byte in utf8Buffer {
h = (h ^ Int(byte)) &* i_16777619
}
return h
}
#endif // swift(>=4.2)
public static func ==(lhs: Name, rhs: Name) -> Bool {
if lhs.utf8Buffer.count != rhs.utf8Buffer.count {
return false
}
return lhs.utf8Buffer.elementsEqual(rhs.utf8Buffer)
}
}
/// The JSON and proto names for a particular field, enum case, or extension.
internal struct Names {
private(set) var json: Name?
private(set) var proto: Name
}
/// A description of the names for a particular field or enum case.
/// The different forms here let us minimize the amount of string
/// data that we store in the binary.
///
/// These are only used in the generated code to initialize a NameMap.
public enum NameDescription {
/// The proto (text format) name and the JSON name are the same string.
case same(proto: StaticString)
/// The JSON name can be computed from the proto string
case standard(proto: StaticString)
/// The JSON and text format names are just different.
case unique(proto: StaticString, json: StaticString)
/// Used for enum cases only to represent a value's primary proto name (the
/// first defined case) and its aliases. The JSON and text format names for
/// enums are always the same.
case aliased(proto: StaticString, aliases: [StaticString])
}
private var internPool = InternPool()
/// The mapping from field/enum-case numbers to names.
private var numberToNameMap: [Int: Names] = [:]
/// The mapping from proto/text names to field/enum-case numbers.
private var protoToNumberMap: [Name: Int] = [:]
/// The mapping from JSON names to field/enum-case numbers.
/// Note that this also contains all of the proto/text names,
/// as required by Google's spec for protobuf JSON.
private var jsonToNumberMap: [Name: Int] = [:]
/// Creates a new empty field/enum-case name/number mapping.
public init() {}
/// Build the bidirectional maps between numbers and proto/JSON names.
public init(dictionaryLiteral elements: (Int, NameDescription)...) {
for (number, description) in elements {
switch description {
case .same(proto: let p):
let protoName = Name(staticString: p, pool: internPool)
let names = Names(json: protoName, proto: protoName)
numberToNameMap[number] = names
protoToNumberMap[protoName] = number
jsonToNumberMap[protoName] = number
case .standard(proto: let p):
let protoName = Name(staticString: p, pool: internPool)
let jsonString = toJsonFieldName(protoName.description)
let jsonName = Name(string: jsonString, pool: internPool)
let names = Names(json: jsonName, proto: protoName)
numberToNameMap[number] = names
protoToNumberMap[protoName] = number
jsonToNumberMap[protoName] = number
jsonToNumberMap[jsonName] = number
case .unique(proto: let p, json: let j):
let jsonName = Name(staticString: j, pool: internPool)
let protoName = Name(staticString: p, pool: internPool)
let names = Names(json: jsonName, proto: protoName)
numberToNameMap[number] = names
protoToNumberMap[protoName] = number
jsonToNumberMap[protoName] = number
jsonToNumberMap[jsonName] = number
case .aliased(proto: let p, aliases: let aliases):
let protoName = Name(staticString: p, pool: internPool)
let names = Names(json: protoName, proto: protoName)
numberToNameMap[number] = names
protoToNumberMap[protoName] = number
jsonToNumberMap[protoName] = number
for alias in aliases {
let protoName = Name(staticString: alias, pool: internPool)
protoToNumberMap[protoName] = number
jsonToNumberMap[protoName] = number
}
}
}
}
/// Returns the name bundle for the field/enum-case with the given number, or
/// `nil` if there is no match.
internal func names(for number: Int) -> Names? {
return numberToNameMap[number]
}
/// Returns the field/enum-case number that has the given JSON name,
/// or `nil` if there is no match.
///
/// This is used by the Text format parser to look up field or enum
/// names using a direct reference to the un-decoded UTF8 bytes.
internal func number(forProtoName raw: UnsafeRawBufferPointer) -> Int? {
let n = Name(transientUtf8Buffer: raw)
return protoToNumberMap[n]
}
/// Returns the field/enum-case number that has the given JSON name,
/// or `nil` if there is no match.
///
/// This accepts a regular `String` and is used in JSON parsing
/// only when a field name or enum name was decoded from a string
/// containing backslash escapes.
///
/// JSON parsing must interpret *both* the JSON name of the
/// field/enum-case provided by the descriptor *as well as* its
/// original proto/text name.
internal func number(forJSONName name: String) -> Int? {
let utf8 = Array(name.utf8)
return utf8.withUnsafeBytes { (buffer: UnsafeRawBufferPointer) in
let n = Name(transientUtf8Buffer: buffer)
return jsonToNumberMap[n]
}
}
/// Returns the field/enum-case number that has the given JSON name,
/// or `nil` if there is no match.
///
/// This is used by the JSON parser when a field name or enum name
/// required no special processing. As a result, we can avoid
/// copying the name and look up the number using a direct reference
/// to the un-decoded UTF8 bytes.
internal func number(forJSONName raw: UnsafeRawBufferPointer) -> Int? {
let n = Name(transientUtf8Buffer: raw)
return jsonToNumberMap[n]
}
}

View File

@ -0,0 +1,23 @@
// Sources/SwiftProtobuf/ProtoNameProviding.swift - Support for accessing proto names
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
/// SwiftProtobuf Internal: Common support looking up field names.
///
/// Messages conform to this protocol to provide the proto/text and JSON field
/// names for their fields. This allows these names to be pulled out into
/// extensions in separate files so that users can omit them in release builds
/// (reducing bloat and minimizing leaks of field names).
public protocol _ProtoNameProviding {
/// The mapping between field numbers and proto/JSON field names defined in
/// the conforming message type.
static var _protobuf_nameMap: _NameMap { get }
}

View File

@ -0,0 +1,43 @@
// Sources/SwiftProtobuf/ProtobufAPIVersionCheck.swift - Version checking
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// A scheme that ensures that generated protos cannot be compiled or linked
/// against a version of the runtime with which they are not compatible.
///
/// In many cases, API changes themselves might introduce incompatibilities
/// between generated code and the runtime library, but we also want to protect
/// against cases where breaking behavioral changes (without affecting the API)
/// would cause generated code to be incompatible with a particular version of
/// the runtime.
///
// -----------------------------------------------------------------------------
/// An empty protocol that encodes the version of the runtime library.
///
/// This protocol will be replaced with one containing a different version
/// number any time that breaking changes are made to the Swift Protobuf API.
/// Combined with the protocol below, this lets us verify that generated code is
/// never compiled against a version of the API with which it is incompatible.
///
/// The version associated with a particular build of the compiler is defined as
/// `Version.compatibilityVersion` in `protoc-gen-swift`. That version and this
/// version must match for the generated protos to be compatible, so if you
/// update one, make sure to update it here and in the associated type below.
public protocol ProtobufAPIVersion_2 {}
/// This protocol is expected to be implemented by a `fileprivate` type in each
/// source file emitted by `protoc-gen-swift`. It effectively creates a binding
/// between the version of the generated code and the version of this library,
/// causing a compile-time error (with reasonable diagnostics) if they are
/// incompatible.
public protocol ProtobufAPIVersionCheck {
associatedtype Version: ProtobufAPIVersion_2
}

View File

@ -0,0 +1,39 @@
// Sources/SwiftProtobuf/ProtobufMap.swift - Map<> support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Generic type representing proto map<> fields.
///
// -----------------------------------------------------------------------------
import Foundation
/// SwiftProtobuf Internal: Support for Encoding/Decoding.
public struct _ProtobufMap<KeyType: MapKeyType, ValueType: FieldType>
{
public typealias Key = KeyType.BaseType
public typealias Value = ValueType.BaseType
public typealias BaseType = Dictionary<Key, Value>
}
/// SwiftProtobuf Internal: Support for Encoding/Decoding.
public struct _ProtobufMessageMap<KeyType: MapKeyType, ValueType: Message & Hashable>
{
public typealias Key = KeyType.BaseType
public typealias Value = ValueType
public typealias BaseType = Dictionary<Key, Value>
}
/// SwiftProtobuf Internal: Support for Encoding/Decoding.
public struct _ProtobufEnumMap<KeyType: MapKeyType, ValueType: Enum>
{
public typealias Key = KeyType.BaseType
public typealias Value = ValueType
public typealias BaseType = Dictionary<Key, Value>
}

View File

@ -0,0 +1,268 @@
// Sources/SwiftProtobuf/SelectiveVisitor.swift - Base for custom Visitors
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// A base for Visitors that only expect a subset of things to called.
///
// -----------------------------------------------------------------------------
import Foundation
/// A base for Visitors that only expects a subset of things to called.
internal protocol SelectiveVisitor: Visitor {
// Adds nothing.
}
/// Default impls for everything so things using this only have to write the
/// methods they expect. Asserts to catch developer errors, but becomes
/// nothing in release to keep code size small.
///
/// NOTE: This is an impl for *everything*. This means the default impls
/// provided by Visitor to bridge packed->repeated, repeated->singular, etc
/// won't kick in.
extension SelectiveVisitor {
internal mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularEnumField<E: Enum>(value: E, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitSingularGroupField<G: Message>(value: G, fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedMessageField<M: Message>(value: [M], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitRepeatedGroupField<G: Message>(value: [G], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitPackedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitMapField<KeyType, ValueType: MapValueType>(
fieldType: _ProtobufMap<KeyType, ValueType>.Type,
value: _ProtobufMap<KeyType, ValueType>.BaseType,
fieldNumber: Int) throws {
assert(false)
}
internal mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
value: _ProtobufEnumMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws where ValueType.RawValue == Int {
assert(false)
}
internal mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
value: _ProtobufMessageMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws {
assert(false)
}
internal mutating func visitExtensionFields(fields: ExtensionFieldValueSet, start: Int, end: Int) throws {
assert(false)
}
internal mutating func visitExtensionFieldsAsMessageSet(
fields: ExtensionFieldValueSet,
start: Int,
end: Int
) throws {
assert(false)
}
internal mutating func visitUnknown(bytes: Data) throws {
assert(false)
}
}

View File

@ -0,0 +1,112 @@
// Sources/SwiftProtobuf/SimpleExtensionMap.swift - Extension support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// A default implementation of ExtensionMap.
///
// -----------------------------------------------------------------------------
// Note: The generated code only relies on ExpressibleByArrayLiteral
public struct SimpleExtensionMap: ExtensionMap, ExpressibleByArrayLiteral, CustomDebugStringConvertible {
public typealias Element = AnyMessageExtension
// Since type objects aren't Hashable, we can't do much better than this...
internal var fields = [Int: Array<AnyMessageExtension>]()
public init() {}
public init(arrayLiteral: Element...) {
insert(contentsOf: arrayLiteral)
}
public init(_ others: SimpleExtensionMap...) {
for other in others {
formUnion(other)
}
}
public subscript(messageType: Message.Type, fieldNumber: Int) -> AnyMessageExtension? {
get {
if let l = fields[fieldNumber] {
for e in l {
if messageType == e.messageType {
return e
}
}
}
return nil
}
}
public func fieldNumberForProto(messageType: Message.Type, protoFieldName: String) -> Int? {
// TODO: Make this faster...
for (_, list) in fields {
for e in list {
if e.fieldName == protoFieldName && e.messageType == messageType {
return e.fieldNumber
}
}
}
return nil
}
public mutating func insert(_ newValue: Element) {
let fieldNumber = newValue.fieldNumber
if let l = fields[fieldNumber] {
let messageType = newValue.messageType
var newL = l.filter { return $0.messageType != messageType }
newL.append(newValue)
fields[fieldNumber] = newL
} else {
fields[fieldNumber] = [newValue]
}
}
public mutating func insert(contentsOf: [Element]) {
for e in contentsOf {
insert(e)
}
}
public mutating func formUnion(_ other: SimpleExtensionMap) {
for (fieldNumber, otherList) in other.fields {
if let list = fields[fieldNumber] {
var newList = list.filter {
for o in otherList {
if $0.messageType == o.messageType { return false }
}
return true
}
newList.append(contentsOf: otherList)
fields[fieldNumber] = newList
} else {
fields[fieldNumber] = otherList
}
}
}
public func union(_ other: SimpleExtensionMap) -> SimpleExtensionMap {
var out = self
out.formUnion(other)
return out
}
public var debugDescription: String {
var names = [String]()
for (_, list) in fields {
for e in list {
names.append("\(e.fieldName):(\(e.fieldNumber))")
}
}
let d = names.joined(separator: ",")
return "SimpleExtensionMap(\(d))"
}
}

View File

@ -0,0 +1,73 @@
// Sources/SwiftProtobuf/StringUtils.swift - String utility functions
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Utility functions for converting UTF8 bytes into Strings.
/// These functions must:
/// * Accept any valid UTF8, including a zero byte (which is
/// a valid UTF8 encoding of U+0000)
/// * Return nil for any invalid UTF8
/// * Be fast (since they're extensively used by all decoders
/// and even some of the encoders)
///
// -----------------------------------------------------------------------------
import Foundation
// Wrapper that takes a buffer and start/end offsets
internal func utf8ToString(
bytes: UnsafeRawBufferPointer,
start: UnsafeRawBufferPointer.Index,
end: UnsafeRawBufferPointer.Index
) -> String? {
return utf8ToString(bytes: bytes.baseAddress! + start, count: end - start)
}
// Swift 4 introduced new faster String facilities
// that seem to work consistently across all platforms.
// Notes on performance:
//
// The pre-verification here only takes about 10% of
// the time needed for constructing the string.
// Eliminating it would provide only a very minor
// speed improvement.
//
// On macOS, this is only about 25% faster than
// the Foundation initializer used below for Swift 3.
// On Linux, the Foundation initializer is much
// slower than on macOS, so this is a much bigger
// win there.
internal func utf8ToString(bytes: UnsafeRawPointer, count: Int) -> String? {
if count == 0 {
return String()
}
let codeUnits = UnsafeRawBufferPointer(start: bytes, count: count)
let sourceEncoding = Unicode.UTF8.self
// Verify that the UTF-8 is valid.
var p = sourceEncoding.ForwardParser()
var i = codeUnits.makeIterator()
Loop:
while true {
switch p.parseScalar(from: &i) {
case .valid(_):
break
case .error:
return nil
case .emptyInput:
break Loop
}
}
// This initializer is fast but does not reject broken
// UTF-8 (which is why we validate the UTF-8 above).
return String(decoding: codeUnits, as: sourceEncoding)
}

View File

@ -0,0 +1,713 @@
// Sources/SwiftProtobuf/TextFormatDecoder.swift - Text format decoding
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Test format decoding engine.
///
// -----------------------------------------------------------------------------
import Foundation
///
/// Provides a higher-level interface to the token stream coming
/// from a TextFormatScanner. In particular, this provides
/// single-token pushback and convenience functions for iterating
/// over complex structures.
///
internal struct TextFormatDecoder: Decoder {
internal var scanner: TextFormatScanner
private var fieldCount = 0
private var terminator: UInt8?
private var fieldNameMap: _NameMap?
private var messageType: Message.Type?
internal var complete: Bool {
mutating get {
return scanner.complete
}
}
internal init(messageType: Message.Type, utf8Pointer: UnsafeRawPointer, count: Int, extensions: ExtensionMap?) throws {
scanner = TextFormatScanner(utf8Pointer: utf8Pointer, count: count, extensions: extensions)
guard let nameProviding = (messageType as? _ProtoNameProviding.Type) else {
throw TextFormatDecodingError.missingFieldNames
}
fieldNameMap = nameProviding._protobuf_nameMap
self.messageType = messageType
}
internal init(messageType: Message.Type, scanner: TextFormatScanner, terminator: UInt8?) throws {
self.scanner = scanner
self.terminator = terminator
guard let nameProviding = (messageType as? _ProtoNameProviding.Type) else {
throw TextFormatDecodingError.missingFieldNames
}
fieldNameMap = nameProviding._protobuf_nameMap
self.messageType = messageType
}
mutating func handleConflictingOneOf() throws {
throw TextFormatDecodingError.conflictingOneOf
}
mutating func nextFieldNumber() throws -> Int? {
if let terminator = terminator {
if scanner.skipOptionalObjectEnd(terminator) {
return nil
}
}
if fieldCount > 0 {
scanner.skipOptionalSeparator()
}
if let key = try scanner.nextOptionalExtensionKey() {
// Extension key; look up in the extension registry
if let fieldNumber = scanner.extensions?.fieldNumberForProto(messageType: messageType!, protoFieldName: key) {
fieldCount += 1
return fieldNumber
} else {
throw TextFormatDecodingError.unknownField
}
} else if let fieldNumber = try scanner.nextFieldNumber(names: fieldNameMap!) {
fieldCount += 1
return fieldNumber
} else if terminator == nil {
return nil
} else {
throw TextFormatDecodingError.truncated
}
}
mutating func decodeSingularFloatField(value: inout Float) throws {
try scanner.skipRequiredColon()
value = try scanner.nextFloat()
}
mutating func decodeSingularFloatField(value: inout Float?) throws {
try scanner.skipRequiredColon()
value = try scanner.nextFloat()
}
mutating func decodeRepeatedFloatField(value: inout [Float]) throws {
try scanner.skipRequiredColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let n = try scanner.nextFloat()
value.append(n)
}
} else {
let n = try scanner.nextFloat()
value.append(n)
}
}
mutating func decodeSingularDoubleField(value: inout Double) throws {
try scanner.skipRequiredColon()
value = try scanner.nextDouble()
}
mutating func decodeSingularDoubleField(value: inout Double?) throws {
try scanner.skipRequiredColon()
value = try scanner.nextDouble()
}
mutating func decodeRepeatedDoubleField(value: inout [Double]) throws {
try scanner.skipRequiredColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let n = try scanner.nextDouble()
value.append(n)
}
} else {
let n = try scanner.nextDouble()
value.append(n)
}
}
mutating func decodeSingularInt32Field(value: inout Int32) throws {
try scanner.skipRequiredColon()
let n = try scanner.nextSInt()
if n > Int64(Int32.max) || n < Int64(Int32.min) {
throw TextFormatDecodingError.malformedNumber
}
value = Int32(truncatingIfNeeded: n)
}
mutating func decodeSingularInt32Field(value: inout Int32?) throws {
try scanner.skipRequiredColon()
let n = try scanner.nextSInt()
if n > Int64(Int32.max) || n < Int64(Int32.min) {
throw TextFormatDecodingError.malformedNumber
}
value = Int32(truncatingIfNeeded: n)
}
mutating func decodeRepeatedInt32Field(value: inout [Int32]) throws {
try scanner.skipRequiredColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let n = try scanner.nextSInt()
if n > Int64(Int32.max) || n < Int64(Int32.min) {
throw TextFormatDecodingError.malformedNumber
}
value.append(Int32(truncatingIfNeeded: n))
}
} else {
let n = try scanner.nextSInt()
if n > Int64(Int32.max) || n < Int64(Int32.min) {
throw TextFormatDecodingError.malformedNumber
}
value.append(Int32(truncatingIfNeeded: n))
}
}
mutating func decodeSingularInt64Field(value: inout Int64) throws {
try scanner.skipRequiredColon()
value = try scanner.nextSInt()
}
mutating func decodeSingularInt64Field(value: inout Int64?) throws {
try scanner.skipRequiredColon()
value = try scanner.nextSInt()
}
mutating func decodeRepeatedInt64Field(value: inout [Int64]) throws {
try scanner.skipRequiredColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let n = try scanner.nextSInt()
value.append(n)
}
} else {
let n = try scanner.nextSInt()
value.append(n)
}
}
mutating func decodeSingularUInt32Field(value: inout UInt32) throws {
try scanner.skipRequiredColon()
let n = try scanner.nextUInt()
if n > UInt64(UInt32.max) {
throw TextFormatDecodingError.malformedNumber
}
value = UInt32(truncatingIfNeeded: n)
}
mutating func decodeSingularUInt32Field(value: inout UInt32?) throws {
try scanner.skipRequiredColon()
let n = try scanner.nextUInt()
if n > UInt64(UInt32.max) {
throw TextFormatDecodingError.malformedNumber
}
value = UInt32(truncatingIfNeeded: n)
}
mutating func decodeRepeatedUInt32Field(value: inout [UInt32]) throws {
try scanner.skipRequiredColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let n = try scanner.nextUInt()
if n > UInt64(UInt32.max) {
throw TextFormatDecodingError.malformedNumber
}
value.append(UInt32(truncatingIfNeeded: n))
}
} else {
let n = try scanner.nextUInt()
if n > UInt64(UInt32.max) {
throw TextFormatDecodingError.malformedNumber
}
value.append(UInt32(truncatingIfNeeded: n))
}
}
mutating func decodeSingularUInt64Field(value: inout UInt64) throws {
try scanner.skipRequiredColon()
value = try scanner.nextUInt()
}
mutating func decodeSingularUInt64Field(value: inout UInt64?) throws {
try scanner.skipRequiredColon()
value = try scanner.nextUInt()
}
mutating func decodeRepeatedUInt64Field(value: inout [UInt64]) throws {
try scanner.skipRequiredColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let n = try scanner.nextUInt()
value.append(n)
}
} else {
let n = try scanner.nextUInt()
value.append(n)
}
}
mutating func decodeSingularSInt32Field(value: inout Int32) throws {
try decodeSingularInt32Field(value: &value)
}
mutating func decodeSingularSInt32Field(value: inout Int32?) throws {
try decodeSingularInt32Field(value: &value)
}
mutating func decodeRepeatedSInt32Field(value: inout [Int32]) throws {
try decodeRepeatedInt32Field(value: &value)
}
mutating func decodeSingularSInt64Field(value: inout Int64) throws {
try decodeSingularInt64Field(value: &value)
}
mutating func decodeSingularSInt64Field(value: inout Int64?) throws {
try decodeSingularInt64Field(value: &value)
}
mutating func decodeRepeatedSInt64Field(value: inout [Int64]) throws {
try decodeRepeatedInt64Field(value: &value)
}
mutating func decodeSingularFixed32Field(value: inout UInt32) throws {
try decodeSingularUInt32Field(value: &value)
}
mutating func decodeSingularFixed32Field(value: inout UInt32?) throws {
try decodeSingularUInt32Field(value: &value)
}
mutating func decodeRepeatedFixed32Field(value: inout [UInt32]) throws {
try decodeRepeatedUInt32Field(value: &value)
}
mutating func decodeSingularFixed64Field(value: inout UInt64) throws {
try decodeSingularUInt64Field(value: &value)
}
mutating func decodeSingularFixed64Field(value: inout UInt64?) throws {
try decodeSingularUInt64Field(value: &value)
}
mutating func decodeRepeatedFixed64Field(value: inout [UInt64]) throws {
try decodeRepeatedUInt64Field(value: &value)
}
mutating func decodeSingularSFixed32Field(value: inout Int32) throws {
try decodeSingularInt32Field(value: &value)
}
mutating func decodeSingularSFixed32Field(value: inout Int32?) throws {
try decodeSingularInt32Field(value: &value)
}
mutating func decodeRepeatedSFixed32Field(value: inout [Int32]) throws {
try decodeRepeatedInt32Field(value: &value)
}
mutating func decodeSingularSFixed64Field(value: inout Int64) throws {
try decodeSingularInt64Field(value: &value)
}
mutating func decodeSingularSFixed64Field(value: inout Int64?) throws {
try decodeSingularInt64Field(value: &value)
}
mutating func decodeRepeatedSFixed64Field(value: inout [Int64]) throws {
try decodeRepeatedInt64Field(value: &value)
}
mutating func decodeSingularBoolField(value: inout Bool) throws {
try scanner.skipRequiredColon()
value = try scanner.nextBool()
}
mutating func decodeSingularBoolField(value: inout Bool?) throws {
try scanner.skipRequiredColon()
value = try scanner.nextBool()
}
mutating func decodeRepeatedBoolField(value: inout [Bool]) throws {
try scanner.skipRequiredColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let n = try scanner.nextBool()
value.append(n)
}
} else {
let n = try scanner.nextBool()
value.append(n)
}
}
mutating func decodeSingularStringField(value: inout String) throws {
try scanner.skipRequiredColon()
value = try scanner.nextStringValue()
}
mutating func decodeSingularStringField(value: inout String?) throws {
try scanner.skipRequiredColon()
value = try scanner.nextStringValue()
}
mutating func decodeRepeatedStringField(value: inout [String]) throws {
try scanner.skipRequiredColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let n = try scanner.nextStringValue()
value.append(n)
}
} else {
let n = try scanner.nextStringValue()
value.append(n)
}
}
mutating func decodeSingularBytesField(value: inout Data) throws {
try scanner.skipRequiredColon()
value = try scanner.nextBytesValue()
}
mutating func decodeSingularBytesField(value: inout Data?) throws {
try scanner.skipRequiredColon()
value = try scanner.nextBytesValue()
}
mutating func decodeRepeatedBytesField(value: inout [Data]) throws {
try scanner.skipRequiredColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let n = try scanner.nextBytesValue()
value.append(n)
}
} else {
let n = try scanner.nextBytesValue()
value.append(n)
}
}
private mutating func decodeEnum<E: Enum>() throws -> E where E.RawValue == Int {
if let name = try scanner.nextOptionalEnumName() {
if let b = E(rawUTF8: name) {
return b
} else {
throw TextFormatDecodingError.unrecognizedEnumValue
}
}
let number = try scanner.nextSInt()
if number >= Int64(Int32.min) && number <= Int64(Int32.max) {
let n = Int32(truncatingIfNeeded: number)
if let e = E(rawValue: Int(n)) {
return e
} else {
throw TextFormatDecodingError.unrecognizedEnumValue
}
}
throw TextFormatDecodingError.malformedText
}
mutating func decodeSingularEnumField<E: Enum>(value: inout E?) throws where E.RawValue == Int {
try scanner.skipRequiredColon()
let e: E = try decodeEnum()
value = e
}
mutating func decodeSingularEnumField<E: Enum>(value: inout E) throws where E.RawValue == Int {
try scanner.skipRequiredColon()
let e: E = try decodeEnum()
value = e
}
mutating func decodeRepeatedEnumField<E: Enum>(value: inout [E]) throws where E.RawValue == Int {
try scanner.skipRequiredColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let e: E = try decodeEnum()
value.append(e)
}
} else {
let e: E = try decodeEnum()
value.append(e)
}
}
mutating func decodeSingularMessageField<M: Message>(value: inout M?) throws {
_ = scanner.skipOptionalColon()
if value == nil {
value = M()
}
let terminator = try scanner.skipObjectStart()
var subDecoder = try TextFormatDecoder(messageType: M.self,scanner: scanner, terminator: terminator)
if M.self == Google_Protobuf_Any.self {
var any = value as! Google_Protobuf_Any?
try any!.decodeTextFormat(decoder: &subDecoder)
value = any as! M?
} else {
try value!.decodeMessage(decoder: &subDecoder)
}
scanner = subDecoder.scanner
}
mutating func decodeRepeatedMessageField<M: Message>(value: inout [M]) throws {
_ = scanner.skipOptionalColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
let terminator = try scanner.skipObjectStart()
var subDecoder = try TextFormatDecoder(messageType: M.self,scanner: scanner, terminator: terminator)
if M.self == Google_Protobuf_Any.self {
var message = Google_Protobuf_Any()
try message.decodeTextFormat(decoder: &subDecoder)
value.append(message as! M)
} else {
var message = M()
try message.decodeMessage(decoder: &subDecoder)
value.append(message)
}
scanner = subDecoder.scanner
}
} else {
let terminator = try scanner.skipObjectStart()
var subDecoder = try TextFormatDecoder(messageType: M.self,scanner: scanner, terminator: terminator)
if M.self == Google_Protobuf_Any.self {
var message = Google_Protobuf_Any()
try message.decodeTextFormat(decoder: &subDecoder)
value.append(message as! M)
} else {
var message = M()
try message.decodeMessage(decoder: &subDecoder)
value.append(message)
}
scanner = subDecoder.scanner
}
}
mutating func decodeSingularGroupField<G: Message>(value: inout G?) throws {
try decodeSingularMessageField(value: &value)
}
mutating func decodeRepeatedGroupField<G: Message>(value: inout [G]) throws {
try decodeRepeatedMessageField(value: &value)
}
private mutating func decodeMapEntry<KeyType, ValueType: MapValueType>(mapType: _ProtobufMap<KeyType, ValueType>.Type, value: inout _ProtobufMap<KeyType, ValueType>.BaseType) throws {
var keyField: KeyType.BaseType?
var valueField: ValueType.BaseType?
let terminator = try scanner.skipObjectStart()
while true {
if scanner.skipOptionalObjectEnd(terminator) {
if let keyField = keyField, let valueField = valueField {
value[keyField] = valueField
return
} else {
throw TextFormatDecodingError.malformedText
}
}
if let key = try scanner.nextKey() {
switch key {
case "key", "1":
try KeyType.decodeSingular(value: &keyField, from: &self)
case "value", "2":
try ValueType.decodeSingular(value: &valueField, from: &self)
default:
throw TextFormatDecodingError.unknownField
}
scanner.skipOptionalSeparator()
}
}
}
mutating func decodeMapField<KeyType, ValueType: MapValueType>(fieldType: _ProtobufMap<KeyType, ValueType>.Type, value: inout _ProtobufMap<KeyType, ValueType>.BaseType) throws {
_ = scanner.skipOptionalColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
try decodeMapEntry(mapType: fieldType, value: &value)
}
} else {
try decodeMapEntry(mapType: fieldType, value: &value)
}
}
private mutating func decodeMapEntry<KeyType, ValueType>(mapType: _ProtobufEnumMap<KeyType, ValueType>.Type, value: inout _ProtobufEnumMap<KeyType, ValueType>.BaseType) throws where ValueType.RawValue == Int {
var keyField: KeyType.BaseType?
var valueField: ValueType?
let terminator = try scanner.skipObjectStart()
while true {
if scanner.skipOptionalObjectEnd(terminator) {
if let keyField = keyField, let valueField = valueField {
value[keyField] = valueField
return
} else {
throw TextFormatDecodingError.malformedText
}
}
if let key = try scanner.nextKey() {
switch key {
case "key", "1":
try KeyType.decodeSingular(value: &keyField, from: &self)
case "value", "2":
try decodeSingularEnumField(value: &valueField)
default:
throw TextFormatDecodingError.unknownField
}
scanner.skipOptionalSeparator()
}
}
}
mutating func decodeMapField<KeyType, ValueType>(fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type, value: inout _ProtobufEnumMap<KeyType, ValueType>.BaseType) throws where ValueType.RawValue == Int {
_ = scanner.skipOptionalColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
try decodeMapEntry(mapType: fieldType, value: &value)
}
} else {
try decodeMapEntry(mapType: fieldType, value: &value)
}
}
private mutating func decodeMapEntry<KeyType, ValueType>(mapType: _ProtobufMessageMap<KeyType, ValueType>.Type, value: inout _ProtobufMessageMap<KeyType, ValueType>.BaseType) throws {
var keyField: KeyType.BaseType?
var valueField: ValueType?
let terminator = try scanner.skipObjectStart()
while true {
if scanner.skipOptionalObjectEnd(terminator) {
if let keyField = keyField, let valueField = valueField {
value[keyField] = valueField
return
} else {
throw TextFormatDecodingError.malformedText
}
}
if let key = try scanner.nextKey() {
switch key {
case "key", "1":
try KeyType.decodeSingular(value: &keyField, from: &self)
case "value", "2":
try decodeSingularMessageField(value: &valueField)
default:
throw TextFormatDecodingError.unknownField
}
scanner.skipOptionalSeparator()
}
}
}
mutating func decodeMapField<KeyType, ValueType>(fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type, value: inout _ProtobufMessageMap<KeyType, ValueType>.BaseType) throws {
_ = scanner.skipOptionalColon()
if scanner.skipOptionalBeginArray() {
var firstItem = true
while true {
if scanner.skipOptionalEndArray() {
return
}
if firstItem {
firstItem = false
} else {
try scanner.skipRequiredComma()
}
try decodeMapEntry(mapType: fieldType, value: &value)
}
} else {
try decodeMapEntry(mapType: fieldType, value: &value)
}
}
mutating func decodeExtensionField(values: inout ExtensionFieldValueSet, messageType: Message.Type, fieldNumber: Int) throws {
if let ext = scanner.extensions?[messageType, fieldNumber] {
var fieldValue = values[fieldNumber]
if fieldValue != nil {
try fieldValue!.decodeExtensionField(decoder: &self)
} else {
fieldValue = try ext._protobuf_newField(decoder: &self)
}
if fieldValue != nil {
values[fieldNumber] = fieldValue
} else {
// Really things should never get here, for TextFormat, decoding
// the value should always work or throw an error. This specific
// error result is to allow this to be more detectable.
throw TextFormatDecodingError.internalExtensionError
}
}
}
}

View File

@ -0,0 +1,40 @@
// Sources/SwiftProtobuf/TextFormatDecodingError.swift - Protobuf text format decoding errors
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Protobuf text format decoding errors
///
// -----------------------------------------------------------------------------
public enum TextFormatDecodingError: Error {
/// Text data could not be parsed
case malformedText
/// A number could not be parsed
case malformedNumber
/// Extraneous data remained after decoding should have been complete
case trailingGarbage
/// The data stopped before we expected
case truncated
/// A string was not valid UTF8
case invalidUTF8
/// The data being parsed does not match the type specified in the proto file
case schemaMismatch
/// Field names were not compiled into the binary
case missingFieldNames
/// A field identifier (name or number) was not found on the message
case unknownField
/// The enum value was not recognized
case unrecognizedEnumValue
/// Text format rejects conflicting values for the same oneof field
case conflictingOneOf
/// An internal error happened while decoding. If this is ever encountered,
/// please file an issue with SwiftProtobuf with as much details as possible
/// for what happened (proto definitions, bytes being decoded (if possible)).
case internalExtensionError
}

View File

@ -0,0 +1,296 @@
// Sources/SwiftProtobuf/TextFormatEncoder.swift - Text format encoding support
//
// Copyright (c) 2014 - 2019 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Text format serialization engine.
///
// -----------------------------------------------------------------------------
import Foundation
private let asciiSpace = UInt8(ascii: " ")
private let asciiColon = UInt8(ascii: ":")
private let asciiComma = UInt8(ascii: ",")
private let asciiMinus = UInt8(ascii: "-")
private let asciiBackslash = UInt8(ascii: "\\")
private let asciiDoubleQuote = UInt8(ascii: "\"")
private let asciiZero = UInt8(ascii: "0")
private let asciiOpenCurlyBracket = UInt8(ascii: "{")
private let asciiCloseCurlyBracket = UInt8(ascii: "}")
private let asciiOpenSquareBracket = UInt8(ascii: "[")
private let asciiCloseSquareBracket = UInt8(ascii: "]")
private let asciiNewline = UInt8(ascii: "\n")
private let asciiUpperA = UInt8(ascii: "A")
private let tabSize = 2
private let tab = [UInt8](repeating: asciiSpace, count: tabSize)
/// TextFormatEncoder has no public members.
internal struct TextFormatEncoder {
private var data = [UInt8]()
private var indentString: [UInt8] = []
var stringResult: String {
get {
return String(bytes: data, encoding: String.Encoding.utf8)!
}
}
internal mutating func append(staticText: StaticString) {
let buff = UnsafeBufferPointer(start: staticText.utf8Start, count: staticText.utf8CodeUnitCount)
data.append(contentsOf: buff)
}
internal mutating func append(name: _NameMap.Name) {
data.append(contentsOf: name.utf8Buffer)
}
internal mutating func append(bytes: [UInt8]) {
data.append(contentsOf: bytes)
}
private mutating func append(text: String) {
data.append(contentsOf: text.utf8)
}
init() {}
internal mutating func indent() {
data.append(contentsOf: indentString)
}
mutating func emitFieldName(name: UnsafeRawBufferPointer) {
indent()
data.append(contentsOf: name)
}
mutating func emitFieldName(name: StaticString) {
let buff = UnsafeRawBufferPointer(start: name.utf8Start, count: name.utf8CodeUnitCount)
emitFieldName(name: buff)
}
mutating func emitFieldName(name: [UInt8]) {
indent()
data.append(contentsOf: name)
}
mutating func emitExtensionFieldName(name: String) {
indent()
data.append(asciiOpenSquareBracket)
append(text: name)
data.append(asciiCloseSquareBracket)
}
mutating func emitFieldNumber(number: Int) {
indent()
appendUInt(value: UInt64(number))
}
mutating func startRegularField() {
append(staticText: ": ")
}
mutating func endRegularField() {
data.append(asciiNewline)
}
// In Text format, a message-valued field writes the name
// without a trailing colon:
// name_of_field {key: value key2: value2}
mutating func startMessageField() {
append(staticText: " {\n")
indentString.append(contentsOf: tab)
}
mutating func endMessageField() {
indentString.removeLast(tabSize)
indent()
append(staticText: "}\n")
}
mutating func startArray() {
data.append(asciiOpenSquareBracket)
}
mutating func arraySeparator() {
append(staticText: ", ")
}
mutating func endArray() {
data.append(asciiCloseSquareBracket)
}
mutating func putEnumValue<E: Enum>(value: E) {
if let name = value.name {
data.append(contentsOf: name.utf8Buffer)
} else {
appendInt(value: Int64(value.rawValue))
}
}
mutating func putFloatValue(value: Float) {
if value.isNaN {
append(staticText: "nan")
} else if !value.isFinite {
if value < 0 {
append(staticText: "-inf")
} else {
append(staticText: "inf")
}
} else {
data.append(contentsOf: value.debugDescription.utf8)
}
}
mutating func putDoubleValue(value: Double) {
if value.isNaN {
append(staticText: "nan")
} else if !value.isFinite {
if value < 0 {
append(staticText: "-inf")
} else {
append(staticText: "inf")
}
} else {
data.append(contentsOf: value.debugDescription.utf8)
}
}
private mutating func appendUInt(value: UInt64) {
if value >= 1000 {
appendUInt(value: value / 1000)
}
if value >= 100 {
data.append(asciiZero + UInt8((value / 100) % 10))
}
if value >= 10 {
data.append(asciiZero + UInt8((value / 10) % 10))
}
data.append(asciiZero + UInt8(value % 10))
}
private mutating func appendInt(value: Int64) {
if value < 0 {
data.append(asciiMinus)
// This is the twos-complement negation of value,
// computed in a way that won't overflow a 64-bit
// signed integer.
appendUInt(value: 1 + ~UInt64(bitPattern: value))
} else {
appendUInt(value: UInt64(bitPattern: value))
}
}
mutating func putInt64(value: Int64) {
appendInt(value: value)
}
mutating func putUInt64(value: UInt64) {
appendUInt(value: value)
}
mutating func appendUIntHex(value: UInt64, digits: Int) {
if digits == 0 {
append(staticText: "0x")
} else {
appendUIntHex(value: value >> 4, digits: digits - 1)
let d = UInt8(truncatingIfNeeded: value % 16)
data.append(d < 10 ? asciiZero + d : asciiUpperA + d - 10)
}
}
mutating func putUInt64Hex(value: UInt64, digits: Int) {
appendUIntHex(value: value, digits: digits)
}
mutating func putBoolValue(value: Bool) {
append(staticText: value ? "true" : "false")
}
mutating func putStringValue(value: String) {
data.append(asciiDoubleQuote)
for c in value.unicodeScalars {
switch c.value {
// Special two-byte escapes
case 8:
append(staticText: "\\b")
case 9:
append(staticText: "\\t")
case 10:
append(staticText: "\\n")
case 11:
append(staticText: "\\v")
case 12:
append(staticText: "\\f")
case 13:
append(staticText: "\\r")
case 34:
append(staticText: "\\\"")
case 92:
append(staticText: "\\\\")
case 0...31, 127: // Octal form for C0 control chars
data.append(asciiBackslash)
data.append(asciiZero + UInt8(c.value / 64))
data.append(asciiZero + UInt8(c.value / 8 % 8))
data.append(asciiZero + UInt8(c.value % 8))
case 0...127: // ASCII
data.append(UInt8(truncatingIfNeeded: c.value))
case 0x80...0x7ff:
data.append(0xc0 + UInt8(c.value / 64))
data.append(0x80 + UInt8(c.value % 64))
case 0x800...0xffff:
data.append(0xe0 + UInt8(truncatingIfNeeded: c.value >> 12))
data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 6) & 0x3f))
data.append(0x80 + UInt8(truncatingIfNeeded: c.value & 0x3f))
default:
data.append(0xf0 + UInt8(truncatingIfNeeded: c.value >> 18))
data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 12) & 0x3f))
data.append(0x80 + UInt8(truncatingIfNeeded: (c.value >> 6) & 0x3f))
data.append(0x80 + UInt8(truncatingIfNeeded: c.value & 0x3f))
}
}
data.append(asciiDoubleQuote)
}
mutating func putBytesValue(value: Data) {
data.append(asciiDoubleQuote)
value.withUnsafeBytes { (body: UnsafeRawBufferPointer) in
if let p = body.baseAddress, body.count > 0 {
for i in 0..<body.count {
let c = p[i]
switch c {
// Special two-byte escapes
case 8:
append(staticText: "\\b")
case 9:
append(staticText: "\\t")
case 10:
append(staticText: "\\n")
case 11:
append(staticText: "\\v")
case 12:
append(staticText: "\\f")
case 13:
append(staticText: "\\r")
case 34:
append(staticText: "\\\"")
case 92:
append(staticText: "\\\\")
case 32...126: // printable ASCII
data.append(c)
default: // Octal form for non-printable chars
data.append(asciiBackslash)
data.append(asciiZero + UInt8(c / 64))
data.append(asciiZero + UInt8(c / 8 % 8))
data.append(asciiZero + UInt8(c % 8))
}
}
}
}
data.append(asciiDoubleQuote)
}
}

View File

@ -0,0 +1,22 @@
// Sources/SwiftProtobuf/TextFormatEncodingOptions.swift - Text format encoding options
//
// Copyright (c) 2014 - 2019 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Text format encoding options
///
// -----------------------------------------------------------------------------
/// Options for TextFormatEncoding.
public struct TextFormatEncodingOptions {
/// Default: Do print unknown fields using numeric notation
public var printUnknownFields: Bool = true
public init() {}
}

View File

@ -0,0 +1,661 @@
// Sources/SwiftProtobuf/TextFormatEncodingVisitor.swift - Text format encoding support
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Text format serialization engine.
///
// -----------------------------------------------------------------------------
import Foundation
private let mapNameResolver: [Int:StaticString] = [1: "key", 2: "value"]
/// Visitor that serializes a message into protobuf text format.
internal struct TextFormatEncodingVisitor: Visitor {
private var encoder: TextFormatEncoder
private var nameMap: _NameMap?
private var nameResolver: [Int:StaticString]
private var extensions: ExtensionFieldValueSet?
private let options: TextFormatEncodingOptions
/// The protobuf text produced by the visitor.
var result: String {
return encoder.stringResult
}
/// Creates a new visitor that serializes the given message to protobuf text
/// format.
init(message: Message, options: TextFormatEncodingOptions) {
self.init(message: message, encoder: TextFormatEncoder(), options: options)
}
/// Creates a new visitor that serializes the given message to protobuf text
/// format, using an existing encoder.
private init(message: Message, encoder: TextFormatEncoder, options: TextFormatEncodingOptions) {
let nameMap: _NameMap?
if let nameProviding = message as? _ProtoNameProviding {
nameMap = type(of: nameProviding)._protobuf_nameMap
} else {
nameMap = nil
}
let extensions = (message as? ExtensibleMessage)?._protobuf_extensionFieldValues
self.init(nameMap: nameMap, nameResolver: [:], extensions: extensions, encoder: encoder, options: options)
}
private init(
nameMap: _NameMap?,
nameResolver: [Int:StaticString],
extensions: ExtensionFieldValueSet?,
encoder: TextFormatEncoder,
options: TextFormatEncodingOptions
) {
self.nameMap = nameMap
self.nameResolver = nameResolver
self.extensions = extensions
self.encoder = encoder
self.options = options
}
// TODO: This largely duplicates emitFieldName() below.
// But, it's slower so we don't want to just have emitFieldName() use
// formatFieldName(). Also, we need to measure whether the optimization
// this provides to repeated fields is worth the effort; consider just
// removing this and having repeated fields just re-run emitFieldName()
// for each item.
private func formatFieldName(lookingUp fieldNumber: Int) -> [UInt8] {
var bytes = [UInt8]()
if let protoName = nameMap?.names(for: fieldNumber)?.proto {
bytes.append(contentsOf: protoName.utf8Buffer)
} else if let protoName = nameResolver[fieldNumber] {
let buff = UnsafeBufferPointer(start: protoName.utf8Start, count: protoName.utf8CodeUnitCount)
bytes.append(contentsOf: buff)
} else if let extensionName = extensions?[fieldNumber]?.protobufExtension.fieldName {
bytes.append(UInt8(ascii: "["))
bytes.append(contentsOf: extensionName.utf8)
bytes.append(UInt8(ascii: "]"))
} else {
bytes.append(contentsOf: fieldNumber.description.utf8)
}
return bytes
}
private mutating func emitFieldName(lookingUp fieldNumber: Int) {
if let protoName = nameMap?.names(for: fieldNumber)?.proto {
encoder.emitFieldName(name: protoName.utf8Buffer)
} else if let protoName = nameResolver[fieldNumber] {
encoder.emitFieldName(name: protoName)
} else if let extensionName = extensions?[fieldNumber]?.protobufExtension.fieldName {
encoder.emitExtensionFieldName(name: extensionName)
} else {
encoder.emitFieldNumber(number: fieldNumber)
}
}
mutating func visitUnknown(bytes: Data) throws {
if options.printUnknownFields {
try bytes.withUnsafeBytes { (body: UnsafeRawBufferPointer) -> () in
if let baseAddress = body.baseAddress, body.count > 0 {
// All fields will be directly handled, so there is no need for
// the unknown field buffering/collection (when scannings to see
// if something is a message, this would be extremely wasteful).
var binaryOptions = BinaryDecodingOptions()
binaryOptions.discardUnknownFields = true
var decoder = BinaryDecoder(forReadingFrom: baseAddress,
count: body.count,
options: binaryOptions)
try visitUnknown(decoder: &decoder)
}
}
}
}
/// Helper for printing out unknowns.
///
/// The implementation tries to be "helpful" and if a length delimited field
/// appears to be a submessage, it prints it as such. However, that opens the
/// door to someone sending a message with an unknown field that is a stack
/// bomb, i.e. - it causes this code to recurse, exhausing the stack and
/// thus opening up an attack vector. To keep this "help", but avoid the
/// attack, a limit is placed on how many times it will recurse before just
/// treating the length delimted fields as bytes and not trying to decode
/// them.
private mutating func visitUnknown(
decoder: inout BinaryDecoder,
recursionBudget: Int = 10
) throws {
// This stack serves to avoid recursion for groups within groups within
// groups..., this avoid the stack attack that the message detection
// hits. No limit is placed on this because there is no stack risk with
// recursion, and because if a limit was hit, there is no other way to
// encode the group (the message field can just print as length
// delimited, groups don't have an option like that).
var groupFieldNumberStack: [Int] = []
while let tag = try decoder.getTag() {
switch tag.wireFormat {
case .varint:
encoder.emitFieldNumber(number: tag.fieldNumber)
var value: UInt64 = 0
encoder.startRegularField()
try decoder.decodeSingularUInt64Field(value: &value)
encoder.putUInt64(value: value)
encoder.endRegularField()
case .fixed64:
encoder.emitFieldNumber(number: tag.fieldNumber)
var value: UInt64 = 0
encoder.startRegularField()
try decoder.decodeSingularFixed64Field(value: &value)
encoder.putUInt64Hex(value: value, digits: 16)
encoder.endRegularField()
case .lengthDelimited:
encoder.emitFieldNumber(number: tag.fieldNumber)
var bytes = Data()
try decoder.decodeSingularBytesField(value: &bytes)
bytes.withUnsafeBytes { (body: UnsafeRawBufferPointer) -> () in
if let baseAddress = body.baseAddress, body.count > 0 {
var encodeAsBytes: Bool
if (recursionBudget > 0) {
do {
// Walk all the fields to test if it looks like a message
var testDecoder = BinaryDecoder(forReadingFrom: baseAddress,
count: body.count,
parent: decoder)
while let _ = try testDecoder.nextFieldNumber() {
}
// No error? Output the message body.
encodeAsBytes = false
var subDecoder = BinaryDecoder(forReadingFrom: baseAddress,
count: bytes.count,
parent: decoder)
encoder.startMessageField()
try visitUnknown(decoder: &subDecoder,
recursionBudget: recursionBudget - 1)
encoder.endMessageField()
} catch {
encodeAsBytes = true
}
} else {
encodeAsBytes = true
}
if (encodeAsBytes) {
encoder.startRegularField()
encoder.putBytesValue(value: bytes)
encoder.endRegularField()
}
}
}
case .startGroup:
encoder.emitFieldNumber(number: tag.fieldNumber)
encoder.startMessageField()
groupFieldNumberStack.append(tag.fieldNumber)
case .endGroup:
let groupFieldNumber = groupFieldNumberStack.popLast()
// Unknown data is scanned and verified by the
// binary parser, so this can never fail.
assert(tag.fieldNumber == groupFieldNumber)
encoder.endMessageField()
case .fixed32:
encoder.emitFieldNumber(number: tag.fieldNumber)
var value: UInt32 = 0
encoder.startRegularField()
try decoder.decodeSingularFixed32Field(value: &value)
encoder.putUInt64Hex(value: UInt64(value), digits: 8)
encoder.endRegularField()
}
}
// Unknown data is scanned and verified by the binary parser, so this can
// never fail.
assert(groupFieldNumberStack.isEmpty)
}
// Visitor.swift defines default versions for other singular field types
// that simply widen and dispatch to one of the following. Since Text format
// does not distinguish e.g., Fixed64 vs. UInt64, this is sufficient.
mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
emitFieldName(lookingUp: fieldNumber)
encoder.startRegularField()
encoder.putFloatValue(value: value)
encoder.endRegularField()
}
mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws {
emitFieldName(lookingUp: fieldNumber)
encoder.startRegularField()
encoder.putDoubleValue(value: value)
encoder.endRegularField()
}
mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws {
emitFieldName(lookingUp: fieldNumber)
encoder.startRegularField()
encoder.putInt64(value: value)
encoder.endRegularField()
}
mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws {
emitFieldName(lookingUp: fieldNumber)
encoder.startRegularField()
encoder.putUInt64(value: value)
encoder.endRegularField()
}
mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws {
emitFieldName(lookingUp: fieldNumber)
encoder.startRegularField()
encoder.putBoolValue(value: value)
encoder.endRegularField()
}
mutating func visitSingularStringField(value: String, fieldNumber: Int) throws {
emitFieldName(lookingUp: fieldNumber)
encoder.startRegularField()
encoder.putStringValue(value: value)
encoder.endRegularField()
}
mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws {
emitFieldName(lookingUp: fieldNumber)
encoder.startRegularField()
encoder.putBytesValue(value: value)
encoder.endRegularField()
}
mutating func visitSingularEnumField<E: Enum>(value: E, fieldNumber: Int) throws {
emitFieldName(lookingUp: fieldNumber)
encoder.startRegularField()
encoder.putEnumValue(value: value)
encoder.endRegularField()
}
mutating func visitSingularMessageField<M: Message>(value: M,
fieldNumber: Int) throws {
emitFieldName(lookingUp: fieldNumber)
// Cache old encoder state
let oldNameMap = self.nameMap
let oldNameResolver = self.nameResolver
let oldExtensions = self.extensions
// Update encoding state for new message
self.nameMap = (M.self as? _ProtoNameProviding.Type)?._protobuf_nameMap
self.nameResolver = [:]
self.extensions = (value as? ExtensibleMessage)?._protobuf_extensionFieldValues
// Restore state before returning
defer {
self.extensions = oldExtensions
self.nameResolver = oldNameResolver
self.nameMap = oldNameMap
}
// Encode submessage
encoder.startMessageField()
if let any = value as? Google_Protobuf_Any {
any.textTraverse(visitor: &self)
} else {
try! value.traverse(visitor: &self)
}
encoder.endMessageField()
}
// Emit the full "verbose" form of an Any. This writes the typeURL
// as a field name in `[...]` followed by the fields of the
// contained message.
internal mutating func visitAnyVerbose(value: Message, typeURL: String) {
encoder.emitExtensionFieldName(name: typeURL)
encoder.startMessageField()
var visitor = TextFormatEncodingVisitor(message: value, encoder: encoder, options: options)
if let any = value as? Google_Protobuf_Any {
any.textTraverse(visitor: &visitor)
} else {
try! value.traverse(visitor: &visitor)
}
encoder = visitor.encoder
encoder.endMessageField()
}
// Write a single special field called "#json". This
// is used for Any objects with undecoded JSON contents.
internal mutating func visitAnyJSONDataField(value: Data) {
encoder.indent()
encoder.append(staticText: "#json: ")
encoder.putBytesValue(value: value)
encoder.append(staticText: "\n")
}
// The default implementations in Visitor.swift provide the correct
// results, but we get significantly better performance by only doing
// the name lookup once for the array, rather than once for each element:
mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws {
assert(!value.isEmpty)
let fieldName = formatFieldName(lookingUp: fieldNumber)
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startRegularField()
encoder.putFloatValue(value: v)
encoder.endRegularField()
}
}
mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws {
assert(!value.isEmpty)
let fieldName = formatFieldName(lookingUp: fieldNumber)
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startRegularField()
encoder.putDoubleValue(value: v)
encoder.endRegularField()
}
}
mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let fieldName = formatFieldName(lookingUp: fieldNumber)
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startRegularField()
encoder.putInt64(value: Int64(v))
encoder.endRegularField()
}
}
mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let fieldName = formatFieldName(lookingUp: fieldNumber)
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startRegularField()
encoder.putInt64(value: v)
encoder.endRegularField()
}
}
mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
let fieldName = formatFieldName(lookingUp: fieldNumber)
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startRegularField()
encoder.putUInt64(value: UInt64(v))
encoder.endRegularField()
}
}
mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
let fieldName = formatFieldName(lookingUp: fieldNumber)
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startRegularField()
encoder.putUInt64(value: v)
encoder.endRegularField()
}
}
mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws {
try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws {
try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
try visitRepeatedUInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
try visitRepeatedUInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws {
assert(!value.isEmpty)
let fieldName = formatFieldName(lookingUp: fieldNumber)
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startRegularField()
encoder.putBoolValue(value: v)
encoder.endRegularField()
}
}
mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws {
assert(!value.isEmpty)
let fieldName = formatFieldName(lookingUp: fieldNumber)
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startRegularField()
encoder.putStringValue(value: v)
encoder.endRegularField()
}
}
mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws {
assert(!value.isEmpty)
let fieldName = formatFieldName(lookingUp: fieldNumber)
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startRegularField()
encoder.putBytesValue(value: v)
encoder.endRegularField()
}
}
mutating func visitRepeatedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws {
assert(!value.isEmpty)
let fieldName = formatFieldName(lookingUp: fieldNumber)
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startRegularField()
encoder.putEnumValue(value: v)
encoder.endRegularField()
}
}
// Messages and groups
mutating func visitRepeatedMessageField<M: Message>(value: [M],
fieldNumber: Int) throws {
assert(!value.isEmpty)
// Look up field name against outer message encoding state
let fieldName = formatFieldName(lookingUp: fieldNumber)
// Cache old encoder state
let oldNameMap = self.nameMap
let oldNameResolver = self.nameResolver
let oldExtensions = self.extensions
// Update encoding state for new message type
self.nameMap = (M.self as? _ProtoNameProviding.Type)?._protobuf_nameMap
self.nameResolver = [:]
self.extensions = (value as? ExtensibleMessage)?._protobuf_extensionFieldValues
// Iterate and encode each message
for v in value {
encoder.emitFieldName(name: fieldName)
encoder.startMessageField()
if let any = v as? Google_Protobuf_Any {
any.textTraverse(visitor: &self)
} else {
try! v.traverse(visitor: &self)
}
encoder.endMessageField()
}
// Restore state
self.extensions = oldExtensions
self.nameResolver = oldNameResolver
self.nameMap = oldNameMap
}
// Google's C++ implementation of Text format supports two formats
// for repeated numeric fields: "short" format writes the list as a
// single field with values enclosed in `[...]`, "long" format
// writes a separate field name/value for each item. They provide
// an option for callers to select which output version they prefer.
// Since this distinction mirrors the difference in Protobuf Binary
// between "packed" and "non-packed", I've chosen to use the short
// format for packed fields and the long version for repeated
// fields. This provides a clear visual distinction between these
// fields (including proto3's default use of packed) without
// introducing the baggage of a separate option.
private mutating func _visitPacked<T>(
value: [T], fieldNumber: Int,
encode: (T, inout TextFormatEncoder) -> ()
) throws {
assert(!value.isEmpty)
emitFieldName(lookingUp: fieldNumber)
encoder.startRegularField()
var firstItem = true
encoder.startArray()
for v in value {
if !firstItem {
encoder.arraySeparator()
}
encode(v, &encoder)
firstItem = false
}
encoder.endArray()
encoder.endRegularField()
}
mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws {
try _visitPacked(value: value, fieldNumber: fieldNumber) {
(v: Float, encoder: inout TextFormatEncoder) in
encoder.putFloatValue(value: v)
}
}
mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws {
try _visitPacked(value: value, fieldNumber: fieldNumber) {
(v: Double, encoder: inout TextFormatEncoder) in
encoder.putDoubleValue(value: v)
}
}
mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws {
try _visitPacked(value: value, fieldNumber: fieldNumber) {
(v: Int32, encoder: inout TextFormatEncoder) in
encoder.putInt64(value: Int64(v))
}
}
mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws {
try _visitPacked(value: value, fieldNumber: fieldNumber) {
(v: Int64, encoder: inout TextFormatEncoder) in
encoder.putInt64(value: v)
}
}
mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
try _visitPacked(value: value, fieldNumber: fieldNumber) {
(v: UInt32, encoder: inout TextFormatEncoder) in
encoder.putUInt64(value: UInt64(v))
}
}
mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
try _visitPacked(value: value, fieldNumber: fieldNumber) {
(v: UInt64, encoder: inout TextFormatEncoder) in
encoder.putUInt64(value: v)
}
}
mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws {
try visitPackedInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws {
try visitPackedInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
try visitPackedUInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
try visitPackedUInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
try visitPackedInt32Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
try visitPackedInt64Field(value: value, fieldNumber: fieldNumber)
}
mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws {
try _visitPacked(value: value, fieldNumber: fieldNumber) {
(v: Bool, encoder: inout TextFormatEncoder) in
encoder.putBoolValue(value: v)
}
}
mutating func visitPackedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws {
try _visitPacked(value: value, fieldNumber: fieldNumber) {
(v: E, encoder: inout TextFormatEncoder) in
encoder.putEnumValue(value: v)
}
}
/// Helper to encapsulate the common structure of iterating over a map
/// and encoding the keys and values.
private mutating func _visitMap<K, V>(
map: Dictionary<K, V>,
fieldNumber: Int,
coder: (inout TextFormatEncodingVisitor, K, V) throws -> ()
) throws {
for (k,v) in map {
emitFieldName(lookingUp: fieldNumber)
encoder.startMessageField()
var visitor = TextFormatEncodingVisitor(nameMap: nil, nameResolver: mapNameResolver, extensions: nil, encoder: encoder, options: options)
try coder(&visitor, k, v)
encoder = visitor.encoder
encoder.endMessageField()
}
}
mutating func visitMapField<KeyType, ValueType: MapValueType>(
fieldType: _ProtobufMap<KeyType, ValueType>.Type,
value: _ProtobufMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws {
try _visitMap(map: value, fieldNumber: fieldNumber) {
(visitor: inout TextFormatEncodingVisitor, key, value) throws -> () in
try KeyType.visitSingular(value: key, fieldNumber: 1, with: &visitor)
try ValueType.visitSingular(value: value, fieldNumber: 2, with: &visitor)
}
}
mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
value: _ProtobufEnumMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws where ValueType.RawValue == Int {
try _visitMap(map: value, fieldNumber: fieldNumber) {
(visitor: inout TextFormatEncodingVisitor, key, value) throws -> () in
try KeyType.visitSingular(value: key, fieldNumber: 1, with: &visitor)
try visitor.visitSingularEnumField(value: value, fieldNumber: 2)
}
}
mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
value: _ProtobufMessageMap<KeyType, ValueType>.BaseType,
fieldNumber: Int
) throws {
try _visitMap(map: value, fieldNumber: fieldNumber) {
(visitor: inout TextFormatEncodingVisitor, key, value) throws -> () in
try KeyType.visitSingular(value: key, fieldNumber: 1, with: &visitor)
try visitor.visitSingularMessageField(value: value, fieldNumber: 2)
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,53 @@
// Sources/SwiftProtobuf/TimeUtils.swift - Generally useful time/calendar functions
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Generally useful time/calendar functions and constants
///
// -----------------------------------------------------------------------------
let minutesPerDay: Int32 = 1440
let minutesPerHour: Int32 = 60
let secondsPerDay: Int32 = 86400
let secondsPerHour: Int32 = 3600
let secondsPerMinute: Int32 = 60
let nanosPerSecond: Int32 = 1000000000
internal func timeOfDayFromSecondsSince1970(seconds: Int64) -> (hh: Int32, mm: Int32, ss: Int32) {
let secondsSinceMidnight = Int32(mod(seconds, Int64(secondsPerDay)))
let ss = mod(secondsSinceMidnight, secondsPerMinute)
let mm = mod(div(secondsSinceMidnight, secondsPerMinute), minutesPerHour)
let hh = Int32(div(secondsSinceMidnight, secondsPerHour))
return (hh: hh, mm: mm, ss: ss)
}
internal func julianDayNumberFromSecondsSince1970(seconds: Int64) -> Int64 {
// January 1, 1970 is Julian Day Number 2440588.
// See http://aa.usno.navy.mil/faq/docs/JD_Formula.php
return div(seconds + 2440588 * Int64(secondsPerDay), Int64(secondsPerDay))
}
internal func gregorianDateFromSecondsSince1970(seconds: Int64) -> (YY: Int32, MM: Int32, DD: Int32) {
// The following implements Richards' algorithm (see the Wikipedia article
// for "Julian day").
// If you touch this code, please test it exhaustively by playing with
// Test_Timestamp.testJSON_range.
let JJ = julianDayNumberFromSecondsSince1970(seconds: seconds)
let f = JJ + 1401 + div(div(4 * JJ + 274277, 146097) * 3, 4) - 38
let e = 4 * f + 3
let g = Int64(div(mod(e, 1461), 4))
let h = 5 * g + 2
let DD = div(mod(h, 153), 5) + 1
let MM = mod(div(h, 153) + 2, 12) + 1
let YY = div(e, 1461) - 4716 + div(12 + 2 - MM, 12)
return (YY: Int32(YY), MM: Int32(MM), DD: Int32(DD))
}

View File

@ -0,0 +1,46 @@
// Sources/SwiftProtobuf/UnknownStorage.swift - Handling unknown fields
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Proto2 binary coding requires storing and recoding of unknown fields.
/// This simple support class handles that requirement. A property of this type
/// is compiled into every proto2 message.
///
// -----------------------------------------------------------------------------
import Foundation
/// Contains any unknown fields in a decoded message; that is, fields that were
/// sent on the wire but were not recognized by the generated message
/// implementation or were valid field numbers but with mismatching wire
/// formats (for example, a field encoded as a varint when a fixed32 integer
/// was expected).
public struct UnknownStorage: Equatable {
/// The raw protocol buffer binary-encoded bytes that represent the unknown
/// fields of a decoded message.
public private(set) var data = Data()
#if !swift(>=4.1)
public static func ==(lhs: UnknownStorage, rhs: UnknownStorage) -> Bool {
return lhs.data == rhs.data
}
#endif
public init() {}
internal mutating func append(protobufData: Data) {
data.append(protobufData)
}
public func traverse<V: Visitor>(visitor: inout V) throws {
if !data.isEmpty {
try visitor.visitUnknown(bytes: data)
}
}
}

View File

@ -0,0 +1,37 @@
// Sources/SwiftProtobuf/UnsafeBufferPointer+Shims.swift - Shims for UnsafeBufferPointer
//
// Copyright (c) 2019 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Shims for UnsafeBufferPointer
///
// -----------------------------------------------------------------------------
extension UnsafeMutableBufferPointer {
#if !swift(>=4.2)
internal static func allocate(capacity: Int) -> UnsafeMutableBufferPointer<Element> {
let pointer = UnsafeMutablePointer<Element>.allocate(capacity: capacity)
return UnsafeMutableBufferPointer(start: pointer, count: capacity)
}
#endif
#if !swift(>=4.1)
internal func deallocate() {
self.baseAddress?.deallocate(capacity: self.count)
}
#endif
}
extension UnsafeMutableRawBufferPointer {
#if !swift(>=4.1)
internal func copyMemory<C: Collection>(from source: C) where C.Element == UInt8 {
self.copyBytes(from: source)
}
#endif
}

View File

@ -0,0 +1,45 @@
// Sources/SwiftProtobuf/UnsafeRawPointer+Shims.swift - Shims for UnsafeRawPointer and friends
//
// Copyright (c) 2019 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Shims for UnsafeRawPointer and friends.
///
// -----------------------------------------------------------------------------
extension UnsafeRawPointer {
/// A shim subscript for UnsafeRawPointer aiming to maintain code consistency.
///
/// We can remove this shim when we rewrite the code to use buffer pointers.
internal subscript(_ offset: Int) -> UInt8 {
get {
return self.load(fromByteOffset: offset, as: UInt8.self)
}
}
}
extension UnsafeMutableRawPointer {
/// A shim subscript for UnsafeMutableRawPointer aiming to maintain code consistency.
///
/// We can remove this shim when we rewrite the code to use buffer pointers.
internal subscript(_ offset: Int) -> UInt8 {
get {
return self.load(fromByteOffset: offset, as: UInt8.self)
}
set {
self.storeBytes(of: newValue, toByteOffset: offset, as: UInt8.self)
}
}
#if !swift(>=4.1)
internal mutating func copyMemory(from source: UnsafeRawPointer, byteCount: Int) {
self.copyBytes(from: source, count: byteCount)
}
#endif
}

View File

@ -0,0 +1,108 @@
// Sources/SwiftProtobuf/Varint.swift - Varint encoding/decoding helpers
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Helper functions to varint-encode and decode integers.
///
// -----------------------------------------------------------------------------
/// Contains helper methods to varint-encode and decode integers.
internal enum Varint {
/// Computes the number of bytes that would be needed to store a 32-bit varint.
///
/// - Parameter value: The number whose varint size should be calculated.
/// - Returns: The size, in bytes, of the 32-bit varint.
static func encodedSize(of value: UInt32) -> Int {
if (value & (~0 << 7)) == 0 {
return 1
}
if (value & (~0 << 14)) == 0 {
return 2
}
if (value & (~0 << 21)) == 0 {
return 3
}
if (value & (~0 << 28)) == 0 {
return 4
}
return 5
}
/// Computes the number of bytes that would be needed to store a signed 32-bit varint, if it were
/// treated as an unsigned integer with the same bit pattern.
///
/// - Parameter value: The number whose varint size should be calculated.
/// - Returns: The size, in bytes, of the 32-bit varint.
static func encodedSize(of value: Int32) -> Int {
if value >= 0 {
return encodedSize(of: UInt32(bitPattern: value))
} else {
// Must sign-extend.
return encodedSize(of: Int64(value))
}
}
/// Computes the number of bytes that would be needed to store a 64-bit varint.
///
/// - Parameter value: The number whose varint size should be calculated.
/// - Returns: The size, in bytes, of the 64-bit varint.
static func encodedSize(of value: Int64) -> Int {
// Handle two common special cases up front.
if (value & (~0 << 7)) == 0 {
return 1
}
if value < 0 {
return 10
}
// Divide and conquer the remaining eight cases.
var value = value
var n = 2
if (value & (~0 << 35)) != 0 {
n += 4
value >>= 28
}
if (value & (~0 << 21)) != 0 {
n += 2
value >>= 14
}
if (value & (~0 << 14)) != 0 {
n += 1
}
return n
}
/// Computes the number of bytes that would be needed to store an unsigned 64-bit varint, if it
/// were treated as a signed integer witht he same bit pattern.
///
/// - Parameter value: The number whose varint size should be calculated.
/// - Returns: The size, in bytes, of the 64-bit varint.
static func encodedSize(of value: UInt64) -> Int {
return encodedSize(of: Int64(bitPattern: value))
}
/// Counts the number of distinct varints in a packed byte buffer.
static func countVarintsInBuffer(start: UnsafeRawPointer, count: Int) -> Int {
// We don't need to decode all the varints to count how many there
// are. Just observe that every varint has exactly one byte with
// value < 128. So we just count those...
var n = 0
var ints = 0
while n < count {
if start.load(fromByteOffset: n, as: UInt8.self) < 128 {
ints += 1
}
n += 1
}
return ints
}
}

View File

@ -0,0 +1,28 @@
// Sources/SwiftProtobuf/Version.swift - Runtime Version info
//
// Copyright (c) 2014 - 2017 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// A interface for exposing the version of the runtime.
///
// -----------------------------------------------------------------------------
import Foundation
// Expose version information about the library.
public struct Version {
/// Major version.
public static let major = 1
/// Minor version.
public static let minor = 12
/// Revision number.
public static let revision = 0
/// String form of the version number.
public static let versionString = "\(major).\(minor).\(revision)"
}

View File

@ -0,0 +1,725 @@
// Sources/SwiftProtobuf/Visitor.swift - Basic serialization machinery
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Protocol for traversing the object tree.
///
/// This is used by:
/// = Protobuf serialization
/// = JSON serialization (with some twists to account for specialty JSON
/// encodings)
/// = Protobuf text serialization
/// = Hashable computation
///
/// Conceptually, serializers create visitor objects that are
/// then passed recursively to every message and field via generated
/// 'traverse' methods. The details get a little involved due to
/// the need to allow particular messages to override particular
/// behaviors for specific encodings, but the general idea is quite simple.
///
// -----------------------------------------------------------------------------
import Foundation
/// This is the key interface used by the generated `traverse()` methods
/// used for serialization. It is implemented by each serialization protocol:
/// Protobuf Binary, Protobuf Text, JSON, and the Hash encoder.
public protocol Visitor {
/// Called for each non-repeated float field
///
/// A default implementation is provided that just widens the value
/// and calls `visitSingularDoubleField`
mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws
/// Called for each non-repeated double field
///
/// There is no default implementation. This must be implemented.
mutating func visitSingularDoubleField(value: Double, fieldNumber: Int) throws
/// Called for each non-repeated int32 field
///
/// A default implementation is provided that just widens the value
/// and calls `visitSingularInt64Field`
mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws
/// Called for each non-repeated int64 field
///
/// There is no default implementation. This must be implemented.
mutating func visitSingularInt64Field(value: Int64, fieldNumber: Int) throws
/// Called for each non-repeated uint32 field
///
/// A default implementation is provided that just widens the value
/// and calls `visitSingularUInt64Field`
mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws
/// Called for each non-repeated uint64 field
///
/// There is no default implementation. This must be implemented.
mutating func visitSingularUInt64Field(value: UInt64, fieldNumber: Int) throws
/// Called for each non-repeated sint32 field
///
/// A default implementation is provided that just forwards to
/// `visitSingularInt32Field`
mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws
/// Called for each non-repeated sint64 field
///
/// A default implementation is provided that just forwards to
/// `visitSingularInt64Field`
mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws
/// Called for each non-repeated fixed32 field
///
/// A default implementation is provided that just forwards to
/// `visitSingularUInt32Field`
mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws
/// Called for each non-repeated fixed64 field
///
/// A default implementation is provided that just forwards to
/// `visitSingularUInt64Field`
mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws
/// Called for each non-repeated sfixed32 field
///
/// A default implementation is provided that just forwards to
/// `visitSingularInt32Field`
mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws
/// Called for each non-repeated sfixed64 field
///
/// A default implementation is provided that just forwards to
/// `visitSingularInt64Field`
mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws
/// Called for each non-repeated bool field
///
/// There is no default implementation. This must be implemented.
mutating func visitSingularBoolField(value: Bool, fieldNumber: Int) throws
/// Called for each non-repeated string field
///
/// There is no default implementation. This must be implemented.
mutating func visitSingularStringField(value: String, fieldNumber: Int) throws
/// Called for each non-repeated bytes field
///
/// There is no default implementation. This must be implemented.
mutating func visitSingularBytesField(value: Data, fieldNumber: Int) throws
/// Called for each non-repeated enum field
///
/// There is no default implementation. This must be implemented.
mutating func visitSingularEnumField<E: Enum>(value: E, fieldNumber: Int) throws
/// Called for each non-repeated nested message field.
///
/// There is no default implementation. This must be implemented.
mutating func visitSingularMessageField<M: Message>(value: M, fieldNumber: Int) throws
/// Called for each non-repeated proto2 group field.
///
/// A default implementation is provided that simply forwards to
/// `visitSingularMessageField`. Implementors who need to handle groups
/// differently than nested messages can override this and provide distinct
/// implementations.
mutating func visitSingularGroupField<G: Message>(value: G, fieldNumber: Int) throws
// Called for each non-packed repeated float field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularFloatField` once for each item in the array.
mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws
// Called for each non-packed repeated double field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularDoubleField` once for each item in the array.
mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws
// Called for each non-packed repeated int32 field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularInt32Field` once for each item in the array.
mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws
// Called for each non-packed repeated int64 field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularInt64Field` once for each item in the array.
mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws
// Called for each non-packed repeated uint32 field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularUInt32Field` once for each item in the array.
mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws
// Called for each non-packed repeated uint64 field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularUInt64Field` once for each item in the array.
mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws
// Called for each non-packed repeated sint32 field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularSInt32Field` once for each item in the array.
mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws
// Called for each non-packed repeated sint64 field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularSInt64Field` once for each item in the array.
mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws
// Called for each non-packed repeated fixed32 field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularFixed32Field` once for each item in the array.
mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws
// Called for each non-packed repeated fixed64 field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularFixed64Field` once for each item in the array.
mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws
// Called for each non-packed repeated sfixed32 field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularSFixed32Field` once for each item in the array.
mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws
// Called for each non-packed repeated sfixed64 field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularSFixed64Field` once for each item in the array.
mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws
// Called for each non-packed repeated bool field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularBoolField` once for each item in the array.
mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws
// Called for each non-packed repeated string field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularStringField` once for each item in the array.
mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws
// Called for each non-packed repeated bytes field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularBytesField` once for each item in the array.
mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws
/// Called for each repeated, unpacked enum field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularEnumField` once for each item in the array.
mutating func visitRepeatedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws
/// Called for each repeated nested message field. The method is called once
/// with the complete array of values for the field.
///
/// A default implementation is provided that simply calls
/// `visitSingularMessageField` once for each item in the array.
mutating func visitRepeatedMessageField<M: Message>(value: [M],
fieldNumber: Int) throws
/// Called for each repeated proto2 group field.
///
/// A default implementation is provided that simply calls
/// `visitSingularGroupField` once for each item in the array.
mutating func visitRepeatedGroupField<G: Message>(value: [G], fieldNumber: Int) throws
// Called for each packed, repeated float field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws
// Called for each packed, repeated double field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws
// Called for each packed, repeated int32 field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws
// Called for each packed, repeated int64 field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws
// Called for each packed, repeated uint32 field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws
// Called for each packed, repeated uint64 field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws
// Called for each packed, repeated sint32 field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws
// Called for each packed, repeated sint64 field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws
// Called for each packed, repeated fixed32 field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws
// Called for each packed, repeated fixed64 field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws
// Called for each packed, repeated sfixed32 field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws
// Called for each packed, repeated sfixed64 field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws
// Called for each packed, repeated bool field.
///
/// This is called once with the complete array of values for
/// the field.
///
/// There is a default implementation that forwards to the non-packed
/// function.
mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws
/// Called for each repeated, packed enum field.
/// The method is called once with the complete array of values for
/// the field.
///
/// A default implementation is provided that simply forwards to
/// `visitRepeatedEnumField`. Implementors who need to handle packed fields
/// differently than unpacked fields can override this and provide distinct
/// implementations.
mutating func visitPackedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws
/// Called for each map field with primitive values. The method is
/// called once with the complete dictionary of keys/values for the
/// field.
///
/// There is no default implementation. This must be implemented.
mutating func visitMapField<KeyType, ValueType: MapValueType>(
fieldType: _ProtobufMap<KeyType, ValueType>.Type,
value: _ProtobufMap<KeyType, ValueType>.BaseType,
fieldNumber: Int) throws
/// Called for each map field with enum values. The method is called
/// once with the complete dictionary of keys/values for the field.
///
/// There is no default implementation. This must be implemented.
mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufEnumMap<KeyType, ValueType>.Type,
value: _ProtobufEnumMap<KeyType, ValueType>.BaseType,
fieldNumber: Int) throws where ValueType.RawValue == Int
/// Called for each map field with message values. The method is
/// called once with the complete dictionary of keys/values for the
/// field.
///
/// There is no default implementation. This must be implemented.
mutating func visitMapField<KeyType, ValueType>(
fieldType: _ProtobufMessageMap<KeyType, ValueType>.Type,
value: _ProtobufMessageMap<KeyType, ValueType>.BaseType,
fieldNumber: Int) throws
/// Called for each extension range.
mutating func visitExtensionFields(fields: ExtensionFieldValueSet, start: Int, end: Int) throws
/// Called for each extension range.
mutating func visitExtensionFieldsAsMessageSet(
fields: ExtensionFieldValueSet,
start: Int,
end: Int) throws
/// Called with the raw bytes that represent any unknown fields.
mutating func visitUnknown(bytes: Data) throws
}
/// Forwarding default implementations of some visitor methods, for convenience.
extension Visitor {
// Default definitions of numeric serializations.
//
// The 32-bit versions widen and delegate to 64-bit versions.
// The specialized integer codings delegate to standard Int/UInt.
//
// These "just work" for Hash and Text formats. Most of these work
// for JSON (32-bit integers are overridden to suppress quoting),
// and a few even work for Protobuf Binary (thanks to varint coding
// which erases the size difference between 32-bit and 64-bit ints).
public mutating func visitSingularFloatField(value: Float, fieldNumber: Int) throws {
try visitSingularDoubleField(value: Double(value), fieldNumber: fieldNumber)
}
public mutating func visitSingularInt32Field(value: Int32, fieldNumber: Int) throws {
try visitSingularInt64Field(value: Int64(value), fieldNumber: fieldNumber)
}
public mutating func visitSingularUInt32Field(value: UInt32, fieldNumber: Int) throws {
try visitSingularUInt64Field(value: UInt64(value), fieldNumber: fieldNumber)
}
public mutating func visitSingularSInt32Field(value: Int32, fieldNumber: Int) throws {
try visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitSingularSInt64Field(value: Int64, fieldNumber: Int) throws {
try visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitSingularFixed32Field(value: UInt32, fieldNumber: Int) throws {
try visitSingularUInt32Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitSingularFixed64Field(value: UInt64, fieldNumber: Int) throws {
try visitSingularUInt64Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitSingularSFixed32Field(value: Int32, fieldNumber: Int) throws {
try visitSingularInt32Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitSingularSFixed64Field(value: Int64, fieldNumber: Int) throws {
try visitSingularInt64Field(value: value, fieldNumber: fieldNumber)
}
// Default definitions of repeated serializations that just iterate and
// invoke the singular encoding. These "just work" for Protobuf Binary (encoder
// and size visitor), Protobuf Text, and Hash visitors. JSON format stores
// repeated values differently from singular, so overrides these.
public mutating func visitRepeatedFloatField(value: [Float], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularFloatField(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedDoubleField(value: [Double], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularDoubleField(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularInt32Field(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularInt64Field(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularUInt32Field(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularUInt64Field(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedSInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularSInt32Field(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedSInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularSInt64Field(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularFixed32Field(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularFixed64Field(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularSFixed32Field(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularSFixed64Field(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedBoolField(value: [Bool], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularBoolField(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedStringField(value: [String], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularStringField(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedBytesField(value: [Data], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularBytesField(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedEnumField<E: Enum>(value: [E], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularEnumField(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedMessageField<M: Message>(value: [M], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularMessageField(value: v, fieldNumber: fieldNumber)
}
}
public mutating func visitRepeatedGroupField<G: Message>(value: [G], fieldNumber: Int) throws {
assert(!value.isEmpty)
for v in value {
try visitSingularGroupField(value: v, fieldNumber: fieldNumber)
}
}
// Default definitions of packed serialization just defer to the
// repeated implementation. This works for Hash and JSON visitors
// (which do not distinguish packed vs. non-packed) but are
// overridden by Protobuf Binary and Text.
public mutating func visitPackedFloatField(value: [Float], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitRepeatedFloatField(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedDoubleField(value: [Double], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitRepeatedDoubleField(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitRepeatedInt32Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitRepeatedInt64Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedUInt32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitRepeatedUInt32Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedUInt64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitRepeatedUInt64Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedSInt32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitPackedInt32Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedSInt64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitPackedInt64Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedFixed32Field(value: [UInt32], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitPackedUInt32Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedFixed64Field(value: [UInt64], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitPackedUInt64Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedSFixed32Field(value: [Int32], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitPackedInt32Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedSFixed64Field(value: [Int64], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitPackedInt64Field(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedBoolField(value: [Bool], fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitRepeatedBoolField(value: value, fieldNumber: fieldNumber)
}
public mutating func visitPackedEnumField<E: Enum>(value: [E],
fieldNumber: Int) throws {
assert(!value.isEmpty)
try visitRepeatedEnumField(value: value, fieldNumber: fieldNumber)
}
// Default handling for Groups is to treat them just like messages.
// This works for Text and Hash, but is overridden by Protobuf Binary
// format (which has a different encoding for groups) and JSON
// (which explicitly ignores all groups).
public mutating func visitSingularGroupField<G: Message>(value: G,
fieldNumber: Int) throws {
try visitSingularMessageField(value: value, fieldNumber: fieldNumber)
}
// Default handling of Extensions as a MessageSet to handing them just
// as plain extensions. Formats that what custom behavior can override
// it.
public mutating func visitExtensionFieldsAsMessageSet(
fields: ExtensionFieldValueSet,
start: Int,
end: Int) throws {
try visitExtensionFields(fields: fields, start: start, end: end)
}
// Default handling for Extensions is to forward the traverse to
// the ExtensionFieldValueSet. Formats that don't care about extensions
// can override to avoid it.
/// Called for each extension range.
public mutating func visitExtensionFields(fields: ExtensionFieldValueSet, start: Int, end: Int) throws {
try fields.traverse(visitor: &self, start: start, end: end)
}
}

View File

@ -0,0 +1,70 @@
// Sources/SwiftProtobuf/WireFormat.swift - Describes proto wire formats
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Types related to binary wire formats of encoded values.
///
// -----------------------------------------------------------------------------
/// Denotes the wire format by which a value is encoded in binary form.
internal enum WireFormat: UInt8 {
case varint = 0
case fixed64 = 1
case lengthDelimited = 2
case startGroup = 3
case endGroup = 4
case fixed32 = 5
}
extension WireFormat {
/// Information about the "MessageSet" format. Used when a Message has
/// the message_set_wire_format option enabled.
///
/// Writing in MessageSet form means instead of writing the Extesions
/// normally as a simple fields, each gets written wrapped in a group:
/// repeated group Item = 1 {
/// required int32 type_id = 2;
/// required bytes message = 3;
/// }
/// Where the field number is the type_id, and the message is serilaized
/// into the bytes.
///
/// The handling of unknown fields is ill defined. In proto1, they were
/// dropped. In the C++ for proto2, since it stores them in the unknowns
/// storage, if preserves any that are length delimited data (since that's
/// how the message also goes out). While the C++ is parsing, where the
/// unknowns fall in the flow of the group, sorta decides what happens.
/// Since it is ill defined, currently SwiftProtobuf will reflect out
/// anything set in the unknownStorage. During parsing, unknowns on the
/// message are preserved, but unknowns within the group are dropped (like
/// map items). Any extension in the MessageSet that isn't in the Regisry
/// being used at parse time will remain in a group and go into the
/// Messages's unknown fields (this way it reflects back out correctly).
internal enum MessageSet {
enum FieldNumbers {
static let item = 1;
static let typeId = 2;
static let message = 3;
}
enum Tags {
static let itemStart = FieldTag(fieldNumber: FieldNumbers.item, wireFormat: .startGroup)
static let itemEnd = FieldTag(fieldNumber: FieldNumbers.item, wireFormat: .endGroup)
static let typeId = FieldTag(fieldNumber: FieldNumbers.typeId, wireFormat: .varint)
static let message = FieldTag(fieldNumber: FieldNumbers.message, wireFormat: .lengthDelimited)
}
// The size of all the tags needed to write out an Extension in MessageSet format.
static let itemTagsEncodedSize =
Tags.itemStart.encodedSize + Tags.itemEnd.encodedSize +
Tags.typeId.encodedSize +
Tags.message.encodedSize
}
}

View File

@ -0,0 +1,66 @@
// Sources/SwiftProtobuf/ZigZag.swift - ZigZag encoding/decoding helpers
//
// Copyright (c) 2014 - 2016 Apple Inc. and the project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See LICENSE.txt for license information:
// https://github.com/apple/swift-protobuf/blob/master/LICENSE.txt
//
// -----------------------------------------------------------------------------
///
/// Helper functions to ZigZag encode and decode signed integers.
///
// -----------------------------------------------------------------------------
/// Contains helper methods to ZigZag encode and decode signed integers.
internal enum ZigZag {
/// Return a 32-bit ZigZag-encoded value.
///
/// ZigZag encodes signed integers into values that can be efficiently encoded with varint.
/// (Otherwise, negative values must be sign-extended to 64 bits to be varint encoded, always
/// taking 10 bytes on the wire.)
///
/// - Parameter value: A signed 32-bit integer.
/// - Returns: An unsigned 32-bit integer representing the ZigZag-encoded value.
static func encoded(_ value: Int32) -> UInt32 {
return UInt32(bitPattern: (value << 1) ^ (value >> 31))
}
/// Return a 64-bit ZigZag-encoded value.
///
/// ZigZag encodes signed integers into values that can be efficiently encoded with varint.
/// (Otherwise, negative values must be sign-extended to 64 bits to be varint encoded, always
/// taking 10 bytes on the wire.)
///
/// - Parameter value: A signed 64-bit integer.
/// - Returns: An unsigned 64-bit integer representing the ZigZag-encoded value.
static func encoded(_ value: Int64) -> UInt64 {
return UInt64(bitPattern: (value << 1) ^ (value >> 63))
}
/// Return a 32-bit ZigZag-decoded value.
///
/// ZigZag enocdes signed integers into values that can be efficiently encoded with varint.
/// (Otherwise, negative values must be sign-extended to 64 bits to be varint encoded, always
/// taking 10 bytes on the wire.)
///
/// - Parameter value: An unsigned 32-bit ZagZag-encoded integer.
/// - Returns: The signed 32-bit decoded value.
static func decoded(_ value: UInt32) -> Int32 {
return Int32(value >> 1) ^ -Int32(value & 1)
}
/// Return a 64-bit ZigZag-decoded value.
///
/// ZigZag enocdes signed integers into values that can be efficiently encoded with varint.
/// (Otherwise, negative values must be sign-extended to 64 bits to be varint encoded, always
/// taking 10 bytes on the wire.)
///
/// - Parameter value: An unsigned 64-bit ZigZag-encoded integer.
/// - Returns: The signed 64-bit decoded value.
static func decoded(_ value: UInt64) -> Int64 {
return Int64(value >> 1) ^ -Int64(value & 1)
}
}

View File

@ -0,0 +1,241 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: google/protobuf/any.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import Foundation
// 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 you 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
}
/// `Any` contains an arbitrary serialized protocol buffer message along with a
/// URL that describes the type of the serialized message.
///
/// Protobuf library provides support to pack/unpack Any values in the form
/// of utility functions or additional generated methods of the Any type.
///
/// Example 1: Pack and unpack a message in C++.
///
/// Foo foo = ...;
/// Any any;
/// any.PackFrom(foo);
/// ...
/// if (any.UnpackTo(&foo)) {
/// ...
/// }
///
/// Example 2: Pack and unpack a message in Java.
///
/// Foo foo = ...;
/// Any any = Any.pack(foo);
/// ...
/// if (any.is(Foo.class)) {
/// foo = any.unpack(Foo.class);
/// }
///
/// Example 3: Pack and unpack a message in Python.
///
/// foo = Foo(...)
/// any = Any()
/// any.Pack(foo)
/// ...
/// if any.Is(Foo.DESCRIPTOR):
/// any.Unpack(foo)
/// ...
///
/// Example 4: Pack and unpack a message in Go
///
/// foo := &pb.Foo{...}
/// any, err := anypb.New(foo)
/// if err != nil {
/// ...
/// }
/// ...
/// foo := &pb.Foo{}
/// if err := any.UnmarshalTo(foo); err != nil {
/// ...
/// }
///
/// The pack methods provided by protobuf library will by default use
/// 'type.googleapis.com/full.type.name' as the type URL and the unpack
/// methods only use the fully qualified type name after the last '/'
/// in the type URL, for example "foo.bar.com/x/y.z" will yield type
/// name "y.z".
///
///
/// JSON
/// ====
/// The JSON representation of an `Any` value uses the regular
/// representation of the deserialized, embedded message, with an
/// additional field `@type` which contains the type URL. Example:
///
/// package google.profile;
/// message Person {
/// string first_name = 1;
/// string last_name = 2;
/// }
///
/// {
/// "@type": "type.googleapis.com/google.profile.Person",
/// "firstName": <string>,
/// "lastName": <string>
/// }
///
/// If the embedded message type is well-known and has a custom JSON
/// representation, that representation will be embedded adding a field
/// `value` which holds the custom JSON in addition to the `@type`
/// field. Example (for message [google.protobuf.Duration][]):
///
/// {
/// "@type": "type.googleapis.com/google.protobuf.Duration",
/// "value": "1.212s"
/// }
public struct Google_Protobuf_Any {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// A URL/resource name that uniquely identifies the type of the serialized
/// protocol buffer message. This string must contain at least
/// one "/" character. The last segment of the URL's path must represent
/// the fully qualified name of the type (as in
/// `path/google.protobuf.Duration`). The name should be in a canonical form
/// (e.g., leading "." is not accepted).
///
/// In practice, teams usually precompile into the binary all types that they
/// expect it to use in the context of Any. However, for URLs which use the
/// scheme `http`, `https`, or no scheme, one can optionally set up a type
/// server that maps type URLs to message definitions as follows:
///
/// * If no scheme is provided, `https` is assumed.
/// * An HTTP GET on the URL must yield a [google.protobuf.Type][]
/// value in binary format, or produce an error.
/// * Applications are allowed to cache lookup results based on the
/// URL, or have them precompiled into a binary to avoid any
/// lookup. Therefore, binary compatibility needs to be preserved
/// on changes to types. (Use versioned type names to manage
/// breaking changes.)
///
/// Note: this functionality is not currently available in the official
/// protobuf release, and it is not used for type URLs beginning with
/// type.googleapis.com.
///
/// Schemes other than `http`, `https` (or the empty scheme) might be
/// used with implementation specific semantics.
public var typeURL: String {
get {return _storage._typeURL}
set {_uniqueStorage()._typeURL = newValue}
}
/// Must be a valid serialized protocol buffer of the above specified type.
public var value: Data {
get {return _storage._value}
set {_uniqueStorage()._value = newValue}
}
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
internal var _storage = _StorageClass.defaultInstance
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "google.protobuf"
extension Google_Protobuf_Any: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Any"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .standard(proto: "type_url"),
2: .same(proto: "value"),
]
typealias _StorageClass = AnyMessageStorage
internal mutating func _uniqueStorage() -> _StorageClass {
if !isKnownUniquelyReferenced(&_storage) {
_storage = _StorageClass(copying: _storage)
}
return _storage
}
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
_ = _uniqueStorage()
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &_storage._typeURL) }()
case 2: try { try decoder.decodeSingularBytesField(value: &_storage._value) }()
default: break
}
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
try withExtendedLifetime(_storage) { (_storage: _StorageClass) in
try _storage.preTraverse()
if !_storage._typeURL.isEmpty {
try visitor.visitSingularStringField(value: _storage._typeURL, fieldNumber: 1)
}
if !_storage._value.isEmpty {
try visitor.visitSingularBytesField(value: _storage._value, fieldNumber: 2)
}
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Any, rhs: Google_Protobuf_Any) -> Bool {
if lhs._storage !== rhs._storage {
let storagesAreEqual: Bool = lhs._storage.isEqualTo(other: rhs._storage)
if !storagesAreEqual {return false}
}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

View File

@ -0,0 +1,424 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: google/protobuf/api.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import Foundation
// 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 you 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
}
/// Api is a light-weight descriptor for an API Interface.
///
/// Interfaces are also described as "protocol buffer services" in some contexts,
/// such as by the "service" keyword in a .proto file, but they are different
/// from API Services, which represent a concrete implementation of an interface
/// as opposed to simply a description of methods and bindings. They are also
/// sometimes simply referred to as "APIs" in other contexts, such as the name of
/// this message itself. See https://cloud.google.com/apis/design/glossary for
/// detailed terminology.
public struct Google_Protobuf_Api {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The fully qualified name of this interface, including package name
/// followed by the interface's simple name.
public var name: String = String()
/// The methods of this interface, in unspecified order.
public var methods: [Google_Protobuf_Method] = []
/// Any metadata attached to the interface.
public var options: [Google_Protobuf_Option] = []
/// A version string for this interface. If specified, must have the form
/// `major-version.minor-version`, as in `1.10`. If the minor version is
/// omitted, it defaults to zero. If the entire version field is empty, the
/// major version is derived from the package name, as outlined below. If the
/// field is not empty, the version in the package name will be verified to be
/// consistent with what is provided here.
///
/// The versioning schema uses [semantic
/// versioning](http://semver.org) where the major version number
/// indicates a breaking change and the minor version an additive,
/// non-breaking change. Both version numbers are signals to users
/// what to expect from different versions, and should be carefully
/// chosen based on the product plan.
///
/// The major version is also reflected in the package name of the
/// interface, which must end in `v<major-version>`, as in
/// `google.feature.v1`. For major versions 0 and 1, the suffix can
/// be omitted. Zero major versions must only be used for
/// experimental, non-GA interfaces.
public var version: String = String()
/// Source context for the protocol buffer service represented by this
/// message.
public var sourceContext: Google_Protobuf_SourceContext {
get {return _sourceContext ?? Google_Protobuf_SourceContext()}
set {_sourceContext = newValue}
}
/// Returns true if `sourceContext` has been explicitly set.
public var hasSourceContext: Bool {return self._sourceContext != nil}
/// Clears the value of `sourceContext`. Subsequent reads from it will return its default value.
public mutating func clearSourceContext() {self._sourceContext = nil}
/// Included interfaces. See [Mixin][].
public var mixins: [Google_Protobuf_Mixin] = []
/// The source syntax of the service.
public var syntax: Google_Protobuf_Syntax = .proto2
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
fileprivate var _sourceContext: Google_Protobuf_SourceContext? = nil
}
/// Method represents a method of an API interface.
public struct Google_Protobuf_Method {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The simple name of this method.
public var name: String = String()
/// A URL of the input message type.
public var requestTypeURL: String = String()
/// If true, the request is streamed.
public var requestStreaming: Bool = false
/// The URL of the output message type.
public var responseTypeURL: String = String()
/// If true, the response is streamed.
public var responseStreaming: Bool = false
/// Any metadata attached to the method.
public var options: [Google_Protobuf_Option] = []
/// The source syntax of this method.
public var syntax: Google_Protobuf_Syntax = .proto2
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// Declares an API Interface to be included in this interface. The including
/// interface must redeclare all the methods from the included interface, but
/// documentation and options are inherited as follows:
///
/// - If after comment and whitespace stripping, the documentation
/// string of the redeclared method is empty, it will be inherited
/// from the original method.
///
/// - Each annotation belonging to the service config (http,
/// visibility) which is not set in the redeclared method will be
/// inherited.
///
/// - If an http annotation is inherited, the path pattern will be
/// modified as follows. Any version prefix will be replaced by the
/// version of the including interface plus the [root][] path if
/// specified.
///
/// Example of a simple mixin:
///
/// package google.acl.v1;
/// service AccessControl {
/// // Get the underlying ACL object.
/// rpc GetAcl(GetAclRequest) returns (Acl) {
/// option (google.api.http).get = "/v1/{resource=**}:getAcl";
/// }
/// }
///
/// package google.storage.v2;
/// service Storage {
/// rpc GetAcl(GetAclRequest) returns (Acl);
///
/// // Get a data record.
/// rpc GetData(GetDataRequest) returns (Data) {
/// option (google.api.http).get = "/v2/{resource=**}";
/// }
/// }
///
/// Example of a mixin configuration:
///
/// apis:
/// - name: google.storage.v2.Storage
/// mixins:
/// - name: google.acl.v1.AccessControl
///
/// The mixin construct implies that all methods in `AccessControl` are
/// also declared with same name and request/response types in
/// `Storage`. A documentation generator or annotation processor will
/// see the effective `Storage.GetAcl` method after inheriting
/// documentation and annotations as follows:
///
/// service Storage {
/// // Get the underlying ACL object.
/// rpc GetAcl(GetAclRequest) returns (Acl) {
/// option (google.api.http).get = "/v2/{resource=**}:getAcl";
/// }
/// ...
/// }
///
/// Note how the version in the path pattern changed from `v1` to `v2`.
///
/// If the `root` field in the mixin is specified, it should be a
/// relative path under which inherited HTTP paths are placed. Example:
///
/// apis:
/// - name: google.storage.v2.Storage
/// mixins:
/// - name: google.acl.v1.AccessControl
/// root: acls
///
/// This implies the following inherited HTTP annotation:
///
/// service Storage {
/// // Get the underlying ACL object.
/// rpc GetAcl(GetAclRequest) returns (Acl) {
/// option (google.api.http).get = "/v2/acls/{resource=**}:getAcl";
/// }
/// ...
/// }
public struct Google_Protobuf_Mixin {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The fully qualified name of the interface which is included.
public var name: String = String()
/// If non-empty specifies a path under which inherited HTTP paths
/// are rooted.
public var root: String = String()
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "google.protobuf"
extension Google_Protobuf_Api: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Api"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "name"),
2: .same(proto: "methods"),
3: .same(proto: "options"),
4: .same(proto: "version"),
5: .standard(proto: "source_context"),
6: .same(proto: "mixins"),
7: .same(proto: "syntax"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &self.name) }()
case 2: try { try decoder.decodeRepeatedMessageField(value: &self.methods) }()
case 3: try { try decoder.decodeRepeatedMessageField(value: &self.options) }()
case 4: try { try decoder.decodeSingularStringField(value: &self.version) }()
case 5: try { try decoder.decodeSingularMessageField(value: &self._sourceContext) }()
case 6: try { try decoder.decodeRepeatedMessageField(value: &self.mixins) }()
case 7: try { try decoder.decodeSingularEnumField(value: &self.syntax) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.name.isEmpty {
try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
}
if !self.methods.isEmpty {
try visitor.visitRepeatedMessageField(value: self.methods, fieldNumber: 2)
}
if !self.options.isEmpty {
try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 3)
}
if !self.version.isEmpty {
try visitor.visitSingularStringField(value: self.version, fieldNumber: 4)
}
if let v = self._sourceContext {
try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
}
if !self.mixins.isEmpty {
try visitor.visitRepeatedMessageField(value: self.mixins, fieldNumber: 6)
}
if self.syntax != .proto2 {
try visitor.visitSingularEnumField(value: self.syntax, fieldNumber: 7)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Api, rhs: Google_Protobuf_Api) -> Bool {
if lhs.name != rhs.name {return false}
if lhs.methods != rhs.methods {return false}
if lhs.options != rhs.options {return false}
if lhs.version != rhs.version {return false}
if lhs._sourceContext != rhs._sourceContext {return false}
if lhs.mixins != rhs.mixins {return false}
if lhs.syntax != rhs.syntax {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_Method: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Method"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "name"),
2: .standard(proto: "request_type_url"),
3: .standard(proto: "request_streaming"),
4: .standard(proto: "response_type_url"),
5: .standard(proto: "response_streaming"),
6: .same(proto: "options"),
7: .same(proto: "syntax"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &self.name) }()
case 2: try { try decoder.decodeSingularStringField(value: &self.requestTypeURL) }()
case 3: try { try decoder.decodeSingularBoolField(value: &self.requestStreaming) }()
case 4: try { try decoder.decodeSingularStringField(value: &self.responseTypeURL) }()
case 5: try { try decoder.decodeSingularBoolField(value: &self.responseStreaming) }()
case 6: try { try decoder.decodeRepeatedMessageField(value: &self.options) }()
case 7: try { try decoder.decodeSingularEnumField(value: &self.syntax) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.name.isEmpty {
try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
}
if !self.requestTypeURL.isEmpty {
try visitor.visitSingularStringField(value: self.requestTypeURL, fieldNumber: 2)
}
if self.requestStreaming != false {
try visitor.visitSingularBoolField(value: self.requestStreaming, fieldNumber: 3)
}
if !self.responseTypeURL.isEmpty {
try visitor.visitSingularStringField(value: self.responseTypeURL, fieldNumber: 4)
}
if self.responseStreaming != false {
try visitor.visitSingularBoolField(value: self.responseStreaming, fieldNumber: 5)
}
if !self.options.isEmpty {
try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 6)
}
if self.syntax != .proto2 {
try visitor.visitSingularEnumField(value: self.syntax, fieldNumber: 7)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Method, rhs: Google_Protobuf_Method) -> Bool {
if lhs.name != rhs.name {return false}
if lhs.requestTypeURL != rhs.requestTypeURL {return false}
if lhs.requestStreaming != rhs.requestStreaming {return false}
if lhs.responseTypeURL != rhs.responseTypeURL {return false}
if lhs.responseStreaming != rhs.responseStreaming {return false}
if lhs.options != rhs.options {return false}
if lhs.syntax != rhs.syntax {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_Mixin: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Mixin"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "name"),
2: .same(proto: "root"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &self.name) }()
case 2: try { try decoder.decodeSingularStringField(value: &self.root) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.name.isEmpty {
try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
}
if !self.root.isEmpty {
try visitor.visitSingularStringField(value: self.root, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Mixin, rhs: Google_Protobuf_Mixin) -> Bool {
if lhs.name != rhs.name {return false}
if lhs.root != rhs.root {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,173 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: google/protobuf/duration.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import Foundation
// 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 you 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
}
/// A Duration represents a signed, fixed-length span of time represented
/// as a count of seconds and fractions of seconds at nanosecond
/// resolution. It is independent of any calendar and concepts like "day"
/// or "month". It is related to Timestamp in that the difference between
/// two Timestamp values is a Duration and it can be added or subtracted
/// from a Timestamp. Range is approximately +-10,000 years.
///
/// # Examples
///
/// Example 1: Compute Duration from two Timestamps in pseudo code.
///
/// Timestamp start = ...;
/// Timestamp end = ...;
/// Duration duration = ...;
///
/// duration.seconds = end.seconds - start.seconds;
/// duration.nanos = end.nanos - start.nanos;
///
/// if (duration.seconds < 0 && duration.nanos > 0) {
/// duration.seconds += 1;
/// duration.nanos -= 1000000000;
/// } else if (duration.seconds > 0 && duration.nanos < 0) {
/// duration.seconds -= 1;
/// duration.nanos += 1000000000;
/// }
///
/// Example 2: Compute Timestamp from Timestamp + Duration in pseudo code.
///
/// Timestamp start = ...;
/// Duration duration = ...;
/// Timestamp end = ...;
///
/// end.seconds = start.seconds + duration.seconds;
/// end.nanos = start.nanos + duration.nanos;
///
/// if (end.nanos < 0) {
/// end.seconds -= 1;
/// end.nanos += 1000000000;
/// } else if (end.nanos >= 1000000000) {
/// end.seconds += 1;
/// end.nanos -= 1000000000;
/// }
///
/// Example 3: Compute Duration from datetime.timedelta in Python.
///
/// td = datetime.timedelta(days=3, minutes=10)
/// duration = Duration()
/// duration.FromTimedelta(td)
///
/// # JSON Mapping
///
/// In JSON format, the Duration type is encoded as a string rather than an
/// object, where the string ends in the suffix "s" (indicating seconds) and
/// is preceded by the number of seconds, with nanoseconds expressed as
/// fractional seconds. For example, 3 seconds with 0 nanoseconds should be
/// encoded in JSON format as "3s", while 3 seconds and 1 nanosecond should
/// be expressed in JSON format as "3.000000001s", and 3 seconds and 1
/// microsecond should be expressed in JSON format as "3.000001s".
public struct Google_Protobuf_Duration {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// Signed seconds of the span of time. Must be from -315,576,000,000
/// to +315,576,000,000 inclusive. Note: these bounds are computed from:
/// 60 sec/min * 60 min/hr * 24 hr/day * 365.25 days/year * 10000 years
public var seconds: Int64 = 0
/// Signed fractions of a second at nanosecond resolution of the span
/// of time. Durations less than one second are represented with a 0
/// `seconds` field and a positive or negative `nanos` field. For durations
/// of one second or more, a non-zero value for the `nanos` field must be
/// of the same sign as the `seconds` field. Must be from -999,999,999
/// to +999,999,999 inclusive.
public var nanos: Int32 = 0
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "google.protobuf"
extension Google_Protobuf_Duration: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Duration"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "seconds"),
2: .same(proto: "nanos"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularInt64Field(value: &self.seconds) }()
case 2: try { try decoder.decodeSingularInt32Field(value: &self.nanos) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.seconds != 0 {
try visitor.visitSingularInt64Field(value: self.seconds, fieldNumber: 1)
}
if self.nanos != 0 {
try visitor.visitSingularInt32Field(value: self.nanos, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Duration, rhs: Google_Protobuf_Duration) -> Bool {
if lhs.seconds != rhs.seconds {return false}
if lhs.nanos != rhs.nanos {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

View File

@ -0,0 +1,92 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: google/protobuf/empty.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import Foundation
// 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 you 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
}
/// A generic empty message that you can re-use to avoid defining duplicated
/// empty messages in your APIs. A typical example is to use it as the request
/// or the response type of an API method. For instance:
///
/// service Foo {
/// rpc Bar(google.protobuf.Empty) returns (google.protobuf.Empty);
/// }
///
/// The JSON representation for `Empty` is empty JSON object `{}`.
public struct Google_Protobuf_Empty {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "google.protobuf"
extension Google_Protobuf_Empty: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Empty"
public static let _protobuf_nameMap = SwiftProtobuf._NameMap()
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let _ = try decoder.nextFieldNumber() {
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Empty, rhs: Google_Protobuf_Empty) -> Bool {
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

View File

@ -0,0 +1,298 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: google/protobuf/field_mask.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import Foundation
// 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 you 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
}
/// `FieldMask` represents a set of symbolic field paths, for example:
///
/// paths: "f.a"
/// paths: "f.b.d"
///
/// Here `f` represents a field in some root message, `a` and `b`
/// fields in the message found in `f`, and `d` a field found in the
/// message in `f.b`.
///
/// Field masks are used to specify a subset of fields that should be
/// returned by a get operation or modified by an update operation.
/// Field masks also have a custom JSON encoding (see below).
///
/// # Field Masks in Projections
///
/// When used in the context of a projection, a response message or
/// sub-message is filtered by the API to only contain those fields as
/// specified in the mask. For example, if the mask in the previous
/// example is applied to a response message as follows:
///
/// f {
/// a : 22
/// b {
/// d : 1
/// x : 2
/// }
/// y : 13
/// }
/// z: 8
///
/// The result will not contain specific values for fields x,y and z
/// (their value will be set to the default, and omitted in proto text
/// output):
///
///
/// f {
/// a : 22
/// b {
/// d : 1
/// }
/// }
///
/// A repeated field is not allowed except at the last position of a
/// paths string.
///
/// If a FieldMask object is not present in a get operation, the
/// operation applies to all fields (as if a FieldMask of all fields
/// had been specified).
///
/// Note that a field mask does not necessarily apply to the
/// top-level response message. In case of a REST get operation, the
/// field mask applies directly to the response, but in case of a REST
/// list operation, the mask instead applies to each individual message
/// in the returned resource list. In case of a REST custom method,
/// other definitions may be used. Where the mask applies will be
/// clearly documented together with its declaration in the API. In
/// any case, the effect on the returned resource/resources is required
/// behavior for APIs.
///
/// # Field Masks in Update Operations
///
/// A field mask in update operations specifies which fields of the
/// targeted resource are going to be updated. The API is required
/// to only change the values of the fields as specified in the mask
/// and leave the others untouched. If a resource is passed in to
/// describe the updated values, the API ignores the values of all
/// fields not covered by the mask.
///
/// If a repeated field is specified for an update operation, new values will
/// be appended to the existing repeated field in the target resource. Note that
/// a repeated field is only allowed in the last position of a `paths` string.
///
/// If a sub-message is specified in the last position of the field mask for an
/// update operation, then new value will be merged into the existing sub-message
/// in the target resource.
///
/// For example, given the target message:
///
/// f {
/// b {
/// d: 1
/// x: 2
/// }
/// c: [1]
/// }
///
/// And an update message:
///
/// f {
/// b {
/// d: 10
/// }
/// c: [2]
/// }
///
/// then if the field mask is:
///
/// paths: ["f.b", "f.c"]
///
/// then the result will be:
///
/// f {
/// b {
/// d: 10
/// x: 2
/// }
/// c: [1, 2]
/// }
///
/// An implementation may provide options to override this default behavior for
/// repeated and message fields.
///
/// In order to reset a field's value to the default, the field must
/// be in the mask and set to the default value in the provided resource.
/// Hence, in order to reset all fields of a resource, provide a default
/// instance of the resource and set all fields in the mask, or do
/// not provide a mask as described below.
///
/// If a field mask is not present on update, the operation applies to
/// all fields (as if a field mask of all fields has been specified).
/// Note that in the presence of schema evolution, this may mean that
/// fields the client does not know and has therefore not filled into
/// the request will be reset to their default. If this is unwanted
/// behavior, a specific service may require a client to always specify
/// a field mask, producing an error if not.
///
/// As with get operations, the location of the resource which
/// describes the updated values in the request message depends on the
/// operation kind. In any case, the effect of the field mask is
/// required to be honored by the API.
///
/// ## Considerations for HTTP REST
///
/// The HTTP kind of an update operation which uses a field mask must
/// be set to PATCH instead of PUT in order to satisfy HTTP semantics
/// (PUT must only be used for full updates).
///
/// # JSON Encoding of Field Masks
///
/// In JSON, a field mask is encoded as a single string where paths are
/// separated by a comma. Fields name in each path are converted
/// to/from lower-camel naming conventions.
///
/// As an example, consider the following message declarations:
///
/// message Profile {
/// User user = 1;
/// Photo photo = 2;
/// }
/// message User {
/// string display_name = 1;
/// string address = 2;
/// }
///
/// In proto a field mask for `Profile` may look as such:
///
/// mask {
/// paths: "user.display_name"
/// paths: "photo"
/// }
///
/// In JSON, the same mask is represented as below:
///
/// {
/// mask: "user.displayName,photo"
/// }
///
/// # Field Masks and Oneof Fields
///
/// Field masks treat fields in oneofs just as regular fields. Consider the
/// following message:
///
/// message SampleMessage {
/// oneof test_oneof {
/// string name = 4;
/// SubMessage sub_message = 9;
/// }
/// }
///
/// The field mask can be:
///
/// mask {
/// paths: "name"
/// }
///
/// Or:
///
/// mask {
/// paths: "sub_message"
/// }
///
/// Note that oneof type names ("test_oneof" in this case) cannot be used in
/// paths.
///
/// ## Field Mask Verification
///
/// The implementation of any API method which has a FieldMask type field in the
/// request should verify the included field paths, and return an
/// `INVALID_ARGUMENT` error if any path is unmappable.
public struct Google_Protobuf_FieldMask {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The set of field mask paths.
public var paths: [String] = []
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "google.protobuf"
extension Google_Protobuf_FieldMask: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".FieldMask"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "paths"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeRepeatedStringField(value: &self.paths) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.paths.isEmpty {
try visitor.visitRepeatedStringField(value: self.paths, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_FieldMask, rhs: Google_Protobuf_FieldMask) -> Bool {
if lhs.paths != rhs.paths {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

View File

@ -0,0 +1,102 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: google/protobuf/source_context.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import Foundation
// 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 you 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
}
/// `SourceContext` represents information about the source of a
/// protobuf element, like the file in which it is defined.
public struct Google_Protobuf_SourceContext {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The path-qualified name of the .proto file that contained the associated
/// protobuf element. For example: `"google/protobuf/source_context.proto"`.
public var fileName: String = String()
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "google.protobuf"
extension Google_Protobuf_SourceContext: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".SourceContext"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .standard(proto: "file_name"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &self.fileName) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.fileName.isEmpty {
try visitor.visitSingularStringField(value: self.fileName, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_SourceContext, rhs: Google_Protobuf_SourceContext) -> Bool {
if lhs.fileName != rhs.fileName {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

View File

@ -0,0 +1,432 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: google/protobuf/struct.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import Foundation
// 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 you 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
}
/// `NullValue` is a singleton enumeration to represent the null value for the
/// `Value` type union.
///
/// The JSON representation for `NullValue` is JSON `null`.
public enum Google_Protobuf_NullValue: SwiftProtobuf.Enum {
public typealias RawValue = Int
/// Null value.
case nullValue // = 0
case UNRECOGNIZED(Int)
public init() {
self = .nullValue
}
public init?(rawValue: Int) {
switch rawValue {
case 0: self = .nullValue
default: self = .UNRECOGNIZED(rawValue)
}
}
public var rawValue: Int {
switch self {
case .nullValue: return 0
case .UNRECOGNIZED(let i): return i
}
}
}
#if swift(>=4.2)
extension Google_Protobuf_NullValue: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static var allCases: [Google_Protobuf_NullValue] = [
.nullValue,
]
}
#endif // swift(>=4.2)
/// `Struct` represents a structured data value, consisting of fields
/// which map to dynamically typed values. In some languages, `Struct`
/// might be supported by a native representation. For example, in
/// scripting languages like JS a struct is represented as an
/// object. The details of that representation are described together
/// with the proto support for the language.
///
/// The JSON representation for `Struct` is JSON object.
public struct Google_Protobuf_Struct {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// Unordered map of dynamically typed values.
public var fields: Dictionary<String,Google_Protobuf_Value> = [:]
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// `Value` represents a dynamically typed value which can be either
/// null, a number, a string, a boolean, a recursive struct value, or a
/// list of values. A producer of value is expected to set one of that
/// variants, absence of any variant indicates an error.
///
/// The JSON representation for `Value` is JSON value.
public struct Google_Protobuf_Value {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The kind of value.
public var kind: Google_Protobuf_Value.OneOf_Kind? = nil
/// Represents a null value.
public var nullValue: Google_Protobuf_NullValue {
get {
if case .nullValue(let v)? = kind {return v}
return .nullValue
}
set {kind = .nullValue(newValue)}
}
/// Represents a double value.
public var numberValue: Double {
get {
if case .numberValue(let v)? = kind {return v}
return 0
}
set {kind = .numberValue(newValue)}
}
/// Represents a string value.
public var stringValue: String {
get {
if case .stringValue(let v)? = kind {return v}
return String()
}
set {kind = .stringValue(newValue)}
}
/// Represents a boolean value.
public var boolValue: Bool {
get {
if case .boolValue(let v)? = kind {return v}
return false
}
set {kind = .boolValue(newValue)}
}
/// Represents a structured value.
public var structValue: Google_Protobuf_Struct {
get {
if case .structValue(let v)? = kind {return v}
return Google_Protobuf_Struct()
}
set {kind = .structValue(newValue)}
}
/// Represents a repeated `Value`.
public var listValue: Google_Protobuf_ListValue {
get {
if case .listValue(let v)? = kind {return v}
return Google_Protobuf_ListValue()
}
set {kind = .listValue(newValue)}
}
public var unknownFields = SwiftProtobuf.UnknownStorage()
/// The kind of value.
public enum OneOf_Kind: Equatable {
/// Represents a null value.
case nullValue(Google_Protobuf_NullValue)
/// Represents a double value.
case numberValue(Double)
/// Represents a string value.
case stringValue(String)
/// Represents a boolean value.
case boolValue(Bool)
/// Represents a structured value.
case structValue(Google_Protobuf_Struct)
/// Represents a repeated `Value`.
case listValue(Google_Protobuf_ListValue)
#if !swift(>=4.1)
public static func ==(lhs: Google_Protobuf_Value.OneOf_Kind, rhs: Google_Protobuf_Value.OneOf_Kind) -> Bool {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch (lhs, rhs) {
case (.nullValue, .nullValue): return {
guard case .nullValue(let l) = lhs, case .nullValue(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.numberValue, .numberValue): return {
guard case .numberValue(let l) = lhs, case .numberValue(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.stringValue, .stringValue): return {
guard case .stringValue(let l) = lhs, case .stringValue(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.boolValue, .boolValue): return {
guard case .boolValue(let l) = lhs, case .boolValue(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.structValue, .structValue): return {
guard case .structValue(let l) = lhs, case .structValue(let r) = rhs else { preconditionFailure() }
return l == r
}()
case (.listValue, .listValue): return {
guard case .listValue(let l) = lhs, case .listValue(let r) = rhs else { preconditionFailure() }
return l == r
}()
default: return false
}
}
#endif
}
public init() {}
}
/// `ListValue` is a wrapper around a repeated field of values.
///
/// The JSON representation for `ListValue` is JSON array.
public struct Google_Protobuf_ListValue {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// Repeated field of dynamically typed values.
public var values: [Google_Protobuf_Value] = []
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "google.protobuf"
extension Google_Protobuf_NullValue: SwiftProtobuf._ProtoNameProviding {
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "NULL_VALUE"),
]
}
extension Google_Protobuf_Struct: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Struct"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "fields"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeMapField(fieldType: SwiftProtobuf._ProtobufMessageMap<SwiftProtobuf.ProtobufString,Google_Protobuf_Value>.self, value: &self.fields) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.fields.isEmpty {
try visitor.visitMapField(fieldType: SwiftProtobuf._ProtobufMessageMap<SwiftProtobuf.ProtobufString,Google_Protobuf_Value>.self, value: self.fields, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Struct, rhs: Google_Protobuf_Struct) -> Bool {
if lhs.fields != rhs.fields {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_Value: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Value"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .standard(proto: "null_value"),
2: .standard(proto: "number_value"),
3: .standard(proto: "string_value"),
4: .standard(proto: "bool_value"),
5: .standard(proto: "struct_value"),
6: .standard(proto: "list_value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try {
if self.kind != nil {try decoder.handleConflictingOneOf()}
var v: Google_Protobuf_NullValue?
try decoder.decodeSingularEnumField(value: &v)
if let v = v {self.kind = .nullValue(v)}
}()
case 2: try {
if self.kind != nil {try decoder.handleConflictingOneOf()}
var v: Double?
try decoder.decodeSingularDoubleField(value: &v)
if let v = v {self.kind = .numberValue(v)}
}()
case 3: try {
if self.kind != nil {try decoder.handleConflictingOneOf()}
var v: String?
try decoder.decodeSingularStringField(value: &v)
if let v = v {self.kind = .stringValue(v)}
}()
case 4: try {
if self.kind != nil {try decoder.handleConflictingOneOf()}
var v: Bool?
try decoder.decodeSingularBoolField(value: &v)
if let v = v {self.kind = .boolValue(v)}
}()
case 5: try {
var v: Google_Protobuf_Struct?
if let current = self.kind {
try decoder.handleConflictingOneOf()
if case .structValue(let m) = current {v = m}
}
try decoder.decodeSingularMessageField(value: &v)
if let v = v {self.kind = .structValue(v)}
}()
case 6: try {
var v: Google_Protobuf_ListValue?
if let current = self.kind {
try decoder.handleConflictingOneOf()
if case .listValue(let m) = current {v = m}
}
try decoder.decodeSingularMessageField(value: &v)
if let v = v {self.kind = .listValue(v)}
}()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch self.kind {
case .nullValue?: try {
guard case .nullValue(let v)? = self.kind else { preconditionFailure() }
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
}()
case .numberValue?: try {
guard case .numberValue(let v)? = self.kind else { preconditionFailure() }
try visitor.visitSingularDoubleField(value: v, fieldNumber: 2)
}()
case .stringValue?: try {
guard case .stringValue(let v)? = self.kind else { preconditionFailure() }
try visitor.visitSingularStringField(value: v, fieldNumber: 3)
}()
case .boolValue?: try {
guard case .boolValue(let v)? = self.kind else { preconditionFailure() }
try visitor.visitSingularBoolField(value: v, fieldNumber: 4)
}()
case .structValue?: try {
guard case .structValue(let v)? = self.kind else { preconditionFailure() }
try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
}()
case .listValue?: try {
guard case .listValue(let v)? = self.kind else { preconditionFailure() }
try visitor.visitSingularMessageField(value: v, fieldNumber: 6)
}()
case nil: break
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Value, rhs: Google_Protobuf_Value) -> Bool {
if lhs.kind != rhs.kind {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_ListValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".ListValue"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "values"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeRepeatedMessageField(value: &self.values) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.values.isEmpty {
try visitor.visitRepeatedMessageField(value: self.values, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_ListValue, rhs: Google_Protobuf_ListValue) -> Bool {
if lhs.values != rhs.values {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

View File

@ -0,0 +1,204 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: google/protobuf/timestamp.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import Foundation
// 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 you 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
}
/// A Timestamp represents a point in time independent of any time zone or local
/// calendar, encoded as a count of seconds and fractions of seconds at
/// nanosecond resolution. The count is relative to an epoch at UTC midnight on
/// January 1, 1970, in the proleptic Gregorian calendar which extends the
/// Gregorian calendar backwards to year one.
///
/// All minutes are 60 seconds long. Leap seconds are "smeared" so that no leap
/// second table is needed for interpretation, using a [24-hour linear
/// smear](https://developers.google.com/time/smear).
///
/// The range is from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. By
/// restricting to that range, we ensure that we can convert to and from [RFC
/// 3339](https://www.ietf.org/rfc/rfc3339.txt) date strings.
///
/// # Examples
///
/// Example 1: Compute Timestamp from POSIX `time()`.
///
/// Timestamp timestamp;
/// timestamp.set_seconds(time(NULL));
/// timestamp.set_nanos(0);
///
/// Example 2: Compute Timestamp from POSIX `gettimeofday()`.
///
/// struct timeval tv;
/// gettimeofday(&tv, NULL);
///
/// Timestamp timestamp;
/// timestamp.set_seconds(tv.tv_sec);
/// timestamp.set_nanos(tv.tv_usec * 1000);
///
/// Example 3: Compute Timestamp from Win32 `GetSystemTimeAsFileTime()`.
///
/// FILETIME ft;
/// GetSystemTimeAsFileTime(&ft);
/// UINT64 ticks = (((UINT64)ft.dwHighDateTime) << 32) | ft.dwLowDateTime;
///
/// // A Windows tick is 100 nanoseconds. Windows epoch 1601-01-01T00:00:00Z
/// // is 11644473600 seconds before Unix epoch 1970-01-01T00:00:00Z.
/// Timestamp timestamp;
/// timestamp.set_seconds((INT64) ((ticks / 10000000) - 11644473600LL));
/// timestamp.set_nanos((INT32) ((ticks % 10000000) * 100));
///
/// Example 4: Compute Timestamp from Java `System.currentTimeMillis()`.
///
/// long millis = System.currentTimeMillis();
///
/// Timestamp timestamp = Timestamp.newBuilder().setSeconds(millis / 1000)
/// .setNanos((int) ((millis % 1000) * 1000000)).build();
///
///
/// Example 5: Compute Timestamp from Java `Instant.now()`.
///
/// Instant now = Instant.now();
///
/// Timestamp timestamp =
/// Timestamp.newBuilder().setSeconds(now.getEpochSecond())
/// .setNanos(now.getNano()).build();
///
///
/// Example 6: Compute Timestamp from current time in Python.
///
/// timestamp = Timestamp()
/// timestamp.GetCurrentTime()
///
/// # JSON Mapping
///
/// In JSON format, the Timestamp type is encoded as a string in the
/// [RFC 3339](https://www.ietf.org/rfc/rfc3339.txt) format. That is, the
/// format is "{year}-{month}-{day}T{hour}:{min}:{sec}[.{frac_sec}]Z"
/// where {year} is always expressed using four digits while {month}, {day},
/// {hour}, {min}, and {sec} are zero-padded to two digits each. The fractional
/// seconds, which can go up to 9 digits (i.e. up to 1 nanosecond resolution),
/// are optional. The "Z" suffix indicates the timezone ("UTC"); the timezone
/// is required. A proto3 JSON serializer should always use UTC (as indicated by
/// "Z") when printing the Timestamp type and a proto3 JSON parser should be
/// able to accept both UTC and other timezones (as indicated by an offset).
///
/// For example, "2017-01-15T01:30:15.01Z" encodes 15.01 seconds past
/// 01:30 UTC on January 15, 2017.
///
/// In JavaScript, one can convert a Date object to this format using the
/// standard
/// [toISOString()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString)
/// method. In Python, a standard `datetime.datetime` object can be converted
/// to this format using
/// [`strftime`](https://docs.python.org/2/library/time.html#time.strftime) with
/// the time format spec '%Y-%m-%dT%H:%M:%S.%fZ'. Likewise, in Java, one can use
/// the Joda Time's [`ISODateTimeFormat.dateTime()`](
/// http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D
/// ) to obtain a formatter capable of generating timestamps in this format.
public struct Google_Protobuf_Timestamp {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// Represents seconds of UTC time since Unix epoch
/// 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to
/// 9999-12-31T23:59:59Z inclusive.
public var seconds: Int64 = 0
/// Non-negative fractions of a second at nanosecond resolution. Negative
/// second values with fractions must still have non-negative nanos values
/// that count forward in time. Must be from 0 to 999,999,999
/// inclusive.
public var nanos: Int32 = 0
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "google.protobuf"
extension Google_Protobuf_Timestamp: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Timestamp"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "seconds"),
2: .same(proto: "nanos"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularInt64Field(value: &self.seconds) }()
case 2: try { try decoder.decodeSingularInt32Field(value: &self.nanos) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.seconds != 0 {
try visitor.visitSingularInt64Field(value: self.seconds, fieldNumber: 1)
}
if self.nanos != 0 {
try visitor.visitSingularInt32Field(value: self.nanos, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Timestamp, rhs: Google_Protobuf_Timestamp) -> Bool {
if lhs.seconds != rhs.seconds {return false}
if lhs.nanos != rhs.nanos {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

View File

@ -0,0 +1,794 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: google/protobuf/type.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
import Foundation
// 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 you 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
}
/// The syntax in which a protocol buffer element is defined.
public enum Google_Protobuf_Syntax: SwiftProtobuf.Enum {
public typealias RawValue = Int
/// Syntax `proto2`.
case proto2 // = 0
/// Syntax `proto3`.
case proto3 // = 1
case UNRECOGNIZED(Int)
public init() {
self = .proto2
}
public init?(rawValue: Int) {
switch rawValue {
case 0: self = .proto2
case 1: self = .proto3
default: self = .UNRECOGNIZED(rawValue)
}
}
public var rawValue: Int {
switch self {
case .proto2: return 0
case .proto3: return 1
case .UNRECOGNIZED(let i): return i
}
}
}
#if swift(>=4.2)
extension Google_Protobuf_Syntax: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static var allCases: [Google_Protobuf_Syntax] = [
.proto2,
.proto3,
]
}
#endif // swift(>=4.2)
/// A protocol buffer message type.
public struct Google_Protobuf_Type {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The fully qualified message name.
public var name: String = String()
/// The list of fields.
public var fields: [Google_Protobuf_Field] = []
/// The list of types appearing in `oneof` definitions in this type.
public var oneofs: [String] = []
/// The protocol buffer options.
public var options: [Google_Protobuf_Option] = []
/// The source context.
public var sourceContext: Google_Protobuf_SourceContext {
get {return _sourceContext ?? Google_Protobuf_SourceContext()}
set {_sourceContext = newValue}
}
/// Returns true if `sourceContext` has been explicitly set.
public var hasSourceContext: Bool {return self._sourceContext != nil}
/// Clears the value of `sourceContext`. Subsequent reads from it will return its default value.
public mutating func clearSourceContext() {self._sourceContext = nil}
/// The source syntax.
public var syntax: Google_Protobuf_Syntax = .proto2
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
fileprivate var _sourceContext: Google_Protobuf_SourceContext? = nil
}
/// A single field of a message type.
public struct Google_Protobuf_Field {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The field type.
public var kind: Google_Protobuf_Field.Kind = .typeUnknown
/// The field cardinality.
public var cardinality: Google_Protobuf_Field.Cardinality = .unknown
/// The field number.
public var number: Int32 = 0
/// The field name.
public var name: String = String()
/// The field type URL, without the scheme, for message or enumeration
/// types. Example: `"type.googleapis.com/google.protobuf.Timestamp"`.
public var typeURL: String = String()
/// The index of the field type in `Type.oneofs`, for message or enumeration
/// types. The first type has index 1; zero means the type is not in the list.
public var oneofIndex: Int32 = 0
/// Whether to use alternative packed wire representation.
public var packed: Bool = false
/// The protocol buffer options.
public var options: [Google_Protobuf_Option] = []
/// The field JSON name.
public var jsonName: String = String()
/// The string value of the default value of this field. Proto2 syntax only.
public var defaultValue: String = String()
public var unknownFields = SwiftProtobuf.UnknownStorage()
/// Basic field types.
public enum Kind: SwiftProtobuf.Enum {
public typealias RawValue = Int
/// Field type unknown.
case typeUnknown // = 0
/// Field type double.
case typeDouble // = 1
/// Field type float.
case typeFloat // = 2
/// Field type int64.
case typeInt64 // = 3
/// Field type uint64.
case typeUint64 // = 4
/// Field type int32.
case typeInt32 // = 5
/// Field type fixed64.
case typeFixed64 // = 6
/// Field type fixed32.
case typeFixed32 // = 7
/// Field type bool.
case typeBool // = 8
/// Field type string.
case typeString // = 9
/// Field type group. Proto2 syntax only, and deprecated.
case typeGroup // = 10
/// Field type message.
case typeMessage // = 11
/// Field type bytes.
case typeBytes // = 12
/// Field type uint32.
case typeUint32 // = 13
/// Field type enum.
case typeEnum // = 14
/// Field type sfixed32.
case typeSfixed32 // = 15
/// Field type sfixed64.
case typeSfixed64 // = 16
/// Field type sint32.
case typeSint32 // = 17
/// Field type sint64.
case typeSint64 // = 18
case UNRECOGNIZED(Int)
public init() {
self = .typeUnknown
}
public init?(rawValue: Int) {
switch rawValue {
case 0: self = .typeUnknown
case 1: self = .typeDouble
case 2: self = .typeFloat
case 3: self = .typeInt64
case 4: self = .typeUint64
case 5: self = .typeInt32
case 6: self = .typeFixed64
case 7: self = .typeFixed32
case 8: self = .typeBool
case 9: self = .typeString
case 10: self = .typeGroup
case 11: self = .typeMessage
case 12: self = .typeBytes
case 13: self = .typeUint32
case 14: self = .typeEnum
case 15: self = .typeSfixed32
case 16: self = .typeSfixed64
case 17: self = .typeSint32
case 18: self = .typeSint64
default: self = .UNRECOGNIZED(rawValue)
}
}
public var rawValue: Int {
switch self {
case .typeUnknown: return 0
case .typeDouble: return 1
case .typeFloat: return 2
case .typeInt64: return 3
case .typeUint64: return 4
case .typeInt32: return 5
case .typeFixed64: return 6
case .typeFixed32: return 7
case .typeBool: return 8
case .typeString: return 9
case .typeGroup: return 10
case .typeMessage: return 11
case .typeBytes: return 12
case .typeUint32: return 13
case .typeEnum: return 14
case .typeSfixed32: return 15
case .typeSfixed64: return 16
case .typeSint32: return 17
case .typeSint64: return 18
case .UNRECOGNIZED(let i): return i
}
}
}
/// Whether a field is optional, required, or repeated.
public enum Cardinality: SwiftProtobuf.Enum {
public typealias RawValue = Int
/// For fields with unknown cardinality.
case unknown // = 0
/// For optional fields.
case `optional` // = 1
/// For required fields. Proto2 syntax only.
case `required` // = 2
/// For repeated fields.
case repeated // = 3
case UNRECOGNIZED(Int)
public init() {
self = .unknown
}
public init?(rawValue: Int) {
switch rawValue {
case 0: self = .unknown
case 1: self = .optional
case 2: self = .required
case 3: self = .repeated
default: self = .UNRECOGNIZED(rawValue)
}
}
public var rawValue: Int {
switch self {
case .unknown: return 0
case .optional: return 1
case .required: return 2
case .repeated: return 3
case .UNRECOGNIZED(let i): return i
}
}
}
public init() {}
}
#if swift(>=4.2)
extension Google_Protobuf_Field.Kind: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static var allCases: [Google_Protobuf_Field.Kind] = [
.typeUnknown,
.typeDouble,
.typeFloat,
.typeInt64,
.typeUint64,
.typeInt32,
.typeFixed64,
.typeFixed32,
.typeBool,
.typeString,
.typeGroup,
.typeMessage,
.typeBytes,
.typeUint32,
.typeEnum,
.typeSfixed32,
.typeSfixed64,
.typeSint32,
.typeSint64,
]
}
extension Google_Protobuf_Field.Cardinality: CaseIterable {
// The compiler won't synthesize support with the UNRECOGNIZED case.
public static var allCases: [Google_Protobuf_Field.Cardinality] = [
.unknown,
.optional,
.required,
.repeated,
]
}
#endif // swift(>=4.2)
/// Enum type definition.
public struct Google_Protobuf_Enum {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// Enum type name.
public var name: String = String()
/// Enum value definitions.
public var enumvalue: [Google_Protobuf_EnumValue] = []
/// Protocol buffer options.
public var options: [Google_Protobuf_Option] = []
/// The source context.
public var sourceContext: Google_Protobuf_SourceContext {
get {return _sourceContext ?? Google_Protobuf_SourceContext()}
set {_sourceContext = newValue}
}
/// Returns true if `sourceContext` has been explicitly set.
public var hasSourceContext: Bool {return self._sourceContext != nil}
/// Clears the value of `sourceContext`. Subsequent reads from it will return its default value.
public mutating func clearSourceContext() {self._sourceContext = nil}
/// The source syntax.
public var syntax: Google_Protobuf_Syntax = .proto2
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
fileprivate var _sourceContext: Google_Protobuf_SourceContext? = nil
}
/// Enum value definition.
public struct Google_Protobuf_EnumValue {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// Enum value name.
public var name: String = String()
/// Enum value number.
public var number: Int32 = 0
/// Protocol buffer options.
public var options: [Google_Protobuf_Option] = []
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// A protocol buffer option, which can be attached to a message, field,
/// enumeration, etc.
public struct Google_Protobuf_Option {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The option's name. For protobuf built-in options (options defined in
/// descriptor.proto), this is the short name. For example, `"map_entry"`.
/// For custom options, it should be the fully-qualified name. For example,
/// `"google.api.http"`.
public var name: String = String()
/// The option's value packed in an Any message. If the value is a primitive,
/// the corresponding wrapper type defined in google/protobuf/wrappers.proto
/// should be used. If the value is an enum, it should be stored as an int32
/// value using the google.protobuf.Int32Value type.
public var value: Google_Protobuf_Any {
get {return _value ?? Google_Protobuf_Any()}
set {_value = newValue}
}
/// Returns true if `value` has been explicitly set.
public var hasValue: Bool {return self._value != nil}
/// Clears the value of `value`. Subsequent reads from it will return its default value.
public mutating func clearValue() {self._value = nil}
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
fileprivate var _value: Google_Protobuf_Any? = nil
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "google.protobuf"
extension Google_Protobuf_Syntax: SwiftProtobuf._ProtoNameProviding {
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "SYNTAX_PROTO2"),
1: .same(proto: "SYNTAX_PROTO3"),
]
}
extension Google_Protobuf_Type: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Type"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "name"),
2: .same(proto: "fields"),
3: .same(proto: "oneofs"),
4: .same(proto: "options"),
5: .standard(proto: "source_context"),
6: .same(proto: "syntax"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &self.name) }()
case 2: try { try decoder.decodeRepeatedMessageField(value: &self.fields) }()
case 3: try { try decoder.decodeRepeatedStringField(value: &self.oneofs) }()
case 4: try { try decoder.decodeRepeatedMessageField(value: &self.options) }()
case 5: try { try decoder.decodeSingularMessageField(value: &self._sourceContext) }()
case 6: try { try decoder.decodeSingularEnumField(value: &self.syntax) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.name.isEmpty {
try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
}
if !self.fields.isEmpty {
try visitor.visitRepeatedMessageField(value: self.fields, fieldNumber: 2)
}
if !self.oneofs.isEmpty {
try visitor.visitRepeatedStringField(value: self.oneofs, fieldNumber: 3)
}
if !self.options.isEmpty {
try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 4)
}
if let v = self._sourceContext {
try visitor.visitSingularMessageField(value: v, fieldNumber: 5)
}
if self.syntax != .proto2 {
try visitor.visitSingularEnumField(value: self.syntax, fieldNumber: 6)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Type, rhs: Google_Protobuf_Type) -> Bool {
if lhs.name != rhs.name {return false}
if lhs.fields != rhs.fields {return false}
if lhs.oneofs != rhs.oneofs {return false}
if lhs.options != rhs.options {return false}
if lhs._sourceContext != rhs._sourceContext {return false}
if lhs.syntax != rhs.syntax {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_Field: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Field"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "kind"),
2: .same(proto: "cardinality"),
3: .same(proto: "number"),
4: .same(proto: "name"),
6: .standard(proto: "type_url"),
7: .standard(proto: "oneof_index"),
8: .same(proto: "packed"),
9: .same(proto: "options"),
10: .standard(proto: "json_name"),
11: .standard(proto: "default_value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularEnumField(value: &self.kind) }()
case 2: try { try decoder.decodeSingularEnumField(value: &self.cardinality) }()
case 3: try { try decoder.decodeSingularInt32Field(value: &self.number) }()
case 4: try { try decoder.decodeSingularStringField(value: &self.name) }()
case 6: try { try decoder.decodeSingularStringField(value: &self.typeURL) }()
case 7: try { try decoder.decodeSingularInt32Field(value: &self.oneofIndex) }()
case 8: try { try decoder.decodeSingularBoolField(value: &self.packed) }()
case 9: try { try decoder.decodeRepeatedMessageField(value: &self.options) }()
case 10: try { try decoder.decodeSingularStringField(value: &self.jsonName) }()
case 11: try { try decoder.decodeSingularStringField(value: &self.defaultValue) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.kind != .typeUnknown {
try visitor.visitSingularEnumField(value: self.kind, fieldNumber: 1)
}
if self.cardinality != .unknown {
try visitor.visitSingularEnumField(value: self.cardinality, fieldNumber: 2)
}
if self.number != 0 {
try visitor.visitSingularInt32Field(value: self.number, fieldNumber: 3)
}
if !self.name.isEmpty {
try visitor.visitSingularStringField(value: self.name, fieldNumber: 4)
}
if !self.typeURL.isEmpty {
try visitor.visitSingularStringField(value: self.typeURL, fieldNumber: 6)
}
if self.oneofIndex != 0 {
try visitor.visitSingularInt32Field(value: self.oneofIndex, fieldNumber: 7)
}
if self.packed != false {
try visitor.visitSingularBoolField(value: self.packed, fieldNumber: 8)
}
if !self.options.isEmpty {
try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 9)
}
if !self.jsonName.isEmpty {
try visitor.visitSingularStringField(value: self.jsonName, fieldNumber: 10)
}
if !self.defaultValue.isEmpty {
try visitor.visitSingularStringField(value: self.defaultValue, fieldNumber: 11)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Field, rhs: Google_Protobuf_Field) -> Bool {
if lhs.kind != rhs.kind {return false}
if lhs.cardinality != rhs.cardinality {return false}
if lhs.number != rhs.number {return false}
if lhs.name != rhs.name {return false}
if lhs.typeURL != rhs.typeURL {return false}
if lhs.oneofIndex != rhs.oneofIndex {return false}
if lhs.packed != rhs.packed {return false}
if lhs.options != rhs.options {return false}
if lhs.jsonName != rhs.jsonName {return false}
if lhs.defaultValue != rhs.defaultValue {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_Field.Kind: SwiftProtobuf._ProtoNameProviding {
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "TYPE_UNKNOWN"),
1: .same(proto: "TYPE_DOUBLE"),
2: .same(proto: "TYPE_FLOAT"),
3: .same(proto: "TYPE_INT64"),
4: .same(proto: "TYPE_UINT64"),
5: .same(proto: "TYPE_INT32"),
6: .same(proto: "TYPE_FIXED64"),
7: .same(proto: "TYPE_FIXED32"),
8: .same(proto: "TYPE_BOOL"),
9: .same(proto: "TYPE_STRING"),
10: .same(proto: "TYPE_GROUP"),
11: .same(proto: "TYPE_MESSAGE"),
12: .same(proto: "TYPE_BYTES"),
13: .same(proto: "TYPE_UINT32"),
14: .same(proto: "TYPE_ENUM"),
15: .same(proto: "TYPE_SFIXED32"),
16: .same(proto: "TYPE_SFIXED64"),
17: .same(proto: "TYPE_SINT32"),
18: .same(proto: "TYPE_SINT64"),
]
}
extension Google_Protobuf_Field.Cardinality: SwiftProtobuf._ProtoNameProviding {
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
0: .same(proto: "CARDINALITY_UNKNOWN"),
1: .same(proto: "CARDINALITY_OPTIONAL"),
2: .same(proto: "CARDINALITY_REQUIRED"),
3: .same(proto: "CARDINALITY_REPEATED"),
]
}
extension Google_Protobuf_Enum: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Enum"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "name"),
2: .same(proto: "enumvalue"),
3: .same(proto: "options"),
4: .standard(proto: "source_context"),
5: .same(proto: "syntax"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &self.name) }()
case 2: try { try decoder.decodeRepeatedMessageField(value: &self.enumvalue) }()
case 3: try { try decoder.decodeRepeatedMessageField(value: &self.options) }()
case 4: try { try decoder.decodeSingularMessageField(value: &self._sourceContext) }()
case 5: try { try decoder.decodeSingularEnumField(value: &self.syntax) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.name.isEmpty {
try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
}
if !self.enumvalue.isEmpty {
try visitor.visitRepeatedMessageField(value: self.enumvalue, fieldNumber: 2)
}
if !self.options.isEmpty {
try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 3)
}
if let v = self._sourceContext {
try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
}
if self.syntax != .proto2 {
try visitor.visitSingularEnumField(value: self.syntax, fieldNumber: 5)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Enum, rhs: Google_Protobuf_Enum) -> Bool {
if lhs.name != rhs.name {return false}
if lhs.enumvalue != rhs.enumvalue {return false}
if lhs.options != rhs.options {return false}
if lhs._sourceContext != rhs._sourceContext {return false}
if lhs.syntax != rhs.syntax {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_EnumValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".EnumValue"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "name"),
2: .same(proto: "number"),
3: .same(proto: "options"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &self.name) }()
case 2: try { try decoder.decodeSingularInt32Field(value: &self.number) }()
case 3: try { try decoder.decodeRepeatedMessageField(value: &self.options) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.name.isEmpty {
try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
}
if self.number != 0 {
try visitor.visitSingularInt32Field(value: self.number, fieldNumber: 2)
}
if !self.options.isEmpty {
try visitor.visitRepeatedMessageField(value: self.options, fieldNumber: 3)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_EnumValue, rhs: Google_Protobuf_EnumValue) -> Bool {
if lhs.name != rhs.name {return false}
if lhs.number != rhs.number {return false}
if lhs.options != rhs.options {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_Option: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Option"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "name"),
2: .same(proto: "value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &self.name) }()
case 2: try { try decoder.decodeSingularMessageField(value: &self._value) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.name.isEmpty {
try visitor.visitSingularStringField(value: self.name, fieldNumber: 1)
}
if let v = self._value {
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Option, rhs: Google_Protobuf_Option) -> Bool {
if lhs.name != rhs.name {return false}
if lhs._value != rhs._value {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}

View File

@ -0,0 +1,496 @@
// DO NOT EDIT.
// swift-format-ignore-file
//
// Generated by the Swift generator plugin for the protocol buffer compiler.
// Source: google/protobuf/wrappers.proto
//
// For information on using the generated types, please see the documentation:
// https://github.com/apple/swift-protobuf/
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Wrappers for primitive (non-message) types. These types are useful
// for embedding primitives in the `google.protobuf.Any` type and for places
// where we need to distinguish between the absence of a primitive
// typed field and its default value.
//
// These wrappers have no meaningful use within repeated fields as they lack
// the ability to detect presence on individual elements.
// These wrappers have no meaningful use within a map or a oneof since
// individual entries of a map or fields of a oneof can already detect presence.
import Foundation
// 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 you 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
}
/// Wrapper message for `double`.
///
/// The JSON representation for `DoubleValue` is JSON number.
public struct Google_Protobuf_DoubleValue {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The double value.
public var value: Double = 0
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// Wrapper message for `float`.
///
/// The JSON representation for `FloatValue` is JSON number.
public struct Google_Protobuf_FloatValue {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The float value.
public var value: Float = 0
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// Wrapper message for `int64`.
///
/// The JSON representation for `Int64Value` is JSON string.
public struct Google_Protobuf_Int64Value {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The int64 value.
public var value: Int64 = 0
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// Wrapper message for `uint64`.
///
/// The JSON representation for `UInt64Value` is JSON string.
public struct Google_Protobuf_UInt64Value {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The uint64 value.
public var value: UInt64 = 0
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// Wrapper message for `int32`.
///
/// The JSON representation for `Int32Value` is JSON number.
public struct Google_Protobuf_Int32Value {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The int32 value.
public var value: Int32 = 0
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// Wrapper message for `uint32`.
///
/// The JSON representation for `UInt32Value` is JSON number.
public struct Google_Protobuf_UInt32Value {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The uint32 value.
public var value: UInt32 = 0
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// Wrapper message for `bool`.
///
/// The JSON representation for `BoolValue` is JSON `true` and `false`.
public struct Google_Protobuf_BoolValue {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The bool value.
public var value: Bool = false
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// Wrapper message for `string`.
///
/// The JSON representation for `StringValue` is JSON string.
public struct Google_Protobuf_StringValue {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The string value.
public var value: String = String()
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
/// Wrapper message for `bytes`.
///
/// The JSON representation for `BytesValue` is JSON string.
public struct Google_Protobuf_BytesValue {
// SwiftProtobuf.Message conformance is added in an extension below. See the
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// The bytes value.
public var value: Data = Data()
public var unknownFields = SwiftProtobuf.UnknownStorage()
public init() {}
}
// MARK: - Code below here is support for the SwiftProtobuf runtime.
fileprivate let _protobuf_package = "google.protobuf"
extension Google_Protobuf_DoubleValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".DoubleValue"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularDoubleField(value: &self.value) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.value != 0 {
try visitor.visitSingularDoubleField(value: self.value, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_DoubleValue, rhs: Google_Protobuf_DoubleValue) -> Bool {
if lhs.value != rhs.value {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_FloatValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".FloatValue"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularFloatField(value: &self.value) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.value != 0 {
try visitor.visitSingularFloatField(value: self.value, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_FloatValue, rhs: Google_Protobuf_FloatValue) -> Bool {
if lhs.value != rhs.value {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_Int64Value: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Int64Value"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularInt64Field(value: &self.value) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.value != 0 {
try visitor.visitSingularInt64Field(value: self.value, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Int64Value, rhs: Google_Protobuf_Int64Value) -> Bool {
if lhs.value != rhs.value {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_UInt64Value: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".UInt64Value"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularUInt64Field(value: &self.value) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.value != 0 {
try visitor.visitSingularUInt64Field(value: self.value, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_UInt64Value, rhs: Google_Protobuf_UInt64Value) -> Bool {
if lhs.value != rhs.value {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_Int32Value: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".Int32Value"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularInt32Field(value: &self.value) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.value != 0 {
try visitor.visitSingularInt32Field(value: self.value, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_Int32Value, rhs: Google_Protobuf_Int32Value) -> Bool {
if lhs.value != rhs.value {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_UInt32Value: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".UInt32Value"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularUInt32Field(value: &self.value) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.value != 0 {
try visitor.visitSingularUInt32Field(value: self.value, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_UInt32Value, rhs: Google_Protobuf_UInt32Value) -> Bool {
if lhs.value != rhs.value {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_BoolValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".BoolValue"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularBoolField(value: &self.value) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if self.value != false {
try visitor.visitSingularBoolField(value: self.value, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_BoolValue, rhs: Google_Protobuf_BoolValue) -> Bool {
if lhs.value != rhs.value {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_StringValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".StringValue"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularStringField(value: &self.value) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.value.isEmpty {
try visitor.visitSingularStringField(value: self.value, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_StringValue, rhs: Google_Protobuf_StringValue) -> Bool {
if lhs.value != rhs.value {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}
extension Google_Protobuf_BytesValue: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
public static let protoMessageName: String = _protobuf_package + ".BytesValue"
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
1: .same(proto: "value"),
]
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
while let fieldNumber = try decoder.nextFieldNumber() {
// The use of inline closures is to circumvent an issue where the compiler
// allocates stack space for every case branch when no optimizations are
// enabled. https://github.com/apple/swift-protobuf/issues/1034
switch fieldNumber {
case 1: try { try decoder.decodeSingularBytesField(value: &self.value) }()
default: break
}
}
}
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
if !self.value.isEmpty {
try visitor.visitSingularBytesField(value: self.value, fieldNumber: 1)
}
try unknownFields.traverse(visitor: &visitor)
}
public static func ==(lhs: Google_Protobuf_BytesValue, rhs: Google_Protobuf_BytesValue) -> Bool {
if lhs.value != rhs.value {return false}
if lhs.unknownFields != rhs.unknownFields {return false}
return true
}
}