GPBDescriptor_PackagePrivate.h 11.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
// 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.

// This header is private to the ProtobolBuffers library and must NOT be
// included by any sources outside this library. The contents of this file are
// subject to change at any time without notice.

#import "GPBDescriptor.h"
36
#import "GPBWireFormat.h"
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85

// Describes attributes of the field.
typedef NS_OPTIONS(uint32_t, GPBFieldFlags) {
  // These map to standard protobuf concepts.
  GPBFieldRequired        = 1 << 0,
  GPBFieldRepeated        = 1 << 1,
  GPBFieldPacked          = 1 << 2,
  GPBFieldOptional        = 1 << 3,
  GPBFieldHasDefaultValue = 1 << 4,

  // These are not standard protobuf concepts, they are specific to the
  // Objective C runtime.

  // These bits are used to mark the field as a map and what the key
  // type is.
  GPBFieldMapKeyMask     = 0xF << 8,
  GPBFieldMapKeyInt32    =  1 << 8,
  GPBFieldMapKeyInt64    =  2 << 8,
  GPBFieldMapKeyUInt32   =  3 << 8,
  GPBFieldMapKeyUInt64   =  4 << 8,
  GPBFieldMapKeySInt32   =  5 << 8,
  GPBFieldMapKeySInt64   =  6 << 8,
  GPBFieldMapKeyFixed32  =  7 << 8,
  GPBFieldMapKeyFixed64  =  8 << 8,
  GPBFieldMapKeySFixed32 =  9 << 8,
  GPBFieldMapKeySFixed64 = 10 << 8,
  GPBFieldMapKeyBool     = 11 << 8,
  GPBFieldMapKeyString   = 12 << 8,

  // Indicates the field needs custom handling for the TextFormat name, if not
  // set, the name can be derived from the ObjC name.
  GPBFieldTextFormatNameCustom = 1 << 16,
  // Indicates the field has an enum descriptor.
  GPBFieldHasEnumDescriptor = 1 << 17,
};

// Describes a single field in a protobuf as it is represented as an ivar.
typedef struct GPBMessageFieldDescription {
  // Name of ivar.
  const char *name;
  // The field number for the ivar.
  uint32_t number;
  // The index (in bits) into _has_storage_.
  //   > 0: the bit to use for a value being set.
  //   = 0: no storage used.
  //   < 0: in a oneOf, use a full int32 to record the field active.
  int32_t hasIndex;
  // Field flags. Use accessor functions below.
  GPBFieldFlags flags;
86 87
  // Data type of the ivar.
  GPBDataType dataType;
88 89 90 91 92
  // Offset of the variable into it's structure struct.
  size_t offset;
  // FieldOptions protobuf, serialized as string.
  const char *fieldOptions;

93
  GPBGenericValue defaultValue;  // Default value for the ivar.
94 95 96 97 98 99
  union {
    const char *className;  // Name for message class.
    // For enums only: If EnumDescriptors are compiled in, it will be that,
    // otherwise it will be the verifier.
    GPBEnumDescriptorFunc enumDescFunc;
    GPBEnumValidationFunc enumVerifier;
100
  } dataTypeSpecific;
101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
} GPBMessageFieldDescription;

// Describes a oneof.
typedef struct GPBMessageOneofDescription {
  // Name of this enum oneof.
  const char *name;
  // The index of this oneof in the has_storage.
  int32_t index;
} GPBMessageOneofDescription;

// Describes an enum type defined in a .proto file.
typedef struct GPBMessageEnumDescription {
  GPBEnumDescriptorFunc enumDescriptorFunc;
} GPBMessageEnumDescription;

// Describes an individual enum constant of a particular type.
typedef struct GPBMessageEnumValueDescription {
  // Name of this enum constant.
  const char *name;
  // Numeric value of this enum constant.
  int32_t number;
} GPBMessageEnumValueDescription;

