// Generated by the protocol buffer compiler.  DO NOT EDIT!

#import "Pair.pb.h"
// @@protoc_insertion_point(imports)

@implementation PairRoot
static PBExtensionRegistry* extensionRegistry = nil;
+ (PBExtensionRegistry*) extensionRegistry {
  return extensionRegistry;
}

+ (void) initialize {
  if (self == [PairRoot class]) {
    PBMutableExtensionRegistry* registry = [PBMutableExtensionRegistry registry];
    [self registerAllExtensions:registry];
    extensionRegistry = registry;
  }
}
+ (void) registerAllExtensions:(PBMutableExtensionRegistry*) registry {
}
@end

@interface Pair ()
@property (strong) NSString* key;
@property (strong) NSString* value;
@end

@implementation Pair

- (BOOL) hasKey {
  return !!hasKey_;
}
- (void) setHasKey:(BOOL) value_ {
  hasKey_ = !!value_;
}
@synthesize key;
- (BOOL) hasValue {
  return !!hasValue_;
}
- (void) setHasValue:(BOOL) value_ {
  hasValue_ = !!value_;
}
@synthesize value;
- (id) init {
  if ((self = [super init])) {
    self.key = @"";
    self.value = @"";
  }
  return self;
}
static Pair* defaultPairInstance = nil;
+ (void) initialize {
  if (self == [Pair class]) {
    defaultPairInstance = [[Pair alloc] init];
  }
}
+ (Pair*) defaultInstance {
  return defaultPairInstance;
}
- (Pair*) defaultInstance {
  return defaultPairInstance;
}
- (BOOL) isInitialized {
  return YES;
}
- (void) writeToCodedOutputStream:(PBCodedOutputStream*) output {
  if (self.hasKey) {
    [output writeString:1 value:self.key];
  }
  if (self.hasValue) {
    [output writeString:2 value:self.value];
  }
  [self.unknownFields writeToCodedOutputStream:output];
}
- (SInt32) serializedSize {
  __block SInt32 size_ = memoizedSerializedSize;
  if (size_ != -1) {
    return size_;
  }

  size_ = 0;
  if (self.hasKey) {
    size_ += computeStringSize(1, self.key);
  }
  if (self.hasValue) {
    size_ += computeStringSize(2, self.value);
  }
  size_ += self.unknownFields.serializedSize;
  memoizedSerializedSize = size_;
  return size_;
}
+ (Pair*) parseFromData:(NSData*) data {
  return (Pair*)[[[Pair builder] mergeFromData:data] build];
}
+ (Pair*) parseFromData:(NSData*) data extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
  return (Pair*)[[[Pair builder] mergeFromData:data extensionRegistry:extensionRegistry] build];
}
+ (Pair*) parseFromInputStream:(NSInputStream*) input {
  return (Pair*)[[[Pair builder] mergeFromInputStream:input] build];
}
+ (Pair*) parseFromInputStream:(NSInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
  return (Pair*)[[[Pair builder] mergeFromInputStream:input extensionRegistry:extensionRegistry] build];
}
+ (Pair*) parseFromCodedInputStream:(PBCodedInputStream*) input {
  return (Pair*)[[[Pair builder] mergeFromCodedInputStream:input] build];
}
+ (Pair*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
  return (Pair*)[[[Pair builder] mergeFromCodedInputStream:input extensionRegistry:extensionRegistry] build];
}
+ (PairBuilder*) builder {
  return [[PairBuilder alloc] init];
}
+ (PairBuilder*) builderWithPrototype:(Pair*) prototype {
  return [[Pair builder] mergeFrom:prototype];
}
- (PairBuilder*) builder {
  return [Pair builder];
}
- (PairBuilder*) toBuilder {
  return [Pair builderWithPrototype:self];
}
- (void) writeDescriptionTo:(NSMutableString*) output withIndent:(NSString*) indent {
  if (self.hasKey) {
    [output appendFormat:@"%@%@: %@\n", indent, @"key", self.key];
  }
  if (self.hasValue) {
    [output appendFormat:@"%@%@: %@\n", indent, @"value", self.value];
  }
  [self.unknownFields writeDescriptionTo:output withIndent:indent];
}
- (BOOL) isEqual:(id)other {
  if (other == self) {
    return YES;
  }
  if (![other isKindOfClass:[Pair class]]) {
    return NO;
  }
  Pair *otherMessage = other;
  return
      self.hasKey == otherMessage.hasKey &&
      (!self.hasKey || [self.key isEqual:otherMessage.key]) &&
      self.hasValue == otherMessage.hasValue &&
      (!self.hasValue || [self.value isEqual:otherMessage.value]) &&
      (self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
}
- (NSUInteger) hash {
  __block NSUInteger hashCode = 7;
  if (self.hasKey) {
    hashCode = hashCode * 31 + [self.key hash];
  }
  if (self.hasValue) {
    hashCode = hashCode * 31 + [self.value hash];
  }
  hashCode = hashCode * 31 + [self.unknownFields hash];
  return hashCode;
}
@end

@interface PairBuilder()
@property (strong) Pair* result;
@end

@implementation PairBuilder
@synthesize result;
- (id) init {
  if ((self = [super init])) {
    self.result = [[Pair alloc] init];
  }
  return self;
}
- (PBGeneratedMessage*) internalGetResult {
  return result;
}
- (PairBuilder*) clear {
  self.result = [[Pair alloc] init];
  return self;
}
- (PairBuilder*) clone {
  return [Pair builderWithPrototype:result];
}
- (Pair*) defaultInstance {
  return [Pair defaultInstance];
}
- (Pair*) build {
  [self checkInitialized];
  return [self buildPartial];
}
- (Pair*) buildPartial {
  Pair* returnMe = result;
  self.result = nil;
  return returnMe;
}
- (PairBuilder*) mergeFrom:(Pair*) other {
  if (other == [Pair defaultInstance]) {
    return self;
  }
  if (other.hasKey) {
    [self setKey:other.key];
  }
  if (other.hasValue) {
    [self setValue:other.value];
  }
  [self mergeUnknownFields:other.unknownFields];
  return self;
}
- (PairBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input {
  return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
}
- (PairBuilder*) mergeFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry {
  PBUnknownFieldSetBuilder* unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
  while (YES) {
    SInt32 tag = [input readTag];
    switch (tag) {
      case 0:
        [self setUnknownFields:[unknownFields build]];
        return self;
      default: {
        if (![self parseUnknownField:input unknownFields:unknownFields extensionRegistry:extensionRegistry tag:tag]) {
          [self setUnknownFields:[unknownFields build]];
          return self;
        }
        break;
      }
      case 10: {
        [self setKey:[input readString]];
        break;
      }
      case 18: {
        [self setValue:[input readString]];
        break;
      }
    }
  }
}
- (BOOL) hasKey {
  return result.hasKey;
}
- (NSString*) key {
  return result.key;
}
- (PairBuilder*) setKey:(NSString*) value {
  result.hasKey = YES;
  result.key = value;
  return self;
}
- (PairBuilder*) clearKey {
  result.hasKey = NO;
  result.key = @"";
  return self;
}
- (BOOL) hasValue {
  return result.hasValue;
}
- (NSString*) value {
  return result.value;
}
- (PairBuilder*) setValue:(NSString*) value {
  result.hasValue = YES;
  result.value = value;
  return self;
}
- (PairBuilder*) clearValue {
  result.hasValue = NO;
  result.value = @"";
  return self;
}
@end


// @@protoc_insertion_point(global_scope)
