Code generate Swift wrappers for protocol buffers.

This commit is contained in:
Matthew Chen 2018-08-02 09:34:50 -04:00
parent d3adb80242
commit ff8565dbd5
9 changed files with 242 additions and 62 deletions

View File

@ -407,7 +407,14 @@ class MessageContext(BaseContext):
for field in explict_fields:
type_name = field.type_swift_not_optional if field.is_required else field.type_swift
writer.add('@objc public let %s: %s' % (field.name_swift, type_name))
writer.newline()
if (not field.is_required) and field.rules != 'repeated':
writer.add('@objc public var %s: Bool {' % field.has_accessor_name() )
writer.push_indent()
writer.add('return proto.%s' % field.has_accessor_name() )
writer.pop_indent()
writer.add('}')
writer.newline()
if len(implict_fields) > 0:
for field in implict_fields:

View File

@ -135,7 +135,6 @@ message DataMessage {
CUSTOM = 4;
}
// @required
optional string value = 1;
optional Type type = 2;
optional string label = 3;
@ -149,7 +148,6 @@ message DataMessage {
CUSTOM = 4;
}
// @required
optional string value = 1;
optional Type type = 2;
optional string label = 3;

View File

@ -25,7 +25,7 @@ NS_ASSUME_NONNULL_BEGIN
SSKProtoGroupDetailsBuilder *groupBuilder = [SSKProtoGroupDetailsBuilder new];
[groupBuilder setId:group.groupId];
[groupBuilder setName:group.groupName];
[groupBuilder setMembersArray:group.groupMemberIds];
[groupBuilder setMembers:group.groupMemberIds];
#ifdef CONVERSATION_COLORS_ENABLED
[groupBuilder setColor:groupThread.conversationColorName];
#endif
@ -38,7 +38,14 @@ NS_ASSUME_NONNULL_BEGIN
[avatarBuilder setContentType:OWSMimeTypeImagePng];
avatarPng = UIImagePNGRepresentation(group.groupImage);
[avatarBuilder setLength:(uint32_t)avatarPng.length];
[groupBuilder setAvatarBuilder:avatarBuilder];
NSError *error;
SSKProtoGroupDetailsAvatar *_Nullable avatarProto = [avatarBuilder buildAndReturnError:&error];
if (error || !avatarProto) {
OWSFail(@"%@ could not build protobuf: %@", self.logTag, error);
} else {
[groupBuilder setAvatar:avatarProto];
}
}
OWSDisappearingMessagesConfiguration *_Nullable disappearingMessagesConfiguration =
@ -53,7 +60,18 @@ NS_ASSUME_NONNULL_BEGIN
[groupBuilder setExpireTimer:0];
}
NSData *groupData = [[groupBuilder build] data];
NSError *error;
SSKProtoGroupDetails *_Nullable groupProto = [groupBuilder buildAndReturnError:&error];
if (error || !groupProto) {
OWSFail(@"%@ could not build protobuf: %@", self.logTag, error);
return;
}
NSData *_Nullable groupData = [groupProto serializedDataAndReturnError:&error];
if (error || !groupData) {
OWSFail(@"%@ could not serialize protobuf: %@", self.logTag, error);
return;
}
uint32_t groupDataLength = (uint32_t)groupData.length;
[self.delegateStream writeRawVarint32:groupDataLength];

View File

