syntax = "proto2";

package wix.api;

import "wix/api/api_errors.proto";
import "google/protobuf/descriptor.proto";

option java_multiple_files = true;
option java_outer_classname = "ValidationsProto";
option java_package = "com.wix.api";

/**
*  Annotation for field validation rules
*  example usage:
*    import "wix/api/validations.proto";
*
*    message User {
*      string id = 1 [(wix.api.readOnly)=true, (wix.api.format)=GUID];
*      double age = 2 [(wix.api.max)=120, (wix.api.min)=0];
*      string email = 3 [(wix.api.format)=EMAIL];
*      string username = 4 [(wix.api.minLength)=3];
*      string phone = 5 [(wix.api.format)=PHONE];
*    }
*
*    message Invoice {
*      string id = 1 [(wix.api.readOnly)=true, (wix.api.format)=GUID];
*      string amount_paid = 2 [(wix.api.decimalValue) = { gte: "0.01" lt: "10" maxScale: 2 }];
*    }
**/
extend google.protobuf.FieldOptions {
    // max possible value
    optional double max = 50201;
    // min possible value
    optional double min = 50202;
    // max length for strings
    optional int32 maxLength = 50203;
    // min length for strings
    optional int32 minLength = 50204;
    // exact length for strings
    optional int32 exactLength = 50206;
    // max size for repeated field, map
    optional int32 maxSize = 50209;
    // min size for repeated field, map
    optional int32 minSize = 50210;
    // exact size for repeated field, map
    optional int32 exactSize = 50213;
    // common known formats like email, URI, etc.
    optional Format format = 50205;
    // indicates this field cannot be set by the client. E.g. Id field assigned by the server
    optional bool readOnly = 50208;
    // indicates this field can be set by the client, but can never be changed or updated
    optional bool immutable = 50212;
    // indicates this field is input-only, it will NOT be returned in output response
    optional bool writeOnly = 50154;
    // decimal value format
    optional DecimalValueOptions decimalValue = 50211;
    // declare custom field validation for all methods
    optional CustomValidationError custom_validation = 50214;
}

/**
* Decimal value validation rules.
* Based on java.math.BigDecimal, implies (wix.api.format) = DECIMAL_VALUE
*/
message DecimalValueOptions {
    optional string lte = 1; // less than or equal
    optional string gte = 2; // greater than or equal
    optional string lt = 3; // less than
    optional string gt = 4; // greater than
    optional int32 maxScale = 5; // max number of fractional digits
}

/**
* Annotation for method validation rules
* example usage:
* import "wix/api/validations.proto";
* service Bloop {
*    rpc Create (CreateBloopRequest) returns (CreateBloopResponse) {
*       option (wix.api.required) = "CreateBloopRequest.Bloop.name";
*    }
* }
**/
extend google.protobuf.MethodOptions {
    // Specify which fields are required in this method.
    // Annotating a nested field as `required` does not imply that the whole path to that field is required, eg.
    // `option (wix.api.required) = "person.pet.name";` means that if a `person` has a `pet`, then the `pet` must have
    // a `name` set; it does not mean that `person` or `person.pet` themselves are required - these fields should be
    // annotated individually if needed.
    // This option can be repeated multiple times to specify multiple fields.
    // example use:
    //    option (wix.api.required) = "userId";
    //    option (wix.api.required) = "userName";
    repeated string required = 50200;
    // Specify list of `immutable` fields which can be writable in this method.
    // Most common in Create methods
    // Only `immutable` AND NOT `readOnly` fields are allowed to be referenced via this annotation
    // example use:
    //    option (wix.api.writable) = "id"; // user-generated id is enabled
    repeated string writable = 50213;

}

extend google.protobuf.OneofOptions {
    // name of the enum field that must be aligned with this oneof (AIP 7015)
    // ADR 038: Linking oneOf with Enum: https://github.com/wix-private/server-infra/blob/master/framework/docs/adr/adr-038-aligned-with-enum.md
    optional AlignedWithEnum aligned_with_enum = 50800;
}

message AlignedWithEnum {
    required string field = 1;
    // defaults to _options if not specified
    optional string suffix = 2;
}

enum Format {
    EMAIL = 0;
    HOSTNAME = 1;
    IPV4 = 2;
    IPV6 = 3;
    URI = 4;
    WEB_URL = 5; // HTTP or HTTPS
    PHONE = 7;
    CREDIT_CARD = 8;
    GUID = 9;
    COUNTRY = 10; // 2 letters ISO-3166-1
    LANGUAGE = 11; // 2 letters ISO-639-1
    /*
      Use this on string or stringValue types to validate the format of that field is same as a decimal value.
      This will ensure keeping the precision of decimal value, such as when passing monetary values.
    */
    DECIMAL_VALUE = 12;
    CURRENCY = 13; // 3 letters - all available currencies
    LANGUAGE_TAG = 14; // IETF BCP 47 language tag (e.g. en-US)
    COLOR_HEX = 15; // hex color format as defined by the MDN https://developer.mozilla.org/en-US/docs/Web/CSS/hex-color
    LOCAL_DATE = 16; // ISO-8601 extended local date format (YYYY-MM-DD)
    LOCAL_TIME = 17; // ISO-8601 extended local time format (hh:mm[:ss][.sss])
    LOCAL_DATE_TIME = 18; // ISO-8601 extended local date-time format (YYYY-MM-DDThh:mm[:ss][.sss])
    URL_SLUG = 19;
    SYSTEM_SLUG = 20;
    SECURE_WEB_URL = 21; // HTTPS only
    SUBDIVISION = 22; // ISO-3166-2
}
