Coverage Report

Created: 2026-05-27 07:00

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/values/string_value.h
Line
Count
Source
1
// Copyright 2023 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
//     https://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
// IWYU pragma: private, include "common/value.h"
16
// IWYU pragma: friend "common/value.h"
17
18
#ifndef THIRD_PARTY_CEL_CPP_COMMON_VALUES_STRING_VALUE_H_
19
#define THIRD_PARTY_CEL_CPP_COMMON_VALUES_STRING_VALUE_H_
20
21
#include <cstddef>
22
#include <cstdint>
23
#include <ostream>
24
#include <string>
25
#include <type_traits>
26
#include <utility>
27
28
#include "absl/base/attributes.h"
29
#include "absl/base/nullability.h"
30
#include "absl/log/absl_check.h"
31
#include "absl/status/status.h"
32
#include "absl/status/statusor.h"
33
#include "absl/strings/cord.h"
34
#include "absl/strings/string_view.h"
35
#include "absl/types/optional.h"
36
#include "common/allocator.h"
37
#include "common/arena.h"
38
#include "common/internal/byte_string.h"
39
#include "common/memory.h"
40
#include "common/type.h"
41
#include "common/value_kind.h"
42
#include "common/values/values.h"
43
#include "google/protobuf/arena.h"
44
#include "google/protobuf/descriptor.h"
45
#include "google/protobuf/io/zero_copy_stream.h"
46
#include "google/protobuf/message.h"
47
48
namespace cel {
49
50
class Value;
51
class ListValue;
52
class StringValue;
53
54
namespace common_internal {
55
absl::string_view LegacyStringValue(const StringValue& value, bool stable,
56
                                    google::protobuf::Arena* absl_nonnull arena);
57
}  // namespace common_internal
58
59
// `StringValue` represents values of the primitive `string` type.
60
class StringValue final : private common_internal::ValueMixin<StringValue> {
61
 public:
62
  static constexpr ValueKind kKind = ValueKind::kString;
63
64
  static StringValue From(const char* absl_nullable value,
65
                          google::protobuf::Arena* absl_nonnull arena
66
                              ABSL_ATTRIBUTE_LIFETIME_BOUND);
67
  static StringValue From(absl::string_view value,
68
                          google::protobuf::Arena* absl_nonnull arena
69
                              ABSL_ATTRIBUTE_LIFETIME_BOUND);
70
  static StringValue From(const absl::Cord& value);
71
  static StringValue From(std::string&& value,
72
                          google::protobuf::Arena* absl_nonnull arena
73
                              ABSL_ATTRIBUTE_LIFETIME_BOUND);
74
75
  static StringValue Wrap(absl::string_view value,
76
                          google::protobuf::Arena* absl_nullable arena
77
                              ABSL_ATTRIBUTE_LIFETIME_BOUND);
78
  static StringValue Wrap(absl::string_view value) = delete;
79
  static StringValue Wrap(const absl::Cord& value);
80
  static StringValue Wrap(std::string&& value) = delete;
81
  static StringValue Wrap(std::string&& value,
82
                          google::protobuf::Arena* absl_nullable arena
83
                              ABSL_ATTRIBUTE_LIFETIME_BOUND) = delete;
84
85
  // Returns a StringValue that aliases the provided string. Caller must ensure
86
  // the provided string outlives the use of the returned StringValue.
87
  static StringValue WrapUnsafe(absl::string_view value);
88
89
  static StringValue Concat(const StringValue& lhs, const StringValue& rhs,
90
                            google::protobuf::Arena* absl_nonnull arena
91
                                ABSL_ATTRIBUTE_LIFETIME_BOUND);
92
93
  ABSL_DEPRECATED("Use From")
94
1
  explicit StringValue(const char* absl_nullable value) : value_(value) {}
95
96
  ABSL_DEPRECATED("Use From")
97
16.4k
  explicit StringValue(absl::string_view value) : value_(value) {}
98
99
  ABSL_DEPRECATED("Use From")
100
0
  explicit StringValue(const absl::Cord& value) : value_(value) {}
101
102
  ABSL_DEPRECATED("Use From")
103
6
  explicit StringValue(std::string&& value) : value_(std::move(value)) {}
104
105
  ABSL_DEPRECATED("Use From")
106
  StringValue(Allocator<> allocator, const char* absl_nullable value)
107
0
      : value_(allocator, value) {}
108
109
  ABSL_DEPRECATED("Use From")
110
  StringValue(Allocator<> allocator, absl::string_view value)
111
10.6k
      : value_(allocator, value) {}
112
113
  ABSL_DEPRECATED("Use From")
114
  StringValue(Allocator<> allocator, const absl::Cord& value)
115
0
      : value_(allocator, value) {}
116
117
  ABSL_DEPRECATED("Use From")
118
  StringValue(Allocator<> allocator, std::string&& value)
119
0
      : value_(allocator, std::move(value)) {}
120
121
  ABSL_DEPRECATED("Use Wrap")
122
  StringValue(Borrower borrower, absl::string_view value)
123
26
      : value_(borrower, value) {}
124
125
  ABSL_DEPRECATED("Use Wrap")
126
  StringValue(Borrower borrower, const absl::Cord& value)
127
0
      : value_(borrower, value) {}
128
129
324
  StringValue() = default;
130
7.81k
  StringValue(const StringValue&) = default;
131
72.5k
  StringValue(StringValue&&) = default;
132
324
  StringValue& operator=(const StringValue&) = default;
133
334
  StringValue& operator=(StringValue&&) = default;
134
135
0
  constexpr ValueKind kind() const { return kKind; }
136
137
0
  absl::string_view GetTypeName() const { return StringType::kName; }
138
139
  std::string DebugString() const;
140
141
  // See Value::SerializeTo().
142
  absl::Status SerializeTo(
143
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
144
      google::protobuf::MessageFactory* absl_nonnull message_factory,
145
      google::protobuf::io::ZeroCopyOutputStream* absl_nonnull output) const;
146
147
  // See Value::ConvertToJson().
148
  absl::Status ConvertToJson(
149
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
150
      google::protobuf::MessageFactory* absl_nonnull message_factory,
151
      google::protobuf::Message* absl_nonnull json) const;
152
153
  absl::Status Equal(const Value& other,
154
                     const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
155
                     google::protobuf::MessageFactory* absl_nonnull message_factory,
156
                     google::protobuf::Arena* absl_nonnull arena,
157
                     Value* absl_nonnull result) const;
158
  using ValueMixin::Equal;
159
160
  StringValue Clone(google::protobuf::Arena* absl_nonnull arena) const;
161
162
0
  bool IsZeroValue() const {
163
0
    return NativeValue([](const auto& value) -> bool { return value.empty(); });
Unexecuted instantiation: bool cel::StringValue::IsZeroValue() const::{lambda(auto:1 const&)#1}::operator()<std::__1::basic_string_view<char, {lambda(auto:1 const&)#1}::operator()::char_traits<char> > >(std::__1::basic_string_view<char, {lambda(auto:1 const&)#1}::operator()::char_traits<char> > const&) const
Unexecuted instantiation: bool cel::StringValue::IsZeroValue() const::{lambda(auto:1 const&)#1}::operator()<absl::lts_20260107::Cord>(absl::lts_20260107::Cord const&) const
164
0
  }
165
166
  ABSL_DEPRECATED("Use ToString()")
167
0
  std::string NativeString() const { return value_.ToString(); }
168
169
  ABSL_DEPRECATED("Use ToStringView()")
170
  absl::string_view NativeString(
171
      std::string& scratch
172
0
          ABSL_ATTRIBUTE_LIFETIME_BOUND) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
173
0
    return value_.ToStringView(&scratch);
174
0
  }
175
176
  ABSL_DEPRECATED("Use ToCord()")
177
0
  absl::Cord NativeCord() const { return value_.ToCord(); }
178
179
  template <typename Visitor>
180
  ABSL_DEPRECATED("Use TryFlat()")
181
  std::common_type_t<
182
      std::invoke_result_t<Visitor, absl::string_view>,
183
      std::invoke_result_t<Visitor, const absl::Cord&>> NativeValue(Visitor&&
184
                                                                        visitor)
185
3.42k
      const {
186
3.42k
    return value_.Visit(std::forward<Visitor>(visitor));
187
3.42k
  }
Unexecuted instantiation: std::__1::common_type<cel::StringValue::IsZeroValue() const::{lambda(auto:1 const&)#1}::__invoke_result_impl<void, cel::StringValue::IsZeroValue() const::{lambda(auto:1 const&)#1}, cel::StringValue::IsZeroValue() const::{lambda(auto:1 const&)#1}::basic_string_view<char, cel::StringValue::IsZeroValue() const::{lambda(auto:1 const&)#1}::char_traits<char> > >::type, std::__1::common_type<void, cel::StringValue::IsZeroValue() const::{lambda(auto:1 const&)#1}, absl::lts_20260107::Cord const&>::type>::type cel::StringValue::NativeValue<cel::StringValue::IsZeroValue() const::{lambda(auto:1 const&)#1}>(cel::StringValue::IsZeroValue() const::{lambda(auto:1 const&)#1}&&) const
Unexecuted instantiation: regex_match_step.cc:std::__1::common_type<std::__1::__invoke_result_impl<void, google::api::expr::runtime::(anonymous namespace)::MatchesVisitor, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::type, std::__1::__invoke_result_impl<void, google::api::expr::runtime::(anonymous namespace)::MatchesVisitor, absl::lts_20260107::Cord const&>::type>::type cel::StringValue::NativeValue<google::api::expr::runtime::(anonymous namespace)::MatchesVisitor>(google::api::expr::runtime::(anonymous namespace)::MatchesVisitor&&) const
string_value.cc:std::__1::common_type<std::__1::__invoke_result_impl<void, absl::lts_20260107::Overload<cel::(anonymous namespace)::StringDebugString<cel::StringValue>(cel::StringValue const&)::{lambda(std::__1::basic_string_view<char, std::__1::char_traits<char> >)#1}, cel::(anonymous namespace)::StringDebugString<cel::StringValue>(cel::StringValue const&)::{lambda(absl::lts_20260107::Cord const&)#1}>, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::type, absl::lts_20260107::Overload<cel::(anonymous namespace)::StringDebugString<cel::StringValue>(cel::StringValue const&)::{lambda(std::__1::basic_string_view<char, std::__1::char_traits<char> >)#1}, cel::(anonymous namespace)::StringDebugString<cel::StringValue>(cel::StringValue const&)::{lambda(absl::lts_20260107::Cord const&)#1}><void, absl::lts_20260107::Overload<cel::(anonymous namespace)::StringDebugString<cel::StringValue>(cel::StringValue const&)::{lambda(std::__1::basic_string_view<char, std::__1::char_traits<char> >)#1}, cel::(anonymous namespace)::StringDebugString<cel::StringValue>(cel::StringValue const&)::{lambda(absl::lts_20260107::Cord const&)#1}>, absl::lts_20260107::Cord const>::type>::type cel::StringValue::NativeValue<absl::lts_20260107::Overload<cel::(anonymous namespace)::StringDebugString<cel::StringValue>(cel::StringValue const&)::{lambda(std::__1::basic_string_view<char, std::__1::char_traits<char> >)#1}, cel::(anonymous namespace)::StringDebugString<cel::StringValue>(cel::StringValue const&)::{lambda(absl::lts_20260107::Cord const&)#1}> >(absl::lts_20260107::Overload<cel::(anonymous namespace)::StringDebugString<cel::StringValue>(cel::StringValue const&)::{lambda(std::__1::basic_string_view<char, std::__1::char_traits<char> >)#1}, cel::(anonymous namespace)::StringDebugString<cel::StringValue>(cel::StringValue const&)::{lambda(absl::lts_20260107::Cord const&)#1}>&&) const
Line
Count
Source
185
2.30k
      const {
186
2.30k
    return value_.Visit(std::forward<Visitor>(visitor));
187
2.30k
  }
Unexecuted instantiation: string_value.cc:std::__1::common_type<std::__1::__invoke_result_impl<void, cel::StringValue::ConvertToJson(google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Message*) const::$_0, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::type, std::__1::__invoke_result_impl<void, cel::StringValue::ConvertToJson(google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Message*) const::$_0, absl::lts_20260107::Cord const&>::type>::type cel::StringValue::NativeValue<cel::StringValue::ConvertToJson(google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Message*) const::$_0>(cel::StringValue::ConvertToJson(google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Message*) const::$_0&&) const
string_value.cc:std::__1::common_type<std::__1::__invoke_result_impl<void, cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::type, std::__1::__invoke_result_impl<void, cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0, absl::lts_20260107::Cord const&>::type>::type cel::StringValue::NativeValue<cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0>(cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0&&) const
Line
Count
Source
185
538
      const {
186
538
    return value_.Visit(std::forward<Visitor>(visitor));
187
538
  }
string_value.cc:std::__1::common_type<std::__1::__invoke_result_impl<void, cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<std::__1::basic_string_view<char, std::__1::char_traits<char> > >(std::__1::basic_string_view<char, std::__1::char_traits<char> > const&) const::{lambda(auto:1 const&)#1}, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::type, std::__1::common_type<void, cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<std::__1::basic_string_view<char, std::__1::char_traits<char> > >(std::__1::basic_string_view<char, std::__1::char_traits<char> > const&) const::{lambda(auto:1 const&)#1}, absl::lts_20260107::Cord const&>::type>::type cel::StringValue::NativeValue<cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<std::__1::basic_string_view<char, std::__1::char_traits<char> > >(std::__1::basic_string_view<char, std::__1::char_traits<char> > const&) const::{lambda(auto:1 const&)#1}>(cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<std::__1::basic_string_view<char, std::__1::char_traits<char> > >(std::__1::basic_string_view<char, std::__1::char_traits<char> > const&) const::{lambda(auto:1 const&)#1}&&) const
Line
Count
Source
185
538
      const {
186
538
    return value_.Visit(std::forward<Visitor>(visitor));
187
538
  }
Unexecuted instantiation: string_value.cc:std::__1::common_type<cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<absl::lts_20260107::Cord>(absl::lts_20260107::Cord const&) const::{lambda(auto:1 const&)#1}::__invoke_result_impl<void, cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<absl::lts_20260107::Cord>(absl::lts_20260107::Cord const&) const::{lambda(auto:1 const&)#1}, cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<absl::lts_20260107::Cord>(absl::lts_20260107::Cord const&) const::{lambda(auto:1 const&)#1}::basic_string_view<char, cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<absl::lts_20260107::Cord>(absl::lts_20260107::Cord const&) const::{lambda(auto:1 const&)#1}::char_traits<char> > >::type, std::__1::common_type<void, cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<absl::lts_20260107::Cord>(absl::lts_20260107::Cord const&) const::{lambda(auto:1 const&)#1}, absl::lts_20260107::Cord const&>::type>::type cel::StringValue::NativeValue<cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<absl::lts_20260107::Cord>(absl::lts_20260107::Cord const&) const::{lambda(auto:1 const&)#1}>(cel::StringValue::Equal(cel::Value const&, google::protobuf::DescriptorPool const*, google::protobuf::MessageFactory*, google::protobuf::Arena*, cel::Value*) const::$_0::operator()<absl::lts_20260107::Cord>(absl::lts_20260107::Cord const&) const::{lambda(auto:1 const&)#1}&&) const
string_value.cc:std::__1::common_type<std::__1::__invoke_result_impl<void, cel::StringValue::Size() const::$_0, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::type, std::__1::__invoke_result_impl<void, cel::StringValue::Size() const::$_0, absl::lts_20260107::Cord const&>::type>::type cel::StringValue::NativeValue<cel::StringValue::Size() const::$_0>(cel::StringValue::Size() const::$_0&&) const
Line
Count
Source
185
47
      const {
186
47
    return value_.Visit(std::forward<Visitor>(visitor));
187
47
  }
Unexecuted instantiation: string_value.cc:std::__1::common_type<std::__1::__invoke_result_impl<void, cel::StringValue::IsEmpty() const::$_0, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::type, std::__1::__invoke_result_impl<void, cel::StringValue::IsEmpty() const::$_0, absl::lts_20260107::Cord const&>::type>::type cel::StringValue::NativeValue<cel::StringValue::IsEmpty() const::$_0>(cel::StringValue::IsEmpty() const::$_0&&) const
Unexecuted instantiation: struct_value_builder.cc:std::__1::common_type<std::__1::__invoke_result_impl<void, absl::lts_20260107::Overload<cel::common_internal::(anonymous namespace)::MessageValueBuilderImpl::SetSingularField(google::protobuf::FieldDescriptor const*, cel::Value)::{lambda(std::__1::basic_string_view<char, std::__1::char_traits<char> >)#2}, cel::common_internal::(anonymous namespace)::MessageValueBuilderImpl::SetSingularField(google::protobuf::FieldDescriptor const*, cel::Value)::{lambda(absl::lts_20260107::Cord const&)#2}>, std::__1::basic_string_view<char, std::__1::char_traits<char> > >::type, absl::lts_20260107::Overload<cel::common_internal::(anonymous namespace)::MessageValueBuilderImpl::SetSingularField(google::protobuf::FieldDescriptor const*, cel::Value)::{lambda(std::__1::basic_string_view<char, std::__1::char_traits<char> >)#2}, cel::common_internal::(anonymous namespace)::MessageValueBuilderImpl::SetSingularField(google::protobuf::FieldDescriptor const*, cel::Value)::{lambda(absl::lts_20260107::Cord const&)#2}><void, std::__1::common_type, absl::lts_20260107::Cord const>::type>::type cel::StringValue::NativeValue<absl::lts_20260107::Overload<cel::common_internal::(anonymous namespace)::MessageValueBuilderImpl::SetSingularField(google::protobuf::FieldDescriptor const*, cel::Value)::{lambda(std::__1::basic_string_view<char, std::__1::char_traits<char> >)#2}, cel::common_internal::(anonymous namespace)::MessageValueBuilderImpl::SetSingularField(google::protobuf::FieldDescriptor const*, cel::Value)::{lambda(absl::lts_20260107::Cord const&)#2}> >(std::__1::common_type&&) const
188
189
0
  void swap(StringValue& other) noexcept {
190
0
    using std::swap;
191
0
    swap(value_, other.value_);
192
0
  }
193
194
  size_t Size() const;
195
196
  bool IsEmpty() const;
197
198
  bool Equals(absl::string_view string) const;
199
  bool Equals(const absl::Cord& string) const;
200
  bool Equals(const StringValue& string) const;
201
202
  int Compare(absl::string_view string) const;
203
  int Compare(const absl::Cord& string) const;
204
  int Compare(const StringValue& string) const;
205
206
  bool StartsWith(absl::string_view string) const;
207
  bool StartsWith(const absl::Cord& string) const;
208
  bool StartsWith(const StringValue& string) const;
209
210
  bool EndsWith(absl::string_view string) const;
211
  bool EndsWith(const absl::Cord& string) const;
212
  bool EndsWith(const StringValue& string) const;
213
214
  bool Contains(absl::string_view string) const;
215
  bool Contains(const absl::Cord& string) const;
216
  bool Contains(const StringValue& string) const;
217
218
  // Returns the 0-based index of the first occurrence of `string` in this
219
  // string, or `absl::nullopt` if `string` is not found.
220
  absl::optional<int64_t> IndexOf(absl::string_view string) const;
221
  absl::optional<int64_t> IndexOf(const absl::Cord& string) const;
222
  absl::optional<int64_t> IndexOf(const StringValue& string) const;
223
  // Returns the 0-based index of the first occurrence of `string` in this
224
  // string at or after `pos`, or `absl::nullopt` if `string` is not found.
225
  absl::optional<int64_t> IndexOf(absl::string_view string, int64_t pos) const;
226
  absl::optional<int64_t> IndexOf(const absl::Cord& string, int64_t pos) const;
227
  absl::optional<int64_t> IndexOf(const StringValue& string, int64_t pos) const;
228
229
  // Returns the 0-based index of the last occurrence of `string` in this
230
  // string, or `absl::nullopt` if `string` is not found.
231
  absl::optional<int64_t> LastIndexOf(absl::string_view string) const;
232
  absl::optional<int64_t> LastIndexOf(const absl::Cord& string) const;
233
  absl::optional<int64_t> LastIndexOf(const StringValue& string) const;
234
  // Returns the 0-based index of the last occurrence of `string` in this
235
  // string at or before `pos`, or `absl::nullopt` if `string` is not found.
236
  absl::optional<int64_t> LastIndexOf(absl::string_view string,
237
                                      int64_t pos) const;
238
  absl::optional<int64_t> LastIndexOf(const absl::Cord& string,
239
                                      int64_t pos) const;
240
  absl::optional<int64_t> LastIndexOf(const StringValue& string,
241
                                      int64_t pos) const;
242
243
  Value Substring(int64_t start) const;
244
245
  Value Substring(int64_t start, int64_t end) const;
246
247
  // Returns a new `StringValue` with all lowercase ASCII characters
248
  // converted to lowercase.
249
  StringValue LowerAscii(google::protobuf::Arena* absl_nonnull arena) const;
250
251
  // Returns a new `StringValue` with all lowercase ASCII characters
252
  // converted to uppercase.
253
  StringValue UpperAscii(google::protobuf::Arena* absl_nonnull arena) const;
254
255
  StringValue Trim() const;
256
257
  // Returns a new `StringValue` with the string surrounded by double quotes.
258
  StringValue Quote(google::protobuf::Arena* absl_nonnull arena) const;
259
260
  // Returns a new `StringValue` with the characters in reverse order.
261
  StringValue Reverse(google::protobuf::Arena* absl_nonnull arena) const;
262
263
  // Joins the elements of `list` with this string using `separator` as the
264
  // separator.
265
  absl::Status Join(const ListValue& list,
266
                    const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
267
                    google::protobuf::MessageFactory* absl_nonnull message_factory,
268
                    google::protobuf::Arena* absl_nonnull arena,
269
                    Value* absl_nonnull result) const;
270
  absl::StatusOr<Value> Join(
271
      const ListValue& list,
272
      const google::protobuf::DescriptorPool* absl_nonnull descriptor_pool,
273
      google::protobuf::MessageFactory* absl_nonnull message_factory,
274
      google::protobuf::Arena* absl_nonnull arena) const;
275
276
  // Splits this string on `delimiter`, returning a list of strings. If `limit`
277
  // is provided and non-negative, the string is split into at most `limit`
278
  // substrings.
279
  absl::Status Split(const StringValue& delimiter, int64_t limit,
280
                     google::protobuf::Arena* absl_nonnull arena,
281
                     Value* absl_nonnull result) const;
282
  absl::StatusOr<Value> Split(const StringValue& delimiter, int64_t limit,
283
                              google::protobuf::Arena* absl_nonnull arena) const;
284
  absl::Status Split(const StringValue& delimiter,
285
                     google::protobuf::Arena* absl_nonnull arena,
286
                     Value* absl_nonnull result) const;
287
  absl::StatusOr<Value> Split(const StringValue& delimiter,
288
                              google::protobuf::Arena* absl_nonnull arena) const;
289
290
  // Replaces occurrences of `needle` with `replacement`. If `limit` is provided
291
  // and non-negative, only the first `limit` occurrences are replaced.
292
  absl::Status Replace(const StringValue& needle,
293
                       const StringValue& replacement, int64_t limit,
294
                       google::protobuf::Arena* absl_nonnull arena,
295
                       Value* absl_nonnull result) const;
296
  absl::StatusOr<Value> Replace(const StringValue& needle,
297
                                const StringValue& replacement, int64_t limit,
298
                                google::protobuf::Arena* absl_nonnull arena) const;
299
  absl::Status Replace(const StringValue& needle,
300
                       const StringValue& replacement,
301
                       google::protobuf::Arena* absl_nonnull arena,
302
                       Value* absl_nonnull result) const;
303
  absl::StatusOr<Value> Replace(const StringValue& needle,
304
                                const StringValue& replacement,
305
                                google::protobuf::Arena* absl_nonnull arena) const;
306
307
  // Returns the character at `pos` as a new `StringValue`. `pos` is a
308
  // 0-based index based on Unicode code points. Returns `ErrorValue` if `pos`
309
  // is out of range.
310
  Value CharAt(int64_t pos) const;
311
312
  absl::optional<absl::string_view> TryFlat() const
313
0
      ABSL_ATTRIBUTE_LIFETIME_BOUND {
314
0
    return value_.TryFlat();
315
0
  }
316
317
19.4k
  std::string ToString() const { return value_.ToString(); }
318
319
0
  void CopyToString(std::string* absl_nonnull out) const {
320
0
    value_.CopyToString(out);
321
0
  }
322
323
0
  void AppendToString(std::string* absl_nonnull out) const {
324
0
    value_.AppendToString(out);
325
0
  }
326
327
0
  absl::Cord ToCord() const { return value_.ToCord(); }
328
329
0
  void CopyToCord(absl::Cord* absl_nonnull out) const {
330
0
    value_.CopyToCord(out);
331
0
  }
332
333
0
  void AppendToCord(absl::Cord* absl_nonnull out) const {
334
0
    value_.AppendToCord(out);
335
0
  }
336
337
  absl::string_view ToStringView(
338
      std::string* absl_nonnull scratch
339
0
          ABSL_ATTRIBUTE_LIFETIME_BOUND) const ABSL_ATTRIBUTE_LIFETIME_BOUND {
340
0
    return value_.ToStringView(scratch);
341
0
  }
342
343
  template <typename H>
344
1.54k
  friend H AbslHashValue(H state, const StringValue& string) {
345
1.54k
    return H::combine(std::move(state), string.value_);
346
1.54k
  }
347
348
42
  friend bool operator==(const StringValue& lhs, const StringValue& rhs) {
349
42
    return lhs.value_ == rhs.value_;
350
42
  }
351
352
0
  friend bool operator<(const StringValue& lhs, const StringValue& rhs) {
353
0
    return lhs.value_ < rhs.value_;
354
0
  }
355
356
 private:
357
  friend class common_internal::ValueMixin<StringValue>;
358
  friend absl::string_view common_internal::LegacyStringValue(
359
      const StringValue& value, bool stable, google::protobuf::Arena* absl_nonnull arena);
360
  friend struct ArenaTraits<StringValue>;
361
362
  explicit StringValue(common_internal::ByteString value) noexcept
363
2.17k
      : value_(std::move(value)) {}
364
365
  common_internal::ByteString value_;
366
};
367
368
0
inline void swap(StringValue& lhs, StringValue& rhs) noexcept { lhs.swap(rhs); }
369
370
3.12k
inline bool operator==(const StringValue& lhs, absl::string_view rhs) {
371
3.12k
  return lhs.Equals(rhs);
372
3.12k
}
373
374
0
inline bool operator==(absl::string_view lhs, const StringValue& rhs) {
375
0
  return rhs == lhs;
376
0
}
377
378
0
inline bool operator==(const StringValue& lhs, const absl::Cord& rhs) {
379
0
  return lhs.Equals(rhs);
380
0
}
381
382
0
inline bool operator==(const absl::Cord& lhs, const StringValue& rhs) {
383
0
  return rhs == lhs;
384
0
}
385
386
0
inline bool operator!=(const StringValue& lhs, absl::string_view rhs) {
387
0
  return !operator==(lhs, rhs);
388
0
}
389
390
0
inline bool operator!=(absl::string_view lhs, const StringValue& rhs) {
391
0
  return !operator==(lhs, rhs);
392
0
}
393
394
0
inline bool operator!=(const StringValue& lhs, const absl::Cord& rhs) {
395
0
  return !operator==(lhs, rhs);
396
0
}
397
398
0
inline bool operator!=(const absl::Cord& lhs, const StringValue& rhs) {
399
0
  return !operator==(lhs, rhs);
400
0
}
401
402
0
inline bool operator!=(const StringValue& lhs, const StringValue& rhs) {
403
0
  return !operator==(lhs, rhs);
404
0
}
405
406
0
inline bool operator<(const StringValue& lhs, absl::string_view rhs) {
407
0
  return lhs.Compare(rhs) < 0;
408
0
}
409
410
0
inline bool operator<(absl::string_view lhs, const StringValue& rhs) {
411
0
  return rhs.Compare(lhs) > 0;
412
0
}
413
414
0
inline bool operator<(const StringValue& lhs, const absl::Cord& rhs) {
415
0
  return lhs.Compare(rhs) < 0;
416
0
}
417
418
0
inline bool operator<(const absl::Cord& lhs, const StringValue& rhs) {
419
0
  return rhs.Compare(lhs) > 0;
420
0
}
421
422
0
inline std::ostream& operator<<(std::ostream& out, const StringValue& value) {
423
0
  return out << value.DebugString();
424
0
}
425
426
inline StringValue StringValue::From(const char* absl_nullable value,
427
                                     google::protobuf::Arena* absl_nonnull arena
428
0
                                         ABSL_ATTRIBUTE_LIFETIME_BOUND) {
429
0
  return From(absl::NullSafeStringView(value), arena);
430
0
}
431
432
inline StringValue StringValue::From(absl::string_view value,
433
                                     google::protobuf::Arena* absl_nonnull arena
434
1
                                         ABSL_ATTRIBUTE_LIFETIME_BOUND) {
435
1
  ABSL_DCHECK(arena != nullptr);
436
437
1
  return StringValue(arena, value);
438
1
}
439
440
0
inline StringValue StringValue::From(const absl::Cord& value) {
441
0
  return StringValue(value);
442
0
}
443
444
inline StringValue StringValue::From(std::string&& value,
445
                                     google::protobuf::Arena* absl_nonnull arena
446
0
                                         ABSL_ATTRIBUTE_LIFETIME_BOUND) {
447
0
  ABSL_DCHECK(arena != nullptr);
448
449
0
  return StringValue(arena, std::move(value));
450
0
}
451
452
inline StringValue StringValue::Wrap(absl::string_view value,
453
                                     google::protobuf::Arena* absl_nullable arena
454
0
                                         ABSL_ATTRIBUTE_LIFETIME_BOUND) {
455
0
  ABSL_DCHECK(arena != nullptr);
456
0
457
0
  return StringValue(Borrower::Arena(arena), value);
458
0
}
459
460
0
inline StringValue StringValue::WrapUnsafe(absl::string_view value) {
461
0
  return StringValue(common_internal::ByteString::FromExternal(value));
462
0
}
463
464
0
inline StringValue StringValue::Wrap(const absl::Cord& value) {
465
0
  return StringValue(value);
466
0
}
467
468
namespace common_internal {
469
470
inline absl::string_view LegacyStringValue(const StringValue& value,
471
                                           bool stable,
472
651
                                           google::protobuf::Arena* absl_nonnull arena) {
473
651
  return LegacyByteString(value.value_, stable, arena);
474
651
}
475
476
}  // namespace common_internal
477
478
template <>
479
struct ArenaTraits<StringValue> {
480
  using constructible = std::true_type;
481
482
16.3k
  static bool trivially_destructible(const StringValue& value) {
483
16.3k
    return ArenaTraits<>::trivially_destructible(value.value_);
484
16.3k
  }
485
};
486
487
}  // namespace cel
488
489
#endif  // THIRD_PARTY_CEL_CPP_COMMON_VALUES_STRING_VALUE_H_