Merge "Make DicTraverseSession having suggest options."
diff --git a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
index 0e9c292..03b3c60 100644
--- a/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
+++ b/native/jni/com_android_inputmethod_latin_BinaryDictionary.cpp
@@ -162,7 +162,7 @@
     const jsize numberOfOptions = env->GetArrayLength(suggestOptions);
     int options[numberOfOptions];
     env->GetIntArrayRegion(suggestOptions, 0, numberOfOptions, options);
-    SuggestOptions givenOptions(options, numberOfOptions);
+    SuggestOptions givenSuggestOptions(options, numberOfOptions);
 
     // Output values
     /* By the way, let's check the output array length here to make sure */
@@ -190,12 +190,11 @@
     memset(outputTypes, 0, sizeof(outputTypes));
 
     int count;
-    if (givenOptions.isGesture() || inputSize > 0) {
+    if (givenSuggestOptions.isGesture() || inputSize > 0) {
         count = dictionary->getSuggestions(pInfo, traverseSession, xCoordinates, yCoordinates,
                 times, pointerIds, inputCodePoints, inputSize, prevWordCodePoints,
-                prevWordCodePointsLength, commitPoint, givenOptions.isGesture(),
-                givenOptions.useFullEditDistance(), outputCodePoints, scores,
-                spaceIndices, outputTypes);
+                prevWordCodePointsLength, commitPoint, &givenSuggestOptions, outputCodePoints,
+                scores, spaceIndices, outputTypes);
     } else {
         count = dictionary->getBigrams(prevWordCodePoints, prevWordCodePointsLength,
                 inputCodePoints, inputSize, outputCodePoints, scores, outputTypes);
diff --git a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
index dfe3b09..08124ff 100644
--- a/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
+++ b/native/jni/com_android_inputmethod_latin_DicTraverseSession.cpp
@@ -34,12 +34,14 @@
     void *ts = reinterpret_cast<void *>(traverseSession);
     Dictionary *dict = reinterpret_cast<Dictionary *>(dictionary);
     if (!previousWord) {
-        DicTraverseWrapper::initDicTraverseSession(ts, dict, 0, 0);
+        DicTraverseWrapper::initDicTraverseSession(
+                ts, dict, 0 /* prevWord */, 0 /* prevWordLength*/, 0 /* suggestOptions */);
         return;
     }
     int prevWord[previousWordLength];
     env->GetIntArrayRegion(previousWord, 0, previousWordLength, prevWord);
-    DicTraverseWrapper::initDicTraverseSession(ts, dict, prevWord, previousWordLength);
+    DicTraverseWrapper::initDicTraverseSession(
+            ts, dict, prevWord, previousWordLength, 0 /* suggestOptions */);
 }
 
 static void latinime_releaseDicTraverseSession(JNIEnv *env, jclass clazz, jlong traverseSession) {
diff --git a/native/jni/src/dic_traverse_wrapper.cpp b/native/jni/src/dic_traverse_wrapper.cpp
index 88ca9fa..ec8c62d 100644
--- a/native/jni/src/dic_traverse_wrapper.cpp
+++ b/native/jni/src/dic_traverse_wrapper.cpp
@@ -22,5 +22,5 @@
 void *(*DicTraverseWrapper::sDicTraverseSessionFactoryMethod)(JNIEnv *, jstring) = 0;
 void (*DicTraverseWrapper::sDicTraverseSessionReleaseMethod)(void *) = 0;
 void (*DicTraverseWrapper::sDicTraverseSessionInitMethod)(
-        void *, const Dictionary *const, const int *, const int) = 0;
+        void *, const Dictionary *const, const int *, const int, const SuggestOptions *const) = 0;
 } // namespace latinime
diff --git a/native/jni/src/dic_traverse_wrapper.h b/native/jni/src/dic_traverse_wrapper.h
index 1108a45..43b4c9a 100644
--- a/native/jni/src/dic_traverse_wrapper.h
+++ b/native/jni/src/dic_traverse_wrapper.h
@@ -22,6 +22,7 @@
 
 namespace latinime {
 class Dictionary;
+class SuggestOptions;
 // TODO: Remove
 class DicTraverseWrapper {
  public:
@@ -32,9 +33,11 @@
         return 0;
     }
     static void initDicTraverseSession(void *traverseSession, const Dictionary *const dictionary,
-            const int *prevWord, const int prevWordLength) {
+            const int *prevWord, const int prevWordLength,
+            const SuggestOptions *const suggestOptions) {
         if (sDicTraverseSessionInitMethod) {
-            sDicTraverseSessionInitMethod(traverseSession, dictionary, prevWord, prevWordLength);
+            sDicTraverseSessionInitMethod(
+                    traverseSession, dictionary, prevWord, prevWordLength, suggestOptions);
         }
     }
     static void releaseDicTraverseSession(void *traverseSession) {
@@ -46,7 +49,8 @@
         sDicTraverseSessionFactoryMethod = factoryMethod;
     }
     static void setTraverseSessionInitMethod(
-            void (*initMethod)(void *, const Dictionary *const, const int *, const int)) {
+            void (*initMethod)(void *, const Dictionary *const, const int *, const int,
+                    const SuggestOptions *const)) {
         sDicTraverseSessionInitMethod = initMethod;
     }
     static void setTraverseSessionReleaseMethod(void (*releaseMethod)(void *)) {
@@ -57,7 +61,7 @@
     DISALLOW_IMPLICIT_CONSTRUCTORS(DicTraverseWrapper);
     static void *(*sDicTraverseSessionFactoryMethod)(JNIEnv *, jstring);
     static void (*sDicTraverseSessionInitMethod)(
-            void *, const Dictionary *const, const int *, const int);
+            void *, const Dictionary *const, const int *, const int, const SuggestOptions *const);
     static void (*sDicTraverseSessionReleaseMethod)(void *);
 };
 } // namespace latinime
