// Copyright 2010-2020, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

// Protocol messages to be used for mozc client/server communication.
//
// The Command message contains all the input/output values for
// client/server commnication.  The messages structure of Command and
// its child messages are here:

syntax = "proto2";

package mozc.commands;

import "protocol/candidates.proto";
import "protocol/config.proto";
import "protocol/engine_builder.proto";
import "protocol/user_dictionary_storage.proto";

option java_outer_classname = "ProtoCommands";
option java_package = "org.mozc.android.inputmethod.japanese.protobuf";

// This enum is used by SessionCommand::input_mode with
// CHANGE_INPUT_MODE and Output::mode.
enum CompositionMode {
  DIRECT = 0;
  HIRAGANA = 1;
  FULL_KATAKANA = 2;
  HALF_ASCII = 3;
  FULL_ASCII = 4;
  HALF_KATAKANA = 5;
  NUM_OF_COMPOSITIONS = 6;
}

message KeyEvent {
  enum SpecialKey {
    NO_SPECIALKEY = 0;
    DIGIT = 1;
    // On Windows, SpecialKey::On and SpecialKey::OFF are obsolete. Use
    // TURN_ON_IME session command should be used instead. See b/10216365.
    // On other platforms, especially on Mac, please note that
    // client/client.cc still relies on SpecialKey::On for session playback.
    // We need to fix b/10250883 first.
    // TODO(team): Unsupport SpecialKey::On and SpecialKey::OFF.
    ON = 2;
    OFF = 3;
    SPACE = 4;
    ENTER = 5;
    LEFT = 6;
    RIGHT = 7;
    UP = 8;
    DOWN = 9;
    ESCAPE = 10;
    DEL = 11;  // not DELETE because DELETE is reserved in MSVC
    BACKSPACE = 12;
    HENKAN = 13;
    MUHENKAN = 14;
    KANA = 15;  // VK_DBE_HIRAGANA(Win), kVK_JIS_Kana(Mac)
    // TODO(toshiyuki): It is better to rename this to HIRAGANA
    // In Windows, we have Katakana and it may confusing.
    HOME = 16;
    END = 17;
    TAB = 18;
    F1 = 19;
    F2 = 20;
    F3 = 21;
    F4 = 22;
    F5 = 23;
    F6 = 24;
    F7 = 25;
    F8 = 26;
    F9 = 27;
    F10 = 28;
    F11 = 29;
    F12 = 30;
    PAGE_UP = 31;
    PAGE_DOWN = 32;
    INSERT = 33;
    F13 = 34;
    F14 = 35;
    F15 = 36;
    F16 = 37;
    F17 = 38;
    F18 = 39;
    F19 = 40;
    F20 = 41;
    F21 = 42;
    F22 = 43;
    F23 = 44;
    F24 = 45;
    EISU = 46;  // alphanumeric  VK_DBE_ALPHANUMERIC(Win), kVK_JIS_Eisu(Mac)
    NUMPAD0 = 47;
    NUMPAD1 = 48;
    NUMPAD2 = 49;
    NUMPAD3 = 50;
    NUMPAD4 = 51;
    NUMPAD5 = 52;
    NUMPAD6 = 53;
    NUMPAD7 = 54;
    NUMPAD8 = 55;
    NUMPAD9 = 56;
    MULTIPLY = 57;    // Numpad [*]
    ADD = 58;         // Numpad [+]
    SEPARATOR = 59;   // Numpad [enter]
    SUBTRACT = 60;    // Numpad [-]
    DECIMAL = 61;     // Numpad [.]
    DIVIDE = 62;      // Numpad [/]
    EQUALS = 63;      // Numpad [=]
    TEXT_INPUT = 64;  // Meta key event representing any text input.
    HANKAKU = 65;
    KANJI = 66;
    KATAKANA = 67;  // VK_DBE_KATAKANA(Win)
    CAPS_LOCK = 68;
    // Unsupported keys (e.g. PrtSc, Pause) fall back to UNDEFINED_KEY.
    UNDEFINED_KEY = 69;
    COMMA = 70;          // Numpad [,]
    CLEAR = 71;          // Numpad [5] without NUMLOCK
    VIRTUAL_LEFT = 72;   // Left key on virtual (software) keyboard
    VIRTUAL_RIGHT = 73;  // Right key on virtual (software) keyboard
    VIRTUAL_ENTER = 74;  // Enter key on virtual (software) keyboard
    VIRTUAL_UP = 75;     // Up key on virtual (software) keyboard
    VIRTUAL_DOWN = 76;   // Down key on virtual (software) keyboard

    NUM_SPECIALKEYS = 77;
  }

  // CTRL, ALT and SHIFT cover both LEFT and RIGHT keys.  If the
  // difference between LEFT and RIGHT is no matter, using CTRL (or ALT, SHIFT)
  // is preferred.
  // If LEFT (or RIGHT) CTRL(or ALT, SHIFT) is pressed, LEFT_CTRL is set on
  // Windows or Mac client, or LEFT_CTRL and CTRL are set on Unix client.
  // Mozc key translation logic is as follows
  //
  //             ---- Modifier Keys -----
  //             |                      |
  //             |         B            |
  //    ---------+------        -- -----+-------
  //    |        |  D  |        |   E   |      |
  //    |    A   +---- +--------+--------  C   |
  //    |              |   F    |              |
  //    --Special Keys--        ---Other Keys---
  //
  // A:Press only a special key
  //   => Send special key event with no modifier.
  // B:Press only modifier keys
  //   => Send modifier key event with no key_code.
  // C:Press an other key
  //   => Send KeyEvent with no modifier.
  // D:Press a special key with one or more modifier keys
  //   => Send special key event with modifiers.
  // E:Press an other key with one or more modifier keys
  //   => If combined key is printable, replace keycodes. Otherwise, just send
  //   with modifier keys. Note that, unless the whole combined key is
  //   printable, keycodes are not replaced even if a subset of combined key is
  //   printable.
  // F:Otherwise
  //   => Send nothing.
  //
  // Following example shows expected behaviours.
  // E.g. )
  //    case   |  Pressed Key  |   translated key event
  //  ----------------------------------------------------
  //     A     |      SP       |  special_key = 4
  //     A     |      F1       |  special_key = 19
  //     B     |     CTRL      |  modifier_key = {CTRL}
  //     B     |     SHIFT     |  modifier_key = {SHIFT}
  //     B     |   CTRL+SHIFT  |  modifier_key = {CTRL,SHIFT}
  //     C     |      'a'      |  key_code = \x61 = 'a'
  //     D     |    CTRL+BS    |  special_key = 12, modifier_key = {CTRL}
  //     D     | CTRL+SHIFT+BS |  special_key = 12, modifier_key = {CTRL,SHIFT}
  //     E     |   SHIFT+'a'   |  key_code = \x41 = 'A'
  //     E     |   CTRL+'a'    |  key_code = \x61, modifier_key = {CTRL}
  //     E     | CTRL+ALT+'a'  |  key_code = \x61, modifier_key = {CTRL,ALT}
  //     E     | CTRL+SHIFT+'a'|  key_code = \x61, modifier_key = {CTRL,SHIFT}
  //     F     | CTRL+BS+SP    |  send nothing
  //
  // In addition, we treat CAPS lock independently besides alphabet keys,
  // though it is a member of modifier keys. Following example shows currently
  // expected behaviours with Caps lock set.
  //
  // E.g. ) While CAPS is set on.
  //    Pressed Key  |   translated key event
  //  ----------------------------------------------------
  //       'a'       |  key_code = \x41 = 'A', modifier_key = {CAPS}
  //     SHIFT+'a'   |  key_code = \x61 = 'a', modifier_key = {CAPS}
  //     CTRL+'a'    |  key_code = \x41, modifier_key = {CTRL,CAPS}
  //   CTRL+ALT+'a'  |  key_code = \x41, modifier_key = {CTRL,ALT,CAPS}
  //   CTRL+SHIFT+'a'|  key_code = \x41, modifier_key = {CTRL,SHIFT,CAPS}
  //
  // However, only in short-cut judgement, we should convert capital characters
  // into lower cases.
  // TODO(peria): Specify exceptions with CAPS, and unify with the above table.

  enum ModifierKey {
    CTRL = 1;
    ALT = 2;
    SHIFT = 4;
    KEY_DOWN = 8;
    KEY_UP = 16;
    LEFT_CTRL = 32;
    LEFT_ALT = 64;
    LEFT_SHIFT = 128;
    RIGHT_CTRL = 256;
    RIGHT_ALT = 512;
    RIGHT_SHIFT = 1024;
    CAPS = 2048;
  }

  // Probable key event, mainly for touch screen.
  // User's input has ambiguity (e.g. the touch position is merginal)
  // so this message expresses the probable event.
  message ProbableKeyEvent {
    // message ID is the same as Input message.
    optional uint32 key_code = 1;
    optional SpecialKey special_key = 3;     // Unprintable key listed above.
    repeated ModifierKey modifier_keys = 4;  // ModifierKeys
    // Sum of probabilities must be lesser or equal than 1.
    // 0<= probability <= 1
    optional double probability = 10;
  }

  // Printable key in UCS4.  If key_code is empty, key_string is used
  // as a raw input.
  optional uint32 key_code = 1;
  optional uint32 modifiers = 2;           // Going to be obsolete.
  optional SpecialKey special_key = 3;     // Unprintable key listed above.
  repeated ModifierKey modifier_keys = 4;  // ModifierKeys

  // String used for preedit.  Kana characters and strings typed from
  // a software keyboard are supposed to be stored here.  If key_code
  // is also set, key_code is treated as the raw input and key_string is
  // treated as the composition input.  For example, to set Kana value,
  // when key_string is "ち", key_code should be 'a' (97).  If key_code
  // is empty, key_string is also treated as the raw input.
  optional string key_string = 5;

  enum InputStyle {
    // Follow the current input mode (default).
    FOLLOW_MODE = 0;
    // Do not transliterate key_string and use it as-is.
    AS_IS = 1;
    // Immediately output key_string on the precomposition mode.
    // Same with AS_IS on the preedit mode.
    DIRECT_INPUT = 2;
  }
  optional InputStyle input_style = 6 [default = FOLLOW_MODE];

  // Input mode
  // For histrical reasons, this field expects a temporary conversion
  // mode rather than comeback input mode.
  optional CompositionMode mode = 7;

  // Probable key events
  // Even if you can fill this field,
  // don't omit Input.key_code and so on
  // because preedit string is composed based on them.
  repeated ProbableKeyEvent probable_key_event = 8;

  // IME on/off mode
  // You can use this field to change the IME on/off mode indirectly without
  // sending SpecialKey:ON or SpecialKey:OFF events.
  // If the internal ImeContext::State is DIRECT and this field is true, the
  // converter will change the state to PRECONPOSITION and then handles this key
  // event.
  // If the internal ImeContext::State is not DIRECT and this field is false,
  // the converter will change the state to DIRECT and then handles this key
  // event.
  // Implementation note: We need both |mode| and |activated| to support
  // indirect IME off, where |mode| should contain the next mode. If this field
  // is not set, the server will act as if indirect on/off was not supported.
  optional bool activated = 9;
}

