Coverage Report

Created: 2026-10-09 06:57

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