Home | History | Annotate | Download | only in java
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      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 <google/protobuf/compiler/java/java_field.h>
     36 
     37 #include <memory>
     38 #ifndef _SHARED_PTR_H
     39 #include <google/protobuf/stubs/shared_ptr.h>
     40 #endif
     41 
     42 #include <google/protobuf/stubs/logging.h>
     43 #include <google/protobuf/stubs/common.h>
     44 #include <google/protobuf/compiler/java/java_context.h>
     45 #include <google/protobuf/compiler/java/java_enum_field.h>
     46 #include <google/protobuf/compiler/java/java_enum_field_lite.h>
     47 #include <google/protobuf/compiler/java/java_helpers.h>
     48 #include <google/protobuf/compiler/java/java_lazy_message_field.h>
     49 #include <google/protobuf/compiler/java/java_lazy_message_field_lite.h>
     50 #include <google/protobuf/compiler/java/java_map_field.h>
     51 #include <google/protobuf/compiler/java/java_map_field_lite.h>
     52 #include <google/protobuf/compiler/java/java_message_field.h>
     53 #include <google/protobuf/compiler/java/java_message_field_lite.h>
     54 #include <google/protobuf/compiler/java/java_primitive_field.h>
     55 #include <google/protobuf/compiler/java/java_primitive_field_lite.h>
     56 #include <google/protobuf/compiler/java/java_string_field.h>
     57 #include <google/protobuf/compiler/java/java_string_field_lite.h>
     58 #include <google/protobuf/io/printer.h>
     59 #include <google/protobuf/stubs/strutil.h>
     60 #include <google/protobuf/stubs/substitute.h>
     61 
     62 
     63 namespace google {
     64 namespace protobuf {
     65 namespace compiler {
     66 namespace java {
     67 
     68 namespace {
     69 
     70 ImmutableFieldGenerator* MakeImmutableGenerator(
     71     const FieldDescriptor* field, int messageBitIndex, int builderBitIndex,
     72     Context* context) {
     73   if (field->is_repeated()) {
     74     switch (GetJavaType(field)) {
     75       case JAVATYPE_MESSAGE:
     76         if (IsMapEntry(field->message_type())) {
     77           return new ImmutableMapFieldGenerator(
     78               field, messageBitIndex, builderBitIndex, context);
     79         } else {
     80           if (IsLazy(field, context->EnforceLite())) {
     81             return new RepeatedImmutableLazyMessageFieldGenerator(
     82                 field, messageBitIndex, builderBitIndex, context);
     83           } else {
     84             return new RepeatedImmutableMessageFieldGenerator(
     85                 field, messageBitIndex, builderBitIndex, context);
     86           }
     87         }
     88       case JAVATYPE_ENUM:
     89         return new RepeatedImmutableEnumFieldGenerator(
     90             field, messageBitIndex, builderBitIndex, context);
     91       case JAVATYPE_STRING:
     92         return new RepeatedImmutableStringFieldGenerator(
     93             field, messageBitIndex, builderBitIndex, context);
     94       default:
     95         return new RepeatedImmutablePrimitiveFieldGenerator(
     96             field, messageBitIndex, builderBitIndex, context);
     97     }
     98   } else {
     99     if (field->containing_oneof()) {
    100       switch (GetJavaType(field)) {
    101         case JAVATYPE_MESSAGE:
    102           if (IsLazy(field, context->EnforceLite())) {
    103             return new ImmutableLazyMessageOneofFieldGenerator(
    104                 field, messageBitIndex, builderBitIndex, context);
    105           } else {
    106             return new ImmutableMessageOneofFieldGenerator(
    107                 field, messageBitIndex, builderBitIndex, context);
    108           }
    109         case JAVATYPE_ENUM:
    110           return new ImmutableEnumOneofFieldGenerator(
    111               field, messageBitIndex, builderBitIndex, context);
    112         case JAVATYPE_STRING:
    113           return new ImmutableStringOneofFieldGenerator(
    114               field, messageBitIndex, builderBitIndex, context);
    115         default:
    116           return new ImmutablePrimitiveOneofFieldGenerator(
    117               field, messageBitIndex, builderBitIndex, context);
    118       }
    119     } else {
    120       switch (GetJavaType(field)) {
    121         case JAVATYPE_MESSAGE:
    122           if (IsLazy(field, context->EnforceLite())) {
    123             return new ImmutableLazyMessageFieldGenerator(
    124                 field, messageBitIndex, builderBitIndex, context);
    125           } else {
    126             return new ImmutableMessageFieldGenerator(
    127                 field, messageBitIndex, builderBitIndex, context);
    128           }
    129         case JAVATYPE_ENUM:
    130           return new ImmutableEnumFieldGenerator(
    131               field, messageBitIndex, builderBitIndex, context);
    132         case JAVATYPE_STRING:
    133           return new ImmutableStringFieldGenerator(
    134               field, messageBitIndex, builderBitIndex, context);
    135         default:
    136           return new ImmutablePrimitiveFieldGenerator(
    137               field, messageBitIndex, builderBitIndex, context);
    138       }
    139     }
    140   }
    141 }
    142 
    143 ImmutableFieldLiteGenerator* MakeImmutableLiteGenerator(
    144     const FieldDescriptor* field, int messageBitIndex, int builderBitIndex,
    145     Context* context) {
    146   if (field->is_repeated()) {
    147     switch (GetJavaType(field)) {
    148       case JAVATYPE_MESSAGE:
    149         if (IsMapEntry(field->message_type())) {
    150           return new ImmutableMapFieldLiteGenerator(
    151               field, messageBitIndex, builderBitIndex, context);
    152         } else {
    153           if (IsLazy(field, context->EnforceLite())) {
    154             return new RepeatedImmutableLazyMessageFieldLiteGenerator(
    155                 field, messageBitIndex, builderBitIndex, context);
    156           } else {
    157             return new RepeatedImmutableMessageFieldLiteGenerator(
    158                 field, messageBitIndex, builderBitIndex, context);
    159           }
    160         }
    161       case JAVATYPE_ENUM:
    162         return new RepeatedImmutableEnumFieldLiteGenerator(
    163             field, messageBitIndex, builderBitIndex, context);
    164       case JAVATYPE_STRING:
    165         return new RepeatedImmutableStringFieldLiteGenerator(
    166             field, messageBitIndex, builderBitIndex, context);
    167       default:
    168         return new RepeatedImmutablePrimitiveFieldLiteGenerator(
    169             field, messageBitIndex, builderBitIndex, context);
    170     }
    171   } else {
    172     if (field->containing_oneof()) {
    173       switch (GetJavaType(field)) {
    174         case JAVATYPE_MESSAGE:
    175           if (IsLazy(field, context->EnforceLite())) {
    176             return new ImmutableLazyMessageOneofFieldLiteGenerator(
    177                 field, messageBitIndex, builderBitIndex, context);
    178           } else {
    179             return new ImmutableMessageOneofFieldLiteGenerator(
    180                 field, messageBitIndex, builderBitIndex, context);
    181           }
    182         case JAVATYPE_ENUM:
    183           return new ImmutableEnumOneofFieldLiteGenerator(
    184               field, messageBitIndex, builderBitIndex, context);
    185         case JAVATYPE_STRING:
    186           return new ImmutableStringOneofFieldLiteGenerator(
    187               field, messageBitIndex, builderBitIndex, context);
    188         default:
    189           return new ImmutablePrimitiveOneofFieldLiteGenerator(
    190               field, messageBitIndex, builderBitIndex, context);
    191       }
    192     } else {
    193       switch (GetJavaType(field)) {
    194         case JAVATYPE_MESSAGE:
    195           if (IsLazy(field, context->EnforceLite())) {
    196             return new ImmutableLazyMessageFieldLiteGenerator(
    197                 field, messageBitIndex, builderBitIndex, context);
    198           } else {
    199             return new ImmutableMessageFieldLiteGenerator(
    200                 field, messageBitIndex, builderBitIndex, context);
    201           }
    202         case JAVATYPE_ENUM:
    203           return new ImmutableEnumFieldLiteGenerator(
    204               field, messageBitIndex, builderBitIndex, context);
    205         case JAVATYPE_STRING:
    206           return new ImmutableStringFieldLiteGenerator(
    207               field, messageBitIndex, builderBitIndex, context);
    208         default:
    209           return new ImmutablePrimitiveFieldLiteGenerator(
    210               field, messageBitIndex, builderBitIndex, context);
    211       }
    212     }
    213   }
    214 }
    215 
    216 
    217 static inline void ReportUnexpectedPackedFieldsCall(io::Printer* printer) {
    218   // Reaching here indicates a bug. Cases are:
    219   //   - This FieldGenerator should support packing,
    220   //     but this method should be overridden.
    221   //   - This FieldGenerator doesn't support packing, and this method
    222   //     should never have been called.
    223   GOOGLE_LOG(FATAL) << "GenerateParsingCodeFromPacked() "
    224              << "called on field generator that does not support packing.";
    225 }
    226 
    227 }  // namespace
    228 
    229 ImmutableFieldGenerator::~ImmutableFieldGenerator() {}
    230 
    231 void ImmutableFieldGenerator::
    232 GenerateParsingCodeFromPacked(io::Printer* printer) const {
    233   ReportUnexpectedPackedFieldsCall(printer);
    234 }
    235 
    236 ImmutableFieldLiteGenerator::~ImmutableFieldLiteGenerator() {}
    237 
    238 void ImmutableFieldLiteGenerator::
    239 GenerateParsingCodeFromPacked(io::Printer* printer) const {
    240   ReportUnexpectedPackedFieldsCall(printer);
    241 }
    242 
    243 // ===================================================================
    244 
    245 template <>
    246 FieldGeneratorMap<ImmutableFieldGenerator>::FieldGeneratorMap(
    247     const Descriptor* descriptor, Context* context)
    248     : descriptor_(descriptor),
    249       field_generators_(new google::protobuf::scoped_ptr<
    250           ImmutableFieldGenerator>[descriptor->field_count()]) {
    251 
    252   // Construct all the FieldGenerators and assign them bit indices for their
    253   // bit fields.
    254   int messageBitIndex = 0;
    255   int builderBitIndex = 0;
    256   for (int i = 0; i < descriptor->field_count(); i++) {
    257     ImmutableFieldGenerator* generator = MakeImmutableGenerator(
    258         descriptor->field(i), messageBitIndex, builderBitIndex, context);
    259     field_generators_[i].reset(generator);
    260     messageBitIndex += generator->GetNumBitsForMessage();
    261     builderBitIndex += generator->GetNumBitsForBuilder();
    262   }
    263 }
    264 
    265 template<>
    266 FieldGeneratorMap<ImmutableFieldGenerator>::~FieldGeneratorMap() {}
    267 
    268 template <>
    269 FieldGeneratorMap<ImmutableFieldLiteGenerator>::FieldGeneratorMap(
    270     const Descriptor* descriptor, Context* context)
    271     : descriptor_(descriptor),
    272       field_generators_(new google::protobuf::scoped_ptr<
    273           ImmutableFieldLiteGenerator>[descriptor->field_count()]) {
    274   // Construct all the FieldGenerators and assign them bit indices for their
    275   // bit fields.
    276   int messageBitIndex = 0;
    277   int builderBitIndex = 0;
    278   for (int i = 0; i < descriptor->field_count(); i++) {
    279     ImmutableFieldLiteGenerator* generator = MakeImmutableLiteGenerator(
    280         descriptor->field(i), messageBitIndex, builderBitIndex, context);
    281     field_generators_[i].reset(generator);
    282     messageBitIndex += generator->GetNumBitsForMessage();
    283     builderBitIndex += generator->GetNumBitsForBuilder();
    284   }
    285 }
    286 
    287 template<>
    288 FieldGeneratorMap<ImmutableFieldLiteGenerator>::~FieldGeneratorMap() {}
    289 
    290 
    291 void SetCommonFieldVariables(const FieldDescriptor* descriptor,
    292                              const FieldGeneratorInfo* info,
    293                              map<string, string>* variables) {
    294   (*variables)["field_name"] = descriptor->name();
    295   (*variables)["name"] = info->name;
    296   (*variables)["capitalized_name"] = info->capitalized_name;
    297   (*variables)["disambiguated_reason"] = info->disambiguated_reason;
    298   (*variables)["constant_name"] = FieldConstantName(descriptor);
    299   (*variables)["number"] = SimpleItoa(descriptor->number());
    300 }
    301 
    302 void SetCommonOneofVariables(const FieldDescriptor* descriptor,
    303                              const OneofGeneratorInfo* info,
    304                              map<string, string>* variables) {
    305   (*variables)["oneof_name"] = info->name;
    306   (*variables)["oneof_capitalized_name"] = info->capitalized_name;
    307   (*variables)["oneof_index"] =
    308       SimpleItoa(descriptor->containing_oneof()->index());
    309   (*variables)["set_oneof_case_message"] = info->name +
    310       "Case_ = " + SimpleItoa(descriptor->number());
    311   (*variables)["clear_oneof_case_message"] = info->name +
    312       "Case_ = 0";
    313   (*variables)["has_oneof_case_message"] = info->name +
    314       "Case_ == " + SimpleItoa(descriptor->number());
    315 }
    316 
    317 void PrintExtraFieldInfo(const map<string, string>& variables,
    318                          io::Printer* printer) {
    319   const map<string, string>::const_iterator it =
    320       variables.find("disambiguated_reason");
    321   if (it != variables.end() && !it->second.empty()) {
    322     printer->Print(
    323         variables,
    324         "// An alternative name is used for field \"$field_name$\" because:\n"
    325         "//     $disambiguated_reason$\n");
    326   }
    327 }
    328 
    329 }  // namespace java
    330 }  // namespace compiler
    331 }  // namespace protobuf
    332 }  // namespace google
    333