// taken from
// https://github.com/protocolbuffers/protobuf/blob/master/js/test.proto

syntax = "proto2";

option java_package = "com.google.apps.jspb.proto";
option java_multiple_files = true;

// import "google/protobuf/descriptor.proto";

package jspb.test;

message Empty {}

enum OuterEnum {
  FOO = 1;
  BAR = 2;
}

message EnumContainer { optional OuterEnum outer_enum = 1; }

message Simple1 {
  required string a_string = 1;
  repeated string a_repeated_string = 2;
  optional bool a_boolean = 3;
}

// A message that differs from Simple1 only by name
message Simple2 {
  required string a_string = 1;
  repeated string a_repeated_string = 2;
}

message SpecialCases {
  required string normal = 1;
  // Examples of Js reserved names that are converted to pb_<name>.
  required string default = 2;
  required string function = 3;
  required string var = 4;
}

message OptionalFields {
  message Nested { optional int32 an_int = 1; }
  optional string a_string = 1;
  required bool a_bool = 2;
  optional Nested a_nested_message = 3;
  repeated Nested a_repeated_message = 4;
  repeated string a_repeated_string = 5;
}

message HasExtensions {
  optional string str1 = 1;
  optional string str2 = 2;
  optional string str3 = 3;
  extensions 10 to max;
}

message Complex {
  message Nested { required int32 an_int = 2; }
  required string a_string = 1;
  optional bool an_out_of_order_bool = 9;
  optional Nested a_nested_message = 4;
  repeated Nested a_repeated_message = 5;
  repeated string a_repeated_string = 7;
  optional double a_floating_point_field = 10;
}

message OuterMessage {
  // Make sure this doesn't conflict with the other Complex message.
  message Complex { optional int32 inner_complex_field = 1; }
}

message MineField {
  // document.cookie is a banned property in a couple of conformance check
  // configs at Google. Verify that having a field called cookie doesn't confuse
  // the compiler and break the build.
  optional string cookie = 1;
}

message IsExtension {
  extend HasExtensions { optional IsExtension ext_field = 100; }
  optional string ext1 = 1;

  // Extensions of proto2 Descriptor messages will be ignored.
  // extend google.protobuf.EnumOptions {
  //   optional string simple_option = 42113038;
  // }
}

message IndirectExtension {
  extend HasExtensions {
    optional Simple1 simple = 101;
    optional string str = 102;
    repeated string repeated_str = 103;
    repeated Simple1 repeated_simple = 104;
  }
}

extend HasExtensions { optional Simple1 simple1 = 105; }

message DefaultValues {
  enum Enum {
    E1 = 13;
    E2 = 77;
  }
  optional string string_field = 1 [ default = "default<>\'\"abc" ];
  optional bool bool_field = 2 [ default = true ];
  optional int64 int_field = 3 [ default = 11 ];
  optional Enum enum_field = 4 [ default = E1 ];
  optional string empty_field = 6 [ default = "" ];
  optional bytes bytes_field = 8
      [ default = "moo" ]; // Base64 encoding is "bW9v"
}

message FloatingPointFields {
  optional float optional_float_field = 1;
  required float required_float_field = 2;
  repeated float repeated_float_field = 3;
  optional float default_float_field = 4 [ default = 2.0 ];
  optional double optional_double_field = 5;
  required double required_double_field = 6;
  repeated double repeated_double_field = 7;
  optional double default_double_field = 8 [ default = 2.0 ];
}

message BooleanFields {
  optional bool optional_boolean_field = 1;
  required bool required_boolean_field = 2;
  repeated bool repeated_boolean_field = 3;
  optional bool default_boolean_field = 4 [ default = true ];
}

message TestClone {
  optional string str = 1;
  optional Simple1 simple1 = 3;
  repeated Simple1 simple2 = 5;
  optional bytes bytes_field = 6;
  optional string unused = 7;
  extensions 10 to max;
}

message TestCloneExtension {
  extend TestClone { optional TestCloneExtension low_ext = 11; }
  optional int32 f = 1;
}

message CloneExtension {
  extend TestClone { optional CloneExtension ext_field = 100; }
  optional string ext = 2;
}

// message TestGroup {
//   repeated group RepeatedGroup = 1 {
//     required string id = 1;
//     repeated bool some_bool = 2;
//   }
//   required group RequiredGroup = 2 {
//     required string id = 1;
//   }
//   optional group OptionalGroup = 3 {
//     required string id = 1;
//   }
//   optional string id = 4;
//   required Simple2 required_simple = 5;
//   optional Simple2 optional_simple = 6;
// }

// message TestGroup1 {
//   optional TestGroup.RepeatedGroup group = 1;
// }

message TestReservedNames {
  optional int32 extension = 1;
  extensions 10 to max;
}

message TestReservedNamesExtension {
  extend TestReservedNames { optional int32 foo = 10; }
}

message TestMessageWithOneof {

  oneof partial_oneof {
    string pone = 3;
    string pthree = 5;
  }

  oneof recursive_oneof {
    TestMessageWithOneof rone = 6;
    string rtwo = 7;
  }

  optional bool normal_field = 8;
  repeated string repeated_field = 9;

  oneof default_oneof_a {
    int32 aone = 10 [ default = 1234 ];
    int32 atwo = 11;
  }

  oneof default_oneof_b {
    int32 bone = 12;
    int32 btwo = 13 [ default = 1234 ];
  }
}

message TestEndsWithBytes {
  optional int32 value = 1;
  optional bytes data = 2;
}

// This message is for testing extension handling doesn't affect fields before
// pivot. Don't add new field to this message. See b/117298778 for more detail.
message TestLastFieldBeforePivot {
  optional int32 last_field_before_pivot = 1;
  extensions 100 to max;
}

extend TestLastFieldBeforePivot {
  optional int32 extend_test_last_field_before_pivot_field = 101;
}

message Int64Types {
  optional int64 int64_normal = 1 [ jstype = JS_NORMAL ];
  optional sint64 int64_string = 2 [ jstype = JS_STRING ];
  optional uint64 int64_number = 3 [ jstype = JS_NUMBER ];
}

message TestMapFieldsNoBinary {
  map<string, string> map_string_string = 1;
  map<string, int32> map_string_int32 = 2;
  map<string, int64> map_string_int64 = 3;
  map<string, bool> map_string_bool = 4;
  map<string, double> map_string_double = 5;
  map<string, MapValueEnumNoBinary> map_string_enum = 6;
  map<string, MapValueMessageNoBinary> map_string_msg = 7;

  map<int32, string> map_int32_string = 8;
  map<int64, string> map_int64_string = 9;
  map<bool, string> map_bool_string = 10;

  optional TestMapFieldsNoBinary test_map_fields = 11;
  map<string, TestMapFieldsNoBinary> map_string_testmapfields = 12;
}

enum MapValueEnumNoBinary {
  MAP_VALUE_FOO_NOBINARY = 0;
  MAP_VALUE_BAR_NOBINARY = 1;
  MAP_VALUE_BAZ_NOBINARY = 2;
}

message MapValueMessageNoBinary { optional int32 foo = 1; }

message Deeply {
  message Nested {
    message Message { optional int32 count = 1; }
  }
}

enum TestAllowAliasEnum {
  option allow_alias = true;

  TEST_ALLOW_ALIAS_DEFAULT = 0;
  VALUE1 = 1;
  value1 = 1;
}
