• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 //  Based on original Protocol Buffers design by
33 //  Sanjay Ghemawat, Jeff Dean, and others.
34 //
35 // This header is logically internal, but is made public because it is used
36 // from protocol-compiler-generated code, which may reside in other components.
37 
38 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
39 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
40 
41 #include <string>
42 #include <vector>
43 #include <google/protobuf/stubs/casts.h>
44 #include <google/protobuf/stubs/common.h>
45 // TODO(jasonh): Remove this once the compiler change to directly include this
46 // is released to components.
47 #include <google/protobuf/descriptor.h>
48 #include <google/protobuf/generated_enum_reflection.h>
49 #include <google/protobuf/metadata.h>
50 #include <google/protobuf/stubs/once.h>
51 #include <google/protobuf/port.h>
52 #include <google/protobuf/unknown_field_set.h>
53 
54 
55 #include <google/protobuf/port_def.inc>
56 
57 #ifdef SWIG
58 #error "You cannot SWIG proto headers"
59 #endif
60 
61 namespace google {
62 namespace protobuf {
63 class DescriptorPool;
64 class MapKey;
65 class MapValueRef;
66 class MessageLayoutInspector;
67 class Message;
68 struct Metadata;
69 }  // namespace protobuf
70 }  // namespace google
71 
72 
73 namespace google {
74 namespace protobuf {
75 namespace internal {
76 class DefaultEmptyOneof;
77 class ReflectionAccessor;
78 
79 // Defined in other files.
80 class ExtensionSet;  // extension_set.h
81 class WeakFieldMap;  // weak_field_map.h
82 
83 // This struct describes the internal layout of the message, hence this is
84 // used to act on the message reflectively.
85 //   default_instance:  The default instance of the message.  This is only
86 //                  used to obtain pointers to default instances of embedded
87 //                  messages, which GetMessage() will return if the particular
88 //                  sub-message has not been initialized yet.  (Thus, all
89 //                  embedded message fields *must* have non-null pointers
90 //                  in the default instance.)
91 //   offsets:       An array of ints giving the byte offsets.
92 //                  For each oneof or weak field, the offset is relative to the
93 //                  default_instance. These can be computed at compile time
94 //                  using the
95 //                  PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET()
96 //                  macro. For each none oneof field, the offset is related to
97 //                  the start of the message object.  These can be computed at
98 //                  compile time using the
99 //                  PROTO2_GENERATED_MESSAGE_FIELD_OFFSET() macro.
100 //                  Besides offsets for all fields, this array also contains
101 //                  offsets for oneof unions. The offset of the i-th oneof union
102 //                  is offsets[descriptor->field_count() + i].
103 //   has_bit_indices:  Mapping from field indexes to their index in the has
104 //                  bit array.
105 //   has_bits_offset:  Offset in the message of an array of uint32s of size
106 //                  descriptor->field_count()/32, rounded up.  This is a
107 //                  bitfield where each bit indicates whether or not the
108 //                  corresponding field of the message has been initialized.
109 //                  The bit for field index i is obtained by the expression:
110 //                    has_bits[i / 32] & (1 << (i % 32))
111 //   unknown_fields_offset:  Offset in the message of the UnknownFieldSet for
112 //                  the message.
113 //   extensions_offset:  Offset in the message of the ExtensionSet for the
114 //                  message, or -1 if the message type has no extension
115 //                  ranges.
116 //   oneof_case_offset:  Offset in the message of an array of uint32s of
117 //                  size descriptor->oneof_decl_count().  Each uint32
118 //                  indicates what field is set for each oneof.
119 //   object_size:   The size of a message object of this type, as measured
120 //                  by sizeof().
121 //   arena_offset:  If a message doesn't have a unknown_field_set that stores
122 //                  the arena, it must have a direct pointer to the arena.
123 //   weak_field_map_offset: If the message proto has weak fields, this is the
124 //                  offset of _weak_field_map_ in the generated proto. Otherwise
125 //                  -1.
126 struct ReflectionSchema {
127  public:
128   // Size of a google::protobuf::Message object of this type.
GetObjectSizeReflectionSchema129   uint32 GetObjectSize() const { return static_cast<uint32>(object_size_); }
130 
131   // Offset of a non-oneof field.  Getting a field offset is slightly more
132   // efficient when we know statically that it is not a oneof field.
GetFieldOffsetNonOneofReflectionSchema133   uint32 GetFieldOffsetNonOneof(const FieldDescriptor* field) const {
134     GOOGLE_DCHECK(!field->containing_oneof());
135     return OffsetValue(offsets_[field->index()], field->type());
136   }
137 
138   // Offset of any field.
GetFieldOffsetReflectionSchema139   uint32 GetFieldOffset(const FieldDescriptor* field) const {
140     if (field->containing_oneof()) {
141       size_t offset =
142           static_cast<size_t>(field->containing_type()->field_count() +
143                               field->containing_oneof()->index());
144       return OffsetValue(offsets_[offset], field->type());
145     } else {
146       return GetFieldOffsetNonOneof(field);
147     }
148   }
149 
IsFieldInlinedReflectionSchema150   bool IsFieldInlined(const FieldDescriptor* field) const {
151     if (field->containing_oneof()) {
152       size_t offset =
153           static_cast<size_t>(field->containing_type()->field_count() +
154                               field->containing_oneof()->index());
155       return Inlined(offsets_[offset], field->type());
156     } else {
157       return Inlined(offsets_[field->index()], field->type());
158     }
159   }
160 
GetOneofCaseOffsetReflectionSchema161   uint32 GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const {
162     return static_cast<uint32>(oneof_case_offset_) +
163            static_cast<uint32>(static_cast<size_t>(oneof_descriptor->index()) *
164                                sizeof(uint32));
165   }
166 
HasHasbitsReflectionSchema167   bool HasHasbits() const { return has_bits_offset_ != -1; }
168 
169   // Bit index within the bit array of hasbits.  Bit order is low-to-high.
HasBitIndexReflectionSchema170   uint32 HasBitIndex(const FieldDescriptor* field) const {
171     GOOGLE_DCHECK(HasHasbits());
172     return has_bit_indices_[field->index()];
173   }
174 
175   // Byte offset of the hasbits array.
HasBitsOffsetReflectionSchema176   uint32 HasBitsOffset() const {
177     GOOGLE_DCHECK(HasHasbits());
178     return static_cast<uint32>(has_bits_offset_);
179   }
180 
181   // The offset of the InternalMetadataWithArena member.
182   // For Lite this will actually be an InternalMetadataWithArenaLite.
183   // The schema doesn't contain enough information to distinguish between
184   // these two cases.
GetMetadataOffsetReflectionSchema185   uint32 GetMetadataOffset() const {
186     return static_cast<uint32>(metadata_offset_);
187   }
188 
189   // Whether this message has an ExtensionSet.
HasExtensionSetReflectionSchema190   bool HasExtensionSet() const { return extensions_offset_ != -1; }
191 
192   // The offset of the ExtensionSet in this message.
GetExtensionSetOffsetReflectionSchema193   uint32 GetExtensionSetOffset() const {
194     GOOGLE_DCHECK(HasExtensionSet());
195     return static_cast<uint32>(extensions_offset_);
196   }
197 
198   // The off set of WeakFieldMap when the message contains weak fields.
199   // The default is 0 for now.
GetWeakFieldMapOffsetReflectionSchema200   int GetWeakFieldMapOffset() const { return weak_field_map_offset_; }
201 
IsDefaultInstanceReflectionSchema202   bool IsDefaultInstance(const Message& message) const {
203     return &message == default_instance_;
204   }
205 
206   // Returns a pointer to the default value for this field.  The size and type
207   // of the underlying data depends on the field's type.
GetFieldDefaultReflectionSchema208   const void* GetFieldDefault(const FieldDescriptor* field) const {
209     return reinterpret_cast<const uint8*>(default_instance_) +
210            OffsetValue(offsets_[field->index()], field->type());
211   }
212 
213 
HasWeakFieldsReflectionSchema214   bool HasWeakFields() const { return weak_field_map_offset_ > 0; }
215 
216   // These members are intended to be private, but we cannot actually make them
217   // private because this prevents us from using aggregate initialization of
218   // them, ie.
219   //
220   //   ReflectionSchema schema = {a, b, c, d, e, ...};
221   // private:
222   const Message* default_instance_;
223   const uint32* offsets_;
224   const uint32* has_bit_indices_;
225   int has_bits_offset_;
226   int metadata_offset_;
227   int extensions_offset_;
228   int oneof_case_offset_;
229   int object_size_;
230   int weak_field_map_offset_;
231 
232   // We tag offset values to provide additional data about fields (such as
233   // inlined).
OffsetValueReflectionSchema234   static uint32 OffsetValue(uint32 v, FieldDescriptor::Type type) {
235     if (type == FieldDescriptor::TYPE_STRING ||
236         type == FieldDescriptor::TYPE_BYTES) {
237       return v & ~1u;
238     } else {
239       return v;
240     }
241   }
242 
InlinedReflectionSchema243   static bool Inlined(uint32 v, FieldDescriptor::Type type) {
244     if (type == FieldDescriptor::TYPE_STRING ||
245         type == FieldDescriptor::TYPE_BYTES) {
246       return v & 1u;
247     } else {
248       // Non string/byte fields are not inlined.
249       return false;
250     }
251   }
252 };
253 
254 // Structs that the code generator emits directly to describe a message.
255 // These should never used directly except to build a ReflectionSchema
256 // object.
257 //
258 // EXPERIMENTAL: these are changing rapidly, and may completely disappear
259 // or merge with ReflectionSchema.
260 struct MigrationSchema {
261   int32 offsets_index;
262   int32 has_bit_indices_index;
263   int object_size;
264 };
265 
266 struct PROTOBUF_EXPORT DescriptorTable {
267   bool* is_initialized;
268   const char* descriptor;
269   const char* filename;
270   int size;  // of serialized descriptor
271   once_flag* once;
272   SCCInfoBase* const* init_default_instances;
273   const DescriptorTable* const* deps;
274   int num_sccs;
275   int num_deps;
276   const MigrationSchema* schemas;
277   const Message* const* default_instances;
278   const uint32* offsets;
279   // update the following descriptor arrays.
280   Metadata* file_level_metadata;
281   int num_messages;
282   const EnumDescriptor** file_level_enum_descriptors;
283   const ServiceDescriptor** file_level_service_descriptors;
284 };
285 
286 // AssignDescriptors() pulls the compiled FileDescriptor from the DescriptorPool
287 // and uses it to populate all of the global variables which store pointers to
288 // the descriptor objects.  It also constructs the reflection objects.  It is
289 // called the first time anyone calls descriptor() or GetReflection() on one of
290 // the types defined in the file.  AssignDescriptors() is thread-safe.
291 void PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* table);
292 
293 // AddDescriptors() is a file-level procedure which adds the encoded
294 // FileDescriptorProto for this .proto file to the global DescriptorPool for
295 // generated files (DescriptorPool::generated_pool()). It ordinarily runs at
296 // static initialization time, but is not used at all in LITE_RUNTIME mode.
297 // AddDescriptors() is *not* thread-safe.
298 void PROTOBUF_EXPORT AddDescriptors(const DescriptorTable* table);
299 
300 // These cannot be in lite so we put them in the reflection.
301 PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8* base, uint32 offset,
302                                                uint32 tag, uint32 has_offset,
303                                                io::CodedOutputStream* output);
304 
305 }  // namespace internal
306 }  // namespace protobuf
307 }  // namespace google
308 
309 #include <google/protobuf/port_undef.inc>
310 
311 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
312