Commit 77b08afa authored by Joshua Haberman's avatar Joshua Haberman Committed by GitHub

Merge pull request #1802 from haberman/jsmapbin

JavaScript: segregate references to binary functionality
parents 24ac9c0c e0e73771
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
goog.require('goog.object'); goog.require('goog.object');
goog.require('jspb.BinaryReader'); goog.require('jspb.BinaryReader');
goog.require('jspb.BinaryWriter'); goog.require('jspb.BinaryWriter');
goog.require('jspb.ExtensionFieldBinaryInfo');
goog.require('jspb.ExtensionFieldInfo'); goog.require('jspb.ExtensionFieldInfo');
goog.require('jspb.Message'); goog.require('jspb.Message');
...@@ -15,6 +16,7 @@ exports.Message = jspb.Message; ...@@ -15,6 +16,7 @@ exports.Message = jspb.Message;
exports.BinaryReader = jspb.BinaryReader; exports.BinaryReader = jspb.BinaryReader;
exports.BinaryWriter = jspb.BinaryWriter; exports.BinaryWriter = jspb.BinaryWriter;
exports.ExtensionFieldInfo = jspb.ExtensionFieldInfo; exports.ExtensionFieldInfo = jspb.ExtensionFieldInfo;
exports.ExtensionFieldBinaryInfo = jspb.ExtensionFieldBinaryInfo;
// These are used by generated code but should not be used directly by clients. // These are used by generated code but should not be used directly by clients.
exports.exportSymbol = goog.exportSymbol; exports.exportSymbol = goog.exportSymbol;
......
...@@ -44,65 +44,23 @@ goog.forwardDeclare('jspb.BinaryWriter'); ...@@ -44,65 +44,23 @@ goog.forwardDeclare('jspb.BinaryWriter');
* on ES6 itself. * on ES6 itself.
* *
* This constructor should only be called from generated message code. It is not * This constructor should only be called from generated message code. It is not
* intended for general use by library consumers. The callback function * intended for general use by library consumers.
* arguments are references to methods in `BinaryReader` and `BinaryWriter`, as
* well as constructors and reader/writer methods in submessage types if
* appropriate, that are used for binary serialization and parsing.
* *
* @template K, V * @template K, V
* *
* @param {!Array<!Array<!Object>>} arr * @param {!Array<!Array<!Object>>} arr
* *
* @param {function(this:jspb.BinaryWriter,number,K)=} opt_keyWriterFn
* The method on BinaryWriter that writes type K to the stream.
*
* @param {function(this:jspb.BinaryReader):K=} opt_keyReaderFn
* The method on BinaryReader that reads type K from the stream.
*
* @param {function(this:jspb.BinaryWriter,number,V)|
* function(this:jspb.BinaryReader,V,?)=} opt_valueWriterFn
* The method on BinaryWriter that writes type V to the stream. May be
* writeMessage, in which case the second callback arg form is used.
*
* @param {function(this:jspb.BinaryReader):V|
* function(this:jspb.BinaryReader,V,
* function(V,!jspb.BinaryReader))=} opt_valueReaderFn
* The method on BinaryReader that reads type V from the stream. May be
* readMessage, in which case the second callback arg form is used.
*
* @param {?function(new:V)|function(new:V,?)=} opt_valueCtor * @param {?function(new:V)|function(new:V,?)=} opt_valueCtor
* The constructor for type V, if type V is a message type. * The constructor for type V, if type V is a message type.
* *
* @param {?function(V,!jspb.BinaryWriter)=} opt_valueWriterCallback
* The BinaryWriter serialization callback for type V, if V is a message
* type.
*
* @param {?function(V,!jspb.BinaryReader)=} opt_valueReaderCallback
* The BinaryReader parsing callback for type V, if V is a message type.
*
* @constructor * @constructor
* @struct * @struct
*/ */
jspb.Map = function( jspb.Map = function(arr, opt_valueCtor) {
arr, opt_keyWriterFn, opt_keyReaderFn, opt_valueWriterFn, opt_valueReaderFn,
opt_valueCtor, opt_valueWriterCallback, opt_valueReaderCallback) {
/** @const @private */ /** @const @private */
this.arr_ = arr; this.arr_ = arr;
/** @const @private */ /** @const @private */
this.keyWriterFn_ = opt_keyWriterFn;
/** @const @private */
this.keyReaderFn_ = opt_keyReaderFn;
/** @const @private */
this.valueWriterFn_ = opt_valueWriterFn;
/** @const @private */
this.valueReaderFn_ = opt_valueReaderFn;
/** @const @private */
this.valueCtor_ = opt_valueCtor; this.valueCtor_ = opt_valueCtor;
/** @const @private */
this.valueWriterCallback_ = opt_valueWriterCallback;
/** @const @private */
this.valueReaderCallback_ = opt_valueReaderCallback;
/** @type {!Object<string, !jspb.Map.Entry_<K,V>>} @private */ /** @type {!Object<string, !jspb.Map.Entry_<K,V>>} @private */
this.map_ = {}; this.map_ = {};
...@@ -385,19 +343,29 @@ jspb.Map.prototype.has = function(key) { ...@@ -385,19 +343,29 @@ jspb.Map.prototype.has = function(key) {
* number. * number.
* @param {number} fieldNumber * @param {number} fieldNumber
* @param {!jspb.BinaryWriter} writer * @param {!jspb.BinaryWriter} writer
* @param {function(this:jspb.BinaryWriter,number,K)=} keyWriterFn
* The method on BinaryWriter that writes type K to the stream.
* @param {function(this:jspb.BinaryWriter,number,V)|
* function(this:jspb.BinaryReader,V,?)=} valueWriterFn
* The method on BinaryWriter that writes type V to the stream. May be
* writeMessage, in which case the second callback arg form is used.
* @param {?function(V,!jspb.BinaryWriter)=} opt_valueWriterCallback
* The BinaryWriter serialization callback for type V, if V is a message
* type.
*/ */
jspb.Map.prototype.serializeBinary = function(fieldNumber, writer) { jspb.Map.prototype.serializeBinary = function(
fieldNumber, writer, keyWriterFn, valueWriterFn, opt_valueWriterCallback) {
var strKeys = this.stringKeys_(); var strKeys = this.stringKeys_();
strKeys.sort(); strKeys.sort();
for (var i = 0; i < strKeys.length; i++) { for (var i = 0; i < strKeys.length; i++) {
var entry = this.map_[strKeys[i]]; var entry = this.map_[strKeys[i]];
writer.beginSubMessage(fieldNumber); writer.beginSubMessage(fieldNumber);
this.keyWriterFn_.call(writer, 1, entry.key); keyWriterFn.call(writer, 1, entry.key);
if (this.valueCtor_) { if (this.valueCtor_) {
this.valueWriterFn_.call(writer, 2, this.wrapEntry_(entry), valueWriterFn.call(writer, 2, this.wrapEntry_(entry),
this.valueWriterCallback_); opt_valueWriterCallback);
} else { } else {
this.valueWriterFn_.call(writer, 2, entry.value); valueWriterFn_.call(writer, 2, entry.value);
} }
writer.endSubMessage(); writer.endSubMessage();
} }
...@@ -410,8 +378,21 @@ jspb.Map.prototype.serializeBinary = function(fieldNumber, writer) { ...@@ -410,8 +378,21 @@ jspb.Map.prototype.serializeBinary = function(fieldNumber, writer) {
* when a key/value pair submessage is encountered. * when a key/value pair submessage is encountered.
* @param {!jspb.Map} map * @param {!jspb.Map} map
* @param {!jspb.BinaryReader} reader * @param {!jspb.BinaryReader} reader
* @param {function(this:jspb.BinaryReader):K=} keyReaderFn
* The method on BinaryReader that reads type K from the stream.
*
* @param {function(this:jspb.BinaryReader):V|
* function(this:jspb.BinaryReader,V,
* function(V,!jspb.BinaryReader))=} valueReaderFn
* The method on BinaryReader that reads type V from the stream. May be
* readMessage, in which case the second callback arg form is used.
*
* @param {?function(V,!jspb.BinaryReader)=} opt_valueReaderCallback
* The BinaryReader parsing callback for type V, if V is a message type.
*
*/ */
jspb.Map.deserializeBinary = function(map, reader) { jspb.Map.deserializeBinary = function(map, reader, keyReaderFn, valueReaderFn,
opt_valueReaderCallback) {
var key = undefined; var key = undefined;
var value = undefined; var value = undefined;
...@@ -422,14 +403,14 @@ jspb.Map.deserializeBinary = function(map, reader) { ...@@ -422,14 +403,14 @@ jspb.Map.deserializeBinary = function(map, reader) {
var field = reader.getFieldNumber(); var field = reader.getFieldNumber();
if (field == 1) { if (field == 1) {
// Key. // Key.
key = map.keyReaderFn_.call(reader); key = keyReaderFn.call(reader);
} else if (field == 2) { } else if (field == 2) {
// Value. // Value.
if (map.valueCtor_) { if (map.valueCtor_) {
value = new map.valueCtor_(); value = new map.valueCtor_();
map.valueReaderFn_.call(reader, value, map.valueReaderCallback_); valueReaderFn.call(reader, value, opt_valueReaderCallback);
} else { } else {
value = map.valueReaderFn_.call(reader); value = valueReaderFn.call(reader);
} }
} }
} }
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
* @author mwr@google.com (Mark Rawling) * @author mwr@google.com (Mark Rawling)
*/ */
goog.provide('jspb.ExtensionFieldBinaryInfo');
goog.provide('jspb.ExtensionFieldInfo'); goog.provide('jspb.ExtensionFieldInfo');
goog.provide('jspb.Message'); goog.provide('jspb.Message');
...@@ -84,19 +85,12 @@ goog.forwardDeclare('xid.String'); ...@@ -84,19 +85,12 @@ goog.forwardDeclare('xid.String');
* @param {?function(new: jspb.Message, Array=)} ctor * @param {?function(new: jspb.Message, Array=)} ctor
* @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn * @param {?function((boolean|undefined),!jspb.Message):!Object} toObjectFn
* @param {number} isRepeated * @param {number} isRepeated
* @param {?function(number,?)=} opt_binaryReaderFn
* @param {?function(number,?)|function(number,?,?,?,?,?)=} opt_binaryWriterFn
* @param {?function(?,?)=} opt_binaryMessageSerializeFn
* @param {?function(?,?)=} opt_binaryMessageDeserializeFn
* @param {?boolean=} opt_isPacked
* @constructor * @constructor
* @struct * @struct
* @template T * @template T
*/ */
jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn, jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn,
isRepeated, opt_binaryReaderFn, opt_binaryWriterFn, isRepeated) {
opt_binaryMessageSerializeFn, opt_binaryMessageDeserializeFn,
opt_isPacked) {
/** @const */ /** @const */
this.fieldIndex = fieldNumber; this.fieldIndex = fieldNumber;
/** @const */ /** @const */
...@@ -106,20 +100,37 @@ jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn, ...@@ -106,20 +100,37 @@ jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn,
/** @const */ /** @const */
this.toObjectFn = toObjectFn; this.toObjectFn = toObjectFn;
/** @const */ /** @const */
this.binaryReaderFn = opt_binaryReaderFn; this.isRepeated = isRepeated;
};
/**
* Stores binary-related information for a single extension field.
* @param {!jspb.ExtensionFieldInfo<T>} fieldInfo
* @param {?function(number,?)=} binaryReaderFn
* @param {?function(number,?)|function(number,?,?,?,?,?)=} binaryWriterFn
* @param {?function(?,?)=} opt_binaryMessageSerializeFn
* @param {?function(?,?)=} opt_binaryMessageDeserializeFn
* @param {?boolean=} opt_isPacked
* @constructor
* @struct
* @template T
*/
jspb.ExtensionFieldBinaryInfo = function(fieldInfo, binaryReaderFn, binaryWriterFn,
binaryMessageSerializeFn, binaryMessageDeserializeFn, isPacked) {
/** @const */
this.fieldInfo = fieldInfo;
/** @const */ /** @const */
this.binaryWriterFn = opt_binaryWriterFn; this.binaryReaderFn = binaryReaderFn;
/** @const */ /** @const */
this.binaryMessageSerializeFn = opt_binaryMessageSerializeFn; this.binaryWriterFn = binaryWriterFn;
/** @const */ /** @const */
this.binaryMessageDeserializeFn = opt_binaryMessageDeserializeFn; this.binaryMessageSerializeFn = binaryMessageSerializeFn;
/** @const */ /** @const */
this.isRepeated = isRepeated; this.binaryMessageDeserializeFn = binaryMessageDeserializeFn;
/** @const */ /** @const */
this.isPacked = opt_isPacked; this.isPacked = isPacked;
}; };
/** /**
* @return {boolean} Does this field represent a sub Message? * @return {boolean} Does this field represent a sub Message?
*/ */
...@@ -491,11 +502,13 @@ jspb.Message.toObjectExtension = function(proto, obj, extensions, ...@@ -491,11 +502,13 @@ jspb.Message.toObjectExtension = function(proto, obj, extensions,
jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions, jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
getExtensionFn) { getExtensionFn) {
for (var fieldNumber in extensions) { for (var fieldNumber in extensions) {
var fieldInfo = extensions[fieldNumber]; var binaryFieldInfo = extensions[fieldNumber];
var fieldInfo = binaryFieldInfo.fieldInfo;
// The old codegen doesn't add the extra fields to ExtensionFieldInfo, so we // The old codegen doesn't add the extra fields to ExtensionFieldInfo, so we
// need to gracefully error-out here rather than produce a null dereference // need to gracefully error-out here rather than produce a null dereference
// below. // below.
if (!fieldInfo.binaryWriterFn) { if (!binaryFieldInfo.binaryWriterFn) {
throw new Error('Message extension present that was generated ' + throw new Error('Message extension present that was generated ' +
'without binary serialization support'); 'without binary serialization support');
} }
...@@ -508,16 +521,17 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions, ...@@ -508,16 +521,17 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
// message may require binary support, so we can *only* catch this error // message may require binary support, so we can *only* catch this error
// here, at runtime (and this decoupled codegen is the whole point of // here, at runtime (and this decoupled codegen is the whole point of
// extensions!). // extensions!).
if (fieldInfo.binaryMessageSerializeFn) { if (binaryFieldInfo.binaryMessageSerializeFn) {
fieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex, binaryFieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex,
value, fieldInfo.binaryMessageSerializeFn); value, binaryFieldInfo.binaryMessageSerializeFn);
} else { } else {
throw new Error('Message extension present holding submessage ' + throw new Error('Message extension present holding submessage ' +
'without binary support enabled, and message is ' + 'without binary support enabled, and message is ' +
'being serialized to binary format'); 'being serialized to binary format');
} }
} else { } else {
fieldInfo.binaryWriterFn.call(writer, fieldInfo.fieldIndex, value); binaryFieldInfo.binaryWriterFn.call(
writer, fieldInfo.fieldIndex, value);
} }
} }
} }
...@@ -535,12 +549,13 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions, ...@@ -535,12 +549,13 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
*/ */
jspb.Message.readBinaryExtension = function(msg, reader, extensions, jspb.Message.readBinaryExtension = function(msg, reader, extensions,
getExtensionFn, setExtensionFn) { getExtensionFn, setExtensionFn) {
var fieldInfo = extensions[reader.getFieldNumber()]; var binaryFieldInfo = extensions[reader.getFieldNumber()];
if (!fieldInfo) { var fieldInfo = binaryFieldInfo.fieldInfo;
if (!binaryFieldInfo) {
reader.skipField(); reader.skipField();
return; return;
} }
if (!fieldInfo.binaryReaderFn) { if (!binaryFieldInfo.binaryReaderFn) {
throw new Error('Deserializing extension whose generated code does not ' + throw new Error('Deserializing extension whose generated code does not ' +
'support binary format'); 'support binary format');
} }
...@@ -548,14 +563,14 @@ jspb.Message.readBinaryExtension = function(msg, reader, extensions, ...@@ -548,14 +563,14 @@ jspb.Message.readBinaryExtension = function(msg, reader, extensions,
var value; var value;
if (fieldInfo.isMessageType()) { if (fieldInfo.isMessageType()) {
value = new fieldInfo.ctor(); value = new fieldInfo.ctor();
fieldInfo.binaryReaderFn.call( binaryFieldInfo.binaryReaderFn.call(
reader, value, fieldInfo.binaryMessageDeserializeFn); reader, value, binaryFieldInfo.binaryMessageDeserializeFn);
} else { } else {
// All other types. // All other types.
value = fieldInfo.binaryReaderFn.call(reader); value = binaryFieldInfo.binaryReaderFn.call(reader);
} }
if (fieldInfo.isRepeated && !fieldInfo.isPacked) { if (fieldInfo.isRepeated && !binaryFieldInfo.isPacked) {
var currentList = getExtensionFn.call(msg, fieldInfo); var currentList = getExtensionFn.call(msg, fieldInfo);
if (!currentList) { if (!currentList) {
setExtensionFn.call(msg, fieldInfo, [value]); setExtensionFn.call(msg, fieldInfo, [value]);
...@@ -747,29 +762,16 @@ jspb.Message.getFieldProto3 = function(msg, fieldNumber, defaultValue) { ...@@ -747,29 +762,16 @@ jspb.Message.getFieldProto3 = function(msg, fieldNumber, defaultValue) {
* of serialization/parsing callbacks (which are required by the map at * of serialization/parsing callbacks (which are required by the map at
* construction time, and the map may be constructed here). * construction time, and the map may be constructed here).
* *
* The below callbacks are used to allow the map to serialize and parse its
* binary wire format data. Their purposes are described in more detail in
* `jspb.Map`'s constructor documentation.
*
* @template K, V * @template K, V
* @param {!jspb.Message} msg * @param {!jspb.Message} msg
* @param {number} fieldNumber * @param {number} fieldNumber
* @param {boolean|undefined} noLazyCreate * @param {boolean|undefined} noLazyCreate
* @param {?=} opt_valueCtor * @param {?=} opt_valueCtor
* @param {function(number,K)=} opt_keyWriterFn
* @param {function():K=} opt_keyReaderFn
* @param {function(number,V)|function(number,V,?)|
* function(number,V,?,?,?,?)=} opt_valueWriterFn
* @param {function():V|
* function(V,function(?,?))=} opt_valueReaderFn
* @param {function(?,?)|function(?,?,?,?,?)=} opt_valueWriterCallback
* @param {function(?,?)=} opt_valueReaderCallback
* @return {!jspb.Map<K, V>|undefined} * @return {!jspb.Map<K, V>|undefined}
* @protected * @protected
*/ */
jspb.Message.getMapField = function(msg, fieldNumber, noLazyCreate, jspb.Message.getMapField = function(msg, fieldNumber, noLazyCreate,
opt_valueCtor, opt_keyWriterFn, opt_keyReaderFn, opt_valueWriterFn, opt_valueCtor) {
opt_valueReaderFn, opt_valueWriterCallback, opt_valueReaderCallback) {
if (!msg.wrappers_) { if (!msg.wrappers_) {
msg.wrappers_ = {}; msg.wrappers_ = {};
} }
...@@ -787,10 +789,7 @@ jspb.Message.getMapField = function(msg, fieldNumber, noLazyCreate, ...@@ -787,10 +789,7 @@ jspb.Message.getMapField = function(msg, fieldNumber, noLazyCreate,
} }
return msg.wrappers_[fieldNumber] = return msg.wrappers_[fieldNumber] =
new jspb.Map( new jspb.Map(
/** @type {!Array<!Array<!Object>>} */ (arr), /** @type {!Array<!Array<!Object>>} */ (arr), opt_valueCtor);
opt_keyWriterFn, opt_keyReaderFn, opt_valueWriterFn,
opt_valueReaderFn, opt_valueCtor, opt_valueWriterCallback,
opt_valueReaderCallback);
} }
}; };
......
...@@ -2252,25 +2252,6 @@ void Generator::GenerateClassField(const GeneratorOptions& options, ...@@ -2252,25 +2252,6 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
" null"); " null");
} }
if (options.binary) {
printer->Print(",\n"
" $keyWriterFn$,\n"
" $keyReaderFn$,\n"
" $valueWriterFn$,\n"
" $valueReaderFn$",
"keyWriterFn", JSBinaryWriterMethodName(options, key_field),
"keyReaderFn", JSBinaryReaderMethodName(options, key_field),
"valueWriterFn", JSBinaryWriterMethodName(options, value_field),
"valueReaderFn", JSBinaryReaderMethodName(options, value_field));
if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
printer->Print(",\n"
" $messageType$.serializeBinaryToWriter,\n"
" $messageType$.deserializeBinaryFromReader",
"messageType", GetPath(options, value_field->message_type()));
}
}
printer->Print( printer->Print(
"));\n"); "));\n");
...@@ -2555,6 +2536,29 @@ void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options, ...@@ -2555,6 +2536,29 @@ void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
"$class$.extensions = {};\n" "$class$.extensions = {};\n"
"\n", "\n",
"class", GetPath(options, desc)); "class", GetPath(options, desc));
if (options.binary) {
printer->Print(
"\n"
"/**\n"
" * The extensions registered with this message class. This is a "
"map of\n"
" * extension field number to fieldInfo object.\n"
" *\n"
" * For example:\n"
" * { 123: {fieldIndex: 123, fieldName: {my_field_name: 0}, "
"ctor: proto.example.MyMessage} }\n"
" *\n"
" * fieldName contains the JsCompiler renamed field name property "
"so that it\n"
" * works in OPTIMIZED mode.\n"
" *\n"
" * @type {!Object.<number, jspb.ExtensionFieldInfo>}\n"
" */\n"
"$class$.extensionsBinary = {};\n"
"\n",
"class", GetPath(options, desc));
}
} }
} }
...@@ -2602,7 +2606,7 @@ void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options, ...@@ -2602,7 +2606,7 @@ void Generator::GenerateClassDeserializeBinary(const GeneratorOptions& options,
" default:\n"); " default:\n");
if (IsExtendable(desc)) { if (IsExtendable(desc)) {
printer->Print( printer->Print(
" jspb.Message.readBinaryExtension(msg, reader, $extobj$,\n" " jspb.Message.readBinaryExtension(msg, reader, $extobj$Binary,\n"
" $class$.prototype.getExtension,\n" " $class$.prototype.getExtension,\n"
" $class$.prototype.setExtension);\n" " $class$.prototype.setExtension);\n"
" break;\n", " break;\n",
...@@ -2632,10 +2636,25 @@ void Generator::GenerateClassDeserializeBinaryField( ...@@ -2632,10 +2636,25 @@ void Generator::GenerateClassDeserializeBinaryField(
"num", SimpleItoa(field->number())); "num", SimpleItoa(field->number()));
if (field->is_map()) { if (field->is_map()) {
const FieldDescriptor* key_field = MapFieldKey(field);
const FieldDescriptor* value_field = MapFieldValue(field);
printer->Print( printer->Print(
" var value = msg.get$name$();\n" " var value = msg.get$name$();\n"
" reader.readMessage(value, jspb.Map.deserializeBinary);\n", " reader.readMessage(value, function(message, reader) {\n",
"name", JSGetterName(options, field)); "name", JSGetterName(options, field));
printer->Print(" jspb.Map.deserializeBinary(message, reader, "
"$keyReaderFn$, $valueReaderFn$",
"keyReaderFn", JSBinaryReaderMethodName(options, key_field),
"valueReaderFn", JSBinaryReaderMethodName(options, value_field));
if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
printer->Print(", $messageType$.deserializeBinaryFromReader",
"messageType", GetPath(options, value_field->message_type()));
}
printer->Print(");\n");
printer->Print(" });\n");
} else { } else {
if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) { if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
printer->Print( printer->Print(
...@@ -2721,8 +2740,8 @@ void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options, ...@@ -2721,8 +2740,8 @@ void Generator::GenerateClassSerializeBinary(const GeneratorOptions& options,
if (IsExtendable(desc)) { if (IsExtendable(desc)) {
printer->Print( printer->Print(
" jspb.Message.serializeBinaryExtensions(this, writer, $extobj$,\n" " jspb.Message.serializeBinaryExtensions(this, writer,\n"
" $class$.prototype.getExtension);\n", " $extobj$Binary, $class$.prototype.getExtension);\n",
"extobj", JSExtensionsObjectName(options, desc->file(), desc), "extobj", JSExtensionsObjectName(options, desc->file(), desc),
"class", GetPath(options, desc)); "class", GetPath(options, desc));
} }
...@@ -2794,9 +2813,21 @@ void Generator::GenerateClassSerializeBinaryField( ...@@ -2794,9 +2813,21 @@ void Generator::GenerateClassSerializeBinaryField(
// Write the field on the wire. // Write the field on the wire.
if (field->is_map()) { if (field->is_map()) {
const FieldDescriptor* key_field = MapFieldKey(field);
const FieldDescriptor* value_field = MapFieldValue(field);
printer->Print( printer->Print(
" f.serializeBinary($index$, writer);\n", " f.serializeBinary($index$, writer, "
"index", SimpleItoa(field->number())); "$keyWriterFn$, $valueWriterFn$",
"index", SimpleItoa(field->number()),
"keyWriterFn", JSBinaryWriterMethodName(options, key_field),
"valueWriterFn", JSBinaryWriterMethodName(options, value_field));
if (value_field->type() == FieldDescriptor::TYPE_MESSAGE) {
printer->Print(", $messageType$.serializeBinaryToWriter",
"messageType", GetPath(options, value_field->message_type()));
}
printer->Print(");\n");
} else { } else {
printer->Print( printer->Print(
" writer.write$method$(\n" " writer.write$method$(\n"
...@@ -2878,7 +2909,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options, ...@@ -2878,7 +2909,7 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
" /** @type {?function((boolean|undefined),!jspb.Message=): " " /** @type {?function((boolean|undefined),!jspb.Message=): "
"!Object} */ (\n" "!Object} */ (\n"
" $toObject$),\n" " $toObject$),\n"
" $repeated$", " $repeated$);\n",
"index", SimpleItoa(field->number()), "index", SimpleItoa(field->number()),
"name", JSObjectFieldName(options, field), "name", JSObjectFieldName(options, field),
"ctor", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ? "ctor", (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE ?
...@@ -2890,12 +2921,18 @@ void Generator::GenerateExtension(const GeneratorOptions& options, ...@@ -2890,12 +2921,18 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
if (options.binary) { if (options.binary) {
printer->Print( printer->Print(
",\n" "\n"
"$extendName$Binary[$index$] = new jspb.ExtensionFieldBinaryInfo(\n"
" $class$.$name$,\n"
" $binaryReaderFn$,\n" " $binaryReaderFn$,\n"
" $binaryWriterFn$,\n" " $binaryWriterFn$,\n"
" $binaryMessageSerializeFn$,\n" " $binaryMessageSerializeFn$,\n"
" $binaryMessageDeserializeFn$,\n" " $binaryMessageDeserializeFn$,\n",
" $isPacked$);\n", "extendName", JSExtensionsObjectName(options, field->file(),
field->containing_type()),
"index", SimpleItoa(field->number()),
"class", extension_scope,
"name", JSObjectFieldName(options, field),
"binaryReaderFn", JSBinaryReaderMethodName(options, field), "binaryReaderFn", JSBinaryReaderMethodName(options, field),
"binaryWriterFn", JSBinaryWriterMethodName(options, field), "binaryWriterFn", JSBinaryWriterMethodName(options, field),
"binaryMessageSerializeFn", "binaryMessageSerializeFn",
...@@ -2905,10 +2942,11 @@ void Generator::GenerateExtension(const GeneratorOptions& options, ...@@ -2905,10 +2942,11 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
"binaryMessageDeserializeFn", "binaryMessageDeserializeFn",
(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ? (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ?
(SubmessageTypeRef(options, field) + (SubmessageTypeRef(options, field) +
".deserializeBinaryFromReader") : "null", ".deserializeBinaryFromReader") : "null");
printer->Print(
" $isPacked$);\n",
"isPacked", (field->is_packed() ? "true" : "false")); "isPacked", (field->is_packed() ? "true" : "false"));
} else {
printer->Print(");\n");
} }
printer->Print( printer->Print(
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment