LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf/compiler/objectivec - objectivec_field.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 0 184 0.0 %
Date: 2015-10-10 Functions: 0 38 0.0 %

          Line data    Source code
       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             : #include <google/protobuf/compiler/objectivec/objectivec_field.h>
      32             : #include <google/protobuf/compiler/objectivec/objectivec_helpers.h>
      33             : #include <google/protobuf/compiler/objectivec/objectivec_enum_field.h>
      34             : #include <google/protobuf/compiler/objectivec/objectivec_map_field.h>
      35             : #include <google/protobuf/compiler/objectivec/objectivec_message_field.h>
      36             : #include <google/protobuf/compiler/objectivec/objectivec_primitive_field.h>
      37             : #include <google/protobuf/io/printer.h>
      38             : #include <google/protobuf/wire_format.h>
      39             : #include <google/protobuf/stubs/common.h>
      40             : #include <google/protobuf/stubs/strutil.h>
      41             : 
      42             : namespace google {
      43             : namespace protobuf {
      44             : namespace compiler {
      45             : namespace objectivec {
      46             : 
      47             : namespace {
      48           0 : void SetCommonFieldVariables(const FieldDescriptor* descriptor,
      49             :                              map<string, string>* variables) {
      50           0 :   string camel_case_name = FieldName(descriptor);
      51             :   string raw_field_name;
      52           0 :   if (descriptor->type() == FieldDescriptor::TYPE_GROUP) {
      53           0 :     raw_field_name = descriptor->message_type()->name();
      54             :   } else {
      55           0 :     raw_field_name = descriptor->name();
      56             :   }
      57             :   // The logic here has to match -[GGPBFieldDescriptor textFormatName].
      58             :   const string un_camel_case_name(
      59           0 :       UnCamelCaseFieldName(camel_case_name, descriptor));
      60           0 :   const bool needs_custom_name = (raw_field_name != un_camel_case_name);
      61             : 
      62           0 :   SourceLocation location;
      63           0 :   if (descriptor->GetSourceLocation(&location)) {
      64           0 :     (*variables)["comments"] = BuildCommentsString(location);
      65             :   } else {
      66           0 :     (*variables)["comments"] = "\n";
      67             :   }
      68           0 :   const string& classname = ClassName(descriptor->containing_type());
      69           0 :   (*variables)["classname"] = classname;
      70           0 :   (*variables)["name"] = camel_case_name;
      71           0 :   const string& capitalized_name = FieldNameCapitalized(descriptor);
      72           0 :   (*variables)["capitalized_name"] = capitalized_name;
      73           0 :   (*variables)["raw_field_name"] = raw_field_name;
      74           0 :   (*variables)["field_number_name"] =
      75           0 :       classname + "_FieldNumber_" + capitalized_name;
      76           0 :   (*variables)["field_number"] = SimpleItoa(descriptor->number());
      77           0 :   (*variables)["has_index"] = SimpleItoa(descriptor->index());
      78           0 :   (*variables)["field_type"] = GetCapitalizedType(descriptor);
      79           0 :   std::vector<string> field_flags;
      80           0 :   if (descriptor->is_repeated()) field_flags.push_back("GPBFieldRepeated");
      81           0 :   if (descriptor->is_required()) field_flags.push_back("GPBFieldRequired");
      82           0 :   if (descriptor->is_optional()) field_flags.push_back("GPBFieldOptional");
      83           0 :   if (descriptor->is_packed()) field_flags.push_back("GPBFieldPacked");
      84             : 
      85             :   // ObjC custom flags.
      86           0 :   if (descriptor->has_default_value())
      87           0 :     field_flags.push_back("GPBFieldHasDefaultValue");
      88           0 :   if (needs_custom_name) field_flags.push_back("GPBFieldTextFormatNameCustom");
      89           0 :   if (descriptor->type() == FieldDescriptor::TYPE_ENUM) {
      90           0 :     field_flags.push_back("GPBFieldHasEnumDescriptor");
      91             :   }
      92             : 
      93           0 :   (*variables)["fieldflags"] = BuildFlagsString(field_flags);
      94             : 
      95           0 :   (*variables)["default"] = DefaultValue(descriptor);
      96           0 :   (*variables)["default_name"] = GPBGenericValueFieldName(descriptor);
      97             : 
      98           0 :   (*variables)["dataTypeSpecific_name"] = "className";
      99           0 :   (*variables)["dataTypeSpecific_value"] = "NULL";
     100             : 
     101           0 :   string field_options = descriptor->options().SerializeAsString();
     102             :   // Must convert to a standard byte order for packing length into
     103             :   // a cstring.
     104           0 :   uint32 length = ghtonl(field_options.length());
     105           0 :   if (length > 0) {
     106           0 :     string bytes((const char*)&length, sizeof(length));
     107           0 :     bytes.append(field_options);
     108           0 :     string options_str = "\"" + CEscape(bytes) + "\"";
     109           0 :     (*variables)["fieldoptions"] = "\"" + CEscape(bytes) + "\"";
     110             :   } else {
     111           0 :     (*variables)["fieldoptions"] = "";
     112             :   }
     113             : 
     114             :   // Clear some common things so they can be set just when needed.
     115           0 :   (*variables)["storage_attribute"] = "";
     116           0 : }
     117             : 
     118             : }  // namespace
     119             : 
     120           0 : FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) {
     121           0 :   FieldGenerator* result = NULL;
     122           0 :   if (field->is_repeated()) {
     123           0 :     switch (GetObjectiveCType(field)) {
     124             :       case OBJECTIVECTYPE_MESSAGE: {
     125           0 :         if (field->is_map()) {
     126           0 :           result = new MapFieldGenerator(field);
     127             :         } else {
     128           0 :           result = new RepeatedMessageFieldGenerator(field);
     129             :         }
     130             :         break;
     131             :       }
     132             :       case OBJECTIVECTYPE_ENUM:
     133           0 :         result = new RepeatedEnumFieldGenerator(field);
     134             :         break;
     135             :       default:
     136           0 :         result = new RepeatedPrimitiveFieldGenerator(field);
     137             :         break;
     138             :     }
     139             :   } else {
     140           0 :     switch (GetObjectiveCType(field)) {
     141             :       case OBJECTIVECTYPE_MESSAGE: {
     142           0 :         result = new MessageFieldGenerator(field);
     143             :         break;
     144             :       }
     145             :       case OBJECTIVECTYPE_ENUM:
     146           0 :         result = new EnumFieldGenerator(field);
     147             :         break;
     148             :       default:
     149           0 :         if (IsReferenceType(field)) {
     150           0 :           result = new PrimitiveObjFieldGenerator(field);
     151             :         } else {
     152           0 :           result = new PrimitiveFieldGenerator(field);
     153             :         }
     154             :         break;
     155             :     }
     156             :   }
     157           0 :   result->FinishInitialization();
     158           0 :   return result;
     159             : }
     160             : 
     161             : 
     162           0 : FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor)
     163           0 :     : descriptor_(descriptor) {
     164           0 :   SetCommonFieldVariables(descriptor, &variables_);
     165           0 : }
     166             : 
     167           0 : FieldGenerator::~FieldGenerator() {}
     168             : 
     169           0 : void FieldGenerator::GenerateFieldNumberConstant(io::Printer* printer) const {
     170             :   printer->Print(
     171             :       variables_,
     172           0 :       "$field_number_name$ = $field_number$,\n");
     173           0 : }
     174             : 
     175           0 : void FieldGenerator::GenerateCFunctionDeclarations(
     176             :     io::Printer* printer) const {
     177             :   // Nothing
     178           0 : }
     179             : 
     180           0 : void FieldGenerator::GenerateCFunctionImplementations(
     181             :     io::Printer* printer) const {
     182             :   // Nothing
     183           0 : }
     184             : 
     185           0 : void FieldGenerator::DetermineForwardDeclarations(
     186             :     set<string>* fwd_decls) const {
     187             :   // Nothing
     188           0 : }
     189             : 
     190           0 : void FieldGenerator::GenerateFieldDescription(
     191             :     io::Printer* printer) const {
     192             :   printer->Print(
     193             :       variables_,
     194             :       "{\n"
     195             :       "  .name = \"$name$\",\n"
     196             :       "  .number = $field_number_name$,\n"
     197             :       "  .hasIndex = $has_index$,\n"
     198             :       "  .flags = $fieldflags$,\n"
     199             :       "  .dataType = GPBDataType$field_type$,\n"
     200             :       "  .offset = offsetof($classname$__storage_, $name$),\n"
     201           0 :       "  .defaultValue.$default_name$ = $default$,\n");
     202             : 
     203             :   // TODO(thomasvl): It might be useful to add a CPP wrapper to support
     204             :   // compiling away the EnumDescriptors.  To do that, we'd need a #if here
     205             :   // to control setting the descriptor vs. the validator, and above in
     206             :   // SetCommonFieldVariables() we'd want to wrap how we add
     207             :   // GPBFieldHasDefaultValue to the flags.
     208             : 
     209             :   // "  .dataTypeSpecific.value* = [something],"
     210           0 :   GenerateFieldDescriptionTypeSpecific(printer);
     211             : 
     212           0 :   const string& field_options(variables_.find("fieldoptions")->second);
     213           0 :   if (field_options.empty()) {
     214           0 :     printer->Print("  .fieldOptions = NULL,\n");
     215             :   } else {
     216             :     // Can't use PrintRaw() here to get the #if/#else/#endif lines completely
     217             :     // outdented because the need for indent captured on the previous
     218             :     // printing of a \n and there is no way to get the current indent level
     219             :     // to call the right number of Outdent()/Indents() to maintain state.
     220             :     printer->Print(
     221             :         variables_,
     222             :         "#if GPBOBJC_INCLUDE_FIELD_OPTIONS\n"
     223             :         "  .fieldOptions = $fieldoptions$,\n"
     224             :         "#else\n"
     225             :         "  .fieldOptions = NULL,\n"
     226           0 :         "#endif  // GPBOBJC_INCLUDE_FIELD_OPTIONS\n");
     227             :   }
     228             : 
     229           0 :   printer->Print("},\n");
     230           0 : }
     231             : 
     232           0 : void FieldGenerator::GenerateFieldDescriptionTypeSpecific(
     233             :     io::Printer* printer) const {
     234             :   printer->Print(
     235             :       variables_,
     236           0 :       "  .dataTypeSpecific.$dataTypeSpecific_name$ = $dataTypeSpecific_value$,\n");
     237           0 : }
     238             : 
     239           0 : void FieldGenerator::SetOneofIndexBase(int index_base) {
     240           0 :   if (descriptor_->containing_oneof() != NULL) {
     241           0 :     int index = descriptor_->containing_oneof()->index() + index_base;
     242             :     // Flip the sign to mark it as a oneof.
     243           0 :     variables_["has_index"] = SimpleItoa(-index);
     244             :   }
     245           0 : }
     246             : 
     247           0 : void FieldGenerator::FinishInitialization(void) {
     248             :   // If "property_type" wasn't set, make it "storage_type".
     249           0 :   if ((variables_.find("property_type") == variables_.end()) &&
     250           0 :       (variables_.find("storage_type") != variables_.end())) {
     251           0 :     variables_["property_type"] = variable("storage_type");
     252             :   }
     253           0 : }
     254             : 
     255           0 : SingleFieldGenerator::SingleFieldGenerator(
     256             :     const FieldDescriptor* descriptor)
     257           0 :     : FieldGenerator(descriptor) {
     258             :   // Nothing
     259           0 : }
     260             : 
     261           0 : SingleFieldGenerator::~SingleFieldGenerator() {}
     262             : 
     263           0 : void SingleFieldGenerator::GenerateFieldStorageDeclaration(
     264             :     io::Printer* printer) const {
     265           0 :   printer->Print(variables_, "$storage_type$ $name$;\n");
     266           0 : }
     267             : 
     268           0 : void SingleFieldGenerator::GeneratePropertyDeclaration(
     269             :     io::Printer* printer) const {
     270           0 :   printer->Print(variables_, "$comments$");
     271           0 :   if (WantsHasProperty()) {
     272             :     printer->Print(
     273             :         variables_,
     274           0 :         "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n");
     275             :   }
     276             :   printer->Print(
     277             :       variables_,
     278             :       "@property(nonatomic, readwrite) $property_type$ $name$;\n"
     279           0 :       "\n");
     280           0 : }
     281             : 
     282           0 : void SingleFieldGenerator::GeneratePropertyImplementation(
     283             :     io::Printer* printer) const {
     284           0 :   if (WantsHasProperty()) {
     285           0 :     printer->Print(variables_, "@dynamic has$capitalized_name$, $name$;\n");
     286             :   } else {
     287           0 :     printer->Print(variables_, "@dynamic $name$;\n");
     288             :   }
     289           0 : }
     290             : 
     291           0 : bool SingleFieldGenerator::WantsHasProperty(void) const {
     292           0 :   if (descriptor_->containing_oneof() != NULL) {
     293             :     // If in a oneof, it uses the oneofcase instead of a has bit.
     294             :     return false;
     295             :   }
     296           0 :   if (HasFieldPresence(descriptor_->file())) {
     297             :     // In proto1/proto2, every field has a has_$name$() method.
     298             :     return true;
     299             :   }
     300           0 :   return false;
     301             : }
     302             : 
     303           0 : ObjCObjFieldGenerator::ObjCObjFieldGenerator(
     304             :     const FieldDescriptor* descriptor)
     305           0 :     : SingleFieldGenerator(descriptor) {
     306           0 :   variables_["property_storage_attribute"] = "strong";
     307           0 :   if (IsRetainedName(variables_["name"])) {
     308           0 :     variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED";
     309             :   }
     310           0 : }
     311             : 
     312           0 : ObjCObjFieldGenerator::~ObjCObjFieldGenerator() {}
     313             : 
     314           0 : void ObjCObjFieldGenerator::GenerateFieldStorageDeclaration(
     315             :     io::Printer* printer) const {
     316           0 :   printer->Print(variables_, "$storage_type$ *$name$;\n");
     317           0 : }
     318             : 
     319           0 : void ObjCObjFieldGenerator::GeneratePropertyDeclaration(
     320             :     io::Printer* printer) const {
     321             : 
     322             :   // Differs from SingleFieldGenerator::GeneratePropertyDeclaration() in that
     323             :   // it uses pointers and deals with Objective C's rules around storage name
     324             :   // conventions (init*, new*, etc.)
     325             : 
     326           0 :   printer->Print(variables_, "$comments$");
     327           0 :   if (WantsHasProperty()) {
     328             :     printer->Print(
     329             :         variables_,
     330           0 :         "@property(nonatomic, readwrite) BOOL has$capitalized_name$;\n");
     331             :   }
     332             :   printer->Print(
     333             :       variables_,
     334           0 :       "@property(nonatomic, readwrite, $property_storage_attribute$, null_resettable) $property_type$ *$name$$storage_attribute$;\n");
     335           0 :   if (IsInitName(variables_.find("name")->second)) {
     336             :     // If property name starts with init we need to annotate it to get past ARC.
     337             :     // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
     338             :     printer->Print(variables_,
     339           0 :                    "- ($property_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n");
     340             :   }
     341           0 :   printer->Print("\n");
     342           0 : }
     343             : 
     344           0 : RepeatedFieldGenerator::RepeatedFieldGenerator(
     345             :     const FieldDescriptor* descriptor)
     346           0 :     : ObjCObjFieldGenerator(descriptor) {
     347             :   // Repeated fields don't use the has index.
     348           0 :   variables_["has_index"] = "GPBNoHasBit";
     349           0 : }
     350             : 
     351           0 : RepeatedFieldGenerator::~RepeatedFieldGenerator() {}
     352             : 
     353           0 : void RepeatedFieldGenerator::FinishInitialization(void) {
     354           0 :   FieldGenerator::FinishInitialization();
     355           0 :   variables_["array_comment"] =
     356           0 :       "// |" + variables_["name"] + "| contains |" + variables_["storage_type"] + "|\n";
     357           0 : }
     358             : 
     359           0 : void RepeatedFieldGenerator::GenerateFieldStorageDeclaration(
     360             :     io::Printer* printer) const {
     361           0 :   printer->Print(variables_, "$array_storage_type$ *$name$;\n");
     362           0 : }
     363             : 
     364           0 : void RepeatedFieldGenerator::GeneratePropertyImplementation(
     365             :     io::Printer* printer) const {
     366           0 :   printer->Print(variables_, "@dynamic $name$, $name$_Count;\n");
     367           0 : }
     368             : 
     369           0 : void RepeatedFieldGenerator::GeneratePropertyDeclaration(
     370             :     io::Printer* printer) const {
     371             : 
     372             :   // Repeated fields don't need the has* properties, but they do expose a
     373             :   // *Count (to check without autocreation).  So for the field property we need
     374             :   // the same logic as ObjCObjFieldGenerator::GeneratePropertyDeclaration() for
     375             :   // dealing with needing Objective C's rules around storage name conventions
     376             :   // (init*, new*, etc.)
     377             : 
     378             :   printer->Print(
     379             :       variables_,
     380             :       "$comments$"
     381             :       "$array_comment$"
     382             :       "@property(nonatomic, readwrite, strong, null_resettable) $array_storage_type$ *$name$$storage_attribute$;\n"
     383           0 :       "@property(nonatomic, readonly) NSUInteger $name$_Count;\n");
     384           0 :   if (IsInitName(variables_.find("name")->second)) {
     385             :     // If property name starts with init we need to annotate it to get past ARC.
     386             :     // http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
     387             :     printer->Print(variables_,
     388           0 :                    "- ($array_storage_type$ *)$name$ GPB_METHOD_FAMILY_NONE;\n");
     389             :   }
     390           0 :   printer->Print("\n");
     391           0 : }
     392             : 
     393           0 : bool RepeatedFieldGenerator::WantsHasProperty(void) const {
     394             :   // Consumer check the array size/existance rather than a has bit.
     395           0 :   return false;
     396             : }
     397             : 
     398           0 : FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor)
     399             :     : descriptor_(descriptor),
     400             :       field_generators_(
     401           0 :           new scoped_ptr<FieldGenerator>[descriptor->field_count()]),
     402             :       extension_generators_(
     403           0 :           new scoped_ptr<FieldGenerator>[descriptor->extension_count()]) {
     404             :   // Construct all the FieldGenerators.
     405           0 :   for (int i = 0; i < descriptor->field_count(); i++) {
     406           0 :     field_generators_[i].reset(FieldGenerator::Make(descriptor->field(i)));
     407             :   }
     408           0 :   for (int i = 0; i < descriptor->extension_count(); i++) {
     409           0 :     extension_generators_[i].reset(FieldGenerator::Make(descriptor->extension(i)));
     410             :   }
     411           0 : }
     412             : 
     413           0 : FieldGeneratorMap::~FieldGeneratorMap() {}
     414             : 
     415           0 : const FieldGenerator& FieldGeneratorMap::get(
     416           0 :     const FieldDescriptor* field) const {
     417           0 :   GOOGLE_CHECK_EQ(field->containing_type(), descriptor_);
     418           0 :   return *field_generators_[field->index()];
     419             : }
     420             : 
     421           0 : const FieldGenerator& FieldGeneratorMap::get_extension(int index) const {
     422           0 :   return *extension_generators_[index];
     423             : }
     424             : 
     425           0 : void FieldGeneratorMap::SetOneofIndexBase(int index_base) {
     426           0 :   for (int i = 0; i < descriptor_->field_count(); i++) {
     427           0 :     field_generators_[i]->SetOneofIndexBase(index_base);
     428             :   }
     429           0 : }
     430             : 
     431             : }  // namespace objectivec
     432             : }  // namespace compiler
     433             : }  // namespace protobuf
     434             : }  // namespace google

Generated by: LCOV version 1.10