syntax = "proto2";

import "google/protobuf/descriptor.proto";

package test;

option cc_generic_services = true;
option (file_option) = 9876543210;

extend google.protobuf.FileOptions {
  optional uint64 file_option = 9585869;
}

extend google.protobuf.FieldOptions {
  optional uint64 field_option = 858769;
}

extend google.protobuf.EnumOptions {
  optional int64 enum_option = 590284;
}

extend google.protobuf.MessageOptions {
  optional int64 message_option = 485969;
}

extend google.protobuf.ServiceOptions {
  optional int64 service_option = 5869607;
}

extend google.protobuf.MethodOptions {
  optional int64 method_option = 7893233;
}

enum StatusType {
  option allow_alias = true;
  option (enum_option) = -789;

  PENDING = 0;
  ENABLED = 1;
  DISABLED = 2;
  DELETED = 3;
  ALIASED = 3;
}

message ResourceFindRequest {
  required string name = 1;
  optional bool active = 2;
  repeated string widgets = 3;
  repeated bytes widget_bytes = 4;
  optional bytes single_bytes = 5;
}

message ResourceSleepRequest {
  optional int32 sleep = 1;
}

message Resource {
  option map_entry = false;
  option (message_option) = -56;

  extensions 100 to max;

  required string name = 1 [(field_option) = 8765432109, ctype = CORD];
  optional int64 date_created = 2;
  optional StatusType status = 3;
  repeated StatusType repeated_enum = 4;
}

message ResourceWithRequiredField {
  required string foo_is_required = 1;
}

message Searchable {
  enum SearchType {
    FLAT = 1;
    NESTED = 2;
  }

  extend test.Resource {
    optional bool ext_is_searchable = 100;
    optional bool ext_is_hidden = 101;
    optional Searchable.SearchType ext_search_type = 102 [default=FLAT];
  }
}

message MessageParent {
  message MessageChild {
    optional string child1 = 1;
  }
}

message Nested {
  extensions 100 to 110;

  optional string name = 1;
  optional Resource resource = 2;
  repeated Resource multiple_resources = 3;
  optional StatusType status = 4;

  message NestedLevelOne {
    extensions 100 to 101;
    optional bool level_one = 1 [default=true];

    extend Resource {
      optional bool ext_nested_in_level_one = 105;
      optional bool ext_dup_field = 106;
    }
  }

  extend NestedLevelOne {
    optional bool ext_nested_level_one = 100;
  }

//  extend Resource {
//    optional bool ext_dup_field = 107;
//  }
}

extend Nested {
  optional string foo = 100;
  optional int64 bar = 101;
}

extend Nested.NestedLevelOne {
  optional bool ext_nested_level_one_outer = 101;
}

service ResourceService {
  option (service_option) = -9876543210;

  rpc Find (ResourceFindRequest) returns (Resource) {
    option (method_option) = 2;
  }
  rpc FindWithRpcFailed (ResourceFindRequest) returns (Resource);
  rpc FindWithSleep (ResourceSleepRequest) returns (Resource);
  rpc FindNotImplemented (ResourceFindRequest) returns (Resource);
}