// Copyright 2016 Istio 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 istio.mixer.v1;

option go_package = "istio.io/api/mixer/v1";

import "gogoproto/gogo.proto";
import "google/protobuf/duration.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/struct.proto";

option (gogoproto.goproto_getters_all) = false;
option (gogoproto.equal_all) = false;
option (gogoproto.gostring_all) = false;
option (gogoproto.stable_marshaler_all) = true;
option cc_enable_arenas = true;

message StructWrap {
  google.protobuf.Struct struct = 1;

  google.protobuf.Value any = 2;
  google.protobuf.ListValue listVal = 3;
  google.protobuf.BoolValue boolVal = 4;
  google.protobuf.StringValue stringVal = 5;
  google.protobuf.NumberValue numberVal = 6;
}

// Attributes represents a set of typed name/value pairs. Many of Mixer's
// API either consume and/or return attributes.
//
// Istio uses attributes to control the runtime behavior of services running in the service mesh.
// Attributes are named and typed pieces of metadata describing ingress and egress traffic and the
// environment this traffic occurs in. An Istio attribute carries a specific piece
// of information such as the error code of an API request, the latency of an API request, or the
// original IP address of a TCP connection. For example:
//
// ```yaml
// request.path: xyz/abc
// request.size: 234
// request.time: 12:34:56.789 04/17/2017
// source.ip: 192.168.0.1
// target.service: example
// ```
//
// A given Istio deployment has a fixed vocabulary of attributes that it understands.
// The specific vocabulary is determined by the set of attribute producers being used
// in the deployment. The primary attribute producer in Istio is Envoy, although
// specialized Mixer adapters and services can also generate attributes.
//
// The common baseline set of attributes available in most Istio deployments is defined
// [here](https://istio.io/docs/reference/config/policy-and-telemetry/attribute-vocabulary/).
//
// Attributes are strongly typed. The supported attribute types are defined by
// [ValueType](https://github.com/istio/api/blob/master/policy/v1beta1/value_type.proto).
// Each type of value is encoded into one of the so-called transport types present
// in this message.
//
// Defines a map of attributes in uncompressed format.
// Following places may use this message:
// 1) Configure Istio/Proxy with static per-proxy attributes, such as source.uid.
// 2) Service IDL definition to extract api attributes for active requests.
// 3) Forward attributes from client proxy to server proxy for HTTP requests.
message Attributes {
  // A map of attribute name to its value.
  map<string, AttributeValue> attributes = 1;

  // Specifies one attribute value with different type.
  message AttributeValue {
    // The attribute value.
    oneof value {
      // Used for values of type STRING, DNS_NAME, EMAIL_ADDRESS, and URI
      string string_value = 2;

      // Used for values of type INT64
      int64 int64_value = 3;

      // Used for values of type DOUBLE
      double double_value = 4;

      // Used for values of type BOOL
      bool bool_value = 5;

      // Used for values of type BYTES
      bytes bytes_value = 6;

      // Used for values of type TIMESTAMP
      google.protobuf.Timestamp timestamp_value = 7;

      // Used for values of type DURATION
      google.protobuf.Duration duration_value = 8;

      // Used for values of type STRING_MAP
      StringMap string_map_value = 9;
    }
  }

  // Defines a string map.
  message StringMap {
    // Holds a set of name/value pairs.
    map<string, string> entries = 1;
  }
}

// Defines a list of attributes in compressed format optimized for transport.
// Within this message, strings are referenced using integer indices into
// one of two string dictionaries. Positive integers index into the global
// deployment-wide dictionary, whereas negative integers index into the message-level
// dictionary instead. The message-level dictionary is carried by the
// `words` field of this message, the deployment-wide dictionary is determined via
// configuration.
message CompressedAttributes {
  // The message-level dictionary.
  repeated string words = 1;

  // Holds attributes of type STRING, DNS_NAME, EMAIL_ADDRESS, URI
  map<sint32, sint32> strings = 2;

  // Holds attributes of type INT64
  map<sint32, int64> int64s = 3;

  // Holds attributes of type DOUBLE
  map<sint32, double> doubles = 4;

  // Holds attributes of type BOOL
  map<sint32, bool> bools = 5;

  // Holds attributes of type TIMESTAMP
  map<sint32, google.protobuf.Timestamp> time = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true];

  // Holds attributes of type DURATION
  map<sint32, google.protobuf.Duration> durations = 7 [(gogoproto.nullable) = false, (gogoproto.stdduration) = true];

  // Holds attributes of type BYTES
  map<sint32, bytes> bytes = 8;

  // Holds attributes of type STRING_MAP
  map<sint32, StringMap> string_maps = 9 [(gogoproto.nullable) = false];
}

// A map of string to string. The keys and values in this map are dictionary
// indices (see the [Attributes][istio.mixer.v1.CompressedAttributes] message for an explanation)
message StringMap {
  // Holds a set of name/value pairs.
  map<sint32, sint32> entries = 1;
}
