// Go support for Protocol Buffers - Google's data interchange format
//
// Copyright 2010 The Go Authors.  All rights reserved.
// https://github.com/golang/protobuf
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

syntax = "proto2";

// This package holds interesting messages.
package my.test;  // dotted package name

option go_package = "github.com/golang/protobuf/protoc-gen-go/testdata/my_test;test";

//import "imp.proto";
import "multi/multi1.proto";  // unused import

enum HatType {
  // deliberately skipping 0
  FEDORA = 1;
  FEZ = 2;
}

// This enum represents days of the week.
enum Days {
  option allow_alias = true;

  MONDAY = 1;
  TUESDAY = 2;
  LUNDI = 1;  // same value as MONDAY
}

// This is a message that might be sent somewhere.
message Request {
  enum Color {
    RED = 0;
    GREEN = 1;
    BLUE = 2;
  }
  repeated int64 key = 1;
//  optional imp.ImportedMessage imported_message = 2;
  optional Color hue = 3; // no default
  optional HatType hat = 4 [default=FEDORA];
//  optional imp.ImportedMessage.Owner owner = 6;
  optional float deadline = 7 [default=inf];
  optional group SomeGroup = 8 {
    optional int32 group_field = 9;
  }

  // These foreign types are in imp2.proto,
  // which is publicly imported by imp.proto.
//  optional imp.PubliclyImportedMessage pub = 10;
//  optional imp.PubliclyImportedEnum pub_enum = 13 [default=HAIR];


  // This is a map field. It will generate map[int32]string.
  map<int32, string> name_mapping = 14;
  // This is a map field whose value type is a message.
  map<sint64, Reply> msg_mapping = 15;

  optional int32 reset = 12;
  // This field should not conflict with any getters.
  optional string get_key = 16;
}

message Reply {
  message Entry {
    required int64 key_that_needs_1234camel_CasIng = 1;
    optional int64 value = 2 [default=7];
    optional int64 _my_field_name_2 = 3;
    enum Game {
      FOOTBALL = 1;
      TENNIS = 2;
    }
  }
  repeated Entry found = 1;
  repeated int32 compact_keys = 2 [packed=true];
  extensions 100 to max;
}

message OtherBase {
  optional string name = 1;
  extensions 100 to max;
}

message ReplyExtensions {
  extend Reply {
    optional double time = 101;
    optional ReplyExtensions carrot = 105;
  }
  extend OtherBase {
    optional ReplyExtensions donut = 101;
  }
}

message OtherReplyExtensions {
  optional int32 key = 1;
}

// top-level extension
extend Reply {
  optional string tag = 103;
  optional OtherReplyExtensions donut = 106;
//  optional imp.ImportedMessage elephant = 107;  // extend with message from another file.
}

message OldReply {
  // Extensions will be encoded in MessageSet wire format.
  option message_set_wire_format = true;
  extensions 100 to max;
}

message Communique {
  optional bool make_me_cry = 1;

  // This is a oneof, called "union".
  oneof union {
    int32 number = 5;
    string name = 6;
    bytes data = 7;
    double temp_c = 8;
    float height = 9;
    Days today = 10;
    bool maybe = 11;
    sint32 delta = 12;  // name will conflict with Delta below
    Reply msg = 16;  // requires two bytes to encode field tag
    group SomeGroup = 14 {
      optional string member = 15;
    }
  }

  message Delta {}
}

