// 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.config.core.v3;

import "envoy/config/core/v3/base.proto";
import "envoy/config/core/v3/extension.proto";

import "google/protobuf/struct.proto";

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

option java_package = "io.envoyproxy.envoy.config.core.v3";
option java_outer_classname = "SubstitutionFormatStringProto";
option java_multiple_files = true;
option go_package = "github.com/envoyproxy/go-control-plane/envoy/config/core/v3;corev3";
option (udpa.annotations.file_status).package_version_status = ACTIVE;

// [#protodoc-title: Substitution format string]

// Optional configuration options to be used with json_format.
message JsonFormatOptions {
  // The output JSON string properties will be sorted.
  //
  // .. note::
  //   As the properties are always sorted, this option has no effect and is deprecated.
  //
  bool sort_properties = 1
      [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];
}

// Configuration to use multiple :ref:`command operators <config_access_log_command_operators>`
// to generate a new string in either plain text or JSON format.
// [#next-free-field: 8]
message SubstitutionFormatString {
  oneof format {
    option (validate.required) = true;

    // Specify a format with command operators to form a text string.
    // Its details is described in :ref:`format string<config_access_log_format_strings>`.
    //
    // For example, setting ``text_format`` like below,
    //
    // .. validated-code-block:: yaml
    //   :type-name: envoy.config.core.v3.SubstitutionFormatString
    //
    //   text_format: "%LOCAL_REPLY_BODY%:%RESPONSE_CODE%:path=%REQ(:path)%\n"
    //
    // generates plain text similar to:
    //
    // .. code-block:: text
    //
    //   upstream connect error:503:path=/foo
    //
    // Deprecated in favor of :ref:`text_format_source <envoy_v3_api_field_config.core.v3.SubstitutionFormatString.text_format_source>`. To migrate text format strings, use the :ref:`inline_string <envoy_v3_api_field_config.core.v3.DataSource.inline_string>` field.
    string text_format = 1
        [deprecated = true, (envoy.annotations.deprecated_at_minor_version) = "3.0"];

    // Specify a format with command operators to form a JSON string.
    // Its details is described in :ref:`format dictionary<config_access_log_format_dictionaries>`.
    // Values are rendered as strings, numbers, or boolean values as appropriate.
    // Nested JSON objects may be produced by some command operators (e.g. FILTER_STATE or DYNAMIC_METADATA).
    // See the documentation for a specific command operator for details.
    //
    // .. validated-code-block:: yaml
    //   :type-name: envoy.config.core.v3.SubstitutionFormatString
    //
    //   json_format:
    //     status: "%RESPONSE_CODE%"
    //     message: "%LOCAL_REPLY_BODY%"
    //
    // The following JSON object would be created:
    //
    // .. code-block:: json
    //
    //  {
    //    "status": 500,
    //    "message": "My error message"
    //  }
    //
    google.protobuf.Struct json_format = 2 [(validate.rules).message = {required: true}];

    // Specify a format with command operators to form a text string.
    // Its details is described in :ref:`format string<config_access_log_format_strings>`.
    //
    // For example, setting ``text_format`` like below,
    //
    // .. validated-code-block:: yaml
    //   :type-name: envoy.config.core.v3.SubstitutionFormatString
    //
    //   text_format_source:
    //     inline_string: "%LOCAL_REPLY_BODY%:%RESPONSE_CODE%:path=%REQ(:path)%\n"
    //
    // generates plain text similar to:
    //
    // .. code-block:: text
    //
    //   upstream connect error:503:path=/foo
    //
    DataSource text_format_source = 5;
  }

  // If set to true, when command operators are evaluated to null,
  //
  // * for ``text_format``, the output of the empty operator is changed from ``-`` to an
  //   empty string, so that empty values are omitted entirely.
  // * for ``json_format`` the keys with null values are omitted in the output structure.
  //
  // .. note::
  //   This option does not work perfectly with ``json_format`` as keys with ``null`` values
  //   will still be included in the output. See https://github.com/envoyproxy/envoy/issues/37941
  //   for more details.
  //
  bool omit_empty_values = 3;

  // Specify a ``content_type`` field.
  // If this field is not set then ``text/plain`` is used for ``text_format`` and
  // ``application/json`` is used for ``json_format``.
  //
  // .. validated-code-block:: yaml
  //   :type-name: envoy.config.core.v3.SubstitutionFormatString
  //
  //   content_type: "text/html; charset=UTF-8"
  //
  string content_type = 4
      [(validate.rules).string = {well_known_regex: HTTP_HEADER_VALUE strict: false}];

  // Specifies a collection of Formatter plugins that can be called from the access log configuration.
  // See the formatters extensions documentation for details.
  // [#extension-category: envoy.formatter]
  repeated TypedExtensionConfig formatters = 6;

  // If json_format is used, the options will be applied to the output JSON string.
  JsonFormatOptions json_format_options = 7;
}
