|
@@ -685,7 +685,7 @@ GenerateClearCode(io::Printer* printer) const {
|
|
|
void RepeatedPrimitiveFieldGenerator::
|
|
|
GenerateMergingCode(io::Printer* printer) const {
|
|
|
// First, figure out the length of the array, then parse.
|
|
|
- if (descriptor_->options().packed()) {
|
|
|
+ if (descriptor_->is_packable() && descriptor_->options().packed()) {
|
|
|
printer->Print(variables_,
|
|
|
"int length = input.readRawVarint32();\n"
|
|
|
"int limit = input.pushLimit(length);\n"
|
|
@@ -736,14 +736,28 @@ GenerateMergingCode(io::Printer* printer) const {
|
|
|
|
|
|
void RepeatedPrimitiveFieldGenerator::
|
|
|
GenerateRepeatedDataSizeCode(io::Printer* printer) const {
|
|
|
- // Creates a variable dataSize and puts the serialized size in
|
|
|
- // there.
|
|
|
- if (FixedSize(descriptor_->type()) == -1) {
|
|
|
+ // Creates a variable dataSize and puts the serialized size in there.
|
|
|
+ // If the element type is a Java reference type, also generates
|
|
|
+ // dataCount which stores the number of non-null elements in the field.
|
|
|
+ if (IsReferenceType(GetJavaType(descriptor_))) {
|
|
|
+ printer->Print(variables_,
|
|
|
+ "int dataCount = 0;\n"
|
|
|
+ "int dataSize = 0;\n"
|
|
|
+ "for (int i = 0; i < this.$name$.length; i++) {\n"
|
|
|
+ " $type$ element = this.$name$[i];\n"
|
|
|
+ " if (element != null) {\n"
|
|
|
+ " dataCount++;\n"
|
|
|
+ " dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
|
|
+ " .compute$capitalized_type$SizeNoTag(element);\n"
|
|
|
+ " }\n"
|
|
|
+ "}\n");
|
|
|
+ } else if (FixedSize(descriptor_->type()) == -1) {
|
|
|
printer->Print(variables_,
|
|
|
"int dataSize = 0;\n"
|
|
|
- "for ($type$ element : this.$name$) {\n"
|
|
|
+ "for (int i = 0; i < this.$name$.length; i++) {\n"
|
|
|
+ " $type$ element = this.$name$[i];\n"
|
|
|
" dataSize += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
|
|
- " .compute$capitalized_type$SizeNoTag(element);\n"
|
|
|
+ " .compute$capitalized_type$SizeNoTag(element);\n"
|
|
|
"}\n");
|
|
|
} else {
|
|
|
printer->Print(variables_,
|
|
@@ -757,18 +771,26 @@ GenerateSerializationCode(io::Printer* printer) const {
|
|
|
"if (this.$name$ != null && this.$name$.length > 0) {\n");
|
|
|
printer->Indent();
|
|
|
|
|
|
- if (descriptor_->options().packed()) {
|
|
|
+ if (descriptor_->is_packable() && descriptor_->options().packed()) {
|
|
|
GenerateRepeatedDataSizeCode(printer);
|
|
|
printer->Print(variables_,
|
|
|
"output.writeRawVarint32($tag$);\n"
|
|
|
"output.writeRawVarint32(dataSize);\n"
|
|
|
- "for ($type$ element : this.$name$) {\n"
|
|
|
- " output.write$capitalized_type$NoTag(element);\n"
|
|
|
+ "for (int i = 0; i < this.$name$.length; i++) {\n"
|
|
|
+ " output.write$capitalized_type$NoTag(this.$name$[i]);\n"
|
|
|
+ "}\n");
|
|
|
+ } else if (IsReferenceType(GetJavaType(descriptor_))) {
|
|
|
+ printer->Print(variables_,
|
|
|
+ "for (int i = 0; i < this.$name$.length; i++) {\n"
|
|
|
+ " $type$ element = this.$name$[i];\n"
|
|
|
+ " if (element != null) {\n"
|
|
|
+ " output.write$capitalized_type$($number$, element);\n"
|
|
|
+ " }\n"
|
|
|
"}\n");
|
|
|
} else {
|
|
|
printer->Print(variables_,
|
|
|
- "for ($type$ element : this.$name$) {\n"
|
|
|
- " output.write$capitalized_type$($number$, element);\n"
|
|
|
+ "for (int i = 0; i < this.$name$.length; i++) {\n"
|
|
|
+ " output.write$capitalized_type$($number$, this.$name$[i]);\n"
|
|
|
"}\n");
|
|
|
}
|
|
|
|
|
@@ -786,14 +808,17 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
|
|
|
|
|
|
printer->Print(
|
|
|
"size += dataSize;\n");
|
|
|
- if (descriptor_->options().packed()) {
|
|
|
+ if (descriptor_->is_packable() && descriptor_->options().packed()) {
|
|
|
printer->Print(variables_,
|
|
|
"size += $tag_size$;\n"
|
|
|
"size += com.google.protobuf.nano.CodedOutputByteBufferNano\n"
|
|
|
" .computeRawVarint32Size(dataSize);\n");
|
|
|
+ } else if (IsReferenceType(GetJavaType(descriptor_))) {
|
|
|
+ printer->Print(variables_,
|
|
|
+ "size += $tag_size$ * dataCount;\n");
|
|
|
} else {
|
|
|
printer->Print(variables_,
|
|
|
- "size += $tag_size$ * this.$name$.length;\n");
|
|
|
+ "size += $tag_size$ * this.$name$.length;\n");
|
|
|
}
|
|
|
|
|
|
printer->Outdent();
|