%module{Google::ProtocolBuffers::Dynamic}; #include "perl_unpollute.h" #include "introspection.h" #include #include %typemap{const Google::ProtocolBuffers::Dynamic::MessageDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::MessageOptionsDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::FieldDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::FieldOptionsDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::OneofDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::OneofOptionsDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::EnumDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::EnumOptionsDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::ServiceDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::ServiceOptionsDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::MethodDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::MethodOptionsDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::FileDef *}{simple}{ %xs_type{O_OBJECT}; }; %typemap{const Google::ProtocolBuffers::Dynamic::FileOptionsDef *}{simple}{ %xs_type{O_OBJECT}; }; %{ #define GPD_INTROSPECTION_RETURN_ARRAY(descriptor_field, package) \ int count = THIS->descriptor_field ## _count(); \ AV *array = newAV(); \ \ av_extend(array, count); \ for (int i = 0; i < count; ++i) { \ SV *item = newSV(0); \ \ sv_setref_iv( \ item, \ "Google::ProtocolBuffers::Dynamic::" #package, \ (IV) THIS->descriptor_field(i) \ );; \ av_push(array, item); \ } \ \ RETVAL = newRV_noinc((SV*) array); %} %name{Google::ProtocolBuffers::Dynamic::DescriptorOptionsDef} class gpd::intr::DescriptorOptionsWrapper { ~DescriptorOptionsWrapper(); SV *custom_option_by_name(const std::string &name); SV *custom_option_by_number(int numbere); SV *AUTOLOAD() %code%{ if (!THIS->get_attribute(cv, &RETVAL)) { croak("Unknown option '%.*s'", SvCUR(cv), SvPVX(cv)); } %}; }; %name{Google::ProtocolBuffers::Dynamic::MessageDef} class google::protobuf::Descriptor { std::string name(); std::string full_name() const; int field_count() const; %name{oneof_count} int oneof_decl_count() const; %name{find_field_by_number} const Google::ProtocolBuffers::Dynamic::FieldDef *FindFieldByNumber(uint32_t number) const; %name{find_field_by_name} const Google::ProtocolBuffers::Dynamic::FieldDef *FindFieldByName(const std::string &name) const; %name{find_oneof_by_name} const Google::ProtocolBuffers::Dynamic::OneofDef *FindOneofByName(const std::string &name) const; SV* fields() const %code{% GPD_INTROSPECTION_RETURN_ARRAY(field, FieldDef); %}; SV* oneofs() const %code{% GPD_INTROSPECTION_RETURN_ARRAY(oneof_decl, OneofDef); %}; bool is_map_entry() const %code{% RETVAL = THIS->options().map_entry(); %}; const Google::ProtocolBuffers::Dynamic::FileDef *file() const; const Google::ProtocolBuffers::Dynamic::MessageOptionsDef *options() const %code%{ RETVAL = gpd::intr::options_make_wrapper(aTHX_ THIS); %}; }; %name{Google::ProtocolBuffers::Dynamic::MessageOptionsDef} class gpd::intr::MessageOptionsWrapper : public %name{Google::ProtocolBuffers::Dynamic::DescriptorOptionsDef} gpd::intr::DescriptorOptionsWrapper { bool deprecated(); }; %name{Google::ProtocolBuffers::Dynamic::FieldDef} class google::protobuf::FieldDescriptor { std::string name() const; std::string full_name() const; uint32_t number() const; bool is_extension() const; int label(); %name{is_packed} bool is_packed() const; bool is_message() const %code%{ RETVAL = THIS->cpp_type() == google::protobuf::FieldDescriptor::CppType::CPPTYPE_MESSAGE; %}; bool is_string() const %code%{ RETVAL = THIS->cpp_type() == google::protobuf::FieldDescriptor::CppType::CPPTYPE_STRING; %}; bool is_repeated() const; bool is_primitive() const %code{% RETVAL = gpd::intr::field_is_primitive(THIS); %}; bool is_map() const; // TODO JSON name %name{descriptor_type} int type() const; int value_type() const %code{% RETVAL = gpd::intr::field_value_type(THIS); %}; SV *default_value() const %code{% RETVAL = gpd::intr::field_default_value(aTHX_ THIS); %}; const Google::ProtocolBuffers::Dynamic::MessageDef *containing_type() const; const Google::ProtocolBuffers::Dynamic::OneofDef *containing_oneof() const; #if GOOGLE_PROTOBUF_VERSION >= 3012000 const Google::ProtocolBuffers::Dynamic::OneofDef *real_containing_oneof() const; #else const Google::ProtocolBuffers::Dynamic::OneofDef *real_containing_oneof() const %code{% PERL_UNUSED_VAR(THIS); RETVAL = NULL; %}; #endif const Google::ProtocolBuffers::Dynamic::EnumDef *enum_type() const; const Google::ProtocolBuffers::Dynamic::MessageDef *message_type() const; #if GOOGLE_PROTOBUF_VERSION >= 3012000 bool has_presence() const; #else bool has_presence() const %code{% RETVAL = !THIS->is_repeated() && ( THIS->cpp_type() == google::protobuf::FieldDescriptor::CppType::CPPTYPE_MESSAGE || THIS->containing_oneof() || THIS->file()->syntax() == google::protobuf::FileDescriptor::SYNTAX_PROTO2 ); %}; #endif const Google::ProtocolBuffers::Dynamic::FileDef *file() const; const Google::ProtocolBuffers::Dynamic::FieldOptionsDef *options() const %code%{ RETVAL = gpd::intr::options_make_wrapper(aTHX_ THIS); %}; }; %name{Google::ProtocolBuffers::Dynamic::FieldOptionsDef} class gpd::intr::FieldOptionsWrapper : public %name{Google::ProtocolBuffers::Dynamic::DescriptorOptionsDef} gpd::intr::DescriptorOptionsWrapper { bool deprecated(); }; %name{Google::ProtocolBuffers::Dynamic::OneofDef} class google::protobuf::OneofDescriptor { std::string name() const; std::string full_name() const; int field_count(); const Google::ProtocolBuffers::Dynamic::FieldDef *find_field_by_number(int number) const %code{% RETVAL = gpd::intr::oneof_find_field_by_number(THIS, number); %}; const Google::ProtocolBuffers::Dynamic::FieldDef *find_field_by_name(std::string name) const %code{% RETVAL = gpd::intr::oneof_find_field_by_name(THIS, name); %}; SV* fields() const %code{% GPD_INTROSPECTION_RETURN_ARRAY(field, FieldDef); %}; const Google::ProtocolBuffers::Dynamic::MessageDef *containing_type() const; #if GOOGLE_PROTOBUF_VERSION >= 3012000 bool is_synthetic() const; #else bool is_synthetic() const %code{% PERL_UNUSED_VAR(THIS); RETVAL = false; %}; #endif const Google::ProtocolBuffers::Dynamic::FileDef *file() const; const Google::ProtocolBuffers::Dynamic::OneofOptionsDef *options() const %code%{ RETVAL = gpd::intr::options_make_wrapper(aTHX_ THIS); %}; }; %name{Google::ProtocolBuffers::Dynamic::OneofOptionsDef} class gpd::intr::OneofOptionsWrapper : public %name{Google::ProtocolBuffers::Dynamic::DescriptorOptionsDef} gpd::intr::DescriptorOptionsWrapper { }; %name{Google::ProtocolBuffers::Dynamic::EnumDef} class google::protobuf::EnumDescriptor { std::string name(); std::string full_name() const; int default_value() const %code%{ RETVAL = gpd::intr::enum_default_value(THIS); %}; int value_count() const; SV *find_number_by_name(std::string name) %code{% const google::protobuf::EnumValueDescriptor *value_descriptor = THIS->FindValueByName(name); RETVAL = value_descriptor ? newSViv(value_descriptor->number()) : &PL_sv_undef; %}; SV *find_name_by_number(int number) %code{% const google::protobuf::EnumValueDescriptor *value_descriptor = THIS->FindValueByNumber(number); if (value_descriptor) { const std::string &name = value_descriptor->name(); RETVAL = newSVpvn(name.data(), name.size()); } else { RETVAL = &PL_sv_undef; } %}; SV *values() const %code{% HV *values = newHV(); for (int i = 0, max = THIS->value_count(); i < max; ++i) { const google::protobuf::EnumValueDescriptor *value_descriptor = THIS->value(i); const std::string &name = value_descriptor->name(); SV **value = hv_fetch(values, name.data(), name.size(), 1); sv_setiv(*value, value_descriptor->number()); } RETVAL = newRV_noinc((SV *) values); %}; const Google::ProtocolBuffers::Dynamic::FileDef *file() const; const Google::ProtocolBuffers::Dynamic::EnumOptionsDef *options() const %code%{ RETVAL = gpd::intr::options_make_wrapper(aTHX_ THIS); %}; }; %name{Google::ProtocolBuffers::Dynamic::EnumOptionsDef} class gpd::intr::EnumOptionsWrapper : public %name{Google::ProtocolBuffers::Dynamic::DescriptorOptionsDef} gpd::intr::DescriptorOptionsWrapper { bool deprecated(); }; %name{Google::ProtocolBuffers::Dynamic::ServiceDef} class google::protobuf::ServiceDescriptor { std::string name(); std::string full_name(); SV* methods() const %code{% GPD_INTROSPECTION_RETURN_ARRAY(method, MethodDef); %}; const Google::ProtocolBuffers::Dynamic::FileDef *file() const; const Google::ProtocolBuffers::Dynamic::ServiceOptionsDef *options() const %code%{ RETVAL = gpd::intr::options_make_wrapper(aTHX_ THIS); %}; }; %name{Google::ProtocolBuffers::Dynamic::ServiceOptionsDef} class gpd::intr::ServiceOptionsWrapper : public %name{Google::ProtocolBuffers::Dynamic::DescriptorOptionsDef} gpd::intr::DescriptorOptionsWrapper { bool deprecated(); }; %name{Google::ProtocolBuffers::Dynamic::MethodDef} class google::protobuf::MethodDescriptor { std::string name(); std::string full_name(); %name{containing_service} const Google::ProtocolBuffers::Dynamic::ServiceDef *service(); const Google::ProtocolBuffers::Dynamic::MessageDef *input_type(); const Google::ProtocolBuffers::Dynamic::MessageDef *output_type(); bool client_streaming(); bool server_streaming(); const Google::ProtocolBuffers::Dynamic::FileDef *file() const; const Google::ProtocolBuffers::Dynamic::MethodOptionsDef *options() const %code%{ RETVAL = gpd::intr::options_make_wrapper(aTHX_ THIS); %}; }; %name{Google::ProtocolBuffers::Dynamic::MethodOptionsDef} class gpd::intr::MethodOptionsWrapper : public %name{Google::ProtocolBuffers::Dynamic::DescriptorOptionsDef} gpd::intr::DescriptorOptionsWrapper { bool deprecated(); }; %name{Google::ProtocolBuffers::Dynamic::FileDef} class google::protobuf::FileDescriptor { std::string name(); std::string package(); SV* dependencies() const %code{% GPD_INTROSPECTION_RETURN_ARRAY(dependency, FileDef); %}; SV* public_dependencies() const %code{% GPD_INTROSPECTION_RETURN_ARRAY(public_dependency, FileDef); %}; SV* messages() const %code{% GPD_INTROSPECTION_RETURN_ARRAY(message_type, MessageDef); %}; SV* enums() const %code{% GPD_INTROSPECTION_RETURN_ARRAY(enum_type, EnumDef); %}; SV* services() const %code{% GPD_INTROSPECTION_RETURN_ARRAY(service, ServiceDef); %}; SV* extensions() const %code{% GPD_INTROSPECTION_RETURN_ARRAY(extension, FieldDef); %}; const Google::ProtocolBuffers::Dynamic::FileOptionsDef *options() const %code%{ google::protobuf::DynamicMessageFactory *factory; google::protobuf::Message *options_dyn; RETVAL = NULL; if (gpd::intr::options_make_wrapper(THIS->pool(), THIS->options(), &factory, &options_dyn)) { RETVAL = new gpd::intr::FileOptionsWrapper(aTHX_ factory, options_dyn, &THIS->options()); } %}; }; %name{Google::ProtocolBuffers::Dynamic::FileOptionsDef} class gpd::intr::FileOptionsWrapper : public %name{Google::ProtocolBuffers::Dynamic::DescriptorOptionsDef} gpd::intr::DescriptorOptionsWrapper { bool deprecated(); }; %package{Google::ProtocolBuffers::Dynamic::Mapper}; %{ #undef GPD_INTROSPECTION_RETURN_ARRAY const Google::ProtocolBuffers::Dynamic::MessageDef* message_descriptor(SV *) INIT: google::protobuf::Descriptor *descriptor = (google::protobuf::Descriptor *) CvXSUBANY(cv).any_ptr; CODE: RETVAL = descriptor; OUTPUT: RETVAL const Google::ProtocolBuffers::Dynamic::EnumDef* enum_descriptor(SV *) INIT: google::protobuf::EnumDescriptor *descriptor = (google::protobuf::EnumDescriptor *) CvXSUBANY(cv).any_ptr; CODE: RETVAL = descriptor; OUTPUT: RETVAL UV constant() CODE: RETVAL = CvXSUBANY(cv).any_uv; OUTPUT: RETVAL const Google::ProtocolBuffers::Dynamic::ServiceDef* service_descriptor(SV *) INIT: google::protobuf::ServiceDescriptor *descriptor = (google::protobuf::ServiceDescriptor *) CvXSUBANY(cv).any_ptr; CODE: RETVAL = descriptor; OUTPUT: RETVAL #define DESCRIPTOR_TYPE(name) \ gpd::intr::define_constant(aTHX_ "DESCRIPTOR_" #name, "descriptor", google::protobuf::FieldDescriptor::TYPE_##name); #define VALUE_TYPE(name) \ gpd::intr::define_constant(aTHX_ "VALUE_" #name, "values", gpd::intr::VALUE_##name); #define LABEL_TYPE(name) \ gpd::intr::define_constant(aTHX_ "LABEL_" #name, "labels", google::protobuf::FieldDescriptor::LABEL_##name); BOOT: LABEL_TYPE(OPTIONAL); LABEL_TYPE(REPEATED); LABEL_TYPE(REQUIRED); DESCRIPTOR_TYPE(DOUBLE); DESCRIPTOR_TYPE(FLOAT); DESCRIPTOR_TYPE(INT64); DESCRIPTOR_TYPE(UINT64); DESCRIPTOR_TYPE(INT32); DESCRIPTOR_TYPE(FIXED64); DESCRIPTOR_TYPE(FIXED32); DESCRIPTOR_TYPE(BOOL); DESCRIPTOR_TYPE(STRING); DESCRIPTOR_TYPE(GROUP); DESCRIPTOR_TYPE(MESSAGE); DESCRIPTOR_TYPE(BYTES); DESCRIPTOR_TYPE(UINT32); DESCRIPTOR_TYPE(ENUM); DESCRIPTOR_TYPE(SFIXED32); DESCRIPTOR_TYPE(SFIXED64); DESCRIPTOR_TYPE(SINT32); DESCRIPTOR_TYPE(SINT64); VALUE_TYPE(FLOAT); VALUE_TYPE(DOUBLE); VALUE_TYPE(BOOL); VALUE_TYPE(STRING); VALUE_TYPE(BYTES); VALUE_TYPE(MESSAGE); VALUE_TYPE(ENUM); VALUE_TYPE(INT32); VALUE_TYPE(UINT32); VALUE_TYPE(INT64); VALUE_TYPE(UINT64); %}