message GenericStorageEntry {
  enum StorageType {
    SYMBOL_HISTORY = 0;
    EMOTICON_HISTORY = 1;
    EMOJI_HISTORY = 2;
  }
  optional StorageType type = 1;
  optional string key = 2;
  // The type must be bytes instead of string
  // because value might have U+0000 character as a terminator.
  // In this case, characters after the terminator are undefined.
  // Such byte stream cannot be treaed by Java's String class, which
  // is used for PB's string type.
  // Instead, PB's bytes type is converted into ByteString in Java,
  // which can treat C laguage style string described above.
  repeated bytes value = 3;
}

message SessionCommand {
  enum CommandType {
    // Do nothing.
    NONE = 0;

    // Revert the session, this is usually similar to type ESC several times.
    REVERT = 1;
    // Commit the session, this is usually similar to type Enter.
    // SUBMIT session command is accepted in any status.
    // Pre-condition:
    // - Any states of IME are acceptable.
    // Post-condition:
    // - Preedit text becomes empty.
    SUBMIT = 2;
    // Select the specified candidate word by id.  This command is
    // usually used with mouse clicking.
    SELECT_CANDIDATE = 3;

    // Set the focus to the candidate by id.  This is usually used
    // with mouse dragging.  The difference from SELECT_CANDIDATE is
    // that HIGHLIGHT_CANDIDATE does not close the candidate window
    // while SELECT_CANDIDATE closes the candidate window.
    HIGHLIGHT_CANDIDATE = 4;

    // Specify the input mode.  This command should be used with
    // composition_mode.
    SWITCH_INPUT_MODE = 5;

    // Return the current status such as composition mode, preedit method, etc.
    GET_STATUS = 6;

    // This command is typically used for mobile IME's partial conversion,
    // but currently it is on the way. This description is for current spec.
    //
    // This command requires that candidates exist.
    //
    // If there is a focused candidate (Conversion or Prediction state),
    // the candidate matched with the given id in the first segment is
    // submitted, even though the selected segment is not the first segment
    // (Important thing is whether focused candidate exists
    // or not. Focused index itself is ignored).
    // This behavior should be updated because current cursor position and
    // position of focused segment affects nothing.
    // We should fix this non-intuitive behavior. Intuitive behavior might be
    // submitting segments from first one to focused one (inclusive).
    //
    // If no focused candidate (Suggestion, including ZeroQuery suggestion),
    // first (and only) segment's candiadte of which id is equal to id field of
    // Input message is submitted.
    // This behavior should be fixed because current cursor position affects
    // nothing. In future, the characters after the cursor should be kept
    // as preedit.
    //
    // This command's pre- and post- conditions are differenct from
    // SUBMIT command's. Following conditions will be kept after updating
    // the behavior.
    // Pre-condition:
    // - There should be candidate.
    // Post-condition:
    // - No guarantee on preedit text.
    // TODO(yamaguchi): Update corresponding implementation please.
    SUBMIT_CANDIDATE = 7;

    // Perform reverse conversion.
    CONVERT_REVERSE = 8;

    // Perform Undo.
    UNDO = 9;

    // Reset convert history and revert current composition.
    // This is usually used by moving cursor with mouse clicking.
    RESET_CONTEXT = 10;

    // Change cursor position in preedit.
    MOVE_CURSOR = 11;

    // Specify the input field type.
    SWITCH_INPUT_FIELD_TYPE = 12;

    // Client side event information for collecting usage statistics
    USAGE_STATS_EVENT = 13;

    // This command is used in only Android.
    // Works UNDO or rewind HIRAGANA characters based on the state.
    UNDO_OR_REWIND = 14;

    // Expand suggestion candidates.
    // Usual suggestion algorithm is not "rich" but "fast" because suggestion
    // is executed every key event (On the other hand predicition is "rich"
    // because prediction is executed only when a user types TAB key).
    // This command expands suggestion candidate but IME state is
    // kept as is (Note : PredictAndConvert key command does almost the same
    // thing but it changes IME state to prediction).
    EXPAND_SUGGESTION = 15;

    // Obsolete command. Used only in old IBus client.
    reserved 16;
    reserved "SEND_CARET_LOCATION";

    // Obsolete command. Don't simply remove this command for NUM_OF_COMMANDS.
    // TODO(team): Replace this command by useful one.
    reserved 17;
    reserved "SEND_LANGUAGE_BAR_COMMAND";

    // Obsolete command. Don't simply remove this command for NUM_OF_COMMANDS.
    // TODO(team): Replace this command by useful one.
    reserved 18;
    reserved "GET_ASYNC_RESULT";

    // Commit the raw text of the composed string.
    COMMIT_RAW_TEXT = 19;

    // Call ConvertPrevPage session command to show the previous page of
    // candidates.
    CONVERT_PREV_PAGE = 20;

    // Call ConvertNextPage session command to show the next page of
    // candidates.
    CONVERT_NEXT_PAGE = 21;

    // Make sure IME is turned on. Optionally you can also provide new input
    // mode in |composition_mode| (but you must not set DIRECT to it).
    // |composition_mode| is honored even when IME is already turned on.
    TURN_ON_IME = 22;

    // Make sure IME is turned off. Optionally you can also provide new input
    // mode in |composition_mode| (but you must not set DIRECT to it). If IME
    // |composition_mode| is honored even when IME is already turned off.
    TURN_OFF_IME = 23;

    // Delete the candidate specified with |id = 2| from the user history.
    DELETE_CANDIDATE_FROM_HISTORY = 24;

    // Stops key toggling of the composer if its table is a toggle-supported
    // layout (e.g., 12-key toggle flick.)
    STOP_KEY_TOGGLING = 25;
  }
  required CommandType type = 1;

  // Unique number specifying a candidate word.
  optional int32 id = 2;

  // This is used with SWITCH_INPUT_MODE, TURN_ON_IME and TURN_OFF_IME.
  optional CompositionMode composition_mode = 3;

  // Text argument.  This is used by CONVERT_REVERSE at this moment.
  optional string text = 4;

  // New cursor position in preedit. Used with MOVE_CURSOR.
  optional uint32 cursor_position = 5;

  reserved 6;  // Deprecated input_field_type

  // Client side event for collecting usage statistics
  enum UsageStatsEvent {
    INFOLIST_WINDOW_SHOW = 1;
    INFOLIST_WINDOW_HIDE = 2;
    HANDWRITING_OPEN_EVENT = 3;
    HANDWRITING_COMMIT_EVENT = 4;
    CHARACTER_PALETTE_OPEN_EVENT = 5;
    CHARACTER_PALETTE_COMMIT_EVENT = 6;
    SOFTWARE_KEYBOARD_LAYOUT_LANDSCAPE = 7;
    SOFTWARE_KEYBOARD_LAYOUT_PORTRAIT = 8;
    SUBMITTED_CANDIDATE_ROW_0 = 9;
    SUBMITTED_CANDIDATE_ROW_1 = 10;
    SUBMITTED_CANDIDATE_ROW_2 = 11;
    SUBMITTED_CANDIDATE_ROW_3 = 12;
    SUBMITTED_CANDIDATE_ROW_4 = 13;
    SUBMITTED_CANDIDATE_ROW_5 = 14;
    SUBMITTED_CANDIDATE_ROW_6 = 15;
    SUBMITTED_CANDIDATE_ROW_7 = 16;
    SUBMITTED_CANDIDATE_ROW_8 = 17;
    SUBMITTED_CANDIDATE_ROW_9 = 18;
    SUBMITTED_CANDIDATE_ROW_GE10 = 19;
    KEYBOARD_FOLD_EVENT = 20;
    KEYBOARD_EXPAND_EVENT = 21;
    MUSHROOM_SELECTION_DIALOG_OPEN_EVENT = 22;
    reserved 23, 24;  // Deprecated keyboard height stats.
    SOFTWARE_KEYBOARD_LAYOUT_ADJUSTMENT_ENABLED_LANDSCAPE = 25;
    SOFTWARE_KEYBOARD_LAYOUT_ADJUSTMENT_ENABLED_PORTRAIT = 26;
    SOFTWARE_KEYBOARD_LAYOUT_ENGLISH_LANDSCAPE = 27;
    SOFTWARE_KEYBOARD_LAYOUT_ENGLISH_PORTRAIT = 28;
  }
  optional UsageStatsEvent usage_stats_event = 7;
  optional int32 usage_stats_event_int_value = 9;

  reserved 8;  // Deprecated caret_rectangle

  reserved 10;  // Deprecated asynchronous_request_id
}

