Browse Source

Merge branch 'master' into conformance-build

Joshua Haberman 6 years ago
parent
commit
0acd543dc4
43 changed files with 1275 additions and 1495 deletions
  1. 13 4
      java/core/src/main/java/com/google/protobuf/Descriptors.java
  2. 0 1
      js/binary/decoder_test.js
  3. 4 1
      python/google/protobuf/descriptor_pool.py
  4. 13 1
      python/google/protobuf/internal/well_known_types.py
  5. 3 2
      ruby/ext/google/protobuf_c/map.c
  6. 3 20
      ruby/ext/google/protobuf_c/message.c
  7. 0 3
      ruby/ext/google/protobuf_c/protobuf.h
  8. 3 2
      ruby/ext/google/protobuf_c/repeated_field.c
  9. 8 0
      ruby/lib/google/protobuf.rb
  10. 1 1
      src/google/protobuf/any.pb.cc
  11. 1 1
      src/google/protobuf/api.pb.cc
  12. 2 1
      src/google/protobuf/compiler/cpp/cpp_file.cc
  13. 1 1
      src/google/protobuf/compiler/cpp/cpp_message.cc
  14. 3 1
      src/google/protobuf/compiler/java/java_message_lite.cc
  15. 1 1
      src/google/protobuf/compiler/plugin.pb.cc
  16. 174 132
      src/google/protobuf/descriptor.cc
  17. 81 62
      src/google/protobuf/descriptor.h
  18. 1 1
      src/google/protobuf/descriptor.pb.cc
  19. 2 0
      src/google/protobuf/descriptor.proto
  20. 252 195
      src/google/protobuf/descriptor_unittest.cc
  21. 1 1
      src/google/protobuf/duration.pb.cc
  22. 9 10
      src/google/protobuf/dynamic_message.cc
  23. 1 1
      src/google/protobuf/empty.pb.cc
  24. 1 1
      src/google/protobuf/field_mask.pb.cc
  25. 203 210
      src/google/protobuf/generated_message_reflection.cc
  26. 5 401
      src/google/protobuf/generated_message_reflection.h
  27. 0 1
      src/google/protobuf/map_entry.h
  28. 1 1
      src/google/protobuf/map_field.h
  29. 1 79
      src/google/protobuf/message.cc
  30. 326 268
      src/google/protobuf/message.h
  31. 4 6
      src/google/protobuf/message_unittest.inc
  32. 33 21
      src/google/protobuf/repeated_field.h
  33. 68 2
      src/google/protobuf/repeated_field_unittest.cc
  34. 1 1
      src/google/protobuf/source_context.pb.cc
  35. 1 1
      src/google/protobuf/struct.pb.cc
  36. 47 51
      src/google/protobuf/text_format.cc
  37. 2 2
      src/google/protobuf/text_format_unittest.cc
  38. 1 1
      src/google/protobuf/timestamp.pb.cc
  39. 1 1
      src/google/protobuf/type.pb.cc
  40. 0 4
      src/google/protobuf/util/internal/json_stream_parser.h
  41. 1 1
      src/google/protobuf/util/message_differencer.cc
  42. 1 1
      src/google/protobuf/wrappers.pb.cc
  43. 1 0
      update_version.py

+ 13 - 4
java/core/src/main/java/com/google/protobuf/Descriptors.java

