// 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;
    IMMUTABLE = 20;
  }

  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;
}
