///
//  Generated code. Do not modify.
///
// ignore_for_file: non_constant_identifier_names,library_prefixes

// ignore_for_file: UNDEFINED_SHOWN_NAME,UNUSED_SHOWN_NAME
import 'dart:core' show int, dynamic, String, List, Map;
import 'package:protobuf/protobuf.dart';

class FieldDescriptorProto_Type extends ProtobufEnum {
  static const FieldDescriptorProto_Type TYPE_DOUBLE =
      const FieldDescriptorProto_Type._(1, 'TYPE_DOUBLE');
  static const FieldDescriptorProto_Type TYPE_FLOAT =
      const FieldDescriptorProto_Type._(2, 'TYPE_FLOAT');
  static const FieldDescriptorProto_Type TYPE_INT64 =
      const FieldDescriptorProto_Type._(3, 'TYPE_INT64');
  static const FieldDescriptorProto_Type TYPE_UINT64 =
      const FieldDescriptorProto_Type._(4, 'TYPE_UINT64');
  static const FieldDescriptorProto_Type TYPE_INT32 =
      const FieldDescriptorProto_Type._(5, 'TYPE_INT32');
  static const FieldDescriptorProto_Type TYPE_FIXED64 =
      const FieldDescriptorProto_Type._(6, 'TYPE_FIXED64');
  static const FieldDescriptorProto_Type TYPE_FIXED32 =
      const FieldDescriptorProto_Type._(7, 'TYPE_FIXED32');
  static const FieldDescriptorProto_Type TYPE_BOOL =
      const FieldDescriptorProto_Type._(8, 'TYPE_BOOL');
  static const FieldDescriptorProto_Type TYPE_STRING =
      const FieldDescriptorProto_Type._(9, 'TYPE_STRING');
  static const FieldDescriptorProto_Type TYPE_GROUP =
      const FieldDescriptorProto_Type._(10, 'TYPE_GROUP');
  static const FieldDescriptorProto_Type TYPE_MESSAGE =
      const FieldDescriptorProto_Type._(11, 'TYPE_MESSAGE');
  static const FieldDescriptorProto_Type TYPE_BYTES =
      const FieldDescriptorProto_Type._(12, 'TYPE_BYTES');
  static const FieldDescriptorProto_Type TYPE_UINT32 =
      const FieldDescriptorProto_Type._(13, 'TYPE_UINT32');
  static const FieldDescriptorProto_Type TYPE_ENUM =
      const FieldDescriptorProto_Type._(14, 'TYPE_ENUM');
  static const FieldDescriptorProto_Type TYPE_SFIXED32 =
      const FieldDescriptorProto_Type._(15, 'TYPE_SFIXED32');
  static const FieldDescriptorProto_Type TYPE_SFIXED64 =
      const FieldDescriptorProto_Type._(16, 'TYPE_SFIXED64');
  static const FieldDescriptorProto_Type TYPE_SINT32 =
      const FieldDescriptorProto_Type._(17, 'TYPE_SINT32');
  static const FieldDescriptorProto_Type TYPE_SINT64 =
      const FieldDescriptorProto_Type._(18, 'TYPE_SINT64');

  static const List<FieldDescriptorProto_Type> values =
      const <FieldDescriptorProto_Type>[
    TYPE_DOUBLE,
    TYPE_FLOAT,
    TYPE_INT64,
    TYPE_UINT64,
    TYPE_INT32,
    TYPE_FIXED64,
    TYPE_FIXED32,
    TYPE_BOOL,
    TYPE_STRING,
    TYPE_GROUP,
    TYPE_MESSAGE,
    TYPE_BYTES,
    TYPE_UINT32,
    TYPE_ENUM,
    TYPE_SFIXED32,
    TYPE_SFIXED64,
    TYPE_SINT32,
    TYPE_SINT64,
  ];

  static final Map<int, dynamic> _byValue = ProtobufEnum.initByValue(values);
  static FieldDescriptorProto_Type valueOf(int value) =>
      _byValue[value] as FieldDescriptorProto_Type;
  static void $checkItem(FieldDescriptorProto_Type v) {
    if (v is! FieldDescriptorProto_Type)
      checkItemFailed(v, 'FieldDescriptorProto_Type');
  }

  const FieldDescriptorProto_Type._(int v, String n) : super(v, n);
}

class FieldDescriptorProto_Label extends ProtobufEnum {
  static const FieldDescriptorProto_Label LABEL_OPTIONAL =
      const FieldDescriptorProto_Label._(1, 'LABEL_OPTIONAL');
  static const FieldDescriptorProto_Label LABEL_REQUIRED =
      const FieldDescriptorProto_Label._(2, 'LABEL_REQUIRED');
  static const FieldDescriptorProto_Label LABEL_REPEATED =
      const FieldDescriptorProto_Label._(3, 'LABEL_REPEATED');

  static const List<FieldDescriptorProto_Label> values =
      const <FieldDescriptorProto_Label>[
    LABEL_OPTIONAL,
    LABEL_REQUIRED,
    LABEL_REPEATED,
  ];

