Google-ProtocolBuffers-Dynamic

 view release on metacpan or  search on metacpan

src/dynamic.cpp  view on Meta::CPAN

    }

    void copy_and_bind(pTHX_ const char *name, const char *target, const string &perl_package, Refcounted *refcounted) {
        copy_and_bind(aTHX_ name, target, perl_package, refcounted, refcounted);
    }

    void copy_and_bind(pTHX_ const char *name, const string &perl_package, Refcounted *refcounted) {
        copy_and_bind(aTHX_ name, name, perl_package, refcounted);
    }

    void copy_and_bind(pTHX_ const char *name, const string &perl_package, Refcounted *refcounted, void *obj) {
        copy_and_bind(aTHX_ name, name, perl_package, refcounted, obj);
    }

    void copy_and_bind(pTHX_ const char *name, const char *prefix, const char *suffix, const string &perl_package, Mapper *mapper) {
        copy_and_bind(aTHX_ name, (string(prefix) + suffix).c_str(), perl_package, mapper);
    }

    void copy_and_bind_field(pTHX_ const char *name, const string &name_prefix, const string &name_suffix, const string &perl_package, MapperField *mapperfield) {
        string temp_name = name_prefix + mapperfield->name() + name_suffix;

        if (mapperfield->is_extension()) {
            for (int i = 0, max = temp_name.size(); i < max; ++i)
                temp_name[i] = temp_name[i] == '.' ? '_' : tolower(temp_name[i]);
        }

        copy_and_bind(aTHX_ name, temp_name.c_str(), perl_package, mapperfield);
    }

    bool is_map_entry(const MessageDef *message, bool check_implicit_map) {
        if (message->mapentry())
            return true;
        if (!check_implicit_map)
            return false;
        const FieldDef *key = message->FindFieldByNumber(1);
        const FieldDef *value = message->FindFieldByNumber(2);
        const char *msg_name = message->name();
        if (message->field_count() != 2 || message->oneof_count() != 0 ||
                key == NULL || value == NULL)
            return false;
        if (strcmp(key->name(), "key") != 0 || strcmp(value->name(), "value") != 0)
            return false;
        size_t msg_name_len = strlen(msg_name);
        if (msg_name_len < 6 || strcmp(msg_name + msg_name_len - 5, "Entry") != 0)
            return false;
        if (key->IsSequence() || value->IsSequence() ||
                key->is_extension() || value->is_extension() ||
                key->subdef() /* message or enum */)
            return false;
        return true;
    }

    void push_method_def(ServiceDef *service_def, const MethodDescriptor *descriptor, const MessageDef *input_message, const MessageDef *output_message) {
        service_def->add_method(
            MethodDef(
                descriptor->name(),
                descriptor->full_name(),
                service_def,
                input_message,
                output_message,
                descriptor->client_streaming(),
                descriptor->server_streaming()
            )
        );
    }
}

void Dynamic::map_message(pTHX_ const string &message, const string &perl_package, const MappingOptions &options) {
    const DescriptorPool *pool = descriptor_loader.pool();
    const Descriptor *descriptor = pool->FindMessageTypeByName(message);

    if (descriptor == NULL) {
        croak("Unable to find a descriptor for message '%s'", message.c_str());
    }

    map_message_recursive(aTHX_ descriptor, perl_package, options);
}

void Dynamic::map_package(pTHX_ const string &pb_package, const string &perl_package_prefix, const MappingOptions &options) {
    map_package_or_prefix(aTHX_ pb_package, false, perl_package_prefix, options);
}

void Dynamic::map_package_prefix(pTHX_ const string &pb_prefix, const string &perl_package_prefix, const MappingOptions &options) {
    map_package_or_prefix(aTHX_ pb_prefix, true, perl_package_prefix, options);
}