@@ -2119,11 +2119,12 @@ public final class Descriptors {
   /**
   /**
    * All descriptors implement this to make it easier to implement tools like {@code
    * All descriptors implement this to make it easier to implement tools like {@code
    * DescriptorPool}.
    * DescriptorPool}.
-   *
-   * <p>This class is public so that the methods it exposes can be called from outside of this
-   * package. However, it should only be subclassed from nested classes of Descriptors.
    */
    */
   public abstract static class GenericDescriptor {
   public abstract static class GenericDescriptor {
+
+    // Private constructor to prevent subclasses outside of com.google.protobuf.Descriptors
+    private GenericDescriptor() {}
+
     public abstract Message toProto();
     public abstract Message toProto();
 
 
     public abstract String getName();
     public abstract String getName();
@@ -2593,20 +2594,23 @@ public final class Descriptors {
   }
   }
 
 
   /** Describes an oneof of a message type. */
   /** Describes an oneof of a message type. */
-  public static final class OneofDescriptor {
+  public static final class OneofDescriptor extends GenericDescriptor {
     /** Get the index of this descriptor within its parent. */
     /** Get the index of this descriptor within its parent. */
     public int getIndex() {
     public int getIndex() {
       return index;
       return index;
     }
     }
 
 
+    @Override
     public String getName() {
     public String getName() {
       return proto.getName();
       return proto.getName();
     }
     }
 
 
+    @Override
     public FileDescriptor getFile() {
     public FileDescriptor getFile() {
       return file;
       return file;
     }
     }
 
 
+    @Override
     public String getFullName() {
     public String getFullName() {
       return fullName;
       return fullName;
     }
     }
@@ -2632,6 +2636,11 @@ public final class Descriptors {
       return fields[index];
       return fields[index];
     }
     }
 
 
+    @Override
+    public OneofDescriptorProto toProto() {
+      return proto;
+    }
+
     private void setProto(final OneofDescriptorProto proto) {
     private void setProto(final OneofDescriptorProto proto) {
       this.proto = proto;
       this.proto = proto;
     }
     }

+ 0 - 1
js/binary/decoder_test.js

@@ -255,7 +255,6 @@ describe('binaryDecoderTest', function() {
 
 
   /**
   /**
    * Verifies that misuse of the decoder class triggers assertions.
    * Verifies that misuse of the decoder class triggers assertions.
-   * @suppress {checkTypes|visibility}
    */
    */
   it('testDecodeErrors', function() {
   it('testDecodeErrors', function() {
     // Reading a value past the end of the stream should trigger an assertion.
     // Reading a value past the end of the stream should trigger an assertion.

+ 4 - 1
python/google/protobuf/descriptor_pool.py

@@ -164,7 +164,10 @@ class DescriptorPool(object):
           warn_msg = ('Conflict register for file "' + file_name +
           warn_msg = ('Conflict register for file "' + file_name +
                       '": ' + desc_name +
                       '": ' + desc_name +
                       ' is already defined in file "' +
                       ' is already defined in file "' +
-                      old_file + '"')
+                      old_file + '". Please fix the conflict by adding '
+                      'package name on the proto file, or use different '
+                      'name for the duplication. This warning will '
+                      'turn into error soon.')
           if isinstance(desc, descriptor.EnumValueDescriptor):
           if isinstance(desc, descriptor.EnumValueDescriptor):
             warn_msg += ('\nNote: enum values appear as '
             warn_msg += ('\nNote: enum values appear as '
                          'siblings of the enum type instead of '
                          'siblings of the enum type instead of '

+ 13 - 1
python/google/protobuf/internal/well_known_types.py

@@ -67,6 +67,8 @@ _DURATION_SECONDS_MAX = 315576000000
 class Any(object):
 class Any(object):
   """Class for Any Message type."""
   """Class for Any Message type."""
 
 
+  __slots__ = ()
+
   def Pack(self, msg, type_url_prefix='type.googleapis.com/',
   def Pack(self, msg, type_url_prefix='type.googleapis.com/',
            deterministic=None):
            deterministic=None):
     """Packs the specified message into current Any message."""
     """Packs the specified message into current Any message."""
@@ -100,6 +102,8 @@ _EPOCH_DATETIME = datetime.utcfromtimestamp(0)
 class Timestamp(object):
 class Timestamp(object):
   """Class for Timestamp message type."""
   """Class for Timestamp message type."""
 
 
+  __slots__ = ()
+
   def ToJsonString(self):
   def ToJsonString(self):
     """Converts Timestamp to RFC 3339 date string format.
     """Converts Timestamp to RFC 3339 date string format.
 
 
@@ -250,6 +254,8 @@ class Timestamp(object):
 class Duration(object):
 class Duration(object):
   """Class for Duration message type."""
   """Class for Duration message type."""
 
 
+  __slots__ = ()
+
   def ToJsonString(self):
   def ToJsonString(self):
     """Converts Duration to string format.
     """Converts Duration to string format.
 
 
@@ -407,6 +413,8 @@ def _RoundTowardZero(value, divider):
 class FieldMask(object):
 class FieldMask(object):
   """Class for FieldMask message type."""
   """Class for FieldMask message type."""
 
 
+  __slots__ = ()
+
   def ToJsonString(self):
   def ToJsonString(self):
     """Converts FieldMask to string according to proto3 JSON spec."""
     """Converts FieldMask to string according to proto3 JSON spec."""
     camelcase_paths = []
     camelcase_paths = []
@@ -563,6 +571,8 @@ class _FieldMaskTree(object):
   In the tree, each leaf node represents a field path.
   In the tree, each leaf node represents a field path.
   """
   """
 
 
+  __slots__ = ('_root',)
+
   def __init__(self, field_mask=None):
   def __init__(self, field_mask=None):
     """Initializes the tree by FieldMask."""
     """Initializes the tree by FieldMask."""
     self._root = {}
     self._root = {}
@@ -743,7 +753,7 @@ def _GetStructValue(struct_value):
 class Struct(object):
 class Struct(object):
   """Class for Struct message type."""
   """Class for Struct message type."""
 
 
-  __slots__ = []
+  __slots__ = ()
 
 
   def __getitem__(self, key):
   def __getitem__(self, key):
     return _GetStructValue(self.fields[key])
     return _GetStructValue(self.fields[key])
@@ -796,6 +806,8 @@ collections_abc.MutableMapping.register(Struct)
 class ListValue(object):
 class ListValue(object):
   """Class for ListValue message type."""
   """Class for ListValue message type."""
 
 
+  __slots__ = ()
+
   def __len__(self):
   def __len__(self):
     return len(self.values)
     return len(self.values)
 
 

+ 3 - 2
ruby/ext/google/protobuf_c/map.c

@@ -538,8 +538,8 @@ VALUE Map_dup(VALUE _self) {
   return new_map;
   return new_map;
 }
 }
 
 
-// Used by Google::Protobuf.deep_copy but not exposed directly.
-VALUE Map_deep_copy(VALUE _self) {
+/* :nodoc: */
+static VALUE Map_deep_copy(VALUE _self) {
   Map* self = ruby_to_Map(_self);
   Map* self = ruby_to_Map(_self);
   VALUE new_map = Map_new_this_type(_self);
   VALUE new_map = Map_new_this_type(_self);
   Map* new_self = ruby_to_Map(new_map);
   Map* new_self = ruby_to_Map(new_map);
@@ -851,5 +851,6 @@ void Map_register(VALUE module) {
   rb_define_method(klass, "to_h", Map_to_h, 0);
   rb_define_method(klass, "to_h", Map_to_h, 0);
   rb_define_method(klass, "inspect", Map_inspect, 0);
   rb_define_method(klass, "inspect", Map_inspect, 0);
   rb_define_method(klass, "merge", Map_merge, 1);
   rb_define_method(klass, "merge", Map_merge, 1);
+  rb_define_method(klass, "deep_copy", Map_deep_copy, 0);
   rb_include_module(klass, rb_mEnumerable);
   rb_include_module(klass, rb_mEnumerable);
 }
 }

+ 3 - 20
ruby/ext/google/protobuf_c/message.c

@@ -511,8 +511,8 @@ VALUE Message_dup(VALUE _self) {
   return new_msg;
   return new_msg;
 }
 }
 
 
-// Internal only; used by Google::Protobuf.deep_copy.
-VALUE Message_deep_copy(VALUE _self) {
+/* :nodoc: */
+static VALUE Message_deep_copy(VALUE _self) {
   MessageHeader* self;
   MessageHeader* self;
   MessageHeader* new_msg_self;
   MessageHeader* new_msg_self;
   VALUE new_msg;
   VALUE new_msg;
@@ -742,6 +742,7 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
   rb_define_method(klass, "to_s", Message_inspect, 0);
   rb_define_method(klass, "to_s", Message_inspect, 0);
   rb_define_method(klass, "[]", Message_index, 1);
   rb_define_method(klass, "[]", Message_index, 1);
   rb_define_method(klass, "[]=", Message_index_set, 2);
   rb_define_method(klass, "[]=", Message_index_set, 2);
+  rb_define_method(klass, "deep_copy", Message_deep_copy, 0);
   rb_define_singleton_method(klass, "decode", Message_decode, 1);
   rb_define_singleton_method(klass, "decode", Message_decode, 1);
   rb_define_singleton_method(klass, "encode", Message_encode, 1);
   rb_define_singleton_method(klass, "encode", Message_encode, 1);
   rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
   rb_define_singleton_method(klass, "decode_json", Message_decode_json, -1);
@@ -829,21 +830,3 @@ VALUE build_module_from_enumdesc(EnumDescriptor* enumdesc) {
 
 
   return mod;
   return mod;
 }
 }
-
-/*
- * call-seq:
- *     Google::Protobuf.deep_copy(obj) => copy_of_obj
- *
- * Performs a deep copy of a RepeatedField instance, a Map instance, or a
- * message object, recursively copying its members.
- */
-VALUE Google_Protobuf_deep_copy(VALUE self, VALUE obj) {
-  VALUE klass = CLASS_OF(obj);
-  if (klass == cRepeatedField) {
-    return RepeatedField_deep_copy(obj);
-  } else if (klass == cMap) {
-    return Map_deep_copy(obj);
-  } else {
-    return Message_deep_copy(obj);
-  }
-}

+ 0 - 3
ruby/ext/google/protobuf_c/protobuf.h

@@ -425,7 +425,6 @@ VALUE RepeatedField_replace(VALUE _self, VALUE list);
 VALUE RepeatedField_clear(VALUE _self);
 VALUE RepeatedField_clear(VALUE _self);
 VALUE RepeatedField_length(VALUE _self);
 VALUE RepeatedField_length(VALUE _self);
 VALUE RepeatedField_dup(VALUE _self);
 VALUE RepeatedField_dup(VALUE _self);
-VALUE RepeatedField_deep_copy(VALUE _self);
 VALUE RepeatedField_to_ary(VALUE _self);
 VALUE RepeatedField_to_ary(VALUE _self);
 VALUE RepeatedField_eq(VALUE _self, VALUE _other);
 VALUE RepeatedField_eq(VALUE _self, VALUE _other);
 VALUE RepeatedField_hash(VALUE _self);
 VALUE RepeatedField_hash(VALUE _self);
@@ -469,7 +468,6 @@ VALUE Map_delete(VALUE _self, VALUE key);
 VALUE Map_clear(VALUE _self);
 VALUE Map_clear(VALUE _self);
 VALUE Map_length(VALUE _self);
 VALUE Map_length(VALUE _self);
 VALUE Map_dup(VALUE _self);
 VALUE Map_dup(VALUE _self);
-VALUE Map_deep_copy(VALUE _self);
 VALUE Map_eq(VALUE _self, VALUE _other);
 VALUE Map_eq(VALUE _self, VALUE _other);
 VALUE Map_hash(VALUE _self);
 VALUE Map_hash(VALUE _self);
 VALUE Map_to_h(VALUE _self);
 VALUE Map_to_h(VALUE _self);
@@ -564,7 +562,6 @@ VALUE Message_alloc(VALUE klass);
 VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self);
 VALUE Message_method_missing(int argc, VALUE* argv, VALUE _self);
 VALUE Message_initialize(int argc, VALUE* argv, VALUE _self);
 VALUE Message_initialize(int argc, VALUE* argv, VALUE _self);
 VALUE Message_dup(VALUE _self);
 VALUE Message_dup(VALUE _self);
-VALUE Message_deep_copy(VALUE _self);
 VALUE Message_eq(VALUE _self, VALUE _other);
 VALUE Message_eq(VALUE _self, VALUE _other);
 VALUE Message_hash(VALUE _self);
 VALUE Message_hash(VALUE _self);
 VALUE Message_inspect(VALUE _self);
 VALUE Message_inspect(VALUE _self);

+ 3 - 2
ruby/ext/google/protobuf_c/repeated_field.c

@@ -355,8 +355,8 @@ VALUE RepeatedField_dup(VALUE _self) {
   return new_rptfield;
   return new_rptfield;
 }
 }
 
 
-// Internal only: used by Google::Protobuf.deep_copy.
-VALUE RepeatedField_deep_copy(VALUE _self) {
+/* :nodoc: */
+static VALUE RepeatedField_deep_copy(VALUE _self) {
   RepeatedField* self = ruby_to_RepeatedField(_self);
   RepeatedField* self = ruby_to_RepeatedField(_self);
   VALUE new_rptfield = RepeatedField_new_this_type(_self);
   VALUE new_rptfield = RepeatedField_new_this_type(_self);
   RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
   RepeatedField* new_rptfield_self = ruby_to_RepeatedField(new_rptfield);
@@ -656,5 +656,6 @@ void RepeatedField_register(VALUE module) {
   rb_define_method(klass, "hash", RepeatedField_hash, 0);
   rb_define_method(klass, "hash", RepeatedField_hash, 0);
   rb_define_method(klass, "+", RepeatedField_plus, 1);
   rb_define_method(klass, "+", RepeatedField_plus, 1);
   rb_define_method(klass, "concat", RepeatedField_concat, 1);
   rb_define_method(klass, "concat", RepeatedField_concat, 1);
+  rb_define_method(klass, "deep_copy", RepeatedField_deep_copy, 0);
   rb_include_module(klass, rb_mEnumerable);
   rb_include_module(klass, rb_mEnumerable);
 }
 }

+ 8 - 0
ruby/lib/google/protobuf.rb

@@ -73,5 +73,13 @@ module Google
       klass.decode_json(json, options)
       klass.decode_json(json, options)
     end
     end
 
 
+    # call-seq:
+    #     Google::Protobuf.deep_copy(obj) => copy_of_obj
+    #
+    # Performs a deep copy of a RepeatedField instance, a Map instance, or a
+    # message object, recursively copying its members.
+    def self.deep_copy(obj)
+      obj.deep_copy
+    end
   end
   end
 end
 end

+ 1 - 1
src/google/protobuf/any.pb.cc

@@ -56,7 +56,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Any_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Any_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2fany_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\031google/protobuf/any.proto\022\017google.prot"
   "\n\031google/protobuf/any.proto\022\017google.prot"
   "obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002"
   "obuf\"&\n\003Any\022\020\n\010type_url\030\001 \001(\t\022\r\n\005value\030\002"
   " \001(\014Bo\n\023com.google.protobufB\010AnyProtoP\001Z"
   " \001(\014Bo\n\023com.google.protobufB\010AnyProtoP\001Z"

+ 1 - 1
src/google/protobuf/api.pb.cc

@@ -129,7 +129,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Mixin_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Mixin_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2fapi_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\031google/protobuf/api.proto\022\017google.prot"
   "\n\031google/protobuf/api.proto\022\017google.prot"
   "obuf\032$google/protobuf/source_context.pro"
   "obuf\032$google/protobuf/source_context.pro"
   "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014"
   "to\032\032google/protobuf/type.proto\"\201\002\n\003Api\022\014"

+ 2 - 1
src/google/protobuf/compiler/cpp/cpp_file.cc

@@ -812,7 +812,8 @@ void FileGenerator::GenerateReflectionInitializationCode(io::Printer* printer) {
   // built into real descriptors at initialization time.
   // built into real descriptors at initialization time.
   const std::string protodef_name =
   const std::string protodef_name =
       UniqueName("descriptor_table_protodef", file_, options_);
       UniqueName("descriptor_table_protodef", file_, options_);
-  format("const char $1$[] =\n", protodef_name);
+  format("const char $1$[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =\n",
+         protodef_name);
   format.Indent();
   format.Indent();
   FileDescriptorProto file_proto;
   FileDescriptorProto file_proto;
   file_->CopyTo(&file_proto);
   file_->CopyTo(&file_proto);

+ 1 - 1
src/google/protobuf/compiler/cpp/cpp_message.cc

@@ -1535,7 +1535,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
   format.Outdent();
   format.Outdent();
   format("};");
   format("};");
   GOOGLE_DCHECK(!need_to_emit_cached_size);
   GOOGLE_DCHECK(!need_to_emit_cached_size);
-}
+}  // NOLINT(readability/fn_size)
 
 
 void MessageGenerator::GenerateInlineMethods(io::Printer* printer) {
 void MessageGenerator::GenerateInlineMethods(io::Printer* printer) {
   if (IsMapEntryMessage(descriptor_)) return;
   if (IsMapEntryMessage(descriptor_)) return;

+ 3 - 1
src/google/protobuf/compiler/java/java_message_lite.cc

@@ -367,7 +367,9 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
       "    synchronized ($classname$.class) {\n"
       "    synchronized ($classname$.class) {\n"
       "      parser = PARSER;\n"
       "      parser = PARSER;\n"
       "      if (parser == null) {\n"
       "      if (parser == null) {\n"
-      "        parser = new DefaultInstanceBasedParser(DEFAULT_INSTANCE);\n"
+      "        parser =\n"
+      "            new DefaultInstanceBasedParser<$classname$>(\n"
+      "                DEFAULT_INSTANCE);\n"
       "        PARSER = parser;\n"
       "        PARSER = parser;\n"
       "      }\n"
       "      }\n"
       "    }\n"
       "    }\n"

+ 1 - 1
src/google/protobuf/compiler/plugin.pb.cc

@@ -163,7 +163,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::compiler::_CodeGeneratorResponse_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2fcompiler_2fplugin_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n%google/protobuf/compiler/plugin.proto\022"
   "\n%google/protobuf/compiler/plugin.proto\022"
   "\030google.protobuf.compiler\032 google/protob"
   "\030google.protobuf.compiler\032 google/protob"
   "uf/descriptor.proto\"F\n\007Version\022\r\n\005major\030"
   "uf/descriptor.proto\"F\n\007Version\022\r\n\005major\030"

File diff suppressed because it is too large
+ 174 - 132
src/google/protobuf/descriptor.cc


+ 81 - 62
src/google/protobuf/descriptor.h

@@ -113,6 +113,7 @@ class SourceCodeInfo;
 
 
 // Defined in message.h
 // Defined in message.h
 class Message;
 class Message;
+class Reflection;
 
 
 // Defined in descriptor.cc
 // Defined in descriptor.cc
 class DescriptorBuilder;
 class DescriptorBuilder;
@@ -122,11 +123,6 @@ struct Symbol;
 // Defined in unknown_field_set.h.
 // Defined in unknown_field_set.h.
 class UnknownField;
 class UnknownField;
 
 
-// Defined in generated_message_reflection.h.
-namespace internal {
-class GeneratedMessageReflection;
-}  // namespace internal
-
 // Defined in command_line_interface.cc
 // Defined in command_line_interface.cc
 namespace compiler {
 namespace compiler {
 class CommandLineInterface;
 class CommandLineInterface;
@@ -188,10 +184,10 @@ class PROTOBUF_EXPORT LazyDescriptor {
   // Init function to be called at init time of a descriptor containing
   // Init function to be called at init time of a descriptor containing
   // a LazyDescriptor.
   // a LazyDescriptor.
   void Init() {
   void Init() {
-    descriptor_ = NULL;
-    name_ = NULL;
-    once_ = NULL;
-    file_ = NULL;
+    descriptor_ = nullptr;
+    name_ = nullptr;
+    once_ = nullptr;
+    file_ = nullptr;
   }
   }
 
 
   // Sets the value of the descriptor if it is known during the descriptor
   // Sets the value of the descriptor if it is known during the descriptor
@@ -250,11 +246,11 @@ class PROTOBUF_EXPORT Descriptor {
   // type array.
   // type array.
   int index() const;
   int index() const;
 
 
-  // The .proto file in which this message type was defined.  Never NULL.
+  // The .proto file in which this message type was defined.  Never nullptr.
   const FileDescriptor* file() const;
   const FileDescriptor* file() const;
 
 
   // If this Descriptor describes a nested type, this returns the type
   // If this Descriptor describes a nested type, this returns the type
-  // in which it is nested.  Otherwise, returns NULL.
+  // in which it is nested.  Otherwise, returns nullptr.
   const Descriptor* containing_type() const;
   const Descriptor* containing_type() const;
 
 
   // Get options for this message type.  These are specified in the .proto file
   // Get options for this message type.  These are specified in the .proto file
@@ -289,10 +285,10 @@ class PROTOBUF_EXPORT Descriptor {
   // These are returned in the order they were defined in the .proto file.
   // These are returned in the order they were defined in the .proto file.
   const FieldDescriptor* field(int index) const;
   const FieldDescriptor* field(int index) const;
 
 
-  // Looks up a field by declared tag number.  Returns NULL if no such field
+  // Looks up a field by declared tag number.  Returns nullptr if no such field
   // exists.
   // exists.
   const FieldDescriptor* FindFieldByNumber(int number) const;
   const FieldDescriptor* FindFieldByNumber(int number) const;
-  // Looks up a field by name.  Returns NULL if no such field exists.
+  // Looks up a field by name.  Returns nullptr if no such field exists.
   const FieldDescriptor* FindFieldByName(const std::string& name) const;
   const FieldDescriptor* FindFieldByName(const std::string& name) const;
 
 
   // Looks up a field by lowercased name (as returned by lowercase_name()).
   // Looks up a field by lowercased name (as returned by lowercase_name()).
@@ -314,7 +310,7 @@ class PROTOBUF_EXPORT Descriptor {
   // These are returned in the order they were defined in the .proto file.
   // These are returned in the order they were defined in the .proto file.
   const OneofDescriptor* oneof_decl(int index) const;
   const OneofDescriptor* oneof_decl(int index) const;
 
 
-  // Looks up a oneof by name.  Returns NULL if no such oneof exists.
+  // Looks up a oneof by name.  Returns nullptr if no such oneof exists.
   const OneofDescriptor* FindOneofByName(const std::string& name) const;
   const OneofDescriptor* FindOneofByName(const std::string& name) const;
 
 
   // Nested type stuff -----------------------------------------------
   // Nested type stuff -----------------------------------------------
@@ -325,7 +321,7 @@ class PROTOBUF_EXPORT Descriptor {
   // These are returned in the order they were defined in the .proto file.
   // These are returned in the order they were defined in the .proto file.
   const Descriptor* nested_type(int index) const;
   const Descriptor* nested_type(int index) const;
 
 
-  // Looks up a nested type by name.  Returns NULL if no such nested type
+  // Looks up a nested type by name.  Returns nullptr if no such nested type
   // exists.
   // exists.
   const Descriptor* FindNestedTypeByName(const std::string& name) const;
   const Descriptor* FindNestedTypeByName(const std::string& name) const;
 
 
@@ -337,11 +333,12 @@ class PROTOBUF_EXPORT Descriptor {
   // These are returned in the order they were defined in the .proto file.
   // These are returned in the order they were defined in the .proto file.
   const EnumDescriptor* enum_type(int index) const;
   const EnumDescriptor* enum_type(int index) const;
 
 
-  // Looks up an enum type by name.  Returns NULL if no such enum type exists.
+  // Looks up an enum type by name.  Returns nullptr if no such enum type
+  // exists.
   const EnumDescriptor* FindEnumTypeByName(const std::string& name) const;
   const EnumDescriptor* FindEnumTypeByName(const std::string& name) const;
 
 
   // Looks up an enum value by name, among all enum types in this message.
   // Looks up an enum value by name, among all enum types in this message.
-  // Returns NULL if no such value exists.
+  // Returns nullptr if no such value exists.
   const EnumValueDescriptor* FindEnumValueByName(const std::string& name) const;
   const EnumValueDescriptor* FindEnumValueByName(const std::string& name) const;
 
 
   // Extensions ------------------------------------------------------
   // Extensions ------------------------------------------------------
@@ -372,7 +369,7 @@ class PROTOBUF_EXPORT Descriptor {
   // Returns true if the number is in one of the extension ranges.
   // Returns true if the number is in one of the extension ranges.
   bool IsExtensionNumber(int number) const;
   bool IsExtensionNumber(int number) const;
 
 
-  // Returns NULL if no extension range contains the given number.
+  // Returns nullptr if no extension range contains the given number.
   const ExtensionRange* FindExtensionRangeContainingNumber(int number) const;
   const ExtensionRange* FindExtensionRangeContainingNumber(int number) const;
 
 
   // The number of extensions -- extending *other* messages -- that were
   // The number of extensions -- extending *other* messages -- that were
@@ -414,7 +411,7 @@ class PROTOBUF_EXPORT Descriptor {
   // Returns true if the number is in one of the reserved ranges.
   // Returns true if the number is in one of the reserved ranges.
   bool IsReservedNumber(int number) const;
   bool IsReservedNumber(int number) const;
 
 
-  // Returns NULL if no reserved range contains the given number.
+  // Returns nullptr if no reserved range contains the given number.
   const ReservedRange* FindReservedRangeContainingNumber(int number) const;
   const ReservedRange* FindReservedRangeContainingNumber(int number) const;
 
 
   // The number of reserved field names in this message type.
   // The number of reserved field names in this message type.
@@ -512,10 +509,8 @@ class PROTOBUF_EXPORT Descriptor {
 // - Get the Descriptor or FileDescriptor for its containing scope, then
 // - Get the Descriptor or FileDescriptor for its containing scope, then
 //   call Descriptor::FindExtensionByName() or
 //   call Descriptor::FindExtensionByName() or
 //   FileDescriptor::FindExtensionByName().
 //   FileDescriptor::FindExtensionByName().
-// - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber().
-// - Given a Reflection for a message object, call
-//   Reflection::FindKnownExtensionByName() or
-//   Reflection::FindKnownExtensionByNumber().
+// - Given a DescriptorPool, call DescriptorPool::FindExtensionByNumber() or
+//   DescriptorPool::FindExtensionByPrintableName().
 // Use DescriptorPool to construct your own descriptors.
 // Use DescriptorPool to construct your own descriptors.
 class PROTOBUF_EXPORT FieldDescriptor {
 class PROTOBUF_EXPORT FieldDescriptor {
  public:
  public:
@@ -669,18 +664,18 @@ class PROTOBUF_EXPORT FieldDescriptor {
   // Get the field default value if cpp_type() == CPPTYPE_ENUM.  If no
   // Get the field default value if cpp_type() == CPPTYPE_ENUM.  If no
   // explicit default was defined, the default is the first value defined
   // explicit default was defined, the default is the first value defined
   // in the enum type (all enum types are required to have at least one value).
   // in the enum type (all enum types are required to have at least one value).
-  // This never returns NULL.
+  // This never returns nullptr.
   const EnumValueDescriptor* default_value_enum() const;
   const EnumValueDescriptor* default_value_enum() const;
   // Get the field default value if cpp_type() == CPPTYPE_STRING.  If no
   // Get the field default value if cpp_type() == CPPTYPE_STRING.  If no
   // explicit default was defined, the default is the empty string.
   // explicit default was defined, the default is the empty string.
   const std::string& default_value_string() const;
   const std::string& default_value_string() const;
 
 
   // The Descriptor for the message of which this is a field.  For extensions,
   // The Descriptor for the message of which this is a field.  For extensions,
-  // this is the extended type.  Never NULL.
+  // this is the extended type.  Never nullptr.
   const Descriptor* containing_type() const;
   const Descriptor* containing_type() const;
 
 
   // If the field is a member of a oneof, this is the one, otherwise this is
   // If the field is a member of a oneof, this is the one, otherwise this is
-  // NULL.
+  // nullptr.
   const OneofDescriptor* containing_oneof() const;
   const OneofDescriptor* containing_oneof() const;
 
 
   // If the field is a member of a oneof, returns the index in that oneof.
   // If the field is a member of a oneof, returns the index in that oneof.
@@ -688,7 +683,7 @@ class PROTOBUF_EXPORT FieldDescriptor {
 
 
   // An extension may be declared within the scope of another message.  If this
   // An extension may be declared within the scope of another message.  If this
   // field is an extension (is_extension() is true), then extension_scope()
   // field is an extension (is_extension() is true), then extension_scope()
-  // returns that message, or NULL if the extension was declared at global
+  // returns that message, or nullptr if the extension was declared at global
   // scope.  If this is not an extension, extension_scope() is undefined (may
   // scope.  If this is not an extension, extension_scope() is undefined (may
   // assert-fail).
   // assert-fail).
   const Descriptor* extension_scope() const;
   const Descriptor* extension_scope() const;
@@ -728,6 +723,21 @@ class PROTOBUF_EXPORT FieldDescriptor {
   // Return true iff [packed = true] is valid for fields of this type.
   // Return true iff [packed = true] is valid for fields of this type.
   static inline bool IsTypePackable(Type field_type);
   static inline bool IsTypePackable(Type field_type);
 
 
+  // Returns full_name() except if the field is a MessageSet extension,
+  // in which case it returns the full_name() of the containing message type
+  // for backwards compatibility with proto1.
+  //
+  // A MessageSet extension is defined as an optional message extension
+  // whose containing type has the message_set_wire_format option set.
+  // This should be true of extensions of google.protobuf.bridge.MessageSet;
+  // by convention, such extensions are named "message_set_extension".
+  //
+  // The opposite operation (looking up an extension's FieldDescriptor given
+  // its printable name) can be accomplished with
+  //     message->file()->pool()->FindExtensionByPrintableName(message, name)
+  // where the extension extends "message".
+  const std::string& PrintableNameForExtension() const;
+
   // Source Location ---------------------------------------------------
   // Source Location ---------------------------------------------------
 
 
   // Updates |*out_location| to the source location of the complete
   // Updates |*out_location| to the source location of the complete
@@ -840,7 +850,7 @@ class PROTOBUF_EXPORT OneofDescriptor {
   // Index of this oneof within the message's oneof array.
   // Index of this oneof within the message's oneof array.
   int index() const;
   int index() const;
 
 
-  // The .proto file in which this oneof was defined.  Never NULL.
+  // The .proto file in which this oneof was defined.  Never nullptr.
   const FileDescriptor* file() const;
   const FileDescriptor* file() const;
   // The Descriptor for the message containing this oneof.
   // The Descriptor for the message containing this oneof.
   const Descriptor* containing_type() const;
   const Descriptor* containing_type() const;
@@ -918,7 +928,7 @@ class PROTOBUF_EXPORT EnumDescriptor {
   // Index of this enum within the file or containing message's enum array.
   // Index of this enum within the file or containing message's enum array.
   int index() const;
   int index() const;
 
 
-  // The .proto file in which this enum type was defined.  Never NULL.
+  // The .proto file in which this enum type was defined.  Never nullptr.
   const FileDescriptor* file() const;
   const FileDescriptor* file() const;
 
 
   // The number of values for this EnumDescriptor.  Guaranteed to be greater
   // The number of values for this EnumDescriptor.  Guaranteed to be greater
@@ -928,14 +938,14 @@ class PROTOBUF_EXPORT EnumDescriptor {
   // These are returned in the order they were defined in the .proto file.
   // These are returned in the order they were defined in the .proto file.
   const EnumValueDescriptor* value(int index) const;
   const EnumValueDescriptor* value(int index) const;
 
 
-  // Looks up a value by name.  Returns NULL if no such value exists.
+  // Looks up a value by name.  Returns nullptr if no such value exists.
   const EnumValueDescriptor* FindValueByName(const std::string& name) const;
   const EnumValueDescriptor* FindValueByName(const std::string& name) const;
-  // Looks up a value by number.  Returns NULL if no such value exists.  If
+  // Looks up a value by number.  Returns nullptr if no such value exists.  If
   // multiple values have this number, the first one defined is returned.
   // multiple values have this number, the first one defined is returned.
   const EnumValueDescriptor* FindValueByNumber(int number) const;
   const EnumValueDescriptor* FindValueByNumber(int number) const;
 
 
   // If this enum type is nested in a message type, this is that message type.
   // If this enum type is nested in a message type, this is that message type.
-  // Otherwise, NULL.
+  // Otherwise, nullptr.
   const Descriptor* containing_type() const;
   const Descriptor* containing_type() const;
 
 
   // Get options for this enum type.  These are specified in the .proto file by
   // Get options for this enum type.  These are specified in the .proto file by
@@ -976,7 +986,7 @@ class PROTOBUF_EXPORT EnumDescriptor {
   // Returns true if the number is in one of the reserved ranges.
   // Returns true if the number is in one of the reserved ranges.
   bool IsReservedNumber(int number) const;
   bool IsReservedNumber(int number) const;
 
 
-  // Returns NULL if no reserved range contains the given number.
+  // Returns nullptr if no reserved range contains the given number.
   const EnumDescriptor::ReservedRange* FindReservedRangeContainingNumber(
   const EnumDescriptor::ReservedRange* FindReservedRangeContainingNumber(
       int number) const;
       int number) const;
 
 
@@ -1008,9 +1018,9 @@ class PROTOBUF_EXPORT EnumDescriptor {
   // unknown. If a new descriptor is created, this is done in a thread-safe way,
   // unknown. If a new descriptor is created, this is done in a thread-safe way,
   // and future calls will return the same value descriptor pointer.
   // and future calls will return the same value descriptor pointer.
   //
   //
-  // This is private but is used by GeneratedMessageReflection (which is
-  // friended below) to return a valid EnumValueDescriptor from GetEnum() when
-  // this feature is enabled.
+  // This is private but is used by Reflection (which is friended below) to
+  // return a valid EnumValueDescriptor from GetEnum() when this feature is
+  // enabled.
   const EnumValueDescriptor* FindValueByNumberCreatingIfUnknown(
   const EnumValueDescriptor* FindValueByNumberCreatingIfUnknown(
       int number) const;
       int number) const;
 
 
@@ -1053,7 +1063,7 @@ class PROTOBUF_EXPORT EnumDescriptor {
   friend class EnumValueDescriptor;
   friend class EnumValueDescriptor;
   friend class FileDescriptor;
   friend class FileDescriptor;
   friend class DescriptorPool;
   friend class DescriptorPool;
-  friend class internal::GeneratedMessageReflection;
+  friend class Reflection;
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor);
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumDescriptor);
 };
 };
 
 
@@ -1077,9 +1087,9 @@ class PROTOBUF_EXPORT EnumValueDescriptor {
   // with C++ scoping rules for enums.
   // with C++ scoping rules for enums.
   const std::string& full_name() const;
   const std::string& full_name() const;
 
 
-  // The .proto file in which this value was defined.  Never NULL.
+  // The .proto file in which this value was defined.  Never nullptr.
   const FileDescriptor* file() const;
   const FileDescriptor* file() const;
-  // The type of this value.  Never NULL.
+  // The type of this value.  Never nullptr.
   const EnumDescriptor* type() const;
   const EnumDescriptor* type() const;
 
 
   // Get options for this enum value.  These are specified in the .proto file by
   // Get options for this enum value.  These are specified in the .proto file by
@@ -1150,7 +1160,7 @@ class PROTOBUF_EXPORT ServiceDescriptor {
   // Index of this service within the file's services array.
   // Index of this service within the file's services array.
   int index() const;
   int index() const;
 
 
-  // The .proto file in which this service was defined.  Never NULL.
+  // The .proto file in which this service was defined.  Never nullptr.
   const FileDescriptor* file() const;
   const FileDescriptor* file() const;
 
 
   // Get options for this service type.  These are specified in the .proto file
   // Get options for this service type.  These are specified in the .proto file
@@ -1232,9 +1242,9 @@ class PROTOBUF_EXPORT MethodDescriptor {
   // Index within the service's Descriptor.
   // Index within the service's Descriptor.
   int index() const;
   int index() const;
 
 
-  // The .proto file in which this method was defined.  Never NULL.
+  // The .proto file in which this method was defined.  Never nullptr.
   const FileDescriptor* file() const;
   const FileDescriptor* file() const;
-  // Gets the service to which this method belongs.  Never NULL.
+  // Gets the service to which this method belongs.  Never nullptr.
   const ServiceDescriptor* service() const;
   const ServiceDescriptor* service() const;
 
 
   // Gets the type of protocol message which this method accepts as input.
   // Gets the type of protocol message which this method accepts as input.
@@ -1319,7 +1329,7 @@ class PROTOBUF_EXPORT FileDescriptor {
   const std::string& package() const;
   const std::string& package() const;
 
 
   // The DescriptorPool in which this FileDescriptor and all its contents were
   // The DescriptorPool in which this FileDescriptor and all its contents were
-  // allocated.  Never NULL.
+  // allocated.  Never nullptr.
   const DescriptorPool* pool() const;
   const DescriptorPool* pool() const;
 
 
   // The number of files imported by this one.
   // The number of files imported by this one.
@@ -1386,16 +1396,17 @@ class PROTOBUF_EXPORT FileDescriptor {
   Syntax syntax() const;
   Syntax syntax() const;
   static const char* SyntaxName(Syntax syntax);
   static const char* SyntaxName(Syntax syntax);
 
 
-  // Find a top-level message type by name.  Returns NULL if not found.
+  // Find a top-level message type by name.  Returns nullptr if not found.
   const Descriptor* FindMessageTypeByName(const std::string& name) const;
   const Descriptor* FindMessageTypeByName(const std::string& name) const;
-  // Find a top-level enum type by name.  Returns NULL if not found.
+  // Find a top-level enum type by name.  Returns nullptr if not found.
   const EnumDescriptor* FindEnumTypeByName(const std::string& name) const;
   const EnumDescriptor* FindEnumTypeByName(const std::string& name) const;
-  // Find an enum value defined in any top-level enum by name.  Returns NULL if
-  // not found.
+  // Find an enum value defined in any top-level enum by name.  Returns nullptr
+  // if not found.
   const EnumValueDescriptor* FindEnumValueByName(const std::string& name) const;
   const EnumValueDescriptor* FindEnumValueByName(const std::string& name) const;
-  // Find a service definition by name.  Returns NULL if not found.
+  // Find a service definition by name.  Returns nullptr if not found.
   const ServiceDescriptor* FindServiceByName(const std::string& name) const;
   const ServiceDescriptor* FindServiceByName(const std::string& name) const;
-  // Find a top-level extension definition by name.  Returns NULL if not found.
+  // Find a top-level extension definition by name.  Returns nullptr if not
+  // found.
   const FieldDescriptor* FindExtensionByName(const std::string& name) const;
   const FieldDescriptor* FindExtensionByName(const std::string& name) const;
   // Similar to FindExtensionByName(), but searches by lowercased-name.  See
   // Similar to FindExtensionByName(), but searches by lowercased-name.  See
   // Descriptor::FindFieldByLowercaseName().
   // Descriptor::FindFieldByLowercaseName().
@@ -1555,7 +1566,7 @@ class PROTOBUF_EXPORT DescriptorPool {
   //   in subsequent lookups in the DescriptorPool.
   //   in subsequent lookups in the DescriptorPool.
   class ErrorCollector;
   class ErrorCollector;
   explicit DescriptorPool(DescriptorDatabase* fallback_database,
   explicit DescriptorPool(DescriptorDatabase* fallback_database,
-                          ErrorCollector* error_collector = NULL);
+                          ErrorCollector* error_collector = nullptr);
 
 
   ~DescriptorPool();
   ~DescriptorPool();
 
 
@@ -1565,20 +1576,20 @@ class PROTOBUF_EXPORT DescriptorPool {
   static const DescriptorPool* generated_pool();
   static const DescriptorPool* generated_pool();
 
 
 
 
-  // Find a FileDescriptor in the pool by file name.  Returns NULL if not
+  // Find a FileDescriptor in the pool by file name.  Returns nullptr if not
   // found.
   // found.
   const FileDescriptor* FindFileByName(const std::string& name) const;
   const FileDescriptor* FindFileByName(const std::string& name) const;
 
 
   // Find the FileDescriptor in the pool which defines the given symbol.
   // Find the FileDescriptor in the pool which defines the given symbol.
   // If any of the Find*ByName() methods below would succeed, then this is
   // If any of the Find*ByName() methods below would succeed, then this is
   // equivalent to calling that method and calling the result's file() method.
   // equivalent to calling that method and calling the result's file() method.
-  // Otherwise this returns NULL.
+  // Otherwise this returns nullptr.
   const FileDescriptor* FindFileContainingSymbol(
   const FileDescriptor* FindFileContainingSymbol(
       const std::string& symbol_name) const;
       const std::string& symbol_name) const;
 
 
   // Looking up descriptors ------------------------------------------
   // Looking up descriptors ------------------------------------------
   // These find descriptors by fully-qualified name.  These will find both
   // These find descriptors by fully-qualified name.  These will find both
-  // top-level descriptors and nested descriptors.  They return NULL if not
+  // top-level descriptors and nested descriptors.  They return nullptr if not
   // found.
   // found.
 
 
   const Descriptor* FindMessageTypeByName(const std::string& name) const;
   const Descriptor* FindMessageTypeByName(const std::string& name) const;
@@ -1595,6 +1606,14 @@ class PROTOBUF_EXPORT DescriptorPool {
   const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee,
   const FieldDescriptor* FindExtensionByNumber(const Descriptor* extendee,
                                                int number) const;
                                                int number) const;
 
 
+  // Finds an extension of the given type by its printable name.
+  // See comments above PrintableNameForExtension() for the definition of
+  // "printable name".  The extendee must be a member of this DescriptorPool
+  // or one of its underlays.  Returns nullptr if there is no known message
+  // extension with the given printable name.
+  const FieldDescriptor* FindExtensionByPrintableName(
+      const Descriptor* extendee, const std::string& printable_name) const;
+
   // Finds extensions of extendee. The extensions will be appended to
   // Finds extensions of extendee. The extensions will be appended to
   // out in an undefined order. Only extensions defined directly in
   // out in an undefined order. Only extensions defined directly in
   // this DescriptorPool or one of its underlays are guaranteed to be
   // this DescriptorPool or one of its underlays are guaranteed to be
@@ -1658,7 +1677,7 @@ class PROTOBUF_EXPORT DescriptorPool {
 
 
   // Convert the FileDescriptorProto to real descriptors and place them in
   // Convert the FileDescriptorProto to real descriptors and place them in
   // this DescriptorPool.  All dependencies of the file must already be in
   // this DescriptorPool.  All dependencies of the file must already be in
-  // the pool.  Returns the resulting FileDescriptor, or NULL if there were
+  // the pool.  Returns the resulting FileDescriptor, or nullptr if there were
   // problems with the input (e.g. the message was invalid, or dependencies
   // problems with the input (e.g. the message was invalid, or dependencies
   // were missing).  Details about the errors are written to GOOGLE_LOG(ERROR).
   // were missing).  Details about the errors are written to GOOGLE_LOG(ERROR).
   const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
   const FileDescriptor* BuildFile(const FileDescriptorProto& proto);
@@ -1824,8 +1843,8 @@ class PROTOBUF_EXPORT DescriptorPool {
   Symbol NewPlaceholderWithMutexHeld(const std::string& name,
   Symbol NewPlaceholderWithMutexHeld(const std::string& name,
                                      PlaceholderType placeholder_type) const;
                                      PlaceholderType placeholder_type) const;
 
 
-  // If fallback_database_ is NULL, this is NULL.  Otherwise, this is a mutex
-  // which must be locked while accessing tables_.
+  // If fallback_database_ is nullptr, this is nullptr.  Otherwise, this is a
+  // mutex which must be locked while accessing tables_.
   internal::WrappedMutex* mutex_;
   internal::WrappedMutex* mutex_;
 
 
   // See constructor.
   // See constructor.
@@ -1989,11 +2008,11 @@ PROTOBUF_DEFINE_ARRAY_ACCESSOR(FileDescriptor, extension,
 // A few accessors differ from the macros...
 // A few accessors differ from the macros...
 
 
 inline bool Descriptor::IsExtensionNumber(int number) const {
 inline bool Descriptor::IsExtensionNumber(int number) const {
-  return FindExtensionRangeContainingNumber(number) != NULL;
+  return FindExtensionRangeContainingNumber(number) != nullptr;
 }
 }
 
 
 inline bool Descriptor::IsReservedNumber(int number) const {
 inline bool Descriptor::IsReservedNumber(int number) const {
-  return FindReservedRangeContainingNumber(number) != NULL;
+  return FindReservedRangeContainingNumber(number) != nullptr;
 }
 }
 
 
 inline bool Descriptor::IsReservedName(const std::string& name) const {
 inline bool Descriptor::IsReservedName(const std::string& name) const {
@@ -2012,7 +2031,7 @@ inline const std::string& Descriptor::reserved_name(int index) const {
 }
 }
 
 
 inline bool EnumDescriptor::IsReservedNumber(int number) const {
 inline bool EnumDescriptor::IsReservedNumber(int number) const {
-  return FindReservedRangeContainingNumber(number) != NULL;
+  return FindReservedRangeContainingNumber(number) != nullptr;
 }
 }
 
 
 inline bool EnumDescriptor::IsReservedName(const std::string& name) const {
 inline bool EnumDescriptor::IsReservedName(const std::string& name) const {
@@ -2062,7 +2081,7 @@ inline bool FieldDescriptor::is_map() const {
 inline int FieldDescriptor::index() const {
 inline int FieldDescriptor::index() const {
   if (!is_extension_) {
   if (!is_extension_) {
     return static_cast<int>(this - containing_type()->fields_);
     return static_cast<int>(this - containing_type()->fields_);
-  } else if (extension_scope_ != NULL) {
+  } else if (extension_scope_ != nullptr) {
     return static_cast<int>(this - extension_scope_->extensions_);
     return static_cast<int>(this - extension_scope_->extensions_);
   } else {
   } else {
     return static_cast<int>(this - file_->extensions_);
     return static_cast<int>(this - file_->extensions_);
@@ -2070,7 +2089,7 @@ inline int FieldDescriptor::index() const {
 }
 }
 
 
 inline int Descriptor::index() const {
 inline int Descriptor::index() const {
-  if (containing_type_ == NULL) {
+  if (containing_type_ == nullptr) {
     return static_cast<int>(this - file_->message_types_);
     return static_cast<int>(this - file_->message_types_);
   } else {
   } else {
     return static_cast<int>(this - containing_type_->nested_types_);
     return static_cast<int>(this - containing_type_->nested_types_);
@@ -2086,7 +2105,7 @@ inline int OneofDescriptor::index() const {
 }
 }
 
 
 inline int EnumDescriptor::index() const {
 inline int EnumDescriptor::index() const {
-  if (containing_type_ == NULL) {
+  if (containing_type_ == nullptr) {
     return static_cast<int>(this - file_->enum_types_);
     return static_cast<int>(this - file_->enum_types_);
   } else {
   } else {
     return static_cast<int>(this - containing_type_->enum_types_);
     return static_cast<int>(this - containing_type_->enum_types_);

+ 1 - 1
src/google/protobuf/descriptor.pb.cc

@@ -1012,7 +1012,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_GeneratedCodeInfo_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2fdescriptor_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n google/protobuf/descriptor.proto\022\017goog"
   "\n google/protobuf/descriptor.proto\022\017goog"
   "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
   "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
   "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
   "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"

+ 2 - 0
src/google/protobuf/descriptor.proto

@@ -369,6 +369,7 @@ message FileOptions {
 
 
 
 
 
 
+
   // Should generic services be generated in each language?  "Generic" services
   // Should generic services be generated in each language?  "Generic" services
   // are not specific to any particular RPC system.  They are generated by the
   // are not specific to any particular RPC system.  They are generated by the
   // main code generators in each language (without additional plugins).
   // main code generators in each language (without additional plugins).
@@ -496,6 +497,7 @@ message MessageOptions {
   reserved 8;  // javalite_serializable
   reserved 8;  // javalite_serializable
   reserved 9;  // javanano_as_lite
   reserved 9;  // javanano_as_lite
 
 
+
   // The parser stores options it doesn't recognize here. See above.
   // The parser stores options it doesn't recognize here. See above.
   repeated UninterpretedOption uninterpreted_option = 999;
   repeated UninterpretedOption uninterpreted_option = 999;
 
 

File diff suppressed because it is too large
+ 252 - 195
src/google/protobuf/descriptor_unittest.cc


+ 1 - 1
src/google/protobuf/duration.pb.cc

@@ -56,7 +56,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Duration_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Duration_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2fduration_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\036google/protobuf/duration.proto\022\017google"
   "\n\036google/protobuf/duration.proto\022\017google"
   ".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r"
   ".protobuf\"*\n\010Duration\022\017\n\007seconds\030\001 \001(\003\022\r"
   "\n\005nanos\030\002 \001(\005B|\n\023com.google.protobufB\rDu"
   "\n\005nanos\030\002 \001(\005B|\n\023com.google.protobufB\rDu"

+ 9 - 10
src/google/protobuf/dynamic_message.cc

@@ -34,10 +34,10 @@
 //
 //
 // DynamicMessage is implemented by constructing a data structure which
 // DynamicMessage is implemented by constructing a data structure which
 // has roughly the same memory layout as a generated message would have.
 // has roughly the same memory layout as a generated message would have.
-// Then, we use GeneratedMessageReflection to implement our reflection
-// interface.  All the other operations we need to implement (e.g.
-// parsing, copying, etc.) are already implemented in terms of
-// Reflection, so the rest is easy.
+// Then, we use Reflection to implement our reflection interface.  All
+// the other operations we need to implement (e.g.  parsing, copying,
+// etc.) are already implemented in terms of Reflection, so the rest is
+// easy.
 //
 //
 // The up side of this strategy is that it's very efficient.  We don't
 // The up side of this strategy is that it's very efficient.  We don't
 // need to use hash_maps or generic representations of fields.  The
 // need to use hash_maps or generic representations of fields.  The
@@ -87,7 +87,6 @@ namespace protobuf {
 
 
 using internal::DynamicMapField;
 using internal::DynamicMapField;
 using internal::ExtensionSet;
 using internal::ExtensionSet;
-using internal::GeneratedMessageReflection;
 using internal::InternalMetadataWithArena;
 using internal::InternalMetadataWithArena;
 using internal::MapField;
 using internal::MapField;
 
 
@@ -248,7 +247,7 @@ class DynamicMessage : public Message {
     //   important (the prototype must be deleted *before* the offsets).
     //   important (the prototype must be deleted *before* the offsets).
     std::unique_ptr<uint32[]> offsets;
     std::unique_ptr<uint32[]> offsets;
     std::unique_ptr<uint32[]> has_bits_indices;
     std::unique_ptr<uint32[]> has_bits_indices;
-    std::unique_ptr<const GeneratedMessageReflection> reflection;
+    std::unique_ptr<const Reflection> reflection;
     // Don't use a unique_ptr to hold the prototype: the destructor for
     // Don't use a unique_ptr to hold the prototype: the destructor for
     // DynamicMessage needs to know whether it is the prototype, and does so by
     // DynamicMessage needs to know whether it is the prototype, and does so by
     // looking back at this field. This would assume details about the
     // looking back at this field. This would assume details about the
@@ -676,8 +675,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
   type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_;
   type_info->pool = (pool_ == NULL) ? type->file()->pool() : pool_;
   type_info->factory = this;
   type_info->factory = this;
 
 
-  // We need to construct all the structures passed to
-  // GeneratedMessageReflection's constructor.  This includes:
+  // We need to construct all the structures passed to Reflection's constructor.
+  // This includes:
   // - A block of memory that contains space for all the message's fields.
   // - A block of memory that contains space for all the message's fields.
   // - An array of integers indicating the byte offset of each field within
   // - An array of integers indicating the byte offset of each field within
   //   this block.
   //   this block.
@@ -801,8 +800,8 @@ const Message* DynamicMessageFactory::GetPrototypeNoLock(
                                        type_info->size,
                                        type_info->size,
                                        type_info->weak_field_map_offset};
                                        type_info->weak_field_map_offset};
 
 
-  type_info->reflection.reset(new GeneratedMessageReflection(
-      type_info->type, schema, type_info->pool, this));
+  type_info->reflection.reset(
+      new Reflection(type_info->type, schema, type_info->pool, this));
 
 
   // Cross link prototypes.
   // Cross link prototypes.
   prototype->CrossLinkPrototypes();
   prototype->CrossLinkPrototypes();

+ 1 - 1
src/google/protobuf/empty.pb.cc

@@ -54,7 +54,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Empty_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Empty_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2fempty_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\033google/protobuf/empty.proto\022\017google.pr"
   "\n\033google/protobuf/empty.proto\022\017google.pr"
   "otobuf\"\007\n\005EmptyBv\n\023com.google.protobufB\n"
   "otobuf\"\007\n\005EmptyBv\n\023com.google.protobufB\n"
   "EmptyProtoP\001Z\'github.com/golang/protobuf"
   "EmptyProtoP\001Z\'github.com/golang/protobuf"

+ 1 - 1
src/google/protobuf/field_mask.pb.cc

@@ -55,7 +55,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_FieldMask_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_FieldMask_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2ffield_5fmask_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n google/protobuf/field_mask.proto\022\017goog"
   "\n google/protobuf/field_mask.proto\022\017goog"
   "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB"
   "le.protobuf\"\032\n\tFieldMask\022\r\n\005paths\030\001 \003(\tB"
   "\214\001\n\023com.google.protobufB\016FieldMaskProtoP"
   "\214\001\n\023com.google.protobufB\016FieldMaskProtoP"

File diff suppressed because it is too large
+ 203 - 210
src/google/protobuf/generated_message_reflection.cc


+ 5 - 401
src/google/protobuf/generated_message_reflection.h

@@ -44,8 +44,8 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/common.h>
 // TODO(jasonh): Remove this once the compiler change to directly include this
 // TODO(jasonh): Remove this once the compiler change to directly include this
 // is released to components.
 // is released to components.
+#include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_enum_reflection.h>
 #include <google/protobuf/generated_enum_reflection.h>
-#include <google/protobuf/message.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/metadata.h>
 #include <google/protobuf/stubs/once.h>
 #include <google/protobuf/stubs/once.h>
 #include <google/protobuf/port.h>
 #include <google/protobuf/port.h>
@@ -58,17 +58,14 @@
 #error "You cannot SWIG proto headers"
 #error "You cannot SWIG proto headers"
 #endif
 #endif
 
 
-namespace upb {
-namespace google_opensource {
-class GMR_Handlers;
-}  // namespace google_opensource
-}  // namespace upb
-
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 class DescriptorPool;
 class DescriptorPool;
 class MapKey;
 class MapKey;
 class MapValueRef;
 class MapValueRef;
+class MessageLayoutInspector;
+class Message;
+struct Metadata;
 }  // namespace protobuf
 }  // namespace protobuf
 }  // namespace google
 }  // namespace google
 
 
@@ -79,9 +76,6 @@ namespace internal {
 class DefaultEmptyOneof;
 class DefaultEmptyOneof;
 class ReflectionAccessor;
 class ReflectionAccessor;
 
 
-// Defined in this file.
-class GeneratedMessageReflection;
-
 // Defined in other files.
 // Defined in other files.
 class ExtensionSet;  // extension_set.h
 class ExtensionSet;  // extension_set.h
 class WeakFieldMap;  // weak_field_map.h
 class WeakFieldMap;  // weak_field_map.h
@@ -92,7 +86,7 @@ class WeakFieldMap;  // weak_field_map.h
 //                  used to obtain pointers to default instances of embedded
 //                  used to obtain pointers to default instances of embedded
 //                  messages, which GetMessage() will return if the particular
 //                  messages, which GetMessage() will return if the particular
 //                  sub-message has not been initialized yet.  (Thus, all
 //                  sub-message has not been initialized yet.  (Thus, all
-//                  embedded message fields *must* have non-NULL pointers
+//                  embedded message fields *must* have non-null pointers
 //                  in the default instance.)
 //                  in the default instance.)
 //   offsets:       An array of ints giving the byte offsets.
 //   offsets:       An array of ints giving the byte offsets.
 //                  For each oneof or weak field, the offset is relative to the
 //                  For each oneof or weak field, the offset is relative to the
@@ -269,396 +263,6 @@ struct MigrationSchema {
   int object_size;
   int object_size;
 };
 };
 
 
-// THIS CLASS IS NOT INTENDED FOR DIRECT USE.  It is intended for use
-// by generated code.  This class is just a big hack that reduces code
-// size.
-//
-// A GeneratedMessageReflection is an implementation of Reflection
-// which expects all fields to be backed by simple variables located in
-// memory.  The locations are given using a base pointer and a set of
-// offsets.
-//
-// It is required that the user represents fields of each type in a standard
-// way, so that GeneratedMessageReflection can cast the void* pointer to
-// the appropriate type.  For primitive fields and string fields, each
-// field should be represented using the obvious C++ primitive type.  Enums and
-// Messages are different:
-//  - Singular Message fields are stored as a pointer to a Message.  These
-//    should start out NULL, except for in the default instance where they
-//    should start out pointing to other default instances.
-//  - Enum fields are stored as an int.  This int must always contain
-//    a valid value, such that EnumDescriptor::FindValueByNumber() would
-//    not return NULL.
-//  - Repeated fields are stored as RepeatedFields or RepeatedPtrFields
-//    of whatever type the individual field would be.  Strings and
-//    Messages use RepeatedPtrFields while everything else uses
-//    RepeatedFields.
-class GeneratedMessageReflection final : public Reflection {
- public:
-  // Constructs a GeneratedMessageReflection.
-  // Parameters:
-  //   descriptor:    The descriptor for the message type being implemented.
-  //   schema:        The description of the internal guts of the message.
-  //   pool:          DescriptorPool to search for extension definitions.  Only
-  //                  used by FindKnownExtensionByName() and
-  //                  FindKnownExtensionByNumber().
-  //   factory:       MessageFactory to use to construct extension messages.
-  GeneratedMessageReflection(const Descriptor* descriptor,
-                             const ReflectionSchema& schema,
-                             const DescriptorPool* pool,
-                             MessageFactory* factory);
-
-  ~GeneratedMessageReflection() override;
-
-  // implements Reflection -------------------------------------------
-
-  const UnknownFieldSet& GetUnknownFields(
-      const Message& message) const override;
-  UnknownFieldSet* MutableUnknownFields(Message* message) const override;
-
-  size_t SpaceUsedLong(const Message& message) const override;
-
-  bool HasField(const Message& message,
-                const FieldDescriptor* field) const override;
-  int FieldSize(const Message& message,
-                const FieldDescriptor* field) const override;
-  void ClearField(Message* message,
-                  const FieldDescriptor* field) const override;
-  bool HasOneof(const Message& message,
-                const OneofDescriptor* oneof_descriptor) const override;
-  void ClearOneof(Message* message,
-                  const OneofDescriptor* oneof_descriptor) const override;
-  void RemoveLast(Message* message,
-                  const FieldDescriptor* field) const override;
-  Message* ReleaseLast(Message* message,
-                       const FieldDescriptor* field) const override;
-  void Swap(Message* message1, Message* message2) const override;
-  void SwapFields(
-      Message* message1, Message* message2,
-      const std::vector<const FieldDescriptor*>& fields) const override;
-  void SwapElements(Message* message, const FieldDescriptor* field, int index1,
-                    int index2) const override;
-  void ListFields(const Message& message,
-                  std::vector<const FieldDescriptor*>* output) const override;
-  int32 GetInt32(const Message& message,
-                 const FieldDescriptor* field) const override;
-  int64 GetInt64(const Message& message,
-                 const FieldDescriptor* field) const override;
-  uint32 GetUInt32(const Message& message,
-                   const FieldDescriptor* field) const override;
-  uint64 GetUInt64(const Message& message,
-                   const FieldDescriptor* field) const override;
-  float GetFloat(const Message& message,
-                 const FieldDescriptor* field) const override;
-  double GetDouble(const Message& message,
-                   const FieldDescriptor* field) const override;
-  bool GetBool(const Message& message,
-               const FieldDescriptor* field) const override;
-  std::string GetString(const Message& message,
-                        const FieldDescriptor* field) const override;
-  const std::string& GetStringReference(const Message& message,
-                                        const FieldDescriptor* field,
-                                        std::string* scratch) const override;
-  const EnumValueDescriptor* GetEnum(
-      const Message& message, const FieldDescriptor* field) const override;
-  int GetEnumValue(const Message& message,
-                   const FieldDescriptor* field) const override;
-  const Message& GetMessage(const Message& message,
-                            const FieldDescriptor* field,
-                            MessageFactory* factory = NULL) const override;
-
-  const FieldDescriptor* GetOneofFieldDescriptor(
-      const Message& message,
-      const OneofDescriptor* oneof_descriptor) const override;
-
- private:
-  bool ContainsMapKey(const Message& message, const FieldDescriptor* field,
-                      const MapKey& key) const override;
-  bool InsertOrLookupMapValue(Message* message, const FieldDescriptor* field,
-                              const MapKey& key,
-                              MapValueRef* val) const override;
-  bool DeleteMapValue(Message* message, const FieldDescriptor* field,
-                      const MapKey& key) const override;
-  MapIterator MapBegin(Message* message,
-                       const FieldDescriptor* field) const override;
-  MapIterator MapEnd(Message* message,
-                     const FieldDescriptor* field) const override;
-  int MapSize(const Message& message,
-              const FieldDescriptor* field) const override;
-
- public:
-  void SetInt32(Message* message, const FieldDescriptor* field,
-                int32 value) const override;
-  void SetInt64(Message* message, const FieldDescriptor* field,
-                int64 value) const override;
-  void SetUInt32(Message* message, const FieldDescriptor* field,
-                 uint32 value) const override;
-  void SetUInt64(Message* message, const FieldDescriptor* field,
-                 uint64 value) const override;
-  void SetFloat(Message* message, const FieldDescriptor* field,
-                float value) const override;
-  void SetDouble(Message* message, const FieldDescriptor* field,
-                 double value) const override;
-  void SetBool(Message* message, const FieldDescriptor* field,
-               bool value) const override;
-  void SetString(Message* message, const FieldDescriptor* field,
-                 const std::string& value) const override;
-  void SetEnum(Message* message, const FieldDescriptor* field,
-               const EnumValueDescriptor* value) const override;
-  void SetEnumValue(Message* message, const FieldDescriptor* field,
-                    int value) const override;
-  Message* MutableMessage(Message* message, const FieldDescriptor* field,
-                          MessageFactory* factory = NULL) const override;
-  void SetAllocatedMessage(Message* message, Message* sub_message,
-                           const FieldDescriptor* field) const override;
-  Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
-                          MessageFactory* factory = NULL) const override;
-
-  int32 GetRepeatedInt32(const Message& message, const FieldDescriptor* field,
-                         int index) const override;
-  int64 GetRepeatedInt64(const Message& message, const FieldDescriptor* field,
-                         int index) const override;
-  uint32 GetRepeatedUInt32(const Message& message, const FieldDescriptor* field,
-                           int index) const override;
-  uint64 GetRepeatedUInt64(const Message& message, const FieldDescriptor* field,
-                           int index) const override;
-  float GetRepeatedFloat(const Message& message, const FieldDescriptor* field,
-                         int index) const override;
-  double GetRepeatedDouble(const Message& message, const FieldDescriptor* field,
-                           int index) const override;
-  bool GetRepeatedBool(const Message& message, const FieldDescriptor* field,
-                       int index) const override;
-  std::string GetRepeatedString(const Message& message,
-                                const FieldDescriptor* field,
-                                int index) const override;
-  const std::string& GetRepeatedStringReference(
-      const Message& message, const FieldDescriptor* field, int index,
-      std::string* scratch) const override;
-  const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
-                                             const FieldDescriptor* field,
-                                             int index) const override;
-  int GetRepeatedEnumValue(const Message& message, const FieldDescriptor* field,
-                           int index) const override;
-  const Message& GetRepeatedMessage(const Message& message,
-                                    const FieldDescriptor* field,
-                                    int index) const override;
-
-  // Set the value of a field.
-  void SetRepeatedInt32(Message* message, const FieldDescriptor* field,
-                        int index, int32 value) const override;
-  void SetRepeatedInt64(Message* message, const FieldDescriptor* field,
-                        int index, int64 value) const override;
-  void SetRepeatedUInt32(Message* message, const FieldDescriptor* field,
-                         int index, uint32 value) const override;
-  void SetRepeatedUInt64(Message* message, const FieldDescriptor* field,
-                         int index, uint64 value) const override;
-  void SetRepeatedFloat(Message* message, const FieldDescriptor* field,
-                        int index, float value) const override;
-  void SetRepeatedDouble(Message* message, const FieldDescriptor* field,
-                         int index, double value) const override;
-  void SetRepeatedBool(Message* message, const FieldDescriptor* field,
-                       int index, bool value) const override;
-  void SetRepeatedString(Message* message, const FieldDescriptor* field,
-                         int index, const std::string& value) const override;
-  void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
-                       int index,
-                       const EnumValueDescriptor* value) const override;
-  void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field,
-                            int index, int value) const override;
-  // Get a mutable pointer to a field with a message type.
-  Message* MutableRepeatedMessage(Message* message,
-                                  const FieldDescriptor* field,
-                                  int index) const override;
-
-  void AddInt32(Message* message, const FieldDescriptor* field,
-                int32 value) const override;
-  void AddInt64(Message* message, const FieldDescriptor* field,
-                int64 value) const override;
-  void AddUInt32(Message* message, const FieldDescriptor* field,
-                 uint32 value) const override;
-  void AddUInt64(Message* message, const FieldDescriptor* field,
-                 uint64 value) const override;
-  void AddFloat(Message* message, const FieldDescriptor* field,
-                float value) const override;
-  void AddDouble(Message* message, const FieldDescriptor* field,
-                 double value) const override;
-  void AddBool(Message* message, const FieldDescriptor* field,
-               bool value) const override;
-  void AddString(Message* message, const FieldDescriptor* field,
-                 const std::string& value) const override;
-  void AddEnum(Message* message, const FieldDescriptor* field,
-               const EnumValueDescriptor* value) const override;
-  void AddEnumValue(Message* message, const FieldDescriptor* field,
-                    int value) const override;
-  Message* AddMessage(Message* message, const FieldDescriptor* field,
-                      MessageFactory* factory = NULL) const override;
-  void AddAllocatedMessage(Message* message, const FieldDescriptor* field,
-                           Message* new_entry) const override;
-
-  const FieldDescriptor* FindKnownExtensionByName(
-      const std::string& name) const override;
-  const FieldDescriptor* FindKnownExtensionByNumber(int number) const override;
-
-  bool SupportsUnknownEnumValues() const override;
-
-  // This value for arena_offset_ indicates that there is no arena pointer in
-  // this message (e.g., old generated code).
-  static const int kNoArenaPointer = -1;
-
-  // This value for unknown_field_offset_ indicates that there is no
-  // UnknownFieldSet in this message, and that instead, we are using the
-  // Zero-Overhead Arena Pointer trick. When this is the case, arena_offset_
-  // actually indexes to an InternalMetadataWithArena instance, which can return
-  // either an arena pointer or an UnknownFieldSet or both. It is never the case
-  // that unknown_field_offset_ == kUnknownFieldSetInMetadata && arena_offset_
-  // == kNoArenaPointer.
-  static const int kUnknownFieldSetInMetadata = -1;
-
- protected:
-  void* MutableRawRepeatedField(Message* message, const FieldDescriptor* field,
-                                FieldDescriptor::CppType, int ctype,
-                                const Descriptor* desc) const override;
-
-  const void* GetRawRepeatedField(const Message& message,
-                                  const FieldDescriptor* field,
-                                  FieldDescriptor::CppType, int ctype,
-                                  const Descriptor* desc) const override;
-
-  MessageFactory* GetMessageFactory() const override;
-
-  void* RepeatedFieldData(Message* message, const FieldDescriptor* field,
-                          FieldDescriptor::CppType cpp_type,
-                          const Descriptor* message_type) const override;
-
- private:
-  friend class ReflectionAccessor;
-  friend class upb::google_opensource::GMR_Handlers;
-
-  const Descriptor* const descriptor_;
-  const ReflectionSchema schema_;
-  const DescriptorPool* const descriptor_pool_;
-  MessageFactory* const message_factory_;
-
-  // Last non weak field index. This is an optimization when most weak fields
-  // are at the end of the containing message. If a message proto doesn't
-  // contain weak fields, then this field equals descriptor_->field_count().
-  int last_non_weak_field_index_;
-
-  template <class T>
-  const T& GetRawNonOneof(const Message& message,
-                          const FieldDescriptor* field) const;
-  template <class T>
-  T* MutableRawNonOneof(Message* message, const FieldDescriptor* field) const;
-
-  template <typename Type>
-  const Type& GetRaw(const Message& message,
-                     const FieldDescriptor* field) const;
-  template <typename Type>
-  inline Type* MutableRaw(Message* message, const FieldDescriptor* field) const;
-  template <typename Type>
-  inline const Type& DefaultRaw(const FieldDescriptor* field) const;
-
-  inline const uint32* GetHasBits(const Message& message) const;
-  inline uint32* MutableHasBits(Message* message) const;
-  inline uint32 GetOneofCase(const Message& message,
-                             const OneofDescriptor* oneof_descriptor) const;
-  inline uint32* MutableOneofCase(
-      Message* message, const OneofDescriptor* oneof_descriptor) const;
-  inline const ExtensionSet& GetExtensionSet(const Message& message) const;
-  inline ExtensionSet* MutableExtensionSet(Message* message) const;
-  inline Arena* GetArena(Message* message) const;
-
-  inline const InternalMetadataWithArena& GetInternalMetadataWithArena(
-      const Message& message) const;
-
-  inline InternalMetadataWithArena* MutableInternalMetadataWithArena(
-      Message* message) const;
-
-  inline bool IsInlined(const FieldDescriptor* field) const;
-
-  inline bool HasBit(const Message& message,
-                     const FieldDescriptor* field) const;
-  inline void SetBit(Message* message, const FieldDescriptor* field) const;
-  inline void ClearBit(Message* message, const FieldDescriptor* field) const;
-  inline void SwapBit(Message* message1, Message* message2,
-                      const FieldDescriptor* field) const;
-
-  // This function only swaps the field. Should swap corresponding has_bit
-  // before or after using this function.
-  void SwapField(Message* message1, Message* message2,
-                 const FieldDescriptor* field) const;
-
-  void SwapOneofField(Message* message1, Message* message2,
-                      const OneofDescriptor* oneof_descriptor) const;
-
-  inline bool HasOneofField(const Message& message,
-                            const FieldDescriptor* field) const;
-  inline void SetOneofCase(Message* message,
-                           const FieldDescriptor* field) const;
-  inline void ClearOneofField(Message* message,
-                              const FieldDescriptor* field) const;
-
-  template <typename Type>
-  inline const Type& GetField(const Message& message,
-                              const FieldDescriptor* field) const;
-  template <typename Type>
-  inline void SetField(Message* message, const FieldDescriptor* field,
-                       const Type& value) const;
-  template <typename Type>
-  inline Type* MutableField(Message* message,
-                            const FieldDescriptor* field) const;
-  template <typename Type>
-  inline const Type& GetRepeatedField(const Message& message,
-                                      const FieldDescriptor* field,
-                                      int index) const;
-  template <typename Type>
-  inline const Type& GetRepeatedPtrField(const Message& message,
-                                         const FieldDescriptor* field,
-                                         int index) const;
-  template <typename Type>
-  inline void SetRepeatedField(Message* message, const FieldDescriptor* field,
-                               int index, Type value) const;
-  template <typename Type>
-  inline Type* MutableRepeatedField(Message* message,
-                                    const FieldDescriptor* field,
-                                    int index) const;
-  template <typename Type>
-  inline void AddField(Message* message, const FieldDescriptor* field,
-                       const Type& value) const;
-  template <typename Type>
-  inline Type* AddField(Message* message, const FieldDescriptor* field) const;
-
-  int GetExtensionNumberOrDie(const Descriptor* type) const;
-
-  // Internal versions of EnumValue API perform no checking. Called after checks
-  // by public methods.
-  void SetEnumValueInternal(Message* message, const FieldDescriptor* field,
-                            int value) const;
-  void SetRepeatedEnumValueInternal(Message* message,
-                                    const FieldDescriptor* field, int index,
-                                    int value) const;
-  void AddEnumValueInternal(Message* message, const FieldDescriptor* field,
-                            int value) const;
-
-  Message* UnsafeArenaReleaseMessage(Message* message,
-                                     const FieldDescriptor* field,
-                                     MessageFactory* factory = NULL) const;
-
-  void UnsafeArenaSetAllocatedMessage(Message* message, Message* sub_message,
-                                      const FieldDescriptor* field) const;
-
-  internal::MapFieldBase* MutableMapData(
-      Message* message, const FieldDescriptor* field) const override;
-
-  const internal::MapFieldBase* GetMapData(
-      const Message& message, const FieldDescriptor* field) const override;
-
-  friend inline  // inline so nobody can call this function.
-      void
-      RegisterAllTypesInternal(const Metadata* file_level_metadata, int size);
-  GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(GeneratedMessageReflection);
-};
-
 struct PROTOBUF_EXPORT DescriptorTable {
 struct PROTOBUF_EXPORT DescriptorTable {
   bool* is_initialized;
   bool* is_initialized;
   const char* descriptor;
   const char* descriptor;

+ 0 - 1
src/google/protobuf/map_entry.h

@@ -126,7 +126,6 @@ class MapEntry
             WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType,
             WireFormatLite::FieldType k_wire_type, WireFormatLite::FieldType,
             int default_enum>
             int default_enum>
   friend class internal::MapField;
   friend class internal::MapField;
-  friend class internal::GeneratedMessageReflection;
 
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MapEntry);
 };
 };

+ 1 - 1
src/google/protobuf/map_field.h

@@ -662,7 +662,7 @@ class PROTOBUF_EXPORT MapValueRef {
   template <typename K, typename V>
   template <typename K, typename V>
   friend class internal::TypeDefinedMapFieldBase;
   friend class internal::TypeDefinedMapFieldBase;
   friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
   friend class ::PROTOBUF_NAMESPACE_ID::MapIterator;
-  friend class internal::GeneratedMessageReflection;
+  friend class Reflection;
   friend class internal::DynamicMapField;
   friend class internal::DynamicMapField;
 
 
   void SetType(FieldDescriptor::CppType type) { type_ = type; }
   void SetType(FieldDescriptor::CppType type) { type_ = type; }

+ 1 - 79
src/google/protobuf/message.cc

@@ -150,7 +150,7 @@ class ReflectionAccessor {
  public:
  public:
   static void* GetOffset(void* msg, const google::protobuf::FieldDescriptor* f,
   static void* GetOffset(void* msg, const google::protobuf::FieldDescriptor* f,
                          const google::protobuf::Reflection* r) {
                          const google::protobuf::Reflection* r) {
-    return static_cast<char*>(msg) + CheckedCast(r)->schema_.GetFieldOffset(f);
+    return static_cast<char*>(msg) + r->schema_.GetFieldOffset(f);
   }
   }
 
 
   static void* GetRepeatedEnum(const Reflection* reflection,
   static void* GetRepeatedEnum(const Reflection* reflection,
@@ -158,13 +158,6 @@ class ReflectionAccessor {
     return reflection->MutableRawRepeatedField(
     return reflection->MutableRawRepeatedField(
         msg, field, FieldDescriptor::CPPTYPE_ENUM, 0, nullptr);
         msg, field, FieldDescriptor::CPPTYPE_ENUM, 0, nullptr);
   }
   }
-
- private:
-  static const GeneratedMessageReflection* CheckedCast(const Reflection* r) {
-    auto gr = dynamic_cast<const GeneratedMessageReflection*>(r);
-    GOOGLE_CHECK(gr != nullptr);
-    return gr;
-  }
 };
 };
 
 
 }  // namespace internal
 }  // namespace internal
@@ -553,64 +546,6 @@ size_t Message::SpaceUsedLong() const {
   return GetReflection()->SpaceUsedLong(*this);
   return GetReflection()->SpaceUsedLong(*this);
 }
 }
 
 
-// =============================================================================
-// Reflection and associated Template Specializations
-
-Reflection::~Reflection() {}
-
-void Reflection::AddAllocatedMessage(Message* /* message */,
-                                     const FieldDescriptor* /*field */,
-                                     Message* /* new_entry */) const {}
-
-#define HANDLE_TYPE(TYPE, CPPTYPE, CTYPE)                               \
-  template <>                                                           \
-  const RepeatedField<TYPE>& Reflection::GetRepeatedField<TYPE>(        \
-      const Message& message, const FieldDescriptor* field) const {     \
-    return *static_cast<RepeatedField<TYPE>*>(MutableRawRepeatedField(  \
-        const_cast<Message*>(&message), field, CPPTYPE, CTYPE, NULL));  \
-  }                                                                     \
-                                                                        \
-  template <>                                                           \
-  RepeatedField<TYPE>* Reflection::MutableRepeatedField<TYPE>(          \
-      Message * message, const FieldDescriptor* field) const {          \
-    return static_cast<RepeatedField<TYPE>*>(                           \
-        MutableRawRepeatedField(message, field, CPPTYPE, CTYPE, NULL)); \
-  }
-
-HANDLE_TYPE(int32, FieldDescriptor::CPPTYPE_INT32, -1);
-HANDLE_TYPE(int64, FieldDescriptor::CPPTYPE_INT64, -1);
-HANDLE_TYPE(uint32, FieldDescriptor::CPPTYPE_UINT32, -1);
-HANDLE_TYPE(uint64, FieldDescriptor::CPPTYPE_UINT64, -1);
-HANDLE_TYPE(float, FieldDescriptor::CPPTYPE_FLOAT, -1);
-HANDLE_TYPE(double, FieldDescriptor::CPPTYPE_DOUBLE, -1);
-HANDLE_TYPE(bool, FieldDescriptor::CPPTYPE_BOOL, -1);
-
-
-#undef HANDLE_TYPE
-
-void* Reflection::MutableRawRepeatedString(Message* message,
-                                           const FieldDescriptor* field,
-                                           bool is_string) const {
-  return MutableRawRepeatedField(message, field,
-                                 FieldDescriptor::CPPTYPE_STRING,
-                                 FieldOptions::STRING, NULL);
-}
-
-
-MapIterator Reflection::MapBegin(Message* message,
-                                 const FieldDescriptor* field) const {
-  GOOGLE_LOG(FATAL) << "Unimplemented Map Reflection API.";
-  MapIterator iter(message, field);
-  return iter;
-}
-
-MapIterator Reflection::MapEnd(Message* message,
-                               const FieldDescriptor* field) const {
-  GOOGLE_LOG(FATAL) << "Unimplemented Map Reflection API.";
-  MapIterator iter(message, field);
-  return iter;
-}
-
 // =============================================================================
 // =============================================================================
 // MessageFactory
 // MessageFactory
 
 
@@ -725,19 +660,6 @@ void MessageFactory::InternalRegisterGeneratedMessage(
 }
 }
 
 
 
 
-MessageFactory* Reflection::GetMessageFactory() const {
-  GOOGLE_LOG(FATAL) << "Not implemented.";
-  return NULL;
-}
-
-void* Reflection::RepeatedFieldData(Message* message,
-                                    const FieldDescriptor* field,
-                                    FieldDescriptor::CppType cpp_type,
-                                    const Descriptor* message_type) const {
-  GOOGLE_LOG(FATAL) << "Not implemented.";
-  return NULL;
-}
-
 namespace {
 namespace {
 template <typename T>
 template <typename T>
 T* GetSingleton() {
 T* GetSingleton() {

+ 326 - 268
src/google/protobuf/message.h

@@ -84,12 +84,12 @@
 //     // Get the descriptors for the fields we're interested in and verify
 //     // Get the descriptors for the fields we're interested in and verify
 //     // their types.
 //     // their types.
 //     const FieldDescriptor* text_field = descriptor->FindFieldByName("text");
 //     const FieldDescriptor* text_field = descriptor->FindFieldByName("text");
-//     assert(text_field != NULL);
+//     assert(text_field != nullptr);
 //     assert(text_field->type() == FieldDescriptor::TYPE_STRING);
 //     assert(text_field->type() == FieldDescriptor::TYPE_STRING);
 //     assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL);
 //     assert(text_field->label() == FieldDescriptor::LABEL_OPTIONAL);
 //     const FieldDescriptor* numbers_field = descriptor->
 //     const FieldDescriptor* numbers_field = descriptor->
 //                                            FindFieldByName("numbers");
 //                                            FindFieldByName("numbers");
-//     assert(numbers_field != NULL);
+//     assert(numbers_field != nullptr);
 //     assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
 //     assert(numbers_field->type() == FieldDescriptor::TYPE_INT32);
 //     assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED);
 //     assert(numbers_field->label() == FieldDescriptor::LABEL_REPEATED);
 //
 //
@@ -119,6 +119,7 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor.h>
+#include <google/protobuf/generated_message_reflection.h>
 #include <google/protobuf/message_lite.h>
 #include <google/protobuf/message_lite.h>
 #include <google/protobuf/port.h>
 #include <google/protobuf/port.h>
 
 
@@ -141,6 +142,8 @@ class Reflection;
 class MessageFactory;
 class MessageFactory;
 
 
 // Defined in other files.
 // Defined in other files.
+class AssignDescriptorsHelper;
+class DynamicMessageFactory;
 class MapKey;
 class MapKey;
 class MapValueRef;
 class MapValueRef;
 class MapIterator;
 class MapIterator;
@@ -212,11 +215,11 @@ class PROTOBUF_EXPORT Message : public MessageLite {
   Message* New() const override = 0;
   Message* New() const override = 0;
 
 
   // Construct a new instance on the arena. Ownership is passed to the caller
   // Construct a new instance on the arena. Ownership is passed to the caller
-  // if arena is a NULL. Default implementation allows for API compatibility
+  // if arena is a nullptr. Default implementation allows for API compatibility
   // during the Arena transition.
   // during the Arena transition.
   Message* New(Arena* arena) const override {
   Message* New(Arena* arena) const override {
     Message* message = New();
     Message* message = New();
-    if (arena != NULL) {
+    if (arena != nullptr) {
       arena->Own(message);
       arena->Own(message);
     }
     }
     return message;
     return message;
@@ -394,23 +397,19 @@ class MutableRepeatedFieldRef;
 // double the message's memory footprint, probably worse.  Allocating the
 // double the message's memory footprint, probably worse.  Allocating the
 // objects on-demand, on the other hand, would be expensive and prone to
 // objects on-demand, on the other hand, would be expensive and prone to
 // memory leaks.  So, instead we ended up with this flat interface.
 // memory leaks.  So, instead we ended up with this flat interface.
-class PROTOBUF_EXPORT Reflection {
+class PROTOBUF_EXPORT Reflection final {
  public:
  public:
-  inline Reflection() {}
-  virtual ~Reflection();
-
   // Get the UnknownFieldSet for the message.  This contains fields which
   // Get the UnknownFieldSet for the message.  This contains fields which
   // were seen when the Message was parsed but were not recognized according
   // were seen when the Message was parsed but were not recognized according
   // to the Message's definition.
   // to the Message's definition.
-  virtual const UnknownFieldSet& GetUnknownFields(
-      const Message& message) const = 0;
+  const UnknownFieldSet& GetUnknownFields(const Message& message) const;
   // Get a mutable pointer to the UnknownFieldSet for the message.  This
   // Get a mutable pointer to the UnknownFieldSet for the message.  This
   // contains fields which were seen when the Message was parsed but were not
   // contains fields which were seen when the Message was parsed but were not
   // recognized according to the Message's definition.
   // recognized according to the Message's definition.
-  virtual UnknownFieldSet* MutableUnknownFields(Message* message) const = 0;
+  UnknownFieldSet* MutableUnknownFields(Message* message) const;
 
 
   // Estimate the amount of memory used by the message object.
   // Estimate the amount of memory used by the message object.
-  virtual size_t SpaceUsedLong(const Message& message) const = 0;
+  size_t SpaceUsedLong(const Message& message) const;
 
 
   PROTOBUF_DEPRECATED_MSG("Please use SpaceUsedLong() instead")
   PROTOBUF_DEPRECATED_MSG("Please use SpaceUsedLong() instead")
   int SpaceUsed(const Message& message) const {
   int SpaceUsed(const Message& message) const {
@@ -418,37 +417,26 @@ class PROTOBUF_EXPORT Reflection {
   }
   }
 
 
   // Check if the given non-repeated field is set.
   // Check if the given non-repeated field is set.
-  virtual bool HasField(const Message& message,
-                        const FieldDescriptor* field) const = 0;
+  bool HasField(const Message& message, const FieldDescriptor* field) const;
 
 
   // Get the number of elements of a repeated field.
   // Get the number of elements of a repeated field.
-  virtual int FieldSize(const Message& message,
-                        const FieldDescriptor* field) const = 0;
+  int FieldSize(const Message& message, const FieldDescriptor* field) const;
 
 
   // Clear the value of a field, so that HasField() returns false or
   // Clear the value of a field, so that HasField() returns false or
   // FieldSize() returns zero.
   // FieldSize() returns zero.
-  virtual void ClearField(Message* message,
-                          const FieldDescriptor* field) const = 0;
+  void ClearField(Message* message, const FieldDescriptor* field) const;
 
 
   // Check if the oneof is set. Returns true if any field in oneof
   // Check if the oneof is set. Returns true if any field in oneof
   // is set, false otherwise.
   // is set, false otherwise.
-  // TODO(jieluo) - make it pure virtual after updating all
-  // the subclasses.
-  virtual bool HasOneof(const Message& /*message*/,
-                        const OneofDescriptor* /*oneof_descriptor*/) const {
-    return false;
-  }
+  bool HasOneof(const Message& message,
+                const OneofDescriptor* oneof_descriptor) const;
 
 
-  virtual void ClearOneof(Message* /*message*/,
-                          const OneofDescriptor* /*oneof_descriptor*/) const {}
+  void ClearOneof(Message* message,
+                  const OneofDescriptor* oneof_descriptor) const;
 
 
-  // Returns the field descriptor if the oneof is set. NULL otherwise.
-  // TODO(jieluo) - make it pure virtual.
-  virtual const FieldDescriptor* GetOneofFieldDescriptor(
-      const Message& /*message*/,
-      const OneofDescriptor* /*oneof_descriptor*/) const {
-    return NULL;
-  }
+  // Returns the field descriptor if the oneof is set. nullptr otherwise.
+  const FieldDescriptor* GetOneofFieldDescriptor(
+      const Message& message, const OneofDescriptor* oneof_descriptor) const;
 
 
   // Removes the last element of a repeated field.
   // Removes the last element of a repeated field.
   // We don't provide a way to remove any element other than the last
   // We don't provide a way to remove any element other than the last
@@ -457,24 +445,21 @@ class PROTOBUF_EXPORT Reflection {
   // than the last, the best way to do it is to re-arrange the elements
   // than the last, the best way to do it is to re-arrange the elements
   // (using Swap()) so that the one you want removed is at the end, then
   // (using Swap()) so that the one you want removed is at the end, then
   // call RemoveLast().
   // call RemoveLast().
-  virtual void RemoveLast(Message* message,
-                          const FieldDescriptor* field) const = 0;
+  void RemoveLast(Message* message, const FieldDescriptor* field) const;
   // Removes the last element of a repeated message field, and returns the
   // Removes the last element of a repeated message field, and returns the
   // pointer to the caller.  Caller takes ownership of the returned pointer.
   // pointer to the caller.  Caller takes ownership of the returned pointer.
-  virtual Message* ReleaseLast(Message* message,
-                               const FieldDescriptor* field) const = 0;
+  Message* ReleaseLast(Message* message, const FieldDescriptor* field) const;
 
 
   // Swap the complete contents of two messages.
   // Swap the complete contents of two messages.
-  virtual void Swap(Message* message1, Message* message2) const = 0;
+  void Swap(Message* message1, Message* message2) const;
 
 
   // Swap fields listed in fields vector of two messages.
   // Swap fields listed in fields vector of two messages.
-  virtual void SwapFields(
-      Message* message1, Message* message2,
-      const std::vector<const FieldDescriptor*>& fields) const = 0;
+  void SwapFields(Message* message1, Message* message2,
+                  const std::vector<const FieldDescriptor*>& fields) const;
 
 
   // Swap two elements of a repeated field.
   // Swap two elements of a repeated field.
-  virtual void SwapElements(Message* message, const FieldDescriptor* field,
-                            int index1, int index2) const = 0;
+  void SwapElements(Message* message, const FieldDescriptor* field, int index1,
+                    int index2) const;
 
 
   // List all fields of the message which are currently set, except for unknown
   // List all fields of the message which are currently set, except for unknown
   // fields, but including extension known to the parser (i.e. compiled in).
   // fields, but including extension known to the parser (i.e. compiled in).
@@ -484,45 +469,36 @@ class PROTOBUF_EXPORT Reflection {
   // ordered by field number.
   // ordered by field number.
   // Use Reflection::GetUnknownFields() or message.unknown_fields() to also get
   // Use Reflection::GetUnknownFields() or message.unknown_fields() to also get
   // access to fields/extensions unknown to the parser.
   // access to fields/extensions unknown to the parser.
-  virtual void ListFields(
-      const Message& message,
-      std::vector<const FieldDescriptor*>* output) const = 0;
+  void ListFields(const Message& message,
+                  std::vector<const FieldDescriptor*>* output) const;
 
 
   // Singular field getters ------------------------------------------
   // Singular field getters ------------------------------------------
   // These get the value of a non-repeated field.  They return the default
   // These get the value of a non-repeated field.  They return the default
   // value for fields that aren't set.
   // value for fields that aren't set.
 
 
-  virtual int32 GetInt32(const Message& message,
-                         const FieldDescriptor* field) const = 0;
-  virtual int64 GetInt64(const Message& message,
-                         const FieldDescriptor* field) const = 0;
-  virtual uint32 GetUInt32(const Message& message,
-                           const FieldDescriptor* field) const = 0;
-  virtual uint64 GetUInt64(const Message& message,
-                           const FieldDescriptor* field) const = 0;
-  virtual float GetFloat(const Message& message,
-                         const FieldDescriptor* field) const = 0;
-  virtual double GetDouble(const Message& message,
-                           const FieldDescriptor* field) const = 0;
-  virtual bool GetBool(const Message& message,
-                       const FieldDescriptor* field) const = 0;
-  virtual std::string GetString(const Message& message,
-                                const FieldDescriptor* field) const = 0;
-  virtual const EnumValueDescriptor* GetEnum(
-      const Message& message, const FieldDescriptor* field) const = 0;
+  int32 GetInt32(const Message& message, const FieldDescriptor* field) const;
+  int64 GetInt64(const Message& message, const FieldDescriptor* field) const;
+  uint32 GetUInt32(const Message& message, const FieldDescriptor* field) const;
+  uint64 GetUInt64(const Message& message, const FieldDescriptor* field) const;
+  float GetFloat(const Message& message, const FieldDescriptor* field) const;
+  double GetDouble(const Message& message, const FieldDescriptor* field) const;
+  bool GetBool(const Message& message, const FieldDescriptor* field) const;
+  std::string GetString(const Message& message,
+                        const FieldDescriptor* field) const;
+  const EnumValueDescriptor* GetEnum(const Message& message,
+                                     const FieldDescriptor* field) const;
 
 
   // GetEnumValue() returns an enum field's value as an integer rather than
   // GetEnumValue() returns an enum field's value as an integer rather than
   // an EnumValueDescriptor*. If the integer value does not correspond to a
   // an EnumValueDescriptor*. If the integer value does not correspond to a
   // known value descriptor, a new value descriptor is created. (Such a value
   // known value descriptor, a new value descriptor is created. (Such a value
   // will only be present when the new unknown-enum-value semantics are enabled
   // will only be present when the new unknown-enum-value semantics are enabled
   // for a message.)
   // for a message.)
-  virtual int GetEnumValue(const Message& message,
-                           const FieldDescriptor* field) const = 0;
+  int GetEnumValue(const Message& message, const FieldDescriptor* field) const;
 
 
   // See MutableMessage() for the meaning of the "factory" parameter.
   // See MutableMessage() for the meaning of the "factory" parameter.
-  virtual const Message& GetMessage(const Message& message,
-                                    const FieldDescriptor* field,
-                                    MessageFactory* factory = NULL) const = 0;
+  const Message& GetMessage(const Message& message,
+                            const FieldDescriptor* field,
+                            MessageFactory* factory = nullptr) const;
 
 
   // Get a string value without copying, if possible.
   // Get a string value without copying, if possible.
   //
   //
@@ -539,32 +515,32 @@ class PROTOBUF_EXPORT Reflection {
   //   a newly-constructed string, though, it's just as fast and more
   //   a newly-constructed string, though, it's just as fast and more
   //   readable to use code like:
   //   readable to use code like:
   //     std::string str = reflection->GetString(message, field);
   //     std::string str = reflection->GetString(message, field);
-  virtual const std::string& GetStringReference(const Message& message,
-                                                const FieldDescriptor* field,
-                                                std::string* scratch) const = 0;
+  const std::string& GetStringReference(const Message& message,
+                                        const FieldDescriptor* field,
+                                        std::string* scratch) const;
 
 
 
 
   // Singular field mutators -----------------------------------------
   // Singular field mutators -----------------------------------------
   // These mutate the value of a non-repeated field.
   // These mutate the value of a non-repeated field.
 
 
-  virtual void SetInt32(Message* message, const FieldDescriptor* field,
-                        int32 value) const = 0;
-  virtual void SetInt64(Message* message, const FieldDescriptor* field,
-                        int64 value) const = 0;
-  virtual void SetUInt32(Message* message, const FieldDescriptor* field,
-                         uint32 value) const = 0;
-  virtual void SetUInt64(Message* message, const FieldDescriptor* field,
-                         uint64 value) const = 0;
-  virtual void SetFloat(Message* message, const FieldDescriptor* field,
-                        float value) const = 0;
-  virtual void SetDouble(Message* message, const FieldDescriptor* field,
-                         double value) const = 0;
-  virtual void SetBool(Message* message, const FieldDescriptor* field,
-                       bool value) const = 0;
-  virtual void SetString(Message* message, const FieldDescriptor* field,
-                         const std::string& value) const = 0;
-  virtual void SetEnum(Message* message, const FieldDescriptor* field,
-                       const EnumValueDescriptor* value) const = 0;
+  void SetInt32(Message* message, const FieldDescriptor* field,
+                int32 value) const;
+  void SetInt64(Message* message, const FieldDescriptor* field,
+                int64 value) const;
+  void SetUInt32(Message* message, const FieldDescriptor* field,
+                 uint32 value) const;
+  void SetUInt64(Message* message, const FieldDescriptor* field,
+                 uint64 value) const;
+  void SetFloat(Message* message, const FieldDescriptor* field,
+                float value) const;
+  void SetDouble(Message* message, const FieldDescriptor* field,
+                 double value) const;
+  void SetBool(Message* message, const FieldDescriptor* field,
+               bool value) const;
+  void SetString(Message* message, const FieldDescriptor* field,
+                 const std::string& value) const;
+  void SetEnum(Message* message, const FieldDescriptor* field,
+               const EnumValueDescriptor* value) const;
   // Set an enum field's value with an integer rather than EnumValueDescriptor.
   // Set an enum field's value with an integer rather than EnumValueDescriptor.
   // For proto3 this is just setting the enum field to the value specified, for
   // For proto3 this is just setting the enum field to the value specified, for
   // proto2 it's more complicated. If value is a known enum value the field is
   // proto2 it's more complicated. If value is a known enum value the field is
@@ -572,8 +548,8 @@ class PROTOBUF_EXPORT Reflection {
   // set. Note this matches the behavior of parsing unknown enum values.
   // set. Note this matches the behavior of parsing unknown enum values.
   // If multiple calls with unknown values happen than they are all added to the
   // If multiple calls with unknown values happen than they are all added to the
   // unknown field set in order of the calls.
   // unknown field set in order of the calls.
-  virtual void SetEnumValue(Message* message, const FieldDescriptor* field,
-                            int value) const = 0;
+  void SetEnumValue(Message* message, const FieldDescriptor* field,
+                    int value) const;
 
 
   // Get a mutable pointer to a field with a message type.  If a MessageFactory
   // Get a mutable pointer to a field with a message type.  If a MessageFactory
   // is provided, it will be used to construct instances of the sub-message;
   // is provided, it will be used to construct instances of the sub-message;
@@ -585,97 +561,86 @@ class PROTOBUF_EXPORT Reflection {
   // FieldDescriptor is for a compiled-in extension, then
   // FieldDescriptor is for a compiled-in extension, then
   // factory->GetPrototype(field->message_type()) MUST return an instance of
   // factory->GetPrototype(field->message_type()) MUST return an instance of
   // the compiled-in class for this type, NOT DynamicMessage.
   // the compiled-in class for this type, NOT DynamicMessage.
-  virtual Message* MutableMessage(Message* message,
-                                  const FieldDescriptor* field,
-                                  MessageFactory* factory = NULL) const = 0;
+  Message* MutableMessage(Message* message, const FieldDescriptor* field,
+                          MessageFactory* factory = nullptr) const;
   // Replaces the message specified by 'field' with the already-allocated object
   // Replaces the message specified by 'field' with the already-allocated object
   // sub_message, passing ownership to the message.  If the field contained a
   // sub_message, passing ownership to the message.  If the field contained a
-  // message, that message is deleted.  If sub_message is NULL, the field is
+  // message, that message is deleted.  If sub_message is nullptr, the field is
   // cleared.
   // cleared.
-  virtual void SetAllocatedMessage(Message* message, Message* sub_message,
-                                   const FieldDescriptor* field) const = 0;
+  void SetAllocatedMessage(Message* message, Message* sub_message,
+                           const FieldDescriptor* field) const;
   // Releases the message specified by 'field' and returns the pointer,
   // Releases the message specified by 'field' and returns the pointer,
   // ReleaseMessage() will return the message the message object if it exists.
   // ReleaseMessage() will return the message the message object if it exists.
-  // Otherwise, it may or may not return NULL.  In any case, if the return value
-  // is non-NULL, the caller takes ownership of the pointer.
+  // Otherwise, it may or may not return nullptr.  In any case, if the return
+  // value is non-null, the caller takes ownership of the pointer.
   // If the field existed (HasField() is true), then the returned pointer will
   // If the field existed (HasField() is true), then the returned pointer will
   // be the same as the pointer returned by MutableMessage().
   // be the same as the pointer returned by MutableMessage().
   // This function has the same effect as ClearField().
   // This function has the same effect as ClearField().
-  virtual Message* ReleaseMessage(Message* message,
-                                  const FieldDescriptor* field,
-                                  MessageFactory* factory = NULL) const = 0;
+  Message* ReleaseMessage(Message* message, const FieldDescriptor* field,
+                          MessageFactory* factory = nullptr) const;
 
 
 
 
   // Repeated field getters ------------------------------------------
   // Repeated field getters ------------------------------------------
   // These get the value of one element of a repeated field.
   // These get the value of one element of a repeated field.
 
 
-  virtual int32 GetRepeatedInt32(const Message& message,
-                                 const FieldDescriptor* field,
-                                 int index) const = 0;
-  virtual int64 GetRepeatedInt64(const Message& message,
-                                 const FieldDescriptor* field,
-                                 int index) const = 0;
-  virtual uint32 GetRepeatedUInt32(const Message& message,
-                                   const FieldDescriptor* field,
-                                   int index) const = 0;
-  virtual uint64 GetRepeatedUInt64(const Message& message,
-                                   const FieldDescriptor* field,
-                                   int index) const = 0;
-  virtual float GetRepeatedFloat(const Message& message,
-                                 const FieldDescriptor* field,
-                                 int index) const = 0;
-  virtual double GetRepeatedDouble(const Message& message,
-                                   const FieldDescriptor* field,
-                                   int index) const = 0;
-  virtual bool GetRepeatedBool(const Message& message,
-                               const FieldDescriptor* field,
-                               int index) const = 0;
-  virtual std::string GetRepeatedString(const Message& message,
-                                        const FieldDescriptor* field,
-                                        int index) const = 0;
-  virtual const EnumValueDescriptor* GetRepeatedEnum(
-      const Message& message, const FieldDescriptor* field,
-      int index) const = 0;
+  int32 GetRepeatedInt32(const Message& message, const FieldDescriptor* field,
+                         int index) const;
+  int64 GetRepeatedInt64(const Message& message, const FieldDescriptor* field,
+                         int index) const;
+  uint32 GetRepeatedUInt32(const Message& message, const FieldDescriptor* field,
+                           int index) const;
+  uint64 GetRepeatedUInt64(const Message& message, const FieldDescriptor* field,
+                           int index) const;
+  float GetRepeatedFloat(const Message& message, const FieldDescriptor* field,
+                         int index) const;
+  double GetRepeatedDouble(const Message& message, const FieldDescriptor* field,
+                           int index) const;
+  bool GetRepeatedBool(const Message& message, const FieldDescriptor* field,
+                       int index) const;
+  std::string GetRepeatedString(const Message& message,
+                                const FieldDescriptor* field, int index) const;
+  const EnumValueDescriptor* GetRepeatedEnum(const Message& message,
+                                             const FieldDescriptor* field,
+                                             int index) const;
   // GetRepeatedEnumValue() returns an enum field's value as an integer rather
   // GetRepeatedEnumValue() returns an enum field's value as an integer rather
   // than an EnumValueDescriptor*. If the integer value does not correspond to a
   // than an EnumValueDescriptor*. If the integer value does not correspond to a
   // known value descriptor, a new value descriptor is created. (Such a value
   // known value descriptor, a new value descriptor is created. (Such a value
   // will only be present when the new unknown-enum-value semantics are enabled
   // will only be present when the new unknown-enum-value semantics are enabled
   // for a message.)
   // for a message.)
-  virtual int GetRepeatedEnumValue(const Message& message,
-                                   const FieldDescriptor* field,
-                                   int index) const = 0;
-  virtual const Message& GetRepeatedMessage(const Message& message,
-                                            const FieldDescriptor* field,
-                                            int index) const = 0;
+  int GetRepeatedEnumValue(const Message& message, const FieldDescriptor* field,
+                           int index) const;
+  const Message& GetRepeatedMessage(const Message& message,
+                                    const FieldDescriptor* field,
+                                    int index) const;
 
 
   // See GetStringReference(), above.
   // See GetStringReference(), above.
-  virtual const std::string& GetRepeatedStringReference(
-      const Message& message, const FieldDescriptor* field, int index,
-      std::string* scratch) const = 0;
+  const std::string& GetRepeatedStringReference(const Message& message,
+                                                const FieldDescriptor* field,
+                                                int index,
+                                                std::string* scratch) const;
 
 
 
 
   // Repeated field mutators -----------------------------------------
   // Repeated field mutators -----------------------------------------
   // These mutate the value of one element of a repeated field.
   // These mutate the value of one element of a repeated field.
 
 
-  virtual void SetRepeatedInt32(Message* message, const FieldDescriptor* field,
-                                int index, int32 value) const = 0;
-  virtual void SetRepeatedInt64(Message* message, const FieldDescriptor* field,
-                                int index, int64 value) const = 0;
-  virtual void SetRepeatedUInt32(Message* message, const FieldDescriptor* field,
-                                 int index, uint32 value) const = 0;
-  virtual void SetRepeatedUInt64(Message* message, const FieldDescriptor* field,
-                                 int index, uint64 value) const = 0;
-  virtual void SetRepeatedFloat(Message* message, const FieldDescriptor* field,
-                                int index, float value) const = 0;
-  virtual void SetRepeatedDouble(Message* message, const FieldDescriptor* field,
-                                 int index, double value) const = 0;
-  virtual void SetRepeatedBool(Message* message, const FieldDescriptor* field,
-                               int index, bool value) const = 0;
-  virtual void SetRepeatedString(Message* message, const FieldDescriptor* field,
-                                 int index, const std::string& value) const = 0;
-  virtual void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
-                               int index,
-                               const EnumValueDescriptor* value) const = 0;
+  void SetRepeatedInt32(Message* message, const FieldDescriptor* field,
+                        int index, int32 value) const;
+  void SetRepeatedInt64(Message* message, const FieldDescriptor* field,
+                        int index, int64 value) const;
+  void SetRepeatedUInt32(Message* message, const FieldDescriptor* field,
+                         int index, uint32 value) const;
+  void SetRepeatedUInt64(Message* message, const FieldDescriptor* field,
+                         int index, uint64 value) const;
+  void SetRepeatedFloat(Message* message, const FieldDescriptor* field,
+                        int index, float value) const;
+  void SetRepeatedDouble(Message* message, const FieldDescriptor* field,
+                         int index, double value) const;
+  void SetRepeatedBool(Message* message, const FieldDescriptor* field,
+                       int index, bool value) const;
+  void SetRepeatedString(Message* message, const FieldDescriptor* field,
+                         int index, const std::string& value) const;
+  void SetRepeatedEnum(Message* message, const FieldDescriptor* field,
+                       int index, const EnumValueDescriptor* value) const;
   // Set an enum field's value with an integer rather than EnumValueDescriptor.
   // Set an enum field's value with an integer rather than EnumValueDescriptor.
   // For proto3 this is just setting the enum field to the value specified, for
   // For proto3 this is just setting the enum field to the value specified, for
   // proto2 it's more complicated. If value is a known enum value the field is
   // proto2 it's more complicated. If value is a known enum value the field is
@@ -683,37 +648,36 @@ class PROTOBUF_EXPORT Reflection {
   // set. Note this matches the behavior of parsing unknown enum values.
   // set. Note this matches the behavior of parsing unknown enum values.
   // If multiple calls with unknown values happen than they are all added to the
   // If multiple calls with unknown values happen than they are all added to the
   // unknown field set in order of the calls.
   // unknown field set in order of the calls.
-  virtual void SetRepeatedEnumValue(Message* message,
-                                    const FieldDescriptor* field, int index,
-                                    int value) const = 0;
+  void SetRepeatedEnumValue(Message* message, const FieldDescriptor* field,
+                            int index, int value) const;
   // Get a mutable pointer to an element of a repeated field with a message
   // Get a mutable pointer to an element of a repeated field with a message
   // type.
   // type.
-  virtual Message* MutableRepeatedMessage(Message* message,
-                                          const FieldDescriptor* field,
-                                          int index) const = 0;
+  Message* MutableRepeatedMessage(Message* message,
+                                  const FieldDescriptor* field,
+                                  int index) const;
 
 
 
 
   // Repeated field adders -------------------------------------------
   // Repeated field adders -------------------------------------------
   // These add an element to a repeated field.
   // These add an element to a repeated field.
 
 
-  virtual void AddInt32(Message* message, const FieldDescriptor* field,
-                        int32 value) const = 0;
-  virtual void AddInt64(Message* message, const FieldDescriptor* field,
-                        int64 value) const = 0;
-  virtual void AddUInt32(Message* message, const FieldDescriptor* field,
-                         uint32 value) const = 0;
-  virtual void AddUInt64(Message* message, const FieldDescriptor* field,
-                         uint64 value) const = 0;
-  virtual void AddFloat(Message* message, const FieldDescriptor* field,
-                        float value) const = 0;
-  virtual void AddDouble(Message* message, const FieldDescriptor* field,
-                         double value) const = 0;
-  virtual void AddBool(Message* message, const FieldDescriptor* field,
-                       bool value) const = 0;
-  virtual void AddString(Message* message, const FieldDescriptor* field,
-                         const std::string& value) const = 0;
-  virtual void AddEnum(Message* message, const FieldDescriptor* field,
-                       const EnumValueDescriptor* value) const = 0;
+  void AddInt32(Message* message, const FieldDescriptor* field,
+                int32 value) const;
+  void AddInt64(Message* message, const FieldDescriptor* field,
+                int64 value) const;
+  void AddUInt32(Message* message, const FieldDescriptor* field,
+                 uint32 value) const;
+  void AddUInt64(Message* message, const FieldDescriptor* field,
+                 uint64 value) const;
+  void AddFloat(Message* message, const FieldDescriptor* field,
+                float value) const;
+  void AddDouble(Message* message, const FieldDescriptor* field,
+                 double value) const;
+  void AddBool(Message* message, const FieldDescriptor* field,
+               bool value) const;
+  void AddString(Message* message, const FieldDescriptor* field,
+                 const std::string& value) const;
+  void AddEnum(Message* message, const FieldDescriptor* field,
+               const EnumValueDescriptor* value) const;
   // Add an integer value to a repeated enum field rather than
   // Add an integer value to a repeated enum field rather than
   // EnumValueDescriptor. For proto3 this is just setting the enum field to the
   // EnumValueDescriptor. For proto3 this is just setting the enum field to the
   // value specified, for proto2 it's more complicated. If value is a known enum
   // value specified, for proto2 it's more complicated. If value is a known enum
@@ -721,19 +685,16 @@ class PROTOBUF_EXPORT Reflection {
   // to the unknown field set. Note this matches the behavior of parsing unknown
   // to the unknown field set. Note this matches the behavior of parsing unknown
   // enum values. If multiple calls with unknown values happen than they are all
   // enum values. If multiple calls with unknown values happen than they are all
   // added to the unknown field set in order of the calls.
   // added to the unknown field set in order of the calls.
-  virtual void AddEnumValue(Message* message, const FieldDescriptor* field,
-                            int value) const = 0;
+  void AddEnumValue(Message* message, const FieldDescriptor* field,
+                    int value) const;
   // See MutableMessage() for comments on the "factory" parameter.
   // See MutableMessage() for comments on the "factory" parameter.
-  virtual Message* AddMessage(Message* message, const FieldDescriptor* field,
-                              MessageFactory* factory = NULL) const = 0;
+  Message* AddMessage(Message* message, const FieldDescriptor* field,
+                      MessageFactory* factory = nullptr) const;
 
 
   // Appends an already-allocated object 'new_entry' to the repeated field
   // Appends an already-allocated object 'new_entry' to the repeated field
   // specified by 'field' passing ownership to the message.
   // specified by 'field' passing ownership to the message.
-  // TODO(tmarek): Make virtual after all subclasses have been
-  // updated.
-  virtual void AddAllocatedMessage(Message* message,
-                                   const FieldDescriptor* field,
-                                   Message* new_entry) const;
+  void AddAllocatedMessage(Message* message, const FieldDescriptor* field,
+                           Message* new_entry) const;
 
 
 
 
   // Get a RepeatedFieldRef object that can be used to read the underlying
   // Get a RepeatedFieldRef object that can be used to read the underlying
@@ -821,14 +782,17 @@ class PROTOBUF_EXPORT Reflection {
   // Extensions ----------------------------------------------------------------
   // Extensions ----------------------------------------------------------------
 
 
   // Try to find an extension of this message type by fully-qualified field
   // Try to find an extension of this message type by fully-qualified field
-  // name.  Returns NULL if no extension is known for this name or number.
-  virtual const FieldDescriptor* FindKnownExtensionByName(
-      const std::string& name) const = 0;
+  // name.  Returns nullptr if no extension is known for this name or number.
+  PROTOBUF_DEPRECATED_MSG(
+      "Please use DescriptorPool::FindExtensionByPrintableName instead")
+  const FieldDescriptor* FindKnownExtensionByName(
+      const std::string& name) const;
 
 
   // Try to find an extension of this message type by field number.
   // Try to find an extension of this message type by field number.
-  // Returns NULL if no extension is known for this name or number.
-  virtual const FieldDescriptor* FindKnownExtensionByNumber(
-      int number) const = 0;
+  // Returns nullptr if no extension is known for this name or number.
+  PROTOBUF_DEPRECATED_MSG(
+      "Please use DescriptorPool::FindExtensionByNumber instead")
+  const FieldDescriptor* FindKnownExtensionByNumber(int number) const;
 
 
   // Feature Flags -------------------------------------------------------------
   // Feature Flags -------------------------------------------------------------
 
 
@@ -849,7 +813,7 @@ class PROTOBUF_EXPORT Reflection {
   //     reflection->SetEnumValue(message, field, new_value);
   //     reflection->SetEnumValue(message, field, new_value);
   //   } else {
   //   } else {
   //     if (field_descriptor->enum_type()->
   //     if (field_descriptor->enum_type()->
-  //             FindValueByNumber(new_value) != NULL) {
+  //             FindValueByNumber(new_value) != nullptr) {
   //       reflection->SetEnumValue(message, field, new_value);
   //       reflection->SetEnumValue(message, field, new_value);
   //     } else if (emit_unknown_enum_values) {
   //     } else if (emit_unknown_enum_values) {
   //       reflection->MutableUnknownFields(message)->AddVarint(
   //       reflection->MutableUnknownFields(message)->AddVarint(
@@ -860,7 +824,7 @@ class PROTOBUF_EXPORT Reflection {
   //       reflection->SetEnumValue(message, field, new_value);
   //       reflection->SetEnumValue(message, field, new_value);
   //     }
   //     }
   //   }
   //   }
-  virtual bool SupportsUnknownEnumValues() const { return false; }
+  bool SupportsUnknownEnumValues() const;
 
 
   // Returns the MessageFactory associated with this message.  This can be
   // Returns the MessageFactory associated with this message.  This can be
   // useful for determining if a message is a generated message or not, for
   // useful for determining if a message is a generated message or not, for
@@ -871,60 +835,63 @@ class PROTOBUF_EXPORT Reflection {
   //   }
   //   }
   // It can also be used to create more messages of this type, though
   // It can also be used to create more messages of this type, though
   // Message::New() is an easier way to accomplish this.
   // Message::New() is an easier way to accomplish this.
-  virtual MessageFactory* GetMessageFactory() const;
+  MessageFactory* GetMessageFactory() const;
 
 
-  // ---------------------------------------------------------------------------
-
- protected:
+ private:
   // Obtain a pointer to a Repeated Field Structure and do some type checking:
   // Obtain a pointer to a Repeated Field Structure and do some type checking:
   //   on field->cpp_type(),
   //   on field->cpp_type(),
   //   on field->field_option().ctype() (if ctype >= 0)
   //   on field->field_option().ctype() (if ctype >= 0)
-  //   of field->message_type() (if message_type != NULL).
+  //   of field->message_type() (if message_type != nullptr).
   // We use 2 routine rather than 4 (const vs mutable) x (scalar vs pointer).
   // We use 2 routine rather than 4 (const vs mutable) x (scalar vs pointer).
-  virtual void* MutableRawRepeatedField(
-      Message* message, const FieldDescriptor* field, FieldDescriptor::CppType,
-      int ctype, const Descriptor* message_type) const = 0;
-
-  // TODO(jieluo) - make it pure virtual after updating all the subclasses.
-  virtual const void* GetRawRepeatedField(
-      const Message& message, const FieldDescriptor* field,
-      FieldDescriptor::CppType cpptype, int ctype,
-      const Descriptor* message_type) const {
-    return MutableRawRepeatedField(const_cast<Message*>(&message), field,
-                                   cpptype, ctype, message_type);
-  }
+  void* MutableRawRepeatedField(Message* message, const FieldDescriptor* field,
+                                FieldDescriptor::CppType, int ctype,
+                                const Descriptor* message_type) const;
+
+  const void* GetRawRepeatedField(const Message& message,
+                                  const FieldDescriptor* field,
+                                  FieldDescriptor::CppType cpptype, int ctype,
+                                  const Descriptor* message_type) const;
 
 
   // The following methods are used to implement (Mutable)RepeatedFieldRef.
   // The following methods are used to implement (Mutable)RepeatedFieldRef.
   // A Ref object will store a raw pointer to the repeated field data (obtained
   // A Ref object will store a raw pointer to the repeated field data (obtained
   // from RepeatedFieldData()) and a pointer to a Accessor (obtained from
   // from RepeatedFieldData()) and a pointer to a Accessor (obtained from
   // RepeatedFieldAccessor) which will be used to access the raw data.
   // RepeatedFieldAccessor) which will be used to access the raw data.
-  //
-  // TODO(xiaofeng): Make these methods pure-virtual.
 
 
   // Returns a raw pointer to the repeated field
   // Returns a raw pointer to the repeated field
   //
   //
   // "cpp_type" and "message_type" are deduced from the type parameter T passed
   // "cpp_type" and "message_type" are deduced from the type parameter T passed
   // to Get(Mutable)RepeatedFieldRef. If T is a generated message type,
   // to Get(Mutable)RepeatedFieldRef. If T is a generated message type,
   // "message_type" should be set to its descriptor. Otherwise "message_type"
   // "message_type" should be set to its descriptor. Otherwise "message_type"
-  // should be set to NULL. Implementations of this method should check whether
-  // "cpp_type"/"message_type" is consistent with the actual type of the field.
-  // We use 1 routine rather than 2 (const vs mutable) because it is protected
-  // and it doesn't change the message.
-  virtual void* RepeatedFieldData(Message* message,
-                                  const FieldDescriptor* field,
-                                  FieldDescriptor::CppType cpp_type,
-                                  const Descriptor* message_type) const;
+  // should be set to nullptr. Implementations of this method should check
+  // whether "cpp_type"/"message_type" is consistent with the actual type of the
+  // field. We use 1 routine rather than 2 (const vs mutable) because it is
+  // protected and it doesn't change the message.
+  void* RepeatedFieldData(Message* message, const FieldDescriptor* field,
+                          FieldDescriptor::CppType cpp_type,
+                          const Descriptor* message_type) const;
 
 
   // The returned pointer should point to a singleton instance which implements
   // The returned pointer should point to a singleton instance which implements
   // the RepeatedFieldAccessor interface.
   // the RepeatedFieldAccessor interface.
-  virtual const internal::RepeatedFieldAccessor* RepeatedFieldAccessor(
+  const internal::RepeatedFieldAccessor* RepeatedFieldAccessor(
       const FieldDescriptor* field) const;
       const FieldDescriptor* field) const;
 
 
- private:
+  const Descriptor* const descriptor_;
+  const internal::ReflectionSchema schema_;
+  const DescriptorPool* const descriptor_pool_;
+  MessageFactory* const message_factory_;
+
+  // Last non weak field index. This is an optimization when most weak fields
+  // are at the end of the containing message. If a message proto doesn't
+  // contain weak fields, then this field equals descriptor_->field_count().
+  int last_non_weak_field_index_;
+
   template <typename T, typename Enable>
   template <typename T, typename Enable>
   friend class RepeatedFieldRef;
   friend class RepeatedFieldRef;
   template <typename T, typename Enable>
   template <typename T, typename Enable>
   friend class MutableRepeatedFieldRef;
   friend class MutableRepeatedFieldRef;
+  friend class ::PROTOBUF_NAMESPACE_ID::MessageLayoutInspector;
+  friend class ::PROTOBUF_NAMESPACE_ID::AssignDescriptorsHelper;
+  friend class DynamicMessageFactory;
   friend class python::MapReflectionFriend;
   friend class python::MapReflectionFriend;
 #define GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND
 #define GOOGLE_PROTOBUF_HAS_CEL_MAP_REFLECTION_FRIEND
   friend class expr::CelMapReflectionFriend;
   friend class expr::CelMapReflectionFriend;
@@ -936,6 +903,10 @@ class PROTOBUF_EXPORT Reflection {
   friend class internal::MapFieldPrinterHelper;
   friend class internal::MapFieldPrinterHelper;
   friend class internal::ReflectionAccessor;
   friend class internal::ReflectionAccessor;
 
 
+  Reflection(const Descriptor* descriptor,
+             const internal::ReflectionSchema& schema,
+             const DescriptorPool* pool, MessageFactory* factory);
+
   // Special version for specialized implementations of string.  We can't
   // Special version for specialized implementations of string.  We can't
   // call MutableRawRepeatedField directly here because we don't have access to
   // call MutableRawRepeatedField directly here because we don't have access to
   // FieldOptions::* which are defined in descriptor.pb.h.  Including that
   // FieldOptions::* which are defined in descriptor.pb.h.  Including that
@@ -946,63 +917,150 @@ class PROTOBUF_EXPORT Reflection {
                                  bool is_string) const;
                                  bool is_string) const;
 
 
   friend class MapReflectionTester;
   friend class MapReflectionTester;
-  // TODO(jieluo) - make the map APIs pure virtual after updating
-  // all the subclasses.
   // Returns true if key is in map. Returns false if key is not in map field.
   // Returns true if key is in map. Returns false if key is not in map field.
-  virtual bool ContainsMapKey(const Message& /* message */,
-                              const FieldDescriptor* /* field */,
-                              const MapKey& /* key */) const {
-    return false;
-  }
+  bool ContainsMapKey(const Message& message, const FieldDescriptor* field,
+                      const MapKey& key) const;
 
 
   // If key is in map field: Saves the value pointer to val and returns
   // If key is in map field: Saves the value pointer to val and returns
   // false. If key in not in map field: Insert the key into map, saves
   // false. If key in not in map field: Insert the key into map, saves
   // value pointer to val and retuns true.
   // value pointer to val and retuns true.
-  virtual bool InsertOrLookupMapValue(Message* /* message */,
-                                      const FieldDescriptor* /* field */,
-                                      const MapKey& /* key */,
-                                      MapValueRef* /* val */) const {
-    return false;
-  }
+  bool InsertOrLookupMapValue(Message* message, const FieldDescriptor* field,
+                              const MapKey& key, MapValueRef* val) const;
 
 
   // Delete and returns true if key is in the map field. Returns false
   // Delete and returns true if key is in the map field. Returns false
   // otherwise.
   // otherwise.
-  virtual bool DeleteMapValue(Message* /* message */,
-                              const FieldDescriptor* /* field */,
-                              const MapKey& /* key */) const {
-    return false;
-  }
+  bool DeleteMapValue(Message* message, const FieldDescriptor* field,
+                      const MapKey& key) const;
 
 
   // Returns a MapIterator referring to the first element in the map field.
   // Returns a MapIterator referring to the first element in the map field.
   // If the map field is empty, this function returns the same as
   // If the map field is empty, this function returns the same as
   // reflection::MapEnd. Mutation to the field may invalidate the iterator.
   // reflection::MapEnd. Mutation to the field may invalidate the iterator.
-  virtual MapIterator MapBegin(Message* message,
-                               const FieldDescriptor* field) const;
+  MapIterator MapBegin(Message* message, const FieldDescriptor* field) const;
 
 
   // Returns a MapIterator referring to the theoretical element that would
   // Returns a MapIterator referring to the theoretical element that would
   // follow the last element in the map field. It does not point to any
   // follow the last element in the map field. It does not point to any
   // real element. Mutation to the field may invalidate the iterator.
   // real element. Mutation to the field may invalidate the iterator.
-  virtual MapIterator MapEnd(Message* message,
-                             const FieldDescriptor* field) const;
+  MapIterator MapEnd(Message* message, const FieldDescriptor* field) const;
 
 
   // Get the number of <key, value> pair of a map field. The result may be
   // Get the number of <key, value> pair of a map field. The result may be
   // different from FieldSize which can have duplicate keys.
   // different from FieldSize which can have duplicate keys.
-  virtual int MapSize(const Message& /* message */,
-                      const FieldDescriptor* /* field */) const {
-    return 0;
-  }
+  int MapSize(const Message& message, const FieldDescriptor* field) const;
 
 
   // Help method for MapIterator.
   // Help method for MapIterator.
   friend class MapIterator;
   friend class MapIterator;
-  virtual internal::MapFieldBase* MutableMapData(
-      Message* /* message */, const FieldDescriptor* /* field */) const {
-    return NULL;
-  }
+  internal::MapFieldBase* MutableMapData(Message* message,
+                                         const FieldDescriptor* field) const;
+
+  const internal::MapFieldBase* GetMapData(const Message& message,
+                                           const FieldDescriptor* field) const;
+
+  template <class T>
+  const T& GetRawNonOneof(const Message& message,
+                          const FieldDescriptor* field) const;
+  template <class T>
+  T* MutableRawNonOneof(Message* message, const FieldDescriptor* field) const;
+
+  template <typename Type>
+  const Type& GetRaw(const Message& message,
+                     const FieldDescriptor* field) const;
+  template <typename Type>
+  inline Type* MutableRaw(Message* message, const FieldDescriptor* field) const;
+  template <typename Type>
+  inline const Type& DefaultRaw(const FieldDescriptor* field) const;
+
+  inline const uint32* GetHasBits(const Message& message) const;
+  inline uint32* MutableHasBits(Message* message) const;
+  inline uint32 GetOneofCase(const Message& message,
+                             const OneofDescriptor* oneof_descriptor) const;
+  inline uint32* MutableOneofCase(
+      Message* message, const OneofDescriptor* oneof_descriptor) const;
+  inline const internal::ExtensionSet& GetExtensionSet(
+      const Message& message) const;
+  inline internal::ExtensionSet* MutableExtensionSet(Message* message) const;
+  inline Arena* GetArena(Message* message) const;
+
+  inline const internal::InternalMetadataWithArena&
+  GetInternalMetadataWithArena(const Message& message) const;
+
+  inline internal::InternalMetadataWithArena* MutableInternalMetadataWithArena(
+      Message* message) const;
+
+  inline bool IsInlined(const FieldDescriptor* field) const;
+
+  inline bool HasBit(const Message& message,
+                     const FieldDescriptor* field) const;
+  inline void SetBit(Message* message, const FieldDescriptor* field) const;
+  inline void ClearBit(Message* message, const FieldDescriptor* field) const;
+  inline void SwapBit(Message* message1, Message* message2,
+                      const FieldDescriptor* field) const;
+
+  // This function only swaps the field. Should swap corresponding has_bit
+  // before or after using this function.
+  void SwapField(Message* message1, Message* message2,
+                 const FieldDescriptor* field) const;
+
+  void SwapOneofField(Message* message1, Message* message2,
+                      const OneofDescriptor* oneof_descriptor) const;
+
+  inline bool HasOneofField(const Message& message,
+                            const FieldDescriptor* field) const;
+  inline void SetOneofCase(Message* message,
+                           const FieldDescriptor* field) const;
+  inline void ClearOneofField(Message* message,
+                              const FieldDescriptor* field) const;
+
+  template <typename Type>
+  inline const Type& GetField(const Message& message,
+                              const FieldDescriptor* field) const;
+  template <typename Type>
+  inline void SetField(Message* message, const FieldDescriptor* field,
+                       const Type& value) const;
+  template <typename Type>
+  inline Type* MutableField(Message* message,
+                            const FieldDescriptor* field) const;
+  template <typename Type>
+  inline const Type& GetRepeatedField(const Message& message,
+                                      const FieldDescriptor* field,
+                                      int index) const;
+  template <typename Type>
+  inline const Type& GetRepeatedPtrField(const Message& message,
+                                         const FieldDescriptor* field,
+                                         int index) const;
+  template <typename Type>
+  inline void SetRepeatedField(Message* message, const FieldDescriptor* field,
+                               int index, Type value) const;
+  template <typename Type>
+  inline Type* MutableRepeatedField(Message* message,
+                                    const FieldDescriptor* field,
+                                    int index) const;
+  template <typename Type>
+  inline void AddField(Message* message, const FieldDescriptor* field,
+                       const Type& value) const;
+  template <typename Type>
+  inline Type* AddField(Message* message, const FieldDescriptor* field) const;
+
+  int GetExtensionNumberOrDie(const Descriptor* type) const;
+
+  // Internal versions of EnumValue API perform no checking. Called after checks
+  // by public methods.
+  void SetEnumValueInternal(Message* message, const FieldDescriptor* field,
+                            int value) const;
+  void SetRepeatedEnumValueInternal(Message* message,
+                                    const FieldDescriptor* field, int index,
+                                    int value) const;
+  void AddEnumValueInternal(Message* message, const FieldDescriptor* field,
+                            int value) const;
 
 
-  virtual const internal::MapFieldBase* GetMapData(
-      const Message& /* message */, const FieldDescriptor* /* field */) const {
-    return NULL;
-  }
+  Message* UnsafeArenaReleaseMessage(Message* message,
+                                     const FieldDescriptor* field,
+                                     MessageFactory* factory = nullptr) const;
+
+  void UnsafeArenaSetAllocatedMessage(Message* message, Message* sub_message,
+                                      const FieldDescriptor* field) const;
+
+  friend inline  // inline so nobody can call this function.
+      void
+      RegisterAllTypesInternal(const Metadata* file_level_metadata, int size);
 
 
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(Reflection);
 };
 };
@@ -1027,7 +1085,7 @@ class PROTOBUF_EXPORT MessageFactory {
   // outlive the MessageFactory.
   // outlive the MessageFactory.
   //
   //
   // Some implementations do not support all types.  GetPrototype() will
   // Some implementations do not support all types.  GetPrototype() will
-  // return NULL if the descriptor passed in is not supported.
+  // return nullptr if the descriptor passed in is not supported.
   //
   //
   // This method may or may not be thread-safe depending on the implementation.
   // This method may or may not be thread-safe depending on the implementation.
   // Each implementation should document its own degree thread-safety.
   // Each implementation should document its own degree thread-safety.
@@ -1039,7 +1097,7 @@ class PROTOBUF_EXPORT MessageFactory {
   //     FooMessage::descriptor()) == FooMessage::default_instance()
   //     FooMessage::descriptor()) == FooMessage::default_instance()
   // This factory supports all types which are found in
   // This factory supports all types which are found in
   // DescriptorPool::generated_pool().  If given a descriptor from any other
   // DescriptorPool::generated_pool().  If given a descriptor from any other
-  // pool, GetPrototype() will return NULL.  (You can also check if a
+  // pool, GetPrototype() will return nullptr.  (You can also check if a
   // descriptor is for a generated message by checking if
   // descriptor is for a generated message by checking if
   // descriptor->file()->pool() == DescriptorPool::generated_pool().)
   // descriptor->file()->pool() == DescriptorPool::generated_pool().)
   //
   //
@@ -1091,8 +1149,8 @@ DECLARE_GET_REPEATED_FIELD(bool)
 
 
 #undef DECLARE_GET_REPEATED_FIELD
 #undef DECLARE_GET_REPEATED_FIELD
 
 
-// Tries to downcast this message to a generated message type.  Returns NULL if
-// this class is not an instance of T.  This works even if RTTI is disabled.
+// Tries to downcast this message to a generated message type.  Returns nullptr
+// if this class is not an instance of T.  This works even if RTTI is disabled.
 //
 //
 // This also has the effect of creating a strong reference to T that will
 // This also has the effect of creating a strong reference to T that will
 // prevent the linker from stripping it out at link time.  This can be important
 // prevent the linker from stripping it out at link time.  This can be important
@@ -1180,14 +1238,14 @@ template <>
 inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrField(
 inline const RepeatedPtrField<Message>& Reflection::GetRepeatedPtrField(
     const Message& message, const FieldDescriptor* field) const {
     const Message& message, const FieldDescriptor* field) const {
   return *static_cast<const RepeatedPtrField<Message>*>(GetRawRepeatedField(
   return *static_cast<const RepeatedPtrField<Message>*>(GetRawRepeatedField(
-      message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1, NULL));
+      message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1, nullptr));
 }
 }
 
 
 template <>
 template <>
 inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrField(
 inline RepeatedPtrField<Message>* Reflection::MutableRepeatedPtrField(
     Message* message, const FieldDescriptor* field) const {
     Message* message, const FieldDescriptor* field) const {
   return static_cast<RepeatedPtrField<Message>*>(MutableRawRepeatedField(
   return static_cast<RepeatedPtrField<Message>*>(MutableRawRepeatedField(
-      message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1, NULL));
+      message, field, FieldDescriptor::CPPTYPE_MESSAGE, -1, nullptr));
 }
 }
 
 
 template <typename PB>
 template <typename PB>

+ 4 - 6
src/google/protobuf/message_unittest.inc

@@ -46,7 +46,11 @@
 #include <fstream>
 #include <fstream>
 #include <sstream>
 #include <sstream>
 
 
+#include <google/protobuf/stubs/logging.h>
+#include <google/protobuf/stubs/common.h>
+#include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/test_util2.h>
 #include <google/protobuf/test_util2.h>
+#include <google/protobuf/io/io_win32.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/coded_stream.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
@@ -54,14 +58,9 @@
 #include <google/protobuf/arena.h>
 #include <google/protobuf/arena.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/generated_message_reflection.h>
 #include <google/protobuf/generated_message_reflection.h>
-
-#include <google/protobuf/stubs/logging.h>
-#include <google/protobuf/stubs/common.h>
-#include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/testing/googletest.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 #include <gtest/gtest.h>
 
 
-#include <google/protobuf/io/io_win32.h>
 
 
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
@@ -630,6 +629,5 @@ TEST(MESSAGE_TEST_NAME, MOMIParserEdgeCases) {
 }
 }
 
 
 
 
-
 }  // namespace protobuf
 }  // namespace protobuf
 }  // namespace google
 }  // namespace google

+ 33 - 21
src/google/protobuf/repeated_field.h

@@ -83,6 +83,7 @@ namespace google {
 namespace protobuf {
 namespace protobuf {
 
 
 class Message;
 class Message;
+class Reflection;
 
 
 namespace internal {
 namespace internal {
 
 
@@ -147,6 +148,11 @@ class RepeatedField final {
   // Appends a new element and return a pointer to it.
   // Appends a new element and return a pointer to it.
   // The new element is uninitialized if |Element| is a POD type.
   // The new element is uninitialized if |Element| is a POD type.
   Element* Add();
   Element* Add();
+  // Append elements in the range [begin, end) after reserving
+  // the appropriate number of elements.
+  template <typename Iter>
+  void Add(Iter begin, Iter end);
+
   // Remove the last element in the array.
   // Remove the last element in the array.
   void RemoveLast();
   void RemoveLast();
 
 
@@ -630,7 +636,7 @@ class PROTOBUF_EXPORT RepeatedPtrFieldBase {
   // The reflection implementation needs to call protected methods directly,
   // The reflection implementation needs to call protected methods directly,
   // reinterpreting pointers as being to Message instead of a specific Message
   // reinterpreting pointers as being to Message instead of a specific Message
   // subclass.
   // subclass.
-  friend class GeneratedMessageReflection;
+  friend class ::PROTOBUF_NAMESPACE_ID::Reflection;
 
 
   // ExtensionSet stores repeated message extensions as
   // ExtensionSet stores repeated message extensions as
   // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to implement
   // RepeatedPtrField<MessageLite>, but non-lite ExtensionSets need to implement
@@ -1071,26 +1077,7 @@ template <typename Element>
 template <typename Iter>
 template <typename Iter>
 RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
 RepeatedField<Element>::RepeatedField(Iter begin, const Iter& end)
     : current_size_(0), total_size_(0), ptr_(NULL) {
     : current_size_(0), total_size_(0), ptr_(NULL) {
-  int reserve = internal::CalculateReserve(begin, end);
-  if (reserve != -1) {
-    if (reserve == 0) {
-      return;
-    }
-
-    Reserve(reserve);
-    // TODO(ckennelly):  The compiler loses track of the buffer freshly
-    // allocated by Reserve() by the time we call elements, so it cannot
-    // guarantee that elements does not alias [begin(), end()).
-    //
-    // If restrict is available, annotating the pointer obtained from elements()
-    // causes this to lower to memcpy instead of memmove.
-    std::copy(begin, end, elements());
-    current_size_ = reserve;
-  } else {
-    for (; begin != end; ++begin) {
-      Add(*begin);
-    }
-  }
+  Add(begin, end);
 }
 }
 
 
 template <typename Element>
 template <typename Element>
@@ -1234,6 +1221,31 @@ inline Element* RepeatedField<Element>::Add() {
   return &elements()[current_size_++];
   return &elements()[current_size_++];
 }
 }
 
 
+template <typename Element>
+template <typename Iter>
+inline void RepeatedField<Element>::Add(Iter begin, Iter end) {
+  int reserve = internal::CalculateReserve(begin, end);
+  if (reserve != -1) {
+    if (reserve == 0) {
+      return;
+    }
+
+    Reserve(reserve + size());
+    // TODO(ckennelly):  The compiler loses track of the buffer freshly
+    // allocated by Reserve() by the time we call elements, so it cannot
+    // guarantee that elements does not alias [begin(), end()).
+    //
+    // If restrict is available, annotating the pointer obtained from elements()
+    // causes this to lower to memcpy instead of memmove.
+    std::copy(begin, end, elements() + size());
+    current_size_ = reserve + size();
+  } else {
+    for (; begin != end; ++begin) {
+      Add(*begin);
+    }
+  }
+}
+
 template <typename Element>
 template <typename Element>
 inline void RepeatedField<Element>::RemoveLast() {
 inline void RepeatedField<Element>::RemoveLast() {
   GOOGLE_DCHECK_GT(current_size_, 0);
   GOOGLE_DCHECK_GT(current_size_, 0);

+ 68 - 2
src/google/protobuf/repeated_field_unittest.cc

@@ -35,14 +35,15 @@
 // TODO(kenton):  Improve this unittest to bring it up to the standards of
 // TODO(kenton):  Improve this unittest to bring it up to the standards of
 //   other proto2 unittests.
 //   other proto2 unittests.
 
 
+#include <google/protobuf/repeated_field.h>
+
 #include <algorithm>
 #include <algorithm>
 #include <limits>
 #include <limits>
 #include <list>
 #include <list>
+#include <sstream>
 #include <type_traits>
 #include <type_traits>
 #include <vector>
 #include <vector>
 
 
-#include <google/protobuf/repeated_field.h>
-
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/unittest.pb.h>
 #include <google/protobuf/unittest.pb.h>
@@ -343,6 +344,71 @@ TEST(RepeatedField, Erase) {
   EXPECT_EQ(8, me.Get(2));
   EXPECT_EQ(8, me.Get(2));
 }
 }
 
 
+// Add contents of empty container to an empty field.
+TEST(RepeatedField, AddRange1) {
+  RepeatedField<int> me;
+  std::vector<int> values;
+
+  me.Add(values.begin(), values.end());
+  ASSERT_EQ(me.size(), 0);
+}
+
+// Add contents of container with one thing to an empty field.
+TEST(RepeatedField, AddRange2) {
+  RepeatedField<int> me;
+  std::vector<int> values;
+  values.push_back(-1);
+
+  me.Add(values.begin(), values.end());
+  ASSERT_EQ(me.size(), 1);
+  ASSERT_EQ(me.Get(0), values[0]);
+}
+
+// Add contents of container with more than one thing to an empty field.
+TEST(RepeatedField, AddRange3) {
+  RepeatedField<int> me;
+  std::vector<int> values;
+  values.push_back(0);
+  values.push_back(1);
+
+  me.Add(values.begin(), values.end());
+  ASSERT_EQ(me.size(), 2);
+  ASSERT_EQ(me.Get(0), values[0]);
+  ASSERT_EQ(me.Get(1), values[1]);
+}
+
+// Add contents of container with more than one thing to a non-empty field.
+TEST(RepeatedField, AddRange4) {
+  RepeatedField<int> me;
+  me.Add(0);
+  me.Add(1);
+
+  std::vector<int> values;
+  values.push_back(2);
+  values.push_back(3);
+
+  me.Add(values.begin(), values.end());
+  ASSERT_EQ(me.size(), 4);
+  ASSERT_EQ(me.Get(0), 0);
+  ASSERT_EQ(me.Get(1), 1);
+  ASSERT_EQ(me.Get(2), values[0]);
+  ASSERT_EQ(me.Get(3), values[1]);
+}
+
+// Add contents of a stringstream in order to test code paths where there is
+// an input iterator.
+TEST(RepeatedField, AddRange5) {
+  RepeatedField<int> me;
+
+  std::stringstream ss;
+  ss << 1 << ' ' << 2;
+
+  me.Add(std::istream_iterator<int>(ss), std::istream_iterator<int>());
+  ASSERT_EQ(me.size(), 2);
+  ASSERT_EQ(me.Get(0), 1);
+  ASSERT_EQ(me.Get(1), 2);
+}
+
 TEST(RepeatedField, CopyConstruct) {
 TEST(RepeatedField, CopyConstruct) {
   RepeatedField<int> source;
   RepeatedField<int> source;
   source.Add(1);
   source.Add(1);

+ 1 - 1
src/google/protobuf/source_context.pb.cc

@@ -55,7 +55,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_SourceContext_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2fsource_5fcontext_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n$google/protobuf/source_context.proto\022\017"
   "\n$google/protobuf/source_context.proto\022\017"
   "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile"
   "google.protobuf\"\"\n\rSourceContext\022\021\n\tfile"
   "_name\030\001 \001(\tB\225\001\n\023com.google.protobufB\022Sou"
   "_name\030\001 \001(\tB\225\001\n\023com.google.protobufB\022Sou"

+ 1 - 1
src/google/protobuf/struct.pb.cc

@@ -124,7 +124,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_ListValue_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2fstruct_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\034google/protobuf/struct.proto\022\017google.p"
   "\n\034google/protobuf/struct.proto\022\017google.p"
   "rotobuf\"\204\001\n\006Struct\0223\n\006fields\030\001 \003(\0132#.goo"
   "rotobuf\"\204\001\n\006Struct\0223\n\006fields\030\001 \003(\0132#.goo"
   "gle.protobuf.Struct.FieldsEntry\032E\n\013Field"
   "gle.protobuf.Struct.FieldsEntry\032E\n\013Field"

+ 47 - 51
src/google/protobuf/text_format.cc

@@ -153,7 +153,7 @@ TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::CreateNested(
 }
 }
 
 
 void CheckFieldIndex(const FieldDescriptor* field, int index) {
 void CheckFieldIndex(const FieldDescriptor* field, int index) {
-  if (field == NULL) {
+  if (field == nullptr) {
     return;
     return;
   }
   }
 
 
@@ -175,7 +175,7 @@ TextFormat::ParseLocation TextFormat::ParseInfoTree::GetLocation(
 
 
   const std::vector<TextFormat::ParseLocation>* locations =
   const std::vector<TextFormat::ParseLocation>* locations =
       FindOrNull(locations_, field);
       FindOrNull(locations_, field);
-  if (locations == NULL || index >= locations->size()) {
+  if (locations == nullptr || index >= locations->size()) {
     return TextFormat::ParseLocation();
     return TextFormat::ParseLocation();
   }
   }
 
 
@@ -191,8 +191,8 @@ TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
 
 
   const std::vector<TextFormat::ParseInfoTree*>* trees =
   const std::vector<TextFormat::ParseInfoTree*>* trees =
       FindOrNull(nested_, field);
       FindOrNull(nested_, field);
-  if (trees == NULL || index >= trees->size()) {
-    return NULL;
+  if (trees == nullptr || index >= trees->size()) {
+    return nullptr;
   }
   }
 
 
   return (*trees)[index];
   return (*trees)[index];
@@ -200,10 +200,12 @@ TextFormat::ParseInfoTree* TextFormat::ParseInfoTree::GetTreeForNested(
 
 
 namespace {
 namespace {
 // These functions implement the behavior of the "default" TextFormat::Finder,
 // These functions implement the behavior of the "default" TextFormat::Finder,
-// they are defined as standalone to be called when finder_ is NULL.
+// they are defined as standalone to be called when finder_ is nullptr.
 const FieldDescriptor* DefaultFinderFindExtension(Message* message,
 const FieldDescriptor* DefaultFinderFindExtension(Message* message,
                                                   const std::string& name) {
                                                   const std::string& name) {
-  return message->GetReflection()->FindKnownExtensionByName(name);
+  const Descriptor* descriptor = message->GetDescriptor();
+  return descriptor->file()->pool()->FindExtensionByPrintableName(descriptor,
+                                                                  name);
 }
 }
 
 
 const Descriptor* DefaultFinderFindAnyType(const Message& message,
 const Descriptor* DefaultFinderFindAnyType(const Message& message,
@@ -211,7 +213,7 @@ const Descriptor* DefaultFinderFindAnyType(const Message& message,
                                            const std::string& name) {
                                            const std::string& name) {
   if (prefix != internal::kTypeGoogleApisComPrefix &&
   if (prefix != internal::kTypeGoogleApisComPrefix &&
       prefix != internal::kTypeGoogleProdComPrefix) {
       prefix != internal::kTypeGoogleProdComPrefix) {
-    return NULL;
+    return nullptr;
   }
   }
   return message.GetDescriptor()->file()->pool()->FindMessageTypeByName(name);
   return message.GetDescriptor()->file()->pool()->FindMessageTypeByName(name);
 }
 }
@@ -312,7 +314,7 @@ class TextFormat::Parser::ParserImpl {
 
 
   void ReportError(int line, int col, const std::string& message) {
   void ReportError(int line, int col, const std::string& message) {
     had_errors_ = true;
     had_errors_ = true;
-    if (error_collector_ == NULL) {
+    if (error_collector_ == nullptr) {
       if (line >= 0) {
       if (line >= 0) {
         GOOGLE_LOG(ERROR) << "Error parsing text-format "
         GOOGLE_LOG(ERROR) << "Error parsing text-format "
                    << root_message_type_->full_name() << ": " << (line + 1)
                    << root_message_type_->full_name() << ": " << (line + 1)
@@ -327,7 +329,7 @@ class TextFormat::Parser::ParserImpl {
   }
   }
 
 
   void ReportWarning(int line, int col, const std::string& message) {
   void ReportWarning(int line, int col, const std::string& message) {
-    if (error_collector_ == NULL) {
+    if (error_collector_ == nullptr) {
       if (line >= 0) {
       if (line >= 0) {
         GOOGLE_LOG(WARNING) << "Warning parsing text-format "
         GOOGLE_LOG(WARNING) << "Warning parsing text-format "
                      << root_message_type_->full_name() << ": " << (line + 1)
                      << root_message_type_->full_name() << ": " << (line + 1)
@@ -391,7 +393,7 @@ class TextFormat::Parser::ParserImpl {
 
 
     std::string field_name;
     std::string field_name;
     bool reserved_field = false;
     bool reserved_field = false;
-    const FieldDescriptor* field = NULL;
+    const FieldDescriptor* field = nullptr;
     int start_line = tokenizer_.current().line;
     int start_line = tokenizer_.current().line;
     int start_column = tokenizer_.current().column;
     int start_column = tokenizer_.current().column;
 
 
@@ -408,7 +410,7 @@ class TextFormat::Parser::ParserImpl {
       const Descriptor* value_descriptor =
       const Descriptor* value_descriptor =
           finder_ ? finder_->FindAnyType(*message, prefix, full_type_name)
           finder_ ? finder_->FindAnyType(*message, prefix, full_type_name)
                   : DefaultFinderFindAnyType(*message, prefix, full_type_name);
                   : DefaultFinderFindAnyType(*message, prefix, full_type_name);
-      if (value_descriptor == NULL) {
+      if (value_descriptor == nullptr) {
         ReportError("Could not find type \"" + prefix + full_type_name +
         ReportError("Could not find type \"" + prefix + full_type_name +
                     "\" stored in google.protobuf.Any.");
                     "\" stored in google.protobuf.Any.");
         return false;
         return false;
@@ -437,7 +439,7 @@ class TextFormat::Parser::ParserImpl {
       field = finder_ ? finder_->FindExtension(message, field_name)
       field = finder_ ? finder_->FindExtension(message, field_name)
                       : DefaultFinderFindExtension(message, field_name);
                       : DefaultFinderFindExtension(message, field_name);
 
 
-      if (field == NULL) {
+      if (field == nullptr) {
         if (!allow_unknown_field_ && !allow_unknown_extension_) {
         if (!allow_unknown_field_ && !allow_unknown_extension_) {
           ReportError("Extension \"" + field_name +
           ReportError("Extension \"" + field_name +
                       "\" is not defined or "
                       "\" is not defined or "
@@ -457,7 +459,8 @@ class TextFormat::Parser::ParserImpl {
       if (allow_field_number_ &&
       if (allow_field_number_ &&
           safe_strto32(field_name, &field_number)) {
           safe_strto32(field_name, &field_number)) {
         if (descriptor->IsExtensionNumber(field_number)) {
         if (descriptor->IsExtensionNumber(field_number)) {
-          field = reflection->FindKnownExtensionByNumber(field_number);
+          field = descriptor->file()->pool()->FindExtensionByNumber(
+              descriptor, field_number);
         } else if (descriptor->IsReservedNumber(field_number)) {
         } else if (descriptor->IsReservedNumber(field_number)) {
           reserved_field = true;
           reserved_field = true;
         } else {
         } else {
@@ -468,33 +471,34 @@ class TextFormat::Parser::ParserImpl {
         // Group names are expected to be capitalized as they appear in the
         // Group names are expected to be capitalized as they appear in the
         // .proto file, which actually matches their type names, not their
         // .proto file, which actually matches their type names, not their
         // field names.
         // field names.
-        if (field == NULL) {
+        if (field == nullptr) {
           std::string lower_field_name = field_name;
           std::string lower_field_name = field_name;
           LowerString(&lower_field_name);
           LowerString(&lower_field_name);
           field = descriptor->FindFieldByName(lower_field_name);
           field = descriptor->FindFieldByName(lower_field_name);
           // If the case-insensitive match worked but the field is NOT a group,
           // If the case-insensitive match worked but the field is NOT a group,
-          if (field != NULL && field->type() != FieldDescriptor::TYPE_GROUP) {
-            field = NULL;
+          if (field != nullptr &&
+              field->type() != FieldDescriptor::TYPE_GROUP) {
+            field = nullptr;
           }
           }
         }
         }
         // Again, special-case group names as described above.
         // Again, special-case group names as described above.
-        if (field != NULL && field->type() == FieldDescriptor::TYPE_GROUP &&
+        if (field != nullptr && field->type() == FieldDescriptor::TYPE_GROUP &&
             field->message_type()->name() != field_name) {
             field->message_type()->name() != field_name) {
-          field = NULL;
+          field = nullptr;
         }
         }
 
 
-        if (field == NULL && allow_case_insensitive_field_) {
+        if (field == nullptr && allow_case_insensitive_field_) {
           std::string lower_field_name = field_name;
           std::string lower_field_name = field_name;
           LowerString(&lower_field_name);
           LowerString(&lower_field_name);
           field = descriptor->FindFieldByLowercaseName(lower_field_name);
           field = descriptor->FindFieldByLowercaseName(lower_field_name);
         }
         }
 
 
-        if (field == NULL) {
+        if (field == nullptr) {
           reserved_field = descriptor->IsReservedName(field_name);
           reserved_field = descriptor->IsReservedName(field_name);
         }
         }
       }
       }
 
 
-      if (field == NULL && !reserved_field) {
+      if (field == nullptr && !reserved_field) {
         if (!allow_unknown_field_) {
         if (!allow_unknown_field_) {
           ReportError("Message type \"" + descriptor->full_name() +
           ReportError("Message type \"" + descriptor->full_name() +
                       "\" has no field named \"" + field_name + "\".");
                       "\" has no field named \"" + field_name + "\".");
@@ -507,7 +511,7 @@ class TextFormat::Parser::ParserImpl {
     }
     }
 
 
     // Skips unknown or reserved fields.
     // Skips unknown or reserved fields.
-    if (field == NULL) {
+    if (field == nullptr) {
       GOOGLE_CHECK(allow_unknown_field_ || allow_unknown_extension_ || reserved_field);
       GOOGLE_CHECK(allow_unknown_field_ || allow_unknown_extension_ || reserved_field);
 
 
       // Try to guess the type of this field.
       // Try to guess the type of this field.
@@ -533,7 +537,7 @@ class TextFormat::Parser::ParserImpl {
       // Fail if the field is a member of a oneof and another member has already
       // Fail if the field is a member of a oneof and another member has already
       // been specified.
       // been specified.
       const OneofDescriptor* oneof = field->containing_oneof();
       const OneofDescriptor* oneof = field->containing_oneof();
-      if (oneof != NULL && reflection->HasOneof(*message, oneof)) {
+      if (oneof != nullptr && reflection->HasOneof(*message, oneof)) {
         const FieldDescriptor* other_field =
         const FieldDescriptor* other_field =
             reflection->GetOneofFieldDescriptor(*message, oneof);
             reflection->GetOneofFieldDescriptor(*message, oneof);
         ReportError("Field \"" + field_name +
         ReportError("Field \"" + field_name +
@@ -601,7 +605,7 @@ class TextFormat::Parser::ParserImpl {
 
 
     // If a parse info tree exists, add the location for the parsed
     // If a parse info tree exists, add the location for the parsed
     // field.
     // field.
-    if (parse_info_tree_ != NULL) {
+    if (parse_info_tree_ != nullptr) {
       RecordLocation(parse_info_tree_, field,
       RecordLocation(parse_info_tree_, field,
                      ParseLocation(start_line, start_column));
                      ParseLocation(start_line, start_column));
     }
     }
@@ -643,10 +647,10 @@ class TextFormat::Parser::ParserImpl {
       ReportError("Message is too deep");
       ReportError("Message is too deep");
       return false;
       return false;
     }
     }
-    // If the parse information tree is not NULL, create a nested one
+    // If the parse information tree is not nullptr, create a nested one
     // for the nested message.
     // for the nested message.
     ParseInfoTree* parent = parse_info_tree_;
     ParseInfoTree* parent = parse_info_tree_;
-    if (parent != NULL) {
+    if (parent != nullptr) {
       parse_info_tree_ = CreateNested(parent, field);
       parse_info_tree_ = CreateNested(parent, field);
     }
     }
 
 
@@ -768,7 +772,7 @@ class TextFormat::Parser::ParserImpl {
         std::string value;
         std::string value;
         int64 int_value = kint64max;
         int64 int_value = kint64max;
         const EnumDescriptor* enum_type = field->enum_type();
         const EnumDescriptor* enum_type = field->enum_type();
-        const EnumValueDescriptor* enum_value = NULL;
+        const EnumValueDescriptor* enum_value = nullptr;
 
 
         if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
         if (LookingAtType(io::Tokenizer::TYPE_IDENTIFIER)) {
           DO(ConsumeIdentifier(&value));
           DO(ConsumeIdentifier(&value));
@@ -786,7 +790,7 @@ class TextFormat::Parser::ParserImpl {
           return false;
           return false;
         }
         }
 
 
-        if (enum_value == NULL) {
+        if (enum_value == nullptr) {
           if (int_value != kint64max &&
           if (int_value != kint64max &&
               reflection->SupportsUnknownEnumValues()) {
               reflection->SupportsUnknownEnumValues()) {
             SET_FIELD(EnumValue, int_value);
             SET_FIELD(EnumValue, int_value);
@@ -1111,7 +1115,7 @@ class TextFormat::Parser::ParserImpl {
                        std::string* serialized_value) {
                        std::string* serialized_value) {
     DynamicMessageFactory factory;
     DynamicMessageFactory factory;
     const Message* value_prototype = factory.GetPrototype(value_descriptor);
     const Message* value_prototype = factory.GetPrototype(value_descriptor);
-    if (value_prototype == NULL) {
+    if (value_prototype == nullptr) {
       return false;
       return false;
     }
     }
     std::unique_ptr<Message> value(value_prototype->New());
     std::unique_ptr<Message> value(value_prototype->New());
@@ -1209,7 +1213,7 @@ class TextFormat::Printer::TextGenerator
   explicit TextGenerator(io::ZeroCopyOutputStream* output,
   explicit TextGenerator(io::ZeroCopyOutputStream* output,
                          int initial_indent_level)
                          int initial_indent_level)
       : output_(output),
       : output_(output),
-        buffer_(NULL),
+        buffer_(nullptr),
         buffer_size_(0),
         buffer_size_(0),
         at_start_of_line_(true),
         at_start_of_line_(true),
         failed_(false),
         failed_(false),
@@ -1293,7 +1297,7 @@ class TextFormat::Printer::TextGenerator
         data += buffer_size_;
         data += buffer_size_;
         size -= buffer_size_;
         size -= buffer_size_;
       }
       }
-      void* void_buffer = NULL;
+      void* void_buffer = nullptr;
       failed_ = !output_->Next(&void_buffer, &buffer_size_);
       failed_ = !output_->Next(&void_buffer, &buffer_size_);
       if (failed_) return;
       if (failed_) return;
       buffer_ = reinterpret_cast<char*>(void_buffer);
       buffer_ = reinterpret_cast<char*>(void_buffer);
@@ -1364,9 +1368,9 @@ MessageFactory* TextFormat::Finder::FindExtensionFactory(
 // ===========================================================================
 // ===========================================================================
 
 
 TextFormat::Parser::Parser()
 TextFormat::Parser::Parser()
-    : error_collector_(NULL),
-      finder_(NULL),
-      parse_info_tree_(NULL),
+    : error_collector_(nullptr),
+      finder_(nullptr),
+      parse_info_tree_(nullptr),
       allow_partial_(false),
       allow_partial_(false),
       allow_case_insensitive_field_(false),
       allow_case_insensitive_field_(false),
       allow_unknown_field_(false),
       allow_unknown_field_(false),
@@ -1647,15 +1651,7 @@ void TextFormat::FastFieldValuePrinter::PrintFieldName(
     const FieldDescriptor* field, BaseTextGenerator* generator) const {
     const FieldDescriptor* field, BaseTextGenerator* generator) const {
   if (field->is_extension()) {
   if (field->is_extension()) {
     generator->PrintLiteral("[");
     generator->PrintLiteral("[");
-    // We special-case MessageSet elements for compatibility with proto1.
-    if (field->containing_type()->options().message_set_wire_format() &&
-        field->type() == FieldDescriptor::TYPE_MESSAGE &&
-        field->is_optional() &&
-        field->extension_scope() == field->message_type()) {
-      generator->PrintString(field->message_type()->full_name());
-    } else {
-      generator->PrintString(field->full_name());
-    }
+    generator->PrintString(field->PrintableNameForExtension());
     generator->PrintLiteral("]");
     generator->PrintLiteral("]");
   } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
   } else if (field->type() == FieldDescriptor::TYPE_GROUP) {
     // Groups must be serialized with their original capitalization.
     // Groups must be serialized with their original capitalization.
@@ -1795,7 +1791,7 @@ TextFormat::Printer::Printer()
       print_message_fields_in_index_order_(false),
       print_message_fields_in_index_order_(false),
       expand_any_(false),
       expand_any_(false),
       truncate_string_field_longer_than_(0LL),
       truncate_string_field_longer_than_(0LL),
-      finder_(NULL) {
+      finder_(nullptr) {
   SetUseUtf8StringEscaping(false);
   SetUseUtf8StringEscaping(false);
 }
 }
 
 
@@ -1821,7 +1817,7 @@ void TextFormat::Printer::SetDefaultFieldValuePrinter(
 
 
 bool TextFormat::Printer::RegisterFieldValuePrinter(
 bool TextFormat::Printer::RegisterFieldValuePrinter(
     const FieldDescriptor* field, const FieldValuePrinter* printer) {
     const FieldDescriptor* field, const FieldValuePrinter* printer) {
-  if (field == NULL || printer == NULL) {
+  if (field == nullptr || printer == nullptr) {
     return false;
     return false;
   }
   }
   FieldValuePrinterWrapper* const wrapper =
   FieldValuePrinterWrapper* const wrapper =
@@ -1837,7 +1833,7 @@ bool TextFormat::Printer::RegisterFieldValuePrinter(
 
 
 bool TextFormat::Printer::RegisterFieldValuePrinter(
 bool TextFormat::Printer::RegisterFieldValuePrinter(
     const FieldDescriptor* field, const FastFieldValuePrinter* printer) {
     const FieldDescriptor* field, const FastFieldValuePrinter* printer) {
-  return field != NULL && printer != NULL &&
+  return field != nullptr && printer != nullptr &&
          custom_printers_.insert(std::make_pair(field, printer)).second;
          custom_printers_.insert(std::make_pair(field, printer)).second;
 }
 }
 
 
@@ -1850,7 +1846,7 @@ bool TextFormat::Printer::RegisterMessagePrinter(
 
 
 bool TextFormat::Printer::PrintToString(const Message& message,
 bool TextFormat::Printer::PrintToString(const Message& message,
                                         std::string* output) const {
                                         std::string* output) const {
-  GOOGLE_DCHECK(output) << "output specified is NULL";
+  GOOGLE_DCHECK(output) << "output specified is nullptr";
 
 
   output->clear();
   output->clear();
   io::StringOutputStream output_stream(output);
   io::StringOutputStream output_stream(output);
@@ -1860,7 +1856,7 @@ bool TextFormat::Printer::PrintToString(const Message& message,
 
 
 bool TextFormat::Printer::PrintUnknownFieldsToString(
 bool TextFormat::Printer::PrintUnknownFieldsToString(
     const UnknownFieldSet& unknown_fields, std::string* output) const {
     const UnknownFieldSet& unknown_fields, std::string* output) const {
-  GOOGLE_DCHECK(output) << "output specified is NULL";
+  GOOGLE_DCHECK(output) << "output specified is nullptr";
 
 
   output->clear();
   output->clear();
   io::StringOutputStream output_stream(output);
   io::StringOutputStream output_stream(output);
@@ -1931,7 +1927,7 @@ bool TextFormat::Printer::PrintAny(const Message& message,
   const Descriptor* value_descriptor =
   const Descriptor* value_descriptor =
       finder_ ? finder_->FindAnyType(message, url_prefix, full_type_name)
       finder_ ? finder_->FindAnyType(message, url_prefix, full_type_name)
               : DefaultFinderFindAnyType(message, url_prefix, full_type_name);
               : DefaultFinderFindAnyType(message, url_prefix, full_type_name);
-  if (value_descriptor == NULL) {
+  if (value_descriptor == nullptr) {
     GOOGLE_LOG(WARNING) << "Proto type " << type_url << " not found";
     GOOGLE_LOG(WARNING) << "Proto type " << type_url << " not found";
     return false;
     return false;
   }
   }
@@ -2004,7 +2000,7 @@ void TextFormat::Printer::PrintFieldValueToString(const Message& message,
                                                   const FieldDescriptor* field,
                                                   const FieldDescriptor* field,
                                                   int index,
                                                   int index,
                                                   std::string* output) const {
                                                   std::string* output) const {
-  GOOGLE_DCHECK(output) << "output specified is NULL";
+  GOOGLE_DCHECK(output) << "output specified is nullptr";
 
 
   output->clear();
   output->clear();
   io::StringOutputStream output_stream(output);
   io::StringOutputStream output_stream(output);
@@ -2353,7 +2349,7 @@ void TextFormat::Printer::PrintFieldValue(const Message& message,
               : reflection->GetEnumValue(message, field);
               : reflection->GetEnumValue(message, field);
       const EnumValueDescriptor* enum_desc =
       const EnumValueDescriptor* enum_desc =
           field->enum_type()->FindValueByNumber(enum_value);
           field->enum_type()->FindValueByNumber(enum_value);
-      if (enum_desc != NULL) {
+      if (enum_desc != nullptr) {
         printer->PrintEnum(enum_value, enum_desc->name(), generator);
         printer->PrintEnum(enum_value, enum_desc->name(), generator);
       } else {
       } else {
         // Ordinarily, enum_desc should not be null, because proto2 has the
         // Ordinarily, enum_desc should not be null, because proto2 has the

+ 2 - 2
src/google/protobuf/text_format_unittest.cc

@@ -82,7 +82,7 @@ const std::string kEscapeTestStringEscaped =
 
 
 class TextFormatTest : public testing::Test {
 class TextFormatTest : public testing::Test {
  public:
  public:
-  static void SetUpTestCase() {
+  static void SetUpTestSuite() {
     GOOGLE_CHECK_OK(File::GetContents(
     GOOGLE_CHECK_OK(File::GetContents(
         TestUtil::GetTestDataPath(
         TestUtil::GetTestDataPath(
             "net/proto2/internal/"
             "net/proto2/internal/"
@@ -105,7 +105,7 @@ std::string TextFormatTest::static_proto_debug_string_;
 
 
 class TextFormatExtensionsTest : public testing::Test {
 class TextFormatExtensionsTest : public testing::Test {
  public:
  public:
-  static void SetUpTestCase() {
+  static void SetUpTestSuite() {
     GOOGLE_CHECK_OK(File::GetContents(
     GOOGLE_CHECK_OK(File::GetContents(
         TestUtil::GetTestDataPath("net/proto2/internal/testdata/"
         TestUtil::GetTestDataPath("net/proto2/internal/testdata/"
                                   "text_format_unittest_extensions_data.txt"),
                                   "text_format_unittest_extensions_data.txt"),

+ 1 - 1
src/google/protobuf/timestamp.pb.cc

@@ -56,7 +56,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Timestamp_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Timestamp_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2ftimestamp_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\037google/protobuf/timestamp.proto\022\017googl"
   "\n\037google/protobuf/timestamp.proto\022\017googl"
   "e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003"
   "e.protobuf\"+\n\tTimestamp\022\017\n\007seconds\030\001 \001(\003"
   "\022\r\n\005nanos\030\002 \001(\005B~\n\023com.google.protobufB\016"
   "\022\r\n\005nanos\030\002 \001(\005B~\n\023com.google.protobufB\016"

+ 1 - 1
src/google/protobuf/type.pb.cc

@@ -194,7 +194,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Option_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_Option_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2ftype_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\032google/protobuf/type.proto\022\017google.pro"
   "\n\032google/protobuf/type.proto\022\017google.pro"
   "tobuf\032\031google/protobuf/any.proto\032$google"
   "tobuf\032\031google/protobuf/any.proto\032$google"
   "/protobuf/source_context.proto\"\327\001\n\004Type\022"
   "/protobuf/source_context.proto\"\327\001\n\004Type\022"

+ 0 - 4
src/google/protobuf/util/internal/json_stream_parser.h

@@ -40,10 +40,6 @@
 
 
 #include <google/protobuf/port_def.inc>
 #include <google/protobuf/port_def.inc>
 
 
-namespace util {
-class Status;
-}  // namespace util
-
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace util {
 namespace util {

+ 1 - 1
src/google/protobuf/util/message_differencer.cc

@@ -1411,7 +1411,7 @@ bool MessageDifferencer::CompareUnknownFields(
     if (change_type == ADDITION || change_type == DELETION ||
     if (change_type == ADDITION || change_type == DELETION ||
         change_type == MODIFICATION) {
         change_type == MODIFICATION) {
       if (reporter_ == NULL) {
       if (reporter_ == NULL) {
-        // We found a difference and we have no reproter.
+        // We found a difference and we have no reporter.
         return false;
         return false;
       }
       }
       is_different = true;
       is_different = true;

+ 1 - 1
src/google/protobuf/wrappers.pb.cc

@@ -263,7 +263,7 @@ static ::PROTOBUF_NAMESPACE_ID::Message const * const file_default_instances[] =
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_BytesValue_default_instance_),
   reinterpret_cast<const ::PROTOBUF_NAMESPACE_ID::Message*>(&PROTOBUF_NAMESPACE_ID::_BytesValue_default_instance_),
 };
 };
 
 
-const char descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto[] =
+const char descriptor_table_protodef_google_2fprotobuf_2fwrappers_2eproto[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) =
   "\n\036google/protobuf/wrappers.proto\022\017google"
   "\n\036google/protobuf/wrappers.proto\022\017google"
   ".protobuf\"\034\n\013DoubleValue\022\r\n\005value\030\001 \001(\001\""
   ".protobuf\"\034\n\013DoubleValue\022\r\n\005value\030\001 \001(\001\""
   "\033\n\nFloatValue\022\r\n\005value\030\001 \001(\002\"\033\n\nInt64Val"
   "\033\n\nFloatValue\022\r\n\005value\030\001 \001(\002\"\033\n\nInt64Val"

+ 1 - 0
update_version.py

@@ -156,6 +156,7 @@ def UpdateCpp():
         r'^#if .* < PROTOBUF_MIN_PROTOC_VERSION$',
         r'^#if .* < PROTOBUF_MIN_PROTOC_VERSION$',
         '#if %s < PROTOBUF_MIN_PROTOC_VERSION' % cpp_version,
         '#if %s < PROTOBUF_MIN_PROTOC_VERSION' % cpp_version,
         line)
         line)
+    return line
     
     
   RewriteTextFile('src/google/protobuf/stubs/common.h', RewriteCommon)
   RewriteTextFile('src/google/protobuf/stubs/common.h', RewriteCommon)
   RewriteTextFile('src/google/protobuf/port_def.inc', RewritePortDef)
   RewriteTextFile('src/google/protobuf/port_def.inc', RewritePortDef)

Some files were not shown because too many files changed in this diff