message Context {
  // Former part of surrounding text.
  optional string preceding_text = 1;

  // Latter part of surrounding text.
  optional string following_text = 2;

  // If this is true, suggestion feature is disabled regardless the
  // congiguration.  If this is false, suggestion feature is followed
  // by the user's configuration.  If you want to omit interim
  // suggestions during the key typing, you might want to use
  // request_suggestion.
  // TODO(komatsu): Delete this field and use experimental_features.
  optional bool suppress_suggestion = 3 [default = false];

  // Input field type.
  // The types are based on the input types defined in HTML5.
  // http://dev.w3.org/html5/spec/Overview.html#attr-input-type
  // Other types are to be added later.
  enum InputFieldType {
    // No restrictions nor special functions. The IME operates as usual.
    NORMAL = 1;

    // Password field. Text is hidden after input.
    // For Android,
    // In order to make the last character visible to the user,
    // the IME must not hold more than 2 characters in preedit.
    PASSWORD = 2;

    // Telephone number
    TEL = 3;

    // Number
    NUMBER = 4;
  }
  // Type of the input field being focused.
  optional InputFieldType input_field_type = 4;

  // An unique revision ID to specify one specific typing session. A client can
  // use arbitrary value for this field. The converter is expected to clear its
  // internal history segments whenever this value is changed. A client should
  // use the same revision ID whenever the converter should keep it internal
  // history segments. In order to avoid unexpected history learnings, a client
  // should update the revision whenever the input focus is changed.
  optional int32 revision = 5 [default = 0];

  // Repeated fields to be used for experimental features.
  repeated string experimental_features = 100;
}

