1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 #import <Foundation/Foundation.h>
33 #import "GPBUtilities.h"
35 #import "GPBDescriptor_PackagePrivate.h"
37 // Macros for stringifying library symbols. These are used in the generated
38 // PB descriptor classes wherever a library symbol name is represented as a
39 // string. See README.google for more information.
40 #define GPBStringify(S) #S
41 #define GPBStringifySymbol(S) GPBStringify(S)
43 #define GPBNSStringify(S) @#S
44 #define GPBNSStringifySymbol(S) GPBNSStringify(S)
46 // Constant to internally mark when there is no has bit.
47 #define GPBNoHasBit INT32_MAX
51 // These two are used to inject a runtime check for version mismatch into the
52 // generated sources to make sure they are linked with a supporting runtime.
53 void GPBCheckRuntimeVersionSupport(int32_t objcRuntimeVersion);
54 GPB_INLINE void GPB_DEBUG_CHECK_RUNTIME_VERSIONS() {
55 // NOTE: By being inline here, this captures the value from the library's
56 // headers at the time the generated code was compiled.
57 #if defined(DEBUG) && DEBUG
58 GPBCheckRuntimeVersionSupport(GOOGLE_PROTOBUF_OBJC_VERSION);
62 // Legacy version of the checks, remove when GOOGLE_PROTOBUF_OBJC_GEN_VERSION
63 // goes away (see more info in GPBBootstrap.h).
64 void GPBCheckRuntimeVersionInternal(int32_t version);
65 GPB_INLINE void GPBDebugCheckRuntimeVersion() {
66 #if defined(DEBUG) && DEBUG
67 GPBCheckRuntimeVersionInternal(GOOGLE_PROTOBUF_OBJC_GEN_VERSION);
71 // Conversion functions for de/serializing floating point types.
73 GPB_INLINE int64_t GPBConvertDoubleToInt64(double v) {
74 union { double f; int64_t i; } u;
79 GPB_INLINE int32_t GPBConvertFloatToInt32(float v) {
80 union { float f; int32_t i; } u;
85 GPB_INLINE double GPBConvertInt64ToDouble(int64_t v) {
86 union { double f; int64_t i; } u;
91 GPB_INLINE float GPBConvertInt32ToFloat(int32_t v) {
92 union { float f; int32_t i; } u;
97 GPB_INLINE int32_t GPBLogicalRightShift32(int32_t value, int32_t spaces) {
98 return (int32_t)((uint32_t)(value) >> spaces);
101 GPB_INLINE int64_t GPBLogicalRightShift64(int64_t value, int32_t spaces) {
102 return (int64_t)((uint64_t)(value) >> spaces);
105 // Decode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
106 // into values that can be efficiently encoded with varint. (Otherwise,
107 // negative values must be sign-extended to 64 bits to be varint encoded,
108 // thus always taking 10 bytes on the wire.)
109 GPB_INLINE int32_t GPBDecodeZigZag32(uint32_t n) {
110 return (int32_t)(GPBLogicalRightShift32((int32_t)n, 1) ^ -((int32_t)(n) & 1));
113 // Decode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
114 // into values that can be efficiently encoded with varint. (Otherwise,
115 // negative values must be sign-extended to 64 bits to be varint encoded,
116 // thus always taking 10 bytes on the wire.)
117 GPB_INLINE int64_t GPBDecodeZigZag64(uint64_t n) {
118 return (int64_t)(GPBLogicalRightShift64((int64_t)n, 1) ^ -((int64_t)(n) & 1));
121 // Encode a ZigZag-encoded 32-bit value. ZigZag encodes signed integers
122 // into values that can be efficiently encoded with varint. (Otherwise,
123 // negative values must be sign-extended to 64 bits to be varint encoded,
124 // thus always taking 10 bytes on the wire.)
125 GPB_INLINE uint32_t GPBEncodeZigZag32(int32_t n) {
126 // Note: the right-shift must be arithmetic
127 return ((uint32_t)n << 1) ^ (uint32_t)(n >> 31);
130 // Encode a ZigZag-encoded 64-bit value. ZigZag encodes signed integers
131 // into values that can be efficiently encoded with varint. (Otherwise,
132 // negative values must be sign-extended to 64 bits to be varint encoded,
133 // thus always taking 10 bytes on the wire.)
134 GPB_INLINE uint64_t GPBEncodeZigZag64(int64_t n) {
135 // Note: the right-shift must be arithmetic
136 return ((uint64_t)n << 1) ^ (uint64_t)(n >> 63);
139 #pragma clang diagnostic push
140 #pragma clang diagnostic ignored "-Wswitch-enum"
141 #pragma clang diagnostic ignored "-Wdirect-ivar-access"
143 GPB_INLINE BOOL GPBDataTypeIsObject(GPBDataType type) {
145 case GPBDataTypeBytes:
146 case GPBDataTypeString:
147 case GPBDataTypeMessage:
148 case GPBDataTypeGroup:
155 GPB_INLINE BOOL GPBDataTypeIsMessage(GPBDataType type) {
157 case GPBDataTypeMessage:
158 case GPBDataTypeGroup:
165 GPB_INLINE BOOL GPBFieldDataTypeIsMessage(GPBFieldDescriptor *field) {
166 return GPBDataTypeIsMessage(field->description_->dataType);
169 GPB_INLINE BOOL GPBFieldDataTypeIsObject(GPBFieldDescriptor *field) {
170 return GPBDataTypeIsObject(field->description_->dataType);
173 GPB_INLINE BOOL GPBExtensionIsMessage(GPBExtensionDescriptor *ext) {
174 return GPBDataTypeIsMessage(ext->description_->dataType);
177 // The field is an array/map or it has an object value.
178 GPB_INLINE BOOL GPBFieldStoresObject(GPBFieldDescriptor *field) {
179 GPBMessageFieldDescription *desc = field->description_;
180 if ((desc->flags & (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0) {
183 return GPBDataTypeIsObject(desc->dataType);
186 BOOL GPBGetHasIvar(GPBMessage *self, int32_t index, uint32_t fieldNumber);
187 void GPBSetHasIvar(GPBMessage *self, int32_t idx, uint32_t fieldNumber,
189 uint32_t GPBGetHasOneof(GPBMessage *self, int32_t index);
192 GPBGetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field) {
193 GPBMessageFieldDescription *fieldDesc = field->description_;
194 return GPBGetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number);
196 GPB_INLINE void GPBSetHasIvarField(GPBMessage *self, GPBFieldDescriptor *field,
198 GPBMessageFieldDescription *fieldDesc = field->description_;
199 GPBSetHasIvar(self, fieldDesc->hasIndex, fieldDesc->number, value);
202 void GPBMaybeClearOneof(GPBMessage *self, GPBOneofDescriptor *oneof,
203 int32_t oneofHasIndex, uint32_t fieldNumberNotToClear);
205 #pragma clang diagnostic pop
207 //%PDDM-DEFINE GPB_IVAR_SET_DECL(NAME, TYPE)
208 //%void GPBSet##NAME##IvarWithFieldInternal(GPBMessage *self,
209 //% NAME$S GPBFieldDescriptor *field,
210 //% NAME$S TYPE value,
211 //% NAME$S GPBFileSyntax syntax);
212 //%PDDM-EXPAND GPB_IVAR_SET_DECL(Bool, BOOL)
213 // This block of code is generated, do not edit it directly.
215 void GPBSetBoolIvarWithFieldInternal(GPBMessage *self,
216 GPBFieldDescriptor *field,
218 GPBFileSyntax syntax);
219 //%PDDM-EXPAND GPB_IVAR_SET_DECL(Int32, int32_t)
220 // This block of code is generated, do not edit it directly.
222 void GPBSetInt32IvarWithFieldInternal(GPBMessage *self,
223 GPBFieldDescriptor *field,
225 GPBFileSyntax syntax);
226 //%PDDM-EXPAND GPB_IVAR_SET_DECL(UInt32, uint32_t)
227 // This block of code is generated, do not edit it directly.
229 void GPBSetUInt32IvarWithFieldInternal(GPBMessage *self,
230 GPBFieldDescriptor *field,
232 GPBFileSyntax syntax);
233 //%PDDM-EXPAND GPB_IVAR_SET_DECL(Int64, int64_t)
234 // This block of code is generated, do not edit it directly.
236 void GPBSetInt64IvarWithFieldInternal(GPBMessage *self,
237 GPBFieldDescriptor *field,
239 GPBFileSyntax syntax);
240 //%PDDM-EXPAND GPB_IVAR_SET_DECL(UInt64, uint64_t)
241 // This block of code is generated, do not edit it directly.
243 void GPBSetUInt64IvarWithFieldInternal(GPBMessage *self,
244 GPBFieldDescriptor *field,
246 GPBFileSyntax syntax);
247 //%PDDM-EXPAND GPB_IVAR_SET_DECL(Float, float)
248 // This block of code is generated, do not edit it directly.
250 void GPBSetFloatIvarWithFieldInternal(GPBMessage *self,
251 GPBFieldDescriptor *field,
253 GPBFileSyntax syntax);
254 //%PDDM-EXPAND GPB_IVAR_SET_DECL(Double, double)
255 // This block of code is generated, do not edit it directly.
257 void GPBSetDoubleIvarWithFieldInternal(GPBMessage *self,
258 GPBFieldDescriptor *field,
260 GPBFileSyntax syntax);
261 //%PDDM-EXPAND GPB_IVAR_SET_DECL(Enum, int32_t)
262 // This block of code is generated, do not edit it directly.
264 void GPBSetEnumIvarWithFieldInternal(GPBMessage *self,
265 GPBFieldDescriptor *field,
267 GPBFileSyntax syntax);
268 //%PDDM-EXPAND-END (8 expansions)
270 int32_t GPBGetEnumIvarWithFieldInternal(GPBMessage *self,
271 GPBFieldDescriptor *field,
272 GPBFileSyntax syntax);
274 id GPBGetObjectIvarWithField(GPBMessage *self, GPBFieldDescriptor *field);
276 void GPBSetObjectIvarWithFieldInternal(GPBMessage *self,
277 GPBFieldDescriptor *field, id value,
278 GPBFileSyntax syntax);
279 void GPBSetRetainedObjectIvarWithFieldInternal(GPBMessage *self,
280 GPBFieldDescriptor *field,
281 id __attribute__((ns_consumed))
283 GPBFileSyntax syntax);
285 // GPBGetObjectIvarWithField will automatically create the field (message) if
286 // it doesn't exist. GPBGetObjectIvarWithFieldNoAutocreate will return nil.
287 id GPBGetObjectIvarWithFieldNoAutocreate(GPBMessage *self,
288 GPBFieldDescriptor *field);
290 void GPBSetAutocreatedRetainedObjectIvarWithField(
291 GPBMessage *self, GPBFieldDescriptor *field,
292 id __attribute__((ns_consumed)) value);
294 // Clears and releases the autocreated message ivar, if it's autocreated. If
295 // it's not set as autocreated, this method does nothing.
296 void GPBClearAutocreatedMessageIvarWithField(GPBMessage *self,
297 GPBFieldDescriptor *field);
299 // Returns an Objective C encoding for |selector|. |instanceSel| should be
300 // YES if it's an instance selector (as opposed to a class selector).
301 // |selector| must be a selector from MessageSignatureProtocol.
302 const char *GPBMessageEncodingForSelector(SEL selector, BOOL instanceSel);
304 // Helper for text format name encoding.
305 // decodeData is the data describing the sepecial decodes.
306 // key and inputString are the input that needs decoding.
307 NSString *GPBDecodeTextFormatName(const uint8_t *decodeData, int32_t key,
308 NSString *inputString);
310 // A series of selectors that are used solely to get @encoding values
311 // for them by the dynamic protobuf runtime code. See
312 // GPBMessageEncodingForSelector for details. GPBRootObject conforms to
313 // the protocol so that it is encoded in the Objective C runtime.
314 @protocol GPBMessageSignatureProtocol
317 #define GPB_MESSAGE_SIGNATURE_ENTRY(TYPE, NAME) \
319 -(void)set##NAME : (TYPE)value; \
320 -(TYPE)get##NAME##AtIndex : (NSUInteger)index;
322 GPB_MESSAGE_SIGNATURE_ENTRY(BOOL, Bool)
323 GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, Fixed32)
324 GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SFixed32)
325 GPB_MESSAGE_SIGNATURE_ENTRY(float, Float)
326 GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, Fixed64)
327 GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SFixed64)
328 GPB_MESSAGE_SIGNATURE_ENTRY(double, Double)
329 GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, Int32)
330 GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, Int64)
331 GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, SInt32)
332 GPB_MESSAGE_SIGNATURE_ENTRY(int64_t, SInt64)
333 GPB_MESSAGE_SIGNATURE_ENTRY(uint32_t, UInt32)
334 GPB_MESSAGE_SIGNATURE_ENTRY(uint64_t, UInt64)
335 GPB_MESSAGE_SIGNATURE_ENTRY(NSData *, Bytes)
336 GPB_MESSAGE_SIGNATURE_ENTRY(NSString *, String)
337 GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Message)
338 GPB_MESSAGE_SIGNATURE_ENTRY(GPBMessage *, Group)
339 GPB_MESSAGE_SIGNATURE_ENTRY(int32_t, Enum)
341 #undef GPB_MESSAGE_SIGNATURE_ENTRY
344 - (NSUInteger)getArrayCount;
345 - (void)setArray:(NSArray *)array;
349 BOOL GPBClassHasSel(Class aClass, SEL sel);