// Copyright 2025 Envoy Project Authors
//
// Licensed 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.

syntax = "proto3";

package envoy.type.matcher.v3;

import "google/protobuf/wrappers.proto";

import "envoy/annotations/deprecation.proto";
import "udpa/annotations/status.proto";
import "udpa/annotations/versioning.proto";
import "validate/validate.proto";

option java_package = "io.envoyproxy.envoy.type.matcher.v3";
option java_outer_classname = "RegexProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3;matcherv3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Regex matcher]

// A regex matcher designed for safety when used with untrusted input.
message RegexMatcher {
  option (udpa.annotations.versioning).previous_message_type = "envoy.type.matcher.RegexMatcher";

  // Google's `RE2 <https://github.com/google/re2>`_ regex engine. The regex string must adhere to
  // the documented `syntax <https://github.com/google/re2/wiki/Syntax>`_. The engine is designed
  // to complete execution in linear time as well as limit the amount of memory used.
  //
  // Envoy supports program size checking via runtime. The runtime keys ``re2.max_program_size.error_level``
  // and ``re2.max_program_size.warn_level`` can be set to integers as the maximum program size or
  // complexity that a compiled regex can have before an exception is thrown or a warning is
  // logged, respectively. ``re2.max_program_size.error_level`` defaults to 100, and
  // ``re2.max_program_size.warn_level`` has no default if unset (will not check/log a warning).
  //
  // Envoy emits two stats for tracking the program size of regexes: the histogram ``re2.program_size``,
  // which records the program size, and the counter ``re2.exceeded_warn_level``, which is incremented
  // each time the program size exceeds the warn level threshold.
  message GoogleRE2 {
    option (udpa.annotations.versioning).previous_message_type =
        "envoy.type.matcher.RegexMatcher.GoogleRE2";

    // This field controls the RE2 "program size" which is a rough estimate of how complex a
    // compiled regex is to evaluate. A regex that has a program size greater than the configured
    // value will fail to compile. In this case, the configured max program size can be increased
    // or the regex can be simplified. If not specified, the default is 100.
    //
    // This field is deprecated; regexp validation should be performed on the management server
    // instead of being done by each individual client.
    //
    // .. note::
    //
    //  Although this field is deprecated, the program size will still be checked against the
    //  global ``re2.max_program_size.error_level`` runtime value.
    //
    google.protobuf.UInt32Value max_program_size = 1
        [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
  }

  oneof engine_type {
    // Google's RE2 regex engine.
    GoogleRE2 google_re2 = 1
        [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
  }

  // The regex match string. The string must be supported by the configured engine. The regex is matched
  // against the full string, not as a partial match.
  string regex = 2 [(validate.rules).string = {min_len: 1}];
}

// Describes how to match a string and then produce a new string using a regular
// expression and a substitution string.
message RegexMatchAndSubstitute {
  option (udpa.annotations.versioning).previous_message_type =
      "envoy.type.matcher.RegexMatchAndSubstitute";

  // The regular expression used to find portions of a string (hereafter called
  // the "subject string") that should be replaced. When a new string is
  // produced during the substitution operation, the new string is initially
  // the same as the subject string, but then all matches in the subject string
  // are replaced by the substitution string. If replacing all matches isn't
  // desired, regular expression anchors can be used to ensure a single match,
  // so as to replace just one occurrence of a pattern. Capture groups can be
  // used in the pattern to extract portions of the subject string, and then
  // referenced in the substitution string.
  RegexMatcher pattern = 1 [(validate.rules).message = {required: true}];

  // The string that should be substituted into matching portions of the
  // subject string during a substitution operation to produce a new string.
  // Capture groups in the pattern can be referenced in the substitution
  // string. Note, however, that the syntax for referring to capture groups is
  // defined by the chosen regular expression engine. Google's `RE2
  // <https://github.com/google/re2>`_ regular expression engine uses a
  // backslash followed by the capture group number to denote a numbered
  // capture group. E.g., ``\1`` refers to capture group 1, and ``\2`` refers
  // to capture group 2.
  string substitution = 2
      [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}];
}
