Coverage Report

Created: 2026-04-21 06:48

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/proc/self/cwd/common/ast/metadata.cc
Line
Count
Source
1
// Copyright 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
//     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
#include "common/ast/metadata.h"
16
17
#include <cstddef>
18
#include <memory>
19
#include <string>
20
#include <utility>
21
#include <variant>
22
#include <vector>
23
24
#include "absl/base/no_destructor.h"
25
#include "absl/base/nullability.h"
26
#include "absl/functional/overload.h"
27
#include "absl/log/absl_check.h"
28
#include "absl/strings/str_cat.h"
29
#include "absl/types/variant.h"
30
31
namespace cel {
32
33
namespace {
34
35
0
const TypeSpec& DefaultTypeSpec() {
36
0
  static absl::NoDestructor<TypeSpec> type(TypeSpecKind{UnsetTypeSpec()});
37
0
  return *type;
38
0
}
39
40
0
std::string FormatPrimitive(PrimitiveType t) {
41
0
  switch (t) {
42
0
    case PrimitiveType::kBool:
43
0
      return "bool";
44
0
    case PrimitiveType::kInt64:
45
0
      return "int";
46
0
    case PrimitiveType::kUint64:
47
0
      return "uint";
48
0
    case PrimitiveType::kDouble:
49
0
      return "double";
50
0
    case PrimitiveType::kString:
51
0
      return "string";
52
0
    case PrimitiveType::kBytes:
53
0
      return "bytes";
54
0
    default:
55
0
      return "*unspecified primitive*";
56
0
  }
57
0
}
58
59
0
std::string FormatWellKnown(WellKnownTypeSpec t) {
60
0
  switch (t) {
61
0
    case WellKnownTypeSpec::kAny:
62
0
      return "google.protobuf.Any";
63
0
    case WellKnownTypeSpec::kDuration:
64
0
      return "google.protobuf.Duration";
65
0
    case WellKnownTypeSpec::kTimestamp:
66
0
      return "google.protobuf.Timestamp";
67
0
    default:
68
0
      return "*unspecified well known*";
69
0
  }
70
0
}
71
72
using FormatIns = std::variant<const TypeSpec* absl_nonnull, std::string>;
73
using FormatStack = std::vector<FormatIns>;
74
75
void HandleFormatTypeSpec(const TypeSpec& t, FormatStack& stack,
76
0
                          std::string* out) {
77
0
  if (t.has_dyn()) {
78
0
    absl::StrAppend(out, "dyn");
79
0
  } else if (t.has_null()) {
80
0
    absl::StrAppend(out, "null");
81
0
  } else if (t.has_primitive()) {
82
0
    absl::StrAppend(out, FormatPrimitive(t.primitive()));
83
0
  } else if (t.has_wrapper()) {
84
0
    absl::StrAppend(out, "wrapper(", FormatPrimitive(t.wrapper()), ")");
85
0
  } else if (t.has_well_known()) {
86
0
    absl::StrAppend(out, FormatWellKnown(t.well_known()));
87
0
    return;
88
0
  } else if (t.has_abstract_type()) {
89
0
    const auto& abs_type = t.abstract_type();
90
0
    if (abs_type.parameter_types().empty()) {
91
0
      absl::StrAppend(out, abs_type.name());
92
0
      return;
93
0
    }
94
0
    absl::StrAppend(out, abs_type.name(), "(");
95
0
    stack.push_back(")");
96
0
    for (size_t i = abs_type.parameter_types().size(); i > 0; --i) {
97
0
      stack.push_back(&abs_type.parameter_types()[i - 1]);
98
0
      if (i > 1) {
99
0
        stack.push_back(", ");
100
0
      }
101
0
    }
102
103
0
  } else if (t.has_type()) {
104
0
    if (t.type() == TypeSpec()) {
105
0
      absl::StrAppend(out, "type");
106
0
      return;
107
0
    }
108
0
    absl::StrAppend(out, "type(");
109
0
    stack.push_back(")");
110
0
    stack.push_back(&t.type());
111
0
  } else if (t.has_message_type()) {
112
0
    absl::StrAppend(out, t.message_type().type());
113
0
  } else if (t.has_type_param()) {
114
0
    absl::StrAppend(out, t.type_param().type());
115
0
  } else if (t.has_list_type()) {
116
0
    absl::StrAppend(out, "list(");
117
0
    stack.push_back(")");
118
0
    stack.push_back(&t.list_type().elem_type());
119
0
  } else if (t.has_map_type()) {
120
0
    absl::StrAppend(out, "map(");
121
0
    stack.push_back(")");
122
0
    stack.push_back(&t.map_type().value_type());
123
0
    stack.push_back(", ");
124
0
    stack.push_back(&t.map_type().key_type());
125
0
  } else {
126
0
    absl::StrAppend(out, "*error*");
127
0
  }
128
0
}
129
130
0
TypeSpecKind CopyImpl(const TypeSpecKind& other) {
131
0
  return absl::visit(
132
0
      absl::Overload(
133
0
          [](const std::unique_ptr<TypeSpec>& other) -> TypeSpecKind {
134
0
            if (other == nullptr) {
135
0
              return std::make_unique<TypeSpec>();
136
0
            }
137
0
            return std::make_unique<TypeSpec>(*other);
138
0
          },
139
0
          [](const auto& other) -> TypeSpecKind {
140
            // Other variants define copy ctor.
141
0
            return other;
142
0
          }),
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<std::__1::monostate>(std::__1::monostate const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::DynTypeSpec>(cel::DynTypeSpec const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::NullTypeSpec>(cel::NullTypeSpec const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::PrimitiveType>(cel::PrimitiveType const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::PrimitiveTypeWrapper>(cel::PrimitiveTypeWrapper const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::WellKnownTypeSpec>(cel::WellKnownTypeSpec const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::ListTypeSpec>(cel::ListTypeSpec const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::MapTypeSpec>(cel::MapTypeSpec const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::FunctionTypeSpec>(cel::FunctionTypeSpec const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::MessageTypeSpec>(cel::MessageTypeSpec const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::ParamTypeSpec>(cel::ParamTypeSpec const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::ErrorTypeSpec>(cel::ErrorTypeSpec const&) const
Unexecuted instantiation: metadata.cc:std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> cel::(anonymous namespace)::CopyImpl(std::__1::variant<std::__1::monostate, cel::DynTypeSpec, cel::NullTypeSpec, cel::PrimitiveType, cel::PrimitiveTypeWrapper, cel::WellKnownTypeSpec, cel::ListTypeSpec, cel::MapTypeSpec, cel::FunctionTypeSpec, cel::MessageTypeSpec, cel::ParamTypeSpec, std::__1::unique_ptr<cel::TypeSpec, std::__1::default_delete<cel::TypeSpec> >, cel::ErrorTypeSpec, cel::AbstractType> const&)::$_1::operator()<cel::AbstractType>(cel::AbstractType const&) const
143
0
      other);
144
0
}
145
146
}  // namespace
147
148
0
const ExtensionSpec::Version& ExtensionSpec::Version::DefaultInstance() {
149
0
  static absl::NoDestructor<Version> instance;
150
0
  return *instance;
151
0
}
152
153
0
const ExtensionSpec& ExtensionSpec::DefaultInstance() {
154
0
  static absl::NoDestructor<ExtensionSpec> instance;
155
0
  return *instance;
156
0
}
157
158
ExtensionSpec::ExtensionSpec(const ExtensionSpec& other)
159
0
    : id_(other.id_),
160
0
      affected_components_(other.affected_components_),
161
0
      version_(other.version_ == nullptr
162
0
                   ? nullptr
163
0
                   : std::make_unique<Version>(*other.version_)) {}
164
165
0
ExtensionSpec& ExtensionSpec::operator=(const ExtensionSpec& other) {
166
0
  id_ = other.id_;
167
0
  affected_components_ = other.affected_components_;
168
0
  if (other.version_ != nullptr) {
169
0
    version_ = std::make_unique<Version>(other.version());
170
0
  } else {
171
0
    version_ = nullptr;
172
0
  }
173
0
  return *this;
174
0
}
175
176
0
const TypeSpec& ListTypeSpec::elem_type() const {
177
0
  if (elem_type_ != nullptr) {
178
0
    return *elem_type_;
179
0
  }
180
0
  return DefaultTypeSpec();
181
0
}
182
183
0
bool ListTypeSpec::operator==(const ListTypeSpec& other) const {
184
0
  return elem_type() == other.elem_type();
185
0
}
186
187
0
const TypeSpec& MapTypeSpec::key_type() const {
188
0
  if (key_type_ != nullptr) {
189
0
    return *key_type_;
190
0
  }
191
0
  return DefaultTypeSpec();
192
0
}
193
194
0
const TypeSpec& MapTypeSpec::value_type() const {
195
0
  if (value_type_ != nullptr) {
196
0
    return *value_type_;
197
0
  }
198
0
  return DefaultTypeSpec();
199
0
}
200
201
0
bool MapTypeSpec::operator==(const MapTypeSpec& other) const {
202
0
  return key_type() == other.key_type() && value_type() == other.value_type();
203
0
}
204
205
0
const TypeSpec& FunctionTypeSpec::result_type() const {
206
0
  if (result_type_ != nullptr) {
207
0
    return *result_type_;
208
0
  }
209
0
  return DefaultTypeSpec();
210
0
}
211
212
0
bool FunctionTypeSpec::operator==(const FunctionTypeSpec& other) const {
213
0
  return result_type() == other.result_type() && arg_types_ == other.arg_types_;
214
0
}
215
216
0
const TypeSpec& TypeSpec::type() const {
217
0
  auto* value = absl::get_if<std::unique_ptr<TypeSpec>>(&type_kind_);
218
0
  if (value != nullptr) {
219
0
    if (*value != nullptr) return **value;
220
0
  }
221
0
  return DefaultTypeSpec();
222
0
}
223
224
TypeSpec::TypeSpec(const TypeSpec& other)
225
0
    : type_kind_(CopyImpl(other.type_kind_)) {}
226
227
0
TypeSpec& TypeSpec::operator=(const TypeSpec& other) {
228
0
  type_kind_ = CopyImpl(other.type_kind_);
229
0
  return *this;
230
0
}
231
232
FunctionTypeSpec::FunctionTypeSpec(const FunctionTypeSpec& other)
233
0
    : result_type_(std::make_unique<TypeSpec>(other.result_type())),
234
0
      arg_types_(other.arg_types()) {}
235
236
0
FunctionTypeSpec& FunctionTypeSpec::operator=(const FunctionTypeSpec& other) {
237
0
  result_type_ = std::make_unique<TypeSpec>(other.result_type());
238
0
  arg_types_ = other.arg_types();
239
0
  return *this;
240
0
}
241
242
0
std::string FormatTypeSpec(const TypeSpec& t) {
243
  // Use a stack to avoid recursion.
244
  // Probably overly defensive, but fuzzers will often notice the recursion
245
  // and try to trigger it.
246
0
  std::string out;
247
0
  FormatStack seq;
248
0
  seq.push_back(&t);
249
0
  while (!seq.empty()) {
250
0
    FormatIns ins = std::move(seq.back());
251
0
    seq.pop_back();
252
0
    if (std::holds_alternative<std::string>(ins)) {
253
0
      absl::StrAppend(&out, std::get<std::string>(ins));
254
0
      continue;
255
0
    }
256
0
    ABSL_DCHECK(std::holds_alternative<const TypeSpec*>(ins));
257
0
    HandleFormatTypeSpec(*std::get<const TypeSpec*>(ins), seq, &out);
258
0
  }
259
0
  return out;
260
0
}
261
262
}  // namespace cel