/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Protocol Buffer messages used for testing Proto3 Schema implementation.
 */

syntax = "proto3";

package proto3_schema_messages;

import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/wrappers.proto";
import "google/protobuf/descriptor.proto";

import "proto3_schema_options.proto";

option java_package = "org.apache.beam.sdk.extensions.protobuf";

message PrimitiveEncodedFields {
  int64 encoded_timestamp = 1;
  int32 encoded_date = 2;
  bytes encoded_numeric = 3;
  bytes encoded_bignumeric = 4;
  int64 encoded_packed_datetime = 5;
  int64 encoded_packed_time = 6;
}

message NestedEncodedFields {
  PrimitiveEncodedFields nested = 1;
  repeated PrimitiveEncodedFields nested_list = 2;
}

message PrimitiveUnEncodedFields {
  string timestamp = 1;
  string date = 2;
  string numeric = 3;
  string bignumeric = 4;
  string datetime = 5;
  string time = 6;
}

message NestedUnEncodedFields {
  PrimitiveUnEncodedFields nested = 1;
  repeated PrimitiveUnEncodedFields nested_list = 2;
}

message WrapperUnEncodedFields {
  google.protobuf.FloatValue float = 1;
  google.protobuf.DoubleValue double = 2;
  google.protobuf.BoolValue bool = 3;
  google.protobuf.Int32Value int32 = 4;
  google.protobuf.Int64Value int64 = 5;
  google.protobuf.UInt32Value uint32 = 6;
  google.protobuf.UInt64Value uint64 = 7;
  google.protobuf.BytesValue bytes = 8;
  google.protobuf.Timestamp timestamp = 9;
}

message NestedWrapperUnEncodedFields {
  WrapperUnEncodedFields nested = 1;
  repeated WrapperUnEncodedFields nested_list = 2;
}

message Primitive {
    double primitive_double = 1;
    float primitive_float = 2;
    int32 primitive_int32 = 3;
    int64 primitive_int64 = 4;
    uint32 primitive_uint32 = 5;
    uint64 primitive_uint64 = 6;
    sint32 primitive_sint32 = 7;
    sint64 primitive_sint64 = 8;
    fixed32 primitive_fixed32 = 9;
    fixed64 primitive_fixed64 = 10;
    sfixed32 primitive_sfixed32 = 11;
    sfixed64 primitive_sfixed64 = 12;
    bool primitive_bool = 13;
    string primitive_string = 14;
    bytes primitive_bytes = 15;
}

message RepeatPrimitive {
    repeated double repeated_double = 1;
    repeated float repeated_float = 2;
    repeated int32 repeated_int32 = 3;
    repeated int64 repeated_int64 = 4;
    repeated uint32 repeated_uint32 = 5;
    repeated uint64 repeated_uint64 = 6;
    repeated sint32 repeated_sint32 = 7;
    repeated sint64 repeated_sint64 = 8;
    repeated fixed32 repeated_fixed32 = 9;
    repeated fixed64 repeated_fixed64 = 10;
    repeated sfixed32 repeated_sfixed32 = 11;
    repeated sfixed64 repeated_sfixed64 = 12;
    repeated bool repeated_bool = 13;
    repeated string repeated_string = 14;
    repeated bytes repeated_bytes = 15;
}

message MapPrimitive {
    map<string, string> string_string_map = 1;
    map<string, int32> string_int_map = 2;
    map<int32, string> int_string_map = 3;
    map<string, bytes> string_bytes_map = 4;
}

message Nested {
  Primitive nested = 1;
  repeated Primitive nested_list = 2;
  map<string, Primitive> nested_map = 3;
}

message OneOf {
  string place1 = 1;
    oneof special_oneof {
        int32 oneof_int32 = 2;
        bool oneof_bool = 3;
        string oneof_string = 4;
        Primitive oneof_primitive = 5;
    }
    int32 place2 = 6;
}

message OuterOneOf {
  oneof outer_oneof {
    OneOf oneof_oneof = 1;
    int32 oneof_int32 = 2;
  }
}

message ReversedOneOf {
  string place1 = 6;
    oneof oneof_reversed {
        int32 oneof_int32 = 5;
        bool oneof_bool = 4;
        string oneof_string = 3;
        Primitive oneof_primitive = 2;
    }
    int32 place2 = 1;
}

message NonContiguousOneOf {
  string place1 = 76;
    oneof oneof_non_contiguous_one {
        int32 oneof_one_int32 = 55;
        bool oneof_one_bool = 1;
        string oneof_one_string = 189;
        Primitive oneof_one_primitive = 22;
    }
    int32 place2 = 33;
    oneof oneof_non_contiguous_two {
        string oneof_two_first_string = 981;
        int32 oneof_two_int32 = 2;
        string oneof_two_second_string = 44;
    }
    int32 place3 = 63;
}

message EnumMessage {
  enum Enum {
    ZERO  = 0;
    TWO = 2;
    THREE = 3;
    }
    Enum enum = 1;
}

