Browse Source

[ObjC] Update oneof generation for proto3 optional.

- Don't make an OneofGenerator for synthetic oneofs.
- Update the field calculations that determine if hasbits are needed to
  know about synthetic oneofs and ignore them.
Thomas Van Lenten 5 years ago
parent
commit
e9b0c92659

+ 1 - 1
objectivec/GPBStruct.pbobjc.m

@@ -256,7 +256,7 @@ void SetGPBValue_NullValue_RawValue(GPBValue *message, int32_t value) {
 }
 }
 
 
 void GPBValue_ClearKindOneOfCase(GPBValue *message) {
 void GPBValue_ClearKindOneOfCase(GPBValue *message) {
-  GPBDescriptor *descriptor = [message descriptor];
+  GPBDescriptor *descriptor = [GPBValue descriptor];
   GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0];
   GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0];
   GPBMaybeClearOneof(message, oneof, -1, 0);
   GPBMaybeClearOneof(message, oneof, -1, 0);
 }
 }

+ 5 - 4
src/google/protobuf/compiler/objectivec/objectivec_field.cc

@@ -238,8 +238,9 @@ void FieldGenerator::SetExtraRuntimeHasBitsBase(int index_base) {
 }
 }
 
 
 void FieldGenerator::SetOneofIndexBase(int index_base) {
 void FieldGenerator::SetOneofIndexBase(int index_base) {
-  if (descriptor_->containing_oneof() != NULL) {
-    int index = descriptor_->containing_oneof()->index() + index_base;
+  const OneofDescriptor *oneof = descriptor_->real_containing_oneof();
+  if (oneof != NULL) {
+    int index = oneof->index() + index_base;
     // Flip the sign to mark it as a oneof.
     // Flip the sign to mark it as a oneof.
     variables_["has_index"] = StrCat(-index);
     variables_["has_index"] = StrCat(-index);
   }
   }
@@ -294,7 +295,7 @@ void SingleFieldGenerator::GeneratePropertyImplementation(
 }
 }
 
 
 bool SingleFieldGenerator::RuntimeUsesHasBit(void) const {
 bool SingleFieldGenerator::RuntimeUsesHasBit(void) const {
-  if (descriptor_->containing_oneof() != NULL) {
+  if (descriptor_->real_containing_oneof()) {
     // The oneof tracks what is set instead.
     // The oneof tracks what is set instead.
     return false;
     return false;
   }
   }
@@ -395,7 +396,7 @@ void RepeatedFieldGenerator::GeneratePropertyDeclaration(
 }
 }
 
 
 bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const {
 bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const {
-  return false;  // The array having anything is what is used.
+  return false;  // The array (or map/dict) having anything is what is used.
 }
 }
 
 
 FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,
 FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor,

+ 6 - 5
src/google/protobuf/compiler/objectivec/objectivec_message.cc

@@ -185,7 +185,7 @@ MessageGenerator::MessageGenerator(const string& root_classname,
         new ExtensionGenerator(class_name_, descriptor_->extension(i)));
         new ExtensionGenerator(class_name_, descriptor_->extension(i)));
   }
   }
 
 
-  for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
+  for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
     OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i));
     OneofGenerator* generator = new OneofGenerator(descriptor_->oneof_decl(i));
     oneof_generators_.emplace_back(generator);
     oneof_generators_.emplace_back(generator);
   }
   }
@@ -339,11 +339,12 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) {
       "deprecated_attribute", deprecated_attribute_,
       "deprecated_attribute", deprecated_attribute_,
       "comments", message_comments);
       "comments", message_comments);
 
 
-  std::vector<char> seen_oneofs(descriptor_->oneof_decl_count(), 0);
+  std::vector<char> seen_oneofs(oneof_generators_.size(), 0);
   for (int i = 0; i < descriptor_->field_count(); i++) {
   for (int i = 0; i < descriptor_->field_count(); i++) {
     const FieldDescriptor* field = descriptor_->field(i);
     const FieldDescriptor* field = descriptor_->field(i);
-    if (field->containing_oneof() != NULL) {
-      const int oneof_index = field->containing_oneof()->index();
+    const OneofDescriptor *oneof = field->real_containing_oneof();
+    if (oneof) {
+      const int oneof_index = oneof->index();
       if (!seen_oneofs[oneof_index]) {
       if (!seen_oneofs[oneof_index]) {
         seen_oneofs[oneof_index] = 1;
         seen_oneofs[oneof_index] = 1;
         oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
         oneof_generators_[oneof_index]->GeneratePublicCasePropertyDeclaration(
@@ -443,7 +444,7 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
     field_generators_.SetOneofIndexBase(sizeof_has_storage);
     field_generators_.SetOneofIndexBase(sizeof_has_storage);
     // sizeof_has_storage needs enough bits for the single fields that aren't in
     // sizeof_has_storage needs enough bits for the single fields that aren't in
     // any oneof, and then one int32 for each oneof (to store the field number).
     // any oneof, and then one int32 for each oneof (to store the field number).
-    sizeof_has_storage += descriptor_->oneof_decl_count();
+    sizeof_has_storage += oneof_generators_.size();
 
 
     printer->Print(
     printer->Print(
         "\n"
         "\n"

+ 1 - 1
src/google/protobuf/compiler/objectivec/objectivec_oneof.cc

@@ -120,7 +120,7 @@ void OneofGenerator::GenerateClearFunctionImplementation(io::Printer* printer) {
   printer->Print(
   printer->Print(
       variables_,
       variables_,
       "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n"
       "void $owning_message_class$_Clear$capitalized_name$OneOfCase($owning_message_class$ *message) {\n"
-      "  GPBDescriptor *descriptor = [message descriptor];\n"
+      "  GPBDescriptor *descriptor = [$owning_message_class$ descriptor];\n"
       "  GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n"
       "  GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:$raw_index$];\n"
       "  GPBMaybeClearOneof(message, oneof, $index$, 0);\n"
       "  GPBMaybeClearOneof(message, oneof, $index$, 0);\n"
       "}\n");
       "}\n");