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 <string>
18 #include <string_view>
19 #include <utility>
20 #include <vector>
21
22 #include "icing/text_classifier/lib3/utils/base/statusor.h"
23 #include "icing/absl_ports/canonical_errors.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
GetPropertyProto(const DocumentProto & document,std::string_view property_name)88 const PropertyProto* GetPropertyProto(const DocumentProto& document,
89 std::string_view property_name) {
90 for (const PropertyProto& property : document.properties()) {
91 if (property.name() == property_name) {
92 return &property;
93 }
94 }
95 return nullptr;
96 }
97
98 template <>
99 libtextclassifier3::StatusOr<std::vector<std::string>>
ExtractPropertyValues(const PropertyProto & property)100 ExtractPropertyValues<std::string>(const PropertyProto& property) {
101 return std::vector<std::string>(property.string_values().begin(),
102 property.string_values().end());
103 }
104
105 template <>
106 libtextclassifier3::StatusOr<std::vector<std::string_view>>
ExtractPropertyValues(const PropertyProto & property)107 ExtractPropertyValues<std::string_view>(const PropertyProto& property) {
108 return std::vector<std::string_view>(property.string_values().begin(),
109 property.string_values().end());
110 }
111
112 template <>
113 libtextclassifier3::StatusOr<std::vector<int64_t>>
ExtractPropertyValues(const PropertyProto & property)114 ExtractPropertyValues<int64_t>(const PropertyProto& property) {
115 return std::vector<int64_t>(property.int64_values().begin(),
116 property.int64_values().end());
117 }
118
119 } // namespace property_util
120
121 } // namespace lib
122 } // namespace icing
123