@ -18,7 +18,7 @@ NS_ASSUME_NONNULL_BEGIN
* recipientId is nil when building "sent" sync messages for messages
* sent to groups.
*/
- (SSKProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId;
- (nullable SSKProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId;
@end
@ -58,7 +58,13 @@ NS_ASSUME_NONNULL_BEGIN
SSKProtoSyncMessageSentBuilder *sentBuilder = [SSKProtoSyncMessageSentBuilder new];
[sentBuilder setTimestamp:self.message.timestamp];
[sentBuilder setDestination:self.sentRecipientId];
[sentBuilder setMessage:[self.message buildDataMessage:self.sentRecipientId]];
SSKProtoDataMessage *_Nullable dataMessage = [self.message buildDataMessage:self.sentRecipientId];
if (!dataMessage) {
OWSFail(@"%@ could not build protobuf: %@", self.logTag, error);
return nil;
}
[sentBuilder setMessage:dataMessage];
[sentBuilder setExpirationStartTimestamp:self.message.timestamp];
NSError *error;

View File

@ -930,20 +930,43 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
}
// recipientId is nil when building "sent" sync messages for messages sent to groups.
- (SSKProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId
- (nullable SSKProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId
{
OWSAssert(self.thread);
SSKProtoDataMessageBuilder *builder = [self dataMessageBuilder];
[builder addLocalProfileKeyIfNecessary:self.thread recipientId:recipientId];
return [builder build];
NSError *error;
SSKProtoDataMessage *_Nullable dataProto = [builder buildAndReturnError:&error];
if (error || !dataProto) {
OWSFail(@"%@ could not build protobuf: %@", self.logTag, error);
return nil;
}
return dataProto;
}
- (nullable NSData *)buildPlainTextData:(SignalRecipient *)recipient
{
NSError *error;
SSKProtoDataMessage *_Nullable dataMessage = [self buildDataMessage:self.recipientId];
if (!dataMessage) {
OWSFail(@"%@ could not build protobuf: %@", self.logTag, error);
return nil;
}
SSKProtoContentBuilder *contentBuilder = [SSKProtoContentBuilder new];
contentBuilder.dataMessage = [self buildDataMessage:recipient.recipientId];
return [[contentBuilder build] data];
[contentBuilder setDataMessage:dataMessage];
SSKProtoContent *_Nullable contentProto = [contentBuilder buildAndReturnError:&error];
if (error || !contentProto) {
OWSFail(@"%@ could not build protobuf: %@", self.logTag, error);
return;
}
NSData *_Nullable contentData = [contentProto serializedDataAndReturnError:&error];
if (error || !contentData) {
OWSFail(@"%@ could not serialize protobuf: %@", self.logTag, error);
return;
}
return contentData;
}
- (BOOL)shouldSyncTranscript

View File

@ -294,32 +294,44 @@ NS_ASSUME_NONNULL_BEGIN
return;
}
if (envelope.content != nil) {
SSKProtoContent *content = [SSKProtoContent parseFromData:plaintextData];
DDLogInfo(@"%@ handling content: <Content: %@>", self.logTag, [self descriptionForContent:content]);
if (envelope.hasContent) {
NSError *error;
SSKProtoContent *_Nullable contentProto = [SSKProtoContent parseData:plaintextData error:&error];
if (error || !contentProto) {
OWSFail(@"%@ could not parse proto: %@", self.logTag, error);
return;
}
DDLogInfo(@"%@ handling content: <Content: %@>", self.logTag, [self descriptionForContent:contentProto]);
if (content.hasSyncMessage) {
[self handleIncomingEnvelope:envelope withSyncMessage:content.syncMessage transaction:transaction];
if (contentProto.hasSyncMessage) {
[self handleIncomingEnvelope:envelope withSyncMessage:contentProto.syncMessage transaction:transaction];
[[OWSDeviceManager sharedManager] setHasReceivedSyncMessage];
} else if (content.hasDataMessage) {
[self handleIncomingEnvelope:envelope withDataMessage:content.dataMessage transaction:transaction];
} else if (content.hasCallMessage) {
[self handleIncomingEnvelope:envelope withCallMessage:content.callMessage];
} else if (content.hasNullMessage) {
} else if (contentProto.hasDataMessage) {
[self handleIncomingEnvelope:envelope withDataMessage:contentProto.dataMessage transaction:transaction];
} else if (contentProto.hasCallMessage) {
[self handleIncomingEnvelope:envelope withCallMessage:contentProto.callMessage];
} else if (contentProto.hasNullMessage) {
DDLogInfo(@"%@ Received null message.", self.logTag);
} else if (content.hasReceiptMessage) {
[self handleIncomingEnvelope:envelope withReceiptMessage:content.receiptMessage transaction:transaction];
} else if (contentProto.hasReceiptMessage) {
[self handleIncomingEnvelope:envelope
withReceiptMessage:contentProto.receiptMessage
transaction:transaction];
} else {
DDLogWarn(@"%@ Ignoring envelope. Content with no known payload", self.logTag);
}
} else if (envelope.legacyMessage != nil) { // DEPRECATED - Remove after all clients have been upgraded.
SSKProtoDataMessage *dataMessage =
[SSKProtoDataMessage parseFromData:plaintextData];
DDLogInfo(
@"%@ handling message: <DataMessage: %@ />", self.logTag, [self descriptionForDataMessage:dataMessage]);
} else if (envelope.hasLegacyMessage) { // DEPRECATED - Remove after all clients have been upgraded.
NSError *error;
SSKProtoDataMessage *_Nullable dataMessageProto = [SSKProtoDataMessage parseData:plaintextData error:&error];
if (error || !dataMessageProto) {
OWSFail(@"%@ could not parse proto: %@", self.logTag, error);
return;
}
DDLogInfo(@"%@ handling message: <DataMessage: %@ />",
self.logTag,
[self descriptionForDataMessage:dataMessageProto]);
[self handleIncomingEnvelope:envelope withDataMessage:dataMessage transaction:transaction];
[self handleIncomingEnvelope:envelope withDataMessage:dataMessageProto transaction:transaction];
} else {
OWSProdInfoWEnvelope([OWSAnalyticsEvents messageManagerErrorEnvelopeNoActionablePayload], envelope);
}
@ -436,12 +448,7 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(receiptMessage);
OWSAssert(transaction);
PBArray *messageTimestamps = receiptMessage.timestamp;
NSMutableArray<NSNumber *> *sentTimestamps = [NSMutableArray new];
for (int i = 0; i < messageTimestamps.count; i++) {
UInt64 timestamp = [messageTimestamps uint64AtIndex:i];
[sentTimestamps addObject:@(timestamp)];
}
NSArray<NSNumber *> *sentTimestamps = receiptMessage.timestamp;
switch (receiptMessage.type) {
case SSKProtoReceiptMessageTypeDelivery:

View File

@ -41,7 +41,7 @@ NS_ASSUME_NONNULL_BEGIN
return NO;
}
- (SSKProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId
- (nullable SSKProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId
{
OWSAssert(self.thread);
@ -57,7 +57,13 @@ NS_ASSUME_NONNULL_BEGIN
[profileManager addUserToProfileWhitelist:recipientId];
}
return [builder build];
NSError *error;
SSKProtoDataMessage *_Nullable dataProto = [builder buildAndReturnError:&error];
if (error || !dataProto) {
OWSFail(@"%@ could not build protobuf: %@", self.logTag, error);
return nil;
}
return dataProto;
}
@end

View File

@ -89,8 +89,11 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_Envelope
@objc public let type: SSKProtoEnvelopeType
@objc public let source: String
@objc public let sourceDevice: UInt32
@objc public let timestamp: UInt64
@objc public var relay: String? {
@ -220,10 +223,29 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_Content
@objc public let dataMessage: SSKProtoDataMessage?
@objc public var hasDataMessage: Bool {
return proto.hasDataMessage
}
@objc public let syncMessage: SSKProtoSyncMessage?
@objc public var hasSyncMessage: Bool {
return proto.hasSyncMessage
}
@objc public let callMessage: SSKProtoCallMessage?
@objc public var hasCallMessage: Bool {
return proto.hasCallMessage
}
@objc public let nullMessage: SSKProtoNullMessage?
@objc public var hasNullMessage: Bool {
return proto.hasNullMessage
}
@objc public let receiptMessage: SSKProtoReceiptMessage?
@objc public var hasReceiptMessage: Bool {
return proto.hasReceiptMessage
}
private init(proto: SignalServiceProtos_Content,
dataMessage: SSKProtoDataMessage?,
@ -701,10 +723,26 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_CallMessage
@objc public let offer: SSKProtoCallMessageOffer?
@objc public var hasOffer: Bool {
return proto.hasOffer
}
@objc public let answer: SSKProtoCallMessageAnswer?
@objc public var hasAnswer: Bool {
return proto.hasAnswer
}
@objc public let iceUpdate: [SSKProtoCallMessageIceUpdate]
@objc public let hangup: SSKProtoCallMessageHangup?
@objc public var hasHangup: Bool {
return proto.hasHangup
}
@objc public let busy: SSKProtoCallMessageBusy?
@objc public var hasBusy: Bool {
return proto.hasBusy
}
@objc public var profileKey: Data? {
guard proto.hasProfileKey else {
@ -836,6 +874,9 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_DataMessage.Quote.QuotedAttachment
@objc public let thumbnail: SSKProtoAttachmentPointer?
@objc public var hasThumbnail: Bool {
return proto.hasThumbnail
}
@objc public var contentType: String? {
guard proto.hasContentType else {
@ -943,7 +984,9 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_DataMessage.Quote
@objc public let id: UInt64
@objc public let author: String
@objc public let attachments: [SSKProtoDataMessageQuoteQuotedAttachment]
@objc public var text: String? {
@ -1192,7 +1235,15 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_DataMessage.Contact.Phone
@objc public let value: String
@objc public var value: String? {
guard proto.hasValue else {
return nil
}
return proto.value
}
@objc public var hasValue: Bool {
return proto.hasValue
}
@objc public var type: SSKProtoDataMessageContactPhoneType {
return SSKProtoDataMessageContactPhone.SSKProtoDataMessageContactPhoneTypeWrap(proto.type)
@ -1211,10 +1262,8 @@ public enum SSKProtoError: Error {
return proto.hasLabel
}
private init(proto: SignalServiceProtos_DataMessage.Contact.Phone,
value: String) {
private init(proto: SignalServiceProtos_DataMessage.Contact.Phone) {
self.proto = proto
self.value = value
}
@objc
@ -1228,17 +1277,11 @@ public enum SSKProtoError: Error {
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_DataMessage.Contact.Phone) throws -> SSKProtoDataMessageContactPhone {
guard proto.hasValue else {
throw SSKProtoError.invalidProtobuf(description: "\(logTag) missing required field: value")
}
let value = proto.value
// MARK: - Begin Validation Logic for SSKProtoDataMessageContactPhone -
// MARK: - End Validation Logic for SSKProtoDataMessageContactPhone -
let result = SSKProtoDataMessageContactPhone(proto: proto,
value: value)
let result = SSKProtoDataMessageContactPhone(proto: proto)
return result
}
}
@ -1302,7 +1345,15 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_DataMessage.Contact.Email
@objc public let value: String
@objc public var value: String? {
guard proto.hasValue else {
return nil
}
return proto.value
}
@objc public var hasValue: Bool {
return proto.hasValue
}
@objc public var type: SSKProtoDataMessageContactEmailType {
return SSKProtoDataMessageContactEmail.SSKProtoDataMessageContactEmailTypeWrap(proto.type)
@ -1321,10 +1372,8 @@ public enum SSKProtoError: Error {
return proto.hasLabel
}
private init(proto: SignalServiceProtos_DataMessage.Contact.Email,
value: String) {
private init(proto: SignalServiceProtos_DataMessage.Contact.Email) {
self.proto = proto
self.value = value
}
@objc
@ -1338,17 +1387,11 @@ public enum SSKProtoError: Error {
}
fileprivate class func parseProto(_ proto: SignalServiceProtos_DataMessage.Contact.Email) throws -> SSKProtoDataMessageContactEmail {
guard proto.hasValue else {
throw SSKProtoError.invalidProtobuf(description: "\(logTag) missing required field: value")
}
let value = proto.value
// MARK: - Begin Validation Logic for SSKProtoDataMessageContactEmail -
// MARK: - End Validation Logic for SSKProtoDataMessageContactEmail -
let result = SSKProtoDataMessageContactEmail(proto: proto,
value: value)
let result = SSKProtoDataMessageContactEmail(proto: proto)
return result
}
}
@ -1573,6 +1616,9 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_DataMessage.Contact.Avatar
@objc public let avatar: SSKProtoAttachmentPointer?
@objc public var hasAvatar: Bool {
return proto.hasAvatar
}
@objc public var isProfile: Bool {
return proto.isProfile
@ -1688,10 +1734,20 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_DataMessage.Contact
@objc public let name: SSKProtoDataMessageContactName?
@objc public var hasName: Bool {
return proto.hasName
}
@objc public let number: [SSKProtoDataMessageContactPhone]
@objc public let email: [SSKProtoDataMessageContactEmail]
@objc public let address: [SSKProtoDataMessageContactPostalAddress]
@objc public let avatar: SSKProtoDataMessageContactAvatar?
@objc public var hasAvatar: Bool {
return proto.hasAvatar
}
@objc public var organization: String? {
guard proto.hasOrganization else {
@ -1871,8 +1927,17 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_DataMessage
@objc public let attachments: [SSKProtoAttachmentPointer]
@objc public let group: SSKProtoGroupContext?
@objc public var hasGroup: Bool {
return proto.hasGroup
}
@objc public let quote: SSKProtoDataMessageQuote?
@objc public var hasQuote: Bool {
return proto.hasQuote
}
@objc public let contact: [SSKProtoDataMessageContact]
@objc public var body: String? {
@ -2287,6 +2352,9 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_SyncMessage.Sent
@objc public let message: SSKProtoDataMessage?
@objc public var hasMessage: Bool {
return proto.hasMessage
}
@objc public var destination: String? {
guard proto.hasDestination else {
@ -2438,6 +2506,9 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_SyncMessage.Groups
@objc public let blob: SSKProtoAttachmentPointer?
@objc public var hasBlob: Bool {
return proto.hasBlob
}
private init(proto: SignalServiceProtos_SyncMessage.Groups,
blob: SSKProtoAttachmentPointer?) {
@ -2650,6 +2721,7 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_SyncMessage.Read
@objc public let sender: String
@objc public let timestamp: UInt64
private init(proto: SignalServiceProtos_SyncMessage.Read,
@ -2814,13 +2886,41 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_SyncMessage
@objc public let sent: SSKProtoSyncMessageSent?
@objc public var hasSent: Bool {
return proto.hasSent
}
@objc public let contacts: SSKProtoSyncMessageContacts?
@objc public var hasContacts: Bool {
return proto.hasContacts
}
@objc public let groups: SSKProtoSyncMessageGroups?
@objc public var hasGroups: Bool {
return proto.hasGroups
}
@objc public let request: SSKProtoSyncMessageRequest?
@objc public var hasRequest: Bool {
return proto.hasRequest
}
@objc public let read: [SSKProtoSyncMessageRead]
@objc public let blocked: SSKProtoSyncMessageBlocked?
@objc public var hasBlocked: Bool {
return proto.hasBlocked
}
@objc public let verified: SSKProtoVerified?
@objc public var hasVerified: Bool {
return proto.hasVerified
}
@objc public let configuration: SSKProtoSyncMessageConfiguration?
@objc public var hasConfiguration: Bool {
return proto.hasConfiguration
}
@objc public var padding: Data? {
guard proto.hasPadding else {
@ -3192,8 +3292,13 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_GroupContext
@objc public let id: Data
@objc public let type: SSKProtoGroupContextType
@objc public let avatar: SSKProtoAttachmentPointer?
@objc public var hasAvatar: Bool {
return proto.hasAvatar
}
@objc public var name: String? {
guard proto.hasName else {
@ -3379,8 +3484,16 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_ContactDetails
@objc public let number: String
@objc public let avatar: SSKProtoContactDetailsAvatar?
@objc public var hasAvatar: Bool {
return proto.hasAvatar
}
@objc public let verified: SSKProtoVerified?
@objc public var hasVerified: Bool {
return proto.hasVerified
}
@objc public var name: String? {
guard proto.hasName else {
@ -3602,7 +3715,11 @@ public enum SSKProtoError: Error {
fileprivate let proto: SignalServiceProtos_GroupDetails
@objc public let id: Data
@objc public let avatar: SSKProtoGroupDetailsAvatar?
@objc public var hasAvatar: Bool {
return proto.hasAvatar
}
@objc public var name: String? {
guard proto.hasName else {

View File

@ -784,7 +784,6 @@ struct SignalServiceProtos_DataMessage {
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// @required
var value: String {
get {return _value ?? String()}
set {_value = newValue}
@ -858,7 +857,6 @@ struct SignalServiceProtos_DataMessage {
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
// methods supported on all messages.
/// @required
var value: String {
get {return _value ?? String()}
set {_value = newValue}