#include "pb/gpb_mapping.h"
#include "pb/decoder.h"
#include <google/protobuf/descriptor.h>
namespace gpdp = gpd::pb;
namespace gp = google::protobuf;
using namespace std;
namespace {
void populate_field(gpdp::DescriptorSet *descriptor_set, gpdp::Descriptor *gpd_descriptor, const gp::FieldDescriptor *field, const gp::DescriptorPool *descriptor_pool) {
bool repeated = field->label() == gp::FieldDescriptor::LABEL_REPEATED;
if (field->type() == gp::FieldDescriptor::TYPE_MESSAGE) {
const gpdp::Descriptor *field_message = map_pb_descriptor(descriptor_set, field->message_type(), descriptor_pool);
gpd_descriptor->add_field(field->number(), repeated, field_message);
} else {
gpd_descriptor->add_field(field->number(), gpdp::FieldType(field->type()), repeated);
}
}
void populate_descriptor(gpdp::DescriptorSet *descriptor_set, gpdp::Descriptor *gpd_descriptor, const gp::Descriptor *descriptor, const gp::DescriptorPool *descriptor_pool) {
for (int i = 0, max = descriptor->field_count(); i < max; ++i) {
const gp::FieldDescriptor *field = descriptor->field(i);
populate_field(descriptor_set, gpd_descriptor, field, descriptor_pool);
}
vector<const gp::FieldDescriptor *> extensions;
descriptor_pool->FindAllExtensions(descriptor, &extensions);
for (vector<const gp::FieldDescriptor *>::const_iterator it = extensions.begin(), en = extensions.end(); it != en; ++it) {
populate_field(descriptor_set, gpd_descriptor, *it, descriptor_pool);
}
}
}
const gpdp::Descriptor *gpdp::map_pb_descriptor(gpdp::DescriptorSet *descriptor_set, const gp::Descriptor *descriptor, const gp::DescriptorPool *descriptor_pool) {
string message_name = descriptor->full_name();
const gpdp::Descriptor *gpd_descriptor = descriptor_set->get_descriptor(message_name);
if (!gpd_descriptor) {
gpdp::Descriptor *new_gpd_descriptor = new gpdp::Descriptor();
descriptor_set->add_descriptor(message_name, new_gpd_descriptor);
populate_descriptor(descriptor_set, new_gpd_descriptor, descriptor, descriptor_pool);
gpd_descriptor = new_gpd_descriptor;
}
return gpd_descriptor;
}