• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #ifndef GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
9 #define GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
10 
11 #include <cstddef>
12 #include <cstdint>
13 #include <string>
14 #include <type_traits>
15 #include <vector>
16 
17 #include "absl/strings/string_view.h"
18 #include "absl/types/span.h"
19 #include "google/protobuf/explicitly_constructed.h"
20 #include "google/protobuf/message_lite.h"
21 
22 // Must be included last.
23 #include "google/protobuf/port_def.inc"
24 
25 #ifdef SWIG
26 #error "You cannot SWIG proto headers"
27 #endif
28 
29 namespace google {
30 namespace protobuf {
31 
32 // This type trait can be used to cause templates to only match proto2 enum
33 // types.
34 template <typename T>
35 struct is_proto_enum : ::std::false_type {};
36 
37 namespace internal {
38 
39 // The table entry format for storing enum name-to-value mapping used with lite
40 // protos. This struct and the following related functions should only be used
41 // by protobuf generated code.
42 struct EnumEntry {
43   absl::string_view name;
44   int value;
45 };
46 
47 // Looks up a numeric enum value given the string name.
48 PROTOBUF_EXPORT bool LookUpEnumValue(const EnumEntry* enums, size_t size,
49                                      absl::string_view name, int* value);
50 
51 // Looks up an enum name given the numeric value.
52 PROTOBUF_EXPORT int LookUpEnumName(const EnumEntry* enums,
53                                    const int* sorted_indices, size_t size,
54                                    int value);
55 
56 // Initializes the list of enum names in std::string form.
57 PROTOBUF_EXPORT bool InitializeEnumStrings(
58     const EnumEntry* enums, const int* sorted_indices, size_t size,
59     internal::ExplicitlyConstructed<std::string>* enum_strings);
60 
61 // The enum validation format is split in 3 parts:
62 //  - A dense sequence, with start+length
63 //  - A variable size presence bitmap (in increments of 32 bits)
64 //  - A variable size sorted int32_t set for everything else.
65 //
66 // The values are as follows:
67 //
68 // 0 - [ sequence start (int16_t) ] | [ sequence size (uint16_t) ] << 16
69 // 1 - [ bitmap size in bits (uint16_t) ] | [ ordered size (uint16_t) ] << 16
70 // x - [ variable length bitmap ]
71 // y - [ variable length of int32_t values ]
72 //
73 // where the bitmap starts right after the end of the sequence.
74 PROTOBUF_EXPORT bool ValidateEnum(int value, const uint32_t* data);
75 PROTOBUF_EXPORT std::vector<uint32_t> GenerateEnumData(
76     absl::Span<const int32_t> values);
77 
ValidateEnumInlined(int value,const uint32_t * data)78 inline PROTOBUF_ALWAYS_INLINE bool ValidateEnumInlined(int value,
79                                                        const uint32_t* data) {
80   const int16_t min_seq = static_cast<int16_t>(data[0] & 0xFFFF);
81   const uint16_t length_seq = static_cast<uint16_t>(data[0] >> 16);
82   uint64_t adjusted =
83       static_cast<uint64_t>(static_cast<int64_t>(value)) - min_seq;
84   // Check if the value is within the sequential part.
85   if (PROTOBUF_PREDICT_TRUE(adjusted < length_seq)) {
86     return true;
87   }
88 
89   const uint16_t length_bitmap = static_cast<uint16_t>(data[1] & 0xFFFF);
90   adjusted -= length_seq;
91   // Check if the value is within the bitmap.
92   if (PROTOBUF_PREDICT_TRUE(adjusted < length_bitmap)) {
93     return ((data[2 + (adjusted / 32)] >> (adjusted % 32)) & 1) == 1;
94   }
95 
96   // Check if the value is on the ordered part.
97   const uint16_t num_ordered = static_cast<uint16_t>(data[1] >> 16);
98   data += 2 + length_bitmap / 32;
99   size_t pos = 0;
100   while (pos < num_ordered) {
101     const int32_t sample = static_cast<int32_t>(data[pos]);
102     if (sample == value) return true;
103     pos = 2 * pos + (sample > value ? 1 : 2);
104   }
105   return false;
106 }
107 
108 }  // namespace internal
109 }  // namespace protobuf
110 }  // namespace google
111 
112 #include "google/protobuf/port_undef.inc"
113 
114 #endif  // GOOGLE_PROTOBUF_GENERATED_ENUM_UTIL_H__
115