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: [email protected] (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
61namespace google {
62namespace protobuf {
63class DescriptorPool;
64class MapKey;
65class MapValueRef;
66class MessageLayoutInspector;
67class Message;
68struct Metadata;
69} // namespace protobuf
70} // namespace google
71
72namespace google {
73namespace protobuf {
74namespace internal {
75class DefaultEmptyOneof;
76class ReflectionAccessor;
77
78// Defined in other files.
79class ExtensionSet; // extension_set.h
80class WeakFieldMap; // weak_field_map.h
81
82// This struct describes the internal layout of the message, hence this is
83// used to act on the message reflectively.
84// default_instance: The default instance of the message. This is only
85// used to obtain pointers to default instances of embedded
86// messages, which GetMessage() will return if the particular
87// sub-message has not been initialized yet. (Thus, all
88// embedded message fields *must* have non-null pointers
89// in the default instance.)
90// offsets: An array of ints giving the byte offsets.
91// For each oneof or weak field, the offset is relative to the
92// default_instance. These can be computed at compile time
93// using the
94// PROTO2_GENERATED_DEFAULT_ONEOF_FIELD_OFFSET()
95// macro. For each none oneof field, the offset is related to
96// the start of the message object. These can be computed at
97// compile time using the
98// PROTO2_GENERATED_MESSAGE_FIELD_OFFSET() macro.
99// Besides offsets for all fields, this array also contains
100// offsets for oneof unions. The offset of the i-th oneof union
101// is offsets[descriptor->field_count() + i].
102// has_bit_indices: Mapping from field indexes to their index in the has
103// bit array.
104// has_bits_offset: Offset in the message of an array of uint32s of size
105// descriptor->field_count()/32, rounded up. This is a
106// bitfield where each bit indicates whether or not the
107// corresponding field of the message has been initialized.
108// The bit for field index i is obtained by the expression:
109// has_bits[i / 32] & (1 << (i % 32))
110// unknown_fields_offset: Offset in the message of the UnknownFieldSet for
111// the message.
112// extensions_offset: Offset in the message of the ExtensionSet for the
113// message, or -1 if the message type has no extension
114// ranges.
115// oneof_case_offset: Offset in the message of an array of uint32s of
116// size descriptor->oneof_decl_count(). Each uint32
117// indicates what field is set for each oneof.
118// object_size: The size of a message object of this type, as measured
119// by sizeof().
120// arena_offset: If a message doesn't have a unknown_field_set that stores
121// the arena, it must have a direct pointer to the arena.
122// weak_field_map_offset: If the message proto has weak fields, this is the
123// offset of _weak_field_map_ in the generated proto. Otherwise
124// -1.
125struct ReflectionSchema {
126 public:
127 // Size of a google::protobuf::Message object of this type.
128 uint32 GetObjectSize() const { return static_cast<uint32>(object_size_); }
129
130 // Offset of a non-oneof field. Getting a field offset is slightly more
131 // efficient when we know statically that it is not a oneof field.
132 uint32 GetFieldOffsetNonOneof(const FieldDescriptor* field) const {
133 GOOGLE_DCHECK(!field->containing_oneof());
134 return OffsetValue(offsets_[field->index()], field->type());
135 }
136
137 // Offset of any field.
138 uint32 GetFieldOffset(const FieldDescriptor* field) const {
139 if (field->containing_oneof()) {
140 size_t offset =
141 static_cast<size_t>(field->containing_type()->field_count() +
142 field->containing_oneof()->index());
143 return OffsetValue(offsets_[offset], field->type());
144 } else {
145 return GetFieldOffsetNonOneof(field);
146 }
147 }
148
149 bool IsFieldInlined(const FieldDescriptor* field) const {
150 if (field->containing_oneof()) {
151 size_t offset =
152 static_cast<size_t>(field->containing_type()->field_count() +
153 field->containing_oneof()->index());
154 return Inlined(offsets_[offset], field->type());
155 } else {
156 return Inlined(offsets_[field->index()], field->type());
157 }
158 }
159
160 uint32 GetOneofCaseOffset(const OneofDescriptor* oneof_descriptor) const {
161 return static_cast<uint32>(oneof_case_offset_) +
162 static_cast<uint32>(static_cast<size_t>(oneof_descriptor->index()) *
163 sizeof(uint32));
164 }
165
166 bool HasHasbits() const { return has_bits_offset_ != -1; }
167
168 // Bit index within the bit array of hasbits. Bit order is low-to-high.
169 uint32 HasBitIndex(const FieldDescriptor* field) const {
170 GOOGLE_DCHECK(HasHasbits());
171 return has_bit_indices_[field->index()];
172 }
173
174 // Byte offset of the hasbits array.
175 uint32 HasBitsOffset() const {
176 GOOGLE_DCHECK(HasHasbits());
177 return static_cast<uint32>(has_bits_offset_);
178 }
179
180 // The offset of the InternalMetadataWithArena member.
181 // For Lite this will actually be an InternalMetadataWithArenaLite.
182 // The schema doesn't contain enough information to distinguish between
183 // these two cases.
184 uint32 GetMetadataOffset() const {
185 return static_cast<uint32>(metadata_offset_);
186 }
187
188 // Whether this message has an ExtensionSet.
189 bool HasExtensionSet() const { return extensions_offset_ != -1; }
190
191 // The offset of the ExtensionSet in this message.
192 uint32 GetExtensionSetOffset() const {
193 GOOGLE_DCHECK(HasExtensionSet());
194 return static_cast<uint32>(extensions_offset_);
195 }
196
197 // The off set of WeakFieldMap when the message contains weak fields.
198 // The default is 0 for now.
199 int GetWeakFieldMapOffset() const { return weak_field_map_offset_; }
200
201 bool IsDefaultInstance(const Message& message) const {
202 return &message == default_instance_;
203 }
204
205 // Returns a pointer to the default value for this field. The size and type
206 // of the underlying data depends on the field's type.
207 const void* GetFieldDefault(const FieldDescriptor* field) const {
208 return reinterpret_cast<const uint8*>(default_instance_) +
209 OffsetValue(offsets_[field->index()], field->type());
210 }
211
212
213 bool HasWeakFields() const { return weak_field_map_offset_ > 0; }
214
215 // These members are intended to be private, but we cannot actually make them
216 // private because this prevents us from using aggregate initialization of
217 // them, ie.
218 //
219 // ReflectionSchema schema = {a, b, c, d, e, ...};
220 // private:
221 const Message* default_instance_;
222 const uint32* offsets_;
223 const uint32* has_bit_indices_;
224 int has_bits_offset_;
225 int metadata_offset_;
226 int extensions_offset_;
227 int oneof_case_offset_;
228 int object_size_;
229 int weak_field_map_offset_;
230
231 // We tag offset values to provide additional data about fields (such as
232 // inlined).
233 static uint32 OffsetValue(uint32 v, FieldDescriptor::Type type) {
234 if (type == FieldDescriptor::TYPE_STRING ||
235 type == FieldDescriptor::TYPE_BYTES) {
236 return v & ~1u;
237 } else {
238 return v;
239 }
240 }
241
242 static bool Inlined(uint32 v, FieldDescriptor::Type type) {
243 if (type == FieldDescriptor::TYPE_STRING ||
244 type == FieldDescriptor::TYPE_BYTES) {
245 return v & 1u;
246 } else {
247 // Non string/byte fields are not inlined.
248 return false;
249 }
250 }
251};
252
253// Structs that the code generator emits directly to describe a message.
254// These should never used directly except to build a ReflectionSchema
255// object.
256//
257// EXPERIMENTAL: these are changing rapidly, and may completely disappear
258// or merge with ReflectionSchema.
259struct MigrationSchema {
260 int32 offsets_index;
261 int32 has_bit_indices_index;
262 int object_size;
263};
264
265struct PROTOBUF_EXPORT DescriptorTable {
266 bool* is_initialized;
267 const char* descriptor;
268 const char* filename;
269 int size; // of serialized descriptor
270 once_flag* once;
271 SCCInfoBase* const* init_default_instances;
272 const DescriptorTable* const* deps;
273 int num_sccs;
274 int num_deps;
275 const MigrationSchema* schemas;
276 const Message* const* default_instances;
277 const uint32* offsets;
278 // update the following descriptor arrays.
279 Metadata* file_level_metadata;
280 int num_messages;
281 const EnumDescriptor** file_level_enum_descriptors;
282 const ServiceDescriptor** file_level_service_descriptors;
283};
284
285// AssignDescriptors() pulls the compiled FileDescriptor from the DescriptorPool
286// and uses it to populate all of the global variables which store pointers to
287// the descriptor objects. It also constructs the reflection objects. It is
288// called the first time anyone calls descriptor() or GetReflection() on one of
289// the types defined in the file. AssignDescriptors() is thread-safe.
290void PROTOBUF_EXPORT AssignDescriptors(const DescriptorTable* table);
291
292// AddDescriptors() is a file-level procedure which adds the encoded
293// FileDescriptorProto for this .proto file to the global DescriptorPool for
294// generated files (DescriptorPool::generated_pool()). It ordinarily runs at
295// static initialization time, but is not used at all in LITE_RUNTIME mode.
296// AddDescriptors() is *not* thread-safe.
297void PROTOBUF_EXPORT AddDescriptors(const DescriptorTable* table);
298
299// These cannot be in lite so we put them in the reflection.
300PROTOBUF_EXPORT void UnknownFieldSetSerializer(const uint8* base, uint32 offset,
301 uint32 tag, uint32 has_offset,
302 io::CodedOutputStream* output);
303
304} // namespace internal
305} // namespace protobuf
306} // namespace google
307
308#include <google/protobuf/port_undef.inc>
309
310#endif // GOOGLE_PROTOBUF_GENERATED_MESSAGE_REFLECTION_H__
311