| // 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 <cstddef> |
| #include <iterator> |
| #include <string> |
| #include <type_traits> |
| |
| #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 <typename E> |
| 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 <typename EnumType> |
| 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<EnumType>(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 <typename Enum> |
| 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<sizeof(Enum) != 0, EnumDescriptor>; |
| |
| 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<Enum>(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<Enum>(); |
| }; |
| |
| // 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 <typename Enum, typename = EnableIfProtoEnum<Enum, false>> |
| bool AbslParseFlag(absl::string_view text, Enum* PROTOBUF_NONNULL e, |
| std::string* PROTOBUF_NONNULL error) { |
| int value; |
| if (internal::AbslParseFlagImpl(text, value, *GetEnumDescriptor<Enum>(), |
| *error)) { |
| *e = static_cast<Enum>(value); |
| return true; |
| } |
| return false; |
| } |
| |
| template <typename Enum, typename = EnableIfProtoEnum<Enum, false>> |
| std::string AbslUnparseFlag(Enum e) { |
| return internal::AbslUnparseFlagImpl(e, *GetEnumDescriptor<Enum>()); |
| } |
| } // 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 <typename Enum> |
| auto EnumerateEnumValues() { |
| return internal::EnumeratedEnumView<Enum>{}; |
| } |
| |
| } // namespace protobuf |
| } // namespace google |
| |
| #include "google/protobuf/port_undef.inc" |
| |
| #endif // GOOGLE_PROTOBUF_GENERATED_ENUM_REFLECTION_H__ |