Skip to content

Commit

Permalink
Create engine::SpellCheckerInterface to reduce direct dependencies to…
Browse files Browse the repository at this point in the history
… SpellCheckerService.

PiperOrigin-RevId: 601951764
  • Loading branch information
hiroyuki-komatsu committed Jan 27, 2024
1 parent 32eb635 commit 492e690
Show file tree
Hide file tree
Showing 20 changed files with 249 additions and 73 deletions.
3 changes: 2 additions & 1 deletion src/composer/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ mozc_cc_library(
"//composer/internal:transliterators",
"//config:character_form_manager",
"//config:config_handler",
"//engine:spellchecker_interface",
"//protocol:commands_cc_proto",
"//protocol:config_cc_proto",
"//spelling:spellchecker_service_interface",
"//testing:gunit_prod",
"//transliteration",
"@com_google_absl//absl/hash",
Expand All @@ -90,6 +90,7 @@ mozc_cc_test(
"//config:config_handler",
"//converter:segments",
"//data_manager/testing:mock_data_manager",
"//engine:spellchecker_interface",
"//protocol:commands_cc_proto",
"//protocol:config_cc_proto",
"//testing:gunit_main",
Expand Down
15 changes: 10 additions & 5 deletions src/composer/composer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
#include <utility>
#include <vector>

#include "spelling/spellchecker_service_interface.h"
#include "absl/hash/hash.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
Expand All @@ -63,6 +62,7 @@
#include "composer/table.h"
#include "config/character_form_manager.h"
#include "config/config_handler.h"
#include "engine/spellchecker_interface.h"
#include "protocol/commands.pb.h"
#include "protocol/config.pb.h"
#include "transliteration/transliteration.h"
Expand Down Expand Up @@ -304,9 +304,9 @@ void Composer::SetRequest(const commands::Request *request) {
request_ = request;
}

void Composer::SetSpellCheckerService(
const spelling::SpellCheckerServiceInterface *spellchecker_service) {
spellchecker_service_ = spellchecker_service;
void Composer::SetSpellchecker(
const engine::SpellcheckerInterface *spellchecker) {
spellchecker_ = spellchecker;
}

void Composer::SetConfig(const config::Config *config) { config_ = config; }
Expand Down Expand Up @@ -886,8 +886,13 @@ void Composer::GetQueriesForPrediction(std::string *base,

std::optional<std::vector<TypeCorrectedQuery>>
Composer::GetTypeCorrectedQueries(absl::string_view context) const {
if (spellchecker_ == nullptr) {
return std::nullopt;
}

return std::nullopt;
std::string asis;
composition_.GetStringWithTrimMode(ASIS, &asis);
return spellchecker_->CheckCompositionSpelling(asis, context, *request_);
}

size_t Composer::GetLength() const { return composition_.GetLength(); }
Expand Down
15 changes: 5 additions & 10 deletions src/composer/composer.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,14 @@
#include <string>
#include <vector>

#include "spelling/spellchecker_service_interface.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
#include "composer/internal/composition.h"
#include "composer/internal/composition_input.h"
#include "composer/internal/transliterators.h"
#include "composer/query.h"
#include "composer/table.h"
#include "engine/spellchecker_interface.h"
#include "protocol/commands.pb.h"
#include "protocol/config.pb.h"
#include "testing/gunit_prod.h" // for FRIEND_TEST()
Expand Down Expand Up @@ -92,8 +92,7 @@ class Composer final {

void SetRequest(const commands::Request *request);
void SetConfig(const config::Config *config);
void SetSpellCheckerService(
const spelling::SpellCheckerServiceInterface *spellchecker_service);
void SetSpellchecker(const engine::SpellcheckerInterface *spellchecker);

void SetInputMode(transliteration::TransliterationType mode);
void SetTemporaryInputMode(transliteration::TransliterationType mode);
Expand Down Expand Up @@ -265,10 +264,6 @@ class Composer final {
int timeout_threshold_msec() const;
void set_timeout_threshold_msec(int threshold_msec);

const spelling::SpellCheckerServiceInterface *spellchecker_service() const {
return spellchecker_service_;
}

private:
FRIEND_TEST(ComposerTest, ApplyTemporaryInputMode);

Expand Down Expand Up @@ -322,10 +317,10 @@ class Composer final {
// be true. When "b" or "c" is typed, the value should be false.
bool is_new_input_;

// Spellchecker service. used for composition spellchecking.
// Spellchecker is used for composition spellchecking.
// Composer doesn't have the ownership of spellchecker_service_,
// SessionHandler owns this this instance. (usually a singleton object).
const spelling::SpellCheckerServiceInterface *spellchecker_service_ = nullptr;
// SessionHandler owns this instance. (usually a singleton object).
const engine::SpellcheckerInterface *spellchecker_ = nullptr;

// Example:
// {{"かん字", 0.99}, {"かlv字", 0.01}}
Expand Down
39 changes: 37 additions & 2 deletions src/composer/composer_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include "config/config_handler.h"
#include "converter/segments.h"
#include "data_manager/testing/mock_data_manager.h"
#include "engine/spellchecker_interface.h"
#include "protocol/commands.pb.h"
#include "protocol/config.pb.h"
#include "testing/gmock.h"
Expand Down Expand Up @@ -3382,16 +3383,50 @@ TEST_F(ComposerTest, NBforeN_WithHalfWidth) {
EXPECT_EQ(prediction, "あな");
}

TEST_F(ComposerTest, SpellCheckerServiceTest) {
TEST_F(ComposerTest, SpellcheckerTest) {
table_->AddRule("a", "", "");
table_->AddRule("i", "", "");
table_->AddRule("u", "", "");
composer_->InsertCharacter("aiu");

const auto preedit = GetPreedit(composer_.get());
composer_->SetSpellCheckerService(nullptr);
composer_->SetSpellchecker(nullptr);
EXPECT_EQ(composer_->GetTypeCorrectedQueries("context"), std::nullopt);

class MockSpellchecker : public engine::SpellcheckerInterface {
public:
MOCK_METHOD(commands::CheckSpellingResponse, CheckSpelling,
(const commands::CheckSpellingRequest &), (const, override));
MOCK_METHOD(std::optional<std::vector<TypeCorrectedQuery>>,
CheckCompositionSpelling,
(absl::string_view, absl::string_view,
const commands::Request &),
(const, override));
MOCK_METHOD(void, MaybeApplyHomonymCorrection, (Segments *),
(const, override));
};

{
auto mock = std::make_unique<MockSpellchecker>();
EXPECT_CALL(*mock, CheckCompositionSpelling(preedit, "context", _))
.WillOnce(Return(std::nullopt));
composer_->SetSpellchecker(mock.get());
EXPECT_EQ(composer_->GetTypeCorrectedQueries("context"), std::nullopt);
}

{
std::vector<TypeCorrectedQuery> expected(1);
expected[0].correction = "いろは";
auto mock = std::make_unique<MockSpellchecker>();
EXPECT_CALL(*mock, CheckCompositionSpelling(preedit, "context", _))
.WillOnce(Return(expected));
composer_->SetSpellchecker(mock.get());
const auto result = composer_->GetTypeCorrectedQueries("context");
ASSERT_TRUE(result);
const auto &corrections = result.value();
ASSERT_EQ(corrections.size(), 1);
EXPECT_EQ(corrections[0].correction, "いろは");
}
}

TEST_F(ComposerTest, UpdateComposition) {
Expand Down
19 changes: 16 additions & 3 deletions src/engine/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -84,12 +84,24 @@ mozc_cc_library(
name = "engine_interface",
hdrs = ["engine_interface.h"],
deps = [
":spellchecker_interface",
":user_data_manager_interface",
"//converter:converter_interface",
"//data_manager:data_manager_interface",
"//dictionary:suppression_dictionary",
"//prediction:predictor_interface",
"//spelling:spellchecker_service_interface",
"@com_google_absl//absl/strings",
],
)

mozc_cc_library(
name = "spellchecker_interface",
hdrs = ["spellchecker_interface.h"],
deps = [
"//composer:query",
"//converter:segments",
"//data_manager",
"//protocol:commands_cc_proto",
"@com_google_absl//absl/strings",
],
)
Expand All @@ -99,7 +111,7 @@ mozc_cc_library(
srcs = ["modules.cc"],
hdrs = ["modules.h"],
deps = [
":user_data_manager_interface",
":spellchecker_interface",
"//base:logging",
"//converter:connector",
"//converter:segmenter",
Expand Down Expand Up @@ -132,6 +144,7 @@ mozc_cc_library(
deps = [
":engine_interface",
":modules",
":spellchecker_interface",
":user_data_manager_interface",
"//base:logging",
"//base:vlog",
Expand Down Expand Up @@ -159,12 +172,12 @@ mozc_cc_library(
hdrs = ["engine_mock.h"],
deps = [
":engine_interface",
":spellchecker_interface",
":user_data_manager_interface",
"//converter:converter_interface",
"//data_manager:data_manager_interface",
"//dictionary:suppression_dictionary",
"//prediction:predictor_interface",
"//spelling:spellchecker_service_interface",
"//testing:gunit",
"@com_google_absl//absl/strings",
],
Expand Down
7 changes: 5 additions & 2 deletions src/engine/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,13 @@
#include "converter/immutable_converter_interface.h"
#include "data_manager/data_manager_interface.h"
#include "dictionary/suppression_dictionary.h"
#include "dictionary/user_dictionary.h"
#include "engine/engine_interface.h"
#include "engine/modules.h"
#include "engine/spellchecker_interface.h"
#include "engine/user_data_manager_interface.h"
#include "prediction/predictor_interface.h"
#include "rewriter/rewriter_interface.h"


namespace mozc {

// Builds and manages a set of modules that are necessary for conversion engine.
Expand Down Expand Up @@ -115,6 +114,10 @@ class Engine : public EngineInterface {
return modules_.GetUserDictionary()->GetPosList();
}

void SetSpellchecker(
const engine::SpellcheckerInterface *spellchecker) override {
modules_.SetSpellchecker(spellchecker);
}

private:
// Initializes the object by the given data manager and is_mobile flag.
Expand Down
4 changes: 3 additions & 1 deletion src/engine/engine_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@
#include "converter/converter_interface.h"
#include "data_manager/data_manager_interface.h"
#include "dictionary/suppression_dictionary.h"
#include "engine/spellchecker_interface.h"
#include "engine/user_data_manager_interface.h"
#include "prediction/predictor_interface.h"


namespace mozc {

// Builds and manages a set of modules that are necessary for conversion,
Expand Down Expand Up @@ -84,6 +84,8 @@ class EngineInterface {
// Gets the user POS list.
virtual std::vector<std::string> GetPosList() const = 0;

virtual void SetSpellchecker(
const engine::SpellcheckerInterface *spellchecker) {}

protected:
EngineInterface() = default;
Expand Down
4 changes: 3 additions & 1 deletion src/engine/engine_mock.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@
#include "data_manager/data_manager_interface.h"
#include "dictionary/suppression_dictionary.h"
#include "engine/engine_interface.h"
#include "engine/spellchecker_interface.h"
#include "engine/user_data_manager_interface.h"
#include "prediction/predictor_interface.h"
#include "testing/gmock.h"


namespace mozc {

class MockEngine : public EngineInterface {
Expand All @@ -59,6 +59,8 @@ class MockEngine : public EngineInterface {
MOCK_METHOD(const DataManagerInterface *, GetDataManager, (),
(const, override));
MOCK_METHOD(std::vector<std::string>, GetPosList, (), (const, override));
MOCK_METHOD(void, SetSpellchecker, (const engine::SpellcheckerInterface *),
(override));
};

} // namespace mozc
Expand Down
12 changes: 11 additions & 1 deletion src/engine/modules.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,11 @@
#include "dictionary/pos_group.h"
#include "dictionary/pos_matcher.h"
#include "dictionary/suppression_dictionary.h"
#include "engine/spellchecker_interface.h"
#include "prediction/rescorer_interface.h"
#include "prediction/suggestion_filter.h"



namespace mozc {
namespace engine {

Expand Down Expand Up @@ -100,6 +100,12 @@ class Modules {
}


const engine::SpellcheckerInterface *GetSpellchecker() const {
return spellchecker_;
}
void SetSpellchecker(const engine::SpellcheckerInterface *spellchecker) {
spellchecker_ = spellchecker;
}

private:
bool initialized_ = false;
Expand All @@ -115,6 +121,10 @@ class Modules {
std::unique_ptr<const prediction::RescorerInterface> rescorer_;


// Spellchecker used for homonym correction.
// Module doesn't have the ownership of spellchecker_,
// SessionHandler owns this this instance. (usually a singleton object).
const engine::SpellcheckerInterface *spellchecker_ = nullptr;
};

} // namespace engine
Expand Down
Loading

0 comments on commit 492e690

Please sign in to comment.