// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.
//
// Protobufs used by both client-server and server-server traffic
// for user data transfer. This file should only contain protobufs
// which are exclusively used on the wire. If a protobuf is persisted on
// disk and not used as part of the wire protocol, it belongs in another
// place such as common/common.proto or within cfile/, server/, etc.
syntax = "proto2";
package kudu;

option java_package = "org.apache.kudu";

import "kudu/common/common.proto";
import "kudu/consensus/metadata.proto";

// Error status returned by any RPC method.
// Every RPC method which could generate an application-level error
// should have this (or a more complex error result) as an optional field
// in its response.
//
// This maps to kudu::Status in C++ and org.apache.kudu.Status in Java.
message AppStatusPB {
  enum ErrorCode {
    UNKNOWN_ERROR = 999;
    OK = 0;
    NOT_FOUND = 1;
    CORRUPTION = 2;
    NOT_SUPPORTED = 3;
    INVALID_ARGUMENT = 4;
    IO_ERROR = 5;
    ALREADY_PRESENT = 6;
    RUNTIME_ERROR = 7;
    NETWORK_ERROR = 8;
    ILLEGAL_STATE = 9;
    NOT_AUTHORIZED = 10;
    ABORTED = 11;
    REMOTE_ERROR = 12;
    SERVICE_UNAVAILABLE = 13;
    TIMED_OUT = 14;
    UNINITIALIZED = 15;
    CONFIGURATION_ERROR = 16;
    INCOMPLETE = 17;
    END_OF_FILE = 18;
    CANCELLED = 19;
  }

  required ErrorCode code = 1;
  optional string message = 2;
  optional int32 posix_code = 4;
}

// Uniquely identify a particular instance of a particular server in the
// cluster.
message NodeInstancePB {
  // Unique ID which is created when the server is first started
  // up. This is stored persistently on disk.
  required bytes permanent_uuid = 1;

  // Sequence number incremented on every start-up of the server.
  // This makes it easy to detect when an instance has restarted (and
  // thus can be assumed to have forgotten any soft state it had in
  // memory).
  //
  // On a freshly initialized server, the first sequence number
  // should be 0.
  required int64 instance_seqno = 2;
}

// Some basic properties common to both masters and tservers.
// They are guaranteed not to change unless the server is restarted.
message ServerRegistrationPB {
  repeated HostPortPB rpc_addresses = 1;
  repeated HostPortPB http_addresses = 2;
  optional string software_version = 3;

  // True if HTTPS has been enabled for the web interface.
  // In this case, https:// URLs should be generated for the above
  // 'http_addresses' field.
  optional bool https_enabled = 4;

  // The wall clock time when the server started as seconds since the Epoch.
  optional int64 start_time = 5;

  // The path of a UNIX domain socket where the server is listening.
  // An '@' prefix indicates the abstract namespace. May be missing
  // if this feature is not enabled.
  optional string unix_domain_socket_path = 6;
}

message ServerEntryPB {
  // If there is an error communicating with the server (or retrieving
  // the server registration on the server itself), this field will be
  // set to contain the error.
  //
  // All subsequent fields are optional, as they may not be set if
  // an error is encountered communicating with the individual server.
  optional AppStatusPB error = 1;

  optional NodeInstancePB instance_id = 2;
  optional ServerRegistrationPB registration = 3;

  // If an error has occurred earlier in the RPC call, the role
  // may be not be set.
  optional consensus.RaftPeerPB.Role role = 4;

  // The unique cluster ID of the cluster this server belongs too.
  // TODO(ghenke): Currently only set for masters.
  optional string cluster_id = 5;

  // If an error has occurred earlier in the RPC call, the
  // member_type may not be set.
  optional consensus.RaftPeerPB.MemberType member_type = 6;
}

// A row block in which each row is stored contiguously.
message RowwiseRowBlockPB {
  // The number of rows in the block. This can typically be calculated
  // by dividing rows.size() by the width of the row, but in the case that
  // the client is scanning an empty projection (i.e a COUNT(*)), this
  // field is the only way to determine how many rows were returned.
  optional int32 num_rows = 1 [ default = 0 ];

  // Sidecar index for the row data.
  //
  // In the sidecar, each row is stored in the same in-memory format
  // as kudu::ContiguousRow (i.e the raw unencoded data followed by
  // a null bitmap).
  //
  // The data for NULL cells will be present with undefined contents --
  // typically it will be filled with \x00s but this is not guaranteed,
  // and clients may choose to initialize NULL cells with whatever they
  // like. Setting to some constant improves RPC compression, though.
  //
  // Any pointers are made relative to the beginning of the indirect
  // data sidecar.
  //
  // See rpc/rpc_sidecar.h for more information on where the data is
  // actually stored.
  optional int32 rows_sidecar = 2;

  // Sidecar index for the indirect data.
  //
  // In the sidecar, "indirect" data types in the block are stored
  // contiguously. For example, STRING values in the block will be
  // stored using the normal Slice in-memory format, except that
  // instead of being pointers in RAM, the pointer portion will be an
  // offset into this protobuf field.
  optional int32 indirect_data_sidecar = 3;
}

// A block of rows in columnar layout.
message ColumnarRowBlockPB {
  message Column {
    // The index of the sidecar containing cell data of the column.
    optional int32 data_sidecar = 1;

    // The index of the sidecar containing any data referred to by binary/string data.
    // In this case, the `data` sidecar will contain an array of `num_rows + 1` uint32s
    // pointing to offsets in this sidecar.
    optional int32 varlen_data_sidecar = 2;

    // If the column is nullable, The index of the sidecar containing a bitmap with a set
    // bit for all non-null cells.
    optional int32 non_null_bitmap_sidecar = 3;
  }
  repeated Column columns = 1;
  optional int64 num_rows = 2;
}
