GPBDescriptor_PackagePrivate.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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. // This header is private to the ProtobolBuffers library and must NOT be
  31. // included by any sources outside this library. The contents of this file are
  32. // subject to change at any time without notice.
  33. #import "GPBDescriptor.h"
  34. #import "GPBWireFormat.h"
  35. // Describes attributes of the field.
  36. typedef NS_OPTIONS(uint16_t, GPBFieldFlags) {
  37. // These map to standard protobuf concepts.
  38. GPBFieldRequired = 1 << 0,
  39. GPBFieldRepeated = 1 << 1,
  40. GPBFieldPacked = 1 << 2,
  41. GPBFieldOptional = 1 << 3,
  42. GPBFieldHasDefaultValue = 1 << 4,
  43. // Indicates the field needs custom handling for the TextFormat name, if not
  44. // set, the name can be derived from the ObjC name.
  45. GPBFieldTextFormatNameCustom = 1 << 6,
  46. // Indicates the field has an enum descriptor.
  47. GPBFieldHasEnumDescriptor = 1 << 7,
  48. // These are not standard protobuf concepts, they are specific to the
  49. // Objective C runtime.
  50. // These bits are used to mark the field as a map and what the key
  51. // type is.
  52. GPBFieldMapKeyMask = 0xF << 8,
  53. GPBFieldMapKeyInt32 = 1 << 8,
  54. GPBFieldMapKeyInt64 = 2 << 8,
  55. GPBFieldMapKeyUInt32 = 3 << 8,
  56. GPBFieldMapKeyUInt64 = 4 << 8,
  57. GPBFieldMapKeySInt32 = 5 << 8,
  58. GPBFieldMapKeySInt64 = 6 << 8,
  59. GPBFieldMapKeyFixed32 = 7 << 8,
  60. GPBFieldMapKeyFixed64 = 8 << 8,
  61. GPBFieldMapKeySFixed32 = 9 << 8,
  62. GPBFieldMapKeySFixed64 = 10 << 8,
  63. GPBFieldMapKeyBool = 11 << 8,
  64. GPBFieldMapKeyString = 12 << 8,
  65. };
  66. // NOTE: The structures defined here have their members ordered to minimize
  67. // their size. This directly impacts the size of apps since these exist per
  68. // field/extension.
  69. // Describes a single field in a protobuf as it is represented as an ivar.
  70. typedef struct GPBMessageFieldDescription {
  71. // Name of ivar.
  72. const char *name;
  73. union {
  74. const char *className; // Name for message class.
  75. // For enums only: If EnumDescriptors are compiled in, it will be that,
  76. // otherwise it will be the verifier.
  77. GPBEnumDescriptorFunc enumDescFunc;
  78. GPBEnumValidationFunc enumVerifier;
  79. } dataTypeSpecific;
  80. // The field number for the ivar.
  81. uint32_t number;
  82. // The index (in bits) into _has_storage_.
  83. // >= 0: the bit to use for a value being set.
  84. // = GPBNoHasBit(INT32_MAX): no storage used.
  85. // < 0: in a oneOf, use a full int32 to record the field active.
  86. int32_t hasIndex;
  87. // Offset of the variable into it's structure struct.
  88. uint32_t offset;
  89. // Field flags. Use accessor functions below.
  90. GPBFieldFlags flags;
  91. // Data type of the ivar.
  92. GPBDataType dataType;
  93. } GPBMessageFieldDescription;
  94. // Fields in messages defined in a 'proto2' syntax file can provide a default
  95. // value. This struct provides the default along with the field info.
  96. typedef struct GPBMessageFieldDescriptionWithDefault {
  97. // Default value for the ivar.
  98. GPBGenericValue defaultValue;
  99. GPBMessageFieldDescription core;
  100. } GPBMessageFieldDescriptionWithDefault;
  101. // Describes attributes of the extension.
  102. typedef NS_OPTIONS(uint8_t, GPBExtensionOptions) {
  103. // These map to standard protobuf concepts.
  104. GPBExtensionRepeated = 1 << 0,
  105. GPBExtensionPacked = 1 << 1,
  106. GPBExtensionSetWireFormat = 1 << 2,
  107. };
  108. // An extension
  109. typedef struct GPBExtensionDescription {
  110. GPBGenericValue defaultValue;
  111. const char *singletonName;
  112. const char *extendedClass;
  113. const char *messageOrGroupClassName;
  114. GPBEnumDescriptorFunc enumDescriptorFunc;
  115. int32_t fieldNumber;
  116. GPBDataType dataType;
  117. GPBExtensionOptions options;
  118. } GPBExtensionDescription;
  119. typedef NS_OPTIONS(uint32_t, GPBDescriptorInitializationFlags) {
  120. GPBDescriptorInitializationFlag_FieldsWithDefault = 1 << 0,
  121. GPBDescriptorInitializationFlag_WireFormat = 1 << 1,
  122. };
  123. @interface GPBDescriptor () {
  124. @package
  125. NSArray *fields_;
  126. NSArray *oneofs_;
  127. uint32_t storageSize_;
  128. }
  129. // fieldDescriptions have to be long lived, they are held as raw pointers.
  130. + (instancetype)
  131. allocDescriptorForClass:(Class)messageClass
  132. rootClass:(Class)rootClass
  133. file:(GPBFileDescriptor *)file
  134. fields:(void *)fieldDescriptions
  135. fieldCount:(uint32_t)fieldCount
  136. storageSize:(uint32_t)storageSize
  137. flags:(GPBDescriptorInitializationFlags)flags;
  138. - (instancetype)initWithClass:(Class)messageClass
  139. file:(GPBFileDescriptor *)file
  140. fields:(NSArray *)fields
  141. storageSize:(uint32_t)storage
  142. wireFormat:(BOOL)wireFormat;
  143. // Called right after init to provide extra information to avoid init having
  144. // an explosion of args. These pointers are recorded, so they are expected
  145. // to live for the lifetime of the app.
  146. - (void)setupOneofs:(const char **)oneofNames
  147. count:(uint32_t)count
  148. firstHasIndex:(int32_t)firstHasIndex;
  149. - (void)setupExtraTextInfo:(const char *)extraTextFormatInfo;
  150. - (void)setupExtensionRanges:(const GPBExtensionRange *)ranges count:(int32_t)count;
  151. - (void)setupContainingMessageClassName:(const char *)msgClassName;
  152. - (void)setupMessageClassNameSuffix:(NSString *)suffix;
  153. @end
  154. @interface GPBFileDescriptor ()
  155. - (instancetype)initWithPackage:(NSString *)package
  156. objcPrefix:(NSString *)objcPrefix
  157. syntax:(GPBFileSyntax)syntax;
  158. - (instancetype)initWithPackage:(NSString *)package
  159. syntax:(GPBFileSyntax)syntax;
  160. @end
  161. @interface GPBOneofDescriptor () {
  162. @package
  163. const char *name_;
  164. NSArray *fields_;
  165. SEL caseSel_;
  166. }
  167. // name must be long lived.
  168. - (instancetype)initWithName:(const char *)name fields:(NSArray *)fields;
  169. @end
  170. @interface GPBFieldDescriptor () {
  171. @package
  172. GPBMessageFieldDescription *description_;
  173. GPB_UNSAFE_UNRETAINED GPBOneofDescriptor *containingOneof_;
  174. SEL getSel_;
  175. SEL setSel_;
  176. SEL hasOrCountSel_; // *Count for map<>/repeated fields, has* otherwise.
  177. SEL setHasSel_;
  178. }
  179. // Single initializer
  180. // description has to be long lived, it is held as a raw pointer.
  181. - (instancetype)initWithFieldDescription:(void *)description
  182. includesDefault:(BOOL)includesDefault
  183. syntax:(GPBFileSyntax)syntax;
  184. @end
  185. @interface GPBEnumDescriptor ()
  186. // valueNames, values and extraTextFormatInfo have to be long lived, they are
  187. // held as raw pointers.
  188. + (instancetype)
  189. allocDescriptorForName:(NSString *)name
  190. valueNames:(const char *)valueNames
  191. values:(const int32_t *)values
  192. count:(uint32_t)valueCount
  193. enumVerifier:(GPBEnumValidationFunc)enumVerifier;
  194. + (instancetype)
  195. allocDescriptorForName:(NSString *)name
  196. valueNames:(const char *)valueNames
  197. values:(const int32_t *)values
  198. count:(uint32_t)valueCount
  199. enumVerifier:(GPBEnumValidationFunc)enumVerifier
  200. extraTextFormatInfo:(const char *)extraTextFormatInfo;
  201. - (instancetype)initWithName:(NSString *)name
  202. valueNames:(const char *)valueNames
  203. values:(const int32_t *)values
  204. count:(uint32_t)valueCount
  205. enumVerifier:(GPBEnumValidationFunc)enumVerifier;
  206. @end
  207. @interface GPBExtensionDescriptor () {
  208. @package
  209. GPBExtensionDescription *description_;
  210. }
  211. @property(nonatomic, readonly) GPBWireFormat wireType;
  212. // For repeated extensions, alternateWireType is the wireType with the opposite
  213. // value for the packable property. i.e. - if the extension was marked packed
  214. // it would be the wire type for unpacked; if the extension was marked unpacked,
  215. // it would be the wire type for packed.
  216. @property(nonatomic, readonly) GPBWireFormat alternateWireType;
  217. // description has to be long lived, it is held as a raw pointer.
  218. - (instancetype)initWithExtensionDescription:
  219. (GPBExtensionDescription *)description;
  220. - (NSComparisonResult)compareByFieldNumber:(GPBExtensionDescriptor *)other;
  221. @end
  222. CF_EXTERN_C_BEGIN
  223. // Direct access is use for speed, to avoid even internally declaring things
  224. // read/write, etc. The warning is enabled in the project to ensure code calling
  225. // protos can turn on -Wdirect-ivar-access without issues.
  226. #pragma clang diagnostic push
  227. #pragma clang diagnostic ignored "-Wdirect-ivar-access"
  228. GPB_INLINE BOOL GPBFieldIsMapOrArray(GPBFieldDescriptor *field) {
  229. return (field->description_->flags &
  230. (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0;
  231. }
  232. GPB_INLINE GPBDataType GPBGetFieldDataType(GPBFieldDescriptor *field) {
  233. return field->description_->dataType;
  234. }
  235. GPB_INLINE int32_t GPBFieldHasIndex(GPBFieldDescriptor *field) {
  236. return field->description_->hasIndex;
  237. }
  238. GPB_INLINE uint32_t GPBFieldNumber(GPBFieldDescriptor *field) {
  239. return field->description_->number;
  240. }
  241. #pragma clang diagnostic pop
  242. uint32_t GPBFieldTag(GPBFieldDescriptor *self);
  243. // For repeated fields, alternateWireType is the wireType with the opposite
  244. // value for the packable property. i.e. - if the field was marked packed it
  245. // would be the wire type for unpacked; if the field was marked unpacked, it
  246. // would be the wire type for packed.
  247. uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self);
  248. GPB_INLINE BOOL GPBPreserveUnknownFields(GPBFileSyntax syntax) {
  249. return syntax != GPBFileSyntaxProto3;
  250. }
  251. GPB_INLINE BOOL GPBHasPreservingUnknownEnumSemantics(GPBFileSyntax syntax) {
  252. return syntax == GPBFileSyntaxProto3;
  253. }
  254. GPB_INLINE BOOL GPBExtensionIsRepeated(GPBExtensionDescription *description) {
  255. return (description->options & GPBExtensionRepeated) != 0;
  256. }
  257. GPB_INLINE BOOL GPBExtensionIsPacked(GPBExtensionDescription *description) {
  258. return (description->options & GPBExtensionPacked) != 0;
  259. }
  260. GPB_INLINE BOOL GPBExtensionIsWireFormat(GPBExtensionDescription *description) {
  261. return (description->options & GPBExtensionSetWireFormat) != 0;
  262. }
  263. // Helper for compile time assets.
  264. #ifndef GPBInternalCompileAssert
  265. #if __has_feature(c_static_assert) || __has_extension(c_static_assert)
  266. #define GPBInternalCompileAssert(test, msg) _Static_assert((test), #msg)
  267. #else
  268. // Pre-Xcode 7 support.
  269. #define GPBInternalCompileAssertSymbolInner(line, msg) GPBInternalCompileAssert ## line ## __ ## msg
  270. #define GPBInternalCompileAssertSymbol(line, msg) GPBInternalCompileAssertSymbolInner(line, msg)
  271. #define GPBInternalCompileAssert(test, msg) \
  272. typedef char GPBInternalCompileAssertSymbol(__LINE__, msg) [ ((test) ? 1 : -1) ]
  273. #endif // __has_feature(c_static_assert) || __has_extension(c_static_assert)
  274. #endif // GPBInternalCompileAssert
  275. // Sanity check that there isn't padding between the field description
  276. // structures with and without a default.
  277. GPBInternalCompileAssert(sizeof(GPBMessageFieldDescriptionWithDefault) ==
  278. (sizeof(GPBGenericValue) +
  279. sizeof(GPBMessageFieldDescription)),
  280. DescriptionsWithDefault_different_size_than_expected);
  281. CF_EXTERN_C_END