Commit dd3d9d65 authored by Joshua Haberman's avatar Joshua Haberman Committed by GitHub

Merge pull request #1447 from seishun/defaults

JavaScript: Make implicit defaults consistent with explicit defaults
parents 77b08afa 73e0b492
...@@ -94,8 +94,10 @@ jspb.debug.dump_ = function(thing) { ...@@ -94,8 +94,10 @@ jspb.debug.dump_ = function(thing) {
var match = /^get([A-Z]\w*)/.exec(name); var match = /^get([A-Z]\w*)/.exec(name);
if (match && name != 'getExtension' && if (match && name != 'getExtension' &&
name != 'getJsPbMessageId') { name != 'getJsPbMessageId') {
var val = thing[name](); var has = 'has' + match[1];
if (val != null) { if (!thing[has] || thing[has]())
{
var val = thing[name]();
object[jspb.debug.formatFieldName_(match[1])] = jspb.debug.dump_(val); object[jspb.debug.formatFieldName_(match[1])] = jspb.debug.dump_(val);
} }
} }
......
...@@ -276,9 +276,6 @@ describe('Message test suite', function() { ...@@ -276,9 +276,6 @@ describe('Message test suite', function() {
}); });
it('testClearFields', function() { it('testClearFields', function() {
// We don't set 'proper' defaults, rather, bools, strings,
// etc, are cleared to undefined or null and take on the Javascript
// meaning for that value. Repeated fields are set to [] when cleared.
var data = ['str', true, [11], [[22], [33]], ['s1', 's2']]; var data = ['str', true, [11], [[22], [33]], ['s1', 's2']];
var foo = new proto.jspb.test.OptionalFields(data); var foo = new proto.jspb.test.OptionalFields(data);
foo.clearAString(); foo.clearAString();
...@@ -286,8 +283,8 @@ describe('Message test suite', function() { ...@@ -286,8 +283,8 @@ describe('Message test suite', function() {
foo.clearANestedMessage(); foo.clearANestedMessage();
foo.clearARepeatedMessageList(); foo.clearARepeatedMessageList();
foo.clearARepeatedStringList(); foo.clearARepeatedStringList();
assertUndefined(foo.getAString()); assertEquals('', foo.getAString());
assertUndefined(foo.getABool()); assertEquals(false, foo.getABool());
assertUndefined(foo.getANestedMessage()); assertUndefined(foo.getANestedMessage());
assertFalse(foo.hasAString()); assertFalse(foo.hasAString());
assertFalse(foo.hasABool()); assertFalse(foo.hasABool());
...@@ -310,8 +307,8 @@ describe('Message test suite', function() { ...@@ -310,8 +307,8 @@ describe('Message test suite', function() {
foo.setANestedMessage(null); foo.setANestedMessage(null);
foo.setARepeatedMessageList(null); foo.setARepeatedMessageList(null);
foo.setARepeatedStringList(null); foo.setARepeatedStringList(null);
assertNull(foo.getAString()); assertEquals('', foo.getAString());
assertNull(foo.getABool()); assertEquals(false, foo.getABool());
assertNull(foo.getANestedMessage()); assertNull(foo.getANestedMessage());
assertFalse(foo.hasAString()); assertFalse(foo.hasAString());
assertFalse(foo.hasABool()); assertFalse(foo.hasABool());
...@@ -328,8 +325,8 @@ describe('Message test suite', function() { ...@@ -328,8 +325,8 @@ describe('Message test suite', function() {
foo.setANestedMessage(undefined); foo.setANestedMessage(undefined);
foo.setARepeatedMessageList(undefined); foo.setARepeatedMessageList(undefined);
foo.setARepeatedStringList(undefined); foo.setARepeatedStringList(undefined);
assertUndefined(foo.getAString()); assertEquals('', foo.getAString());
assertUndefined(foo.getABool()); assertEquals(false, foo.getABool());
assertUndefined(foo.getANestedMessage()); assertUndefined(foo.getANestedMessage());
assertFalse(foo.hasAString()); assertFalse(foo.hasAString());
assertFalse(foo.hasABool()); assertFalse(foo.hasABool());
...@@ -346,9 +343,9 @@ describe('Message test suite', function() { ...@@ -346,9 +343,9 @@ describe('Message test suite', function() {
{1000: 'unique'}]); {1000: 'unique'}]);
var diff = /** @type {proto.jspb.test.HasExtensions} */ var diff = /** @type {proto.jspb.test.HasExtensions} */
(jspb.Message.difference(p1, p2)); (jspb.Message.difference(p1, p2));
assertUndefined(diff.getStr1()); assertEquals('', diff.getStr1());
assertEquals('what', diff.getStr2()); assertEquals('what', diff.getStr2());
assertUndefined(diff.getStr3()); assertEquals('', diff.getStr3());
assertEquals('unique', diff.extensionObject_[1000]); assertEquals('unique', diff.extensionObject_[1000]);
}); });
...@@ -806,7 +803,7 @@ describe('Message test suite', function() { ...@@ -806,7 +803,7 @@ describe('Message test suite', function() {
var message = new proto.jspb.test.TestMessageWithOneof([,, 'x']); var message = new proto.jspb.test.TestMessageWithOneof([,, 'x']);
assertEquals('x', message.getPone()); assertEquals('x', message.getPone());
assertUndefined(message.getPthree()); assertEquals('', message.getPthree());
assertEquals( assertEquals(
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
message.getPartialOneofCase()); message.getPartialOneofCase());
...@@ -815,7 +812,7 @@ describe('Message test suite', function() { ...@@ -815,7 +812,7 @@ describe('Message test suite', function() {
it('testKeepsLastWireValueSetInUnion_multipleValues', function() { it('testKeepsLastWireValueSetInUnion_multipleValues', function() {
var message = new proto.jspb.test.TestMessageWithOneof([,, 'x',, 'y']); var message = new proto.jspb.test.TestMessageWithOneof([,, 'x',, 'y']);
assertUndefined('x', message.getPone()); assertEquals('', message.getPone());
assertEquals('y', message.getPthree()); assertEquals('y', message.getPthree());
assertEquals( assertEquals(
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE, proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PTHREE,
...@@ -824,19 +821,19 @@ describe('Message test suite', function() { ...@@ -824,19 +821,19 @@ describe('Message test suite', function() {
it('testSettingOneofFieldClearsOthers', function() { it('testSettingOneofFieldClearsOthers', function() {
var message = new proto.jspb.test.TestMessageWithOneof; var message = new proto.jspb.test.TestMessageWithOneof;
assertUndefined(message.getPone()); assertEquals('', message.getPone());
assertUndefined(message.getPthree()); assertEquals('', message.getPthree());
assertFalse(message.hasPone()); assertFalse(message.hasPone());
assertFalse(message.hasPthree()); assertFalse(message.hasPthree());
message.setPone('hi'); message.setPone('hi');
assertEquals('hi', message.getPone()); assertEquals('hi', message.getPone());
assertUndefined(message.getPthree()); assertEquals('', message.getPthree());
assertTrue(message.hasPone()); assertTrue(message.hasPone());
assertFalse(message.hasPthree()); assertFalse(message.hasPthree());
message.setPthree('bye'); message.setPthree('bye');
assertUndefined(message.getPone()); assertEquals('', message.getPone());
assertEquals('bye', message.getPthree()); assertEquals('bye', message.getPthree());
assertFalse(message.hasPone()); assertFalse(message.hasPone());
assertTrue(message.hasPthree()); assertTrue(message.hasPthree());
...@@ -845,8 +842,8 @@ describe('Message test suite', function() { ...@@ -845,8 +842,8 @@ describe('Message test suite', function() {
it('testSettingOneofFieldDoesNotClearFieldsFromOtherUnions', function() { it('testSettingOneofFieldDoesNotClearFieldsFromOtherUnions', function() {
var other = new proto.jspb.test.TestMessageWithOneof; var other = new proto.jspb.test.TestMessageWithOneof;
var message = new proto.jspb.test.TestMessageWithOneof; var message = new proto.jspb.test.TestMessageWithOneof;
assertUndefined(message.getPone()); assertEquals('', message.getPone());
assertUndefined(message.getPthree()); assertEquals('', message.getPthree());
assertUndefined(message.getRone()); assertUndefined(message.getRone());
assertFalse(message.hasPone()); assertFalse(message.hasPone());
assertFalse(message.hasPthree()); assertFalse(message.hasPthree());
...@@ -854,13 +851,13 @@ describe('Message test suite', function() { ...@@ -854,13 +851,13 @@ describe('Message test suite', function() {
message.setPone('hi'); message.setPone('hi');
message.setRone(other); message.setRone(other);
assertEquals('hi', message.getPone()); assertEquals('hi', message.getPone());
assertUndefined(message.getPthree()); assertEquals('', message.getPthree());
assertEquals(other, message.getRone()); assertEquals(other, message.getRone());
assertTrue(message.hasPone()); assertTrue(message.hasPone());
assertFalse(message.hasPthree()); assertFalse(message.hasPthree());
message.setPthree('bye'); message.setPthree('bye');
assertUndefined(message.getPone()); assertEquals('', message.getPone());
assertEquals('bye', message.getPthree()); assertEquals('bye', message.getPthree());
assertEquals(other, message.getRone()); assertEquals(other, message.getRone());
assertFalse(message.hasPone()); assertFalse(message.hasPone());
...@@ -889,7 +886,7 @@ describe('Message test suite', function() { ...@@ -889,7 +886,7 @@ describe('Message test suite', function() {
it('testMessageWithDefaultOneofValues', function() { it('testMessageWithDefaultOneofValues', function() {
var message = new proto.jspb.test.TestMessageWithOneof; var message = new proto.jspb.test.TestMessageWithOneof;
assertEquals(1234, message.getAone()); assertEquals(1234, message.getAone());
assertUndefined(message.getAtwo()); assertEquals(0, message.getAtwo());
assertEquals( assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofACase proto.jspb.test.TestMessageWithOneof.DefaultOneofACase
.DEFAULT_ONEOF_A_NOT_SET, .DEFAULT_ONEOF_A_NOT_SET,
...@@ -897,7 +894,7 @@ describe('Message test suite', function() { ...@@ -897,7 +894,7 @@ describe('Message test suite', function() {
message.setAone(567); message.setAone(567);
assertEquals(567, message.getAone()); assertEquals(567, message.getAone());
assertUndefined(message.getAtwo()); assertEquals(0, message.getAtwo());
assertEquals( assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE, proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE,
message.getDefaultOneofACase()); message.getDefaultOneofACase());
...@@ -911,7 +908,7 @@ describe('Message test suite', function() { ...@@ -911,7 +908,7 @@ describe('Message test suite', function() {
message.clearAtwo(); message.clearAtwo();
assertEquals(1234, message.getAone()); assertEquals(1234, message.getAone());
assertUndefined(message.getAtwo()); assertEquals(0, message.getAtwo());
assertEquals( assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofACase proto.jspb.test.TestMessageWithOneof.DefaultOneofACase
.DEFAULT_ONEOF_A_NOT_SET, .DEFAULT_ONEOF_A_NOT_SET,
...@@ -920,7 +917,7 @@ describe('Message test suite', function() { ...@@ -920,7 +917,7 @@ describe('Message test suite', function() {
it('testMessageWithDefaultOneofValues_defaultNotOnFirstField', function() { it('testMessageWithDefaultOneofValues_defaultNotOnFirstField', function() {
var message = new proto.jspb.test.TestMessageWithOneof; var message = new proto.jspb.test.TestMessageWithOneof;
assertUndefined(message.getBone()); assertEquals(0, message.getBone());
assertEquals(1234, message.getBtwo()); assertEquals(1234, message.getBtwo());
assertFalse(message.hasBone()); assertFalse(message.hasBone());
assertFalse(message.hasBtwo()); assertFalse(message.hasBtwo());
...@@ -939,7 +936,7 @@ describe('Message test suite', function() { ...@@ -939,7 +936,7 @@ describe('Message test suite', function() {
message.getDefaultOneofBCase()); message.getDefaultOneofBCase());
message.setBtwo(3); message.setBtwo(3);
assertUndefined(message.getBone()); assertEquals(0, message.getBone());
assertFalse(message.hasBone()); assertFalse(message.hasBone());
assertTrue(message.hasBtwo()); assertTrue(message.hasBtwo());
assertEquals(3, message.getBtwo()); assertEquals(3, message.getBtwo());
...@@ -948,7 +945,7 @@ describe('Message test suite', function() { ...@@ -948,7 +945,7 @@ describe('Message test suite', function() {
message.getDefaultOneofBCase()); message.getDefaultOneofBCase());
message.clearBtwo(); message.clearBtwo();
assertUndefined(message.getBone()); assertEquals(0, message.getBone());
assertFalse(message.hasBone()); assertFalse(message.hasBone());
assertFalse(message.hasBtwo()); assertFalse(message.hasBtwo());
assertEquals(1234, message.getBtwo()); assertEquals(1234, message.getBtwo());
...@@ -962,7 +959,7 @@ describe('Message test suite', function() { ...@@ -962,7 +959,7 @@ describe('Message test suite', function() {
var message = var message =
new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567)); new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567));
assertEquals(567, message.getAone()); assertEquals(567, message.getAone());
assertUndefined(message.getAtwo()); assertEquals(0, message.getAtwo());
assertEquals( assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE, proto.jspb.test.TestMessageWithOneof.DefaultOneofACase.AONE,
message.getDefaultOneofACase()); message.getDefaultOneofACase());
...@@ -998,7 +995,7 @@ describe('Message test suite', function() { ...@@ -998,7 +995,7 @@ describe('Message test suite', function() {
message = message =
new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890)); new proto.jspb.test.TestMessageWithOneof(new Array(12).concat(890));
assertUndefined(message.getBone()); assertEquals(0, message.getBone());
assertEquals(890, message.getBtwo()); assertEquals(890, message.getBtwo());
assertEquals( assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
...@@ -1006,7 +1003,7 @@ describe('Message test suite', function() { ...@@ -1006,7 +1003,7 @@ describe('Message test suite', function() {
message = new proto.jspb.test.TestMessageWithOneof( message = new proto.jspb.test.TestMessageWithOneof(
new Array(11).concat(567, 890)); new Array(11).concat(567, 890));
assertUndefined(message.getBone()); assertEquals(0, message.getBone());
assertEquals(890, message.getBtwo()); assertEquals(890, message.getBtwo());
assertEquals( assertEquals(
proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO, proto.jspb.test.TestMessageWithOneof.DefaultOneofBCase.BTWO,
...@@ -1023,7 +1020,7 @@ describe('Message test suite', function() { ...@@ -1023,7 +1020,7 @@ describe('Message test suite', function() {
var other = new proto.jspb.test.TestMessageWithOneof; var other = new proto.jspb.test.TestMessageWithOneof;
message.setRone(other); message.setRone(other);
assertEquals(other, message.getRone()); assertEquals(other, message.getRone());
assertUndefined(message.getRtwo()); assertEquals('', message.getRtwo());
assertEquals( assertEquals(
proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RONE, proto.jspb.test.TestMessageWithOneof.RecursiveOneofCase.RONE,
message.getRecursiveOneofCase()); message.getRecursiveOneofCase());
...@@ -1041,7 +1038,7 @@ describe('Message test suite', function() { ...@@ -1041,7 +1038,7 @@ describe('Message test suite', function() {
var message = new proto.jspb.test.TestMessageWithOneof; var message = new proto.jspb.test.TestMessageWithOneof;
message.setPone('x'); message.setPone('x');
assertEquals('x', message.getPone()); assertEquals('x', message.getPone());
assertUndefined(message.getPthree()); assertEquals('', message.getPthree());
assertEquals( assertEquals(
proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE, proto.jspb.test.TestMessageWithOneof.PartialOneofCase.PONE,
message.getPartialOneofCase()); message.getPartialOneofCase());
......
...@@ -221,10 +221,10 @@ describe('proto3Test', function() { ...@@ -221,10 +221,10 @@ describe('proto3Test', function() {
it('testOneofs', function() { it('testOneofs', function() {
var msg = new proto.jspb.test.TestProto3(); var msg = new proto.jspb.test.TestProto3();
assertEquals(msg.getOneofUint32(), undefined); assertEquals(msg.getOneofUint32(), 0);
assertEquals(msg.getOneofForeignMessage(), undefined); assertEquals(msg.getOneofForeignMessage(), undefined);
assertEquals(msg.getOneofString(), undefined); assertEquals(msg.getOneofString(), '');
assertEquals(msg.getOneofBytes(), undefined); assertEquals(msg.getOneofBytes(), '');
assertFalse(msg.hasOneofUint32()); assertFalse(msg.hasOneofUint32());
assertFalse(msg.hasOneofString()); assertFalse(msg.hasOneofString());
assertFalse(msg.hasOneofBytes()); assertFalse(msg.hasOneofBytes());
...@@ -232,8 +232,8 @@ describe('proto3Test', function() { ...@@ -232,8 +232,8 @@ describe('proto3Test', function() {
msg.setOneofUint32(42); msg.setOneofUint32(42);
assertEquals(msg.getOneofUint32(), 42); assertEquals(msg.getOneofUint32(), 42);
assertEquals(msg.getOneofForeignMessage(), undefined); assertEquals(msg.getOneofForeignMessage(), undefined);
assertEquals(msg.getOneofString(), undefined); assertEquals(msg.getOneofString(), '');
assertEquals(msg.getOneofBytes(), undefined); assertEquals(msg.getOneofBytes(), '');
assertTrue(msg.hasOneofUint32()); assertTrue(msg.hasOneofUint32());
assertFalse(msg.hasOneofString()); assertFalse(msg.hasOneofString());
assertFalse(msg.hasOneofBytes()); assertFalse(msg.hasOneofBytes());
...@@ -241,27 +241,27 @@ describe('proto3Test', function() { ...@@ -241,27 +241,27 @@ describe('proto3Test', function() {
var submsg = new proto.jspb.test.ForeignMessage(); var submsg = new proto.jspb.test.ForeignMessage();
msg.setOneofForeignMessage(submsg); msg.setOneofForeignMessage(submsg);
assertEquals(msg.getOneofUint32(), undefined); assertEquals(msg.getOneofUint32(), 0);
assertEquals(msg.getOneofForeignMessage(), submsg); assertEquals(msg.getOneofForeignMessage(), submsg);
assertEquals(msg.getOneofString(), undefined); assertEquals(msg.getOneofString(), '');
assertEquals(msg.getOneofBytes(), undefined); assertEquals(msg.getOneofBytes(), '');
assertFalse(msg.hasOneofUint32()); assertFalse(msg.hasOneofUint32());
assertFalse(msg.hasOneofString()); assertFalse(msg.hasOneofString());
assertFalse(msg.hasOneofBytes()); assertFalse(msg.hasOneofBytes());
msg.setOneofString('hello'); msg.setOneofString('hello');
assertEquals(msg.getOneofUint32(), undefined); assertEquals(msg.getOneofUint32(), 0);
assertEquals(msg.getOneofForeignMessage(), undefined); assertEquals(msg.getOneofForeignMessage(), undefined);
assertEquals(msg.getOneofString(), 'hello'); assertEquals(msg.getOneofString(), 'hello');
assertEquals(msg.getOneofBytes(), undefined); assertEquals(msg.getOneofBytes(), '');
assertFalse(msg.hasOneofUint32()); assertFalse(msg.hasOneofUint32());
assertTrue(msg.hasOneofString()); assertTrue(msg.hasOneofString());
assertFalse(msg.hasOneofBytes()); assertFalse(msg.hasOneofBytes());
msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF')); msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF'));
assertEquals(msg.getOneofUint32(), undefined); assertEquals(msg.getOneofUint32(), 0);
assertEquals(msg.getOneofForeignMessage(), undefined); assertEquals(msg.getOneofForeignMessage(), undefined);
assertEquals(msg.getOneofString(), undefined); assertEquals(msg.getOneofString(), '');
assertEquals(msg.getOneofBytes_asB64(), assertEquals(msg.getOneofBytes_asB64(),
goog.crypt.base64.encodeString('\u00FF\u00FF')); goog.crypt.base64.encodeString('\u00FF\u00FF'));
assertFalse(msg.hasOneofUint32()); assertFalse(msg.hasOneofUint32());
......
...@@ -768,7 +768,6 @@ string MaybeNumberString(const FieldDescriptor* field, const string& orig) { ...@@ -768,7 +768,6 @@ string MaybeNumberString(const FieldDescriptor* field, const string& orig) {
} }
string JSFieldDefault(const FieldDescriptor* field) { string JSFieldDefault(const FieldDescriptor* field) {
assert(field->has_default_value());
switch (field->cpp_type()) { switch (field->cpp_type()) {
case FieldDescriptor::CPPTYPE_INT32: case FieldDescriptor::CPPTYPE_INT32:
return MaybeNumberString( return MaybeNumberString(
...@@ -943,7 +942,7 @@ string JSFieldTypeAnnotation(const GeneratorOptions& options, ...@@ -943,7 +942,7 @@ string JSFieldTypeAnnotation(const GeneratorOptions& options,
} }
if (field->is_optional() && is_primitive && if (field->is_optional() && is_primitive &&
(!field->has_default_value() || force_optional) && !force_present) { force_optional && !force_present) {
jstype += "?"; jstype += "?";
} else if (field->is_required() && !is_primitive && !force_optional) { } else if (field->is_required() && !is_primitive && !force_optional) {
jstype = "!" + jstype; jstype = "!" + jstype;
...@@ -1258,6 +1257,10 @@ string GetPivot(const Descriptor* desc) { ...@@ -1258,6 +1257,10 @@ string GetPivot(const Descriptor* desc) {
// Returns true for fields that represent "null" as distinct from the default // Returns true for fields that represent "null" as distinct from the default
// value. See http://go/proto3#heading=h.kozewqqcqhuz for more information. // value. See http://go/proto3#heading=h.kozewqqcqhuz for more information.
bool HasFieldPresence(const FieldDescriptor* field) { bool HasFieldPresence(const FieldDescriptor* field) {
if (field->is_repeated()) {
return false;
}
return return
(field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) || (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) ||
(field->containing_oneof() != NULL) || (field->containing_oneof() != NULL) ||
...@@ -2387,7 +2390,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, ...@@ -2387,7 +2390,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"index", JSFieldIndex(field), "index", JSFieldIndex(field),
"default", Proto3PrimitiveFieldDefault(field)); "default", Proto3PrimitiveFieldDefault(field));
} else { } else {
if (field->has_default_value()) { if (!field->is_repeated()) {
printer->Print("!this.has$name$() ? $defaultValue$ : ", printer->Print("!this.has$name$() ? $defaultValue$ : ",
"name", JSGetterName(options, field), "name", JSGetterName(options, field),
"defaultValue", JSFieldDefault(field)); "defaultValue", JSFieldDefault(field));
...@@ -2398,10 +2401,6 @@ void Generator::GenerateClassField(const GeneratorOptions& options, ...@@ -2398,10 +2401,6 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
printer->Print("jspb.Message.getRepeatedFloatingPointField(" printer->Print("jspb.Message.getRepeatedFloatingPointField("
"this, $index$)", "this, $index$)",
"index", JSFieldIndex(field)); "index", JSFieldIndex(field));
} else if (field->is_optional() && !field->has_default_value()) {
printer->Print("jspb.Message.getOptionalFloatingPointField("
"this, $index$)",
"index", JSFieldIndex(field));
} else { } else {
// Convert "NaN" to NaN. // Convert "NaN" to NaN.
printer->Print("+jspb.Message.getField(this, $index$)", printer->Print("+jspb.Message.getField(this, $index$)",
...@@ -2477,7 +2476,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options, ...@@ -2477,7 +2476,7 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"returndoc", JSReturnDoc(options, field)); "returndoc", JSReturnDoc(options, field));
} }
if (HasFieldPresence(field)) { if (HasFieldPresence(field) || field->is_repeated()) {
printer->Print( printer->Print(
"$class$.prototype.clear$name$ = function() {\n" "$class$.prototype.clear$name$ = function() {\n"
" jspb.Message.set$oneoftag$Field(this, $index$$oneofgroup$, ", " jspb.Message.set$oneoftag$Field(this, $index$$oneofgroup$, ",
...@@ -2494,22 +2493,24 @@ void Generator::GenerateClassField(const GeneratorOptions& options, ...@@ -2494,22 +2493,24 @@ void Generator::GenerateClassField(const GeneratorOptions& options,
"\n", "\n",
"clearedvalue", (field->is_repeated() ? "[]" : "undefined"), "clearedvalue", (field->is_repeated() ? "[]" : "undefined"),
"returnvalue", JSReturnClause(field)); "returnvalue", JSReturnClause(field));
printer->Print(
"/**\n"
" * Returns whether this field is set.\n"
" * @return{!boolean}\n"
" */\n"
"$class$.prototype.has$name$ = function() {\n"
" return jspb.Message.getField(this, $index$) != null;\n"
"};\n"
"\n"
"\n",
"class", GetPath(options, field->containing_type()),
"name", JSGetterName(options, field),
"index", JSFieldIndex(field));
} }
} }
if (HasFieldPresence(field)) {
printer->Print(
"/**\n"
" * Returns whether this field is set.\n"
" * @return{!boolean}\n"
" */\n"
"$class$.prototype.has$name$ = function() {\n"
" return jspb.Message.getField(this, $index$) != null;\n"
"};\n"
"\n"
"\n",
"class", GetPath(options, field->containing_type()),
"name", JSGetterName(options, field),
"index", JSFieldIndex(field));
}
} }
void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options, void Generator::GenerateClassExtensionFieldInfo(const GeneratorOptions& options,
...@@ -2756,11 +2757,18 @@ void Generator::GenerateClassSerializeBinaryField( ...@@ -2756,11 +2757,18 @@ void Generator::GenerateClassSerializeBinaryField(
const GeneratorOptions& options, const GeneratorOptions& options,
io::Printer* printer, io::Printer* printer,
const FieldDescriptor* field) const { const FieldDescriptor* field) const {
printer->Print( if (HasFieldPresence(field) &&
" f = this.get$name$($nolazy$);\n", field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
"name", JSGetterName(options, field, BYTES_U8), printer->Print(
// No lazy creation for maps containers -- fastpath the empty case. " f = jspb.Message.getField(this, $index$);\n",
"nolazy", (field->is_map()) ? "true" : ""); "index", JSFieldIndex(field));
} else {
printer->Print(
" f = this.get$name$($nolazy$);\n",
"name", JSGetterName(options, field, BYTES_U8),
// No lazy creation for maps containers -- fastpath the empty case.
"nolazy", (field->is_map()) ? "true" : "");
}
// Print an `if (condition)` statement that evaluates to true if the field // Print an `if (condition)` statement that evaluates to true if the field
......
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