aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/google/protobuf/extension_set.h
diff options
context:
space:
mode:
authorGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-12-18 02:11:36 +0000
committerGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-12-18 02:11:36 +0000
commitfccb146e3fe437b0df1e9c50d4b8e1080ddb4bd9 (patch)
tree9f2d9fe0267d96a54e541377ffeada3d0bff0d1d /src/google/protobuf/extension_set.h
parentd5cf7b55a6a1f959d1646785f63ca2b62da78079 (diff)
Massive roll-up of changes. See CHANGES.txt.
Diffstat (limited to 'src/google/protobuf/extension_set.h')
-rw-r--r--src/google/protobuf/extension_set.h202
1 files changed, 146 insertions, 56 deletions
diff --git a/src/google/protobuf/extension_set.h b/src/google/protobuf/extension_set.h
index e5ac277e..b1a55338 100644
--- a/src/google/protobuf/extension_set.h
+++ b/src/google/protobuf/extension_set.h
@@ -53,6 +53,7 @@ namespace protobuf {
class FieldDescriptor; // descriptor.h
class DescriptorPool; // descriptor.h
class MessageLite; // message_lite.h
+ class Message; // message.h
class MessageFactory; // message.h
class UnknownFieldSet; // unknown_field_set.h
namespace io {
@@ -76,6 +77,84 @@ namespace internal {
// ExtensionSet::Extension small.
typedef uint8 FieldType;
+// A function which, given an integer value, returns true if the number
+// matches one of the defined values for the corresponding enum type. This
+// is used with RegisterEnumExtension, below.
+typedef bool EnumValidityFunc(int number);
+
+// Version of the above which takes an argument. This is needed to deal with
+// extensions that are not compiled in.
+typedef bool EnumValidityFuncWithArg(const void* arg, int number);
+
+// Information about a registered extension.
+struct ExtensionInfo {
+ inline ExtensionInfo() {}
+ inline ExtensionInfo(FieldType type, bool is_repeated, bool is_packed)
+ : type(type), is_repeated(is_repeated), is_packed(is_packed),
+ descriptor(NULL) {}
+
+ FieldType type;
+ bool is_repeated;
+ bool is_packed;
+
+ union {
+ struct {
+ EnumValidityFuncWithArg* enum_is_valid;
+ const void* enum_is_valid_arg;
+ };
+ const MessageLite* message_prototype;
+ };
+
+ // The descriptor for this extension, if one exists and is known. May be
+ // NULL. Must not be NULL if the descriptor for the extension does not
+ // live in the same pool as the descriptor for the containing type.
+ const FieldDescriptor* descriptor;
+};
+
+// Abstract interface for an object which looks up extension definitions. Used
+// when parsing.
+class LIBPROTOBUF_EXPORT ExtensionFinder {
+ public:
+ virtual ~ExtensionFinder();
+
+ // Find the extension with the given containing type and number.
+ virtual bool Find(int number, ExtensionInfo* output) = 0;
+};
+
+// Implementation of ExtensionFinder which finds extensions defined in .proto
+// files which have been compiled into the binary.
+class LIBPROTOBUF_EXPORT GeneratedExtensionFinder : public ExtensionFinder {
+ public:
+ GeneratedExtensionFinder(const MessageLite* containing_type)
+ : containing_type_(containing_type) {}
+ virtual ~GeneratedExtensionFinder() {}
+
+ // Returns true and fills in *output if found, otherwise returns false.
+ virtual bool Find(int number, ExtensionInfo* output);
+
+ private:
+ const MessageLite* containing_type_;
+};
+
+// Implementation of ExtensionFinder which finds extensions in a given
+// DescriptorPool, using the given MessageFactory to construct sub-objects.
+// This class is implemented in extension_set_heavy.cc.
+class LIBPROTOBUF_EXPORT DescriptorPoolExtensionFinder : public ExtensionFinder {
+ public:
+ DescriptorPoolExtensionFinder(const DescriptorPool* pool,
+ MessageFactory* factory,
+ const Descriptor* containing_type)
+ : pool_(pool), factory_(factory), containing_type_(containing_type) {}
+ virtual ~DescriptorPoolExtensionFinder() {}
+
+ virtual bool Find(int number, ExtensionInfo* output);
+
+ private:
+ const DescriptorPool* pool_;
+ MessageFactory* factory_;
+ const Descriptor* containing_type_;
+};
+
// This is an internal helper class intended for use within the protocol buffer
// library and generated classes. Clients should not use it directly. Instead,
// use the generated accessors such as GetExtension() of the class being
@@ -92,11 +171,6 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
ExtensionSet();
~ExtensionSet();
- // A function which, given an integer value, returns true if the number
- // matches one of the defined values for the corresponding enum type. This
- // is used with RegisterEnumExtension, below.
- typedef bool EnumValidityFunc(int number);
-
// These are called at startup by protocol-compiler-generated code to
// register known extensions. The registrations are used by ParseField()
// to look up extensions for parsed field numbers. Note that dynamic parsing
@@ -117,11 +191,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
// =================================================================
// Add all fields which are currently present to the given vector. This
- // is useful to implement Reflection::ListFields(). The FieldDescriptors
- // are looked up by number from the given pool.
- //
- // TODO(kenton): Looking up each field by number is somewhat unfortunate.
- // Is there a better way?
+ // is useful to implement Reflection::ListFields().
void AppendToList(const Descriptor* containing_type,
const DescriptorPool* pool,
vector<const FieldDescriptor*>* output) const;
@@ -176,21 +246,25 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
const MessageLite& GetMessage(int number, const Descriptor* message_type,
MessageFactory* factory) const;
- void SetInt32 (int number, FieldType type, int32 value);
- void SetInt64 (int number, FieldType type, int64 value);
- void SetUInt32(int number, FieldType type, uint32 value);
- void SetUInt64(int number, FieldType type, uint64 value);
- void SetFloat (int number, FieldType type, float value);
- void SetDouble(int number, FieldType type, double value);
- void SetBool (int number, FieldType type, bool value);
- void SetEnum (int number, FieldType type, int value);
- void SetString(int number, FieldType type, const string& value);
- string * MutableString (int number, FieldType type);
- MessageLite* MutableMessage(int number, FieldType type,
- const MessageLite& prototype);
+ // |descriptor| may be NULL so long as it is known that the descriptor for
+ // the extension lives in the same pool as the descriptor for the containing
+ // type.
+#define desc const FieldDescriptor* descriptor // avoid line wrapping
+ void SetInt32 (int number, FieldType type, int32 value, desc);
+ void SetInt64 (int number, FieldType type, int64 value, desc);
+ void SetUInt32(int number, FieldType type, uint32 value, desc);
+ void SetUInt64(int number, FieldType type, uint64 value, desc);
+ void SetFloat (int number, FieldType type, float value, desc);
+ void SetDouble(int number, FieldType type, double value, desc);
+ void SetBool (int number, FieldType type, bool value, desc);
+ void SetEnum (int number, FieldType type, int value, desc);
+ void SetString(int number, FieldType type, const string& value, desc);
+ string * MutableString (int number, FieldType type, desc);
MessageLite* MutableMessage(int number, FieldType type,
- const Descriptor* message_type,
+ const MessageLite& prototype, desc);
+ MessageLite* MutableMessage(const FieldDescriptor* decsriptor,
MessageFactory* factory);
+#undef desc
// repeated fields -------------------------------------------------
@@ -217,21 +291,22 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
string * MutableRepeatedString (int number, int index);
MessageLite* MutableRepeatedMessage(int number, int index);
- void AddInt32 (int number, FieldType type, bool packed, int32 value);
- void AddInt64 (int number, FieldType type, bool packed, int64 value);
- void AddUInt32(int number, FieldType type, bool packed, uint32 value);
- void AddUInt64(int number, FieldType type, bool packed, uint64 value);
- void AddFloat (int number, FieldType type, bool packed, float value);
- void AddDouble(int number, FieldType type, bool packed, double value);
- void AddBool (int number, FieldType type, bool packed, bool value);
- void AddEnum (int number, FieldType type, bool packed, int value);
- void AddString(int number, FieldType type, const string& value);
- string * AddString (int number, FieldType type);
+#define desc const FieldDescriptor* descriptor // avoid line wrapping
+ void AddInt32 (int number, FieldType type, bool packed, int32 value, desc);
+ void AddInt64 (int number, FieldType type, bool packed, int64 value, desc);
+ void AddUInt32(int number, FieldType type, bool packed, uint32 value, desc);
+ void AddUInt64(int number, FieldType type, bool packed, uint64 value, desc);
+ void AddFloat (int number, FieldType type, bool packed, float value, desc);
+ void AddDouble(int number, FieldType type, bool packed, double value, desc);
+ void AddBool (int number, FieldType type, bool packed, bool value, desc);
+ void AddEnum (int number, FieldType type, bool packed, int value, desc);
+ void AddString(int number, FieldType type, const string& value, desc);
+ string * AddString (int number, FieldType type, desc);
MessageLite* AddMessage(int number, FieldType type,
- const MessageLite& prototype);
- MessageLite* AddMessage(int number, FieldType type,
- const Descriptor* message_type,
+ const MessageLite& prototype, desc);
+ MessageLite* AddMessage(const FieldDescriptor* descriptor,
MessageFactory* factory);
+#undef desc
void RemoveLast(int number);
void SwapElements(int number, int index1, int index2);
@@ -257,7 +332,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
// methods of ExtensionSet, this only works for generated message types --
// it looks up extensions registered using RegisterExtension().
bool ParseField(uint32 tag, io::CodedInputStream* input,
- const MessageLite* containing_type,
+ ExtensionFinder* extension_finder,
FieldSkipper* field_skipper);
// Specific versions for lite or full messages (constructs the appropriate
@@ -265,13 +340,13 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
bool ParseField(uint32 tag, io::CodedInputStream* input,
const MessageLite* containing_type);
bool ParseField(uint32 tag, io::CodedInputStream* input,
- const MessageLite* containing_type,
+ const Message* containing_type,
UnknownFieldSet* unknown_fields);
// Parse an entire message in MessageSet format. Such messages have no
// fields, only extensions.
bool ParseMessageSet(io::CodedInputStream* input,
- const MessageLite* containing_type,
+ ExtensionFinder* extension_finder,
FieldSkipper* field_skipper);
// Specific versions for lite or full messages (constructs the appropriate
@@ -279,7 +354,7 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
bool ParseMessageSet(io::CodedInputStream* input,
const MessageLite* containing_type);
bool ParseMessageSet(io::CodedInputStream* input,
- const MessageLite* containing_type,
+ const Message* containing_type,
UnknownFieldSet* unknown_fields);
// Write all extension fields with field numbers in the range
@@ -359,6 +434,11 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
// For repeated types, this indicates if the [packed=true] option is set.
bool is_packed;
+ // The descriptor for this extension, if one exists and is known. May be
+ // NULL. Must not be NULL if the descriptor for the extension does not
+ // live in the same pool as the descriptor for the containing type.
+ const FieldDescriptor* descriptor;
+
// For packed fields, the size of the packed data is recorded here when
// ByteSize() is called then used during serialization.
// TODO(kenton): Use atomic<int> when C++ supports it.
@@ -368,9 +448,15 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
void SerializeFieldWithCachedSizes(
int number,
io::CodedOutputStream* output) const;
+ uint8* SerializeFieldWithCachedSizesToArray(
+ int number,
+ uint8* target) const;
void SerializeMessageSetItemWithCachedSizes(
int number,
io::CodedOutputStream* output) const;
+ uint8* SerializeMessageSetItemWithCachedSizesToArray(
+ int number,
+ uint8* target) const;
int ByteSize(int number) const;
int MessageSetItemByteSize(int number) const;
void Clear();
@@ -381,14 +467,16 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
// Gets the extension with the given number, creating it if it does not
// already exist. Returns true if the extension did not already exist.
- bool MaybeNewExtension(int number, Extension** result);
+ bool MaybeNewExtension(int number, const FieldDescriptor* descriptor,
+ Extension** result);
// Parse a single MessageSet item -- called just after the item group start
// tag has been read.
bool ParseMessageSetItem(io::CodedInputStream* input,
- const MessageLite* containing_type,
+ ExtensionFinder* extension_finder,
FieldSkipper* field_skipper);
+
// Hack: RepeatedPtrFieldBase declares ExtensionSet as a friend. This
// friendship should automatically extend to ExtensionSet::Extension, but
// unfortunately some older compilers (e.g. GCC 3.4.4) do not implement this
@@ -412,16 +500,18 @@ class LIBPROTOBUF_EXPORT ExtensionSet {
// These are just for convenience...
inline void ExtensionSet::SetString(int number, FieldType type,
- const string& value) {
- MutableString(number, type)->assign(value);
+ const string& value,
+ const FieldDescriptor* descriptor) {
+ MutableString(number, type, descriptor)->assign(value);
}
inline void ExtensionSet::SetRepeatedString(int number, int index,
const string& value) {
MutableRepeatedString(number, index)->assign(value);
}
inline void ExtensionSet::AddString(int number, FieldType type,
- const string& value) {
- AddString(number, type)->assign(value);
+ const string& value,
+ const FieldDescriptor* descriptor) {
+ AddString(number, type, descriptor)->assign(value);
}
// ===================================================================
@@ -502,7 +592,7 @@ template<> inline TYPE PrimitiveTypeTraits<TYPE>::Get( \
} \
template<> inline void PrimitiveTypeTraits<TYPE>::Set( \
int number, FieldType field_type, TYPE value, ExtensionSet* set) { \
- set->Set##METHOD(number, field_type, value); \
+ set->Set##METHOD(number, field_type, value, NULL); \
} \
\
template<> inline TYPE RepeatedPrimitiveTypeTraits<TYPE>::Get( \
@@ -516,7 +606,7 @@ template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Set( \
template<> inline void RepeatedPrimitiveTypeTraits<TYPE>::Add( \
int number, FieldType field_type, bool is_packed, \
TYPE value, ExtensionSet* set) { \
- set->Add##METHOD(number, field_type, is_packed, value); \
+ set->Add##METHOD(number, field_type, is_packed, value, NULL); \
}
PROTOBUF_DEFINE_PRIMITIVE_TYPE( int32, Int32)
@@ -544,11 +634,11 @@ class LIBPROTOBUF_EXPORT StringTypeTraits {
}
static inline void Set(int number, FieldType field_type,
const string& value, ExtensionSet* set) {
- set->SetString(number, field_type, value);
+ set->SetString(number, field_type, value, NULL);
}
static inline string* Mutable(int number, FieldType field_type,
ExtensionSet* set) {
- return set->MutableString(number, field_type);
+ return set->MutableString(number, field_type, NULL);
}
};
@@ -571,11 +661,11 @@ class LIBPROTOBUF_EXPORT RepeatedStringTypeTraits {
static inline void Add(int number, FieldType field_type,
bool /*is_packed*/, const string& value,
ExtensionSet* set) {
- set->AddString(number, field_type, value);
+ set->AddString(number, field_type, value, NULL);
}
static inline string* Add(int number, FieldType field_type,
ExtensionSet* set) {
- return set->AddString(number, field_type);
+ return set->AddString(number, field_type, NULL);
}
};
@@ -596,7 +686,7 @@ class EnumTypeTraits {
static inline void Set(int number, FieldType field_type,
ConstType value, ExtensionSet* set) {
GOOGLE_DCHECK(IsValid(value));
- set->SetEnum(number, field_type, value);
+ set->SetEnum(number, field_type, value, NULL);
}
};
@@ -616,7 +706,7 @@ class RepeatedEnumTypeTraits {
static inline void Add(int number, FieldType field_type,
bool is_packed, ConstType value, ExtensionSet* set) {
GOOGLE_DCHECK(IsValid(value));
- set->AddEnum(number, field_type, is_packed, value);
+ set->AddEnum(number, field_type, is_packed, value, NULL);
}
};
@@ -640,7 +730,7 @@ class MessageTypeTraits {
static inline MutableType Mutable(int number, FieldType field_type,
ExtensionSet* set) {
return static_cast<Type*>(
- set->MutableMessage(number, field_type, Type::default_instance()));
+ set->MutableMessage(number, field_type, Type::default_instance(), NULL));
}
};
@@ -659,7 +749,7 @@ class RepeatedMessageTypeTraits {
static inline MutableType Add(int number, FieldType field_type,
ExtensionSet* set) {
return static_cast<Type*>(
- set->AddMessage(number, field_type, Type::default_instance()));
+ set->AddMessage(number, field_type, Type::default_instance(), NULL));
}
};