  static final Map<int, dynamic> _byValue = ProtobufEnum.initByValue(values);
  static FieldDescriptorProto_Label valueOf(int value) =>
      _byValue[value] as FieldDescriptorProto_Label;
  static void $checkItem(FieldDescriptorProto_Label v) {
    if (v is! FieldDescriptorProto_Label)
      checkItemFailed(v, 'FieldDescriptorProto_Label');
  }

  const FieldDescriptorProto_Label._(int v, String n) : super(v, n);
}

class FileOptions_OptimizeMode extends ProtobufEnum {
  static const FileOptions_OptimizeMode SPEED =
      const FileOptions_OptimizeMode._(1, 'SPEED');
  static const FileOptions_OptimizeMode CODE_SIZE =
      const FileOptions_OptimizeMode._(2, 'CODE_SIZE');
  static const FileOptions_OptimizeMode LITE_RUNTIME =
      const FileOptions_OptimizeMode._(3, 'LITE_RUNTIME');

  static const List<FileOptions_OptimizeMode> values =
      const <FileOptions_OptimizeMode>[
    SPEED,
    CODE_SIZE,
    LITE_RUNTIME,
  ];

  static final Map<int, dynamic> _byValue = ProtobufEnum.initByValue(values);
  static FileOptions_OptimizeMode valueOf(int value) =>
      _byValue[value] as FileOptions_OptimizeMode;
  static void $checkItem(FileOptions_OptimizeMode v) {
    if (v is! FileOptions_OptimizeMode)
      checkItemFailed(v, 'FileOptions_OptimizeMode');
  }

  const FileOptions_OptimizeMode._(int v, String n) : super(v, n);
}

class FieldOptions_CType extends ProtobufEnum {
  static const FieldOptions_CType STRING =
      const FieldOptions_CType._(0, 'STRING');
  static const FieldOptions_CType CORD = const FieldOptions_CType._(1, 'CORD');
  static const FieldOptions_CType STRING_PIECE =
      const FieldOptions_CType._(2, 'STRING_PIECE');

  static const List<FieldOptions_CType> values = const <FieldOptions_CType>[
    STRING,
    CORD,
    STRING_PIECE,
  ];

  static final Map<int, dynamic> _byValue = ProtobufEnum.initByValue(values);
  static FieldOptions_CType valueOf(int value) =>
      _byValue[value] as FieldOptions_CType;
  static void $checkItem(FieldOptions_CType v) {
    if (v is! FieldOptions_CType) checkItemFailed(v, 'FieldOptions_CType');
  }

  const FieldOptions_CType._(int v, String n) : super(v, n);
}

class FieldOptions_JSType extends ProtobufEnum {
  static const FieldOptions_JSType JS_NORMAL =
      const FieldOptions_JSType._(0, 'JS_NORMAL');
  static const FieldOptions_JSType JS_STRING =
      const FieldOptions_JSType._(1, 'JS_STRING');
  static const FieldOptions_JSType JS_NUMBER =
      const FieldOptions_JSType._(2, 'JS_NUMBER');

  static const List<FieldOptions_JSType> values = const <FieldOptions_JSType>[
    JS_NORMAL,
    JS_STRING,
    JS_NUMBER,
  ];

  static final Map<int, dynamic> _byValue = ProtobufEnum.initByValue(values);
  static FieldOptions_JSType valueOf(int value) =>
      _byValue[value] as FieldOptions_JSType;
  static void $checkItem(FieldOptions_JSType v) {
    if (v is! FieldOptions_JSType) checkItemFailed(v, 'FieldOptions_JSType');
  }

  const FieldOptions_JSType._(int v, String n) : super(v, n);
}

class MethodOptions_IdempotencyLevel extends ProtobufEnum {
  static const MethodOptions_IdempotencyLevel IDEMPOTENCY_UNKNOWN =
      const MethodOptions_IdempotencyLevel._(0, 'IDEMPOTENCY_UNKNOWN');
  static const MethodOptions_IdempotencyLevel NO_SIDE_EFFECTS =
      const MethodOptions_IdempotencyLevel._(1, 'NO_SIDE_EFFECTS');
  static const MethodOptions_IdempotencyLevel IDEMPOTENT =
      const MethodOptions_IdempotencyLevel._(2, 'IDEMPOTENT');

  static const List<MethodOptions_IdempotencyLevel> values =
      const <MethodOptions_IdempotencyLevel>[
    IDEMPOTENCY_UNKNOWN,
    NO_SIDE_EFFECTS,
    IDEMPOTENT,
  ];

  static final Map<int, dynamic> _byValue = ProtobufEnum.initByValue(values);
  static MethodOptions_IdempotencyLevel valueOf(int value) =>
      _byValue[value] as MethodOptions_IdempotencyLevel;
  static void $checkItem(MethodOptions_IdempotencyLevel v) {
    if (v is! MethodOptions_IdempotencyLevel)
      checkItemFailed(v, 'MethodOptions_IdempotencyLevel');
  }

  const MethodOptions_IdempotencyLevel._(int v, String n) : super(v, n);
}
