1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// http://code.google.com/p/protobuf/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31// Author: kenton@google.com (Kenton Varda) 32// Based on original Protocol Buffers design by 33// Sanjay Ghemawat, Jeff Dean, and others. 34 35#include <map> 36#include <string> 37 38#include <google/protobuf/compiler/javamicro/javamicro_primitive_field.h> 39#include <google/protobuf/stubs/common.h> 40#include <google/protobuf/compiler/javamicro/javamicro_helpers.h> 41#include <google/protobuf/io/printer.h> 42#include <google/protobuf/wire_format.h> 43#include <google/protobuf/stubs/strutil.h> 44 45namespace google { 46namespace protobuf { 47namespace compiler { 48namespace javamicro { 49 50using internal::WireFormat; 51using internal::WireFormatLite; 52 53namespace { 54 55const char* PrimitiveTypeName(JavaType type) { 56 switch (type) { 57 case JAVATYPE_INT : return "int"; 58 case JAVATYPE_LONG : return "long"; 59 case JAVATYPE_FLOAT : return "float"; 60 case JAVATYPE_DOUBLE : return "double"; 61 case JAVATYPE_BOOLEAN: return "boolean"; 62 case JAVATYPE_STRING : return "java.lang.String"; 63 case JAVATYPE_BYTES : return "com.google.protobuf.micro.ByteStringMicro"; 64 case JAVATYPE_ENUM : return NULL; 65 case JAVATYPE_MESSAGE: return NULL; 66 67 // No default because we want the compiler to complain if any new 68 // JavaTypes are added. 69 } 70 71 GOOGLE_LOG(FATAL) << "Can't get here."; 72 return NULL; 73} 74 75bool IsReferenceType(JavaType type) { 76 switch (type) { 77 case JAVATYPE_INT : return false; 78 case JAVATYPE_LONG : return false; 79 case JAVATYPE_FLOAT : return false; 80 case JAVATYPE_DOUBLE : return false; 81 case JAVATYPE_BOOLEAN: return false; 82 case JAVATYPE_STRING : return true; 83 case JAVATYPE_BYTES : return true; 84 case JAVATYPE_ENUM : return false; 85 case JAVATYPE_MESSAGE: return true; 86 87 // No default because we want the compiler to complain if any new 88 // JavaTypes are added. 89 } 90 91 GOOGLE_LOG(FATAL) << "Can't get here."; 92 return false; 93} 94 95const char* GetCapitalizedType(const FieldDescriptor* field) { 96 switch (field->type()) { 97 case FieldDescriptor::TYPE_INT32 : return "Int32" ; 98 case FieldDescriptor::TYPE_UINT32 : return "UInt32" ; 99 case FieldDescriptor::TYPE_SINT32 : return "SInt32" ; 100 case FieldDescriptor::TYPE_FIXED32 : return "Fixed32" ; 101 case FieldDescriptor::TYPE_SFIXED32: return "SFixed32"; 102 case FieldDescriptor::TYPE_INT64 : return "Int64" ; 103 case FieldDescriptor::TYPE_UINT64 : return "UInt64" ; 104 case FieldDescriptor::TYPE_SINT64 : return "SInt64" ; 105 case FieldDescriptor::TYPE_FIXED64 : return "Fixed64" ; 106 case FieldDescriptor::TYPE_SFIXED64: return "SFixed64"; 107 case FieldDescriptor::TYPE_FLOAT : return "Float" ; 108 case FieldDescriptor::TYPE_DOUBLE : return "Double" ; 109 case FieldDescriptor::TYPE_BOOL : return "Bool" ; 110 case FieldDescriptor::TYPE_STRING : return "String" ; 111 case FieldDescriptor::TYPE_BYTES : return "Bytes" ; 112 case FieldDescriptor::TYPE_ENUM : return "Enum" ; 113 case FieldDescriptor::TYPE_GROUP : return "Group" ; 114 case FieldDescriptor::TYPE_MESSAGE : return "Message" ; 115 116 // No default because we want the compiler to complain if any new 117 // types are added. 118 } 119 120 GOOGLE_LOG(FATAL) << "Can't get here."; 121 return NULL; 122} 123 124// For encodings with fixed sizes, returns that size in bytes. Otherwise 125// returns -1. 126int FixedSize(FieldDescriptor::Type type) { 127 switch (type) { 128 case FieldDescriptor::TYPE_INT32 : return -1; 129 case FieldDescriptor::TYPE_INT64 : return -1; 130 case FieldDescriptor::TYPE_UINT32 : return -1; 131 case FieldDescriptor::TYPE_UINT64 : return -1; 132 case FieldDescriptor::TYPE_SINT32 : return -1; 133 case FieldDescriptor::TYPE_SINT64 : return -1; 134 case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size; 135 case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size; 136 case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size; 137 case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size; 138 case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize; 139 case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize; 140 141 case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize; 142 case FieldDescriptor::TYPE_ENUM : return -1; 143 144 case FieldDescriptor::TYPE_STRING : return -1; 145 case FieldDescriptor::TYPE_BYTES : return -1; 146 case FieldDescriptor::TYPE_GROUP : return -1; 147 case FieldDescriptor::TYPE_MESSAGE : return -1; 148 149 // No default because we want the compiler to complain if any new 150 // types are added. 151 } 152 GOOGLE_LOG(FATAL) << "Can't get here."; 153 return -1; 154} 155 156// Return true if the type is a that has variable length 157// for instance String's. 158bool IsVariableLenType(JavaType type) { 159 switch (type) { 160 case JAVATYPE_INT : return false; 161 case JAVATYPE_LONG : return false; 162 case JAVATYPE_FLOAT : return false; 163 case JAVATYPE_DOUBLE : return false; 164 case JAVATYPE_BOOLEAN: return false; 165 case JAVATYPE_STRING : return true; 166 case JAVATYPE_BYTES : return true; 167 case JAVATYPE_ENUM : return false; 168 case JAVATYPE_MESSAGE: return true; 169 170 // No default because we want the compiler to complain if any new 171 // JavaTypes are added. 172 } 173 174 GOOGLE_LOG(FATAL) << "Can't get here."; 175 return false; 176} 177 178bool IsFastStringHandling(const FieldDescriptor* descriptor, 179 const Params params) { 180 return ((params.optimization() == JAVAMICRO_OPT_SPEED) 181 && (GetJavaType(descriptor) == JAVATYPE_STRING)); 182} 183 184void SetPrimitiveVariables(const FieldDescriptor* descriptor, const Params params, 185 map<string, string>* variables) { 186 (*variables)["name"] = 187 UnderscoresToCamelCase(descriptor); 188 (*variables)["capitalized_name"] = 189 UnderscoresToCapitalizedCamelCase(descriptor); 190 (*variables)["number"] = SimpleItoa(descriptor->number()); 191 (*variables)["type"] = PrimitiveTypeName(GetJavaType(descriptor)); 192 (*variables)["default"] = DefaultValue(params, descriptor); 193 (*variables)["boxed_type"] = BoxedPrimitiveTypeName(GetJavaType(descriptor)); 194 (*variables)["capitalized_type"] = GetCapitalizedType(descriptor); 195 (*variables)["tag"] = SimpleItoa(WireFormat::MakeTag(descriptor)); 196 (*variables)["tag_size"] = SimpleItoa( 197 WireFormat::TagSize(descriptor->number(), descriptor->type())); 198 if (IsReferenceType(GetJavaType(descriptor))) { 199 (*variables)["null_check"] = 200 " if (value == null) {\n" 201 " throw new NullPointerException();\n" 202 " }\n"; 203 } else { 204 (*variables)["null_check"] = ""; 205 } 206 int fixed_size = FixedSize(descriptor->type()); 207 if (fixed_size != -1) { 208 (*variables)["fixed_size"] = SimpleItoa(fixed_size); 209 } 210 (*variables)["message_name"] = descriptor->containing_type()->name(); 211} 212} // namespace 213 214// =================================================================== 215 216PrimitiveFieldGenerator:: 217PrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params) 218 : FieldGenerator(params), descriptor_(descriptor) { 219 SetPrimitiveVariables(descriptor, params, &variables_); 220} 221 222PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {} 223 224void PrimitiveFieldGenerator:: 225GenerateMembers(io::Printer* printer) const { 226 printer->Print(variables_, 227 "private boolean has$capitalized_name$;\n" 228 "private $type$ $name$_ = $default$;\n" 229 "public $type$ get$capitalized_name$() { return $name$_; }\n" 230 "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"); 231 if (IsFastStringHandling(descriptor_, params_)) { 232 printer->Print(variables_, 233 "private byte [] $name$Utf8_ = null;\n" 234 "public $message_name$ set$capitalized_name$($type$ value) {\n" 235 " has$capitalized_name$ = true;\n" 236 " $name$_ = value;\n" 237 " $name$Utf8_ = null;\n" 238 " return this;\n" 239 "}\n" 240 "public $message_name$ clear$capitalized_name$() {\n" 241 " has$capitalized_name$ = false;\n" 242 " $name$_ = $default$;\n" 243 " $name$Utf8_ = null;\n" 244 " return this;\n" 245 "}\n"); 246 } else { 247 if (IsVariableLenType(GetJavaType(descriptor_))) { 248 printer->Print(variables_, 249 "public $message_name$ set$capitalized_name$($type$ value) {\n" 250 " has$capitalized_name$ = true;\n" 251 " $name$_ = value;\n" 252 " return this;\n" 253 "}\n" 254 "public $message_name$ clear$capitalized_name$() {\n" 255 " has$capitalized_name$ = false;\n" 256 " $name$_ = $default$;\n" 257 " return this;\n" 258 "}\n"); 259 } else { 260 printer->Print(variables_, 261 "public $message_name$ set$capitalized_name$($type$ value) {\n" 262 " has$capitalized_name$ = true;\n" 263 " $name$_ = value;\n" 264 " return this;\n" 265 "}\n" 266 "public $message_name$ clear$capitalized_name$() {\n" 267 " has$capitalized_name$ = false;\n" 268 " $name$_ = $default$;\n" 269 " return this;\n" 270 "}\n"); 271 } 272 } 273} 274 275void PrimitiveFieldGenerator:: 276GenerateMergingCode(io::Printer* printer) const { 277 printer->Print(variables_, 278 "if (other.has$capitalized_name$()) {\n" 279 " set$capitalized_name$(other.get$capitalized_name$());\n" 280 "}\n"); 281} 282 283void PrimitiveFieldGenerator:: 284GenerateParsingCode(io::Printer* printer) const { 285 printer->Print(variables_, 286 "set$capitalized_name$(input.read$capitalized_type$());\n"); 287} 288 289void PrimitiveFieldGenerator:: 290GenerateSerializationCode(io::Printer* printer) const { 291 if (IsFastStringHandling(descriptor_, params_)) { 292 printer->Print(variables_, 293 "if (has$capitalized_name$()) {\n" 294 " output.writeByteArray($number$, $name$Utf8_);\n" 295 "}\n"); 296 } else { 297 printer->Print(variables_, 298 "if (has$capitalized_name$()) {\n" 299 " output.write$capitalized_type$($number$, get$capitalized_name$());\n" 300 "}\n"); 301 } 302} 303 304void PrimitiveFieldGenerator:: 305GenerateSerializedSizeCode(io::Printer* printer) const { 306 if (IsFastStringHandling(descriptor_, params_)) { 307 printer->Print(variables_, 308 "if (has$capitalized_name$()) {\n" 309 " try {\n" 310 " $name$Utf8_ = $name$_.getBytes(\"UTF-8\");\n" 311 " } catch (java.io.UnsupportedEncodingException e) {\n" 312 " throw new RuntimeException(\"UTF-8 not supported.\");\n" 313 " }\n" 314 " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" 315 " .computeByteArraySize($number$, $name$Utf8_);\n" 316 "}\n"); 317 } else { 318 printer->Print(variables_, 319 "if (has$capitalized_name$()) {\n" 320 " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" 321 " .compute$capitalized_type$Size($number$, get$capitalized_name$());\n" 322 "}\n"); 323 } 324} 325 326string PrimitiveFieldGenerator::GetBoxedType() const { 327 return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); 328} 329 330// =================================================================== 331 332RepeatedPrimitiveFieldGenerator:: 333RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, const Params& params) 334 : FieldGenerator(params), descriptor_(descriptor) { 335 SetPrimitiveVariables(descriptor, params, &variables_); 336 if (descriptor_->options().packed()) { 337 GOOGLE_LOG(FATAL) << "MicroRuntime does not support packed"; 338 } 339} 340 341RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {} 342 343void RepeatedPrimitiveFieldGenerator:: 344GenerateMembers(io::Printer* printer) const { 345 if (IsFastStringHandling(descriptor_, params_)) { 346 if (params_.java_use_vector()) { 347 printer->Print(variables_, 348 "private java.util.Vector $name$_ = new java.util.Vector();\n" 349 "public java.util.Vector get$capitalized_name$List() {\n" 350 " return $name$_;\n" 351 "}\n" 352 "private java.util.Vector $name$Utf8_ = new java.util.Vector();\n" 353 "public int get$capitalized_name$Count() { return $name$_.size(); }\n" 354 "public $type$ get$capitalized_name$(int index) {\n" 355 " return (($type$)$name$_.elementAt(index));\n" 356 "}\n" 357 "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" 358 "$null_check$" 359 " $name$_.setElementAt(value, index);\n" 360 " $name$Utf8_ = null;\n" 361 " return this;\n" 362 "}\n" 363 "public $message_name$ add$capitalized_name$($type$ value) {\n" 364 "$null_check$" 365 " $name$_.addElement(value);\n" 366 " $name$Utf8_ = null;\n" 367 " return this;\n" 368 "}\n" 369 "public $message_name$ clear$capitalized_name$() {\n" 370 " $name$_.removeAllElements();\n" 371 " $name$Utf8_ = null;\n" 372 " return this;\n" 373 "}\n"); 374 } else { 375 printer->Print(variables_, 376 "private java.util.List<$type$> $name$_ =\n" 377 " java.util.Collections.emptyList();\n" 378 "public java.util.List<$type$> get$capitalized_name$List() {\n" 379 " return $name$_;\n" // note: unmodifiable list 380 "}\n" 381 "private java.util.List<byte []> $name$Utf8_ = null;\n" 382 "public int get$capitalized_name$Count() { return $name$_.size(); }\n" 383 "public $type$ get$capitalized_name$(int index) {\n" 384 " return $name$_.get(index);\n" 385 "}\n" 386 "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" 387 "$null_check$" 388 " $name$_.set(index, value);\n" 389 " $name$Utf8_ = null;\n" 390 " return this;\n" 391 "}\n" 392 "public $message_name$ add$capitalized_name$($type$ value) {\n" 393 "$null_check$" 394 " if ($name$_.isEmpty()) {\n" 395 " $name$_ = new java.util.ArrayList<$type$>();\n" 396 " }\n" 397 " $name$_.add(value);\n" 398 " $name$Utf8_ = null;\n" 399 " return this;\n" 400 "}\n" 401 "public $message_name$ clear$capitalized_name$() {\n" 402 " $name$_ = java.util.Collections.emptyList();\n" 403 " $name$Utf8_ = null;\n" 404 " return this;\n" 405 "}\n"); 406 } 407 } else if (params_.java_use_vector()) { 408 if (IsReferenceType(GetJavaType(descriptor_))) { 409 printer->Print(variables_, 410 "private java.util.Vector $name$_ = new java.util.Vector();\n" 411 "public java.util.Vector get$capitalized_name$List() {\n" 412 " return $name$_;\n" 413 "}\n" 414 "public int get$capitalized_name$Count() { return $name$_.size(); }\n" 415 "public $type$ get$capitalized_name$(int index) {\n" 416 " return ($type$) $name$_.elementAt(index);\n" 417 "}\n" 418 "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" 419 "$null_check$" 420 " $name$_.setElementAt(value, index);\n" 421 " return this;\n" 422 "}\n" 423 "public $message_name$ add$capitalized_name$($type$ value) {\n" 424 "$null_check$" 425 " $name$_.addElement(value);\n" 426 " return this;\n" 427 "}\n" 428 "public $message_name$ clear$capitalized_name$() {\n" 429 " $name$_.removeAllElements();\n" 430 " return this;\n" 431 "}\n"); 432 } else { 433 printer->Print(variables_, 434 "private java.util.Vector $name$_ = new java.util.Vector();\n" 435 "public java.util.Vector get$capitalized_name$List() {\n" 436 " return $name$_;\n" 437 "}\n" 438 "public int get$capitalized_name$Count() { return $name$_.size(); }\n" 439 "public $type$ get$capitalized_name$(int index) {\n" 440 " return (($boxed_type$)$name$_.elementAt(index)).$type$Value();\n" 441 "}\n" 442 "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" 443 "$null_check$" 444 " $name$_.setElementAt(new $boxed_type$(value), index);\n" 445 " return this;\n" 446 "}\n" 447 "public $message_name$ add$capitalized_name$($type$ value) {\n" 448 "$null_check$" 449 " $name$_.addElement(new $boxed_type$(value));\n" 450 " return this;\n" 451 "}\n" 452 "public $message_name$ clear$capitalized_name$() {\n" 453 " $name$_.removeAllElements();\n" 454 " return this;\n" 455 "}\n"); 456 } 457 } else { 458 printer->Print(variables_, 459 "private java.util.List<$boxed_type$> $name$_ =\n" 460 " java.util.Collections.emptyList();\n" 461 "public java.util.List<$boxed_type$> get$capitalized_name$List() {\n" 462 " return $name$_;\n" // note: unmodifiable list 463 "}\n" 464 "public int get$capitalized_name$Count() { return $name$_.size(); }\n" 465 "public $type$ get$capitalized_name$(int index) {\n" 466 " return $name$_.get(index);\n" 467 "}\n" 468 "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n" 469 "$null_check$" 470 " $name$_.set(index, value);\n" 471 " return this;\n" 472 "}\n" 473 "public $message_name$ add$capitalized_name$($type$ value) {\n" 474 "$null_check$" 475 " if ($name$_.isEmpty()) {\n" 476 " $name$_ = new java.util.ArrayList<$boxed_type$>();\n" 477 " }\n" 478 " $name$_.add(value);\n" 479 " return this;\n" 480 "}\n" 481 "public $message_name$ clear$capitalized_name$() {\n" 482 " $name$_ = java.util.Collections.emptyList();\n" 483 " return this;\n" 484 "}\n"); 485 } 486 if (descriptor_->options().packed()) { 487 printer->Print(variables_, 488 "private int $name$MemoizedSerializedSize;\n"); 489 } 490} 491 492void RepeatedPrimitiveFieldGenerator:: 493GenerateMergingCode(io::Printer* printer) const { 494 if (params_.java_use_vector()) { 495 printer->Print(variables_, 496 "if (other.$name$_.size() != 0) {\n" 497 " for (int i = 0; i < other.$name$_.size(); i++)) {\n" 498 " result.$name$_.addElement(other.$name$_.elementAt(i));\n" 499 " }\n" 500 "}\n"); 501 } else { 502 printer->Print(variables_, 503 "if (!other.$name$_.isEmpty()) {\n" 504 " if (result.$name$_.isEmpty()) {\n" 505 " result.$name$_ = new java.util.ArrayList<$type$>();\n" 506 " }\n" 507 " result.$name$_.addAll(other.$name$_);\n" 508 "}\n"); 509 } 510} 511 512void RepeatedPrimitiveFieldGenerator:: 513GenerateParsingCode(io::Printer* printer) const { 514 if (descriptor_->options().packed()) { 515 printer->Print(variables_, 516 "int length = input.readRawVarint32();\n" 517 "int limit = input.pushLimit(length);\n" 518 "while (input.getBytesUntilLimit() > 0) {\n" 519 " add$capitalized_name$(input.read$capitalized_type$());\n" 520 "}\n" 521 "input.popLimit(limit);\n"); 522 } else { 523 printer->Print(variables_, 524 "add$capitalized_name$(input.read$capitalized_type$());\n"); 525 } 526} 527 528void RepeatedPrimitiveFieldGenerator:: 529GenerateSerializationCode(io::Printer* printer) const { 530 if (descriptor_->options().packed()) { 531 printer->Print(variables_, 532 "if (get$capitalized_name$List().size() > 0) {\n" 533 " output.writeRawVarint32($tag$);\n" 534 " output.writeRawVarint32($name$MemoizedSerializedSize);\n" 535 "}\n"); 536 if (params_.java_use_vector()) { 537 printer->Print(variables_, 538 "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" 539 " output.write$capitalized_type$NoTag(get$capitalized_name$(i));\n" 540 "}\n"); 541 } else { 542 printer->Print(variables_, 543 "for ($type$ element : get$capitalized_name$List()) {\n" 544 " output.write$capitalized_type$NoTag(element);\n" 545 "}\n"); 546 } 547 } else { 548 if (params_.java_use_vector()) { 549 if (IsFastStringHandling(descriptor_, params_)) { 550 printer->Print(variables_, 551 "for (int i = 0; i < $name$Utf8_.size(); i++) {\n" 552 " output.writeByteArray($number$, (byte []) $name$Utf8_.get(i));\n" 553 "}\n"); 554 } else { 555 printer->Print(variables_, 556 "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" 557 " output.write$capitalized_type$($number$, get$capitalized_name$(i));\n" 558 "}\n"); 559 } 560 } else { 561 if (IsFastStringHandling(descriptor_, params_)) { 562 printer->Print(variables_, 563 "for (byte [] element : $name$Utf8_) {\n" 564 " output.writeByteArray($number$, element);\n" 565 "}\n"); 566 } else { 567 printer->Print(variables_, 568 "for ($type$ element : get$capitalized_name$List()) {\n" 569 " output.write$capitalized_type$($number$, element);\n" 570 "}\n"); 571 } 572 } 573 } 574} 575 576void RepeatedPrimitiveFieldGenerator:: 577GenerateSerializedSizeCode(io::Printer* printer) const { 578 printer->Print(variables_, 579 "{\n" 580 " int dataSize = 0;\n"); 581 printer->Indent(); 582 583 if (FixedSize(descriptor_->type()) == -1) { 584 if (params_.java_use_vector()) { 585 if (IsFastStringHandling(descriptor_, params_)) { 586 printer->Print(variables_, 587 "$name$Utf8_ = new java.util.Vector();\n" 588 "byte[] bytes = null;\n" 589 "int sizeArray = get$capitalized_name$List().size();\n" 590 "for (int i = 0; i < sizeArray; i++) {\n" 591 " $type$ element = ($type$)$name$_.elementAt(i);\n" 592 " try {\n" 593 " bytes = element.getBytes(\"UTF-8\");\n" 594 " } catch (java.io.UnsupportedEncodingException e) {\n" 595 " throw new RuntimeException(\"UTF-8 not supported.\");\n" 596 " }\n" 597 " $name$Utf8_.addElement(bytes);\n" 598 " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n" 599 " .computeByteArraySizeNoTag(bytes);\n" 600 "}\n"); 601 } else { 602 printer->Print(variables_, 603 "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n" 604 " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n" 605 " .compute$capitalized_type$SizeNoTag(($type$)get$capitalized_name$(i));\n" 606 "}\n"); 607 } 608 } else { 609 if (IsFastStringHandling(descriptor_, params_)) { 610 printer->Print(variables_, 611 "$name$Utf8_ = new java.util.ArrayList<byte[]>();\n" 612 "byte[] bytes = null;\n" 613 "int sizeArray = get$capitalized_name$List().size();\n" 614 "for (int i = 0; i < sizeArray; i++) {\n" 615 " $type$ element = get$capitalized_name$(i);\n" 616 " try {\n" 617 " bytes = element.getBytes(\"UTF-8\");\n" 618 " } catch (java.io.UnsupportedEncodingException e) {\n" 619 " throw new RuntimeException(\"UTF-8 not supported.\");\n" 620 " }\n" 621 " $name$Utf8_.add(bytes);\n" 622 " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n" 623 " .computeByteArraySizeNoTag(bytes);\n" 624 "}\n"); 625 } else { 626 printer->Print(variables_, 627 "for ($type$ element : get$capitalized_name$List()) {\n" 628 " dataSize += com.google.protobuf.micro.CodedOutputStreamMicro\n" 629 " .compute$capitalized_type$SizeNoTag(element);\n" 630 "}\n"); 631 } 632 } 633 } else { 634 printer->Print(variables_, 635 "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n"); 636 } 637 638 printer->Print( 639 "size += dataSize;\n"); 640 641 if (descriptor_->options().packed()) { 642 if (params_.java_use_vector()) { 643 printer->Print(variables_, 644 "if (get$capitalized_name$List().size() != 0) {\n"); 645 } else { 646 printer->Print(variables_, 647 "if (!get$capitalized_name$List().isEmpty()) {\n"); 648 } 649 printer->Print(variables_, 650 " size += $tag_size$;\n" 651 " size += com.google.protobuf.micro.CodedOutputStreamMicro\n" 652 " .computeInt32SizeNoTag(dataSize);\n" 653 "}\n"); 654 } else { 655 printer->Print(variables_, 656 "size += $tag_size$ * get$capitalized_name$List().size();\n"); 657 } 658 659 // cache the data size for packed fields. 660 if (descriptor_->options().packed()) { 661 printer->Print(variables_, 662 "$name$MemoizedSerializedSize = dataSize;\n"); 663 } 664 665 printer->Outdent(); 666 printer->Print("}\n"); 667} 668 669string RepeatedPrimitiveFieldGenerator::GetBoxedType() const { 670 return BoxedPrimitiveTypeName(GetJavaType(descriptor_)); 671} 672 673} // namespace javamicro 674} // namespace compiler 675} // namespace protobuf 676} // namespace google 677