// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#import "GPBUnknownField.h"
#import "GPBUnknownField_PackagePrivate.h"

#import "GPBCodedOutputStream.h"
#import "GPBCodedOutputStream_PackagePrivate.h"
#import "GPBUnknownFields.h"
#import "GPBUnknownFields_PackagePrivate.h"
#import "GPBWireFormat.h"

#define ASSERT_FIELD_TYPE(type)                               \
  if (type_ != type) {                                        \
    [NSException raise:NSInternalInconsistencyException       \
                format:@"GPBUnknownField is the wrong type"]; \
  }

@implementation GPBUnknownField {
  int32_t number_;
  GPBUnknownFieldType type_;

  union {
    uint64_t intValue;                 // type == Varint, Fixed32, Fixed64
    NSData *_Nonnull lengthDelimited;  // type == LengthDelimited
    GPBUnknownFields *_Nonnull group;  // type == Group
  } storage_;
}

@synthesize number = number_;
@synthesize type = type_;

- (instancetype)initWithNumber:(int32_t)number varint:(uint64_t)varint {
  if ((self = [super init])) {
    number_ = number;
    type_ = GPBUnknownFieldTypeVarint;
    storage_.intValue = varint;
  }
  return self;
}

- (instancetype)initWithNumber:(int32_t)number fixed32:(uint32_t)fixed32 {
  if ((self = [super init])) {
    number_ = number;
    type_ = GPBUnknownFieldTypeFixed32;
    storage_.intValue = fixed32;
  }
  return self;
}

- (instancetype)initWithNumber:(int32_t)number fixed64:(uint64_t)fixed64 {
  if ((self = [super init])) {
    number_ = number;
    type_ = GPBUnknownFieldTypeFixed64;
    storage_.intValue = fixed64;
  }
  return self;
}

- (instancetype)initWithNumber:(int32_t)number lengthDelimited:(nonnull NSData *)data {
  if ((self = [super init])) {
    number_ = number;
    type_ = GPBUnknownFieldTypeLengthDelimited;
    storage_.lengthDelimited = [data copy];
  }
  return self;
}

- (instancetype)initWithNumber:(int32_t)number group:(nonnull GPBUnknownFields *)group {
  if ((self = [super init])) {
    number_ = number;
    type_ = GPBUnknownFieldTypeGroup;
    // Taking ownership of the group; so retain, not copy.
    storage_.group = [group retain];
  }
  return self;
}

- (void)dealloc {
  switch (type_) {
    case GPBUnknownFieldTypeVarint:
    case GPBUnknownFieldTypeFixed32:
    case GPBUnknownFieldTypeFixed64:
      break;
    case GPBUnknownFieldTypeLengthDelimited:
      [storage_.lengthDelimited release];
      break;
    case GPBUnknownFieldTypeGroup:
      [storage_.group release];
      break;
  }

  [super dealloc];
}

// Direct access is use for speed, to avoid even internally declaring things
// read/write, etc. The warning is enabled in the project to ensure code calling
// protos can turn on -Wdirect-ivar-access without issues.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdirect-ivar-access"

- (uint64_t)varint {
  ASSERT_FIELD_TYPE(GPBUnknownFieldTypeVarint);
  return storage_.intValue;
}

- (uint32_t)fixed32 {
  ASSERT_FIELD_TYPE(GPBUnknownFieldTypeFixed32);
  return (uint32_t)storage_.intValue;
}

- (uint64_t)fixed64 {
  ASSERT_FIELD_TYPE(GPBUnknownFieldTypeFixed64);
  return storage_.intValue;
}

- (NSData *)lengthDelimited {
  ASSERT_FIELD_TYPE(GPBUnknownFieldTypeLengthDelimited);
  return storage_.lengthDelimited;
}

- (GPBUnknownFields *)group {
  ASSERT_FIELD_TYPE(GPBUnknownFieldTypeGroup);
  return storage_.group;
}

- (id)copyWithZone:(NSZone *)zone {
  switch (type_) {
    case GPBUnknownFieldTypeVarint:
    case GPBUnknownFieldTypeFixed32:
    case GPBUnknownFieldTypeFixed64:
    case GPBUnknownFieldTypeLengthDelimited:
      // In these modes, the object isn't mutable, so just return self.
      return [self retain];
    case GPBUnknownFieldTypeGroup: {
      // The `GPBUnknownFields` for the group is mutable, so a new instance of this object and
      // the group is needed.
      GPBUnknownFields *copyGroup = [storage_.group copyWithZone:zone];
      GPBUnknownField *copy = [[GPBUnknownField allocWithZone:zone] initWithNumber:number_
                                                                             group:copyGroup];
      [copyGroup release];
      return copy;
    }
  }
}

