xref: /aosp_15_r20/external/icing/icing/schema/property-util.cc (revision 8b6cd535a057e39b3b86660c4aa06c99747c2136)
1 // Copyright (C) 2022 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/schema/property-util.h"
16 
17 #include <cstddef>
18 #include <cstdint>
19 #include <string>
20 #include <string_view>
21 #include <vector>
22 
23 #include "icing/text_classifier/lib3/utils/base/statusor.h"
24 #include "icing/absl_ports/str_cat.h"
25 #include "icing/absl_ports/str_join.h"
26 #include "icing/proto/document.pb.h"
27 
28 namespace icing {
29 namespace lib {
30 
31 namespace property_util {
32 
ConvertToPropertyExprIndexStr(int index)33 std::string ConvertToPropertyExprIndexStr(int index) {
34   if (index == kWildcardPropertyIndex) {
35     return "";
36   }
37   return absl_ports::StrCat(kLBracket, std::to_string(index), kRBracket);
38 }
39 
ConcatenatePropertyPathExpr(std::string_view property_path_expr1,std::string_view property_path_expr2)40 std::string ConcatenatePropertyPathExpr(std::string_view property_path_expr1,
41                                         std::string_view property_path_expr2) {
42   if (property_path_expr1.empty()) {
43     return std::string(property_path_expr2);
44   }
45   if (property_path_expr2.empty()) {
46     return std::string(property_path_expr1);
47   }
48   return absl_ports::StrCat(property_path_expr1, kPropertyPathSeparator,
49                             property_path_expr2);
50 }
51 
SplitPropertyPathExpr(std::string_view property_path_expr)52 std::vector<std::string_view> SplitPropertyPathExpr(
53     std::string_view property_path_expr) {
54   return absl_ports::StrSplit(property_path_expr, kPropertyPathSeparator);
55 }
56 
ParsePropertyNameExpr(std::string_view property_name_expr)57 PropertyInfo ParsePropertyNameExpr(std::string_view property_name_expr) {
58   size_t l_bracket = property_name_expr.find(kLBracket);
59   if (l_bracket == std::string_view::npos ||
60       l_bracket >= property_name_expr.length()) {
61     return PropertyInfo(std::string(property_name_expr),
62                         kWildcardPropertyIndex);
63   }
64   size_t r_bracket = property_name_expr.find(kRBracket, l_bracket);
65   if (r_bracket == std::string_view::npos || r_bracket - l_bracket < 2) {
66     return PropertyInfo(std::string(property_name_expr),
67                         kWildcardPropertyIndex);
68   }
69   std::string index_string = std::string(
70       property_name_expr.substr(l_bracket + 1, r_bracket - l_bracket - 1));
71   return PropertyInfo(std::string(property_name_expr.substr(0, l_bracket)),
72                       std::stoi(index_string));
73 }
74 
ParsePropertyPathExpr(std::string_view property_path_expr)75 std::vector<PropertyInfo> ParsePropertyPathExpr(
76     std::string_view property_path_expr) {
77   std::vector<std::string_view> property_name_exprs =
78       SplitPropertyPathExpr(property_path_expr);
79 
80   std::vector<PropertyInfo> property_infos;
81   property_infos.reserve(property_name_exprs.size());
82   for (std::string_view property_name_expr : property_name_exprs) {
83     property_infos.push_back(ParsePropertyNameExpr(property_name_expr));
84   }
85   return property_infos;
86 }
87 
IsParentPropertyPath(std::string_view property_path_expr1,std::string_view property_path_expr2)88 bool IsParentPropertyPath(std::string_view property_path_expr1,
89                           std::string_view property_path_expr2) {
90   if (property_path_expr2.length() < property_path_expr1.length()) {
91     return false;
92   }
93   if (property_path_expr1 !=
94       property_path_expr2.substr(0, property_path_expr1.length())) {
95     return false;
96   }
97   if (property_path_expr2.length() > property_path_expr1.length() &&
98       property_path_expr2[property_path_expr1.length()] !=
99           kPropertyPathSeparator[0]) {
100     return false;
101   }
102   return true;
103 }
104 
GetPropertyProto(const DocumentProto & document,std::string_view property_name)105 const PropertyProto* GetPropertyProto(const DocumentProto& document,
106                                       std::string_view property_name) {
107   for (const PropertyProto& property : document.properties()) {
108     if (property.name() == property_name) {
109       return &property;
110     }
111   }
112   return nullptr;
113 }
114 
115 template <>
116 libtextclassifier3::StatusOr<std::vector<std::string>>
ExtractPropertyValues(const PropertyProto & property)117 ExtractPropertyValues<std::string>(const PropertyProto& property) {
118   return std::vector<std::string>(property.string_values().begin(),
119                                   property.string_values().end());
120 }
121 
122 template <>
123 libtextclassifier3::StatusOr<std::vector<std::string_view>>
ExtractPropertyValues(const PropertyProto & property)124 ExtractPropertyValues<std::string_view>(const PropertyProto& property) {
125   return std::vector<std::string_view>(property.string_values().begin(),
126                                        property.string_values().end());
127 }
128 
129 template <>
130 libtextclassifier3::StatusOr<std::vector<int64_t>>
ExtractPropertyValues(const PropertyProto & property)131 ExtractPropertyValues<int64_t>(const PropertyProto& property) {
132   return std::vector<int64_t>(property.int64_values().begin(),
133                               property.int64_values().end());
134 }
135 
136 template <>
ExtractPropertyValues(const PropertyProto & property)137 libtextclassifier3::StatusOr<std::vector<double>> ExtractPropertyValues<double>(
138     const PropertyProto& property) {
139   return std::vector<double>(property.double_values().begin(),
140                              property.double_values().end());
141 }
142 
143 template <>
ExtractPropertyValues(const PropertyProto & property)144 libtextclassifier3::StatusOr<std::vector<bool>> ExtractPropertyValues<bool>(
145     const PropertyProto& property) {
146   return std::vector<bool>(property.boolean_values().begin(),
147                            property.boolean_values().end());
148 }
149 
150 template <>
151 libtextclassifier3::StatusOr<std::vector<PropertyProto::VectorProto>>
ExtractPropertyValues(const PropertyProto & property)152 ExtractPropertyValues<PropertyProto::VectorProto>(
153     const PropertyProto& property) {
154   return std::vector<PropertyProto::VectorProto>(
155       property.vector_values().begin(), property.vector_values().end());
156 }
157 
158 template <>
159 libtextclassifier3::StatusOr<std::vector<PropertyProto::BlobHandleProto>>
ExtractPropertyValues(const PropertyProto & property)160 ExtractPropertyValues<PropertyProto::BlobHandleProto>(
161     const PropertyProto& property) {
162   return std::vector<PropertyProto::BlobHandleProto>(
163       property.blob_handle_values().begin(),
164       property.blob_handle_values().end());
165 }
166 
167 }  // namespace property_util
168 
169 }  // namespace lib
170 }  // namespace icing
171