| // 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__ |