syntax = "proto3";

package xds.type.matcher.v3;

import "xds/core/v3/extension.proto";
import "xds/type/matcher/v3/regex.proto";

import "validate/validate.proto";

option java_package = "com.github.xds.type.matcher.v3";
option java_outer_classname = "StringProto";
option java_multiple_files = true;
option go_package = "github.com/cncf/xds/go/xds/type/matcher/v3";

// [#protodoc-title: String matcher]

// Specifies the way to match a string.
// [#next-free-field: 9]
message StringMatcher {
  oneof match_pattern {
    option (validate.required) = true;

    // The input string must match exactly the string specified here.
    //
    // Examples:
    //
    // * *abc* only matches the value *abc*.
    string exact = 1;

    // The input string must have the prefix specified here.
    // Note: empty prefix is not allowed, please use regex instead.
    //
    // Examples:
    //
    // * *abc* matches the value *abc.xyz*
    string prefix = 2 [(validate.rules).string = {min_len: 1}];

    // The input string must have the suffix specified here.
    // Note: empty prefix is not allowed, please use regex instead.
    //
    // Examples:
    //
    // * *abc* matches the value *xyz.abc*
    string suffix = 3 [(validate.rules).string = {min_len: 1}];

    // The input string must match the regular expression specified here.
    RegexMatcher safe_regex = 5 [(validate.rules).message = {required: true}];

    // The input string must have the substring specified here.
    // Note: empty contains match is not allowed, please use regex instead.
    //
    // Examples:
    //
    // * *abc* matches the value *xyz.abc.def*
    string contains = 7 [(validate.rules).string = {min_len: 1}];

    // Use an extension as the matcher type.
    // [#extension-category: envoy.string_matcher]
    xds.core.v3.TypedExtensionConfig custom = 8;
  }

  // If true, indicates the exact/prefix/suffix matching should be case insensitive. This has no
  // effect for the safe_regex match.
  // For example, the matcher *data* will match both input string *Data* and *data* if set to true.
  bool ignore_case = 6;
}

// Specifies a list of ways to match a string.
message ListStringMatcher {
  repeated StringMatcher patterns = 1 [(validate.rules).repeated = {min_items: 1}];
}
