// Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. // // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file or at // https://developers.google.com/open-source/licenses/bsd // Author: jasonh@google.com (Jason Hsueh) // // This header is logically internal, but is made public because it is used // from protocol-compiler-generated code, which may reside in other components. // It provides reflection support for generated enums, and is included in // generated .pb.h files and should have minimal dependencies. The methods are // implemented in generated_message_reflection.cc. #ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ #define GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ #include #include #include #include #include "absl/log/absl_check.h" #include "absl/strings/string_view.h" #include "google/protobuf/generated_enum_util.h" #include "google/protobuf/port.h" #ifdef SWIG #error "You cannot SWIG proto headers" #endif // Must be included last. #include "google/protobuf/port_def.inc" namespace google { namespace protobuf { class EnumDescriptor; } // namespace protobuf } // namespace google namespace google { namespace protobuf { // Returns the EnumDescriptor for enum type E, which must be a // proto-declared enum type. Code generated by the protocol compiler // will include specializations of this template for each enum type declared. template PROTOBUF_FUTURE_ADD_EARLY_NODISCARD const EnumDescriptor* PROTOBUF_NONNULL GetEnumDescriptor(); namespace internal { // Helper for EnumType_Parse functions: try to parse the string 'name' as // an enum name of the given type, returning true and filling in value on // success, or returning false and leaving value unchanged on failure. PROTOBUF_FUTURE_ADD_EARLY_NODISCARD PROTOBUF_EXPORT bool ParseNamedEnum( const EnumDescriptor* PROTOBUF_NONNULL descriptor, absl::string_view name, int* PROTOBUF_NONNULL value); template PROTOBUF_FUTURE_ADD_EARLY_NODISCARD bool ParseNamedEnum( const EnumDescriptor* PROTOBUF_NONNULL descriptor, absl::string_view name, EnumType* PROTOBUF_NONNULL value) { int tmp; if (!ParseNamedEnum(descriptor, name, &tmp)) return false; *value = static_cast(tmp); return true; } // Just a wrapper around printing the name of a value. The main point of this // function is not to be inlined, so that you can do this without including // descriptor.h. PROTOBUF_FUTURE_ADD_EARLY_NODISCARD PROTOBUF_EXPORT const std::string& NameOfEnum( const EnumDescriptor* PROTOBUF_NONNULL descriptor, int value); template class EnumeratedEnumView { // Make the type dependent to avoid eager instantiations. // EnumDescriptor is incomplete at this point, but will be complete when this // template is instantiated. using Desc = std::enable_if_t; public: using value_type = Enum; class iterator { public: using difference_type = ptrdiff_t; using value_type = Enum; using pointer = value_type*; using reference = value_type&; using iterator_category = std::input_iterator_tag; iterator() : desc_(nullptr), index_(0) {} iterator(const iterator&) = default; iterator& operator=(const iterator&) = default; friend bool operator==(iterator a, iterator b) { ABSL_DCHECK_EQ(a.desc_, b.desc_); return a.index_ == b.index_; } friend bool operator!=(iterator a, iterator b) { return !(a == b); } Enum operator*() const { return static_cast(desc_->value(index_)->number()); } iterator& operator++() { ++index_; return *this; } iterator operator++(int) { auto copy = *this; ++*this; return copy; } private: friend EnumeratedEnumView; iterator(const Desc* PROTOBUF_NONNULL desc, int index) : desc_(desc), index_(index) {} const Desc* PROTOBUF_NONNULL desc_; int index_; }; using const_iterator = iterator; // Proto enums are never empty. bool empty() const { return false; } size_t size() const { return desc_->value_count(); } iterator begin() const { return iterator(desc_, 0); } iterator end() const { return iterator(desc_, size()); } iterator cbegin() const { return begin(); } iterator cend() const { return end(); } private: const Desc* PROTOBUF_NONNULL desc_ = GetEnumDescriptor(); }; // Runtime implementation for Abseil flag support for enums. [[nodiscard]] PROTOBUF_EXPORT bool AbslParseFlagImpl(absl::string_view text, int& e, const EnumDescriptor& desc, std::string& error); [[nodiscard]] PROTOBUF_EXPORT std::string AbslUnparseFlagImpl( int e, const EnumDescriptor& desc); namespace generated_enum { // We inject these functions in the user namespace to allow for ADL on the // enums. // These overloads handle reflection based enums. template > bool AbslParseFlag(absl::string_view text, Enum* PROTOBUF_NONNULL e, std::string* PROTOBUF_NONNULL error) { int value; if (internal::AbslParseFlagImpl(text, value, *GetEnumDescriptor(), *error)) { *e = static_cast(value); return true; } return false; } template > std::string AbslUnparseFlag(Enum e) { return internal::AbslUnparseFlagImpl(e, *GetEnumDescriptor()); } } // namespace generated_enum } // namespace internal // Returns an iterable object that will yield all the enum labels for `Enum` in // the same order as specified in their EnumDescriptor. // The returned type is unspecified. template auto EnumerateEnumValues() { return internal::EnumeratedEnumView{}; } } // namespace protobuf } // namespace google #include "google/protobuf/port_undef.inc" #endif // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__