Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-31 10:12:25

0001 #ifndef GOOGLE_PROTOBUF_REFLECTION_VISIT_FIELDS_H__
0002 #define GOOGLE_PROTOBUF_REFLECTION_VISIT_FIELDS_H__
0003 
0004 #include <cstdint>
0005 #include <string>
0006 #include <utility>
0007 
0008 #include "absl/base/attributes.h"
0009 #include "absl/log/absl_check.h"
0010 #include "absl/strings/cord.h"
0011 #include "google/protobuf/descriptor.h"
0012 #include "google/protobuf/descriptor.pb.h"
0013 #include "google/protobuf/descriptor_lite.h"
0014 #include "google/protobuf/extension_set.h"
0015 #include "google/protobuf/generated_message_reflection.h"
0016 #include "google/protobuf/message.h"
0017 #include "google/protobuf/port.h"
0018 #include "google/protobuf/reflection.h"
0019 #include "google/protobuf/reflection_visit_field_info.h"
0020 #include "google/protobuf/repeated_field.h"
0021 #include "google/protobuf/repeated_ptr_field.h"
0022 
0023 
0024 // Must be the last include.
0025 #include "google/protobuf/port_def.inc"  // NOLINT
0026 
0027 namespace google {
0028 namespace protobuf {
0029 namespace internal {
0030 
0031 enum class FieldMask : uint32_t {
0032   kInt32 = 1 << FieldDescriptor::CPPTYPE_INT32,
0033   kInt64 = 1 << FieldDescriptor::CPPTYPE_INT64,
0034   kUInt32 = 1 << FieldDescriptor::CPPTYPE_UINT32,
0035   kUInt64 = 1 << FieldDescriptor::CPPTYPE_UINT64,
0036   kDouble = 1 << FieldDescriptor::CPPTYPE_DOUBLE,
0037   kFloat = 1 << FieldDescriptor::CPPTYPE_FLOAT,
0038   kBool = 1 << FieldDescriptor::CPPTYPE_BOOL,
0039   kEnum = 1 << FieldDescriptor::CPPTYPE_ENUM,
0040   kString = 1 << FieldDescriptor::CPPTYPE_STRING,
0041   kMessage = 1 << FieldDescriptor::CPPTYPE_MESSAGE,
0042   kPrimitive =
0043       kInt32 | kInt64 | kUInt32 | kUInt64 | kDouble | kFloat | kBool | kEnum,
0044   kAll = 0xFFFFFFFFu,
0045 };
0046 
0047 inline FieldMask operator|(FieldMask lhs, FieldMask rhs) {
0048   return static_cast<FieldMask>(static_cast<uint32_t>(lhs) |
0049                                 static_cast<uint32_t>(rhs));
0050 }
0051 
0052 #ifdef __cpp_if_constexpr
0053 
0054 template <typename MessageT, typename CallbackFn>
0055 void VisitFields(MessageT& message, CallbackFn&& func,
0056                  FieldMask mask = FieldMask::kAll);
0057 
0058 class ReflectionVisit final {
0059  public:
0060   template <typename MessageT, typename CallbackFn>
0061   static void VisitFields(MessageT& message, CallbackFn&& func, FieldMask mask);
0062 
0063   template <typename CallbackFn>
0064   static void VisitMessageFields(const Message& message, CallbackFn&& func);
0065 
0066   template <typename CallbackFn>
0067   static void VisitMessageFields(Message& message, CallbackFn&& func);
0068 
0069  private:
0070   static const internal::ReflectionSchema& GetSchema(
0071       const Reflection* reflection) {
0072     return reflection->schema_;
0073   }
0074   static const Descriptor* GetDescriptor(const Reflection* reflection) {
0075     return reflection->descriptor_;
0076   }
0077   static const internal::ExtensionSet& ExtensionSet(
0078       const Reflection* reflection, const Message& message) {
0079     return reflection->GetExtensionSet(message);
0080   }
0081   static internal::ExtensionSet& ExtensionSet(const Reflection* reflection,
0082                                               Message& message) {
0083     return *reflection->MutableExtensionSet(&message);
0084   }
0085 };
0086 
0087 inline bool ShouldVisit(FieldMask mask, FieldDescriptor::CppType cpptype) {
0088   if (PROTOBUF_PREDICT_TRUE(mask == FieldMask::kAll)) return true;
0089   return (static_cast<uint32_t>(mask) & (1 << cpptype)) != 0;
0090 }
0091 
0092 template <typename MessageT, typename CallbackFn>
0093 void ReflectionVisit::VisitFields(MessageT& message, CallbackFn&& func,
0094                                   FieldMask mask) {
0095   const Reflection* reflection = message.GetReflection();
0096   const auto& schema = GetSchema(reflection);
0097 
0098   ABSL_CHECK(!schema.HasWeakFields()) << "weak fields are not supported";
0099 
0100   // See Reflection::ListFields for the optimization.
0101   const uint32_t* const has_bits =
0102       schema.HasHasbits() ? reflection->GetHasBits(message) : nullptr;
0103   const uint32_t* const has_bits_indices = schema.has_bit_indices_;
0104   const Descriptor* descriptor = GetDescriptor(reflection);
0105   const int field_count = descriptor->field_count();
0106 
0107   for (int i = 0; i < field_count; i++) {
0108     const FieldDescriptor* field = descriptor->field(i);
0109     ABSL_DCHECK(!field->options().weak()) << "weak fields are not supported";
0110 
0111     if (!ShouldVisit(mask, field->cpp_type())) continue;
0112 
0113     if (field->is_repeated()) {
0114       switch (field->type()) {
0115 #define PROTOBUF_HANDLE_REPEATED_CASE(TYPE, CPPTYPE, NAME)                  \
0116   case FieldDescriptor::TYPE_##TYPE: {                                      \
0117     ABSL_DCHECK(!field->is_map());                                          \
0118     const auto& rep =                                                       \
0119         reflection->GetRawNonOneof<RepeatedField<CPPTYPE>>(message, field); \
0120     if (rep.size() == 0) continue;                                          \
0121     func(internal::Repeated##NAME##DynamicFieldInfo<MessageT>{              \
0122         reflection, message, field, rep});                                  \
0123     break;                                                                  \
0124   }
0125 
0126         PROTOBUF_HANDLE_REPEATED_CASE(DOUBLE, double, Double);
0127         PROTOBUF_HANDLE_REPEATED_CASE(FLOAT, float, Float);
0128         PROTOBUF_HANDLE_REPEATED_CASE(INT64, int64_t, Int64);
0129         PROTOBUF_HANDLE_REPEATED_CASE(UINT64, uint64_t, UInt64);
0130         PROTOBUF_HANDLE_REPEATED_CASE(INT32, int32_t, Int32);
0131         PROTOBUF_HANDLE_REPEATED_CASE(FIXED64, uint64_t, Fixed64);
0132         PROTOBUF_HANDLE_REPEATED_CASE(FIXED32, uint32_t, Fixed32);
0133         PROTOBUF_HANDLE_REPEATED_CASE(BOOL, bool, Bool);
0134         PROTOBUF_HANDLE_REPEATED_CASE(UINT32, uint32_t, UInt32);
0135         PROTOBUF_HANDLE_REPEATED_CASE(ENUM, int, Enum);
0136         PROTOBUF_HANDLE_REPEATED_CASE(SFIXED32, int32_t, SFixed32);
0137         PROTOBUF_HANDLE_REPEATED_CASE(SFIXED64, int64_t, SFixed64);
0138         PROTOBUF_HANDLE_REPEATED_CASE(SINT32, int32_t, SInt32);
0139         PROTOBUF_HANDLE_REPEATED_CASE(SINT64, int64_t, SInt64);
0140 
0141 #define PROTOBUF_HANDLE_REPEATED_PTR_CASE(TYPE, CPPTYPE, NAME)                 \
0142   case FieldDescriptor::TYPE_##TYPE: {                                         \
0143     if (PROTOBUF_PREDICT_TRUE(!field->is_map())) {                             \
0144       /* Handle repeated fields. */                                            \
0145       const auto& rep = reflection->GetRawNonOneof<RepeatedPtrField<CPPTYPE>>( \
0146           message, field);                                                     \
0147       if (rep.size() == 0) continue;                                           \
0148       func(internal::Repeated##NAME##DynamicFieldInfo<MessageT>{               \
0149           reflection, message, field, rep});                                   \
0150     } else {                                                                   \
0151       /* Handle map fields. */                                                 \
0152       const auto& map =                                                        \
0153           reflection->GetRawNonOneof<MapFieldBase>(message, field);            \
0154       if (map.size() == 0) continue; /* NOLINT */                              \
0155       const Descriptor* desc = field->message_type();                          \
0156       func(internal::MapDynamicFieldInfo<MessageT>{reflection, message, field, \
0157                                                    desc->map_key(),            \
0158                                                    desc->map_value(), map});   \
0159     }                                                                          \
0160     break;                                                                     \
0161   }
0162 
0163         PROTOBUF_HANDLE_REPEATED_PTR_CASE(MESSAGE, Message, Message);
0164         PROTOBUF_HANDLE_REPEATED_PTR_CASE(GROUP, Message, Group);
0165 
0166         case FieldDescriptor::TYPE_BYTES:
0167         case FieldDescriptor::TYPE_STRING:
0168 #define PROTOBUF_IMPL_STRING_CASE(CPPTYPE, NAME)                               \
0169   {                                                                            \
0170     const auto& rep =                                                          \
0171         reflection->GetRawNonOneof<RepeatedPtrField<CPPTYPE>>(message, field); \
0172     if (rep.size() == 0) continue;                                             \
0173     func(internal::Repeated##NAME##DynamicFieldInfo<MessageT>{                 \
0174         reflection, message, field, rep});                                     \
0175   }
0176 
0177           switch (cpp::EffectiveStringCType(field)) {
0178             default:
0179             case FieldOptions::STRING:
0180               PROTOBUF_IMPL_STRING_CASE(std::string, String);
0181               break;
0182           }
0183           break;
0184         default:
0185           internal::Unreachable();
0186           break;
0187       }
0188 #undef PROTOBUF_HANDLE_REPEATED_CASE
0189 #undef PROTOBUF_HANDLE_REPEATED_PTR_CASE
0190 #undef PROTOBUF_IMPL_STRING_CASE
0191     } else if (schema.InRealOneof(field)) {
0192       const OneofDescriptor* containing_oneof = field->containing_oneof();
0193       const uint32_t* const oneof_case_array =
0194           internal::GetConstPointerAtOffset<uint32_t>(
0195               &message, schema.oneof_case_offset_);
0196       // Equivalent to: !HasOneofField(message, field)
0197       if (static_cast<int64_t>(oneof_case_array[containing_oneof->index()]) !=
0198           field->number()) {
0199         continue;
0200       }
0201       switch (field->type()) {
0202 #define PROTOBUF_HANDLE_CASE(TYPE, NAME)                                       \
0203   case FieldDescriptor::TYPE_##TYPE:                                           \
0204     func(internal::NAME##DynamicFieldInfo<MessageT, true>{reflection, message, \
0205                                                           field});             \
0206     break;
0207         PROTOBUF_HANDLE_CASE(DOUBLE, Double);
0208         PROTOBUF_HANDLE_CASE(FLOAT, Float);
0209         PROTOBUF_HANDLE_CASE(INT64, Int64);
0210         PROTOBUF_HANDLE_CASE(UINT64, UInt64);
0211         PROTOBUF_HANDLE_CASE(INT32, Int32);
0212         PROTOBUF_HANDLE_CASE(FIXED64, Fixed64);
0213         PROTOBUF_HANDLE_CASE(FIXED32, Fixed32);
0214         PROTOBUF_HANDLE_CASE(BOOL, Bool);
0215         PROTOBUF_HANDLE_CASE(UINT32, UInt32);
0216         PROTOBUF_HANDLE_CASE(ENUM, Enum);
0217         PROTOBUF_HANDLE_CASE(SFIXED32, SFixed32);
0218         PROTOBUF_HANDLE_CASE(SFIXED64, SFixed64);
0219         PROTOBUF_HANDLE_CASE(SINT32, SInt32);
0220         PROTOBUF_HANDLE_CASE(SINT64, SInt64);
0221 
0222         case FieldDescriptor::TYPE_MESSAGE:
0223         case FieldDescriptor::TYPE_GROUP:
0224           func(internal::MessageDynamicFieldInfo<MessageT, true>{
0225               reflection, message, field});
0226           break;
0227 
0228         case FieldDescriptor::TYPE_BYTES:
0229         case FieldDescriptor::TYPE_STRING: {
0230           auto ctype = cpp::EffectiveStringCType(field);
0231           if (ctype == FieldOptions::CORD) {
0232             func(CordDynamicFieldInfo<MessageT, true>{reflection, message,
0233                                                       field});
0234           } else {
0235             func(StringDynamicFieldInfo<MessageT, true>{reflection, message,
0236                                                         field});
0237           }
0238           break;
0239         }
0240         default:
0241           internal::Unreachable();
0242           break;
0243 #undef PROTOBUF_HANDLE_CASE
0244       }
0245     } else {
0246       auto index = has_bits_indices[i];
0247       bool check_hasbits = has_bits && index != static_cast<uint32_t>(-1);
0248       if (PROTOBUF_PREDICT_TRUE(check_hasbits)) {
0249         if ((has_bits[index / 32] & (1u << (index % 32))) == 0) continue;
0250       } else {
0251         // Skip if it has default values.
0252         if (!reflection->HasBit(message, field)) continue;
0253       }
0254       switch (field->type()) {
0255 #define PROTOBUF_HANDLE_CASE(TYPE, NAME)                                     \
0256   case FieldDescriptor::TYPE_##TYPE:                                         \
0257     func(internal::NAME##DynamicFieldInfo<MessageT, false>{reflection,       \
0258                                                            message, field}); \
0259     break;
0260         PROTOBUF_HANDLE_CASE(DOUBLE, Double);
0261         PROTOBUF_HANDLE_CASE(FLOAT, Float);
0262         PROTOBUF_HANDLE_CASE(INT64, Int64);
0263         PROTOBUF_HANDLE_CASE(UINT64, UInt64);
0264         PROTOBUF_HANDLE_CASE(INT32, Int32);
0265         PROTOBUF_HANDLE_CASE(FIXED64, Fixed64);
0266         PROTOBUF_HANDLE_CASE(FIXED32, Fixed32);
0267         PROTOBUF_HANDLE_CASE(BOOL, Bool);
0268         PROTOBUF_HANDLE_CASE(UINT32, UInt32);
0269         PROTOBUF_HANDLE_CASE(ENUM, Enum);
0270         PROTOBUF_HANDLE_CASE(SFIXED32, SFixed32);
0271         PROTOBUF_HANDLE_CASE(SFIXED64, SFixed64);
0272         PROTOBUF_HANDLE_CASE(SINT32, SInt32);
0273         PROTOBUF_HANDLE_CASE(SINT64, SInt64);
0274 
0275         case FieldDescriptor::TYPE_MESSAGE:
0276         case FieldDescriptor::TYPE_GROUP:
0277           func(internal::MessageDynamicFieldInfo<MessageT, false>{
0278               reflection, message, field});
0279           break;
0280         case FieldDescriptor::TYPE_BYTES:
0281         case FieldDescriptor::TYPE_STRING: {
0282           auto ctype = cpp::EffectiveStringCType(field);
0283           if (ctype == FieldOptions::CORD) {
0284             func(CordDynamicFieldInfo<MessageT, false>{reflection, message,
0285                                                        field});
0286           } else {
0287             func(StringDynamicFieldInfo<MessageT, false>{reflection, message,
0288                                                          field});
0289           }
0290           break;
0291         }
0292         default:
0293           internal::Unreachable();
0294           break;
0295 #undef PROTOBUF_HANDLE_CASE
0296       }
0297     }
0298   }
0299 
0300   if (!schema.HasExtensionSet()) return;
0301 
0302   auto& set = ExtensionSet(reflection, message);
0303   auto* extendee = reflection->descriptor_;
0304   auto* pool = reflection->descriptor_pool_;
0305 
0306   set.ForEach([&](int number, auto& ext) {
0307     ABSL_DCHECK_GT(ext.type, 0);
0308     ABSL_DCHECK_LE(ext.type, FieldDescriptor::MAX_TYPE);
0309 
0310     if (!ShouldVisit(mask, FieldDescriptor::TypeToCppType(
0311                                static_cast<FieldDescriptor::Type>(ext.type)))) {
0312       return;
0313     }
0314 
0315     if (ext.is_repeated) {
0316       if (ext.GetSize() == 0) return;
0317 
0318       switch (ext.type) {
0319 #define PROTOBUF_HANDLE_CASE(TYPE, NAME)                                \
0320   case FieldDescriptor::TYPE_##TYPE:                                    \
0321     func(internal::Repeated##NAME##DynamicExtensionInfo<decltype(ext)>{ \
0322         ext, number});                                                  \
0323     break;
0324         PROTOBUF_HANDLE_CASE(DOUBLE, Double);
0325         PROTOBUF_HANDLE_CASE(FLOAT, Float);
0326         PROTOBUF_HANDLE_CASE(INT64, Int64);
0327         PROTOBUF_HANDLE_CASE(UINT64, UInt64);
0328         PROTOBUF_HANDLE_CASE(INT32, Int32);
0329         PROTOBUF_HANDLE_CASE(FIXED64, Fixed64);
0330         PROTOBUF_HANDLE_CASE(FIXED32, Fixed32);
0331         PROTOBUF_HANDLE_CASE(BOOL, Bool);
0332         PROTOBUF_HANDLE_CASE(UINT32, UInt32);
0333         PROTOBUF_HANDLE_CASE(ENUM, Enum);
0334         PROTOBUF_HANDLE_CASE(SFIXED32, SFixed32);
0335         PROTOBUF_HANDLE_CASE(SFIXED64, SFixed64);
0336         PROTOBUF_HANDLE_CASE(SINT32, SInt32);
0337         PROTOBUF_HANDLE_CASE(SINT64, SInt64);
0338 
0339         PROTOBUF_HANDLE_CASE(MESSAGE, Message);
0340         PROTOBUF_HANDLE_CASE(GROUP, Group);
0341 
0342         case FieldDescriptor::TYPE_BYTES:
0343         case FieldDescriptor::TYPE_STRING:
0344           func(internal::RepeatedStringDynamicExtensionInfo<decltype(ext)>{
0345               ext, number});
0346           break;
0347         default:
0348           internal::Unreachable();
0349           break;
0350 #undef PROTOBUF_HANDLE_CASE
0351       }
0352     } else {
0353       if (ext.is_cleared) return;
0354 
0355       switch (ext.type) {
0356 #define PROTOBUF_HANDLE_CASE(TYPE, NAME)                                    \
0357   case FieldDescriptor::TYPE_##TYPE:                                        \
0358     func(internal::NAME##DynamicExtensionInfo<decltype(ext)>{ext, number}); \
0359     break;
0360         PROTOBUF_HANDLE_CASE(DOUBLE, Double);
0361         PROTOBUF_HANDLE_CASE(FLOAT, Float);
0362         PROTOBUF_HANDLE_CASE(INT64, Int64);
0363         PROTOBUF_HANDLE_CASE(UINT64, UInt64);
0364         PROTOBUF_HANDLE_CASE(INT32, Int32);
0365         PROTOBUF_HANDLE_CASE(FIXED64, Fixed64);
0366         PROTOBUF_HANDLE_CASE(FIXED32, Fixed32);
0367         PROTOBUF_HANDLE_CASE(BOOL, Bool);
0368         PROTOBUF_HANDLE_CASE(UINT32, UInt32);
0369         PROTOBUF_HANDLE_CASE(ENUM, Enum);
0370         PROTOBUF_HANDLE_CASE(SFIXED32, SFixed32);
0371         PROTOBUF_HANDLE_CASE(SFIXED64, SFixed64);
0372         PROTOBUF_HANDLE_CASE(SINT32, SInt32);
0373         PROTOBUF_HANDLE_CASE(SINT64, SInt64);
0374 
0375         PROTOBUF_HANDLE_CASE(GROUP, Group);
0376         case FieldDescriptor::TYPE_MESSAGE: {
0377           const FieldDescriptor* field =
0378               ext.descriptor != nullptr
0379                   ? ext.descriptor
0380                   : pool->FindExtensionByNumber(extendee, number);
0381           ABSL_DCHECK_EQ(field->number(), number);
0382           bool is_mset =
0383               field->containing_type()->options().message_set_wire_format();
0384           func(internal::MessageDynamicExtensionInfo<decltype(ext)>{ext, number,
0385                                                                     is_mset});
0386           break;
0387         }
0388 
0389         case FieldDescriptor::TYPE_BYTES:
0390         case FieldDescriptor::TYPE_STRING:
0391           func(
0392               internal::StringDynamicExtensionInfo<decltype(ext)>{ext, number});
0393           break;
0394 
0395         default:
0396           internal::Unreachable();
0397           break;
0398 #undef PROTOBUF_HANDLE_CASE
0399       }
0400     }
0401   });
0402 }
0403 
0404 template <typename CallbackFn>
0405 void ReflectionVisit::VisitMessageFields(const Message& message,
0406                                          CallbackFn&& func) {
0407   ReflectionVisit::VisitFields(
0408       message,
0409       [&](auto info) {
0410         if constexpr (info.is_map) {
0411           auto value_type = info.value_type();
0412           if (value_type != FieldDescriptor::TYPE_MESSAGE &&
0413               value_type != FieldDescriptor::TYPE_GROUP) {
0414             return;
0415           }
0416           info.VisitElements([&](auto key, auto val) {
0417             if constexpr (val.cpp_type == FieldDescriptor::CPPTYPE_MESSAGE) {
0418               func(val.Get());
0419             }
0420           });
0421         } else if constexpr (info.cpp_type ==
0422                              FieldDescriptor::CPPTYPE_MESSAGE) {
0423           if constexpr (info.is_repeated) {
0424             for (const auto& it : info.Get()) {
0425               func(DownCastMessage<Message>(it));
0426             }
0427           } else {
0428             func(info.Get());
0429           }
0430         }
0431       },
0432       FieldMask::kMessage);
0433 }
0434 
0435 template <typename CallbackFn>
0436 void ReflectionVisit::VisitMessageFields(Message& message, CallbackFn&& func) {
0437   ReflectionVisit::VisitFields(
0438       message,
0439       [&](auto info) {
0440         if constexpr (info.is_map) {
0441           auto value_type = info.value_type();
0442           if (value_type != FieldDescriptor::TYPE_MESSAGE &&
0443               value_type != FieldDescriptor::TYPE_GROUP) {
0444             return;
0445           }
0446           info.VisitElements([&](auto key, auto val) {
0447             if constexpr (val.cpp_type == FieldDescriptor::CPPTYPE_MESSAGE) {
0448               func(*val.Mutable());
0449             }
0450           });
0451         } else if constexpr (info.cpp_type ==
0452                              FieldDescriptor::CPPTYPE_MESSAGE) {
0453           if constexpr (info.is_repeated) {
0454             for (auto& it : info.Mutable()) {
0455               func(DownCastMessage<Message>(it));
0456             }
0457           } else {
0458             func(info.Mutable());
0459           }
0460         }
0461       },
0462       FieldMask::kMessage);
0463 }
0464 
0465 // Visits present fields of "message" and calls the callback function "func".
0466 // Skips fields whose ctypes are missing in "mask".
0467 template <typename MessageT, typename CallbackFn>
0468 void VisitFields(MessageT& message, CallbackFn&& func, FieldMask mask) {
0469   ReflectionVisit::VisitFields(message, std::forward<CallbackFn>(func), mask);
0470 }
0471 
0472 // Visits message fields of "message" and calls "func". Expects "func" to
0473 // accept const Message&. Note the following divergence from VisitFields.
0474 //
0475 // --Each of N elements of a repeated message field is visited (total N).
0476 // --Each of M elements of a map field whose value type is message are visited
0477 //   (total M).
0478 // --A map field whose value type is not message is ignored.
0479 //
0480 // This is a helper API built on top of VisitFields to hide specifics about
0481 // extensions, repeated fields, etc.
0482 template <typename CallbackFn>
0483 void VisitMessageFields(const Message& message, CallbackFn&& func) {
0484   ReflectionVisit::VisitMessageFields(message, std::forward<CallbackFn>(func));
0485 }
0486 
0487 // Same as VisitMessageFields above but expects "func" to accept Message&. This
0488 // is useful when mutable access is required. As mutable access can be
0489 // expensive, use it only if it's necessary.
0490 template <typename CallbackFn>
0491 void VisitMutableMessageFields(Message& message, CallbackFn&& func) {
0492   ReflectionVisit::VisitMessageFields(message, std::forward<CallbackFn>(func));
0493 }
0494 
0495 #endif  // __cpp_if_constexpr
0496 
0497 }  // namespace internal
0498 }  // namespace protobuf
0499 }  // namespace google
0500 
0501 #include "google/protobuf/port_undef.inc"
0502 
0503 #endif  // GOOGLE_PROTOBUF_REFLECTION_VISIT_FIELDS_H__