diff --git a/native/jni/src/dictionary.cpp b/native/jni/src/dictionary.cpp
index dadb2ba..d9ed0fe 100644
--- a/native/jni/src/dictionary.cpp
+++ b/native/jni/src/dictionary.cpp
@@ -25,6 +25,7 @@
 #include "binary_format.h"
 #include "defines.h"
 #include "dic_traverse_wrapper.h"
+#include "suggest_options.h"
 #include "suggest/core/suggest.h"
 #include "suggest/policyimpl/gesture/gesture_suggest_policy_factory.h"
 #include "suggest/policyimpl/typing/typing_suggest_policy_factory.h"
@@ -53,13 +54,13 @@
 
 int Dictionary::getSuggestions(ProximityInfo *proximityInfo, void *traverseSession,
         int *xcoordinates, int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints,
-        int inputSize, int *prevWordCodePoints, int prevWordLength, int commitPoint, bool isGesture,
-        bool useFullEditDistance, int *outWords, int *frequencies, int *spaceIndices,
-        int *outputTypes) const {
+        int inputSize, int *prevWordCodePoints, int prevWordLength, int commitPoint,
+        const SuggestOptions *const suggestOptions, int *outWords, int *frequencies,
+        int *spaceIndices, int *outputTypes) const {
     int result = 0;
-    if (isGesture) {
+    if (suggestOptions->isGesture()) {
         DicTraverseWrapper::initDicTraverseSession(
-                traverseSession, this, prevWordCodePoints, prevWordLength);
+                traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
         result = mGestureSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
                 ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint, outWords,
                 frequencies, spaceIndices, outputTypes);
@@ -70,7 +71,7 @@
     } else {
         if (USE_SUGGEST_INTERFACE_FOR_TYPING) {
             DicTraverseWrapper::initDicTraverseSession(
-                    traverseSession, this, prevWordCodePoints, prevWordLength);
+                    traverseSession, this, prevWordCodePoints, prevWordLength, suggestOptions);
             result = mTypingSuggest->getSuggestions(proximityInfo, traverseSession, xcoordinates,
                     ycoordinates, times, pointerIds, inputCodePoints, inputSize, commitPoint,
                     outWords, frequencies, spaceIndices, outputTypes);
@@ -84,8 +85,8 @@
             mBigramDictionary->fillBigramAddressToProbabilityMapAndFilter(prevWordCodePoints,
                     prevWordLength, &bigramMap, bigramFilter);
             result = mUnigramDictionary->getSuggestions(proximityInfo, xcoordinates, ycoordinates,
-                    inputCodePoints, inputSize, &bigramMap, bigramFilter, useFullEditDistance,
-                    outWords, frequencies, outputTypes);
+                    inputCodePoints, inputSize, &bigramMap, bigramFilter,
+                    suggestOptions->useFullEditDistance(), outWords, frequencies, outputTypes);
             return result;
         }
     }
diff --git a/native/jni/src/dictionary.h b/native/jni/src/dictionary.h
index edec83f..e6861a3 100644
--- a/native/jni/src/dictionary.h
+++ b/native/jni/src/dictionary.h
@@ -26,6 +26,7 @@
 class BigramDictionary;
 class ProximityInfo;
 class SuggestInterface;
+class SuggestOptions;
 class UnigramDictionary;
 
 class Dictionary {
@@ -54,9 +55,9 @@
 
     int getSuggestions(ProximityInfo *proximityInfo, void *traverseSession, int *xcoordinates,
             int *ycoordinates, int *times, int *pointerIds, int *inputCodePoints, int inputSize,
-            int *prevWordCodePoints, int prevWordLength, int commitPoint, bool isGesture,
-            bool useFullEditDistance, int *outWords, int *frequencies, int *spaceIndices,
-            int *outputTypes) const;
+            int *prevWordCodePoints, int prevWordLength, int commitPoint,
+            const SuggestOptions *const suggestOptions, int *outWords, int *frequencies,
+            int *spaceIndices, int *outputTypes) const;
 
     int getBigrams(const int *word, int length, int *inputCodePoints, int inputSize, int *outWords,
             int *frequencies, int *outputTypes) const;
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.cpp b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
index 6408f01..f9f1c09 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.cpp
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.cpp
@@ -34,10 +34,11 @@
 
 // TODO: Pass "DicTraverseSession *traverseSession" when the source code structure settles down.
 static void initSessionInstance(void *traverseSession, const Dictionary *const dictionary,
-        const int *prevWord, const int prevWordLength) {
+        const int *prevWord, const int prevWordLength,
+        const SuggestOptions *const suggestOptions) {
     if (traverseSession) {
         DicTraverseSession *tSession = static_cast<DicTraverseSession *>(traverseSession);
-        tSession->init(dictionary, prevWord, prevWordLength);
+        tSession->init(dictionary, prevWord, prevWordLength, suggestOptions);
     }
 }
 
