Home | History | Annotate | Download | only in javamicro
      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 (at) 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_message_field.h>
     39 #include <google/protobuf/compiler/javamicro/javamicro_helpers.h>
     40 #include <google/protobuf/io/printer.h>
     41 #include <google/protobuf/wire_format.h>
     42 #include <google/protobuf/stubs/strutil.h>
     43 
     44 namespace google {
     45 namespace protobuf {
     46 namespace compiler {
     47 namespace javamicro {
     48 
     49 namespace {
     50 
     51 // TODO(kenton):  Factor out a "SetCommonFieldVariables()" to get rid of
     52 //   repeat code between this and the other field types.
     53 void SetMessageVariables(const Params& params,
     54     const FieldDescriptor* descriptor, map<string, string>* variables) {
     55   (*variables)["name"] =
     56     UnderscoresToCamelCase(descriptor);
     57   (*variables)["capitalized_name"] =
     58     UnderscoresToCapitalizedCamelCase(descriptor);
     59   (*variables)["number"] = SimpleItoa(descriptor->number());
     60   (*variables)["type"] = ClassName(params, descriptor->message_type());
     61   (*variables)["group_or_message"] =
     62     (descriptor->type() == FieldDescriptor::TYPE_GROUP) ?
     63     "Group" : "Message";
     64   (*variables)["message_name"] = descriptor->containing_type()->name();
     65   //(*variables)["message_type"] = descriptor->message_type()->name();
     66 }
     67 
     68 }  // namespace
     69 
     70 // ===================================================================
     71 
     72 MessageFieldGenerator::
     73 MessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
     74   : FieldGenerator(params), descriptor_(descriptor) {
     75   SetMessageVariables(params, descriptor, &variables_);
     76 }
     77 
     78 MessageFieldGenerator::~MessageFieldGenerator() {}
     79 
     80 void MessageFieldGenerator::
     81 GenerateMembers(io::Printer* printer) const {
     82   printer->Print(variables_,
     83     "private boolean has$capitalized_name$;\n"
     84 //    "private $type$ $name$_ = null;\n"
     85 //    "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
     86 //    "public $type$ get$capitalized_name$() { return $name$_; }\n"
     87     "private $type$ $name$_ = null;\n"
     88     "public boolean has$capitalized_name$() { return has$capitalized_name$; }\n"
     89     "public $type$ get$capitalized_name$() { return $name$_; }\n"
     90     "public $message_name$ set$capitalized_name$($type$ value) {\n"
     91     "  if (value == null) {\n"
     92     "    throw new NullPointerException();\n"
     93     "  }\n"
     94     "  has$capitalized_name$ = true;\n"
     95     "  $name$_ = value;\n"
     96     "  return this;\n"
     97     "}\n"
     98     "public $message_name$ clear$capitalized_name$() {\n"
     99     "  has$capitalized_name$ = false;\n"
    100     "  $name$_ = null;\n"
    101     "  return this;\n"
    102     "}\n");
    103 }
    104 
    105 void MessageFieldGenerator::
    106 GenerateMergingCode(io::Printer* printer) const {
    107   printer->Print(variables_,
    108     "if (other.has$capitalized_name$()) {\n"
    109     "  merge$capitalized_name$(other.get$capitalized_name$());\n"
    110     "}\n");
    111 }
    112 
    113 void MessageFieldGenerator::
    114 GenerateParsingCode(io::Printer* printer) const {
    115   printer->Print(variables_,
    116     "$type$ value = new $type$();\n");
    117 
    118   if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
    119     printer->Print(variables_,
    120       "input.readGroup(value, $number$);\n");
    121   } else {
    122     printer->Print(variables_,
    123       "input.readMessage(value);\n");
    124   }
    125 
    126   printer->Print(variables_,
    127     "set$capitalized_name$(value);\n");
    128 }
    129 
    130 void MessageFieldGenerator::
    131 GenerateSerializationCode(io::Printer* printer) const {
    132   printer->Print(variables_,
    133     "if (has$capitalized_name$()) {\n"
    134     "  output.write$group_or_message$($number$, get$capitalized_name$());\n"
    135     "}\n");
    136 }
    137 
    138 void MessageFieldGenerator::
    139 GenerateSerializedSizeCode(io::Printer* printer) const {
    140   printer->Print(variables_,
    141     "if (has$capitalized_name$()) {\n"
    142     "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
    143     "    .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
    144     "}\n");
    145 }
    146 
    147 string MessageFieldGenerator::GetBoxedType() const {
    148   return ClassName(params_, descriptor_->message_type());
    149 }
    150 
    151 // ===================================================================
    152 
    153 RepeatedMessageFieldGenerator::
    154 RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, const Params& params)
    155   : FieldGenerator(params), descriptor_(descriptor) {
    156   SetMessageVariables(params, descriptor, &variables_);
    157 }
    158 
    159 RepeatedMessageFieldGenerator::~RepeatedMessageFieldGenerator() {}
    160 
    161 void RepeatedMessageFieldGenerator::
    162 GenerateMembers(io::Printer* printer) const {
    163   if (params_.java_use_vector()) {
    164     printer->Print(variables_,
    165       "private java.util.Vector $name$_ = new java.util.Vector();\n"
    166       "public java.util.Vector get$capitalized_name$List() {\n"
    167       "  return $name$_;\n"
    168       "}\n"
    169       "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
    170       "public $type$ get$capitalized_name$(int index) {\n"
    171       "  return ($type$) $name$_.elementAt(index);\n"
    172       "}\n"
    173       "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
    174       "  if (value == null) {\n"
    175       "    throw new NullPointerException();\n"
    176       "  }\n"
    177       "  $name$_.setElementAt(value, index);\n"
    178       "  return this;\n"
    179       "}\n"
    180       "public $message_name$ add$capitalized_name$($type$ value) {\n"
    181       "  if (value == null) {\n"
    182       "    throw new NullPointerException();\n"
    183       "  }\n"
    184       "  $name$_.addElement(value);\n"
    185       "  return this;\n"
    186       "}\n"
    187       "public $message_name$ clear$capitalized_name$() {\n"
    188       "  $name$_.removeAllElements();\n"
    189       "  return this;\n"
    190       "}\n");
    191   } else {
    192     printer->Print(variables_,
    193       "private java.util.List<$type$> $name$_ =\n"
    194       "  java.util.Collections.emptyList();\n"
    195       "public java.util.List<$type$> get$capitalized_name$List() {\n"
    196       "  return $name$_;\n"
    197       "}\n"
    198       "public int get$capitalized_name$Count() { return $name$_.size(); }\n"
    199       "public $type$ get$capitalized_name$(int index) {\n"
    200       "  return $name$_.get(index);\n"
    201       "}\n"
    202       "public $message_name$ set$capitalized_name$(int index, $type$ value) {\n"
    203       "  if (value == null) {\n"
    204       "    throw new NullPointerException();\n"
    205       "  }\n"
    206       "  $name$_.set(index, value);\n"
    207       "  return this;\n"
    208       "}\n"
    209       "public $message_name$ add$capitalized_name$($type$ value) {\n"
    210       "  if (value == null) {\n"
    211       "    throw new NullPointerException();\n"
    212       "  }\n"
    213       "  if ($name$_.isEmpty()) {\n"
    214       "    $name$_ = new java.util.ArrayList<$type$>();\n"
    215       "  }\n"
    216       "  $name$_.add(value);\n"
    217       "  return this;\n"
    218       "}\n"
    219       "public $message_name$ clear$capitalized_name$() {\n"
    220       "  $name$_ = java.util.Collections.emptyList();\n"
    221       "  return this;\n"
    222       "}\n");
    223   }
    224 }
    225 
    226 void RepeatedMessageFieldGenerator::
    227 GenerateMergingCode(io::Printer* printer) const {
    228   if (params_.java_use_vector()) {
    229     printer->Print(variables_,
    230       "if (other.$name$_.size() != 0) {\n"
    231       "  for (int i = 0; i < other.$name$_.size(); i++) {\n"
    232       "    result.$name$_.addElement(other.$name$_.elementAt(i));\n"
    233       "  }\n"
    234       "}\n");
    235   } else {
    236     printer->Print(variables_,
    237       "if (!other.$name$_.isEmpty()) {\n"
    238       "  if (result.$name$_.isEmpty()) {\n"
    239       "    result.$name$_ = new java.util.ArrayList<$type$>();\n"
    240       "  }\n"
    241       "  result.$name$_.addAll(other.$name$_);\n"
    242       "}\n");
    243   }
    244 }
    245 
    246 void RepeatedMessageFieldGenerator::
    247 GenerateParsingCode(io::Printer* printer) const {
    248   printer->Print(variables_,
    249     "$type$ value = new $type$();\n");
    250 
    251   if (descriptor_->type() == FieldDescriptor::TYPE_GROUP) {
    252     printer->Print(variables_,
    253       "input.readGroup(value, $number$);\n");
    254   } else {
    255     printer->Print(variables_,
    256       "input.readMessage(value);\n");
    257   }
    258 
    259   printer->Print(variables_,
    260     "add$capitalized_name$(value);\n");
    261 }
    262 
    263 void RepeatedMessageFieldGenerator::
    264 GenerateSerializationCode(io::Printer* printer) const {
    265   if (params_.java_use_vector()) {
    266     printer->Print(variables_,
    267       "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
    268       "  output.write$group_or_message$($number$, get$capitalized_name$(i));\n"
    269       "}\n");
    270   } else {
    271     printer->Print(variables_,
    272       "for ($type$ element : get$capitalized_name$List()) {\n"
    273       "  output.write$group_or_message$($number$, element);\n"
    274       "}\n");
    275   }
    276 }
    277 
    278 void RepeatedMessageFieldGenerator::
    279 GenerateSerializedSizeCode(io::Printer* printer) const {
    280   if (params_.java_use_vector()) {
    281     printer->Print(variables_,
    282       "for (int i = 0; i < get$capitalized_name$List().size(); i++) {\n"
    283       "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
    284       "    .compute$group_or_message$Size($number$, get$capitalized_name$(i));\n"
    285       "}\n");
    286   } else {
    287     printer->Print(variables_,
    288       "for ($type$ element : get$capitalized_name$List()) {\n"
    289       "  size += com.google.protobuf.micro.CodedOutputStreamMicro\n"
    290       "    .compute$group_or_message$Size($number$, element);\n"
    291       "}\n");
    292   }
    293 }
    294 
    295 string RepeatedMessageFieldGenerator::GetBoxedType() const {
    296   return ClassName(params_, descriptor_->message_type());
    297 }
    298 
    299 }  // namespace javamicro
    300 }  // namespace compiler
    301 }  // namespace protobuf
    302 }  // namespace google
    303