syntax = "proto3";

package sample_bank_account;


/**
 * @Indexed
 * @TypeId(100042)
 */
message User {
   /* CommentOne */

   /* @CommentTwo */

   /**
    * @Field(store = Store.YES)
    * @SortableField
    */
   int32 id = 1;

   /**
    * @Field(store = Store.YES)
    */
   repeated int32 accountIds = 2;

   /**
    * @Field(store = Store.YES)
    * @SortableField
    */
   string name = 3;

   /**
    * @Field(store = Store.YES, indexNullAs = "_null_")
    * @SortableField
    */
   optional string surname = 4;

   /**
    * @Field(store = Store.YES, indexNullAs = "_null_")
    */   
   optional string salutation = 5;

   /**
    * @Indexed
    */
   message Address {

      /**
       * @Field(store = Store.YES)
       */
      string street = 1;

      /**
       * @Field(store = Store.YES)
       */
      string postCode = 2;

      /**
       * @Field(store = Store.YES)
       */
      int32 number = 3;

      bool isCommercial = 4;
   }

   /**
    * @Field(store = Store.YES)
    */
   repeated Address addresses = 6;     //a repeated field cannot be marked required

   /**
    * @Field(store = Store.NO, indexNullAs = "-1")
    * @SortableField
    */
   optional int32 age = 7;   // persisting age instead of birth date is not ideal but is ok for our sample code

   /* @TypeId(100041) */
   enum Gender {
      MALE = 0;    //NOTE: It seems negative values are accepted too!
      FEMALE = 1;
      UNSPECIFIED = 2;
   }

   /**
    * @Field(store = Store.YES)
    */
   optional Gender gender = 8;

   optional string notes = 9;

   /**
    * @Field(store = Store.YES, indexNullAs = "-1")
    * @SortableField
    */
   optional fixed64 creationDate = 10;

   optional fixed64 passwordExpirationDate = 11;

   optional int64 qrCode = 12;
}

/**
 * @Indexed
 */
message Account {
   reserved "gamma";
   reserved "alpha", "beta";
   reserved 8;
   reserved 10, 11;
   reserved 13 to 15;
   reserved 17, 19 to 20, 22;

   /**
    * @Field(store = Store.YES)
    * @SortableField
    */
   int32 id = 1;

   /**
    * @Field(store = Store.YES)
    * @SortableField
    */
   optional string description = 2;// [default = "Checking account"];

   /**
    * @Field(store = Store.YES)
    * @SortableField
    */
   fixed64 creationDate = 3;

   /**
    * @Indexed
    */
   message Limits {

       /**
        * @Field(store = Store.YES)
        */
       optional double maxDailyLimit = 1;

       /**
        * @Field(store = Store.YES)
        */
       optional double maxTransactionLimit = 2;

       /**
        * @Field(store = Store.YES)
        */
       repeated string payees = 3;
   }

   /**
    * @Field(store = Store.YES)
    */
   optional Limits limits = 4;

   /**
    * @Field(store = Store.YES)
    */
   Limits hardLimits = 5;

   /**
    * @Field(store = Store.YES)
    */
   repeated bytes blurb = 6;

   /** @TypeId(100043) */
   enum Currency {
      EUR = 0;
      GBP = 1;
      USD = 2;
      BRL = 3;
   }

   repeated Currency currencies = 7;
}

/**
 * @Indexed
 * @Analyzer(definition = "standard")
 */
message Transaction {

   /**
    * @Field(store = Store.YES)
    * @SortableField
    */
   int32 id = 1;

   /**
    * @Field
    * @SortableField
    */
   optional string description = 2;

   /**
    * @Field(store = Store.YES, analyze = Analyze.YES))
    * @SortableField
    */
   optional string longDescription = 3;

   /**
    * @Field(store = Store.YES, analyze = Analyze.YES))
    * @Analyzer(definition = "ngram")
    */
   optional string notes = 4;

   /**
    * @Field(store = Store.YES)
    */
   int32 accountId = 5;

   /**
    * @Field(store = Store.YES)
    */
   fixed64 date = 6;  // there is no native Date type in protobuf so we have to store it as a long

   /**
    * @Field(store = Store.YES)
    * @SortableField
    */
   double amount = 7; // how do I store a BigDecimal? maybe as a byte array ..

   /**
    * @Field(store = Store.YES)
    */
   bool isDebit = 8;

   /**
    * No annotations here. This is left unindexed on purpose.
    */
   bool isValid = 9;

   oneof choice {
      string one = 10;
      int32 or_the_other = 11;
   }

}

message Numerics {

   /**
    * @Field(store = Store.YES)
    */
   optional int32 simpleByte = 1;

   /**
    * @Field(store = Store.YES)
    */
   optional int32 simpleShort = 2;

   /**
    * @Field(store = Store.YES)
    */
   optional int32 simpleInt = 3;

   /**
    * @Field(store = Store.YES)
    */
   optional int64 simpleLong = 4;

   /**
    * @Field(store = Store.YES)
    */
   optional float simpleFloat = 5;

   /**
    * @Field(store = Store.YES)
    */
   optional double simpleDouble = 6;
}

/**
 * An array of int.
 */
message int_array {
   repeated int32 theArray = 1;
}

/**
 * A list of User messages.
 */
message user_list {
   repeated User theList = 1;
}

/**
 * identifiers using protobuf keywords
 */
message message {
   bool true = 1;
   int32 map = 2;
   string message = 3;
}

//todo demonstrate collection of 'any'