@@ -62,10 +63,11 @@
 static TraverseSessionFactoryRegisterer traverseSessionFactoryRegisterer;
 
 void DicTraverseSession::init(const Dictionary *const dictionary, const int *prevWord,
-        int prevWordLength) {
+        int prevWordLength, const SuggestOptions *const suggestOptions) {
     mDictionary = dictionary;
     mMultiWordCostMultiplier = BinaryFormat::getMultiWordCostMultiplier(mDictionary->getDict(),
             mDictionary->getDictSize());
+    mSuggestOptions = suggestOptions;
     if (!prevWord) {
         mPrevWordPos = NOT_VALID_WORD;
         return;
diff --git a/native/jni/src/suggest/core/session/dic_traverse_session.h b/native/jni/src/suggest/core/session/dic_traverse_session.h
index d88be5b..5aaad03 100644
--- a/native/jni/src/suggest/core/session/dic_traverse_session.h
+++ b/native/jni/src/suggest/core/session/dic_traverse_session.h
@@ -30,12 +30,13 @@
 
 class Dictionary;
 class ProximityInfo;
+class SuggestOptions;
 
 class DicTraverseSession {
  public:
     AK_FORCE_INLINE DicTraverseSession(JNIEnv *env, jstring localeStr)
             : mPrevWordPos(NOT_VALID_WORD), mProximityInfo(0),
-              mDictionary(0), mDicNodesCache(), mMultiBigramMap(),
+              mDictionary(0), mSuggestOptions(0), mDicNodesCache(), mMultiBigramMap(),
               mInputSize(0), mPartiallyCommited(false), mMaxPointerCount(1),
               mMultiWordCostMultiplier(1.0f) {
         // NOTE: mProximityInfoStates is an array of instances.
@@ -45,7 +46,8 @@
     // Non virtual inline destructor -- never inherit this class
     AK_FORCE_INLINE ~DicTraverseSession() {}
 
-    void init(const Dictionary *dictionary, const int *prevWord, int prevWordLength);
+    void init(const Dictionary *dictionary, const int *prevWord, int prevWordLength,
+            const SuggestOptions *const suggestOptions);
     // TODO: Remove and merge into init
     void setupForGetSuggestions(const ProximityInfo *pInfo, const int *inputCodePoints,
             const int inputSize, const int *const inputXs, const int *const inputYs,
@@ -61,6 +63,7 @@
     // getters and setters
     //--------------------
     const ProximityInfo *getProximityInfo() const { return mProximityInfo; }
+    const SuggestOptions *getSuggestOptions() const { return mSuggestOptions; }
     int getPrevWordPos() const { return mPrevWordPos; }
     // TODO: REMOVE
     void setPrevWordPos(int pos) { mPrevWordPos = pos; }
@@ -167,6 +170,7 @@
     int mPrevWordPos;
     const ProximityInfo *mProximityInfo;
     const Dictionary *mDictionary;
+    const SuggestOptions *mSuggestOptions;
 
     DicNodesCache mDicNodesCache;
     // Temporary cache for bigram frequencies
diff --git a/native/jni/src/suggest_options.h b/native/jni/src/suggest_options.h
index 1bed47c..e9d7bc8 100644
--- a/native/jni/src/suggest_options.h
+++ b/native/jni/src/suggest_options.h
@@ -23,6 +23,9 @@
 
 class SuggestOptions{
  public:
+    SuggestOptions(const int *const options, const int length)
+            : mOptions(options), mLength(length) {}
+
     AK_FORCE_INLINE bool isGesture() const {
         return getBoolOption(IS_GESTURE);
     }
@@ -31,14 +34,18 @@
         return getBoolOption(USE_FULL_EDIT_DISTANCE);
     }
 
-    SuggestOptions(const int *const options, const int length)
-            : mOptions(options), mLength(length) {}
+    AK_FORCE_INLINE bool getAdditionalFeaturesBoolOption(const int key) const {
+        return getBoolOption(key + ADDITIONAL_FEATURES_OPTIONS);
+    }
 
  private:
     // Need to update com.android.inputmethod.latin.NativeSuggestOptions when you add, remove or
     // reorder options.
     static const int IS_GESTURE = 0;
     static const int USE_FULL_EDIT_DISTANCE = 1;
+    // Additional features options are stored after the other options and used as setting values of
+    // experimental features.
+    static const int ADDITIONAL_FEATURES_OPTIONS = 2;
 
     const int *const mOptions;
     const int mLength;