// Clients' capability.
// Users cannot modify this.
// The server has to obey this capability.
message Capability {
  // Bit fields to notify what the client can do.
  enum TextDeletionCapabilityType {
    NO_TEXT_DELETION_CAPABILITY = 0;

    // Can delete preceding text which is adjacent to preedit.
    DELETE_PRECEDING_TEXT = 1;
  }
  optional TextDeletionCapabilityType text_deletion = 1
      [default = NO_TEXT_DELETION_CAPABILITY];
}

// Next ID: 2
// Bundles together some Android experiment flags so that they can be easily
// retrieved throughout the native code.  These flags are generally specific to
// the decoder, and are made available when the decoder is initialized.
message DecoderExperimentParams {
  optional bool enable_simplified_ranking = 1;
}

// Clients' request to the server.
// Users cannot modify this.
// In the future each request may be able to be overwirtten by Config.
// The server does not have to obey this request.
message Request {
  // Enable zero query suggestion.
  optional bool zero_query_suggestion = 1
      [default = false];  // true for android

  // Conversion's candidate includes suggestion, prediction and conversion.
  optional bool mixed_conversion = 2 [default = false];  // true for android

  reserved 3;  // Deprecated combine_all_segments

  enum SpecialRomanjiTable {
    // Do not use special table.
    // Romanji table is selected based on Config.
    DEFAULT_TABLE = 0;

    // Use special table for 12keys (to hiragana).
    TWELVE_KEYS_TO_HIRAGANA = 10;

    // This is a temporary romaji table that is to be used instead of the
    // current 12keys-to-hiragana table.
    // TODO(noriyukit): Replace TWELVE_KEYS_TO_HIRAGANA by this.
    TWELVE_KEYS_TO_HIRAGANA_INTUITIVE = 10000;

    // Use special table for 12keys (to half-width ascii).
    TWELVE_KEYS_TO_HALFWIDTHASCII = 11;

    // Use special table for flick (to hiragana).
    FLICK_TO_HIRAGANA = 13;

    // This is a temporary romaji table that is to be used instead of the
    // current flick-to-hiragana table.
    // TODO(noriyukit): Replace FLICK_TO_HIRAGANA by this.
    FLICK_TO_HIRAGANA_INTUITIVE = 10002;

    // Use special table for flick (to half-width ascii).
    FLICK_TO_HALFWIDTHASCII = 14;

    // Use special table for flick (to alphabet).
    FLICK_TO_HALFWIDTHASCII_IOS = 44;

    // Use special table for flick (to number).
    FLICK_TO_NUMBER = 43;

    // Use special table for both toggle and flick (to hiragana).
    TOGGLE_FLICK_TO_HIRAGANA = 16;

    // This is a temporary romaji table that is to be used instead of the
    // current toggle_flick_hiragana table.
    // TODO(noriyukit): Replace TOGGLE_FLICK_HIRAGANA by this.
    TOGGLE_FLICK_TO_HIRAGANA_INTUITIVE = 10001;

    // Use special table for both toggle and flick (to number).
    TOGGLE_FLICK_TO_NUMBER = 42;

    // Use special table for both toggle and flick (to alphabet).
    TOGGLE_FLICK_TO_HALFWIDTHASCII_IOS = 45;

    // Use special table for both toggle and flick (to half-width ascii).
    TOGGLE_FLICK_TO_HALFWIDTHASCII = 17;

    // Use special table for Qwerty (for Mobile) (to hiragana).
    QWERTY_MOBILE_TO_HIRAGANA = 20;

    // Use special table for Qwerty (for Mobile) (to half-width ascii).
    QWERTY_MOBILE_TO_HALFWIDTHASCII = 22;

    // Use special table for Godan (to hiragana).
    GODAN_TO_HIRAGANA = 30;

    // Use special table for Godan (to half-width ascii).
    GODAN_TO_HALFWIDTHASCII = 31;

    // Use special table for Notouch (to hiragana).
    NOTOUCH_TO_HIRAGANA = 40;

    // Use special table for Notouch (to half-width ascii).
    NOTOUCH_TO_HALFWIDTHASCII = 41;

    // Obsolete items.
    reserved 12, 15, 32, 21, 18;
    reserved "TWELVE_KEYS_TO_NUMBER";
    reserved "GODAN_TO_NUMBER";
    reserved "QWERTY_MOBILE_TO_HIRAGANA_NUMBER";
  }

  // Use special Romanji table.
  optional SpecialRomanjiTable special_romanji_table = 4
      [default = DEFAULT_TABLE];  //  TWELVE_KEYS_TO_HIRAGANA for android.

  enum SpaceOnAlphanumeric {
    // The first input is treated as a space, double input is treated
    // as a conversion.  If a character is input after the first
    // input, the composition will remain.  For example, "ab<space>dc"
    // becomes "ab dc" as a single composition.
    SPACE_OR_CONVERT_KEEPING_COMPOSITION = 0;

    // The first input is treated as a space, double input is treated
    // as a conversion.  If a character is input after the first
    // input, the previous composition will be committed.  For
    // example, "ab<space>dc" results "ab " as a committed string and
    // "dc" as a composition.
    SPACE_OR_CONVERT_COMMITING_COMPOSITION = 1;

    // Commit the composition and a space.
    COMMIT = 2;
  }

  optional SpaceOnAlphanumeric space_on_alphanumeric = 6
      [default = SPACE_OR_CONVERT_KEEPING_COMPOSITION];

  // Keyboard name for touch devices.
  // For example, "TWELVE_KEY_TOGGLE_KANA", "QWERTY_KANA_NUMBER".
  // It is used to analyze touch event usage stats.
  optional string keyboard_name = 7;

  // Enables Composer's input mode auto updating by using surrounding text.
  // For example, when a composition string is "ad", a carret is at the end,
  // and a user selects HIRAGANA mode, if the user moves the carret to between
  // "a" and "d" the mode will be automatically switch to ASCII (temporarily).
  // See details in the Composer::UpdateInputMode.
  optional bool update_input_mode_from_surrounding_text = 8 [default = true];

  // Enables Kana-modifier-insensitive conversion as follows:
  // 1) Voiced/Semi-voiced kana will be hit by non-modified kana.
  //    e.g.) "ば" and "ぱ" will be hit by key "は".
  // 2) Geminate consonant "っ" will be hit by non-modified kana "つ".
  // 3) Palatalized kana will be hit by non-modified kana.
  //    e.g.) "ゃ" will be hit by key "や".
  // Here is an example of the search: "学校" ("がっこう") will be hit
  // by "かつこう".
  optional bool kana_modifier_insensitive_conversion = 9 [default = false];

  // Enables Auto partial suggestion.
  // For Auto partial suggestion, we can see first segment only candidates
  // adding to normal realtime conversion suggestion results.
  // If we commit that candidate, we will show suggestions for remaining part
  // of key.
  //
  // Note: This feature can be enabled only for mobile due to UX design.
  optional bool auto_partial_suggestion = 10 [default = false];

  // Nowadays, four kinds of emoji characters are used in Japan.
  // - Unicode: Unicode based emoji (since Unicode 6.0).
  // - Docomo: Docomo's carrier emoji.
  // - Softbank: Softbank's carrier emoji.
  // - Kddi: Kddi's carrier emoji.
  // Note that especially latter three kinds are used on Mobile phones.
  // So, it is necessary to control what kinds of emoji can be used or not
  // based on client's (or connected application's) information.
  // For example, on Android;
  // - Unicode emoji characters are available only on Android 4.1 or later
  //   only.
  // - JP mobile carriers' emoji characters depend on the devices. Also,
  //   we need to check the text field's attribute for them.
  // The following bit set tells the emoji availability to EmojiRewriter.
  enum EmojiCarrierType {
    UNICODE_EMOJI = 1;
    DOCOMO_EMOJI = 2;
    SOFTBANK_EMOJI = 4;
    KDDI_EMOJI = 8;
  }

  // By default, UNICODE emoji is available.
  optional int32 available_emoji_carrier = 11 [default = 1];

  // For emoji rewriter, it is necessary to control when the rewriter runs
  // based on the clients. The following bit set is sync'ed to
  // RewriterInterface::CapabilityType (see rewriter_interface.h, too),
  // so that clients can fill the value.
  enum RewriterCapability {
    NOT_AVAILABLE = 0;
    CONVERSION = 1;
    PREDICTION = 2;
    SUGGESTION = 4;
    ALL = 7;  // CONVERSION | PREDICTION | SUGGESTION.
  }

  // By default, Emoji rewriter works on conversion mode only.
  optional int32 emoji_rewriter_capability = 12 [default = 1];

  // Controls the behavior when a user types the left/right key at the edge
  // of the preedit string (in more precise, the left key at the beginning
  // of the preedit string, or the right key at the end).
  enum CrossingEdgeBehavior {
    // This is the default behavior. The cursor movement at the edge
    // will make nothing, i.e., keeping the current cursor position (at the
    // edge), consume the key event.
    DO_NOTHING = 0;

    // This is the behavior, especially designed for alphabet keyboards on
    // mobile devices. Assuming the following text:
    //   XXXXabcde|YYYYY
    // where XXXX is preceding text, abcde is composing text, YYYYY is
    // following text and '|' is the caret, when a user sends "RIGHT"
    // cursor key, we'd like to commit the abcde and move the caret to right.
    // So the user will get:
    //   XXXXabcdeY|YYYY
    // Here, what we need is commiting the "abcde" with the appropriate
    // caret position. (Note that we need to handle the left cursor key, too).
    // Also, we should *NOT* consume the key, so that the key event will be
    // handled appropriately by the target application.
    COMMIT_WITHOUT_CONSUMING = 1;
  }
  optional CrossingEdgeBehavior crossing_edge_behavior = 13
      [default = DO_NOTHING];

  // Controls the behavior of language aware input.  Language aware input
  // guesses the actual language regardless the input mode.  For example,
  // if user type "てｓｔ" it will be treated as "test".
  enum LanguageAwareInputBehavior {
    // Performs the default behavior considering the platform and channel.
    DEFAULT_LANGUAGE_AWARE_BEHAVIOR = 0;

    // Does not perform this functionarity.
    NO_LANGUAGE_AWARE_INPUT = 1;

    // Adds a language aware candidate to the suggestion.
    LANGUAGE_AWARE_SUGGESTION = 2;
  }
  optional LanguageAwareInputBehavior language_aware_input = 14
      [default = DEFAULT_LANGUAGE_AWARE_BEHAVIOR];

  // Page size of the candidate list.
  optional int32 candidate_page_size = 15 [default = 9];

  // The maximum limit of the candidates size.
  // If not set, converter doesn't limit the size.
  // NOTE: Each segment has at least one candidate and meta candidates even if
  //       this value is set to 0.
  optional int32 candidates_size_limit = 16;

  // Experimentally changes the decoder's behavior.
  // This flag is usually populated through the phenotype flags.
  optional DecoderExperimentParams decoder_experiment_params = 17;
}