void Dynamic::map_package_or_prefix(pTHX_ const string &pb_package_or_prefix, bool is_prefix, const string &perl_package_prefix, const MappingOptions &options) {
    string prefix_and_dot = pb_package_or_prefix + ".";

    for (unordered_set<const FileDescriptor *>::iterator it = files.begin(), en = files.end(); it != en; ++it) {
        const FileDescriptor *file = *it;
        const string &file_package = file->package();
        bool is_exact = false;

        if (pb_package_or_prefix == file_package) {
            is_exact = true;
        } else if (is_prefix) {

            if (file_package.length() <= prefix_and_dot.length() ||
                    strncmp(file_package.data(), prefix_and_dot.data(), prefix_and_dot.length()) != 0)
                continue;
        } else {
            continue;
        }

        string perl_package = perl_package_prefix;
        if (!is_exact) {
            perl_package += "::";

            for (string::const_iterator it = file_package.begin() + prefix_and_dot.length(), en = file_package.end(); it != en; ++it) {
                if (*it == '.')
                    perl_package += "::";
                else
                    perl_package += *it;
            }
        }

        for (int i = 0, max = file->message_type_count(); i < max; ++i) {
            const Descriptor *descriptor = file->message_type(i);
            if (descriptor_map.find(descriptor->full_name()) != descriptor_map.end())
                continue;

src/dynamic.cpp  view on Meta::CPAN

    if (options.client_services == MappingOptions::Disable)
        return;

    bool define_perl_names = !options.no_redefine_perl_names || gv_stashpvn(perl_package.data(), perl_package.size(), 0) == NULL;

    if (define_perl_names)
        check_package(aTHX_ perl_package, descriptor->full_name());
    if (mapped_services.find(descriptor->full_name()) != mapped_services.end())
        croak("Service '%s' has already been mapped", descriptor->full_name().c_str());

    mapped_services.insert(descriptor->full_name());
    mark_package(aTHX_ perl_package, options.stack_trace);

    if (define_perl_names)
        bind_service(aTHX_ perl_package, descriptor, options);
}

void Dynamic::bind_service(pTHX_ const string &perl_package, const ServiceDescriptor *descriptor, const MappingOptions &options) {
    ServiceDef *service_def = new ServiceDef(descriptor->full_name());

    switch (options.client_services) {
    case MappingOptions::Noop:
        map_service_noop(aTHX_ descriptor, perl_package, options, service_def);
        break;
    case MappingOptions::GrpcXS:
        map_service_grpc_xs(aTHX_ descriptor, perl_package, options, service_def);
        break;
    default:
        croak("Unhandled client_service option %d", options.client_services);
    }

    copy_and_bind(aTHX_ "service_descriptor", perl_package, this, const_cast<ServiceDescriptor *>(descriptor));
}

void Dynamic::map_service_noop(pTHX_ const ServiceDescriptor *descriptor, const string &perl_package, const MappingOptions &options, ServiceDef *service_def) {
    for (int i = 0, max = descriptor->method_count(); i < max; ++i) {
        const MethodDescriptor *method = descriptor->method(i);
        const Descriptor *input = method->input_type(), *output = method->output_type();
        const MessageDef *input_def = def_builder.GetMessageDef(input);
        const MessageDef *output_def = def_builder.GetMessageDef(output);

        push_method_def(service_def, method, input_def, output_def);
    }
}

void Dynamic::map_service_grpc_xs(pTHX_ const ServiceDescriptor *descriptor, const string &perl_package, const MappingOptions &options, ServiceDef *service_def) {
    string isa_name = perl_package + "::ISA";
    AV *isa = get_av(isa_name.c_str(), 1);
    SV *base_stub_package = newSVpvs("Grpc::Client::BaseStub");

    SvREFCNT_inc(base_stub_package);
    av_push(isa, base_stub_package);
    load_module(PERL_LOADMOD_NOIMPORT, base_stub_package, NULL);

    for (int i = 0, max = descriptor->method_count(); i < max; ++i) {
        const MethodDescriptor *method = descriptor->method(i);
        string full_method = "/" + descriptor->full_name() + "/" + method->name().c_str();
        const Descriptor *input = method->input_type(), *output = method->output_type();
        const MessageDef *input_def = def_builder.GetMessageDef(input);
        const MessageDef *output_def = def_builder.GetMessageDef(output);
        MethodMapper *mapper = new MethodMapper(aTHX_ this, full_method, input_def, output_def, method->client_streaming(), method->server_streaming());

        copy_and_bind(aTHX_ "grpc_xs_call_service_passthrough", method->name().c_str(), perl_package, mapper);

        pending_methods.push_back(mapper);
        push_method_def(service_def, method, input_def, output_def);
    }
}

void Dynamic::resolve_references() {
    for (std::vector<Mapper *>::iterator it = pending.begin(), en = pending.end(); it != en; ++it)
        (*it)->resolve_mappers();
    for (std::vector<Mapper *>::iterator it = pending.begin(), en = pending.end(); it != en; ++it)
        (*it)->create_encoder_decoder();
    pending.clear();
    for (std::vector<MethodMapper *>::iterator it = pending_methods.begin(), en = pending_methods.end(); it != en; ++it)
        (*it)->resolve_input_output();
    pending_methods.clear();
}

const Mapper *Dynamic::find_mapper(const MessageDef *message_def) const {
    unordered_map<string, const Mapper *>::const_iterator item = descriptor_map.find(message_def->full_name());

    if (item == descriptor_map.end())
        croak("Unknown type '%s'", message_def->full_name());

    return item->second;
}



( run in 2.567 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )