Coverage Report

Created: 2025-11-29 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/source.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
#ifndef THIRD_PARTY_CEL_CPP_COMMON_SOURCE_H_
16
#define THIRD_PARTY_CEL_CPP_COMMON_SOURCE_H_
17
18
#include <cstdint>
19
#include <memory>
20
#include <string>
21
#include <utility>
22
23
#include "absl/base/attributes.h"
24
#include "absl/base/nullability.h"
25
#include "absl/status/statusor.h"
26
#include "absl/strings/cord.h"
27
#include "absl/strings/string_view.h"
28
#include "absl/types/optional.h"
29
#include "absl/types/span.h"
30
#include "absl/types/variant.h"
31
32
namespace cel {
33
34
namespace common_internal {
35
class SourceImpl;
36
}  // namespace common_internal
37
38
class Source;
39
40
// SourcePosition represents an offset in source text.
41
using SourcePosition = int32_t;
42
43
// SourceRange represents a range of positions, where `begin` is inclusive and
44
// `end` is exclusive.
45
struct SourceRange final {
46
  SourcePosition begin = -1;
47
  SourcePosition end = -1;
48
};
49
50
0
inline bool operator==(const SourceRange& lhs, const SourceRange& rhs) {
51
0
  return lhs.begin == rhs.begin && lhs.end == rhs.end;
52
0
}
53
54
0
inline bool operator!=(const SourceRange& lhs, const SourceRange& rhs) {
55
0
  return !operator==(lhs, rhs);
56
0
}
57
58
// `SourceLocation` is a representation of a line and column in source text.
59
struct SourceLocation final {
60
  int32_t line = -1;    // 1-based line number.
61
  int32_t column = -1;  // 0-based column number.
62
};
63
64
0
inline bool operator==(const SourceLocation& lhs, const SourceLocation& rhs) {
65
0
  return lhs.line == rhs.line && lhs.column == rhs.column;
66
0
}
67
68
0
inline bool operator!=(const SourceLocation& lhs, const SourceLocation& rhs) {
69
0
  return !operator==(lhs, rhs);
70
0
}
71
72
// `SourceContentView` is a view of the content owned by `Source`, which is a
73
// sequence of Unicode code points.
74
class SourceContentView final {
75
 public:
76
  SourceContentView(const SourceContentView&) = default;
77
  SourceContentView(SourceContentView&&) = default;
78
  SourceContentView& operator=(const SourceContentView&) = default;
79
  SourceContentView& operator=(SourceContentView&&) = default;
80
81
  SourcePosition size() const;
82
83
  bool empty() const;
84
85
  char32_t at(SourcePosition position) const;
86
87
  std::string ToString(SourcePosition begin, SourcePosition end) const;
88
43.1k
  std::string ToString(SourcePosition begin) const {
89
43.1k
    return ToString(begin, size());
90
43.1k
  }
91
0
  std::string ToString() const { return ToString(0); }
92
93
  void AppendToString(std::string& dest) const;
94
95
 private:
96
  friend class Source;
97
98
  constexpr SourceContentView() = default;
99
100
  constexpr explicit SourceContentView(absl::Span<const char> view)
101
40.4k
      : view_(view) {}
102
103
  constexpr explicit SourceContentView(absl::Span<const uint8_t> view)
104
3.48k
      : view_(view) {}
105
106
  constexpr explicit SourceContentView(absl::Span<const char16_t> view)
107
7.67k
      : view_(view) {}
108
109
  constexpr explicit SourceContentView(absl::Span<const char32_t> view)
110
11.0k
      : view_(view) {}
111
112
  absl::variant<absl::Span<const char>, absl::Span<const uint8_t>,
113
                absl::Span<const char16_t>, absl::Span<const char32_t>>
114
      view_;
115
};
116
117
// `Source` represents the source expression.
118
class Source {
119
 public:
120
  using ContentView = SourceContentView;
121
122
  Source(const Source&) = delete;
123
  Source(Source&&) = delete;
124
125
4.20k
  virtual ~Source() = default;
126
127
  Source& operator=(const Source&) = delete;
128
  Source& operator=(Source&&) = delete;
129
130
  virtual absl::string_view description() const
131
      ABSL_ATTRIBUTE_LIFETIME_BOUND = 0;
132
133
  // Maps a `SourcePosition` to a `SourceLocation`. Returns an empty
134
  // `absl::optional` when `SourcePosition` is invalid or the information
135
  // required to perform the mapping is not present.
136
  absl::optional<SourceLocation> GetLocation(SourcePosition position) const;
137
138
  // Maps a `SourceLocation` to a `SourcePosition`. Returns an empty
139
  // `absl::optional` when `SourceLocation` is invalid or the information
140
  // required to perform the mapping is not present.
141
  absl::optional<SourcePosition> GetPosition(
142
      const SourceLocation& location) const;
143
144
  absl::optional<std::string> Snippet(int32_t line) const;
145
146
  // Formats an annotated snippet highlighting an error at location, e.g.
147
  //
148
  // "\n | $SOURCE_SNIPPET" +
149
  // "\n | .......^"
150
  //
151
  // Returns an empty string if location is not a valid location in this source.
152
  std::string DisplayErrorLocation(SourceLocation location) const;
153
154
  // Returns a view of the underlying expression text, if present.
155
  virtual ContentView content() const ABSL_ATTRIBUTE_LIFETIME_BOUND = 0;
156
157
  // Returns a `absl::Span` of `SourcePosition` which represent the positions
158
  // where new lines occur.
159
  virtual absl::Span<const SourcePosition> line_offsets() const
160
      ABSL_ATTRIBUTE_LIFETIME_BOUND = 0;
161
162
 protected:
163
0
  static constexpr ContentView EmptyContentView() { return ContentView(); }
164
40.4k
  static constexpr ContentView MakeContentView(absl::Span<const char> view) {
165
40.4k
    return ContentView(view);
166
40.4k
  }
167
3.48k
  static constexpr ContentView MakeContentView(absl::Span<const uint8_t> view) {
168
3.48k
    return ContentView(view);
169
3.48k
  }
170
  static constexpr ContentView MakeContentView(
171
7.67k
      absl::Span<const char16_t> view) {
172
7.67k
    return ContentView(view);
173
7.67k
  }
174
  static constexpr ContentView MakeContentView(
175
11.0k
      absl::Span<const char32_t> view) {
176
11.0k
    return ContentView(view);
177
11.0k
  }
178
179
 private:
180
  friend class common_internal::SourceImpl;
181
182
4.20k
  Source() = default;
183
184
  absl::optional<SourcePosition> FindLinePosition(int32_t line) const;
185
186
  absl::optional<std::pair<int32_t, SourcePosition>> FindLine(
187
      SourcePosition position) const;
188
};
189
190
using SourcePtr = std::unique_ptr<Source>;
191
192
absl::StatusOr<absl_nonnull SourcePtr> NewSource(
193
    absl::string_view content, std::string description = "<input>");
194
195
absl::StatusOr<absl_nonnull SourcePtr> NewSource(
196
    const absl::Cord& content, std::string description = "<input>");
197
198
}  // namespace cel
199
200
#endif  // THIRD_PARTY_CEL_CPP_COMMON_SOURCE_H_