// Describes attributes of the extension.
typedef NS_OPTIONS(uint32_t, GPBExtensionOptions) {
  // These map to standard protobuf concepts.
  GPBExtensionRepeated      = 1 << 0,
  GPBExtensionPacked        = 1 << 1,
  GPBExtensionSetWireFormat = 1 << 2,
};

// An extension
typedef struct GPBExtensionDescription {
  const char *singletonName;
135
  GPBDataType dataType;
136 137
  const char *extendedClass;
  int32_t fieldNumber;
138
  GPBGenericValue defaultValue;
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218
  const char *messageOrGroupClassName;
  GPBExtensionOptions options;
  GPBEnumDescriptorFunc enumDescriptorFunc;
} GPBExtensionDescription;

@interface GPBDescriptor () {
 @package
  NSArray *fields_;
  NSArray *oneofs_;
  size_t storageSize_;
}

// fieldDescriptions, enumDescriptions, rangeDescriptions, and
// extraTextFormatInfo have to be long lived, they are held as raw pointers.
+ (instancetype)
    allocDescriptorForClass:(Class)messageClass
                  rootClass:(Class)rootClass
                       file:(GPBFileDescriptor *)file
                     fields:(GPBMessageFieldDescription *)fieldDescriptions
                 fieldCount:(NSUInteger)fieldCount
                     oneofs:(GPBMessageOneofDescription *)oneofDescriptions
                 oneofCount:(NSUInteger)oneofCount
                      enums:(GPBMessageEnumDescription *)enumDescriptions
                  enumCount:(NSUInteger)enumCount
                     ranges:(const GPBExtensionRange *)ranges
                 rangeCount:(NSUInteger)rangeCount
                storageSize:(size_t)storageSize
                 wireFormat:(BOOL)wireFormat;
+ (instancetype)
    allocDescriptorForClass:(Class)messageClass
                  rootClass:(Class)rootClass
                       file:(GPBFileDescriptor *)file
                     fields:(GPBMessageFieldDescription *)fieldDescriptions
                 fieldCount:(NSUInteger)fieldCount
                     oneofs:(GPBMessageOneofDescription *)oneofDescriptions
                 oneofCount:(NSUInteger)oneofCount
                      enums:(GPBMessageEnumDescription *)enumDescriptions
                  enumCount:(NSUInteger)enumCount
                     ranges:(const GPBExtensionRange *)ranges
                 rangeCount:(NSUInteger)rangeCount
                storageSize:(size_t)storageSize
                 wireFormat:(BOOL)wireFormat
        extraTextFormatInfo:(const char *)extraTextFormatInfo;

- (instancetype)initWithClass:(Class)messageClass
                         file:(GPBFileDescriptor *)file
                       fields:(NSArray *)fields
                       oneofs:(NSArray *)oneofs
                        enums:(NSArray *)enums
              extensionRanges:(const GPBExtensionRange *)ranges
         extensionRangesCount:(NSUInteger)rangeCount
                  storageSize:(size_t)storage
                   wireFormat:(BOOL)wireFormat;

@end

@interface GPBFileDescriptor ()
- (instancetype)initWithPackage:(NSString *)package
                         syntax:(GPBFileSyntax)syntax;
@end

@interface GPBOneofDescriptor () {
 @package
  GPBMessageOneofDescription *oneofDescription_;
  NSArray *fields_;

  SEL caseSel_;
}
- (instancetype)initWithOneofDescription:
                    (GPBMessageOneofDescription *)oneofDescription
                                  fields:(NSArray *)fields;
@end

@interface GPBFieldDescriptor () {
 @package
  GPBMessageFieldDescription *description_;
  GPB_UNSAFE_UNRETAINED GPBOneofDescriptor *containingOneof_;

  SEL getSel_;
  SEL setSel_;
219
  SEL hasOrCountSel_;  // *Count for map<>/repeated fields, has* otherwise.
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
  SEL setHasSel_;
}

// Single initializer
// description has to be long lived, it is held as a raw pointer.
- (instancetype)initWithFieldDescription:
                    (GPBMessageFieldDescription *)description
                               rootClass:(Class)rootClass
                                  syntax:(GPBFileSyntax)syntax;
