xref: /aosp_15_r20/external/icing/icing/util/scorable_property_set.cc (revision 8b6cd535a057e39b3b86660c4aa06c99747c2136)
1 // Copyright (C) 2024 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "icing/util/scorable_property_set.h"
16 
17 #include <cstdint>
18 #include <memory>
19 #include <optional>
20 #include <string>
21 #include <string_view>
22 #include <utility>
23 #include <vector>
24 
25 #include "icing/text_classifier/lib3/utils/base/statusor.h"
26 #include "icing/absl_ports/canonical_errors.h"
27 #include "icing/legacy/core/icing-string-util.h"
28 #include "icing/proto/internal/scorable_property_set.pb.h"
29 #include "icing/proto/schema.pb.h"
30 #include "icing/schema/property-util.h"
31 #include "icing/schema/schema-store.h"
32 #include "icing/schema/scorable_property_manager.h"
33 #include "icing/store/document-filter-data.h"
34 #include "icing/util/status-macros.h"
35 
36 namespace icing {
37 namespace lib {
38 
39 libtextclassifier3::StatusOr<std::unique_ptr<ScorablePropertySet>>
Create(ScorablePropertySetProto && scorable_property_set_proto,SchemaTypeId schema_type_id,const SchemaStore * schema_store)40 ScorablePropertySet::Create(
41     ScorablePropertySetProto&& scorable_property_set_proto,
42     SchemaTypeId schema_type_id, const SchemaStore* schema_store) {
43   ICING_ASSIGN_OR_RETURN(
44       const std::vector<ScorablePropertyManager::ScorablePropertyInfo>*
45           ordered_scorable_property_info,
46       schema_store->GetOrderedScorablePropertyInfo(schema_type_id));
47   if (ordered_scorable_property_info == nullptr ||
48       ordered_scorable_property_info->size() !=
49           scorable_property_set_proto.properties_size()) {
50     return absl_ports::InvalidArgumentError(IcingStringUtil::StringPrintf(
51         "ScorablePropertySetProto data is inconsistent with the schema config "
52         "of type id %d",
53         schema_type_id));
54   }
55   return std::unique_ptr<ScorablePropertySet>(new ScorablePropertySet(
56       std::move(scorable_property_set_proto), schema_type_id, schema_store));
57 }
58 
59 libtextclassifier3::StatusOr<std::unique_ptr<ScorablePropertySet>>
Create(const DocumentProto & document,SchemaTypeId schema_type_id,const SchemaStore * schema_store)60 ScorablePropertySet::Create(const DocumentProto& document,
61                             SchemaTypeId schema_type_id,
62                             const SchemaStore* schema_store) {
63   ICING_ASSIGN_OR_RETURN(
64       const std::vector<ScorablePropertyManager::ScorablePropertyInfo>*
65           ordered_scorable_property_info,
66       schema_store->GetOrderedScorablePropertyInfo(schema_type_id));
67   if (ordered_scorable_property_info == nullptr) {
68     // It should never happen
69     return absl_ports::InternalError(
70         "SchemaStore::ordered_scorable_property_paths returned nullptr");
71   }
72   if (ordered_scorable_property_info->empty()) {
73     return absl_ports::InvalidArgumentError(IcingStringUtil::StringPrintf(
74         "No scorable property defined under the config of type id %d",
75         schema_type_id));
76   }
77 
78   ScorablePropertySetProto scorable_property_set_proto_to_build;
79   for (const ScorablePropertyManager::ScorablePropertyInfo&
80            scorable_property_info : *ordered_scorable_property_info) {
81     ScorablePropertyProto* new_property =
82         scorable_property_set_proto_to_build.add_properties();
83 
84     if (scorable_property_info.data_type ==
85         PropertyConfigProto::DataType::DOUBLE) {
86       libtextclassifier3::StatusOr<std::vector<double>> content_or =
87           property_util::ExtractPropertyValuesFromDocument<double>(
88               document, scorable_property_info.property_path);
89       if (content_or.ok()) {
90         new_property->mutable_double_values()->Add(
91             content_or.ValueOrDie().begin(), content_or.ValueOrDie().end());
92       }
93     } else if (scorable_property_info.data_type ==
94                PropertyConfigProto::DataType::INT64) {
95       libtextclassifier3::StatusOr<std::vector<int64_t>> content_or =
96           property_util::ExtractPropertyValuesFromDocument<int64_t>(
97               document, scorable_property_info.property_path);
98       if (content_or.ok()) {
99         new_property->mutable_int64_values()->Add(
100             content_or.ValueOrDie().begin(), content_or.ValueOrDie().end());
101       }
102     } else if (scorable_property_info.data_type ==
103                PropertyConfigProto::DataType::BOOLEAN) {
104       libtextclassifier3::StatusOr<std::vector<bool>> content_or =
105           property_util::ExtractPropertyValuesFromDocument<bool>(
106               document, scorable_property_info.property_path);
107       if (content_or.ok()) {
108         new_property->mutable_boolean_values()->Add(
109             content_or.ValueOrDie().begin(), content_or.ValueOrDie().end());
110       }
111     }
112   }
113   return std::unique_ptr<ScorablePropertySet>(
114       new ScorablePropertySet(std::move(scorable_property_set_proto_to_build),
115                               schema_type_id, schema_store));
116 }
117 
GetScorablePropertyProto(const std::string & property_path) const118 const ScorablePropertyProto* ScorablePropertySet::GetScorablePropertyProto(
119     const std::string& property_path) const {
120   libtextclassifier3::StatusOr<std::optional<int>> index_or =
121       schema_store_->GetScorablePropertyIndex(schema_type_id_, property_path);
122   if (!index_or.ok() || !index_or.ValueOrDie().has_value()) {
123     return nullptr;
124   }
125   return &scorable_property_set_proto_.properties(
126       index_or.ValueOrDie().value());
127 }
128 
ScorablePropertySet(ScorablePropertySetProto && scorable_property_set_proto,SchemaTypeId schema_type_id,const SchemaStore * schema_store)129 ScorablePropertySet::ScorablePropertySet(
130     ScorablePropertySetProto&& scorable_property_set_proto,
131     SchemaTypeId schema_type_id, const SchemaStore* schema_store)
132     : scorable_property_set_proto_(std::move(scorable_property_set_proto)),
133       schema_type_id_(schema_type_id),
134       schema_store_(schema_store) {}
135 
136 }  // namespace lib
137 }  // namespace icing
138