size_t WireFormat::FieldByteSize(const FieldDescriptor* field,
                                 const Message& message) {
  const Reflection* message_reflection = message.GetReflection();

  if (field->is_extension() &&
      field->containing_type()->options().message_set_wire_format() &&
      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
      !field->is_repeated()) {
    return MessageSetItemByteSize(field, message);
  }

  size_t count = 0;
  if (field->is_repeated()) {
    if (field->is_map()) {
      const MapFieldBase* map_field =
          message_reflection->GetMapData(message, field);
      if (map_field->IsMapValid()) {
        count = FromIntSize(map_field->size());
      } else {
        count = FromIntSize(message_reflection->FieldSize(message, field));
      }
    } else {
      count = FromIntSize(message_reflection->FieldSize(message, field));
    }
  } else if (field->containing_type()->options().map_entry()) {
    // Map entry fields always need to be serialized.
    count = 1;
  } else if (message_reflection->HasField(message, field)) {
    count = 1;
  }

  const size_t data_size = FieldDataOnlyByteSize(field, message);
  size_t our_size = data_size;
  if (field->is_packed()) {
    if (data_size > 0) {
      // Packed fields get serialized like a string, not their native type.
      // Technically this doesn't really matter; the size only changes if it's
      // a GROUP
      our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
      our_size += io::CodedOutputStream::VarintSize32(data_size);
    }
  } else {
    our_size += count * TagSize(field->number(), field->type());
  }
  return our_size;
}
size_t WireFormat::FieldByteSize(const FieldDescriptor* field,
                                 const Message& message) {
  const Reflection* message_reflection = message.GetReflection();

  if (field->is_extension() &&
      field->containing_type()->options().message_set_wire_format() &&
      field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
      !field->is_repeated()) {
    return MessageSetItemByteSize(field, message);
  }

  size_t count = 0;
  if (field->is_repeated()) {
    if (field->is_map()) {
      const MapFieldBase* map_field =
          message_reflection->GetMapData(message, field);
      if (map_field->IsMapValid()) {
        count = FromIntSize(map_field->size());
      } else {
        count = FromIntSize(message_reflection->FieldSize(message, field));
      }
    } else {
      count = FromIntSize(message_reflection->FieldSize(message, field));
    }
  } else if (field->containing_type()->options().map_entry()) {
     
    count = 1;
  } else if (message_reflection->HasField(message, field)) {
    count = 1;
  }

  const size_t data_size = FieldDataOnlyByteSize(field, message);
  size_t our_size = data_size;
  if (field->is_packed()) {
    if (data_size > 0) {
       
       
       
      our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
      our_size += io::CodedOutputStream::VarintSize32(data_size);
    }
  } else {
    our_size += count * TagSize(field->number(), field->type());
  }
  return our_size;
}