@end

@interface GPBEnumDescriptor ()
// valueDescriptions and extraTextFormatInfo have to be long lived, they are
// held as raw pointers.
+ (instancetype)
    allocDescriptorForName:(NSString *)name
                    values:(GPBMessageEnumValueDescription *)valueDescriptions
                valueCount:(NSUInteger)valueCount
              enumVerifier:(GPBEnumValidationFunc)enumVerifier;
+ (instancetype)
    allocDescriptorForName:(NSString *)name
                    values:(GPBMessageEnumValueDescription *)valueDescriptions
                valueCount:(NSUInteger)valueCount
              enumVerifier:(GPBEnumValidationFunc)enumVerifier
       extraTextFormatInfo:(const char *)extraTextFormatInfo;

- (instancetype)initWithName:(NSString *)name
                      values:(GPBMessageEnumValueDescription *)valueDescriptions
                  valueCount:(NSUInteger)valueCount
                enumVerifier:(GPBEnumValidationFunc)enumVerifier;
@end

@interface GPBExtensionDescriptor () {
 @package
  GPBExtensionDescription *description_;
}
256 257 258 259 260 261 262
@property(nonatomic, readonly) GPBWireFormat wireType;

// For repeated extensions, alternateWireType is the wireType with the opposite
// value for the packable property.  i.e. - if the extension was marked packed
// it would be the wire type for unpacked; if the extension was marked unpacked,
// it would be the wire type for packed.
@property(nonatomic, readonly) GPBWireFormat alternateWireType;
263 264 265

// description has to be long lived, it is held as a raw pointer.
- (instancetype)initWithExtensionDescription:
266 267
    (GPBExtensionDescription *)description;
- (NSComparisonResult)compareByFieldNumber:(GPBExtensionDescriptor *)other;
268 269 270 271 272 273 274 275 276
@end

CF_EXTERN_C_BEGIN

GPB_INLINE BOOL GPBFieldIsMapOrArray(GPBFieldDescriptor *field) {
  return (field->description_->flags &
          (GPBFieldRepeated | GPBFieldMapKeyMask)) != 0;
}

277 278
GPB_INLINE GPBDataType GPBGetFieldDataType(GPBFieldDescriptor *field) {
  return field->description_->dataType;
279 280 281 282 283 284 285 286 287 288 289 290
}

GPB_INLINE int32_t GPBFieldHasIndex(GPBFieldDescriptor *field) {
  return field->description_->hasIndex;
}

GPB_INLINE uint32_t GPBFieldNumber(GPBFieldDescriptor *field) {
  return field->description_->number;
}

uint32_t GPBFieldTag(GPBFieldDescriptor *self);

291 292 293 294 295 296
// For repeated fields, alternateWireType is the wireType with the opposite
// value for the packable property.  i.e. - if the field was marked packed it
// would be the wire type for unpacked; if the field was marked unpacked, it
// would be the wire type for packed.
uint32_t GPBFieldAlternateTag(GPBFieldDescriptor *self);

297 298 299 300 301 302 303 304
GPB_INLINE BOOL GPBPreserveUnknownFields(GPBFileSyntax syntax) {
  return syntax != GPBFileSyntaxProto3;
}

GPB_INLINE BOOL GPBHasPreservingUnknownEnumSemantics(GPBFileSyntax syntax) {
  return syntax == GPBFileSyntaxProto3;
}

305 306 307 308 309 310 311 312 313 314 315 316 317
GPB_INLINE BOOL GPBExtensionIsRepeated(GPBExtensionDescription *description) {
  return (description->options & GPBExtensionRepeated) != 0;
}

GPB_INLINE BOOL GPBExtensionIsPacked(GPBExtensionDescription *description) {
  return (description->options & GPBExtensionPacked) != 0;
}

GPB_INLINE BOOL GPBExtensionIsWireFormat(GPBExtensionDescription *description) {
  return (description->options & GPBExtensionSetWireFormat) != 0;
}


318
CF_EXTERN_C_END