1 /*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "actions/utils.h"
18
19 #include "utils/base/logging.h"
20 #include "utils/normalization.h"
21 #include "utils/strings/stringpiece.h"
22
23 namespace libtextclassifier3 {
24
FillSuggestionFromSpec(const ActionSuggestionSpec * action,ReflectiveFlatbuffer * entity_data,ActionSuggestion * suggestion)25 void FillSuggestionFromSpec(const ActionSuggestionSpec* action,
26 ReflectiveFlatbuffer* entity_data,
27 ActionSuggestion* suggestion) {
28 if (action != nullptr) {
29 suggestion->score = action->score();
30 suggestion->priority_score = action->priority_score();
31 if (action->type() != nullptr) {
32 suggestion->type = action->type()->str();
33 }
34 if (action->response_text() != nullptr) {
35 suggestion->response_text = action->response_text()->str();
36 }
37 if (action->serialized_entity_data() != nullptr) {
38 TC3_CHECK_NE(entity_data, nullptr);
39 entity_data->MergeFromSerializedFlatbuffer(
40 StringPiece(action->serialized_entity_data()->data(),
41 action->serialized_entity_data()->size()));
42 }
43 if (action->entity_data() != nullptr) {
44 TC3_CHECK_NE(entity_data, nullptr);
45 entity_data->MergeFrom(
46 reinterpret_cast<const flatbuffers::Table*>(action->entity_data()));
47 }
48 }
49 if (entity_data != nullptr && entity_data->HasExplicitlySetFields()) {
50 suggestion->serialized_entity_data = entity_data->Serialize();
51 }
52 }
53
SuggestTextRepliesFromCapturingMatch(const ReflectiveFlatbufferBuilder * entity_data_builder,const RulesModel_::RuleActionSpec_::RuleCapturingGroup * group,const UnicodeText & match_text,const std::string & smart_reply_action_type,std::vector<ActionSuggestion> * actions)54 void SuggestTextRepliesFromCapturingMatch(
55 const ReflectiveFlatbufferBuilder* entity_data_builder,
56 const RulesModel_::RuleActionSpec_::RuleCapturingGroup* group,
57 const UnicodeText& match_text, const std::string& smart_reply_action_type,
58 std::vector<ActionSuggestion>* actions) {
59 if (group->text_reply() != nullptr) {
60 ActionSuggestion suggestion;
61 suggestion.response_text = match_text.ToUTF8String();
62 suggestion.type = smart_reply_action_type;
63 std::unique_ptr<ReflectiveFlatbuffer> entity_data =
64 entity_data_builder != nullptr ? entity_data_builder->NewRoot()
65 : nullptr;
66 FillSuggestionFromSpec(group->text_reply(), entity_data.get(), &suggestion);
67 actions->push_back(suggestion);
68 }
69 }
70
NormalizeMatchText(const UniLib & unilib,const RulesModel_::RuleActionSpec_::RuleCapturingGroup * group,StringPiece match_text)71 UnicodeText NormalizeMatchText(
72 const UniLib& unilib,
73 const RulesModel_::RuleActionSpec_::RuleCapturingGroup* group,
74 StringPiece match_text) {
75 UnicodeText normalized_match_text =
76 UTF8ToUnicodeText(match_text, /*do_copy=*/false);
77 if (group->normalization_options() != nullptr) {
78 normalized_match_text = NormalizeText(
79 unilib, group->normalization_options(), normalized_match_text);
80 }
81 return normalized_match_text;
82 }
83
FillAnnotationFromCapturingMatch(const CodepointSpan & span,const RulesModel_::RuleActionSpec_::RuleCapturingGroup * group,const int message_index,StringPiece match_text,ActionSuggestionAnnotation * annotation)84 bool FillAnnotationFromCapturingMatch(
85 const CodepointSpan& span,
86 const RulesModel_::RuleActionSpec_::RuleCapturingGroup* group,
87 const int message_index, StringPiece match_text,
88 ActionSuggestionAnnotation* annotation) {
89 if (group->annotation_name() == nullptr &&
90 group->annotation_type() == nullptr) {
91 return false;
92 }
93 annotation->span.span = span;
94 annotation->span.message_index = message_index;
95 annotation->span.text = match_text.ToString();
96 if (group->annotation_name() != nullptr) {
97 annotation->name = group->annotation_name()->str();
98 }
99 if (group->annotation_type() != nullptr) {
100 annotation->entity.collection = group->annotation_type()->str();
101 }
102 return true;
103 }
104
MergeEntityDataFromCapturingMatch(const RulesModel_::RuleActionSpec_::RuleCapturingGroup * group,StringPiece match_text,ReflectiveFlatbuffer * buffer)105 bool MergeEntityDataFromCapturingMatch(
106 const RulesModel_::RuleActionSpec_::RuleCapturingGroup* group,
107 StringPiece match_text, ReflectiveFlatbuffer* buffer) {
108 if (group->entity_field() != nullptr) {
109 if (!buffer->ParseAndSet(group->entity_field(), match_text.ToString())) {
110 TC3_LOG(ERROR) << "Could not set entity data from rule capturing group.";
111 return false;
112 }
113 }
114 if (group->entity_data() != nullptr) {
115 if (!buffer->MergeFrom(reinterpret_cast<const flatbuffers::Table*>(
116 group->entity_data()))) {
117 TC3_LOG(ERROR) << "Could not set entity data for capturing match.";
118 return false;
119 }
120 }
121 return true;
122 }
123
124 } // namespace libtextclassifier3
125