// Note there is another ApplicationInfo inside RendererCommand.
// Since Input is not using nested message, define ApplicationInfo here.
message ApplicationInfo {
  optional uint32 process_id = 1;
  optional uint32 thread_id = 2;
  // The time difference between local time and UTC time in seconds.
  // This field is not supported except for NaCl.
  // We use this field in NaCl Mozc because we can't know the local timezone in
  // NaCl environment.
  optional int32 timezone_offset = 3;
}

message Input {
  enum CommandType {
    NONE = 0;
    CREATE_SESSION = 1;
    DELETE_SESSION = 2;
    SEND_KEY = 3;

    // Check only if the key event will be consumed.  This command is
    // for TSF on Windows.  You do not need to use this command, if it
    // is not necessary.
    TEST_SEND_KEY = 4;

    // Evaluate the command specified by SessionCommand.  The output
    // format should be the same with an output of a SEND_KEY command.
    SEND_COMMAND = 5;

    // Config accessors.
    // There are three configurations.
    // Stored config, Imposed config, One-shot config.
    // Stored config : Set by SET_CONFIG command.
    // Its lifetime is permanent (stored into a storage).
    // GET_CONFIG returns stored config.
    // Imposed config : Set by SET_IMPOSED_CONFIG. Its lifetime is the
    // same as the process (*not* stored into a storage as opposed to Stored
    // config).
    // Imposed config is prioritized over Stored config.
    // Only the values explicitly set are effective and override ones in Stored
    // config. In typical usage, most fields are not set.
    // GET_CONFIG's result is *not* affected by imposed config
    // (stored config returns).
    // One-shot config : Set by each key events.
    // It is effective while the key event is processed.
    // This is prioritized over Imposed config.
    // Like as Imposed config, some fields can be omitted.
    // TODO(matsuzakit): Rename (GET|SET)_CONFIG to (GET|SET)_STORED_CONFIG
    GET_CONFIG = 6;
    SET_CONFIG = 7;
    SET_IMPOSED_CONFIG = 22;

    // Set client's request
    SET_REQUEST = 17;

    // sync dictionary/history data to local file
    SYNC_DATA = 8;

    // shutdowon server safely
    SHUTDOWN = 9;

    // reload mutable data (like config, user-dic, history)
    RELOAD = 10;

    // clear user history data
    CLEAR_USER_HISTORY = 11;

    // clear user prediction data
    CLEAR_USER_PREDICTION = 12;

    // clear unused prediction
    CLEAR_UNUSED_USER_PREDICTION = 16;

    // clean up sessions
    // shutdwon if session is empty and
    // mozc_server is launched with timeout mode
    CLEANUP = 13;

    // no operation
    // can be used for pinging the server
    NO_OPERATION = 14;

    // Sync feature is deprecated since 1.13 dev.
    reserved 18, 23, 24;
    reserved "START_CLOUD_SYNC";
    reserved "GET_CLOUD_SYNC_STATUS";
    reserved "ADD_AUTH_CODE";

    reserved 20, 21, 25;
    reserved "INSERT_TO_STORAGE";
    reserved "READ_ALL_FROM_STORAGE";
    reserved "CLEAR_STORAGE";

    // Send a command for user dictionary session.
    SEND_USER_DICTIONARY_COMMAND = 26;

    // Send an engine_reload_request (ID: 15) to reload the engine.
    SEND_ENGINE_RELOAD_REQUEST = 27;

    // Number of commands.
    // When new command is added, the command should use below number
    // and NUM_OF_COMMANDS should be incremented.
    //
    // Note: This enum lack the value for 15 and 19 and it may cause a crash.
    //       Please reuse these value if you can.
    //       15 have never been used before, and 19 was used to clear synced
    //       data on dev channel.
    NUM_OF_COMMANDS = 28;
  }
  required CommandType type = 1;

  // Session ID created by CREATE_SESSION.
  optional uint64 id = 2 [jstype = JS_STRING];

  // Key combinations used for SEND_KEY or TEST_SEND_KEY.
  optional KeyEvent key = 3;

  // Command sent to the session layer used with SEND_COMMAND.
  optional SessionCommand command = 4;

  // Input config
  optional mozc.config.Config config = 5;

  // Context data
  optional Context context = 6;

  // Client capability
  optional Capability capability = 7;

  // Application information, like process id.
  // Server may be able to change the behavior by seeing the
  // the program name.
  optional ApplicationInfo application_info = 8;

  // Client request
  optional Request request = 9;

  // If the command is INSERT_TO_STORAGE, all the fields must be filled.
  // If READ_ALL_FROM_STORAGE, key and value fields are ignored.
  optional GenericStorageEntry storage_entry = 10;

  reserved 11;  // Deprecated auth_code

  enum TouchAction {
    TOUCH_DOWN = 1;
    TOUCH_MOVE = 2;
    TOUCH_UP = 3;
  }
  message TouchPosition {
    optional TouchAction action = 1;
    // x, y potision: keyboad left-top is (0, 0), right-bottom is (1, 1).
    optional float x = 2;
    optional float y = 3;
    // timestamp (in ms) is set to zero when the touch event starts.
    optional int64 timestamp = 4;
  }
  // TouchEvent contains source_id and stroke.
  // Touch_events contain all key touch event.
  // Statistical information are collected for each source_id
  // by SessionUsageObserver.
  message TouchEvent {
    // source_id specifies the user action such as "X button pressed".
    // It must be unique within the same keyboard_name,
    // which is set in Request message.
    optional uint32 source_id = 1;
    repeated TouchPosition stroke = 2;
  }
  repeated TouchEvent touch_events = 12;

  optional mozc.user_dictionary.UserDictionaryCommand user_dictionary_command =
      13;

  // A flag to control if the server should return suggest-results or not.
  // If this is set to false, regardless of other configurations,
  // the server won't return suggestion results.
  // This is set to true by default.
  // Note that even if this flag is set to false, when a suggestion is shown
  // in the previous phase, it is possible from the client to submit it.
  // This works only for suggestions for the key insersion, but not for
  // others commands, such as predictions or conversions.
  // This flag is used for the performance improvement in terms of the
  // latency.  If you want to suppress the suggestions for the UX improment,
  // you may want to use suppress_suggestion in the Context message.
  optional bool request_suggestion = 14 [default = true];

  optional mozc.EngineReloadRequest engine_reload_request = 15;
}

// Result contains data to be submitted to the host application by the
// ime client.
message Result {
  enum ResultType {
    NONE = 0;
    STRING = 1;
  }
  required ResultType type = 1;
  // The result of conversion.
  required string value = 2;

  // Source of the value.  It is almost always the reading of the value.
  optional string key = 3;

  // The caret position after the result submission.
  // "0" means the end of the result, and a positive value means moving forward
  // and a negative value backward.
  // e.g.) "-s", where s is the length of value, means the caret position
  // after the committing should be the beginning of the committed value.
  optional int32 cursor_offset = 4 [default = 0];
}

// Preedit represents a composition data, which is rendered on the
// host application by the ime client.  On Japanese IME, the both
// Preedit and Conversion statuses are represented by this message.
message Preedit {
  required uint32 cursor = 1;
  // The string data of Preedit is separated into Segment messages
  // presenting the ime server's status.  On Preedit status of
  // Japanese IME, there are up to three segments; left side chars of
  // cursor, forcused char, right side chars of cursor.  On Conversion
  // status of Japanese IME, the messages literally represent the
  // segments of the conversion.
  repeated group Segment = 2 {
    enum Annotation {
      NONE = 0;
      UNDERLINE = 1;
      HIGHLIGHT = 2;
    }
    required Annotation annotation = 3;
    required string value = 4;

    // The length of value in characters.  This is NOT a number in
    // bytes or logical character units.  So, the length of "abc" and
    // "あいう" should be 3, "ヴ" should be 1 and "ｳﾞ" and "う゛"
    // should be 2.
    required uint32 value_length = 5;

    // Source of the value.  It is almost always the reading of the value.
    optional string key = 6;
  }

  // The position of the first segment whose annotation is 'HIGHLIGHT'. Not set
  // if there are no such segments.
  optional uint32 highlighted_position = 3;

  // This flag is set to true if the character at the cursor position
  // is in toggleable state.  For example, when the table is
  // TOGGLE_FLICK_TO_HIRAGANA and key event '1' is received
  // repeatedly, the preedit toggles like あ -> い -> う -> ....  This
  // flag is true during this cycle.  This state is reset when user
  // types another key or SessionCommand::STOP_KEY_TOGGLING is
  // received.
  optional bool is_toggleable = 4 [default = false];
}

