blob: abeb4275014365f97b265b9cf06028cd527ecda7 [file] [log] [blame]
Protobuf Team Bot306123e2022-11-04 09:25:30 -07001/*
2 * Copyright (c) 2009-2021, Google LLC
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of Google LLC nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#ifndef UPB_PROTOS_PROTOS_H_
29#define UPB_PROTOS_PROTOS_H_
30
31#include <type_traits>
Protobuf Team Botccdfaf72023-03-02 17:49:04 -080032#include <vector>
Protobuf Team Bot306123e2022-11-04 09:25:30 -070033
34#include "absl/status/status.h"
35#include "absl/status/statusor.h"
Protobuf Team Bot45462532023-05-07 09:58:19 -070036#include "upb/message/copy.h"
Eric Salo27d70ed2022-11-16 22:13:41 -080037#include "upb/message/extension_internal.h"
38#include "upb/mini_table/types.h"
Protobuf Team Bot306123e2022-11-04 09:25:30 -070039#include "upb/upb.hpp"
Eric Salo27d70ed2022-11-16 22:13:41 -080040#include "upb/wire/decode.h"
41#include "upb/wire/encode.h"
Protobuf Team Bot306123e2022-11-04 09:25:30 -070042
43namespace protos {
44
45using Arena = ::upb::Arena;
46class ExtensionRegistry;
47
48template <typename T>
49using Proxy = std::conditional_t<std::is_const<T>::value,
50 typename std::remove_const_t<T>::CProxy,
51 typename T::Proxy>;
52
53// Provides convenient access to Proxy and CProxy message types.
54//
55// Using rebinding and handling of const, Ptr<Message> and Ptr<const Message>
56// allows copying const with T* const and avoids using non-copyable Proxy types
57// directly.
58template <typename T>
59class Ptr final {
60 public:
61 Ptr() = delete;
62
63 // Implicit conversions
64 Ptr(T* m) : p_(m) {} // NOLINT
65 Ptr(const Proxy<T>* p) : p_(*p) {} // NOLINT
66 Ptr(Proxy<T> p) : p_(p) {} // NOLINT
67 Ptr(const Ptr& m) = default;
68
69 Ptr& operator=(Ptr v) & {
70 Proxy<T>::Rebind(p_, v.p_);
71 return *this;
72 }
73
74 Proxy<T> operator*() const { return p_; }
75 Proxy<T>* operator->() const {
76 return const_cast<Proxy<T>*>(std::addressof(p_));
77 }
78
79#ifdef __clang__
80#pragma clang diagnostic push
81#pragma clang diagnostic ignored "-Wclass-conversion"
82#endif
83 template <typename U = T, std::enable_if_t<!std::is_const<U>::value, int> = 0>
84 operator Ptr<const T>() const {
85 Proxy<const T> p(p_);
86 return Ptr<const T>(&p);
87 }
88#ifdef __clang__
89#pragma clang diagnostic pop
90#endif
91
92 private:
93 Ptr(void* msg, upb_Arena* arena) : p_(msg, arena) {} // NOLINT
94
95 friend class Ptr<const T>;
96 friend typename T::Access;
97
98 Proxy<T> p_;
99};
100
101inline absl::string_view UpbStrToStringView(upb_StringView str) {
102 return absl::string_view(str.data, str.size);
103}
104
105// TODO: update bzl and move to upb runtime / protos.cc.
106inline upb_StringView UpbStrFromStringView(absl::string_view str,
107 upb_Arena* arena) {
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700108 const size_t str_size = str.size();
Eric Saloe932f792022-11-20 20:10:54 -0800109 char* buffer = static_cast<char*>(upb_Arena_Malloc(arena, str_size));
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700110 memcpy(buffer, str.data(), str_size);
111 return upb_StringView_FromDataAndSize(buffer, str_size);
112}
113
114template <typename T>
115typename T::Proxy CreateMessage(::protos::Arena& arena) {
116 return typename T::Proxy(upb_Message_New(T::minitable(), arena.ptr()),
117 arena.ptr());
118}
119
Protobuf Team Bot3286f942023-03-07 07:09:44 -0800120template <typename T>
121typename T::Proxy CloneMessage(Ptr<T> message, upb::Arena& arena) {
122 return typename T::Proxy(
Protobuf Team Bot45462532023-05-07 09:58:19 -0700123 upb_Message_DeepClone(message->msg(), T::minitable(), arena.ptr()),
124 arena.ptr());
Protobuf Team Bot3286f942023-03-07 07:09:44 -0800125}
126
Protobuf Team Bot496e2fd2023-06-23 10:56:29 -0700127template <typename T>
128void DeepCopy(Ptr<const T> source_message, Ptr<T> target_message) {
129 upb_Message_DeepCopy(
130 target_message->msg(), source_message->msg(), T::minitable(),
131 static_cast<upb_Arena*>(target_message->GetInternalArena()));
132}
133
134template <typename T>
135void DeepCopy(Ptr<const T> source_message, T* target_message) {
136 DeepCopy(source_message, protos::Ptr(target_message));
137}
138
139template <typename T>
140void DeepCopy(const T* source_message, Ptr<T> target_message) {
141 DeepCopy(protos::Ptr(source_message), target_message);
142}
143
144template <typename T>
145void DeepCopy(const T* source_message, T* target_message) {
146 DeepCopy(protos::Ptr(source_message), protos::Ptr(target_message));
147}
148
149template <typename T>
150void ClearMessage(Ptr<T> message) {
151 static_assert(!std::is_const_v<T>, "");
152 upb_Message_Clear(message->msg(), T::minitable());
153}
154
155template <typename T>
156void ClearMessage(T* message) {
157 ClearMessage(protos::Ptr(message));
158}
159
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700160// begin:github_only
161// This type exists to work around an absl type that has not yet been
162// released.
163struct SourceLocation {
164 static SourceLocation current() { return {}; }
165 absl::string_view file_name() { return "<unknown>"; }
166 int line() { return 0; }
167};
168// end:github_only
169
170// begin:google_only
171// using SourceLocation = absl::SourceLocation;
172// end:google_only
173
174absl::Status MessageAllocationError(
175 SourceLocation loc = SourceLocation::current());
176
177absl::Status ExtensionNotFoundError(
178 int extension_number, SourceLocation loc = SourceLocation::current());
179
180absl::Status MessageDecodeError(upb_DecodeStatus status,
181 SourceLocation loc = SourceLocation::current());
182
183absl::Status MessageEncodeError(upb_EncodeStatus status,
184 SourceLocation loc = SourceLocation::current());
185
186namespace internal {
187template <typename T>
188T CreateMessage() {
189 return T();
190}
191
192template <typename T>
193typename T::Proxy CreateMessageProxy(void* msg, upb_Arena* arena) {
194 return typename T::Proxy(msg, arena);
195}
196
197template <typename T>
198typename T::CProxy CreateMessage(upb_Message* msg) {
199 return typename T::CProxy(msg);
200}
201
202class ExtensionMiniTableProvider {
203 public:
Protobuf Team Botccdfaf72023-03-02 17:49:04 -0800204 constexpr explicit ExtensionMiniTableProvider(
205 const upb_MiniTableExtension* mini_table_ext)
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700206 : mini_table_ext_(mini_table_ext) {}
Eric Salo75907f72022-11-07 11:10:10 -0800207 const upb_MiniTableExtension* mini_table_ext() const {
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700208 return mini_table_ext_;
209 }
210
211 private:
Eric Salo75907f72022-11-07 11:10:10 -0800212 const upb_MiniTableExtension* mini_table_ext_;
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700213};
214
215// -------------------------------------------------------------------
216// ExtensionIdentifier
217// This is the type of actual extension objects. E.g. if you have:
218// extend Foo {
219// optional MyExtension bar = 1234;
220// }
221// then "bar" will be defined in C++ as:
222// ExtensionIdentifier<Foo, MyExtension> bar(&namespace_bar_ext);
223template <typename ExtendeeType, typename ExtensionType>
224class ExtensionIdentifier : public ExtensionMiniTableProvider {
225 public:
226 using Extension = ExtensionType;
227 using Extendee = ExtendeeType;
228
Protobuf Team Botccdfaf72023-03-02 17:49:04 -0800229 constexpr explicit ExtensionIdentifier(
230 const upb_MiniTableExtension* mini_table_ext)
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700231 : ExtensionMiniTableProvider(mini_table_ext) {}
232};
233
234template <typename T>
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700235void* GetInternalMsg(const T* message) {
236 return message->msg();
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700237}
238
239template <typename T>
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700240void* GetInternalMsg(Ptr<T> message) {
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700241 return message->msg();
242}
243
244template <typename T>
245upb_Arena* GetArena(const T& message) {
246 return static_cast<upb_Arena*>(message.GetInternalArena());
247}
248
249template <typename T>
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700250upb_Arena* GetArena(Ptr<T> message) {
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700251 return static_cast<upb_Arena*>(message->GetInternalArena());
252}
253
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700254template <typename T>
255const upb_MiniTable* GetMiniTable(const T*) {
256 return T::minitable();
257}
258
259template <typename T>
260const upb_MiniTable* GetMiniTable(Ptr<T>) {
261 return T::minitable();
262}
263
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700264upb_ExtensionRegistry* GetUpbExtensions(
265 const ExtensionRegistry& extension_registry);
266
267absl::StatusOr<absl::string_view> Serialize(const upb_Message* message,
268 const upb_MiniTable* mini_table,
269 upb_Arena* arena, int options);
270
271} // namespace internal
272
273class ExtensionRegistry {
274 public:
275 ExtensionRegistry(
Protobuf Team Botccdfaf72023-03-02 17:49:04 -0800276 const std::vector<const ::protos::internal::ExtensionMiniTableProvider*>&
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700277 extensions,
278 const upb::Arena& arena)
279 : registry_(upb_ExtensionRegistry_New(arena.ptr())) {
280 if (registry_) {
281 for (const auto& ext_provider : extensions) {
282 const auto* ext = ext_provider->mini_table_ext();
283 bool success = upb_ExtensionRegistry_AddArray(registry_, &ext, 1);
284 if (!success) {
285 registry_ = nullptr;
286 break;
287 }
288 }
289 }
290 }
291
292 private:
293 friend upb_ExtensionRegistry* ::protos::internal::GetUpbExtensions(
294 const ExtensionRegistry& extension_registry);
295 upb_ExtensionRegistry* registry_;
296};
297
298template <typename T>
299using EnableIfProtosClass = std::enable_if_t<
300 std::is_base_of<typename T::Access, T>::value &&
301 std::is_base_of<typename T::Access, typename T::ExtendableType>::value>;
302
303template <typename T>
304using EnableIfMutableProto = std::enable_if_t<!std::is_const<T>::value>;
305
306template <typename T, typename Extendee, typename Extension,
307 typename = EnableIfProtosClass<T>>
308bool HasExtension(
309 const T& message,
310 const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
311 return _upb_Message_Getext(message.msg(), id.mini_table_ext()) != nullptr;
312}
313
314template <typename T, typename Extendee, typename Extension,
315 typename = EnableIfProtosClass<T>>
316bool HasExtension(
317 const Ptr<T>& message,
318 const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
319 return _upb_Message_Getext(message->msg(), id.mini_table_ext()) != nullptr;
320}
321
322template <typename T, typename Extendee, typename Extension,
323 typename = EnableIfProtosClass<T>, typename = EnableIfMutableProto<T>>
324void ClearExtension(
325 const Ptr<T>& message,
326 const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
Eric Salo3bac8782022-12-07 18:12:14 -0800327 _upb_Message_ClearExtensionField(message->msg(), id.mini_table_ext());
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700328}
329
330template <typename T, typename Extendee, typename Extension,
331 typename = EnableIfProtosClass<T>>
332void ClearExtension(
333 const T& message,
334 const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
Eric Salo3bac8782022-12-07 18:12:14 -0800335 _upb_Message_ClearExtensionField(message.msg(), id.mini_table_ext());
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700336}
337
338template <typename T, typename Extendee, typename Extension,
339 typename = EnableIfProtosClass<T>>
340absl::Status SetExtension(
341 const T& message,
342 const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id,
343 Extension& value) {
344 auto* message_arena = static_cast<upb_Arena*>(message.GetInternalArena());
345 upb_Message_Extension* msg_ext = _upb_Message_GetOrCreateExtension(
346 message.msg(), id.mini_table_ext(), message_arena);
347 if (!msg_ext) {
348 return MessageAllocationError();
349 }
350 auto* extension_arena = static_cast<upb_Arena*>(value.GetInternalArena());
351 if (message_arena != extension_arena) {
352 upb_Arena_Fuse(message_arena, extension_arena);
353 }
354 msg_ext->data.ptr = value.msg();
355 return absl::OkStatus();
356}
357
358template <typename T, typename Extendee, typename Extension,
359 typename = EnableIfProtosClass<T>, typename = EnableIfMutableProto<T>>
360absl::Status SetExtension(
361 const Ptr<T>& message,
362 const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id,
363 Extension& value) {
364 auto* message_arena = static_cast<upb_Arena*>(message->GetInternalArena());
365 upb_Message_Extension* msg_ext = _upb_Message_GetOrCreateExtension(
366 message->msg(), id.mini_table_ext(), message_arena);
367 if (!msg_ext) {
368 return MessageAllocationError();
369 }
370 auto* extension_arena = static_cast<upb_Arena*>(message->GetInternalArena());
371 if (message_arena != extension_arena) {
372 upb_Arena_Fuse(message_arena, extension_arena);
373 }
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700374 msg_ext->data.ptr = ::protos::internal::GetInternalMsg(&value);
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700375 return absl::OkStatus();
376}
377
378template <typename T, typename Extendee, typename Extension,
379 typename = EnableIfProtosClass<T>>
380absl::StatusOr<Ptr<const Extension>> GetExtension(
381 const T& message,
382 const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
383 const upb_Message_Extension* ext =
384 _upb_Message_Getext(message.msg(), id.mini_table_ext());
385 if (!ext) {
386 return ExtensionNotFoundError(id.mini_table_ext()->field.number);
387 }
388 return Ptr<const Extension>(
389 ::protos::internal::CreateMessage<Extension>(ext->data.ptr));
390}
391
392template <typename T, typename Extendee, typename Extension,
393 typename = EnableIfProtosClass<T>>
394absl::StatusOr<Ptr<const Extension>> GetExtension(
395 const Ptr<T>& message,
396 const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
397 const upb_Message_Extension* ext =
398 _upb_Message_Getext(message->msg(), id.mini_table_ext());
399 if (!ext) {
400 return ExtensionNotFoundError(id.mini_table_ext()->field.number);
401 }
402 return Ptr<const Extension>(
403 ::protos::internal::CreateMessage<Extension>(ext->data.ptr));
404}
405
406template <typename T>
407bool Parse(T& message, absl::string_view bytes) {
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700408 upb_Message_Clear(message.msg(), ::protos::internal::GetMiniTable(&message));
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700409 auto* arena = static_cast<upb_Arena*>(message.GetInternalArena());
410 return upb_Decode(bytes.data(), bytes.size(), message.msg(), T::minitable(),
411 /* extreg= */ nullptr, /* options= */ 0,
412 arena) == kUpb_DecodeStatus_Ok;
413}
414
415template <typename T>
Protobuf Team Bot28de62f2023-02-08 09:17:23 -0800416bool Parse(T& message, absl::string_view bytes,
417 const ::protos::ExtensionRegistry& extension_registry) {
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700418 upb_Message_Clear(message.msg(), ::protos::internal::GetMiniTable(message));
Protobuf Team Bot28de62f2023-02-08 09:17:23 -0800419 auto* arena = static_cast<upb_Arena*>(message.GetInternalArena());
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700420 return upb_Decode(bytes.data(), bytes.size(), message.msg(),
421 ::protos::internal::GetMiniTable(message),
Protobuf Team Bot28de62f2023-02-08 09:17:23 -0800422 /* extreg= */
423 ::protos::internal::GetUpbExtensions(extension_registry),
424 /* options= */ 0, arena) == kUpb_DecodeStatus_Ok;
425}
426
427template <typename T>
Protobuf Team Botb5384af2023-01-09 10:10:09 -0800428bool Parse(Ptr<T>& message, absl::string_view bytes) {
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700429 upb_Message_Clear(message->msg(), ::protos::internal::GetMiniTable(message));
Protobuf Team Botb5384af2023-01-09 10:10:09 -0800430 auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700431 return upb_Decode(bytes.data(), bytes.size(), message->msg(),
432 ::protos::internal::GetMiniTable(message),
Protobuf Team Botb5384af2023-01-09 10:10:09 -0800433 /* extreg= */ nullptr, /* options= */ 0,
434 arena) == kUpb_DecodeStatus_Ok;
435}
436
437template <typename T>
Protobuf Team Bot28de62f2023-02-08 09:17:23 -0800438bool Parse(Ptr<T>& message, absl::string_view bytes,
439 const ::protos::ExtensionRegistry& extension_registry) {
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700440 upb_Message_Clear(message->msg(), ::protos::internal::GetMiniTable(message));
Protobuf Team Bot28de62f2023-02-08 09:17:23 -0800441 auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700442 return upb_Decode(bytes.data(), bytes.size(), message->msg(),
443 ::protos::internal::GetMiniTable(message),
Protobuf Team Bot28de62f2023-02-08 09:17:23 -0800444 /* extreg= */
445 ::protos::internal::GetUpbExtensions(extension_registry),
446 /* options= */ 0, arena) == kUpb_DecodeStatus_Ok;
447}
448
449template <typename T>
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700450bool Parse(T* message, absl::string_view bytes) {
451 upb_Message_Clear(message->msg(), ::protos::internal::GetMiniTable(message));
Protobuf Team Botd3ec4b62022-11-16 12:21:33 -0800452 auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700453 return upb_Decode(bytes.data(), bytes.size(), message->msg(),
454 ::protos::internal::GetMiniTable(message),
Protobuf Team Botd3ec4b62022-11-16 12:21:33 -0800455 /* extreg= */ nullptr, /* options= */ 0,
456 arena) == kUpb_DecodeStatus_Ok;
457}
458
459template <typename T>
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700460absl::StatusOr<T> Parse(absl::string_view bytes, int options = 0) {
461 T message;
462 auto* arena = static_cast<upb_Arena*>(message.GetInternalArena());
463 upb_DecodeStatus status =
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700464 upb_Decode(bytes.data(), bytes.size(), message.msg(),
465 ::protos::internal::GetMiniTable(&message),
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700466 /* extreg= */ nullptr, /* options= */ 0, arena);
467 if (status == kUpb_DecodeStatus_Ok) {
468 return message;
469 }
470 return MessageDecodeError(status);
471}
472
473template <typename T>
474absl::StatusOr<T> Parse(absl::string_view bytes,
475 const ::protos::ExtensionRegistry& extension_registry,
476 int options = 0) {
477 T message;
478 auto* arena = static_cast<upb_Arena*>(message.GetInternalArena());
479 upb_DecodeStatus status =
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700480 upb_Decode(bytes.data(), bytes.size(), message.msg(),
481 ::protos::internal::GetMiniTable(&message),
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700482 ::protos::internal::GetUpbExtensions(extension_registry),
483 /* options= */ 0, arena);
484 if (status == kUpb_DecodeStatus_Ok) {
485 return message;
486 }
487 return MessageDecodeError(status);
488}
489
490template <typename T>
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700491absl::StatusOr<absl::string_view> Serialize(const T* message, upb::Arena& arena,
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700492 int options = 0) {
Protobuf Team Botd3ec4b62022-11-16 12:21:33 -0800493 return ::protos::internal::Serialize(
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700494 message->msg(), ::protos::internal::GetMiniTable(message), arena.ptr(),
Protobuf Team Botd3ec4b62022-11-16 12:21:33 -0800495 options);
496}
497
498template <typename T>
Protobuf Team Botb5384af2023-01-09 10:10:09 -0800499absl::StatusOr<absl::string_view> Serialize(Ptr<T> message, upb::Arena& arena,
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700500 int options = 0) {
Protobuf Team Bot923e8b72023-06-23 10:26:51 -0700501 return ::protos::internal::Serialize(
502 message->msg(), ::protos::internal::GetMiniTable(message), arena.ptr(),
503 options);
Protobuf Team Bot306123e2022-11-04 09:25:30 -0700504}
505
506} // namespace protos
507
508#endif // UPB_PROTOS_PROTOS_H_