#ifndef _GPD_XS_DYNAMIC_INTROSPECTION
#define _GPD_XS_DYNAMIC_INTROSPECTION
#include <string>
namespace google {
namespace protobuf {
class Message;
class Descriptor;
class MessageOptions;
class FieldDescriptor;
class FieldOptions;
class OneofDescriptor;
class OneofOptions;
class EnumDescriptor;
class EnumOptions;
class ServiceDescriptor;
class ServiceOptions;
class MethodDescriptor;
class MethodOptions;
class FileDescriptor;
class FileOptions;
class DescriptorPool;
class DynamicMessageFactory;
}
}
#include "thx_member.h"
namespace gpd {
namespace intr {
class DescriptorOptionsWrapper;
// same values as in upb/def.h, for backwards compatibility/stability
enum ValueType {
VALUE_BOOL = 1,
VALUE_FLOAT = 2,
VALUE_INT32 = 3,
VALUE_UINT32 = 4,
VALUE_ENUM = 5, /* Enum values are int32. */
VALUE_STRING = 6,
VALUE_BYTES = 7,
VALUE_MESSAGE = 8,
VALUE_DOUBLE = 9,
VALUE_INT64 = 10,
VALUE_UINT64 = 11,
VALUE_INVALID = -1
};
// helpers for uPB methods that don't have a direct equivalent in the descriptor API
ValueType field_value_type(const google::protobuf::FieldDescriptor *field_def);
bool field_is_primitive(const google::protobuf::FieldDescriptor *field_def);
SV *field_default_value(pTHX_ const google::protobuf::FieldDescriptor *field_def);
int enum_default_value(const google::protobuf::EnumDescriptor *enum_def);
const google::protobuf::FieldDescriptor *oneof_find_field_by_number(const google::protobuf::OneofDescriptor *oneof_def, int number);
const google::protobuf::FieldDescriptor *oneof_find_field_by_name(const google::protobuf::OneofDescriptor *oneof_def, const std::string &name);
bool options_make_wrapper(const google::protobuf::DescriptorPool *descriptor_pool, const google::protobuf::Message &options_def, google::protobuf::DynamicMessageFactory **factory, google::protobuf::Message **options_dyn);
template<class W, class D>
W *options_make_wrapper(pTHX_ const D *descriptor) {
google::protobuf::DynamicMessageFactory *factory;
google::protobuf::Message *options_dyn;
if (options_make_wrapper(descriptor->file()->pool(), descriptor->options(), &factory, &options_dyn)) {
return new W(aTHX_ factory, options_dyn, &descriptor->options());
}
return NULL;
}
// helper function for introspection.xsp
void define_constant(pTHX_ const char *name, const char *tag, int value);
class DescriptorOptionsWrapper {
public:
DescriptorOptionsWrapper(pTHX_ google::protobuf::DynamicMessageFactory *_factory, const google::protobuf::Message *_options);
virtual ~DescriptorOptionsWrapper();
SV *custom_option_by_name(const std::string &name);
SV *custom_option_by_number(int number);
bool get_attribute(CV *autoload_cv, SV **retval);
private:
SV *get_field(const google::protobuf::FieldDescriptor *field);
DECL_THX_MEMBER;
google::protobuf::DynamicMessageFactory *factory;
const google::protobuf::Message *options;
};
#define OPTIONS_WRAPPER_SCAFFOLDING(OPT_TYPE) \
private: \
const google::protobuf::OPT_TYPE ## Options *options; \
public: \
OPT_TYPE ## OptionsWrapper(pTHX_ \
google::protobuf::DynamicMessageFactory *_factory, \
google::protobuf::Message *_options_dyn, \
const google::protobuf::OPT_TYPE ## Options *_options) : \
DescriptorOptionsWrapper(aTHX_ _factory, _options_dyn), \
options(_options) { \
}
class MessageOptionsWrapper : public DescriptorOptionsWrapper {
OPTIONS_WRAPPER_SCAFFOLDING(Message);
bool deprecated();
};
class FieldOptionsWrapper : public DescriptorOptionsWrapper {
OPTIONS_WRAPPER_SCAFFOLDING(Field);
bool deprecated();
};
class OneofOptionsWrapper : public DescriptorOptionsWrapper {
OPTIONS_WRAPPER_SCAFFOLDING(Oneof);
};
class EnumOptionsWrapper : public DescriptorOptionsWrapper {
OPTIONS_WRAPPER_SCAFFOLDING(Enum);
bool deprecated();
};
class ServiceOptionsWrapper : public DescriptorOptionsWrapper {
OPTIONS_WRAPPER_SCAFFOLDING(Service);
bool deprecated();
};
class MethodOptionsWrapper : public DescriptorOptionsWrapper {
OPTIONS_WRAPPER_SCAFFOLDING(Method);
bool deprecated();
};
class FileOptionsWrapper : public DescriptorOptionsWrapper {
OPTIONS_WRAPPER_SCAFFOLDING(File);
bool deprecated();
};
#undef OPTIONS_WRAPPER_SCAFFOLDING
}
}
// type aliases to make XS++-generated code work
namespace Google {
namespace ProtocolBuffers {
namespace Dynamic {
typedef google::protobuf::Descriptor MessageDef;
typedef gpd::intr::MessageOptionsWrapper MessageOptionsDef;
typedef google::protobuf::FieldDescriptor FieldDef;
typedef gpd::intr::FieldOptionsWrapper FieldOptionsDef;
typedef google::protobuf::OneofDescriptor OneofDef;
typedef gpd::intr::OneofOptionsWrapper OneofOptionsDef;
typedef google::protobuf::EnumDescriptor EnumDef;
typedef gpd::intr::EnumOptionsWrapper EnumOptionsDef;
typedef google::protobuf::ServiceDescriptor ServiceDef;
typedef gpd::intr::ServiceOptionsWrapper ServiceOptionsDef;
typedef google::protobuf::MethodDescriptor MethodDef;
typedef gpd::intr::MethodOptionsWrapper MethodOptionsDef;
typedef google::protobuf::FileDescriptor FileDef;
typedef gpd::intr::FileOptionsWrapper FileOptionsDef;
}
}
}
#endif