13d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// Copyright 2010 Google Inc. 23d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// 33d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// Licensed under the Apache License, Version 2.0 (the "License"); you 43d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// may not use this file except in compliance with the License. 53d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// You may obtain a copy of the License at 63d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// 73d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// http://www.apache.org/licenses/LICENSE-2.0 83d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// 93d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// Unless required by applicable law or agreed to in writing, software 103d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// distributed under the License is distributed on an "AS IS" BASIS, 113d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 123d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// implied. See the License for the specific language governing 133d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville// permissions and limitations under the License. 143d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 153d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include "protobuf_v8.h" 163d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 173d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include <map> 183d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include <string> 193d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include <iostream> 203d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include <sstream> 213d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 223d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include <google/protobuf/dynamic_message.h> 233d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include <google/protobuf/descriptor.h> 243d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include <google/protobuf/descriptor.pb.h> 253d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 263d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include "logging.h" 279b92c6b4651e608125a48f8f06a7a840042e090dWink Saville#include "util.h" 289b92c6b4651e608125a48f8f06a7a840042e090dWink Saville 293d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include "node_buffer.h" 303d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include "node_object_wrap.h" 313d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 323d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#include "node_util.h" 333d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 343d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville//#define PROTOBUF_V8_DEBUG 353d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#ifdef PROTOBUF_V8_DEBUG 363d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 376464068a31ff890d42d3da9cdf580d07c9c630d8Steve Block#define DBG(...) ALOGD(__VA_ARGS__) 383d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 393d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#else 403d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 413d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#define DBG(...) 423d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 433d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#endif 443d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 453d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing google::protobuf::Descriptor; 463d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing google::protobuf::DescriptorPool; 473d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing google::protobuf::DynamicMessageFactory; 483d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing google::protobuf::FieldDescriptor; 493d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing google::protobuf::FileDescriptorSet; 503d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing google::protobuf::Message; 513d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing google::protobuf::Reflection; 523d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 533d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville//using ObjectWrap; 543d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville//using Buffer; 553d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 563d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing std::map; 573d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing std::string; 583d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 593d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Array; 603d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::AccessorInfo; 613d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Arguments; 623d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Boolean; 633d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Context; 643d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::External; 653d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Function; 663d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::FunctionTemplate; 673d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Integer; 683d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Handle; 693d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::HandleScope; 703d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::InvocationCallback; 713d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Local; 723d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::NamedPropertyGetter; 733d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Number; 743d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Object; 753d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::ObjectTemplate; 763d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Persistent; 773d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Script; 783d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::String; 793d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::Value; 803d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleusing v8::V8; 813d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 823d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savillenamespace protobuf_v8 { 833d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 843d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville template <typename T> 853d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville static T* UnwrapThis(const Arguments& args) { 863d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return ObjectWrap::Unwrap<T>(args.This()); 873d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 883d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 893d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville template <typename T> 903d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville static T* UnwrapThis(const AccessorInfo& args) { 913d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return ObjectWrap::Unwrap<T>(args.This()); 923d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 933d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 943d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Persistent<FunctionTemplate> SchemaTemplate; 953d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Persistent<FunctionTemplate> TypeTemplate; 963d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Persistent<FunctionTemplate> ParseTemplate; 973d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Persistent<FunctionTemplate> SerializeTemplate; 983d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 993d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville class Schema : public ObjectWrap { 1003d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville public: 1013d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Schema(Handle<Object> self, const DescriptorPool* pool) 1023d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville : pool_(pool) { 1033d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Schema::Schema E:"); 1043d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville factory_.SetDelegateToGeneratedFactory(true); 1053d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville self->SetInternalField(1, Array::New()); 1063d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Wrap(self); 1073d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Schema::Schema X:"); 1083d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 1093d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1103d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville virtual ~Schema() { 1113d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("~Schema::Schema E:"); 1123d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (pool_ != DescriptorPool::generated_pool()) 1133d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville delete pool_; 1143d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("~Schema::Schema X:"); 1153d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 1163d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1173d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville class Type : public ObjectWrap { 1183d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville public: 1193d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Schema* schema_; 1203d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const Descriptor* descriptor_; 1213d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1223d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Message* NewMessage() const { 1233d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::NewMessage() EX:"); 1243d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return schema_->NewMessage(descriptor_); 1253d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 1263d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1273d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Function> Constructor() const { 1283d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::Constrocutor() EX:"); 1293d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return handle_->GetInternalField(2).As<Function>(); 1303d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 1313d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1323d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Local<Object> NewObject(Handle<Value> properties) const { 1333d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::NewObjext(properties) EX:"); 1343d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return Constructor()->NewInstance(1, &properties); 1353d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 1363d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1373d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Type(Schema* schema, const Descriptor* descriptor, Handle<Object> self) 1383d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville : schema_(schema), descriptor_(descriptor) { 1393d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::Type(schema, descriptor, self) E:"); 1403d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // Generate functions for bulk conversion between a JS object 1413d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // and an array in descriptor order: 1423d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // from = function(arr) { this.f0 = arr[0]; this.f1 = arr[1]; ... } 1433d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // to = function() { return [ this.f0, this.f1, ... ] } 1443d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // This is faster than repeatedly calling Get/Set on a v8::Object. 1453d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville std::ostringstream from, to; 1463d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville from << "(function(arr) { if(arr) {"; 1473d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville to << "(function() { return [ "; 1483d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1493d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville for (int i = 0; i < descriptor->field_count(); i++) { 1503d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville from << 1513d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville "var x = arr[" << i << "]; " 1523d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville "if(x !== undefined) this['" << 1533d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville descriptor->field(i)->camelcase_name() << 1543d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville "'] = x; "; 1553d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1563d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (i > 0) to << ", "; 1573d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville to << "this['" << descriptor->field(i)->camelcase_name() << "']"; 1583d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("field name=%s", descriptor->field(i)->name().c_str()); 1593d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 1603d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1613d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville from << " }})"; 1623d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville to << " ]; })"; 1633d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1643d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // managed type->schema link 1653d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville self->SetInternalField(1, schema_->handle_); 1663d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1673d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Function> constructor = 1683d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Script::Compile(String::New(from.str().c_str()))->Run().As<Function>(); 1693d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville constructor->SetHiddenValue(String::New("type"), self); 1703d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1713d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Function> bind = 1723d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Script::Compile(String::New( 1733d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville "(function(self) {" 1743d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville " var f = this;" 1753d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville " return function(arg) {" 1763d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville " return f.call(self, arg);" 1773d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville " };" 1783d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville "})"))->Run().As<Function>(); 1793d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Value> arg = self; 1803d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville constructor->Set(String::New("parse"), bind->Call(ParseTemplate->GetFunction(), 1, &arg)); 1813d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville constructor->Set(String::New("serialize"), bind->Call(SerializeTemplate->GetFunction(), 1, &arg)); 1823d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville self->SetInternalField(2, constructor); 1833d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville self->SetInternalField(3, Script::Compile(String::New(to.str().c_str()))->Run()); 1843d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1853d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Wrap(self); 1863d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::Type(schema, descriptor, self) X:"); 1873d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 1883d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1893d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#define GET(TYPE) \ 1903d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville (index >= 0 ? \ 1913d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville reflection->GetRepeated##TYPE(instance, field, index) : \ 1923d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville reflection->Get##TYPE(instance, field)) 1933d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 1943d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville static Handle<Value> ToJs(const Message& instance, 1953d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const Reflection* reflection, 1963d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const FieldDescriptor* field, 1973d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const Type* message_type, 1983d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville int index) { 1993d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs(instance, refelction, field, message_type) E:"); 2003d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville switch (field->cpp_type()) { 2013d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_MESSAGE: 2023d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs CPPTYPE_MESSAGE"); 2033d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return message_type->ToJs(GET(Message)); 2043d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_STRING: { 2053d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs CPPTYPE_STRING"); 2063d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const string& value = GET(String); 2073d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return String::New(value.data(), value.length()); 2083d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 2093d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_INT32: 2103d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs CPPTYPE_INT32"); 2113d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return Integer::New(GET(Int32)); 2123d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_UINT32: 2133d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs CPPTYPE_UINT32"); 2143d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return Integer::NewFromUnsigned(GET(UInt32)); 2153d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_INT64: 2163d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs CPPTYPE_INT64"); 2173d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return Number::New(GET(Int64)); 2183d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_UINT64: 2193d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs CPPTYPE_UINT64"); 2203d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return Number::New(GET(UInt64)); 2213d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_FLOAT: 2223d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs CPPTYPE_FLOAT"); 2233d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return Number::New(GET(Float)); 2243d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_DOUBLE: 2253d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs CPPTYPE_DOUBLE"); 2263d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return Number::New(GET(Double)); 2273d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_BOOL: 2283d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs CPPTYPE_BOOL"); 2293d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return Boolean::New(GET(Bool)); 2303d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_ENUM: 2313d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs CPPTYPE_ENUM"); 2323d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return String::New(GET(Enum)->name().c_str()); 2333d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 2343d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2353d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return Handle<Value>(); // NOTREACHED 2363d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 2373d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#undef GET 2383d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2393d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Object> ToJs(const Message& instance) const { 2403d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs(Message) E:"); 2413d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const Reflection* reflection = instance.GetReflection(); 2423d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const Descriptor* descriptor = instance.GetDescriptor(); 2433d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2443d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Array> properties = Array::New(descriptor->field_count()); 2453d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville for (int i = 0; i < descriptor->field_count(); i++) { 2463d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville HandleScope scope; 2473d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2483d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const FieldDescriptor* field = descriptor->field(i); 2493d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville bool repeated = field->is_repeated(); 2503d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (repeated && !reflection->FieldSize(instance, field)) { 2513d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Ignore repeated field with no size in reflection data"); 2523d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville continue; 2533d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 2543d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (!repeated && !reflection->HasField(instance, field)) { 2553d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Ignore field with no field in relfection data"); 2563d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville continue; 2573d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 2583d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2593d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const Type* child_type = 2603d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ? 2613d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville schema_->GetType(field->message_type()) : NULL; 2623d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2633d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Value> value; 2643d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (field->is_repeated()) { 2653d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville int size = reflection->FieldSize(instance, field); 2663d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Array> array = Array::New(size); 2673d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville for (int j = 0; j < size; j++) { 2683d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville array->Set(j, ToJs(instance, reflection, field, child_type, j)); 2693d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 2703d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville value = array; 2713d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } else { 2723d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville value = ToJs(instance, reflection, field, child_type, -1); 2733d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 2743d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2753d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs: set property[%d]=%s", i, ToCString(value)); 2763d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville properties->Set(i, value); 2773d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 2783d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2793d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToJs(Message) X:"); 2803d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return NewObject(properties); 2813d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 2823d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2833d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville static Handle<Value> Parse(const Arguments& args) { 2843d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::Parse(args) E:"); 2853d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Type* type = UnwrapThis<Type>(args); 2863d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Buffer* buf = ObjectWrap::Unwrap<Buffer>(args[0]->ToObject()); 2873d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2883d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Message* message = type->NewMessage(); 2893d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville message->ParseFromArray(buf->data(), buf->length()); 2903d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Object> result = type->ToJs(*message); 2913d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville delete message; 2923d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2933d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::Parse(args) X:"); 2943d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return result; 2953d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 2963d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 2973d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#define SET(TYPE, EXPR) \ 2983d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (repeated) reflection->Add##TYPE(instance, field, EXPR); \ 2993d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville else reflection->Set##TYPE(instance, field, EXPR) 3003d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 3019b92c6b4651e608125a48f8f06a7a840042e090dWink Saville static bool ToProto(Message* instance, 3023d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const FieldDescriptor* field, 3033d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Value> value, 3043d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const Type* type, 3053d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville bool repeated) { 3063d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto(instance, field, value, type, repeated) E:"); 3079b92c6b4651e608125a48f8f06a7a840042e090dWink Saville bool ok = true; 3083d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville HandleScope scope; 3093d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 3103d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto field->name()=%s", field->name().c_str()); 3113d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const Reflection* reflection = instance->GetReflection(); 3123d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville switch (field->cpp_type()) { 3133d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_MESSAGE: 3143d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto CPPTYPE_MESSAGE"); 3159b92c6b4651e608125a48f8f06a7a840042e090dWink Saville ok = type->ToProto(repeated ? 3169b92c6b4651e608125a48f8f06a7a840042e090dWink Saville reflection->AddMessage(instance, field) : 3179b92c6b4651e608125a48f8f06a7a840042e090dWink Saville reflection->MutableMessage(instance, field), 3189b92c6b4651e608125a48f8f06a7a840042e090dWink Saville value.As<Object>()); 3193d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville break; 3203d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_STRING: { 3213d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto CPPTYPE_STRING"); 3223d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville String::AsciiValue ascii(value); 3233d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SET(String, string(*ascii, ascii.length())); 3243d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville break; 3253d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 3263d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_INT32: 3273d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto CPPTYPE_INT32"); 3283d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SET(Int32, value->NumberValue()); 3293d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville break; 3303d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_UINT32: 3313d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto CPPTYPE_UINT32"); 3323d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SET(UInt32, value->NumberValue()); 3333d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville break; 3343d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_INT64: 3353d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto CPPTYPE_INT64"); 3363d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SET(Int64, value->NumberValue()); 3373d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville break; 3383d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_UINT64: 3393d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto CPPTYPE_UINT64"); 3403d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SET(UInt64, value->NumberValue()); 3413d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville break; 3423d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_FLOAT: 3433d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto CPPTYPE_FLOAT"); 3443d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SET(Float, value->NumberValue()); 3453d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville break; 3463d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_DOUBLE: 3473d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto CPPTYPE_DOUBLE"); 3483d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SET(Double, value->NumberValue()); 3493d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville break; 3503d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_BOOL: 3513d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto CPPTYPE_BOOL"); 3523d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SET(Bool, value->BooleanValue()); 3533d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville break; 3543d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville case FieldDescriptor::CPPTYPE_ENUM: 3553d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Type::ToProto CPPTYPE_ENUM"); 3569b92c6b4651e608125a48f8f06a7a840042e090dWink Saville 3579b92c6b4651e608125a48f8f06a7a840042e090dWink Saville // Don't use SET as vd can be NULL 3589b92c6b4651e608125a48f8f06a7a840042e090dWink Saville char error_buff[256]; 3599b92c6b4651e608125a48f8f06a7a840042e090dWink Saville const google::protobuf::EnumValueDescriptor* vd; 3609b92c6b4651e608125a48f8f06a7a840042e090dWink Saville int i32_value = 0; 3619b92c6b4651e608125a48f8f06a7a840042e090dWink Saville const char *str_value = NULL; 3629b92c6b4651e608125a48f8f06a7a840042e090dWink Saville const google::protobuf::EnumDescriptor* ed = field->enum_type(); 3639b92c6b4651e608125a48f8f06a7a840042e090dWink Saville 3649b92c6b4651e608125a48f8f06a7a840042e090dWink Saville if (value->IsNumber()) { 3659b92c6b4651e608125a48f8f06a7a840042e090dWink Saville i32_value = value->Int32Value(); 3669b92c6b4651e608125a48f8f06a7a840042e090dWink Saville vd = ed->FindValueByNumber(i32_value); 3679b92c6b4651e608125a48f8f06a7a840042e090dWink Saville if (vd == NULL) { 3689b92c6b4651e608125a48f8f06a7a840042e090dWink Saville snprintf(error_buff, sizeof(error_buff), 3699b92c6b4651e608125a48f8f06a7a840042e090dWink Saville "Type::ToProto Bad enum value, %d is not a member of enum %s", 3709b92c6b4651e608125a48f8f06a7a840042e090dWink Saville i32_value, ed->full_name().c_str()); 3719b92c6b4651e608125a48f8f06a7a840042e090dWink Saville } 3729b92c6b4651e608125a48f8f06a7a840042e090dWink Saville } else { 3739b92c6b4651e608125a48f8f06a7a840042e090dWink Saville str_value = ToCString(value); 3749b92c6b4651e608125a48f8f06a7a840042e090dWink Saville // TODO: Why can str_value be corrupted sometimes? 3756464068a31ff890d42d3da9cdf580d07c9c630d8Steve Block ALOGD("str_value=%s", str_value); 3769b92c6b4651e608125a48f8f06a7a840042e090dWink Saville vd = ed->FindValueByName(str_value); 3779b92c6b4651e608125a48f8f06a7a840042e090dWink Saville if (vd == NULL) { 3789b92c6b4651e608125a48f8f06a7a840042e090dWink Saville snprintf(error_buff, sizeof(error_buff), 3799b92c6b4651e608125a48f8f06a7a840042e090dWink Saville "Type::ToProto Bad enum value, %s is not a member of enum %s", 3809b92c6b4651e608125a48f8f06a7a840042e090dWink Saville str_value, ed->full_name().c_str()); 3819b92c6b4651e608125a48f8f06a7a840042e090dWink Saville } 3829b92c6b4651e608125a48f8f06a7a840042e090dWink Saville } 3839b92c6b4651e608125a48f8f06a7a840042e090dWink Saville if (vd != NULL) { 3849b92c6b4651e608125a48f8f06a7a840042e090dWink Saville if (repeated) { 3859b92c6b4651e608125a48f8f06a7a840042e090dWink Saville reflection->AddEnum(instance, field, vd); 3869b92c6b4651e608125a48f8f06a7a840042e090dWink Saville } else { 3879b92c6b4651e608125a48f8f06a7a840042e090dWink Saville reflection->SetEnum(instance, field, vd); 3889b92c6b4651e608125a48f8f06a7a840042e090dWink Saville } 3899b92c6b4651e608125a48f8f06a7a840042e090dWink Saville } else { 3909b92c6b4651e608125a48f8f06a7a840042e090dWink Saville v8::ThrowException(String::New(error_buff)); 3919b92c6b4651e608125a48f8f06a7a840042e090dWink Saville ok = false; 3929b92c6b4651e608125a48f8f06a7a840042e090dWink Saville } 3933d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville break; 3943d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 3959b92c6b4651e608125a48f8f06a7a840042e090dWink Saville DBG("Type::ToProto(instance, field, value, type, repeated) X: ok=%d", ok); 3969b92c6b4651e608125a48f8f06a7a840042e090dWink Saville return ok; 3973d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 3983d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville#undef SET 3993d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4009b92c6b4651e608125a48f8f06a7a840042e090dWink Saville bool ToProto(Message* instance, Handle<Object> src) const { 4013d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("ToProto(Message *, Handle<Object>) E:"); 4029b92c6b4651e608125a48f8f06a7a840042e090dWink Saville 4033d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Function> to_array = handle_->GetInternalField(3).As<Function>(); 4043d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Array> properties = to_array->Call(src, 0, NULL).As<Array>(); 4059b92c6b4651e608125a48f8f06a7a840042e090dWink Saville bool ok = true; 4069b92c6b4651e608125a48f8f06a7a840042e090dWink Saville for (int i = 0; ok && (i < descriptor_->field_count()); i++) { 4073d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Value> value = properties->Get(i); 4083d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (value->IsUndefined()) continue; 4093d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4103d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const FieldDescriptor* field = descriptor_->field(i); 4113d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const Type* child_type = 4123d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ? 4133d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville schema_->GetType(field->message_type()) : NULL; 4143d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (field->is_repeated()) { 4153d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if(!value->IsArray()) { 4169b92c6b4651e608125a48f8f06a7a840042e090dWink Saville ok = ToProto(instance, field, value, child_type, true); 4173d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } else { 4183d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Array> array = value.As<Array>(); 4193d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville int length = array->Length(); 4209b92c6b4651e608125a48f8f06a7a840042e090dWink Saville for (int j = 0; ok && (j < length); j++) { 4219b92c6b4651e608125a48f8f06a7a840042e090dWink Saville ok = ToProto(instance, field, array->Get(j), child_type, true); 4223d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4233d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4243d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } else { 4259b92c6b4651e608125a48f8f06a7a840042e090dWink Saville ok = ToProto(instance, field, value, child_type, false); 4263d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4273d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4289b92c6b4651e608125a48f8f06a7a840042e090dWink Saville DBG("ToProto(Message *, Handle<Object>) X: ok=%d", ok); 4299b92c6b4651e608125a48f8f06a7a840042e090dWink Saville return ok; 4303d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4313d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4323d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville static Handle<Value> Serialize(const Arguments& args) { 4339b92c6b4651e608125a48f8f06a7a840042e090dWink Saville Handle<Value> result; 4343d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Serialize(Arguments&) E:"); 4353d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (!args[0]->IsObject()) { 4363d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Serialize(Arguments&) X: not an object"); 4373d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return v8::ThrowException(args[0]); 4383d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4393d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4403d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Type* type = UnwrapThis<Type>(args); 4413d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Message* message = type->NewMessage(); 4429b92c6b4651e608125a48f8f06a7a840042e090dWink Saville if (type->ToProto(message, args[0].As<Object>())) { 4439b92c6b4651e608125a48f8f06a7a840042e090dWink Saville int length = message->ByteSize(); 4449b92c6b4651e608125a48f8f06a7a840042e090dWink Saville Buffer* buffer = Buffer::New(length); 4459b92c6b4651e608125a48f8f06a7a840042e090dWink Saville message->SerializeWithCachedSizesToArray((google::protobuf::uint8*)buffer->data()); 4469b92c6b4651e608125a48f8f06a7a840042e090dWink Saville delete message; 4479b92c6b4651e608125a48f8f06a7a840042e090dWink Saville 4489b92c6b4651e608125a48f8f06a7a840042e090dWink Saville result = buffer->handle_; 4499b92c6b4651e608125a48f8f06a7a840042e090dWink Saville } else { 4509b92c6b4651e608125a48f8f06a7a840042e090dWink Saville result = v8::Undefined(); 4519b92c6b4651e608125a48f8f06a7a840042e090dWink Saville } 4523d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Serialize(Arguments&) X"); 4539b92c6b4651e608125a48f8f06a7a840042e090dWink Saville return result; 4543d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4553d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4563d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville static Handle<Value> ToString(const Arguments& args) { 4573d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return String::New(UnwrapThis<Type>(args)->descriptor_->full_name().c_str()); 4583d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4593d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville }; 4603d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4613d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Message* NewMessage(const Descriptor* descriptor) { 4623d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Schema::NewMessage(descriptor) EX:"); 4633d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return factory_.GetPrototype(descriptor)->New(); 4643d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4653d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4663d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Type* GetType(const Descriptor* descriptor) { 4673d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Schema::GetType(descriptor) E:"); 4683d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Type* result = types_[descriptor]; 4693d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (result) return result; 4703d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4713d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville result = types_[descriptor] = 4723d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville new Type(this, descriptor, TypeTemplate->GetFunction()->NewInstance()); 4733d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4743d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // managed schema->[type] link 4753d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Array> types = handle_->GetInternalField(1).As<Array>(); 4763d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville types->Set(types->Length(), result->handle_); 4773d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Schema::GetType(descriptor) X:"); 4783d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return result; 4793d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4803d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4813d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const DescriptorPool* pool_; 4823d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville map<const Descriptor*, Type*> types_; 4833d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DynamicMessageFactory factory_; 4843d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4853d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville static Handle<Value> GetType(const Local<String> name, 4863d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const AccessorInfo& args) { 4873d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Schema::GetType(name, args) E:"); 4883d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Schema* schema = UnwrapThis<Schema>(args); 4893d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville const Descriptor* descriptor = 4903d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville schema->pool_->FindMessageTypeByName(*String::AsciiValue(name)); 4913d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4923d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Schema::GetType(name, args) X:"); 4933d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return descriptor ? 4943d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville schema->GetType(descriptor)->Constructor() : 4953d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Handle<Function>(); 4963d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 4973d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 4983d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville static Handle<Value> NewSchema(const Arguments& args) { 4993d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Schema::NewSchema E: args.Length()=%d", args.Length()); 5003d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (!args.Length()) { 5013d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return (new Schema(args.This(), 5023d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DescriptorPool::generated_pool()))->handle_; 5033d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 5043d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5053d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville Buffer* buf = ObjectWrap::Unwrap<Buffer>(args[0]->ToObject()); 5063d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5073d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville FileDescriptorSet descriptors; 5083d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville if (!descriptors.ParseFromArray(buf->data(), buf->length())) { 5093d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Schema::NewSchema X: bad descriptor"); 5103d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return v8::ThrowException(String::New("Malformed descriptor")); 5113d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 5123d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5133d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DescriptorPool* pool = new DescriptorPool; 5143d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville for (int i = 0; i < descriptors.file_size(); i++) { 5153d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville pool->BuildFile(descriptors.file(i)); 5163d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 5173d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5183d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Schema::NewSchema X"); 5193d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville return (new Schema(args.This(), pool))->handle_; 5203d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 5213d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville }; 5223d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5233d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville void Init() { 5243d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Init E:"); 5253d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville HandleScope handle_scope; 5263d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5273d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville TypeTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New()); 5283d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville TypeTemplate->SetClassName(String::New("Type")); 5293d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // native self 5303d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // owning schema (so GC can manage our lifecyle) 5313d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // constructor 5323d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // toArray 5333d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville TypeTemplate->InstanceTemplate()->SetInternalFieldCount(4); 5343d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5353d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SchemaTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(Schema::NewSchema)); 5363d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SchemaTemplate->SetClassName(String::New("Schema")); 5373d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // native self 5383d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville // array of types (so GC can manage our lifecyle) 5393d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SchemaTemplate->InstanceTemplate()->SetInternalFieldCount(2); 5403d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SchemaTemplate->InstanceTemplate()->SetNamedPropertyHandler(Schema::GetType); 5413d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5423d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville ParseTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(Schema::Type::Parse)); 5433d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville SerializeTemplate = Persistent<FunctionTemplate>::New(FunctionTemplate::New(Schema::Type::Serialize)); 5443d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5453d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("Init X:"); 5463d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville } 5473d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5483d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville} // namespace protobuf_v8 5493d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville 5503d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Savilleextern "C" void SchemaObjectTemplateInit(Handle<ObjectTemplate> target) { 5513d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville DBG("SchemaObjectTemplateInit(target) EX:"); 5523d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville target->Set(String::New("Schema"), protobuf_v8::SchemaTemplate); 5533d6d348df5378b3f3f79ebbfad21d86ae1c9f239Wink Saville} 554