// Generated by the protocol buffer compiler.  DO NOT EDIT!
// NO CHECKED-IN PROTOBUF GENCODE
// clang-format off
// source: google/protobuf/struct.proto

#import "GPBDescriptor.h"
#import "GPBMessage.h"
#import "GPBRootObject.h"

#if GOOGLE_PROTOBUF_OBJC_VERSION < 40311
#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
#if 40311 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION
#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources.
#endif

// @@protoc_insertion_point(imports)

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"

CF_EXTERN_C_BEGIN

@class GPBListValue;
@class GPBStruct;
@class GPBValue;

NS_ASSUME_NONNULL_BEGIN

#pragma mark - Enum GPBNullValue

/**
 * Represents a JSON `null`.
 *
 * `NullValue` is a sentinel, using an enum with only one value to represent
 * the null value for the `Value` type union.
 *
 * A field of type `NullValue` with any value other than `0` is considered
 * invalid. Most ProtoJSON serializers will emit a Value with a `null_value` set
 * as a JSON `null` regardless of the integer value, and so will round trip to
 * a `0` value.
 **/
typedef GPB_ENUM(GPBNullValue) {
  /**
   * Value used if any message's field encounters a value that is not defined
   * by this enum. The message will also have C functions to get/set the rawValue
   * of the field.
   **/
  GPBNullValue_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue,
  /** Null value. */
  GPBNullValue_NullValue = 0,
};

GPBEnumDescriptor *GPBNullValue_EnumDescriptor(void);

/**
 * Checks to see if the given value is defined by the enum or was not known at
 * the time this source was generated.
 **/
BOOL GPBNullValue_IsValidValue(int32_t value);

#pragma mark - GPBStructRoot

/**
 * Exposes the extension registry for this file.
 *
 * The base class provides:
 * @code
 *   + (GPBExtensionRegistry *)extensionRegistry;
 * @endcode
 * which is a @c GPBExtensionRegistry that includes all the extensions defined by
 * this file and all files that it depends on.
 **/
GPB_FINAL @interface GPBStructRoot : GPBRootObject
@end

#pragma mark - GPBStruct

typedef GPB_ENUM(GPBStruct_FieldNumber) {
  GPBStruct_FieldNumber_Fields = 1,
};

/**
 * Represents a JSON object.
 *
 * An unordered key-value map, intending to perfectly capture the semantics of a
 * JSON object. This enables parsing any arbitrary JSON payload as a message
 * field in ProtoJSON format.
 *
 * This follows RFC 8259 guidelines for interoperable JSON: notably this type
 * cannot represent large Int64 values or `NaN`/`Infinity` numbers,
 * since the JSON format generally does not support those values in its number
 * type.
 *
 * If you do not intend to parse arbitrary JSON into your message, a custom
 * typed message should be preferred instead of using this type.
 **/
GPB_FINAL @interface GPBStruct : GPBMessage

/** Unordered map of dynamically typed values. */
@property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary<NSString*, GPBValue*> *fields;
/** The number of items in @c fields without causing the container to be created. */
@property(nonatomic, readonly) NSUInteger fields_Count;

@end

#pragma mark - GPBValue

typedef GPB_ENUM(GPBValue_FieldNumber) {
  GPBValue_FieldNumber_NullValue = 1,
  GPBValue_FieldNumber_NumberValue = 2,
  GPBValue_FieldNumber_StringValue = 3,
  GPBValue_FieldNumber_BoolValue = 4,
  GPBValue_FieldNumber_StructValue = 5,
  GPBValue_FieldNumber_ListValue = 6,
};

typedef GPB_ENUM(GPBValue_Kind_OneOfCase) {
  GPBValue_Kind_OneOfCase_GPBUnsetOneOfCase = 0,
  GPBValue_Kind_OneOfCase_NullValue = 1,
  GPBValue_Kind_OneOfCase_NumberValue = 2,
  GPBValue_Kind_OneOfCase_StringValue = 3,
  GPBValue_Kind_OneOfCase_BoolValue = 4,
  GPBValue_Kind_OneOfCase_StructValue = 5,
  GPBValue_Kind_OneOfCase_ListValue = 6,
};

/**
 * Represents a JSON value.
 *
 * `Value` represents a dynamically typed value which can be either
 * null, a number, a string, a boolean, a recursive struct value, or a
 * list of values. A producer of value is expected to set one of these
 * variants. Absence of any variant is an invalid state.
 **/
GPB_FINAL @interface GPBValue : GPBMessage

/** The kind of value. */
@property(nonatomic, readonly) GPBValue_Kind_OneOfCase kindOneOfCase;

/** Represents a JSON `null`. */
@property(nonatomic, readwrite) GPBNullValue nullValue;
@property(nonatomic, readwrite) BOOL hasNullValue;

/**
 * Represents a JSON number. Must not be `NaN`, `Infinity` or
 * `-Infinity`, since those are not supported in JSON. This also cannot
 * represent large Int64 values, since JSON format generally does not
 * support them in its number type.
 **/
@property(nonatomic, readwrite) double numberValue;
@property(nonatomic, readwrite) BOOL hasNumberValue;

/** Represents a JSON string. */
@property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue;
/** Test to see if @c stringValue has been set. */
@property(nonatomic, readwrite) BOOL hasStringValue;

/** Represents a JSON boolean (`true` or `false` literal in JSON). */
@property(nonatomic, readwrite) BOOL boolValue;
@property(nonatomic, readwrite) BOOL hasBoolValue;

/** Represents a JSON object. */
@property(nonatomic, readwrite, strong, null_resettable) GPBStruct *structValue;
/** Test to see if @c structValue has been set. */
@property(nonatomic, readwrite) BOOL hasStructValue;

/** Represents a JSON array. */
@property(nonatomic, readwrite, strong, null_resettable) GPBListValue *listValue;
/** Test to see if @c listValue has been set. */
@property(nonatomic, readwrite) BOOL hasListValue;

@end

/**
 * Fetches the raw value of a @c GPBValue's @c nullValue property, even
 * if the value was not defined by the enum at the time the code was generated.
 **/
int32_t GPBValue_NullValue_RawValue(GPBValue *message);
/**
 * Sets the raw value of an @c GPBValue's @c nullValue property, allowing
 * it to be set to a value that was not defined by the enum at the time the code
 * was generated.
 **/
void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value);

/**
 * Clears whatever value was set for the oneof 'kind'.
 **/
void GPBValue_ClearKindOneOfCase(GPBValue *message);

#pragma mark - GPBListValue

typedef GPB_ENUM(GPBListValue_FieldNumber) {
  GPBListValue_FieldNumber_ValuesArray = 1,
};

/**
 * Represents a JSON array.
 **/
GPB_FINAL @interface GPBListValue : GPBMessage

/** Repeated field of dynamically typed values. */
@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray<GPBValue*> *valuesArray;
/** The number of items in @c valuesArray without causing the container to be created. */
@property(nonatomic, readonly) NSUInteger valuesArray_Count;

@end

NS_ASSUME_NONNULL_END

CF_EXTERN_C_END

#pragma clang diagnostic pop

// @@protoc_insertion_point(global_scope)

// clang-format on