message Status {
  // Whether IME is ON or OFF
  optional bool activated = 1;

  // Visible composition mode when IME is activated. This mode may come from a
  // temporary composition mode. See |comeback_mode|.
  // TODO(yukawa): Rename this field to "visible_mode".
  optional CompositionMode mode = 2;

  // True composition mode that is suitable for system global and permanent
  // composition mode. When a temporary composition mode exists,
  // |comeback_mode| can be different from |mode|.
  // TODO(yukawa): Use more appropriate name.
  optional CompositionMode comeback_mode = 3;
}

// This message contains which characters are to be deleted by client.
// E.g. if current composition and surrounding text are
//     "この感じは漢字は"
//                ^^^^^^
// and we send DeletionRange with offset == -3 and length == 3, then they will
// be rendered like:
//     "この漢字は"
//          ^^^^^^
message DeletionRange {
  // Offset of start of range.
  optional int32 offset = 1;

  // Length of the range.
  optional int32 length = 2;
}

message Output {
  optional uint64 id = 1 [jstype = JS_STRING];

  // This variable is going to be obsolete.
  optional CompositionMode mode = 2;

  optional bool consumed = 3;
  optional Result result = 4;
  optional Preedit preedit = 5;
  optional Candidates candidates = 6;
  optional KeyEvent key = 7;

  // when URL is non empty, UI can open the page with a browser,
  // after finishing the all rendering part.
  // We are using this feature for bug-report system.
  optional string url = 8;

  // Output config
  optional mozc.config.Config config = 9;

  // PreeditMethod: this is the default input mode of the session.
  // If the user's config is "kana-input", it returns KANA.  Only
  // CreateSession response will have this field.
  enum PreeditMethod {
    ASCII = 0;
    KANA = 1;
  }
  optional PreeditMethod preedit_method = 10 [default = ASCII];

  // ErrorCode:
  // if SessionHandler::EvalCommand() returns false,
  // return output with error_code = SESSION_FAILURE;
  enum ErrorCode {
    SESSION_SUCCESS = 0;
    SESSION_FAILURE = 1;
  }
  optional ErrorCode error_code = 11 [default = SESSION_SUCCESS];

  reserved 12;  // Deprecated elapsed_time

  // The current IME status.
  optional Status status = 13;

  // All flatten candidate words stored in 1D array.  This value is
  // filled only when the content is changed.
  optional CandidateList all_candidate_words = 14;

  reserved 15;  // Deprecated performed_command

  // Range of characters to be deleted by client.
  optional DeletionRange deletion_range = 16;

  // if launch_tool_mode is set, MozcTool is supposed to be launched
  // by client.
  enum ToolMode {
    NO_TOOL = 0;  // no need to launch tool
    CONFIG_DIALOG = 1;
    DICTIONARY_TOOL = 2;
    WORD_REGISTER_DIALOG = 3;
  }
  optional ToolMode launch_tool_mode = 17 [default = NO_TOOL];

  // Callback request to the client.
  message Callback {
    // Callback command to be sent from the client to the server.  The
    // optional values such as id and composition_mode can be modified
    // or added by the client.
    optional SessionCommand session_command = 1;

    // Callback command should be sent after this delay.
    optional uint32 delay_millisec = 2;
  }
  optional Callback callback = 18;

  // Used when the command is READ_ALL_FROM_STORAGE.
  optional GenericStorageEntry storage_entry = 19;

  reserved 20;  // Deprecated cloud_sync_status

  optional mozc.user_dictionary.UserDictionaryCommandStatus
      user_dictionary_command_status = 21;

  optional mozc.EngineReloadResponse engine_reload_response = 22;
}

message Command {
  required Input input = 1;
  required Output output = 2;
}

message CommandList {
  // This message is used for unittest.
  repeated Command commands = 1;
}
