| 459 | class EncodeProtoOp : public OpKernel { |
| 460 | public: |
| 461 | explicit EncodeProtoOp(OpKernelConstruction* context) : OpKernel(context) { |
| 462 | string descriptor_source; |
| 463 | OP_REQUIRES_OK(context, |
| 464 | context->GetAttr("descriptor_source", &descriptor_source)); |
| 465 | // We always get back a desc_pool, but we may not own it. If we own it, |
| 466 | // owned_desc_pool_ will be filled in. |
| 467 | DescriptorPool const* desc_pool; |
| 468 | OP_REQUIRES_OK(context, GetDescriptorPool(context->env(), descriptor_source, |
| 469 | &desc_pool, &owned_desc_pool_)); |
| 470 | |
| 471 | string message_type; |
| 472 | OP_REQUIRES_OK(context, context->GetAttr("message_type", &message_type)); |
| 473 | const Descriptor* message_desc = |
| 474 | desc_pool->FindMessageTypeByName(message_type); |
| 475 | OP_REQUIRES(context, message_desc != nullptr, |
| 476 | errors::InvalidArgument("No descriptor found for message type ", |
| 477 | message_type)); |
| 478 | |
| 479 | OP_REQUIRES_OK(context, context->GetAttr("field_names", &field_names_)); |
| 480 | |
| 481 | // Gather the field descriptors for the given field_names. |
| 482 | field_descs_.resize(field_names_.size()); |
| 483 | for (int i = 0; i < field_names_.size(); i++) { |
| 484 | const string& name = field_names_[i]; |
| 485 | auto field_desc = message_desc->FindFieldByName(name); |
| 486 | OP_REQUIRES(context, field_desc != nullptr, |
| 487 | errors::InvalidArgument("Unknown field: ", name, |
| 488 | " in message type ", message_type)); |
| 489 | |
| 490 | field_descs_[i] = field_desc; |
| 491 | } |
| 492 | |
| 493 | // Build a list of indices into field_descs sorted by increasing |
| 494 | // field_number. This will be used to output fields in sorted order, |
| 495 | // which is strongly encouraged when serializing protobufs. |
| 496 | sorted_field_index_.resize(field_names_.size()); |
| 497 | // Start with the fields sorted by current index. |
| 498 | for (int i = 0; i < field_names_.size(); i++) sorted_field_index_[i] = i; |
| 499 | // Then sort the field indices by their proto field number. |
| 500 | std::sort(sorted_field_index_.begin(), sorted_field_index_.end(), |
| 501 | [this](int a, int b) -> bool { |
| 502 | return field_descs_[a]->number() < field_descs_[b]->number(); |
| 503 | }); |
| 504 | } |
| 505 | |
| 506 | void Compute(OpKernelContext* ctx) override { |
| 507 | const Tensor* sizes_tensor; |
nothing calls this directly
no test coverage detected