message WktMessage {
    google.protobuf.DoubleValue double = 1;
    google.protobuf.FloatValue float = 2;
    google.protobuf.Int32Value int32 = 3;
    google.protobuf.Int64Value int64 = 4;
    google.protobuf.UInt32Value uint32 = 5;
    google.protobuf.UInt64Value uint64 = 6;
    google.protobuf.BoolValue bool = 13;
    google.protobuf.StringValue string = 14;
    google.protobuf.BytesValue bytes = 15;
    google.protobuf.Timestamp timestamp = 16;
    google.protobuf.Duration duration = 17;
}

message OptionMessage {
    option (proto3_schema_options.message_option_int) = 42;
    option (proto3_schema_options.message_option_string) = "this is a message string";
    option (proto3_schema_options.message_option_message) = {
		single_string: "foobar in message"
		single_int32: 12
		single_int64: 34
	};
    option (proto3_schema_options.message_option_repeated) = "string_1";
    option (proto3_schema_options.message_option_repeated) = "string_2";
    option (proto3_schema_options.message_option_repeated) = "string_3";
    option (proto3_schema_options.message_option_repeated) = "string_3";
    option (proto3_schema_options.message_option_repeated_message) = {
		single_string: "string in message in option in message"
	};
    option (proto3_schema_options.message_option_repeated_message) = {
		single_int32: 1
	};
    option (proto3_schema_options.message_option_repeated_message) = {
		single_int64: 2
	};

    string field_one = 1 [
        (proto3_schema_options.field_option_int) = 13,
        (proto3_schema_options.field_option_string) = "this is a field string",
        (proto3_schema_options.field_option_message) = {
            single_string: "foobar in field"
            single_int32: 56
            single_int64: 78
            optional_string: "this is optional"
        },
        (proto3_schema_options.field_option_repeated) = "field_string_1",
        (proto3_schema_options.field_option_repeated) = "field_string_2",
        (proto3_schema_options.field_option_repeated) = "field_string_3",

        (proto3_schema_options.field_option_repeated_message) = {
            single_string: "string in message in option in field"
        },
        (proto3_schema_options.field_option_repeated_message) = {
            single_int32: 77
        },
        (proto3_schema_options.field_option_repeated_message) = {
            single_int64: 88
        }];
}

message SelfNested {
  SelfNested nested = 1;
}

message FirstCircularNested {
  SecondCircularNested nested = 1;
}

message SecondCircularNested {
  FirstCircularNested nested = 1;
}

message Empty {
}

message OptionalPrimitive {
    optional int32 primitive_int32 = 1;
    optional bool primitive_bool = 2;
    optional string primitive_string = 3;
    optional bytes primitive_bytes = 4;
}

message OptionalNested {
    optional OptionalPrimitive nested = 1;
}

// MapPrimitive and MapWrapped have the same Beam Schema.
message MapWrapped {
  map<string, google.protobuf.StringValue> string_string_map = 1;
  map<string, google.protobuf.Int32Value> string_int_map = 2;
  map<int32, google.protobuf.StringValue> int_string_map = 3;
  map<string, google.protobuf.BytesValue> string_bytes_map = 4;
}

message OptionalEnumMessage {
  enum Enum {
    ZERO = 0;
    TWO  = 2;
    THREE = 3;
  }
  optional Enum enum = 1;
}

message OptionalPrimitive2 {
  optional double primitive_double = 1;
  optional float primitive_float = 2;
  optional int32 primitive_int32 = 3;
  optional int64 primitive_int64 = 4;
  optional uint32 primitive_uint32 = 5;
  optional uint64 primitive_uint64 = 6;
  optional sint32 primitive_sint32 = 7;
  optional sint64 primitive_sint64 = 8;
  optional fixed32 primitive_fixed32 = 9;
  optional fixed64 primitive_fixed64 = 10;
  optional sfixed32 primitive_sfixed32 = 11;
  optional sfixed64 primitive_sfixed64 = 12;
  optional bool primitive_bool = 13;
  optional string primitive_string = 14;
  optional bytes primitive_bytes = 15;
}

message SimpleOneof {
  oneof group {
    int32 int32 = 3;
    string string = 4;
  }
}

message WrapPrimitive {
  google.protobuf.DoubleValue double = 1;
  google.protobuf.FloatValue float = 2;
  google.protobuf.Int32Value int32 = 3;
  google.protobuf.Int64Value int64 = 4;
  google.protobuf.UInt32Value uint32 = 5;
  google.protobuf.UInt64Value uint64 = 6;
  google.protobuf.BoolValue bool = 13;
  google.protobuf.StringValue string = 14;
  google.protobuf.BytesValue bytes = 15;
}

message NoWrapPrimitive {
  optional double double = 1;
  optional float float = 2 ;
  optional int32 int32 = 3;
  optional int64 int64 = 4;
  optional uint32  uint32 = 5;
  optional uint64 uint64 = 6;
  optional bool bool = 13;
  optional string string = 14;
  optional bytes bytes = 15;
}