- (BOOL)isEqual:(id)object {
  if (self == object) return YES;
  if (![object isKindOfClass:[GPBUnknownField class]]) return NO;
  GPBUnknownField *field = (GPBUnknownField *)object;
  if (number_ != field->number_) return NO;
  if (type_ != field->type_) return NO;
  switch (type_) {
    case GPBUnknownFieldTypeVarint:
    case GPBUnknownFieldTypeFixed32:
    case GPBUnknownFieldTypeFixed64:
      return storage_.intValue == field->storage_.intValue;
    case GPBUnknownFieldTypeLengthDelimited:
      return [storage_.lengthDelimited isEqual:field->storage_.lengthDelimited];
    case GPBUnknownFieldTypeGroup:
      return [storage_.group isEqual:field->storage_.group];
  }
}

- (NSUInteger)hash {
  const NSUInteger prime = 31;
  NSUInteger result = prime * (NSUInteger)number_ + type_;
  switch (type_) {
    case GPBUnknownFieldTypeVarint:
    case GPBUnknownFieldTypeFixed32:
    case GPBUnknownFieldTypeFixed64:
      result = prime * result + (NSUInteger)storage_.intValue;
      break;
    case GPBUnknownFieldTypeLengthDelimited:
      result = prime * result + [storage_.lengthDelimited hash];
      break;
    case GPBUnknownFieldTypeGroup:
      result = prime * result + [storage_.group hash];
  }
  return result;
}

- (NSString *)description {
  NSMutableString *description =
      [NSMutableString stringWithFormat:@"<%@ %p>: Field: %d", [self class], self, number_];
  switch (type_) {
    case GPBUnknownFieldTypeVarint:
      [description appendFormat:@" varint: %llu", storage_.intValue];
      break;
    case GPBUnknownFieldTypeFixed32:
      [description appendFormat:@" fixed32: %u", (uint32_t)storage_.intValue];
      break;
    case GPBUnknownFieldTypeFixed64:
      [description appendFormat:@" fixed64: %llu", storage_.intValue];
      break;
    case GPBUnknownFieldTypeLengthDelimited:
      [description appendFormat:@" fixed64: %@", storage_.lengthDelimited];
      break;
    case GPBUnknownFieldTypeGroup:
      [description appendFormat:@" group: %@", storage_.group];
      break;
  }
  return description;
}

#pragma mark - Internal Methods

- (size_t)computeSerializedSize {
  switch (type_) {
    case GPBUnknownFieldTypeVarint:
      return GPBComputeUInt64Size(number_, storage_.intValue);
    case GPBUnknownFieldTypeFixed32:
      return GPBComputeFixed32Size(number_, (uint32_t)storage_.intValue);
    case GPBUnknownFieldTypeFixed64:
      return GPBComputeFixed64Size(number_, storage_.intValue);
    case GPBUnknownFieldTypeLengthDelimited:
      return GPBComputeBytesSize(number_, storage_.lengthDelimited);
    case GPBUnknownFieldTypeGroup:
      return (GPBComputeTagSize(number_) * 2) + [storage_.group computeSerializedSize];
  }
}

- (void)writeToCodedOutputStream:(nonnull GPBCodedOutputStream *)output {
  switch (type_) {
    case GPBUnknownFieldTypeVarint:
      [output writeUInt64:number_ value:storage_.intValue];
      break;
    case GPBUnknownFieldTypeFixed32:
      [output writeFixed32:number_ value:(uint32_t)storage_.intValue];
      break;
    case GPBUnknownFieldTypeFixed64:
      [output writeFixed64:number_ value:storage_.intValue];
      break;
    case GPBUnknownFieldTypeLengthDelimited:
      [output writeBytes:number_ value:storage_.lengthDelimited];
      break;
    case GPBUnknownFieldTypeGroup:
      [output writeRawVarint32:(int32_t)GPBWireFormatMakeTag((uint32_t)number_,
                                                             GPBWireFormatStartGroup)];
      [storage_.group writeToCodedOutputStream:output];
      [output
          writeRawVarint32:(int32_t)GPBWireFormatMakeTag((uint32_t)number_, GPBWireFormatEndGroup)];
      break;
  }
}

#pragma clang diagnostic pop

@end
