Home | History | Annotate | Download | only in objectivec
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // This header is private to the ProtobolBuffers library and must NOT be
     32 // included by any sources outside this library. The contents of this file are
     33 // subject to change at any time without notice.
     34 
     35 #import "GPBMessage.h"
     36 
     37 #import <libkern/OSAtomic.h>
     38 
     39 #import "GPBBootstrap.h"
     40 
     41 typedef struct GPBMessage_Storage {
     42   uint32_t _has_storage_[0];
     43 } GPBMessage_Storage;
     44 
     45 typedef struct GPBMessage_Storage *GPBMessage_StoragePtr;
     46 
     47 @interface GPBMessage () {
     48  @package
     49   // NOTE: Because of the +allocWithZone code using NSAllocateObject(),
     50   // this structure should ideally always be kept pointer aligned where the
     51   // real storage starts is also pointer aligned. The compiler/runtime already
     52   // do this, but it may not be documented.
     53 
     54   // A pointer to the actual fields of the subclasses. The actual structure
     55   // pointed to by this pointer will depend on the subclass.
     56   // All of the actual structures will start the same as
     57   // GPBMessage_Storage with _has_storage__ as the first field.
     58   // Kept public because static functions need to access it.
     59   GPBMessage_StoragePtr messageStorage_;
     60 
     61   // A lock to provide mutual exclusion from internal data that can be modified
     62   // by *read* operations such as getters (autocreation of message fields and
     63   // message extensions, not setting of values). Used to guarantee thread safety
     64   // for concurrent reads on the message.
     65   // NOTE: OSSpinLock may seem like a good fit here but Apple engineers have
     66   // pointed out that they are vulnerable to live locking on iOS in cases of
     67   // priority inversion:
     68   //   http://mjtsai.com/blog/2015/12/16/osspinlock-is-unsafe/
     69   //   https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20151214/000372.html
     70   // Use of readOnlySemaphore_ must be prefaced by a call to
     71   // GPBPrepareReadOnlySemaphore to ensure it has been created. This allows
     72   // readOnlySemaphore_ to be only created when actually needed.
     73   dispatch_once_t readOnlySemaphoreCreationOnce_;
     74   dispatch_semaphore_t readOnlySemaphore_;
     75 }
     76 
     77 // Gets an extension value without autocreating the result if not found. (i.e.
     78 // returns nil if the extension is not set)
     79 - (id)getExistingExtension:(GPBExtensionDescriptor *)extension;
     80 
     81 // Returns an array of GPBExtensionDescriptor* for all the extensions currently
     82 // in use on the message.  They are sorted by field number.
     83 - (NSArray *)sortedExtensionsInUse;
     84 
     85 // Parses a message of this type from the input and merges it with this
     86 // message.
     87 //
     88 // Warning:  This does not verify that all required fields are present in
     89 // the input message.
     90 // Note:  The caller should call
     91 // -[CodedInputStream checkLastTagWas:] after calling this to
     92 // verify that the last tag seen was the appropriate end-group tag,
     93 // or zero for EOF.
     94 // NOTE: This will throw if there is an error while parsing.
     95 - (void)mergeFromCodedInputStream:(GPBCodedInputStream *)input
     96                 extensionRegistry:(GPBExtensionRegistry *)extensionRegistry;
     97 
     98 // Parses the next delimited message of this type from the input and merges it
     99 // with this message.
    100 - (void)mergeDelimitedFromCodedInputStream:(GPBCodedInputStream *)input
    101                          extensionRegistry:
    102                              (GPBExtensionRegistry *)extensionRegistry;
    103 
    104 - (void)addUnknownMapEntry:(int32_t)fieldNum value:(NSData *)data;
    105 
    106 @end
    107 
    108 CF_EXTERN_C_BEGIN
    109 
    110 
    111 // Call this before using the readOnlySemaphore_. This ensures it is created only once.
    112 NS_INLINE void GPBPrepareReadOnlySemaphore(GPBMessage *self) {
    113   dispatch_once(&self->readOnlySemaphoreCreationOnce_, ^{
    114     self->readOnlySemaphore_ = dispatch_semaphore_create(1);
    115   });
    116 }
    117 
    118 // Returns a new instance that was automatically created by |autocreator| for
    119 // its field |field|.
    120 GPBMessage *GPBCreateMessageWithAutocreator(Class msgClass,
    121                                             GPBMessage *autocreator,
    122                                             GPBFieldDescriptor *field)
    123     __attribute__((ns_returns_retained));
    124 
    125 // Returns whether |message| autocreated this message. This is NO if the message
    126 // was not autocreated by |message| or if it has been mutated since
    127 // autocreation.
    128 BOOL GPBWasMessageAutocreatedBy(GPBMessage *message, GPBMessage *parent);
    129 
    130 // Call this when you mutate a message. It will cause the message to become
    131 // visible to its autocreator.
    132 void GPBBecomeVisibleToAutocreator(GPBMessage *self);
    133 
    134 // Call this when an array/dictionary is mutated so the parent message that
    135 // autocreated it can react.
    136 void GPBAutocreatedArrayModified(GPBMessage *self, id array);
    137 void GPBAutocreatedDictionaryModified(GPBMessage *self, id dictionary);
    138 
    139 // Clear the autocreator, if any. Asserts if the autocreator still has an
    140 // autocreated reference to this message.
    141 void GPBClearMessageAutocreator(GPBMessage *self);
    142 
    143 CF_EXTERN_C_END
    144