/src/LPM/external.protobuf/include/google/protobuf/message_lite.h
Line  | Count  | Source (jump to first uncovered line)  | 
1  |  | // Protocol Buffers - Google's data interchange format  | 
2  |  | // Copyright 2008 Google Inc.  All rights reserved.  | 
3  |  | //  | 
4  |  | // Use of this source code is governed by a BSD-style  | 
5  |  | // license that can be found in the LICENSE file or at  | 
6  |  | // https://developers.google.com/open-source/licenses/bsd  | 
7  |  |  | 
8  |  | // Authors: wink@google.com (Wink Saville),  | 
9  |  | //          kenton@google.com (Kenton Varda)  | 
10  |  | //  Based on original Protocol Buffers design by  | 
11  |  | //  Sanjay Ghemawat, Jeff Dean, and others.  | 
12  |  | //  | 
13  |  | // Defines MessageLite, the abstract interface implemented by all (lite  | 
14  |  | // and non-lite) protocol message objects.  | 
15  |  |  | 
16  |  | #ifndef GOOGLE_PROTOBUF_MESSAGE_LITE_H__  | 
17  |  | #define GOOGLE_PROTOBUF_MESSAGE_LITE_H__  | 
18  |  |  | 
19  |  | #include <climits>  | 
20  |  | #include <cstddef>  | 
21  |  | #include <cstdint>  | 
22  |  | #include <cstring>  | 
23  |  | #include <iosfwd>  | 
24  |  | #include <new>  | 
25  |  | #include <string>  | 
26  |  | #include <type_traits>  | 
27  |  |  | 
28  |  | #include "absl/base/attributes.h"  | 
29  |  | #include "absl/base/casts.h"  | 
30  |  | #include "absl/log/absl_check.h"  | 
31  |  | #include "absl/numeric/bits.h"  | 
32  |  | #include "absl/strings/cord.h"  | 
33  |  | #include "absl/strings/string_view.h"  | 
34  |  | #include "google/protobuf/arena.h"  | 
35  |  | #include "google/protobuf/explicitly_constructed.h"  | 
36  |  | #include "google/protobuf/internal_visibility.h"  | 
37  |  | #include "google/protobuf/io/coded_stream.h"  | 
38  |  | #include "google/protobuf/metadata_lite.h"  | 
39  |  | #include "google/protobuf/port.h"  | 
40  |  |  | 
41  |  |  | 
42  |  | // clang-format off  | 
43  |  | #include "google/protobuf/port_def.inc"  | 
44  |  | // clang-format on  | 
45  |  |  | 
46  |  | #ifdef SWIG  | 
47  |  | #error "You cannot SWIG proto headers"  | 
48  |  | #endif  | 
49  |  |  | 
50  |  | namespace google { | 
51  |  | namespace protobuf { | 
52  |  |  | 
53  |  | template <typename T>  | 
54  |  | class RepeatedPtrField;  | 
55  |  |  | 
56  |  | class FastReflectionMessageMutator;  | 
57  |  | class FastReflectionStringSetter;  | 
58  |  | class Reflection;  | 
59  |  | class Descriptor;  | 
60  |  | class AssignDescriptorsHelper;  | 
61  |  | class MessageLite;  | 
62  |  |  | 
63  |  | namespace io { | 
64  |  |  | 
65  |  | class CodedInputStream;  | 
66  |  | class CodedOutputStream;  | 
67  |  | class ZeroCopyInputStream;  | 
68  |  | class ZeroCopyOutputStream;  | 
69  |  |  | 
70  |  | }  // namespace io  | 
71  |  |  | 
72  |  | namespace compiler { | 
73  |  | namespace cpp { | 
74  |  | class MessageTableTester;  | 
75  |  | }  // namespace cpp  | 
76  |  | }  // namespace compiler  | 
77  |  |  | 
78  |  | namespace internal { | 
79  |  |  | 
80  |  | class MessageCreator { | 
81  |  |  public:  | 
82  |  |   using Func = void* (*)(const void*, void*, Arena*);  | 
83  |  |  | 
84  |  |   // Use -1/0/1 to be able to use <0, ==0, >0  | 
85  |  |   enum Tag : int8_t { | 
86  |  |     kFunc = -1,  | 
87  |  |     kZeroInit = 0,  | 
88  |  |     kMemcpy = 1,  | 
89  |  |   };  | 
90  |  |  | 
91  |  |   constexpr MessageCreator()  | 
92  | 0  |       : allocation_size_(), tag_(), alignment_(), arena_bits_(uintptr_t{}) {} | 
93  |  |  | 
94  |  |   static constexpr MessageCreator ZeroInit(uint32_t allocation_size,  | 
95  |  |                                            uint8_t alignment,  | 
96  | 0  |                                            uintptr_t arena_bits = 0) { | 
97  | 0  |     MessageCreator out;  | 
98  | 0  |     out.allocation_size_ = allocation_size;  | 
99  | 0  |     out.tag_ = kZeroInit;  | 
100  | 0  |     out.alignment_ = alignment;  | 
101  | 0  |     out.arena_bits_ = arena_bits;  | 
102  | 0  |     return out;  | 
103  | 0  |   }  | 
104  |  |   static constexpr MessageCreator CopyInit(uint32_t allocation_size,  | 
105  |  |                                            uint8_t alignment,  | 
106  | 0  |                                            uintptr_t arena_bits = 0) { | 
107  | 0  |     MessageCreator out;  | 
108  | 0  |     out.allocation_size_ = allocation_size;  | 
109  | 0  |     out.tag_ = kMemcpy;  | 
110  | 0  |     out.alignment_ = alignment;  | 
111  | 0  |     out.arena_bits_ = arena_bits;  | 
112  | 0  |     return out;  | 
113  | 0  |   }  | 
114  |  |   constexpr MessageCreator(Func func, uint32_t allocation_size,  | 
115  |  |                            uint8_t alignment)  | 
116  |  |       : allocation_size_(allocation_size),  | 
117  |  |         tag_(kFunc),  | 
118  |  |         alignment_(alignment),  | 
119  | 0  |         func_(func) {} | 
120  |  |  | 
121  |  |   // Template for testing.  | 
122  |  |   template <bool test_call = false, typename MessageLite>  | 
123  |  |   MessageLite* New(const MessageLite* prototype_for_func,  | 
124  |  |                    const MessageLite* prototype_for_copy, Arena* arena) const;  | 
125  |  |  | 
126  |  |   template <bool test_call = false, typename MessageLite>  | 
127  |  |   MessageLite* PlacementNew(const MessageLite* prototype_for_func,  | 
128  |  |                             const MessageLite* prototype_for_copy, void* mem,  | 
129  |  |                             Arena* arena) const;  | 
130  |  |  | 
131  | 0  |   Tag tag() const { return tag_; } | 
132  |  |  | 
133  | 0  |   uint32_t allocation_size() const { return allocation_size_; } | 
134  |  |  | 
135  | 0  |   uint8_t alignment() const { return alignment_; } | 
136  |  |  | 
137  | 0  |   uintptr_t arena_bits() const { | 
138  | 0  |     ABSL_DCHECK_NE(+tag(), +kFunc);  | 
139  | 0  |     return arena_bits_;  | 
140  | 0  |   }  | 
141  |  |  | 
142  |  |  private:  | 
143  |  |   uint32_t allocation_size_;  | 
144  |  |   Tag tag_;  | 
145  |  |   uint8_t alignment_;  | 
146  |  |   union { | 
147  |  |     Func func_;  | 
148  |  |     uintptr_t arena_bits_;  | 
149  |  |   };  | 
150  |  | };  | 
151  |  |  | 
152  |  | // Allow easy change to regular int on platforms where the atomic might have a  | 
153  |  | // perf impact.  | 
154  |  | //  | 
155  |  | // CachedSize is like std::atomic<int> but with some important changes:  | 
156  |  | //  | 
157  |  | // 1) CachedSize uses Get / Set rather than load / store.  | 
158  |  | // 2) CachedSize always uses relaxed ordering.  | 
159  |  | // 3) CachedSize is assignable and copy-constructible.  | 
160  |  | // 4) CachedSize has a constexpr default constructor, and a constexpr  | 
161  |  | //    constructor that takes an int argument.  | 
162  |  | // 5) If the compiler supports the __atomic_load_n / __atomic_store_n builtins,  | 
163  |  | //    then CachedSize is trivially copyable.  | 
164  |  | //  | 
165  |  | // Developed at https://godbolt.org/z/vYcx7zYs1 ; supports gcc, clang, MSVC.  | 
166  |  | class PROTOBUF_EXPORT CachedSize { | 
167  |  |  private:  | 
168  |  |   using Scalar = int;  | 
169  |  |  | 
170  |  |  public:  | 
171  | 0  |   constexpr CachedSize() noexcept : atom_(Scalar{}) {} | 
172  |  |   // NOLINTNEXTLINE(google-explicit-constructor)  | 
173  | 157k  |   constexpr CachedSize(Scalar desired) noexcept : atom_(desired) {} | 
174  |  |  | 
175  |  | #if PROTOBUF_BUILTIN_ATOMIC  | 
176  |  |   constexpr CachedSize(const CachedSize& other) = default;  | 
177  |  |  | 
178  | 0  |   Scalar Get() const noexcept { | 
179  | 0  |     return __atomic_load_n(&atom_, __ATOMIC_RELAXED);  | 
180  | 0  |   }  | 
181  |  |  | 
182  | 0  |   void Set(Scalar desired) const noexcept { | 
183  | 0  |     // Avoid writing the value when it is zero. This prevents writing to global  | 
184  | 0  |     // default instances, which might be in readonly memory.  | 
185  | 0  |     if (ABSL_PREDICT_FALSE(desired == 0)) { | 
186  | 0  |       if (Get() == 0) return;  | 
187  | 0  |     }  | 
188  | 0  |     __atomic_store_n(&atom_, desired, __ATOMIC_RELAXED);  | 
189  | 0  |   }  | 
190  |  |  | 
191  | 0  |   void SetNonZero(Scalar desired) const noexcept { | 
192  | 0  |     __atomic_store_n(&atom_, desired, __ATOMIC_RELAXED);  | 
193  | 0  |   }  | 
194  |  | #else  | 
195  |  |   CachedSize(const CachedSize& other) noexcept : atom_(other.Get()) {} | 
196  |  |   CachedSize& operator=(const CachedSize& other) noexcept { | 
197  |  |     Set(other.Get());  | 
198  |  |     return *this;  | 
199  |  |   }  | 
200  |  |  | 
201  |  |   Scalar Get() const noexcept {  // | 
202  |  |     return atom_.load(std::memory_order_relaxed);  | 
203  |  |   }  | 
204  |  |  | 
205  |  |   void Set(Scalar desired) const noexcept { | 
206  |  |     // Avoid writing the value when it is zero. This prevents writing to global  | 
207  |  |     // default instances, which might be in readonly memory.  | 
208  |  |     if (ABSL_PREDICT_FALSE(desired == 0)) { | 
209  |  |       if (Get() == 0) return;  | 
210  |  |     }  | 
211  |  |     atom_.store(desired, std::memory_order_relaxed);  | 
212  |  |   }  | 
213  |  |  | 
214  |  |   void SetNonZero(Scalar desired) const noexcept { | 
215  |  |     atom_.store(desired, std::memory_order_relaxed);  | 
216  |  |   }  | 
217  |  | #endif  | 
218  |  |  | 
219  |  |  private:  | 
220  |  | #if PROTOBUF_BUILTIN_ATOMIC  | 
221  |  |   mutable Scalar atom_;  | 
222  |  | #else  | 
223  |  |   mutable std::atomic<Scalar> atom_;  | 
224  |  | #endif  | 
225  |  | };  | 
226  |  |  | 
227  |  | // TODO: Upgrade to `auto` parameters when we drop C++14 support.  | 
228  |  | template <typename T, const T* kDefault>  | 
229  |  | struct GeneratedMessageTraitsT { | 
230  |  |   static constexpr const void* default_instance() { return kDefault; } | 
231  |  |   static constexpr auto StrongPointer() { return default_instance(); } | 
232  |  | };  | 
233  |  |  | 
234  |  | template <typename T>  | 
235  |  | struct FallbackMessageTraits { | 
236  |  |   static const void* default_instance() { return T::default_instance(); } | 
237  |  |   // We can't make a constexpr pointer to the default, so use a function pointer  | 
238  |  |   // instead.  | 
239  | 18.4k  |   static constexpr auto StrongPointer() { return &T::default_instance; } | 
240  |  | };  | 
241  |  |  | 
242  |  | // Traits for message T.  | 
243  |  | // We use a class scope variable template, which can be specialized with a  | 
244  |  | // different type in a non-defining declaration.  | 
245  |  | // We need non-defining declarations because we might have duplicates of the  | 
246  |  | // same trait specification on each dependent coming from different .proto.h  | 
247  |  | // files.  | 
248  |  | struct MessageTraitsImpl { | 
249  |  |   template <typename T>  | 
250  |  |   static FallbackMessageTraits<T> value;  | 
251  |  | };  | 
252  |  | template <typename T>  | 
253  |  | using MessageTraits = decltype(MessageTraitsImpl::value<T>);  | 
254  |  |  | 
255  |  | // For MessageLite to friend.  | 
256  |  | auto GetClassData(const MessageLite& msg);  | 
257  |  |  | 
258  |  | class SwapFieldHelper;  | 
259  |  |  | 
260  |  | // See parse_context.h for explanation  | 
261  |  | class ParseContext;  | 
262  |  |  | 
263  |  | struct DescriptorTable;  | 
264  |  | class DescriptorPoolExtensionFinder;  | 
265  |  | class ExtensionSet;  | 
266  |  | class LazyField;  | 
267  |  | class RepeatedPtrFieldBase;  | 
268  |  | class TcParser;  | 
269  |  | struct TcParseTableBase;  | 
270  |  | class WireFormatLite;  | 
271  |  | class WeakFieldMap;  | 
272  |  | class RustMapHelper;  | 
273  |  |  | 
274  |  | // We compute sizes as size_t but cache them as int.  This function converts a  | 
275  |  | // computed size to a cached size.  Since we don't proceed with serialization  | 
276  |  | // if the total size was > INT_MAX, it is not important what this function  | 
277  |  | // returns for inputs > INT_MAX.  However this case should not error or  | 
278  |  | // ABSL_CHECK-fail, because the full size_t resolution is still returned from  | 
279  |  | // ByteSizeLong() and checked against INT_MAX; we can catch the overflow  | 
280  |  | // there.  | 
281  | 0  | inline int ToCachedSize(size_t size) { return static_cast<int>(size); } | 
282  |  |  | 
283  |  | // We mainly calculate sizes in terms of size_t, but some functions that  | 
284  |  | // compute sizes return "int".  These int sizes are expected to always be  | 
285  |  | // positive. This function is more efficient than casting an int to size_t  | 
286  |  | // directly on 64-bit platforms because it avoids making the compiler emit a  | 
287  |  | // sign extending instruction, which we don't want and don't want to pay for.  | 
288  | 0  | inline size_t FromIntSize(int size) { | 
289  | 0  |   // Convert to unsigned before widening so sign extension is not necessary.  | 
290  | 0  |   return static_cast<unsigned int>(size);  | 
291  | 0  | }  | 
292  |  |  | 
293  |  | // For cases where a legacy function returns an integer size.  We ABSL_DCHECK()  | 
294  |  | // that the conversion will fit within an integer; if this is false then we  | 
295  |  | // are losing information.  | 
296  | 0  | inline int ToIntSize(size_t size) { | 
297  | 0  |   ABSL_DCHECK_LE(size, static_cast<size_t>(INT_MAX));  | 
298  | 0  |   return static_cast<int>(size);  | 
299  | 0  | }  | 
300  |  |  | 
301  |  | #if defined(PROTOBUF_FUTURE_STRING_VIEW_RETURN_TYPE)  | 
302  |  | using GetTypeNameReturnType = absl::string_view;  | 
303  |  | #else  | 
304  |  | using GetTypeNameReturnType = std::string;  | 
305  |  | #endif  | 
306  |  |  | 
307  |  | // Default empty string object. Don't use this directly. Instead, call  | 
308  |  | // GetEmptyString() to get the reference. This empty string is aligned with a  | 
309  |  | // minimum alignment of 8 bytes to match the requirement of ArenaStringPtr.  | 
310  |  | PROTOBUF_EXPORT extern ExplicitlyConstructedArenaString  | 
311  |  |     fixed_address_empty_string;  | 
312  |  |  | 
313  |  |  | 
314  | 0  | PROTOBUF_EXPORT constexpr const std::string& GetEmptyStringAlreadyInited() { | 
315  | 0  |   return fixed_address_empty_string.get();  | 
316  | 0  | }  | 
317  |  |  | 
318  |  | PROTOBUF_EXPORT size_t StringSpaceUsedExcludingSelfLong(const std::string& str);  | 
319  |  |  | 
320  |  | struct ClassDataFull;  | 
321  |  |  | 
322  |  | // Note: The order of arguments in the functions is chosen so that it has  | 
323  |  | // the same ABI as the member function that calls them. Eg the `this`  | 
324  |  | // pointer becomes the first argument in the free function.  | 
325  |  | //  | 
326  |  | // Future work:  | 
327  |  | // We could save more data by omitting any optional pointer that would  | 
328  |  | // otherwise be null. We can have some metadata in ClassData telling us if we  | 
329  |  | // have them and their offset.  | 
330  |  |  | 
331  |  | struct PROTOBUF_EXPORT ClassData { | 
332  |  |   const MessageLite* prototype;  | 
333  |  |   const internal::TcParseTableBase* tc_table;  | 
334  |  |   void (*on_demand_register_arena_dtor)(MessageLite& msg, Arena& arena);  | 
335  |  |   bool (*is_initialized)(const MessageLite&);  | 
336  |  |   void (*merge_to_from)(MessageLite& to, const MessageLite& from_msg);  | 
337  |  |   internal::MessageCreator message_creator;  | 
338  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
339  |  |   void (*destroy_message)(MessageLite& msg);  | 
340  |  |   void (MessageLite::*clear)();  | 
341  |  |   size_t (*byte_size_long)(const MessageLite&);  | 
342  |  |   uint8_t* (*serialize)(const MessageLite& msg, uint8_t* ptr,  | 
343  |  |                         io::EpsCopyOutputStream* stream);  | 
344  |  | #endif  // PROTOBUF_CUSTOM_VTABLE  | 
345  |  |  | 
346  |  |   // Offset of the CachedSize member.  | 
347  |  |   uint32_t cached_size_offset;  | 
348  |  |   // LITE objects (ie !descriptor_methods) collocate their name as a  | 
349  |  |   // char[] just beyond the ClassData.  | 
350  |  |   bool is_lite;  | 
351  |  |   bool is_dynamic = false;  | 
352  |  |  | 
353  |  |   // In normal mode we have the small constructor to avoid the cost in  | 
354  |  |   // codegen.  | 
355  |  | #if !defined(PROTOBUF_CUSTOM_VTABLE)  | 
356  |  |   constexpr ClassData(  | 
357  |  |       const MessageLite* prototype, const internal::TcParseTableBase* tc_table,  | 
358  |  |       void (*on_demand_register_arena_dtor)(MessageLite&, Arena&),  | 
359  |  |       bool (*is_initialized)(const MessageLite&),  | 
360  |  |       void (*merge_to_from)(MessageLite& to, const MessageLite& from_msg),  | 
361  |  |       internal::MessageCreator message_creator, uint32_t cached_size_offset,  | 
362  |  |       bool is_lite  | 
363  |  |       )  | 
364  |  |       : prototype(prototype),  | 
365  |  |         tc_table(tc_table),  | 
366  |  |         on_demand_register_arena_dtor(on_demand_register_arena_dtor),  | 
367  |  |         is_initialized(is_initialized),  | 
368  |  |         merge_to_from(merge_to_from),  | 
369  |  |         message_creator(message_creator),  | 
370  |  |         cached_size_offset(cached_size_offset),  | 
371  |  |         is_lite(is_lite)  | 
372  | 0  |   { | 
373  | 0  |   }  | 
374  |  | #endif  // !PROTOBUF_CUSTOM_VTABLE  | 
375  |  |  | 
376  |  |   // But we always provide the full constructor even in normal mode to make  | 
377  |  |   // helper code simpler.  | 
378  |  |   constexpr ClassData(  | 
379  |  |       const MessageLite* prototype, const internal::TcParseTableBase* tc_table,  | 
380  |  |       void (*on_demand_register_arena_dtor)(MessageLite&, Arena&),  | 
381  |  |       bool (*is_initialized)(const MessageLite&),  | 
382  |  |       void (*merge_to_from)(MessageLite& to, const MessageLite& from_msg),  | 
383  |  |       internal::MessageCreator message_creator,  | 
384  |  |       void (*destroy_message)(MessageLite& msg),  //  | 
385  |  |       void (MessageLite::*clear)(),  | 
386  |  |       size_t (*byte_size_long)(const MessageLite&),  | 
387  |  |       uint8_t* (*serialize)(const MessageLite& msg, uint8_t* ptr,  | 
388  |  |                             io::EpsCopyOutputStream* stream),  | 
389  |  |       uint32_t cached_size_offset, bool is_lite  | 
390  |  |       )  | 
391  |  |       : prototype(prototype),  | 
392  |  |         tc_table(tc_table),  | 
393  |  |         on_demand_register_arena_dtor(on_demand_register_arena_dtor),  | 
394  |  |         is_initialized(is_initialized),  | 
395  |  |         merge_to_from(merge_to_from),  | 
396  |  |         message_creator(message_creator),  | 
397  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
398  |  |         destroy_message(destroy_message),  | 
399  |  |         clear(clear),  | 
400  |  |         byte_size_long(byte_size_long),  | 
401  |  |         serialize(serialize),  | 
402  |  | #endif  // PROTOBUF_CUSTOM_VTABLE  | 
403  |  |         cached_size_offset(cached_size_offset),  | 
404  |  |         is_lite(is_lite)  | 
405  | 0  |   { | 
406  | 0  |   }  | 
407  |  |  | 
408  |  |   const ClassDataFull& full() const;  | 
409  |  |  | 
410  | 0  |   MessageLite* New(Arena* arena) const { | 
411  | 0  |     return message_creator.New(prototype, prototype, arena);  | 
412  | 0  |   }  | 
413  |  |  | 
414  | 0  |   MessageLite* PlacementNew(void* mem, Arena* arena) const { | 
415  | 0  |     return message_creator.PlacementNew(prototype, prototype, mem, arena);  | 
416  | 0  |   }  | 
417  |  |  | 
418  | 0  |   uint32_t allocation_size() const { return message_creator.allocation_size(); } | 
419  |  |  | 
420  | 0  |   uint8_t alignment() const { return message_creator.alignment(); } | 
421  |  | };  | 
422  |  |  | 
423  |  | template <size_t N>  | 
424  |  | struct ClassDataLite { | 
425  |  |   ClassData header;  | 
426  |  |   const char type_name[N];  | 
427  |  |  | 
428  | 0  |   constexpr const ClassData* base() const { return &header; } | 
429  |  | };  | 
430  |  |  | 
431  |  | // We use a secondary vtable for descriptor based methods. This way ClassData  | 
432  |  | // does not grow with the number of descriptor methods. This avoids extra  | 
433  |  | // costs in MessageLite.  | 
434  |  | struct PROTOBUF_EXPORT DescriptorMethods { | 
435  |  |   absl::string_view (*get_type_name)(const ClassData* data);  | 
436  |  |   std::string (*initialization_error_string)(const MessageLite&);  | 
437  |  |   const internal::TcParseTableBase* (*get_tc_table)(const MessageLite&);  | 
438  |  |   size_t (*space_used_long)(const MessageLite&);  | 
439  |  |   std::string (*debug_string)(const MessageLite&);  | 
440  |  | };  | 
441  |  |  | 
442  |  | struct PROTOBUF_EXPORT ClassDataFull : ClassData { | 
443  |  |   constexpr ClassDataFull(ClassData base,  | 
444  |  |                           const DescriptorMethods* descriptor_methods,  | 
445  |  |                           const internal::DescriptorTable* descriptor_table,  | 
446  |  |                           void (*get_metadata_tracker)())  | 
447  |  |       : ClassData(base),  | 
448  |  |         descriptor_methods(descriptor_methods),  | 
449  |  |         descriptor_table(descriptor_table),  | 
450  |  |         reflection(),  | 
451  |  |         descriptor(),  | 
452  | 0  |         get_metadata_tracker(get_metadata_tracker) {} | 
453  |  |  | 
454  | 2.01M  |   constexpr const ClassData* base() const { return this; } | 
455  |  |  | 
456  |  |   const DescriptorMethods* descriptor_methods;  | 
457  |  |  | 
458  |  |   // Codegen types will provide a DescriptorTable to do lazy  | 
459  |  |   // registration/initialization of the reflection objects.  | 
460  |  |   // Other types, like DynamicMessage, keep the table as null but eagerly  | 
461  |  |   // populate `reflection`/`descriptor` fields.  | 
462  |  |   const internal::DescriptorTable* descriptor_table;  | 
463  |  |   // Accesses are protected by the once_flag in `descriptor_table`. When the  | 
464  |  |   // table is null these are populated from the beginning and need to  | 
465  |  |   // protection.  | 
466  |  |   mutable const Reflection* reflection;  | 
467  |  |   mutable const Descriptor* descriptor;  | 
468  |  |  | 
469  |  |   // When an access tracker is installed, this function notifies the tracker  | 
470  |  |   // that GetMetadata was called.  | 
471  |  |   void (*get_metadata_tracker)();  | 
472  |  | };  | 
473  |  |  | 
474  | 2  | inline const ClassDataFull& ClassData::full() const { | 
475  | 2  |   ABSL_DCHECK(!is_lite);  | 
476  | 2  |   return *static_cast<const ClassDataFull*>(this);  | 
477  | 2  | }  | 
478  |  |  | 
479  |  | }  // namespace internal  | 
480  |  |  | 
481  |  | // Interface to light weight protocol messages.  | 
482  |  | //  | 
483  |  | // This interface is implemented by all protocol message objects.  Non-lite  | 
484  |  | // messages additionally implement the Message interface, which is a  | 
485  |  | // subclass of MessageLite.  Use MessageLite instead when you only need  | 
486  |  | // the subset of features which it supports -- namely, nothing that uses  | 
487  |  | // descriptors or reflection.  You can instruct the protocol compiler  | 
488  |  | // to generate classes which implement only MessageLite, not the full  | 
489  |  | // Message interface, by adding the following line to the .proto file:  | 
490  |  | //  | 
491  |  | //   option optimize_for = LITE_RUNTIME;  | 
492  |  | //  | 
493  |  | // This is particularly useful on resource-constrained systems where  | 
494  |  | // the full protocol buffers runtime library is too big.  | 
495  |  | //  | 
496  |  | // Note that on non-constrained systems (e.g. servers) when you need  | 
497  |  | // to link in lots of protocol definitions, a better way to reduce  | 
498  |  | // total code footprint is to use optimize_for = CODE_SIZE.  This  | 
499  |  | // will make the generated code smaller while still supporting all the  | 
500  |  | // same features (at the expense of speed).  optimize_for = LITE_RUNTIME  | 
501  |  | // is best when you only have a small number of message types linked  | 
502  |  | // into your binary, in which case the size of the protocol buffers  | 
503  |  | // runtime itself is the biggest problem.  | 
504  |  | //  | 
505  |  | // Users must not derive from this class. Only the protocol compiler and  | 
506  |  | // the internal library are allowed to create subclasses.  | 
507  |  | class PROTOBUF_EXPORT MessageLite { | 
508  |  |  public:  | 
509  |  |   MessageLite(const MessageLite&) = delete;  | 
510  |  |   MessageLite& operator=(const MessageLite&) = delete;  | 
511  | 157k  |   PROTOBUF_VIRTUAL ~MessageLite() = default;  | 
512  |  |  | 
513  |  |   // Basic Operations ------------------------------------------------  | 
514  |  |  | 
515  |  |   // Get the name of this message type, e.g. "foo.bar.BazProto".  | 
516  |  |   internal::GetTypeNameReturnType GetTypeName() const;  | 
517  |  |  | 
518  |  |   // Construct a new instance of the same type.  Ownership is passed to the  | 
519  |  |   // caller.  | 
520  | 0  |   MessageLite* New() const { return New(nullptr); } | 
521  |  |  | 
522  |  |   // Construct a new instance on the arena. Ownership is passed to the caller  | 
523  |  |   // if arena is a nullptr.  | 
524  |  |   MessageLite* New(Arena* arena) const;  | 
525  |  |  | 
526  |  |   // Returns the arena, if any, that directly owns this message and its internal  | 
527  |  |   // memory (Arena::Own is different in that the arena doesn't directly own the  | 
528  |  |   // internal memory). This method is used in proto's implementation for  | 
529  |  |   // swapping, moving and setting allocated, for deciding whether the ownership  | 
530  |  |   // of this message or its internal memory could be changed.  | 
531  | 58.8k  |   Arena* GetArena() const { return _internal_metadata_.arena(); } | 
532  |  |  | 
533  |  |   // Clear all fields of the message and set them to their default values.  | 
534  |  |   // Clear() assumes that any memory allocated to hold parts of the message  | 
535  |  |   // will likely be needed again, so the memory used may not be freed.  | 
536  |  |   // To ensure that all memory used by a Message is freed, you must delete it.  | 
537  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
538  |  |   void Clear() { (this->*_class_data_->clear)(); } | 
539  |  | #else  | 
540  |  |   virtual void Clear() = 0;  | 
541  |  | #endif  // PROTOBUF_CUSTOM_VTABLE  | 
542  |  |  | 
543  |  |   // Quickly check if all required fields have values set.  | 
544  |  |   bool IsInitialized() const;  | 
545  |  |  | 
546  |  |   // This is not implemented for Lite messages -- it just returns "(cannot  | 
547  |  |   // determine missing fields for lite message)".  However, it is implemented  | 
548  |  |   // for full messages.  See message.h.  | 
549  |  |   std::string InitializationErrorString() const;  | 
550  |  |  | 
551  |  |   // If |other| is the exact same class as this, calls MergeFrom(). Otherwise,  | 
552  |  |   // results are undefined (probably crash).  | 
553  |  |   void CheckTypeAndMergeFrom(const MessageLite& other);  | 
554  |  |  | 
555  |  |   // These methods return a human-readable summary of the message. Note that  | 
556  |  |   // since the MessageLite interface does not support reflection, there is very  | 
557  |  |   // little information that these methods can provide. They are shadowed by  | 
558  |  |   // methods of the same name on the Message interface which provide much more  | 
559  |  |   // information. The methods here are intended primarily to facilitate code  | 
560  |  |   // reuse for logic that needs to interoperate with both full and lite protos.  | 
561  |  |   //  | 
562  |  |   // The format of the returned string is subject to change, so please do not  | 
563  |  |   // assume it will remain stable over time.  | 
564  |  |   std::string DebugString() const;  | 
565  | 0  |   std::string ShortDebugString() const { return DebugString(); } | 
566  |  |   // MessageLite::DebugString is already Utf8 Safe. This is to add compatibility  | 
567  |  |   // with Message.  | 
568  | 0  |   std::string Utf8DebugString() const { return DebugString(); } | 
569  |  |  | 
570  |  |   // Implementation of the `AbslStringify` interface. This adds `DebugString()`  | 
571  |  |   // to the sink. Do not rely on exact format.  | 
572  |  |   template <typename Sink>  | 
573  |  |   friend void AbslStringify(Sink& sink, const google::protobuf::MessageLite& msg) { | 
574  |  |     sink.Append(msg.DebugString());  | 
575  |  |   }  | 
576  |  |  | 
577  |  |   // Parsing ---------------------------------------------------------  | 
578  |  |   // Methods for parsing in protocol buffer format.  Most of these are  | 
579  |  |   // just simple wrappers around MergeFromCodedStream().  Clear() will be  | 
580  |  |   // called before merging the input.  | 
581  |  |  | 
582  |  |   // Fill the message with a protocol buffer parsed from the given input  | 
583  |  |   // stream. Returns false on a read error or if the input is in the wrong  | 
584  |  |   // format.  A successful return does not indicate the entire input is  | 
585  |  |   // consumed, ensure you call ConsumedEntireMessage() to check that if  | 
586  |  |   // applicable.  | 
587  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromCodedStream(  | 
588  |  |       io::CodedInputStream* input);  | 
589  |  |   // Like ParseFromCodedStream(), but accepts messages that are missing  | 
590  |  |   // required fields.  | 
591  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromCodedStream(  | 
592  |  |       io::CodedInputStream* input);  | 
593  |  |   // Read a protocol buffer from the given zero-copy input stream.  If  | 
594  |  |   // successful, the entire input will be consumed.  | 
595  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromZeroCopyStream(  | 
596  |  |       io::ZeroCopyInputStream* input);  | 
597  |  |   // Like ParseFromZeroCopyStream(), but accepts messages that are missing  | 
598  |  |   // required fields.  | 
599  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromZeroCopyStream(  | 
600  |  |       io::ZeroCopyInputStream* input);  | 
601  |  |   // Parse a protocol buffer from a file descriptor.  If successful, the entire  | 
602  |  |   // input will be consumed.  | 
603  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromFileDescriptor(  | 
604  |  |       int file_descriptor);  | 
605  |  |   // Like ParseFromFileDescriptor(), but accepts messages that are missing  | 
606  |  |   // required fields.  | 
607  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromFileDescriptor(  | 
608  |  |       int file_descriptor);  | 
609  |  |   // Parse a protocol buffer from a C++ istream.  If successful, the entire  | 
610  |  |   // input will be consumed.  | 
611  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromIstream(std::istream* input);  | 
612  |  |   // Like ParseFromIstream(), but accepts messages that are missing  | 
613  |  |   // required fields.  | 
614  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromIstream(  | 
615  |  |       std::istream* input);  | 
616  |  |   // Read a protocol buffer from the given zero-copy input stream, expecting  | 
617  |  |   // the message to be exactly "size" bytes long.  If successful, exactly  | 
618  |  |   // this many bytes will have been consumed from the input.  | 
619  |  |   bool MergePartialFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input,  | 
620  |  |                                              int size);  | 
621  |  |   // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are  | 
622  |  |   // missing required fields.  | 
623  |  |   bool MergeFromBoundedZeroCopyStream(io::ZeroCopyInputStream* input, int size);  | 
624  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromBoundedZeroCopyStream(  | 
625  |  |       io::ZeroCopyInputStream* input, int size);  | 
626  |  |   // Like ParseFromBoundedZeroCopyStream(), but accepts messages that are  | 
627  |  |   // missing required fields.  | 
628  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromBoundedZeroCopyStream(  | 
629  |  |       io::ZeroCopyInputStream* input, int size);  | 
630  |  |   // Parses a protocol buffer contained in a string. Returns true on success.  | 
631  |  |   // This function takes a string in the (non-human-readable) binary wire  | 
632  |  |   // format, matching the encoding output by MessageLite::SerializeToString().  | 
633  |  |   // If you'd like to convert a human-readable string into a protocol buffer  | 
634  |  |   // object, see google::protobuf::TextFormat::ParseFromString().  | 
635  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromString(absl::string_view data);  | 
636  |  |   // Like ParseFromString(), but accepts messages that are missing  | 
637  |  |   // required fields.  | 
638  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromString(  | 
639  |  |       absl::string_view data);  | 
640  |  |   // Parse a protocol buffer contained in an array of bytes.  | 
641  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromArray(const void* data, int size);  | 
642  |  |   // Like ParseFromArray(), but accepts messages that are missing  | 
643  |  |   // required fields.  | 
644  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromArray(const void* data,  | 
645  |  |                                                           int size);  | 
646  |  |  | 
647  |  |  | 
648  |  |   // Reads a protocol buffer from the stream and merges it into this  | 
649  |  |   // Message.  Singular fields read from the what is  | 
650  |  |   // already in the Message and repeated fields are appended to those  | 
651  |  |   // already present.  | 
652  |  |   //  | 
653  |  |   // It is the responsibility of the caller to call input->LastTagWas()  | 
654  |  |   // (for groups) or input->ConsumedEntireMessage() (for non-groups) after  | 
655  |  |   // this returns to verify that the message's end was delimited correctly.  | 
656  |  |   //  | 
657  |  |   // ParseFromCodedStream() is implemented as Clear() followed by  | 
658  |  |   // MergeFromCodedStream().  | 
659  |  |   bool MergeFromCodedStream(io::CodedInputStream* input);  | 
660  |  |  | 
661  |  |   // Like MergeFromCodedStream(), but succeeds even if required fields are  | 
662  |  |   // missing in the input.  | 
663  |  |   //  | 
664  |  |   // MergeFromCodedStream() is just implemented as MergePartialFromCodedStream()  | 
665  |  |   // followed by IsInitialized().  | 
666  |  |   bool MergePartialFromCodedStream(io::CodedInputStream* input);  | 
667  |  |  | 
668  |  |   // Merge a protocol buffer contained in a string.  | 
669  |  |   bool MergeFromString(absl::string_view data);  | 
670  |  |  | 
671  |  |  | 
672  |  |   // Serialization ---------------------------------------------------  | 
673  |  |   // Methods for serializing in protocol buffer format.  Most of these  | 
674  |  |   // are just simple wrappers around ByteSize() and SerializeWithCachedSizes().  | 
675  |  |  | 
676  |  |   // Write a protocol buffer of this message to the given output.  Returns  | 
677  |  |   // false on a write error.  If the message is missing required fields,  | 
678  |  |   // this may ABSL_CHECK-fail.  | 
679  |  |   bool SerializeToCodedStream(io::CodedOutputStream* output) const;  | 
680  |  |   // Like SerializeToCodedStream(), but allows missing required fields.  | 
681  |  |   bool SerializePartialToCodedStream(io::CodedOutputStream* output) const;  | 
682  |  |   // Write the message to the given zero-copy output stream.  All required  | 
683  |  |   // fields must be set.  | 
684  |  |   bool SerializeToZeroCopyStream(io::ZeroCopyOutputStream* output) const;  | 
685  |  |   // Like SerializeToZeroCopyStream(), but allows missing required fields.  | 
686  |  |   bool SerializePartialToZeroCopyStream(io::ZeroCopyOutputStream* output) const;  | 
687  |  |   // Serialize the message and store it in the given string.  All required  | 
688  |  |   // fields must be set.  | 
689  |  |   bool SerializeToString(std::string* output) const;  | 
690  |  |   // Like SerializeToString(), but allows missing required fields.  | 
691  |  |   bool SerializePartialToString(std::string* output) const;  | 
692  |  |   // Serialize the message and store it in the given byte array.  All required  | 
693  |  |   // fields must be set.  | 
694  |  |   bool SerializeToArray(void* data, int size) const;  | 
695  |  |   // Like SerializeToArray(), but allows missing required fields.  | 
696  |  |   bool SerializePartialToArray(void* data, int size) const;  | 
697  |  |  | 
698  |  |   // Make a string encoding the message. Is equivalent to calling  | 
699  |  |   // SerializeToString() on a string and using that.  Returns the empty  | 
700  |  |   // string if SerializeToString() would have returned an error.  | 
701  |  |   // Note: If you intend to generate many such strings, you may  | 
702  |  |   // reduce heap fragmentation by instead re-using the same string  | 
703  |  |   // object with calls to SerializeToString().  | 
704  |  |   std::string SerializeAsString() const;  | 
705  |  |   // Like SerializeAsString(), but allows missing required fields.  | 
706  |  |   std::string SerializePartialAsString() const;  | 
707  |  |  | 
708  |  |   // Serialize the message and write it to the given file descriptor.  All  | 
709  |  |   // required fields must be set.  | 
710  |  |   bool SerializeToFileDescriptor(int file_descriptor) const;  | 
711  |  |   // Like SerializeToFileDescriptor(), but allows missing required fields.  | 
712  |  |   bool SerializePartialToFileDescriptor(int file_descriptor) const;  | 
713  |  |   // Serialize the message and write it to the given C++ ostream.  All  | 
714  |  |   // required fields must be set.  | 
715  |  |   bool SerializeToOstream(std::ostream* output) const;  | 
716  |  |   // Like SerializeToOstream(), but allows missing required fields.  | 
717  |  |   bool SerializePartialToOstream(std::ostream* output) const;  | 
718  |  |  | 
719  |  |   // Like SerializeToString(), but appends to the data to the string's  | 
720  |  |   // existing contents.  All required fields must be set.  | 
721  |  |   bool AppendToString(std::string* output) const;  | 
722  |  |   // Like AppendToString(), but allows missing required fields.  | 
723  |  |   bool AppendPartialToString(std::string* output) const;  | 
724  |  |  | 
725  |  |   // Reads a protocol buffer from a Cord and merges it into this message.  | 
726  |  |   bool MergeFromCord(const absl::Cord& cord);  | 
727  |  |   // Like MergeFromCord(), but accepts messages that are missing  | 
728  |  |   // required fields.  | 
729  |  |   bool MergePartialFromCord(const absl::Cord& cord);  | 
730  |  |   // Parse a protocol buffer contained in a Cord.  | 
731  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParseFromCord(const absl::Cord& cord);  | 
732  |  |   // Like ParseFromCord(), but accepts messages that are missing  | 
733  |  |   // required fields.  | 
734  |  |   ABSL_ATTRIBUTE_REINITIALIZES bool ParsePartialFromCord(  | 
735  |  |       const absl::Cord& cord);  | 
736  |  |  | 
737  |  |   // Serialize the message and store it in the given Cord.  All required  | 
738  |  |   // fields must be set.  | 
739  |  |   bool SerializeToCord(absl::Cord* output) const;  | 
740  |  |   // Like SerializeToCord(), but allows missing required fields.  | 
741  |  |   bool SerializePartialToCord(absl::Cord* output) const;  | 
742  |  |  | 
743  |  |   // Make a Cord encoding the message. Is equivalent to calling  | 
744  |  |   // SerializeToCord() on a Cord and using that.  Returns an empty  | 
745  |  |   // Cord if SerializeToCord() would have returned an error.  | 
746  |  |   absl::Cord SerializeAsCord() const;  | 
747  |  |   // Like SerializeAsCord(), but allows missing required fields.  | 
748  |  |   absl::Cord SerializePartialAsCord() const;  | 
749  |  |  | 
750  |  |   // Like SerializeToCord(), but appends to the data to the Cord's existing  | 
751  |  |   // contents.  All required fields must be set.  | 
752  |  |   bool AppendToCord(absl::Cord* output) const;  | 
753  |  |   // Like AppendToCord(), but allows missing required fields.  | 
754  |  |   bool AppendPartialToCord(absl::Cord* output) const;  | 
755  |  |  | 
756  |  |   // Computes the serialized size of the message.  This recursively calls  | 
757  |  |   // ByteSizeLong() on all embedded messages.  | 
758  |  |   //  | 
759  |  |   // ByteSizeLong() is generally linear in the number of fields defined for the  | 
760  |  |   // proto.  | 
761  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
762  |  |   size_t ByteSizeLong() const { return _class_data_->byte_size_long(*this); } | 
763  |  | #else  | 
764  |  |   virtual size_t ByteSizeLong() const = 0;  | 
765  |  | #endif  // PROTOBUF_CUSTOM_VTABLE  | 
766  |  |  | 
767  |  |   // Legacy ByteSize() API.  | 
768  | 0  |   [[deprecated("Please use ByteSizeLong() instead")]] int ByteSize() const { | 
769  | 0  |     return internal::ToIntSize(ByteSizeLong());  | 
770  | 0  |   }  | 
771  |  |  | 
772  |  |   // Serializes the message without recomputing the size.  The message must not  | 
773  |  |   // have changed since the last call to ByteSize(), and the value returned by  | 
774  |  |   // ByteSize must be non-negative.  Otherwise the results are undefined.  | 
775  | 0  |   void SerializeWithCachedSizes(io::CodedOutputStream* output) const { | 
776  | 0  |     output->SetCur(_InternalSerialize(output->Cur(), output->EpsCopy()));  | 
777  | 0  |   }  | 
778  |  |  | 
779  |  |   // Functions below here are not part of the public interface.  It isn't  | 
780  |  |   // enforced, but they should be treated as private, and will be private  | 
781  |  |   // at some future time.  Unfortunately the implementation of the "friend"  | 
782  |  |   // keyword in GCC is broken at the moment, but we expect it will be fixed.  | 
783  |  |  | 
784  |  |   // Like SerializeWithCachedSizes, but writes directly to *target, returning  | 
785  |  |   // a pointer to the byte immediately after the last byte written.  "target"  | 
786  |  |   // must point at a byte array of at least ByteSize() bytes.  Whether to use  | 
787  |  |   // deterministic serialization, e.g., maps in sorted order, is determined by  | 
788  |  |   // CodedOutputStream::IsDefaultSerializationDeterministic().  | 
789  |  |   uint8_t* SerializeWithCachedSizesToArray(uint8_t* target) const;  | 
790  |  |  | 
791  |  |   // Returns the result of the last call to ByteSize().  An embedded message's  | 
792  |  |   // size is needed both to serialize it (only true for length-prefixed  | 
793  |  |   // submessages) and to compute the outer message's size.  Caching  | 
794  |  |   // the size avoids computing it multiple times.  | 
795  |  |   // Note that the submessage size is unnecessary when using  | 
796  |  |   // group encoding / delimited since we have SGROUP/EGROUP bounds.  | 
797  |  |   //  | 
798  |  |   // ByteSize() does not automatically use the cached size when available  | 
799  |  |   // because this would require invalidating it every time the message was  | 
800  |  |   // modified, which would be too hard and expensive.  (E.g. if a deeply-nested  | 
801  |  |   // sub-message is changed, all of its parents' cached sizes would need to be  | 
802  |  |   // invalidated, which is too much work for an otherwise inlined setter  | 
803  |  |   // method.)  | 
804  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
805  |  |   int GetCachedSize() const { return AccessCachedSize().Get(); } | 
806  |  | #else  | 
807  |  |   int GetCachedSize() const;  | 
808  |  | #endif  | 
809  |  |  | 
810  |  |   const char* _InternalParse(const char* ptr, internal::ParseContext* ctx);  | 
811  |  |  | 
812  |  |   void OnDemandRegisterArenaDtor(Arena* arena);  | 
813  |  |  | 
814  |  |  protected:  | 
815  |  |   // Message implementations require access to internally visible API.  | 
816  | 157k  |   static constexpr internal::InternalVisibility internal_visibility() { | 
817  | 157k  |     return internal::InternalVisibility{}; | 
818  | 157k  |   }  | 
819  |  |  | 
820  |  |   template <typename T>  | 
821  | 0  |   PROTOBUF_ALWAYS_INLINE static T* DefaultConstruct(Arena* arena) { | 
822  | 0  |     return static_cast<T*>(Arena::DefaultConstruct<T>(arena));  | 
823  | 0  |   } Unexecuted instantiation: google::protobuf::Any* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::Any>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::UninterpretedOption_NamePart* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::UninterpretedOption_NamePart>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::SourceCodeInfo_Location* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::SourceCodeInfo_Location>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::GeneratedCodeInfo_Annotation* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::GeneratedCodeInfo_Annotation>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::FieldOptions_FeatureSupport* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::FieldOptions_FeatureSupport>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::FieldOptions_EditionDefault* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::FieldOptions_EditionDefault>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::FeatureSet* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::FeatureSet>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::ExtensionRangeOptions_Declaration* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::ExtensionRangeOptions_Declaration>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::EnumDescriptorProto_EnumReservedRange* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::EnumDescriptorProto_EnumReservedRange>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::DescriptorProto_ReservedRange* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::DescriptorProto_ReservedRange>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::UninterpretedOption* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::UninterpretedOption>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::SourceCodeInfo* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::SourceCodeInfo>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::GeneratedCodeInfo* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::GeneratedCodeInfo>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::FeatureSetDefaults_FeatureSetEditionDefault>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::ServiceOptions* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::ServiceOptions>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::OneofOptions* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::OneofOptions>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::MethodOptions* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::MethodOptions>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::MessageOptions* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::MessageOptions>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::FileOptions* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::FileOptions>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::FieldOptions* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::FieldOptions>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::FeatureSetDefaults* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::FeatureSetDefaults>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::ExtensionRangeOptions* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::ExtensionRangeOptions>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::EnumValueOptions* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::EnumValueOptions>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::EnumOptions* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::EnumOptions>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::OneofDescriptorProto* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::OneofDescriptorProto>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::MethodDescriptorProto* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::MethodDescriptorProto>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::FieldDescriptorProto* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::FieldDescriptorProto>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::EnumValueDescriptorProto* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::EnumValueDescriptorProto>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::DescriptorProto_ExtensionRange* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::DescriptorProto_ExtensionRange>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::ServiceDescriptorProto* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::ServiceDescriptorProto>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::EnumDescriptorProto* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::EnumDescriptorProto>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::DescriptorProto* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::DescriptorProto>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::FileDescriptorProto* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::FileDescriptorProto>(google::protobuf::Arena*) Unexecuted instantiation: google::protobuf::FileDescriptorSet* google::protobuf::MessageLite::DefaultConstruct<google::protobuf::FileDescriptorSet>(google::protobuf::Arena*) Unexecuted instantiation: iCCP* google::protobuf::MessageLite::DefaultConstruct<iCCP>(google::protobuf::Arena*) Unexecuted instantiation: PLTE* google::protobuf::MessageLite::DefaultConstruct<PLTE>(google::protobuf::Arena*) Unexecuted instantiation: OtherChunk* google::protobuf::MessageLite::DefaultConstruct<OtherChunk>(google::protobuf::Arena*) Unexecuted instantiation: IHDR* google::protobuf::MessageLite::DefaultConstruct<IHDR>(google::protobuf::Arena*) Unexecuted instantiation: IDAT* google::protobuf::MessageLite::DefaultConstruct<IDAT>(google::protobuf::Arena*) Unexecuted instantiation: PngChunk* google::protobuf::MessageLite::DefaultConstruct<PngChunk>(google::protobuf::Arena*) Unexecuted instantiation: PngProto* google::protobuf::MessageLite::DefaultConstruct<PngProto>(google::protobuf::Arena*)  | 
824  |  |  | 
825  |  |   template <typename T>  | 
826  |  |   static void* NewImpl(const void*, void* mem, Arena* arena) { | 
827  |  |     return ::new (mem) T(arena);  | 
828  |  |   }  | 
829  |  |   template <typename T>  | 
830  | 0  |   static constexpr internal::MessageCreator GetNewImpl() { | 
831  | 0  | #if defined(__cpp_if_constexpr)  | 
832  | 0  |     if constexpr (internal::EnableCustomNewFor<T>()) { | 
833  | 0  | #else  | 
834  | 0  |     // Equally valid code, but might be more work for the compiler  | 
835  | 0  |     if (internal::EnableCustomNewFor<T>()) { | 
836  | 0  | #endif  | 
837  | 0  |       return T::InternalNewImpl_();  | 
838  | 0  |     } else { | 
839  | 0  |       return internal::MessageCreator(&T::PlacementNew_, sizeof(T), alignof(T));  | 
840  | 0  |     }  | 
841  | 0  |   } Unexecuted instantiation: google::protobuf::internal::MessageCreator google::protobuf::MessageLite::GetNewImpl<IHDR>() Unexecuted instantiation: google::protobuf::internal::MessageCreator google::protobuf::MessageLite::GetNewImpl<PLTE>() Unexecuted instantiation: google::protobuf::internal::MessageCreator google::protobuf::MessageLite::GetNewImpl<IDAT>() Unexecuted instantiation: google::protobuf::internal::MessageCreator google::protobuf::MessageLite::GetNewImpl<iCCP>() Unexecuted instantiation: google::protobuf::internal::MessageCreator google::protobuf::MessageLite::GetNewImpl<OtherChunk>() Unexecuted instantiation: google::protobuf::internal::MessageCreator google::protobuf::MessageLite::GetNewImpl<PngChunk>() Unexecuted instantiation: google::protobuf::internal::MessageCreator google::protobuf::MessageLite::GetNewImpl<PngProto>()  | 
842  |  |  | 
843  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
844  |  |   template <typename T>  | 
845  |  |   static constexpr auto GetClearImpl() { | 
846  |  |     return static_cast<void (MessageLite::*)()>(&T::Clear);  | 
847  |  |   }  | 
848  |  | #else   // PROTOBUF_CUSTOM_VTABLE  | 
849  |  |   // When custom vtables are off we avoid instantiating the functions because we  | 
850  |  |   // will not use them anyway. Less work for the compiler.  | 
851  |  |   template <typename T>  | 
852  |  |   using GetClearImpl = std::nullptr_t;  | 
853  |  | #endif  // PROTOBUF_CUSTOM_VTABLE  | 
854  |  |  | 
855  |  |   template <typename T>  | 
856  | 0  |   PROTOBUF_ALWAYS_INLINE static T* CopyConstruct(Arena* arena, const T& from) { | 
857  | 0  |     return static_cast<T*>(Arena::CopyConstruct<T>(arena, &from));  | 
858  | 0  |   } Unexecuted instantiation: PLTE* google::protobuf::MessageLite::CopyConstruct<PLTE>(google::protobuf::Arena*, PLTE const&) Unexecuted instantiation: IDAT* google::protobuf::MessageLite::CopyConstruct<IDAT>(google::protobuf::Arena*, IDAT const&) Unexecuted instantiation: iCCP* google::protobuf::MessageLite::CopyConstruct<iCCP>(google::protobuf::Arena*, iCCP const&) Unexecuted instantiation: OtherChunk* google::protobuf::MessageLite::CopyConstruct<OtherChunk>(google::protobuf::Arena*, OtherChunk const&) Unexecuted instantiation: IHDR* google::protobuf::MessageLite::CopyConstruct<IHDR>(google::protobuf::Arena*, IHDR const&)  | 
859  |  |  | 
860  | 0  |   const internal::TcParseTableBase* GetTcParseTable() const { | 
861  | 0  |     auto* data = GetClassData();  | 
862  | 0  |     ABSL_DCHECK(data != nullptr);  | 
863  | 0  | 
  | 
864  | 0  |     auto* tc_table = data->tc_table;  | 
865  | 0  |     if (ABSL_PREDICT_FALSE(tc_table == nullptr)) { | 
866  | 0  |       ABSL_DCHECK(!data->is_lite);  | 
867  | 0  |       return data->full().descriptor_methods->get_tc_table(*this);  | 
868  | 0  |     }  | 
869  | 0  |     return tc_table;  | 
870  | 0  |   }  | 
871  |  |  | 
872  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
873  |  |   explicit constexpr MessageLite(const internal::ClassData* data)  | 
874  |  |       : _class_data_(data) {} | 
875  |  |   explicit MessageLite(Arena* arena, const internal::ClassData* data)  | 
876  |  |       : _internal_metadata_(arena), _class_data_(data) {} | 
877  |  | #else   // PROTOBUF_CUSTOM_VTABLE  | 
878  | 0  |   constexpr MessageLite() {} | 
879  | 157k  |   explicit MessageLite(Arena* arena) : _internal_metadata_(arena) {} | 
880  | 0  |   explicit constexpr MessageLite(const internal::ClassData*) {} | 
881  |  |   explicit MessageLite(Arena* arena, const internal::ClassData*)  | 
882  | 0  |       : _internal_metadata_(arena) {} | 
883  |  | #endif  // PROTOBUF_CUSTOM_VTABLE  | 
884  |  |  | 
885  |  |   // GetClassData() returns a pointer to a ClassData struct which  | 
886  |  |   // exists in global memory and is unique to each subclass.  This uniqueness  | 
887  |  |   // property is used in order to quickly determine whether two messages are  | 
888  |  |   // of the same type.  | 
889  |  |   //  | 
890  |  |   // This is a work in progress. There are still some types (eg MapEntry) that  | 
891  |  |   // return a default table instead of a unique one.  | 
892  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
893  |  |   const internal::ClassData* GetClassData() const { | 
894  |  |     ::absl::PrefetchToLocalCache(_class_data_);  | 
895  |  |     return _class_data_;  | 
896  |  |   }  | 
897  |  | #else   // PROTOBUF_CUSTOM_VTABLE  | 
898  |  |   virtual const internal::ClassData* GetClassData() const = 0;  | 
899  |  | #endif  // PROTOBUF_CUSTOM_VTABLE  | 
900  |  |  | 
901  |  |   template <typename T>  | 
902  | 0  |   static auto GetClassDataGenerated() { | 
903  | 0  |     static_assert(std::is_base_of<MessageLite, T>::value, "");  | 
904  | 0  |     // We could speed this up if needed by avoiding the function call.  | 
905  | 0  |     // In LTO this is likely inlined, so it might not matter.  | 
906  | 0  |     static_assert(  | 
907  | 0  |         std::is_same<const T&, decltype(T::default_instance())>::value, "");  | 
908  | 0  |     return T::default_instance().T::GetClassData();  | 
909  | 0  |   }  | 
910  |  |  | 
911  |  |   internal::InternalMetadata _internal_metadata_;  | 
912  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
913  |  |   const internal::ClassData* _class_data_;  | 
914  |  | #endif  // PROTOBUF_CUSTOM_VTABLE  | 
915  |  |  | 
916  |  |   // Return the cached size object as described by  | 
917  |  |   // ClassData::cached_size_offset.  | 
918  | 0  |   const internal::CachedSize& AccessCachedSize() const { | 
919  | 0  |     return *reinterpret_cast<const internal::CachedSize*>(  | 
920  | 0  |         reinterpret_cast<const char*>(this) +  | 
921  | 0  |         GetClassData()->cached_size_offset);  | 
922  | 0  |   }  | 
923  |  |  | 
924  |  |  public:  | 
925  |  |   enum ParseFlags { | 
926  |  |     // Merge vs. Parse:  | 
927  |  |     // Merge: overwrites scalar fields but appends to repeated fields in the  | 
928  |  |     //        destination; other fields in the destination remain untouched.  | 
929  |  |     // Parse: clears all fields in the destination before calling Merge.  | 
930  |  |     kMerge = 0,  | 
931  |  |     kParse = 1,  | 
932  |  |     // Default behaviour vs. Partial:  | 
933  |  |     // Default: a missing required field is deemed as parsing failure.  | 
934  |  |     // Partial: parse or merge will not give an error if input is missing  | 
935  |  |     //          required fields.  | 
936  |  |     kMergePartial = 2,  | 
937  |  |     kParsePartial = 3,  | 
938  |  |     // Default behaviour vs. Aliasing:  | 
939  |  |     // Default:  when merging, pointer is followed and expanded (deep-copy).  | 
940  |  |     // Aliasing: when merging, the destination message is allowed to retain  | 
941  |  |     //           pointers to the original structure (shallow-copy). This mostly  | 
942  |  |     //           is intended for use with STRING_PIECE.  | 
943  |  |     // NOTE: STRING_PIECE is not recommended for new usage. Prefer Cords.  | 
944  |  |     kMergeWithAliasing = 4,  | 
945  |  |     kParseWithAliasing = 5,  | 
946  |  |     kMergePartialWithAliasing = 6,  | 
947  |  |     kParsePartialWithAliasing = 7  | 
948  |  |   };  | 
949  |  |  | 
950  |  |   template <ParseFlags flags, typename T>  | 
951  |  |   bool ParseFrom(const T& input);  | 
952  |  |  | 
953  |  |   // Fast path when conditions match (ie. non-deterministic)  | 
954  |  |   //  uint8_t* _InternalSerialize(uint8_t* ptr) const;  | 
955  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
956  |  |   uint8_t* _InternalSerialize(uint8_t* ptr,  | 
957  |  |                               io::EpsCopyOutputStream* stream) const { | 
958  |  |     return _class_data_->serialize(*this, ptr, stream);  | 
959  |  |   }  | 
960  |  | #else   // PROTOBUF_CUSTOM_VTABLE  | 
961  |  |   virtual uint8_t* _InternalSerialize(  | 
962  |  |       uint8_t* ptr, io::EpsCopyOutputStream* stream) const = 0;  | 
963  |  | #endif  // PROTOBUF_CUSTOM_VTABLE  | 
964  |  |  | 
965  |  |   // Identical to IsInitialized() except that it logs an error message.  | 
966  | 0  |   bool IsInitializedWithErrors() const { | 
967  | 0  |     if (IsInitialized()) return true;  | 
968  | 0  |     LogInitializationErrorMessage();  | 
969  | 0  |     return false;  | 
970  | 0  |   }  | 
971  |  |  | 
972  |  | #if defined(PROTOBUF_CUSTOM_VTABLE)  | 
973  |  |   void operator delete(MessageLite* msg, std::destroying_delete_t) { | 
974  |  |     msg->DeleteInstance();  | 
975  |  |   }  | 
976  |  | #endif  | 
977  |  |  | 
978  |  |  private:  | 
979  |  |   friend class FastReflectionMessageMutator;  | 
980  |  |   friend class AssignDescriptorsHelper;  | 
981  |  |   friend class FastReflectionStringSetter;  | 
982  |  |   friend class Message;  | 
983  |  |   friend class Reflection;  | 
984  |  |   friend class TypeId;  | 
985  |  |   friend class compiler::cpp::MessageTableTester;  | 
986  |  |   friend class internal::DescriptorPoolExtensionFinder;  | 
987  |  |   friend class internal::ExtensionSet;  | 
988  |  |   friend class internal::LazyField;  | 
989  |  |   friend class internal::SwapFieldHelper;  | 
990  |  |   friend class internal::TcParser;  | 
991  |  |   friend struct internal::TcParseTableBase;  | 
992  |  |   friend class internal::UntypedMapBase;  | 
993  |  |   friend class internal::WeakFieldMap;  | 
994  |  |   friend class internal::WireFormatLite;  | 
995  |  |   friend class internal::RustMapHelper;  | 
996  |  |   friend internal::MessageCreator;  | 
997  |  |  | 
998  |  |   template <typename Type>  | 
999  |  |   friend class Arena::InternalHelper;  | 
1000  |  |  | 
1001  |  |   friend auto internal::GetClassData(const MessageLite& msg);  | 
1002  |  |  | 
1003  |  |   void LogInitializationErrorMessage() const;  | 
1004  |  |  | 
1005  |  |   bool MergeFromImpl(io::CodedInputStream* input, ParseFlags parse_flags);  | 
1006  |  |  | 
1007  |  |   // Runs the destructor for this instance.  | 
1008  |  |   void DestroyInstance();  | 
1009  |  |   // Runs the destructor for this instance and deletes the memory via  | 
1010  |  |   // `operator delete`  | 
1011  |  |   void DeleteInstance();  | 
1012  |  |  | 
1013  |  |   // For tests that need to inspect private _oneof_case_. It is the callers  | 
1014  |  |   // responsibility to ensure T has the right member.  | 
1015  |  |   template <typename T>  | 
1016  |  |   static uint32_t GetOneofCaseOffsetForTesting() { | 
1017  |  |     return offsetof(T, _impl_._oneof_case_);  | 
1018  |  |   }  | 
1019  |  | };  | 
1020  |  |  | 
1021  |  | // A `std::type_info` equivalent for protobuf message types.  | 
1022  |  | // This class is preferred over using `typeid` for a few reasons:  | 
1023  |  | //  - It works with RTTI disabled.  | 
1024  |  | //  - It works for `DynamicMessage` types.  | 
1025  |  | //  - It works in custom vtable mode.  | 
1026  |  | //  | 
1027  |  | // Usage:  | 
1028  |  | //  - Instead of `typeid(Type)` use `TypeId::Get<Type>()`  | 
1029  |  | //  - Instead of `typeid(expr)` use `TypeId::Get(expr)`  | 
1030  |  | //  | 
1031  |  | // Supports all relationals including <=>, and supports hashing via  | 
1032  |  | // `absl::Hash`.  | 
1033  |  | class TypeId { | 
1034  |  |  public:  | 
1035  | 0  |   static TypeId Get(const MessageLite& msg) { | 
1036  | 0  |     return TypeId(msg.GetClassData());  | 
1037  | 0  |   }  | 
1038  |  |  | 
1039  |  |   template <typename T>  | 
1040  | 0  |   static TypeId Get() { | 
1041  | 0  |     return TypeId(MessageLite::GetClassDataGenerated<T>());  | 
1042  | 0  |   }  | 
1043  |  |  | 
1044  |  |   // Name of the message type.  | 
1045  |  |   // Equivalent to `.GetTypeName()` on the message.  | 
1046  |  |   absl::string_view name() const;  | 
1047  |  |  | 
1048  | 0  |   friend constexpr bool operator==(TypeId a, TypeId b) { | 
1049  | 0  |     return a.data_ == b.data_;  | 
1050  | 0  |   }  | 
1051  | 0  |   friend constexpr bool operator!=(TypeId a, TypeId b) { return !(a == b); } | 
1052  | 0  |   friend constexpr bool operator<(TypeId a, TypeId b) { | 
1053  | 0  |     return a.data_ < b.data_;  | 
1054  | 0  |   }  | 
1055  | 0  |   friend constexpr bool operator>(TypeId a, TypeId b) { | 
1056  | 0  |     return a.data_ > b.data_;  | 
1057  | 0  |   }  | 
1058  | 0  |   friend constexpr bool operator<=(TypeId a, TypeId b) { | 
1059  | 0  |     return a.data_ <= b.data_;  | 
1060  | 0  |   }  | 
1061  | 0  |   friend constexpr bool operator>=(TypeId a, TypeId b) { | 
1062  | 0  |     return a.data_ >= b.data_;  | 
1063  | 0  |   }  | 
1064  |  |  | 
1065  |  | #if defined(__cpp_impl_three_way_comparison) && \  | 
1066  |  |     __cpp_impl_three_way_comparison >= 201907L  | 
1067  |  |   friend constexpr auto operator<=>(TypeId a, TypeId b) { | 
1068  |  |     return a.data_ <=> b.data_;  | 
1069  |  |   }  | 
1070  |  | #endif  | 
1071  |  |  | 
1072  |  |   template <typename H>  | 
1073  |  |   friend H AbslHashValue(H state, TypeId id) { | 
1074  |  |     return H::combine(std::move(state), id.data_);  | 
1075  |  |   }  | 
1076  |  |  | 
1077  |  |  private:  | 
1078  | 0  |   constexpr explicit TypeId(const internal::ClassData* data) : data_(data) {} | 
1079  |  |  | 
1080  |  |   const internal::ClassData* data_;  | 
1081  |  | };  | 
1082  |  |  | 
1083  |  | namespace internal { | 
1084  |  |  | 
1085  | 0  | inline auto GetClassData(const MessageLite& msg) { return msg.GetClassData(); } | 
1086  |  |  | 
1087  |  | template <bool alias>  | 
1088  |  | bool MergeFromImpl(absl::string_view input, MessageLite* msg,  | 
1089  |  |                    const internal::TcParseTableBase* tc_table,  | 
1090  |  |                    MessageLite::ParseFlags parse_flags);  | 
1091  |  | extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl<false>(  | 
1092  |  |     absl::string_view input, MessageLite* msg,  | 
1093  |  |     const internal::TcParseTableBase* tc_table,  | 
1094  |  |     MessageLite::ParseFlags parse_flags);  | 
1095  |  | extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl<true>(  | 
1096  |  |     absl::string_view input, MessageLite* msg,  | 
1097  |  |     const internal::TcParseTableBase* tc_table,  | 
1098  |  |     MessageLite::ParseFlags parse_flags);  | 
1099  |  |  | 
1100  |  | template <bool alias>  | 
1101  |  | bool MergeFromImpl(io::ZeroCopyInputStream* input, MessageLite* msg,  | 
1102  |  |                    const internal::TcParseTableBase* tc_table,  | 
1103  |  |                    MessageLite::ParseFlags parse_flags);  | 
1104  |  | extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl<false>(  | 
1105  |  |     io::ZeroCopyInputStream* input, MessageLite* msg,  | 
1106  |  |     const internal::TcParseTableBase* tc_table,  | 
1107  |  |     MessageLite::ParseFlags parse_flags);  | 
1108  |  | extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl<true>(  | 
1109  |  |     io::ZeroCopyInputStream* input, MessageLite* msg,  | 
1110  |  |     const internal::TcParseTableBase* tc_table,  | 
1111  |  |     MessageLite::ParseFlags parse_flags);  | 
1112  |  |  | 
1113  |  | struct BoundedZCIS { | 
1114  |  |   io::ZeroCopyInputStream* zcis;  | 
1115  |  |   int limit;  | 
1116  |  | };  | 
1117  |  |  | 
1118  |  | template <bool alias>  | 
1119  |  | bool MergeFromImpl(BoundedZCIS input, MessageLite* msg,  | 
1120  |  |                    const internal::TcParseTableBase* tc_table,  | 
1121  |  |                    MessageLite::ParseFlags parse_flags);  | 
1122  |  | extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl<false>(  | 
1123  |  |     BoundedZCIS input, MessageLite* msg,  | 
1124  |  |     const internal::TcParseTableBase* tc_table,  | 
1125  |  |     MessageLite::ParseFlags parse_flags);  | 
1126  |  | extern template PROTOBUF_EXPORT_TEMPLATE_DECLARE bool MergeFromImpl<true>(  | 
1127  |  |     BoundedZCIS input, MessageLite* msg,  | 
1128  |  |     const internal::TcParseTableBase* tc_table,  | 
1129  |  |     MessageLite::ParseFlags parse_flags);  | 
1130  |  |  | 
1131  |  | template <typename T>  | 
1132  |  | struct SourceWrapper;  | 
1133  |  |  | 
1134  |  | template <bool alias, typename T>  | 
1135  |  | bool MergeFromImpl(const SourceWrapper<T>& input, MessageLite* msg,  | 
1136  |  |                    const internal::TcParseTableBase* tc_table,  | 
1137  |  |                    MessageLite::ParseFlags parse_flags) { | 
1138  |  |   return input.template MergeInto<alias>(msg, tc_table, parse_flags);  | 
1139  |  | }  | 
1140  |  |  | 
1141  |  | }  // namespace internal  | 
1142  |  |  | 
1143  |  | template <MessageLite::ParseFlags flags, typename T>  | 
1144  |  | bool MessageLite::ParseFrom(const T& input) { | 
1145  |  |   if (flags & kParse) Clear();  | 
1146  |  |   constexpr bool alias = (flags & kMergeWithAliasing) != 0;  | 
1147  |  |   const internal::TcParseTableBase* tc_table;  | 
1148  |  |   PROTOBUF_ALWAYS_INLINE_CALL tc_table = GetTcParseTable();  | 
1149  |  |   return internal::MergeFromImpl<alias>(input, this, tc_table, flags);  | 
1150  |  | }  | 
1151  |  |  | 
1152  |  | // ===================================================================  | 
1153  |  | // Shutdown support.  | 
1154  |  |  | 
1155  |  |  | 
1156  |  | // Shut down the entire protocol buffers library, deleting all static-duration  | 
1157  |  | // objects allocated by the library or by generated .pb.cc files.  | 
1158  |  | //  | 
1159  |  | // There are two reasons you might want to call this:  | 
1160  |  | // * You use a draconian definition of "memory leak" in which you expect  | 
1161  |  | //   every single malloc() to have a corresponding free(), even for objects  | 
1162  |  | //   which live until program exit.  | 
1163  |  | // * You are writing a dynamically-loaded library which needs to clean up  | 
1164  |  | //   after itself when the library is unloaded.  | 
1165  |  | //  | 
1166  |  | // It is safe to call this multiple times.  However, it is not safe to use  | 
1167  |  | // any other part of the protocol buffers library after  | 
1168  |  | // ShutdownProtobufLibrary() has been called. Furthermore this call is not  | 
1169  |  | // thread safe, user needs to synchronize multiple calls.  | 
1170  |  | PROTOBUF_EXPORT void ShutdownProtobufLibrary();  | 
1171  |  |  | 
1172  |  | namespace internal { | 
1173  |  |  | 
1174  |  | // Register a function to be called when ShutdownProtocolBuffers() is called.  | 
1175  |  | PROTOBUF_EXPORT void OnShutdown(void (*func)());  | 
1176  |  | // Run an arbitrary function on an arg  | 
1177  |  | PROTOBUF_EXPORT void OnShutdownRun(void (*f)(const void*), const void* arg);  | 
1178  |  |  | 
1179  |  | template <typename T>  | 
1180  |  | T* OnShutdownDelete(T* p) { | 
1181  |  |   OnShutdownRun([](const void* pp) { delete static_cast<const T*>(pp); }, p); | 
1182  |  |   return p;  | 
1183  |  | }  | 
1184  |  |  | 
1185  | 0  | inline void AssertDownCast(const MessageLite& from, const MessageLite& to) { | 
1186  | 0  |   ABSL_DCHECK(TypeId::Get(from) == TypeId::Get(to))  | 
1187  | 0  |       << "Cannot downcast " << from.GetTypeName() << " to " << to.GetTypeName();  | 
1188  | 0  | }  | 
1189  |  |  | 
1190  |  | template <bool test_call, typename MessageLite>  | 
1191  |  | PROTOBUF_ALWAYS_INLINE inline MessageLite* MessageCreator::PlacementNew(  | 
1192  |  |     const MessageLite* prototype_for_func,  | 
1193  | 0  |     const MessageLite* prototype_for_copy, void* mem, Arena* arena) const { | 
1194  | 0  |   ABSL_DCHECK_EQ(reinterpret_cast<uintptr_t>(mem) % alignment_, 0u);  | 
1195  | 0  |   const Tag as_tag = tag();  | 
1196  | 0  |   // When the feature is not enabled we skip the `as_tag` check since it is  | 
1197  | 0  |   // unnecessary. Except for testing, where we want to test the copy logic even  | 
1198  | 0  |   // when we can't use it for real messages.  | 
1199  | 0  |   constexpr bool kMustBeFunc = !test_call && !internal::EnableCustomNew();  | 
1200  | 0  |   static_assert(kFunc < 0 && !(kZeroInit < 0) && !(kMemcpy < 0),  | 
1201  | 0  |                 "Only kFunc must be the only negative value");  | 
1202  | 0  |   if (ABSL_PREDICT_FALSE(kMustBeFunc || as_tag < 0)) { | 
1203  | 0  |     PROTOBUF_DEBUG_COUNTER("MessageCreator.Func").Inc(); | 
1204  | 0  |     return static_cast<MessageLite*>(func_(prototype_for_func, mem, arena));  | 
1205  | 0  |   }  | 
1206  | 0  | 
  | 
1207  | 0  |   char* dst = static_cast<char*>(mem);  | 
1208  | 0  |   const size_t size = allocation_size_;  | 
1209  | 0  |   const char* src = reinterpret_cast<const char*>(prototype_for_copy);  | 
1210  | 0  | 
  | 
1211  | 0  |   // These are a bit more efficient than calling normal memset/memcpy because:  | 
1212  | 0  |   //  - We know the minimum size is 16. We have a fallback for when it is not.  | 
1213  | 0  |   //  - We can "underflow" the buffer because those are the MessageLite bytes  | 
1214  | 0  |   //    we will set later.  | 
1215  | 0  | #ifndef PROTO2_OPENSOURCE  | 
1216  | 0  |   // This manual handling shows a 1.85% improvement in the parsing  | 
1217  | 0  |   // microbenchmark.  | 
1218  | 0  |   // TODO: Verify this is still the case.  | 
1219  | 0  | #endif  // !PROTO2_OPENSOUCE  | 
1220  | 0  |   if (as_tag == kZeroInit) { | 
1221  | 0  |     // Make sure the input is really all zeros.  | 
1222  | 0  |     ABSL_DCHECK(std::all_of(src + sizeof(MessageLite), src + size,  | 
1223  | 0  |                             [](auto c) { return c == 0; })); | 
1224  | 0  | 
  | 
1225  | 0  |     if (sizeof(MessageLite) != 16) { | 
1226  | 0  |       memset(dst, 0, size);  | 
1227  | 0  |     } else if (size <= 32) { | 
1228  | 0  |       memset(dst + size - 16, 0, 16);  | 
1229  | 0  |     } else if (size <= 64) { | 
1230  | 0  |       memset(dst + 16, 0, 16);  | 
1231  | 0  |       memset(dst + size - 32, 0, 32);  | 
1232  | 0  |     } else { | 
1233  | 0  |       for (size_t offset = 16; offset + 64 < size; offset += 64) { | 
1234  | 0  |         absl::PrefetchToLocalCacheForWrite(dst + offset + 64);  | 
1235  | 0  |         memset(dst + offset, 0, 64);  | 
1236  | 0  |       }  | 
1237  | 0  |       memset(dst + size - 64, 0, 64);  | 
1238  | 0  |     }  | 
1239  | 0  |   } else { | 
1240  | 0  |     ABSL_DCHECK_EQ(+as_tag, +kMemcpy);  | 
1241  | 0  | 
  | 
1242  | 0  |     if (sizeof(MessageLite) != 16) { | 
1243  | 0  |       memcpy(dst, src, size);  | 
1244  | 0  |     } else if (size <= 32) { | 
1245  | 0  |       memcpy(dst + size - 16, src + size - 16, 16);  | 
1246  | 0  |     } else if (size <= 64) { | 
1247  | 0  |       memcpy(dst + 16, src + 16, 16);  | 
1248  | 0  |       memcpy(dst + size - 32, src + size - 32, 32);  | 
1249  | 0  |     } else { | 
1250  | 0  |       for (size_t offset = 16; offset + 64 < size; offset += 64) { | 
1251  | 0  |         absl::PrefetchToLocalCache(src + offset + 64);  | 
1252  | 0  |         absl::PrefetchToLocalCacheForWrite(dst + offset + 64);  | 
1253  | 0  |         memcpy(dst + offset, src + offset, 64);  | 
1254  | 0  |       }  | 
1255  | 0  |       memcpy(dst + size - 64, src + size - 64, 64);  | 
1256  | 0  |     }  | 
1257  | 0  |   }  | 
1258  | 0  | 
  | 
1259  | 0  |   if (arena_bits() != 0) { | 
1260  | 0  |     if (as_tag == kZeroInit) { | 
1261  | 0  |       PROTOBUF_DEBUG_COUNTER("MessageCreator.ZeroArena").Inc(); | 
1262  | 0  |     } else { | 
1263  | 0  |       PROTOBUF_DEBUG_COUNTER("MessageCreator.McpyArena").Inc(); | 
1264  | 0  |     }  | 
1265  | 0  |   } else { | 
1266  | 0  |     if (as_tag == kZeroInit) { | 
1267  | 0  |       PROTOBUF_DEBUG_COUNTER("MessageCreator.Zero").Inc(); | 
1268  | 0  |     } else { | 
1269  | 0  |       PROTOBUF_DEBUG_COUNTER("MessageCreator.Mcpy").Inc(); | 
1270  | 0  |     }  | 
1271  | 0  |   }  | 
1272  | 0  | 
  | 
1273  | 0  |   if (internal::PerformDebugChecks() || arena != nullptr) { | 
1274  | 0  |     if (uintptr_t offsets = arena_bits()) { | 
1275  | 0  |       do { | 
1276  | 0  |         const size_t offset = absl::countr_zero(offsets) * sizeof(Arena*);  | 
1277  | 0  |         ABSL_DCHECK_LE(offset + sizeof(Arena*), size);  | 
1278  | 0  |         // Verify we are overwriting a null pointer. If we are not, there is a  | 
1279  | 0  |         // bug somewhere.  | 
1280  | 0  |         ABSL_DCHECK_EQ(*reinterpret_cast<Arena**>(dst + offset), nullptr);  | 
1281  | 0  |         memcpy(dst + offset, &arena, sizeof(arena));  | 
1282  | 0  |         offsets &= offsets - 1;  | 
1283  | 0  |       } while (offsets != 0);  | 
1284  | 0  |     }  | 
1285  | 0  |   }  | 
1286  | 0  | 
  | 
1287  | 0  |   // The second memcpy overwrites part of the first, but the compiler should  | 
1288  | 0  |   // avoid the double-write. It's easier than trying to avoid the overlap.  | 
1289  | 0  |   memcpy(dst, static_cast<const void*>(prototype_for_copy),  | 
1290  | 0  |          sizeof(MessageLite));  | 
1291  | 0  |   memcpy(dst + PROTOBUF_FIELD_OFFSET(MessageLite, _internal_metadata_), &arena,  | 
1292  | 0  |          sizeof(arena));  | 
1293  | 0  |   return Launder(reinterpret_cast<MessageLite*>(mem));  | 
1294  | 0  | }  | 
1295  |  |  | 
1296  |  | template <bool test_call, typename MessageLite>  | 
1297  |  | PROTOBUF_ALWAYS_INLINE inline MessageLite* MessageCreator::New(  | 
1298  |  |     const MessageLite* prototype_for_func,  | 
1299  | 0  |     const MessageLite* prototype_for_copy, Arena* arena) const { | 
1300  | 0  |   return PlacementNew<test_call>(prototype_for_func, prototype_for_copy,  | 
1301  | 0  |                                  arena != nullptr  | 
1302  | 0  |                                      ? arena->AllocateAligned(allocation_size_)  | 
1303  | 0  |                                      : ::operator new(allocation_size_),  | 
1304  | 0  |                                  arena);  | 
1305  | 0  | }  | 
1306  |  |  | 
1307  |  | }  // namespace internal  | 
1308  |  |  | 
1309  |  | std::string ShortFormat(const MessageLite& message_lite);  | 
1310  |  | std::string Utf8Format(const MessageLite& message_lite);  | 
1311  |  |  | 
1312  |  | // Cast functions for message pointer/references.  | 
1313  |  | // This is the supported API to cast from a Message/MessageLite to derived  | 
1314  |  | // types. These work even when RTTI is disabled on message types.  | 
1315  |  | //  | 
1316  |  | // The template parameter is simplified and the return type is inferred from the  | 
1317  |  | // input. Eg just `DynamicCastMessage<Foo>(x)` instead of  | 
1318  |  | // `DynamicCastMessage<const Foo*>(x)`.  | 
1319  |  | //  | 
1320  |  | // `DynamicCastMessage` is similar to `dynamic_cast`, returns `nullptr` when the  | 
1321  |  | // input is not an instance of `T`. The overloads that take a reference will  | 
1322  |  | // terminate on mismatch.  | 
1323  |  | //  | 
1324  |  | // `DownCastMessage` is a lightweight function for downcasting base  | 
1325  |  | // `MessageLite` pointer to derived type, where it only does type checking if  | 
1326  |  | // !NDEBUG. It should only be used when the caller is certain that the input  | 
1327  |  | // message is of instance `T`.  | 
1328  |  | template <typename T>  | 
1329  | 0  | const T* DynamicCastMessage(const MessageLite* from) { | 
1330  | 0  |   static_assert(std::is_base_of<MessageLite, T>::value, "");  | 
1331  | 0  | 
  | 
1332  | 0  |   // We might avoid the call to T::GetClassData() altogether if T were to  | 
1333  | 0  |   // expose the class data pointer.  | 
1334  | 0  |   if (from == nullptr || TypeId::Get<T>() != TypeId::Get(*from)) { | 
1335  | 0  |     return nullptr;  | 
1336  | 0  |   }  | 
1337  | 0  | 
  | 
1338  | 0  |   return static_cast<const T*>(from);  | 
1339  | 0  | }  | 
1340  |  |  | 
1341  |  | template <typename T>  | 
1342  |  | T* DynamicCastMessage(MessageLite* from) { | 
1343  |  |   return const_cast<T*>(  | 
1344  |  |       DynamicCastMessage<T>(static_cast<const MessageLite*>(from)));  | 
1345  |  | }  | 
1346  |  |  | 
1347  |  | namespace internal { | 
1348  |  | [[noreturn]] PROTOBUF_EXPORT void FailDynamicCast(const MessageLite& from,  | 
1349  |  |                                                   const MessageLite& to);  | 
1350  |  | }  // namespace internal  | 
1351  |  |  | 
1352  |  | template <typename T>  | 
1353  |  | const T& DynamicCastMessage(const MessageLite& from) { | 
1354  |  |   const T* destination_message = DynamicCastMessage<T>(&from);  | 
1355  |  |   if (ABSL_PREDICT_FALSE(destination_message == nullptr)) { | 
1356  |  |     // Move the logging into an out-of-line function to reduce bloat in the  | 
1357  |  |     // caller.  | 
1358  |  |     internal::FailDynamicCast(from, T::default_instance());  | 
1359  |  |   }  | 
1360  |  |   return *destination_message;  | 
1361  |  | }  | 
1362  |  |  | 
1363  |  | template <typename T>  | 
1364  |  | T& DynamicCastMessage(MessageLite& from) { | 
1365  |  |   return const_cast<T&>(  | 
1366  |  |       DynamicCastMessage<T>(static_cast<const MessageLite&>(from)));  | 
1367  |  | }  | 
1368  |  |  | 
1369  |  | template <typename T>  | 
1370  | 18.4k  | const T* DownCastMessage(const MessageLite* from) { | 
1371  | 18.4k  |   internal::StrongReferenceToType<T>();  | 
1372  | 36.8k  |   ABSL_DCHECK(DynamicCastMessage<T>(from) == from)  | 
1373  | 36.8k  |       << "Cannot downcast " << from->GetTypeName() << " to "  | 
1374  | 36.8k  |       << T::default_instance().GetTypeName();  | 
1375  | 18.4k  |   return static_cast<const T*>(from);  | 
1376  | 18.4k  | }  | 
1377  |  |  | 
1378  |  | template <typename T>  | 
1379  | 18.4k  | T* DownCastMessage(MessageLite* from) { | 
1380  | 18.4k  |   return const_cast<T*>(  | 
1381  | 18.4k  |       DownCastMessage<T>(static_cast<const MessageLite*>(from)));  | 
1382  | 18.4k  | }  | 
1383  |  |  | 
1384  |  | template <typename T>  | 
1385  |  | const T& DownCastMessage(const MessageLite& from) { | 
1386  |  |   return *DownCastMessage<T>(&from);  | 
1387  |  | }  | 
1388  |  |  | 
1389  |  | template <typename T>  | 
1390  |  | T& DownCastMessage(MessageLite& from) { | 
1391  |  |   return *DownCastMessage<T>(&from);  | 
1392  |  | }  | 
1393  |  |  | 
1394  |  | template <>  | 
1395  | 0  | inline const MessageLite* DynamicCastMessage(const MessageLite* from) { | 
1396  | 0  |   return from;  | 
1397  | 0  | }  | 
1398  |  | template <>  | 
1399  | 0  | inline const MessageLite* DownCastMessage(const MessageLite* from) { | 
1400  | 0  |   return from;  | 
1401  | 0  | }  | 
1402  |  |  | 
1403  |  | // Deprecated names for the cast functions.  | 
1404  |  | // Prefer the ones above.  | 
1405  |  | template <typename T>  | 
1406  |  | PROTOBUF_DEPRECATE_AND_INLINE()  | 
1407  |  | const T* DynamicCastToGenerated(const MessageLite* from) { | 
1408  |  |   return DynamicCastMessage<T>(from);  | 
1409  |  | }  | 
1410  |  |  | 
1411  |  | template <typename T>  | 
1412  |  | PROTOBUF_DEPRECATE_AND_INLINE()  | 
1413  |  | T* DynamicCastToGenerated(MessageLite* from) { | 
1414  |  |   return DynamicCastMessage<T>(from);  | 
1415  |  | }  | 
1416  |  |  | 
1417  |  | template <typename T>  | 
1418  |  | PROTOBUF_DEPRECATE_AND_INLINE()  | 
1419  |  | const T& DynamicCastToGenerated(const MessageLite& from) { | 
1420  |  |   return DynamicCastMessage<T>(from);  | 
1421  |  | }  | 
1422  |  |  | 
1423  |  | template <typename T>  | 
1424  |  | PROTOBUF_DEPRECATE_AND_INLINE()  | 
1425  |  | T& DynamicCastToGenerated(MessageLite& from) { | 
1426  |  |   return DynamicCastMessage<T>(from);  | 
1427  |  | }  | 
1428  |  |  | 
1429  |  | template <typename T>  | 
1430  |  | PROTOBUF_DEPRECATE_AND_INLINE()  | 
1431  |  | const T* DownCastToGenerated(const MessageLite* from) { | 
1432  |  |   return DownCastMessage<T>(from);  | 
1433  |  | }  | 
1434  |  |  | 
1435  |  | template <typename T>  | 
1436  |  | PROTOBUF_DEPRECATE_AND_INLINE()  | 
1437  |  | T* DownCastToGenerated(MessageLite* from) { | 
1438  |  |   return DownCastMessage<T>(from);  | 
1439  |  | }  | 
1440  |  |  | 
1441  |  | template <typename T>  | 
1442  |  | PROTOBUF_DEPRECATE_AND_INLINE()  | 
1443  |  | const T& DownCastToGenerated(const MessageLite& from) { | 
1444  |  |   return DownCastMessage<T>(from);  | 
1445  |  | }  | 
1446  |  |  | 
1447  |  | template <typename T>  | 
1448  |  | PROTOBUF_DEPRECATE_AND_INLINE()  | 
1449  |  | T& DownCastToGenerated(MessageLite& from) { | 
1450  |  |   return DownCastMessage<T>(from);  | 
1451  |  | }  | 
1452  |  |  | 
1453  |  | }  // namespace protobuf  | 
1454  |  | }  // namespace google  | 
1455  |  |  | 
1456  |  | #include "google/protobuf/port_undef.inc"  | 
1457  |  |  | 
1458  |  | #endif  // GOOGLE_PROTOBUF_MESSAGE_LITE_H__  |