Browse Source

Down-integrate internal changes to github. (#5575)

* Down-integrate internal changes to github.

* Fix BUILD file and regenerate csharp descritpor
Yilun Chong 6 years ago
parent
commit
a2a0afb546
69 changed files with 857 additions and 1114 deletions
  1. 0 1
      BUILD
  2. 2 1
      conformance/conformance.proto
  3. 1 1
      csharp/src/Google.Protobuf.Conformance/Conformance.cs
  4. 10 12
      src/google/protobuf/any.pb.cc
  5. 54 83
      src/google/protobuf/api.pb.cc
  6. 0 43
      src/google/protobuf/arenastring.cc
  7. 3 2
      src/google/protobuf/compiler/cpp/cpp_extension.cc
  8. 3 3
      src/google/protobuf/compiler/cpp/cpp_field.cc
  9. 4 4
      src/google/protobuf/compiler/cpp/cpp_file.cc
  10. 2 2
      src/google/protobuf/compiler/cpp/cpp_generator.cc
  11. 76 84
      src/google/protobuf/compiler/cpp/cpp_helpers.cc
  12. 2 1
      src/google/protobuf/compiler/cpp/cpp_helpers.h
  13. 2 3
      src/google/protobuf/compiler/cpp/cpp_map_field.cc
  14. 19 24
      src/google/protobuf/compiler/cpp/cpp_message.cc
  15. 3 3
      src/google/protobuf/compiler/cpp/cpp_primitive_field.cc
  16. 2 1
      src/google/protobuf/compiler/cpp/cpp_string_field.cc
  17. 3 2
      src/google/protobuf/compiler/java/java_context.cc
  18. 7 6
      src/google/protobuf/compiler/java/java_enum.cc
  19. 10 9
      src/google/protobuf/compiler/java/java_enum_field.cc
  20. 4 3
      src/google/protobuf/compiler/java/java_enum_field_lite.cc
  21. 4 3
      src/google/protobuf/compiler/java/java_enum_lite.cc
  22. 4 3
      src/google/protobuf/compiler/java/java_extension.cc
  23. 5 4
      src/google/protobuf/compiler/java/java_field.cc
  24. 5 7
      src/google/protobuf/compiler/java/java_file.cc
  25. 7 8
      src/google/protobuf/compiler/java/java_helpers.cc
  26. 2 2
      src/google/protobuf/compiler/java/java_map_field.cc
  27. 21 24
      src/google/protobuf/compiler/java/java_message.cc
  28. 5 5
      src/google/protobuf/compiler/java/java_message_builder.cc
  29. 2 2
      src/google/protobuf/compiler/java/java_message_builder_lite.cc
  30. 4 4
      src/google/protobuf/compiler/java/java_message_field.cc
  31. 2 1
      src/google/protobuf/compiler/java/java_message_field_lite.cc
  32. 9 9
      src/google/protobuf/compiler/java/java_message_lite.cc
  33. 16 17
      src/google/protobuf/compiler/java/java_primitive_field.cc
  34. 4 3
      src/google/protobuf/compiler/java/java_primitive_field_lite.cc
  35. 7 6
      src/google/protobuf/compiler/java/java_service.cc
  36. 7 6
      src/google/protobuf/compiler/java/java_string_field.cc
  37. 3 2
      src/google/protobuf/compiler/java/java_string_field_lite.cc
  38. 33 26
      src/google/protobuf/compiler/js/js_generator.cc
  39. 3 2
      src/google/protobuf/compiler/parser.cc
  40. 49 69
      src/google/protobuf/compiler/plugin.pb.cc
  41. 22 22
      src/google/protobuf/compiler/python/python_generator.cc
  42. 5 4
      src/google/protobuf/descriptor.cc
  43. 2 4
      src/google/protobuf/descriptor.h
  44. 182 306
      src/google/protobuf/descriptor.pb.cc
  45. 2 8
      src/google/protobuf/duration.pb.cc
  46. 7 6
      src/google/protobuf/field_mask.pb.cc
  47. 4 4
      src/google/protobuf/generated_message_util.h
  48. 1 0
      src/google/protobuf/io/coded_stream.h
  49. 2 0
      src/google/protobuf/map.h
  50. 9 0
      src/google/protobuf/map_test.cc
  51. 3 1
      src/google/protobuf/parse_context.h
  52. 2 1
      src/google/protobuf/reflection_ops.cc
  53. 5 4
      src/google/protobuf/repeated_field_unittest.cc
  54. 7 6
      src/google/protobuf/source_context.pb.cc
  55. 21 33
      src/google/protobuf/struct.pb.cc
  56. 8 8
      src/google/protobuf/text_format.cc
  57. 5 4
      src/google/protobuf/text_format_unittest.cc
  58. 2 8
      src/google/protobuf/timestamp.pb.cc
  59. 86 131
      src/google/protobuf/type.pb.cc
  60. 5 4
      src/google/protobuf/util/internal/datapiece.cc
  61. 5 4
      src/google/protobuf/util/internal/json_objectwriter.cc
  62. 11 10
      src/google/protobuf/util/internal/protostream_objectsource.cc
  63. 3 2
      src/google/protobuf/util/internal/protostream_objectwriter.cc
  64. 3 2
      src/google/protobuf/util/internal/utility.h
  65. 4 6
      src/google/protobuf/util/message_differencer.cc
  66. 2 1
      src/google/protobuf/util/time_util.cc
  67. 4 4
      src/google/protobuf/util/type_resolver_util.cc
  68. 23 0
      src/google/protobuf/wire_format_lite.h
  69. 23 40
      src/google/protobuf/wrappers.pb.cc

+ 0 - 1
BUILD

@@ -93,7 +93,6 @@ cc_library(
     srcs = [
     srcs = [
         # AUTOGEN(protobuf_lite_srcs)
         # AUTOGEN(protobuf_lite_srcs)
         "src/google/protobuf/arena.cc",
         "src/google/protobuf/arena.cc",
-        "src/google/protobuf/arenastring.cc",
         "src/google/protobuf/extension_set.cc",
         "src/google/protobuf/extension_set.cc",
         "src/google/protobuf/generated_message_table_driven_lite.cc",
         "src/google/protobuf/generated_message_table_driven_lite.cc",
         "src/google/protobuf/generated_message_util.cc",
         "src/google/protobuf/generated_message_util.cc",

+ 2 - 1
conformance/conformance.proto

@@ -71,7 +71,7 @@ enum TestCategory {
   JSON_IGNORE_UNKNOWN_PARSING_TEST = 3;
   JSON_IGNORE_UNKNOWN_PARSING_TEST = 3;
   // Test jspb wire format. Google internal only. Opensource testees just skip it.
   // Test jspb wire format. Google internal only. Opensource testees just skip it.
   JSPB_TEST = 4;
   JSPB_TEST = 4;
-  // Test text format. For cpp, java and python, testees can already deal with 
+  // Test text format. For cpp, java and python, testees can already deal with
   // this type. Testees of other languages can simply skip it.
   // this type. Testees of other languages can simply skip it.
   TEXT_FORMAT_TEST = 5;
   TEXT_FORMAT_TEST = 5;
 }
 }
@@ -169,3 +169,4 @@ message JspbEncodingConfig {
   // Encode the value field of Any as jspb array if ture, otherwise binary.
   // Encode the value field of Any as jspb array if ture, otherwise binary.
   bool use_jspb_array_any_format = 1;
   bool use_jspb_array_any_format = 1;
 }
 }
+

+ 1 - 1
csharp/src/Google.Protobuf.Conformance/Conformance.cs

@@ -93,7 +93,7 @@ namespace Conformance {
     /// </summary>
     /// </summary>
     [pbr::OriginalName("JSPB_TEST")] JspbTest = 4,
     [pbr::OriginalName("JSPB_TEST")] JspbTest = 4,
     /// <summary>
     /// <summary>
-    /// Test text format. For cpp, java and python, testees can already deal with 
+    /// Test text format. For cpp, java and python, testees can already deal with
     /// this type. Testees of other languages can simply skip it.
     /// this type. Testees of other languages can simply skip it.
     /// </summary>
     /// </summary>
     [pbr::OriginalName("TEXT_FORMAT_TEST")] TextFormatTest = 5,
     [pbr::OriginalName("TEXT_FORMAT_TEST")] TextFormatTest = 5,

+ 10 - 12
src/google/protobuf/any.pb.cc

@@ -210,16 +210,13 @@ const char* Any::_InternalParse(const char* begin, const char* end, void* object
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Any.type_url");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Any.type_url");
-        auto str = msg->mutable_type_url();
+        object = msg->mutable_type_url();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -228,16 +225,13 @@ const char* Any::_InternalParse(const char* begin, const char* end, void* object
         if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        auto str = msg->mutable_value();
+        object = msg->mutable_value();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParser;
           parser_till_end = ::google::protobuf::internal::GreedyStringParser;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheck(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheck(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -256,6 +250,10 @@ const char* Any::_InternalParse(const char* begin, const char* end, void* object
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);

+ 54 - 83
src/google/protobuf/api.pb.cc

@@ -316,16 +316,13 @@ const char* Api::_InternalParse(const char* begin, const char* end, void* object
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Api.name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Api.name");
-        auto str = msg->mutable_name();
+        object = msg->mutable_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -338,11 +335,9 @@ const char* Api::_InternalParse(const char* begin, const char* end, void* object
           parser_till_end = ::google::protobuf::Method::_InternalParse;
           parser_till_end = ::google::protobuf::Method::_InternalParse;
           object = msg->add_methods();
           object = msg->add_methods();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
         break;
         break;
@@ -356,11 +351,9 @@ const char* Api::_InternalParse(const char* begin, const char* end, void* object
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           object = msg->add_options();
           object = msg->add_options();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
         break;
         break;
@@ -371,16 +364,13 @@ const char* Api::_InternalParse(const char* begin, const char* end, void* object
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Api.version");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Api.version");
-        auto str = msg->mutable_version();
+        object = msg->mutable_version();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -392,11 +382,9 @@ const char* Api::_InternalParse(const char* begin, const char* end, void* object
         parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
         parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
         object = msg->mutable_source_context();
         object = msg->mutable_source_context();
         if (size > end - ptr) goto len_delim_till_end;
         if (size > end - ptr) goto len_delim_till_end;
-        auto newend = ptr + size;
-        bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                       ptr, newend);
-        GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-        ptr = newend;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
         break;
         break;
       }
       }
       // repeated .google.protobuf.Mixin mixins = 6;
       // repeated .google.protobuf.Mixin mixins = 6;
@@ -408,11 +396,9 @@ const char* Api::_InternalParse(const char* begin, const char* end, void* object
           parser_till_end = ::google::protobuf::Mixin::_InternalParse;
           parser_till_end = ::google::protobuf::Mixin::_InternalParse;
           object = msg->add_mixins();
           object = msg->add_mixins();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
         break;
         break;
@@ -420,11 +406,9 @@ const char* Api::_InternalParse(const char* begin, const char* end, void* object
       // .google.protobuf.Syntax syntax = 7;
       // .google.protobuf.Syntax syntax = 7;
       case 7: {
       case 7: {
         if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_syntax(static_cast<::google::protobuf::Syntax>(val));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::Syntax value = static_cast<::google::protobuf::Syntax>(val);
-        msg->set_syntax(value);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -442,6 +426,10 @@ const char* Api::_InternalParse(const char* begin, const char* end, void* object
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -987,16 +975,13 @@ const char* Method::_InternalParse(const char* begin, const char* end, void* obj
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Method.name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Method.name");
-        auto str = msg->mutable_name();
+        object = msg->mutable_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -1006,27 +991,21 @@ const char* Method::_InternalParse(const char* begin, const char* end, void* obj
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Method.request_type_url");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Method.request_type_url");
-        auto str = msg->mutable_request_type_url();
+        object = msg->mutable_request_type_url();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
       // bool request_streaming = 3;
       // bool request_streaming = 3;
       case 3: {
       case 3: {
         if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_request_streaming(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        bool value = val;
-        msg->set_request_streaming(value);
         break;
         break;
       }
       }
       // string response_type_url = 4;
       // string response_type_url = 4;
@@ -1035,27 +1014,21 @@ const char* Method::_InternalParse(const char* begin, const char* end, void* obj
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Method.response_type_url");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Method.response_type_url");
-        auto str = msg->mutable_response_type_url();
+        object = msg->mutable_response_type_url();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
       // bool response_streaming = 5;
       // bool response_streaming = 5;
       case 5: {
       case 5: {
         if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_response_streaming(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        bool value = val;
-        msg->set_response_streaming(value);
         break;
         break;
       }
       }
       // repeated .google.protobuf.Option options = 6;
       // repeated .google.protobuf.Option options = 6;
@@ -1067,11 +1040,9 @@ const char* Method::_InternalParse(const char* begin, const char* end, void* obj
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           object = msg->add_options();
           object = msg->add_options();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 50 && (ptr += 1));
         break;
         break;
@@ -1079,11 +1050,9 @@ const char* Method::_InternalParse(const char* begin, const char* end, void* obj
       // .google.protobuf.Syntax syntax = 7;
       // .google.protobuf.Syntax syntax = 7;
       case 7: {
       case 7: {
         if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_syntax(static_cast<::google::protobuf::Syntax>(val));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::Syntax value = static_cast<::google::protobuf::Syntax>(val);
-        msg->set_syntax(value);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -1101,6 +1070,10 @@ const char* Method::_InternalParse(const char* begin, const char* end, void* obj
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -1616,16 +1589,13 @@ const char* Mixin::_InternalParse(const char* begin, const char* end, void* obje
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Mixin.name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Mixin.name");
-        auto str = msg->mutable_name();
+        object = msg->mutable_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -1635,16 +1605,13 @@ const char* Mixin::_InternalParse(const char* begin, const char* end, void* obje
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Mixin.root");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Mixin.root");
-        auto str = msg->mutable_root();
+        object = msg->mutable_root();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -1663,6 +1630,10 @@ const char* Mixin::_InternalParse(const char* begin, const char* end, void* obje
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);

+ 0 - 43
src/google/protobuf/arenastring.cc

@@ -1,43 +0,0 @@
-// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc.  All rights reserved.
-// https://developers.google.com/protocol-buffers/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-//     * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//     * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-//     * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// The ArenaString implementation is not included in the open-source release. Do
-// not include this file in the distribution.
-
-#include <google/protobuf/arenastring.h>
-
-namespace google {
-namespace protobuf {
-namespace internal {
-
-
-}  // namespace internal
-}  // namespace protobuf
-}  // namespace google

+ 3 - 2
src/google/protobuf/compiler/cpp/cpp_extension.cc

@@ -40,6 +40,7 @@
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -95,7 +96,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
   variables_["name"] = name;
   variables_["name"] = name;
   variables_["constant_name"] = FieldConstantName(descriptor_);
   variables_["constant_name"] = FieldConstantName(descriptor_);
   variables_["field_type"] =
   variables_["field_type"] =
-      SimpleItoa(static_cast<int>(descriptor_->type()));
+      StrCat(static_cast<int>(descriptor_->type()));
   variables_["packed"] = descriptor_->options().packed() ? "true" : "false";
   variables_["packed"] = descriptor_->options().packed() ? "true" : "false";
 
 
   string scope =
   string scope =
@@ -103,7 +104,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor,
   variables_["scope"] = scope;
   variables_["scope"] = scope;
   string scoped_name = scope + name;
   string scoped_name = scope + name;
   variables_["scoped_name"] = scoped_name;
   variables_["scoped_name"] = scoped_name;
-  variables_["number"] = SimpleItoa(descriptor_->number());
+  variables_["number"] = StrCat(descriptor_->number());
 }
 }
 
 
 ExtensionGenerator::~ExtensionGenerator() {}
 ExtensionGenerator::~ExtensionGenerator() {}

+ 3 - 3
src/google/protobuf/compiler/cpp/cpp_field.cc

@@ -62,13 +62,13 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
   SetCommonVars(options, variables);
   SetCommonVars(options, variables);
   (*variables)["ns"] = Namespace(descriptor);
   (*variables)["ns"] = Namespace(descriptor);
   (*variables)["name"] = FieldName(descriptor);
   (*variables)["name"] = FieldName(descriptor);
-  (*variables)["index"] = SimpleItoa(descriptor->index());
-  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["index"] = StrCat(descriptor->index());
+  (*variables)["number"] = StrCat(descriptor->number());
   (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
   (*variables)["classname"] = ClassName(FieldScope(descriptor), false);
   (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
   (*variables)["declared_type"] = DeclaredTypeMethodName(descriptor->type());
   (*variables)["field_member"] = FieldName(descriptor) + "_";
   (*variables)["field_member"] = FieldName(descriptor) + "_";
 
 
-  (*variables)["tag_size"] = SimpleItoa(
+  (*variables)["tag_size"] = StrCat(
       WireFormat::TagSize(descriptor->number(), descriptor->type()));
       WireFormat::TagSize(descriptor->number(), descriptor->type()));
   (*variables)["deprecated_attr"] =
   (*variables)["deprecated_attr"] =
       DeprecatedAttribute(options, descriptor->options().deprecated());
       DeprecatedAttribute(options, descriptor->options().deprecated());

+ 4 - 4
src/google/protobuf/compiler/cpp/cpp_file.cc

@@ -50,6 +50,7 @@
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
 
 
+
 #include <google/protobuf/port_def.inc>
 #include <google/protobuf/port_def.inc>
 
 
 namespace google {
 namespace google {
@@ -477,10 +478,9 @@ void FileGenerator::GenerateInternalForwardDeclarations(
     auto scc = scc_analyzer->GetSCC(msg);
     auto scc = scc_analyzer->GetSCC(msg);
     string repr =
     string repr =
         UniqueName(ClassName(scc->GetRepresentative()), msg, options_);
         UniqueName(ClassName(scc->GetRepresentative()), msg, options_);
-    global_namespace_decls.insert(
-        "extern " + dllexport + weak_attr + " ::" + ProtobufNamespace(options) +
-        "::internal::SCCInfo<" + SimpleItoa(scc->children.size()) +
-        "> scc_info_" + repr);
+    global_namespace_decls.insert(StrCat(
+        "extern ", dllexport, weak_attr, " ::", ProtobufNamespace(options),
+        "::internal::SCCInfo<", scc->children.size(), "> scc_info_", repr));
   }
   }
 
 
   format("\n");
   format("\n");

+ 2 - 2
src/google/protobuf/compiler/cpp/cpp_generator.cc

@@ -46,6 +46,7 @@
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 
 
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -203,8 +204,7 @@ bool CppGenerator::Generate(const FileDescriptor* file,
       }
       }
       for (int i = 0; i < num_cc_files; i++) {
       for (int i = 0; i < num_cc_files; i++) {
         std::unique_ptr<io::ZeroCopyOutputStream> output(
         std::unique_ptr<io::ZeroCopyOutputStream> output(
-            generator_context->Open(basename + ".out/" +
-                                    SimpleItoa(i) + ".cc"));
+            generator_context->Open(StrCat(basename, ".out/", i, ".cc")));
         io::Printer printer(output.get(), '$');
         io::Printer printer(output.get(), '$');
         if (i < file_generator.NumMessages()) {
         if (i < file_generator.NumMessages()) {
           file_generator.GenerateSourceForMessage(i, &printer);
           file_generator.GenerateSourceForMessage(i, &printer);

+ 76 - 84
src/google/protobuf/compiler/cpp/cpp_helpers.cc

@@ -41,6 +41,7 @@
 #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/compiler/cpp/cpp_helpers.h>
 #include <google/protobuf/compiler/cpp/cpp_helpers.h>
+
 #include <google/protobuf/compiler/scc.h>
 #include <google/protobuf/compiler/scc.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/zero_copy_stream.h>
 #include <google/protobuf/io/zero_copy_stream.h>
@@ -420,7 +421,7 @@ string FieldConstantName(const FieldDescriptor* field) {
     // This field's camelcase name is not unique.  As a hack, add the field
     // This field's camelcase name is not unique.  As a hack, add the field
     // number to the constant name.  This makes the constant rather useless,
     // number to the constant name.  This makes the constant rather useless,
     // but what can we do?
     // but what can we do?
-    result += "_" + SimpleItoa(field->number());
+    result += "_" + StrCat(field->number());
   }
   }
 
 
   return result;
   return result;
@@ -555,9 +556,9 @@ string Int32ToString(int number) {
   if (number == kint32min) {
   if (number == kint32min) {
     // This needs to be special-cased, see explanation here:
     // This needs to be special-cased, see explanation here:
     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
-    return SimpleItoa(number + 1) + " - 1";
+    return StrCat(number + 1, " - 1");
   } else {
   } else {
-    return SimpleItoa(number);
+    return StrCat(number);
   }
   }
 }
 }
 
 
@@ -565,14 +566,13 @@ string Int64ToString(const string& macro_prefix, int64 number) {
   if (number == kint64min) {
   if (number == kint64min) {
     // This needs to be special-cased, see explanation here:
     // This needs to be special-cased, see explanation here:
     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
     // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52661
-    return macro_prefix + "_LONGLONG(" + SimpleItoa(number + 1) +
-           ") - 1";
+    return StrCat(macro_prefix, "_LONGLONG(", number + 1, ") - 1");
   }
   }
-  return macro_prefix + "_LONGLONG(" + SimpleItoa(number) + ")";
+  return StrCat(macro_prefix, "_LONGLONG(", number, ")");
 }
 }
 
 
 string UInt64ToString(const string& macro_prefix, uint64 number) {
 string UInt64ToString(const string& macro_prefix, uint64 number) {
-  return macro_prefix + "_ULONGLONG(" + SimpleItoa(number) + ")";
+  return StrCat(macro_prefix, "_ULONGLONG(", number, ")");
 }
 }
 
 
 string DefaultValue(const FieldDescriptor* field) {
 string DefaultValue(const FieldDescriptor* field) {
@@ -591,7 +591,7 @@ string DefaultValue(const Options& options, const FieldDescriptor* field) {
     case FieldDescriptor::CPPTYPE_INT32:
     case FieldDescriptor::CPPTYPE_INT32:
       return Int32ToString(field->default_value_int32());
       return Int32ToString(field->default_value_int32());
     case FieldDescriptor::CPPTYPE_UINT32:
     case FieldDescriptor::CPPTYPE_UINT32:
-      return SimpleItoa(field->default_value_uint32()) + "u";
+      return StrCat(field->default_value_uint32()) + "u";
     case FieldDescriptor::CPPTYPE_INT64:
     case FieldDescriptor::CPPTYPE_INT64:
       return Int64ToString("PROTOBUF", field->default_value_int64());
       return Int64ToString("PROTOBUF", field->default_value_int64());
     case FieldDescriptor::CPPTYPE_UINT64:
     case FieldDescriptor::CPPTYPE_UINT64:
@@ -1422,6 +1422,26 @@ class ParseLoopGenerator {
         "    }  // switch\n"
         "    }  // switch\n"
         "  }  // while\n"
         "  }  // while\n"
         "  return ptr;\n");
         "  return ptr;\n");
+    if (use_string_) {
+      format_(
+          "string_till_end:\n"
+          "  static_cast<$string$*>(object)->clear();\n"
+          // TODO(gerbens) evaluate security
+          "  static_cast<$string$*>(object)->reserve(size);\n"
+          "  goto len_delim_till_end;\n");
+    }
+    if (use_arena_string_) {
+      format_(
+          "arena_string_till_end:\n"
+          "  object = "
+          "static_cast<::$proto_ns$::internal::ArenaStringPtr*>(object)->"
+          "Mutable(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), "
+          "msg->GetArenaNoVirtual());\n"
+          "  static_cast<$string$*>(object)->clear();\n"
+          // TODO(gerbens) evaluate security
+          "  static_cast<$string$*>(object)->reserve(size);\n"
+          "  goto len_delim_till_end;\n");
+    }
     if (use_length_delimited_) {
     if (use_length_delimited_) {
       format_(
       format_(
           "len_delim_till_end:\n"
           "len_delim_till_end:\n"
@@ -1447,33 +1467,30 @@ class ParseLoopGenerator {
   Formatter format_;
   Formatter format_;
   bool use_length_delimited_ = false;
   bool use_length_delimited_ = false;
   bool use_group_ = false;
   bool use_group_ = false;
+  bool use_string_ = false;
+  bool use_arena_string_ = false;
 
 
   using WireFormat = internal::WireFormat;
   using WireFormat = internal::WireFormat;
   using WireFormatLite = internal::WireFormatLite;
   using WireFormatLite = internal::WireFormatLite;
 
 
   void GenerateArenaString(const FieldDescriptor* field, const string& utf8) {
   void GenerateArenaString(const FieldDescriptor* field, const string& utf8) {
+    use_arena_string_ = true;
+    if (HasFieldPresence(field->file())) {
+      format_("HasBitSetters::set_has_$1$(msg);\n", FieldName(field));
+    }
     format_(
     format_(
         "if (size > end - ptr + "
         "if (size > end - ptr + "
         "::$proto_ns$::internal::ParseContext::kSlopBytes) {\n"
         "::$proto_ns$::internal::ParseContext::kSlopBytes) {\n"
-        "  auto str = msg->mutable_$1$();\n"
-        "  str->clear();\n"
-        // TODO(gerbens) evaluate security
-        "  str->reserve(size);\n"
-        "  object = str;\n"
+        "  object = &msg->$1$_;\n"
         "  parser_till_end = ::$proto_ns$::internal::GreedyStringParser$2$;\n"
         "  parser_till_end = ::$proto_ns$::internal::GreedyStringParser$2$;\n"
-        "  goto len_delim_till_end;\n"
+        "  goto arena_string_till_end;\n"
         "}\n"
         "}\n"
         "$GOOGLE_PROTOBUF$_PARSER_ASSERT(::$proto_ns$::internal::StringCheck$2$"
         "$GOOGLE_PROTOBUF$_PARSER_ASSERT(::$proto_ns$::internal::StringCheck$2$"
-        "(ptr, size, ctx));\n",
-        FieldName(field), utf8);
-    if (HasFieldPresence(field->file())) {
-      format_("HasBitSetters::set_has_$1$(msg);\n", FieldName(field));
-    }
-    format_(
+        "(ptr, size, ctx));\n"
         "::$proto_ns$::internal::CopyIntoArenaString(ptr, size, &msg->$1$_, "
         "::$proto_ns$::internal::CopyIntoArenaString(ptr, size, &msg->$1$_, "
         "msg->GetArenaNoVirtual());\n"
         "msg->GetArenaNoVirtual());\n"
         "ptr += size;\n",
         "ptr += size;\n",
-        FieldName(field));
+        FieldName(field), utf8);
   }
   }
 
 
   void GenerateStrings(const FieldDescriptor* field, bool check_utf8) {
   void GenerateStrings(const FieldDescriptor* field, bool check_utf8) {
@@ -1510,40 +1527,40 @@ class ParseLoopGenerator {
       return;
       return;
     }
     }
     format_(
     format_(
-        "auto str = msg->$1$_$2$();\n"
+        "object = msg->$1$_$2$();\n"
         "if (size > end - ptr + "
         "if (size > end - ptr + "
-        "::$proto_ns$::internal::ParseContext::kSlopBytes) {\n"
-        "  object = str;\n",
+        "::$proto_ns$::internal::ParseContext::kSlopBytes) {\n",
         field->is_repeated() && !field->is_packable() ? "add" : "mutable",
         field->is_repeated() && !field->is_packable() ? "add" : "mutable",
         FieldName(field));
         FieldName(field));
     string name;
     string name;
+    string label = "len_delim_till_end";
     switch (ctype) {
     switch (ctype) {
       case FieldOptions::STRING:
       case FieldOptions::STRING:
         name = "GreedyStringParser";
         name = "GreedyStringParser";
-        format_(
-            "  str->clear();\n"
-            // TODO(gerbens) evaluate security
-            "  str->reserve(size);\n");
+        use_string_ = true;
+        label = "string_till_end";
         break;
         break;
       case FieldOptions::CORD:
       case FieldOptions::CORD:
         name = "CordParser";
         name = "CordParser";
-        format_("  str->Clear();\n");
+        format_("  static_cast<::Cord*>(object)->Clear();\n");
         break;
         break;
       case FieldOptions::STRING_PIECE:
       case FieldOptions::STRING_PIECE:
         name = "StringPieceParser";
         name = "StringPieceParser";
-        format_("  str->Clear();\n");
+        format_(
+            "  "
+            "static_cast<::$proto_ns$::internal::StringPieceField*>(object)->"
+            "Clear();\n");
         break;
         break;
     }
     }
     format_(
     format_(
         "  parser_till_end = ::$proto_ns$::internal::$1$$2$;\n"
         "  parser_till_end = ::$proto_ns$::internal::$1$$2$;\n"
-        "  goto len_delim_till_end;\n"
+        "  goto $3$;\n"
         "}\n"
         "}\n"
         "$GOOGLE_PROTOBUF$_PARSER_ASSERT(::$proto_ns$::internal::StringCheck$2$"
         "$GOOGLE_PROTOBUF$_PARSER_ASSERT(::$proto_ns$::internal::StringCheck$2$"
-        "("
-        "ptr, size, ctx));\n"
-        "::$proto_ns$::internal::Inline$1$(str, ptr, size, ctx);\n"
+        "(ptr, size, ctx));\n"
+        "::$proto_ns$::internal::Inline$1$(object, ptr, size, ctx);\n"
         "ptr += size;\n",
         "ptr += size;\n",
-        name, utf8);
+        name, utf8, label);
   }
   }
 
 
   void GenerateLengthDelim(const FieldDescriptor* field) {
   void GenerateLengthDelim(const FieldDescriptor* field) {
@@ -1690,11 +1707,9 @@ class ParseLoopGenerator {
           }
           }
           format_(
           format_(
               "if (size > end - ptr) goto len_delim_till_end;\n"
               "if (size > end - ptr) goto len_delim_till_end;\n"
-              "auto newend = ptr + size;\n"
-              "bool ok = ctx->ParseExactRange({parser_till_end, object},\n"
-              "                               ptr, newend);\n"
-              "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ok);\n"
-              "ptr = newend;\n");
+              "ptr += size;\n"
+              "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ctx->ParseExactRange(\n"
+              "    {parser_till_end, object}, ptr - size, ptr));\n");
           break;
           break;
         }
         }
         default:
         default:
@@ -1712,21 +1727,11 @@ class ParseLoopGenerator {
     }
     }
     switch (wiretype) {
     switch (wiretype) {
       case WireFormatLite::WIRETYPE_VARINT: {
       case WireFormatLite::WIRETYPE_VARINT: {
-        format_(
-            "$uint64$ val;\n"
-            "ptr = ::$proto_ns$::io::Parse64(ptr, &val);\n"
-            "$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n");
         string type = PrimitiveTypeName(options_, field->cpp_type());
         string type = PrimitiveTypeName(options_, field->cpp_type());
-        if ((field->type() == FieldDescriptor::TYPE_SINT32 ||
-             field->type() == FieldDescriptor::TYPE_SINT64) &&
+        string prefix = field->is_repeated() ? "add" : "set";
+        if (field->type() == FieldDescriptor::TYPE_ENUM &&
             !IsProto1(field->file(), options_)) {
             !IsProto1(field->file(), options_)) {
-          int size = field->type() == FieldDescriptor::TYPE_SINT32 ? 32 : 64;
-          format_(
-              "$1$ value = "
-              "::$proto_ns$::internal::WireFormatLite::ZigZagDecode$2$(val);\n",
-              type, size);
-        } else if (field->type() == FieldDescriptor::TYPE_ENUM &&
-                   !IsProto1(field->file(), options_)) {
+          format_("$uint64$ val = ::$proto_ns$::internal::ReadVarint(&ptr);\n");
           if (!HasPreservingUnknownEnumSemantics(field->file())) {
           if (!HasPreservingUnknownEnumSemantics(field->file())) {
             format_(
             format_(
                 "if (!$1$_IsValid(val)) {\n"
                 "if (!$1$_IsValid(val)) {\n"
@@ -1736,30 +1741,31 @@ class ParseLoopGenerator {
                 "}\n",
                 "}\n",
                 QualifiedClassName(field->enum_type()), field->number());
                 QualifiedClassName(field->enum_type()), field->number());
           }
           }
-          format_("$1$ value = static_cast<$1$>(val);\n",
-                  QualifiedClassName(field->enum_type()));
+          format_("msg->$1$_$2$(static_cast<$3$>(val));\n", prefix,
+                  FieldName(field), QualifiedClassName(field->enum_type()));
         } else {
         } else {
-          format_("$1$ value = val;\n", type);
-        }
-        if (field->is_repeated()) {
-          format_("msg->add_$1$(value);\n", FieldName(field));
-        } else {
-          format_("msg->set_$1$(value);\n", FieldName(field));
+          string zigzag;
+          if ((field->type() == FieldDescriptor::TYPE_SINT32 ||
+               field->type() == FieldDescriptor::TYPE_SINT64) &&
+              !IsProto1(field->file(), options_)) {
+            int size = field->type() == FieldDescriptor::TYPE_SINT32 ? 32 : 64;
+            zigzag = StrCat("ZigZag", size);
+          }
+          format_(
+              "msg->$1$_$2$(::$proto_ns$::internal::ReadVarint$3$(&ptr));\n",
+              prefix, FieldName(field), zigzag);
         }
         }
+        format_("$GOOGLE_PROTOBUF$_PARSER_ASSERT(ptr);\n");
         break;
         break;
       }
       }
+      case WireFormatLite::WIRETYPE_FIXED32:
       case WireFormatLite::WIRETYPE_FIXED64: {
       case WireFormatLite::WIRETYPE_FIXED64: {
+        string prefix = field->is_repeated() ? "add" : "set";
         string type = PrimitiveTypeName(options_, field->cpp_type());
         string type = PrimitiveTypeName(options_, field->cpp_type());
         format_(
         format_(
-            "$1$ val;\n"
-            "::std::memcpy(&val, ptr, 8);\n"
-            "ptr += 8;\n",
-            type);
-        if (field->is_repeated()) {
-          format_("msg->add_$1$(val);\n", FieldName(field));
-        } else {
-          format_("msg->set_$1$(val);\n", FieldName(field));
-        }
+            "msg->$1$_$2$(::$proto_ns$::io::UnalignedLoad<$3$>(ptr));\n"
+            "ptr += sizeof($3$);\n",
+            prefix, FieldName(field), type);
         break;
         break;
       }
       }
       case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
       case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
@@ -1786,20 +1792,6 @@ class ParseLoopGenerator {
         GOOGLE_LOG(FATAL) << "Can't have end group field\n";
         GOOGLE_LOG(FATAL) << "Can't have end group field\n";
         break;
         break;
       }
       }
-      case WireFormatLite::WIRETYPE_FIXED32: {
-        string type = PrimitiveTypeName(options_, field->cpp_type());
-        format_(
-            "$1$ val;\n"
-            "std::memcpy(&val, ptr, 4);\n"
-            "ptr += 4;\n",
-            type);
-        if (field->is_repeated()) {
-          format_("msg->add_$1$(val);\n", FieldName(field));
-        } else {
-          format_("msg->set_$1$(val);\n", FieldName(field));
-        }
-        break;
-      }
     }  // switch (wire_type)
     }  // switch (wire_type)
 
 
     if (ShouldRepeat(field, wiretype)) {
     if (ShouldRepeat(field, wiretype)) {

+ 2 - 1
src/google/protobuf/compiler/cpp/cpp_helpers.h

@@ -51,6 +51,7 @@
 
 
 #include <google/protobuf/port_def.inc>
 #include <google/protobuf/port_def.inc>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -593,7 +594,7 @@ class PROTOC_EXPORT Formatter {
   template <typename I, typename = typename std::enable_if<
   template <typename I, typename = typename std::enable_if<
                             std::is_integral<I>::value>::type>
                             std::is_integral<I>::value>::type>
   static std::string ToString(I x) {
   static std::string ToString(I x) {
-    return SimpleItoa(x);
+    return StrCat(x);
   }
   }
   static std::string ToString(strings::Hex x) { return StrCat(x); }
   static std::string ToString(strings::Hex x) { return StrCat(x); }
   static std::string ToString(const FieldDescriptor* d) { return Payload(d); }
   static std::string ToString(const FieldDescriptor* d) { return Payload(d); }

+ 2 - 3
src/google/protobuf/compiler/cpp/cpp_map_field.cc

@@ -80,9 +80,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
   (*variables)["val_wire_type"] =
   (*variables)["val_wire_type"] =
       "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
       "TYPE_" + ToUpper(DeclaredTypeMethodName(val->type()));
   (*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
   (*variables)["map_classname"] = ClassName(descriptor->message_type(), false);
-  (*variables)["number"] = SimpleItoa(descriptor->number());
-  (*variables)["tag"] =
-      SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+  (*variables)["number"] = StrCat(descriptor->number());
+  (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));
 
 
   if (HasDescriptorMethods(descriptor->file(), options)) {
   if (HasDescriptorMethods(descriptor->file(), options)) {
     (*variables)["lite"] = "";
     (*variables)["lite"] = "";

+ 19 - 24
src/google/protobuf/compiler/cpp/cpp_message.cc

@@ -246,8 +246,7 @@ bool HasPrivateHasMethod(const FieldDescriptor* field) {
 
 
 bool ShouldMarkClassAsFinal(const Descriptor* descriptor,
 bool ShouldMarkClassAsFinal(const Descriptor* descriptor,
                             const Options& options) {
                             const Options& options) {
-  const string name = ClassName(descriptor, true);
-  return HasPrefixString(name, "::google::protobuf");
+  return true;
 }
 }
 
 
 bool ShouldMarkClearAsFinal(const Descriptor* descriptor,
 bool ShouldMarkClearAsFinal(const Descriptor* descriptor,
@@ -909,7 +908,7 @@ void MessageGenerator::GenerateFieldAccessorDefinitions(io::Printer* printer) {
       format.Set("field_name", UnderscoresToCamelCase(field->name(), true));
       format.Set("field_name", UnderscoresToCamelCase(field->name(), true));
       format.Set("oneof_name", field->containing_oneof()->name());
       format.Set("oneof_name", field->containing_oneof()->name());
       format.Set("oneof_index",
       format.Set("oneof_index",
-                 SimpleItoa(field->containing_oneof()->index()));
+                 StrCat(field->containing_oneof()->index()));
       GenerateOneofMemberHasBits(field, format);
       GenerateOneofMemberHasBits(field, format);
     } else {
     } else {
       // Singular field.
       // Singular field.
@@ -1342,8 +1341,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) {
   const string has_bits_decl =
   const string has_bits_decl =
       sizeof_has_bits == 0
       sizeof_has_bits == 0
           ? ""
           ? ""
-          : "::$proto_ns$::internal::HasBits<" +
-                SimpleItoa(sizeof_has_bits / 4) + "> _has_bits_;\n";
+          : StrCat("::$proto_ns$::internal::HasBits<",
+                         sizeof_has_bits / 4, "> _has_bits_;\n");
 
 
   // To minimize padding, data members are divided into three sections:
   // To minimize padding, data members are divided into three sections:
   // (1) members assumed to align to 8 bytes
   // (1) members assumed to align to 8 bytes
@@ -1634,10 +1633,9 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
       std::map<string, string> vars;
       std::map<string, string> vars;
       vars["classtype"] = QualifiedClassName(descriptor_);
       vars["classtype"] = QualifiedClassName(descriptor_);
       vars["field_name"] = FieldName(field);
       vars["field_name"] = FieldName(field);
-      vars["tag"] = SimpleItoa(tag);
-      vars["hasbit"] = SimpleItoa(i);
-      vars["type"] =
-          SimpleItoa(CalcFieldNum(generator, field, options_));
+      vars["tag"] = StrCat(tag);
+      vars["hasbit"] = StrCat(i);
+      vars["type"] = StrCat(CalcFieldNum(generator, field, options_));
       vars["ptr"] = "nullptr";
       vars["ptr"] = "nullptr";
       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
         GOOGLE_CHECK(!IsMapEntryMessage(field->message_type()));
         GOOGLE_CHECK(!IsMapEntryMessage(field->message_type()));
@@ -1646,8 +1644,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
               "::" +
               "::" +
               UniqueName("TableStruct", field->message_type(), options_) +
               UniqueName("TableStruct", field->message_type(), options_) +
               "::serialization_table + " +
               "::serialization_table + " +
-              SimpleItoa(
-                  FindMessageIndexInFile(field->message_type()));
+              StrCat(FindMessageIndexInFile(field->message_type()));
         }
         }
       }
       }
       Formatter::SaveState saver(&format);
       Formatter::SaveState saver(&format);
@@ -1724,7 +1721,7 @@ int MessageGenerator::GenerateFieldMetadata(io::Printer* printer) {
         ptr =
         ptr =
             "::" + UniqueName("TableStruct", field->message_type(), options_) +
             "::" + UniqueName("TableStruct", field->message_type(), options_) +
             "::serialization_table + " +
             "::serialization_table + " +
-            SimpleItoa(FindMessageIndexInFile(field->message_type()));
+            StrCat(FindMessageIndexInFile(field->message_type()));
       }
       }
     }
     }
 
 
@@ -2172,16 +2169,15 @@ size_t MessageGenerator::GenerateParseOffsets(io::Printer* printer) {
     std::map<string, string> vars;
     std::map<string, string> vars;
     if (field->containing_oneof() != NULL) {
     if (field->containing_oneof() != NULL) {
       vars["name"] = field->containing_oneof()->name();
       vars["name"] = field->containing_oneof()->name();
-      vars["presence"] =
-          SimpleItoa(field->containing_oneof()->index());
+      vars["presence"] = StrCat(field->containing_oneof()->index());
     } else {
     } else {
       vars["name"] = FieldName(field);
       vars["name"] = FieldName(field);
-      vars["presence"] = SimpleItoa(has_bit_indices_[field->index()]);
+      vars["presence"] = StrCat(has_bit_indices_[field->index()]);
     }
     }
-    vars["nwtype"] = SimpleItoa(normal_wiretype);
-    vars["pwtype"] = SimpleItoa(packed_wiretype);
-    vars["ptype"] = SimpleItoa(processing_type);
-    vars["tag_size"] = SimpleItoa(tag_size);
+    vars["nwtype"] = StrCat(normal_wiretype);
+    vars["pwtype"] = StrCat(packed_wiretype);
+    vars["ptype"] = StrCat(processing_type);
+    vars["tag_size"] = StrCat(tag_size);
 
 
     format.AddMap(vars);
     format.AddMap(vars);
 
 
@@ -2336,9 +2332,8 @@ std::pair<size_t, size_t> MessageGenerator::GenerateOffsets(
   } else if (HasFieldPresence(descriptor_->file())) {
   } else if (HasFieldPresence(descriptor_->file())) {
     entries += has_bit_indices_.size();
     entries += has_bit_indices_.size();
     for (int i = 0; i < has_bit_indices_.size(); i++) {
     for (int i = 0; i < has_bit_indices_.size(); i++) {
-      const string index = has_bit_indices_[i] >= 0
-                               ? SimpleItoa(has_bit_indices_[i])
-                               : "~0u";
+      const string index =
+          has_bit_indices_[i] >= 0 ? StrCat(has_bit_indices_[i]) : "~0u";
       format("$1$,\n", index);
       format("$1$,\n", index);
     }
     }
   }
   }
@@ -3775,8 +3770,8 @@ void MessageGenerator::GenerateSerializeOneExtensionRange(
     io::Printer* printer, const Descriptor::ExtensionRange* range,
     io::Printer* printer, const Descriptor::ExtensionRange* range,
     bool to_array) {
     bool to_array) {
   std::map<string, string> vars;
   std::map<string, string> vars;
-  vars["start"] = SimpleItoa(range->start);
-  vars["end"] = SimpleItoa(range->end);
+  vars["start"] = StrCat(range->start);
+  vars["end"] = StrCat(range->end);
   Formatter format(printer, vars);
   Formatter format(printer, vars);
   format("// Extension range [$start$, $end$)\n");
   format("// Extension range [$start$, $end$)\n");
   if (to_array) {
   if (to_array) {

+ 3 - 3
src/google/protobuf/compiler/cpp/cpp_primitive_field.cc

@@ -38,6 +38,7 @@
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -85,11 +86,10 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
   SetCommonFieldVariables(descriptor, variables, options);
   SetCommonFieldVariables(descriptor, variables, options);
   (*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type());
   (*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type());
   (*variables)["default"] = DefaultValue(options, descriptor);
   (*variables)["default"] = DefaultValue(options, descriptor);
-  (*variables)["tag"] =
-      SimpleItoa(internal::WireFormat::MakeTag(descriptor));
+  (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor));
   int fixed_size = FixedSize(descriptor->type());
   int fixed_size = FixedSize(descriptor->type());
   if (fixed_size != -1) {
   if (fixed_size != -1) {
-    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+    (*variables)["fixed_size"] = StrCat(fixed_size);
   }
   }
   (*variables)["wire_format_field_type"] = FieldDescriptorProto_Type_Name(
   (*variables)["wire_format_field_type"] = FieldDescriptorProto_Type_Name(
       static_cast<FieldDescriptorProto_Type>(descriptor->type()));
       static_cast<FieldDescriptorProto_Type>(descriptor->type()));

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

@@ -39,6 +39,7 @@
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -52,7 +53,7 @@ void SetStringVariables(const FieldDescriptor* descriptor,
   SetCommonFieldVariables(descriptor, variables, options);
   SetCommonFieldVariables(descriptor, variables, options);
   (*variables)["default"] = DefaultValue(options, descriptor);
   (*variables)["default"] = DefaultValue(options, descriptor);
   (*variables)["default_length"] =
   (*variables)["default_length"] =
-      SimpleItoa(descriptor->default_value_string().length());
+      StrCat(descriptor->default_value_string().length());
   string default_variable_string = MakeDefaultName(descriptor);
   string default_variable_string = MakeDefaultName(descriptor);
   (*variables)["default_variable_name"] = default_variable_string;
   (*variables)["default_variable_name"] = default_variable_string;
   (*variables)["default_variable"] =
   (*variables)["default_variable"] =

+ 3 - 2
src/google/protobuf/compiler/java/java_context.cc

@@ -35,6 +35,7 @@
 #include <google/protobuf/compiler/java/java_name_resolver.h>
 #include <google/protobuf/compiler/java/java_name_resolver.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
+
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/map_util.h>
 
 
 namespace google {
 namespace google {
@@ -159,8 +160,8 @@ void Context::InitializeFieldGeneratorInfoForFields(
     // For fields conflicting with some other fields, we append the field
     // For fields conflicting with some other fields, we append the field
     // number to their field names in generated code to avoid conflicts.
     // number to their field names in generated code to avoid conflicts.
     if (is_conflict[i]) {
     if (is_conflict[i]) {
-      info.name += SimpleItoa(field->number());
-      info.capitalized_name += SimpleItoa(field->number());
+      info.name += StrCat(field->number());
+      info.capitalized_name += StrCat(field->number());
       info.disambiguated_reason = conflict_reason[i];
       info.disambiguated_reason = conflict_reason[i];
     }
     }
     field_generator_info_map_[field] = info;
     field_generator_info_map_[field] = info;

+ 7 - 6
src/google/protobuf/compiler/java/java_enum.cc

@@ -44,6 +44,7 @@
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -96,8 +97,8 @@ void EnumGenerator::Generate(io::Printer* printer) {
   for (int i = 0; i < canonical_values_.size(); i++) {
   for (int i = 0; i < canonical_values_.size(); i++) {
     std::map<string, string> vars;
     std::map<string, string> vars;
     vars["name"] = canonical_values_[i]->name();
     vars["name"] = canonical_values_[i]->name();
-    vars["index"] = SimpleItoa(canonical_values_[i]->index());
-    vars["number"] = SimpleItoa(canonical_values_[i]->number());
+    vars["index"] = StrCat(canonical_values_[i]->index());
+    vars["number"] = StrCat(canonical_values_[i]->number());
     WriteEnumValueDocComment(printer, canonical_values_[i]);
     WriteEnumValueDocComment(printer, canonical_values_[i]);
     if (canonical_values_[i]->options().deprecated()) {
     if (canonical_values_[i]->options().deprecated()) {
       printer->Print("@java.lang.Deprecated\n");
       printer->Print("@java.lang.Deprecated\n");
@@ -141,7 +142,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
   for (int i = 0; i < descriptor_->value_count(); i++) {
   for (int i = 0; i < descriptor_->value_count(); i++) {
     std::map<string, string> vars;
     std::map<string, string> vars;
     vars["name"] = descriptor_->value(i)->name();
     vars["name"] = descriptor_->value(i)->name();
-    vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+    vars["number"] = StrCat(descriptor_->value(i)->number());
     vars["{"] = "";
     vars["{"] = "";
     vars["}"] = "";
     vars["}"] = "";
     WriteEnumValueDocComment(printer, descriptor_->value(i));
     WriteEnumValueDocComment(printer, descriptor_->value(i));
@@ -192,7 +193,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
   for (int i = 0; i < canonical_values_.size(); i++) {
   for (int i = 0; i < canonical_values_.size(); i++) {
     printer->Print("case $number$: return $name$;\n", "name",
     printer->Print("case $number$: return $name$;\n", "name",
                    canonical_values_[i]->name(), "number",
                    canonical_values_[i]->name(), "number",
-                   SimpleItoa(canonical_values_[i]->number()));
+                   StrCat(canonical_values_[i]->number()));
   }
   }
 
 
   printer->Outdent();
   printer->Outdent();
@@ -244,7 +245,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
           "  return $file$.getDescriptor().getEnumTypes().get($index$);\n",
           "  return $file$.getDescriptor().getEnumTypes().get($index$);\n",
           "file",
           "file",
           name_resolver_->GetClassName(descriptor_->file(), immutable_api_),
           name_resolver_->GetClassName(descriptor_->file(), immutable_api_),
-          "index", SimpleItoa(descriptor_->index()));
+          "index", StrCat(descriptor_->index()));
     } else {
     } else {
       printer->Print(
       printer->Print(
           "  return $parent$.$descriptor$.getEnumTypes().get($index$);\n",
           "  return $parent$.$descriptor$.getEnumTypes().get($index$);\n",
@@ -257,7 +258,7 @@ void EnumGenerator::Generate(io::Printer* printer) {
                   .no_standard_descriptor_accessor()
                   .no_standard_descriptor_accessor()
               ? "getDefaultInstance().getDescriptorForType()"
               ? "getDefaultInstance().getDescriptorForType()"
               : "getDescriptor()",
               : "getDescriptor()",
-          "index", SimpleItoa(descriptor_->index()));
+          "index", StrCat(descriptor_->index()));
     }
     }
 
 
     printer->Print(
     printer->Print(

+ 10 - 9
src/google/protobuf/compiler/java/java_enum_field.cc

@@ -46,6 +46,7 @@
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -67,10 +68,10 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
       name_resolver->GetMutableClassName(descriptor->enum_type());
       name_resolver->GetMutableClassName(descriptor->enum_type());
   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
   (*variables)["default_number"] =
   (*variables)["default_number"] =
-      SimpleItoa(descriptor->default_value_enum()->number());
-  (*variables)["tag"] = SimpleItoa(
+      StrCat(descriptor->default_value_enum()->number());
+  (*variables)["tag"] = StrCat(
       static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
       static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
-  (*variables)["tag_size"] = SimpleItoa(
+  (*variables)["tag_size"] = StrCat(
       internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
       internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
   // by the proto compiler
   // by the proto compiler
@@ -358,7 +359,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
 void ImmutableEnumFieldGenerator::
 void ImmutableEnumFieldGenerator::
 GenerateEqualsCode(io::Printer* printer) const {
 GenerateEqualsCode(io::Printer* printer) const {
   printer->Print(variables_,
   printer->Print(variables_,
-    "result = result && $name$_ == other.$name$_;\n");
+    "if ($name$_ != other.$name$_) return false;\n");
 }
 }
 
 
 void ImmutableEnumFieldGenerator::
 void ImmutableEnumFieldGenerator::
@@ -554,12 +555,12 @@ void ImmutableEnumOneofFieldGenerator::
 GenerateEqualsCode(io::Printer* printer) const {
 GenerateEqualsCode(io::Printer* printer) const {
   if (SupportUnknownEnumValue(descriptor_->file())) {
   if (SupportUnknownEnumValue(descriptor_->file())) {
     printer->Print(variables_,
     printer->Print(variables_,
-      "result = result && get$capitalized_name$Value()\n"
-      "    == other.get$capitalized_name$Value();\n");
+      "if (get$capitalized_name$Value()\n"
+      "    != other.get$capitalized_name$Value()) return false;\n");
   } else {
   } else {
     printer->Print(variables_,
     printer->Print(variables_,
-      "result = result && get$capitalized_name$()\n"
-      "    .equals(other.get$capitalized_name$());\n");
+      "if (!get$capitalized_name$()\n"
+      "    .equals(other.get$capitalized_name$())) return false;\n");
   }
   }
 }
 }
 
 
@@ -983,7 +984,7 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
 void RepeatedImmutableEnumFieldGenerator::
 void RepeatedImmutableEnumFieldGenerator::
 GenerateEqualsCode(io::Printer* printer) const {
 GenerateEqualsCode(io::Printer* printer) const {
   printer->Print(variables_,
   printer->Print(variables_,
-    "result = result && $name$_.equals(other.$name$_);\n");
+    "if (!$name$_.equals(other.$name$_)) return false;\n");
 }
 }
 
 
 void RepeatedImmutableEnumFieldGenerator::
 void RepeatedImmutableEnumFieldGenerator::

+ 4 - 3
src/google/protobuf/compiler/java/java_enum_field_lite.cc

@@ -46,6 +46,7 @@
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -67,10 +68,10 @@ void SetEnumVariables(const FieldDescriptor* descriptor,
       name_resolver->GetMutableClassName(descriptor->enum_type());
       name_resolver->GetMutableClassName(descriptor->enum_type());
   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
   (*variables)["default_number"] =
   (*variables)["default_number"] =
-      SimpleItoa(descriptor->default_value_enum()->number());
-  (*variables)["tag"] = SimpleItoa(
+      StrCat(descriptor->default_value_enum()->number());
+  (*variables)["tag"] = StrCat(
       static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
       static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
-  (*variables)["tag_size"] = SimpleItoa(
+  (*variables)["tag_size"] = StrCat(
       internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
       internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
   // by the proto compiler
   // by the proto compiler

+ 4 - 3
src/google/protobuf/compiler/java/java_enum_lite.cc

@@ -43,6 +43,7 @@
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/descriptor.pb.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
+
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/map_util.h>
 
 
 namespace google {
 namespace google {
@@ -87,7 +88,7 @@ void EnumLiteGenerator::Generate(io::Printer* printer) {
   for (int i = 0; i < canonical_values_.size(); i++) {
   for (int i = 0; i < canonical_values_.size(); i++) {
     std::map<string, string> vars;
     std::map<string, string> vars;
     vars["name"] = canonical_values_[i]->name();
     vars["name"] = canonical_values_[i]->name();
-    vars["number"] = SimpleItoa(canonical_values_[i]->number());
+    vars["number"] = StrCat(canonical_values_[i]->number());
     WriteEnumValueDocComment(printer, canonical_values_[i]);
     WriteEnumValueDocComment(printer, canonical_values_[i]);
     if (canonical_values_[i]->options().deprecated()) {
     if (canonical_values_[i]->options().deprecated()) {
       printer->Print("@java.lang.Deprecated\n");
       printer->Print("@java.lang.Deprecated\n");
@@ -122,7 +123,7 @@ void EnumLiteGenerator::Generate(io::Printer* printer) {
   for (int i = 0; i < descriptor_->value_count(); i++) {
   for (int i = 0; i < descriptor_->value_count(); i++) {
     std::map<string, string> vars;
     std::map<string, string> vars;
     vars["name"] = descriptor_->value(i)->name();
     vars["name"] = descriptor_->value(i)->name();
-    vars["number"] = SimpleItoa(descriptor_->value(i)->number());
+    vars["number"] = StrCat(descriptor_->value(i)->number());
     vars["{"] = "";
     vars["{"] = "";
     vars["}"] = "";
     vars["}"] = "";
     WriteEnumValueDocComment(printer, descriptor_->value(i));
     WriteEnumValueDocComment(printer, descriptor_->value(i));
@@ -166,7 +167,7 @@ void EnumLiteGenerator::Generate(io::Printer* printer) {
   for (int i = 0; i < canonical_values_.size(); i++) {
   for (int i = 0; i < canonical_values_.size(); i++) {
     printer->Print("case $number$: return $name$;\n", "name",
     printer->Print("case $number$: return $name$;\n", "name",
                    canonical_values_[i]->name(), "number",
                    canonical_values_[i]->name(), "number",
-                   SimpleItoa(canonical_values_[i]->number()));
+                   StrCat(canonical_values_[i]->number()));
   }
   }
 
 
   printer->Outdent();
   printer->Outdent();

+ 4 - 3
src/google/protobuf/compiler/java/java_extension.cc

@@ -41,6 +41,7 @@
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -69,9 +70,9 @@ void ExtensionGenerator::InitTemplateVars(
   vars["name"] = UnderscoresToCamelCase(descriptor);
   vars["name"] = UnderscoresToCamelCase(descriptor);
   vars["containing_type"] =
   vars["containing_type"] =
       name_resolver->GetClassName(descriptor->containing_type(), immutable);
       name_resolver->GetClassName(descriptor->containing_type(), immutable);
-  vars["number"] = SimpleItoa(descriptor->number());
+  vars["number"] = StrCat(descriptor->number());
   vars["constant_name"] = FieldConstantName(descriptor);
   vars["constant_name"] = FieldConstantName(descriptor);
-  vars["index"] = SimpleItoa(descriptor->index());
+  vars["index"] = StrCat(descriptor->index());
   vars["default"] = descriptor->is_repeated() ?
   vars["default"] = descriptor->is_repeated() ?
       "" : DefaultValue(descriptor, immutable, name_resolver);
       "" : DefaultValue(descriptor, immutable, name_resolver);
   vars["type_constant"] = FieldTypeName(GetType(descriptor));
   vars["type_constant"] = FieldTypeName(GetType(descriptor));
@@ -152,7 +153,7 @@ int ImmutableExtensionGenerator::GenerateNonNestedInitializationCode(
     printer->Print(
     printer->Print(
         "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
         "$name$.internalInit(descriptor.getExtensions().get($index$));\n",
         "name", UnderscoresToCamelCase(descriptor_), "index",
         "name", UnderscoresToCamelCase(descriptor_), "index",
-        SimpleItoa(descriptor_->index()));
+        StrCat(descriptor_->index()));
     bytecode_estimate += 21;
     bytecode_estimate += 21;
   }
   }
   return bytecode_estimate;
   return bytecode_estimate;

+ 5 - 4
src/google/protobuf/compiler/java/java_field.cc

@@ -55,6 +55,7 @@
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/substitute.h>
 
 
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -254,7 +255,7 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor,
   (*variables)["capitalized_name"] = info->capitalized_name;
   (*variables)["capitalized_name"] = info->capitalized_name;
   (*variables)["disambiguated_reason"] = info->disambiguated_reason;
   (*variables)["disambiguated_reason"] = info->disambiguated_reason;
   (*variables)["constant_name"] = FieldConstantName(descriptor);
   (*variables)["constant_name"] = FieldConstantName(descriptor);
-  (*variables)["number"] = SimpleItoa(descriptor->number());
+  (*variables)["number"] = StrCat(descriptor->number());
   // These variables are placeholders to pick out the beginning and ends of
   // These variables are placeholders to pick out the beginning and ends of
   // identifiers for annotations (when doing so with existing variables would
   // identifiers for annotations (when doing so with existing variables would
   // be ambiguous or impossible). They should never be set to anything but the
   // be ambiguous or impossible). They should never be set to anything but the
@@ -269,13 +270,13 @@ void SetCommonOneofVariables(const FieldDescriptor* descriptor,
   (*variables)["oneof_name"] = info->name;
   (*variables)["oneof_name"] = info->name;
   (*variables)["oneof_capitalized_name"] = info->capitalized_name;
   (*variables)["oneof_capitalized_name"] = info->capitalized_name;
   (*variables)["oneof_index"] =
   (*variables)["oneof_index"] =
-      SimpleItoa(descriptor->containing_oneof()->index());
+      StrCat(descriptor->containing_oneof()->index());
   (*variables)["set_oneof_case_message"] =
   (*variables)["set_oneof_case_message"] =
-      info->name + "Case_ = " + SimpleItoa(descriptor->number());
+      info->name + "Case_ = " + StrCat(descriptor->number());
   (*variables)["clear_oneof_case_message"] = info->name +
   (*variables)["clear_oneof_case_message"] = info->name +
       "Case_ = 0";
       "Case_ = 0";
   (*variables)["has_oneof_case_message"] =
   (*variables)["has_oneof_case_message"] =
-      info->name + "Case_ == " + SimpleItoa(descriptor->number());
+      info->name + "Case_ == " + StrCat(descriptor->number());
 }
 }
 
 
 void PrintExtraFieldInfo(const std::map<string, string>& variables,
 void PrintExtraFieldInfo(const std::map<string, string>& variables,

+ 5 - 7
src/google/protobuf/compiler/java/java_file.cc

@@ -54,6 +54,7 @@
 #include <google/protobuf/dynamic_message.h>
 #include <google/protobuf/dynamic_message.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -172,11 +173,10 @@ void MaybeRestartJavaMethod(io::Printer* printer,
 
 
   if ((*bytecode_estimate) > bytesPerMethod) {
   if ((*bytecode_estimate) > bytesPerMethod) {
     ++(*method_num);
     ++(*method_num);
-    printer->Print(chain_statement, "method_num",
-                   SimpleItoa(*method_num));
+    printer->Print(chain_statement, "method_num", StrCat(*method_num));
     printer->Outdent();
     printer->Outdent();
     printer->Print("}\n");
     printer->Print("}\n");
-    printer->Print(method_decl, "method_num", SimpleItoa(*method_num));
+    printer->Print(method_decl, "method_num", StrCat(*method_num));
     printer->Indent();
     printer->Indent();
     *bytecode_estimate = 0;
     *bytecode_estimate = 0;
   }
   }
@@ -548,13 +548,11 @@ void FileGenerator::GenerateDescriptorInitializationCodeForMutable(io::Printer*
             "      $scope$.getExtensions().get($index$),\n"
             "      $scope$.getExtensions().get($index$),\n"
             "      (com.google.protobuf.Message) defaultExtensionInstance);\n"
             "      (com.google.protobuf.Message) defaultExtensionInstance);\n"
             "}\n",
             "}\n",
-            "scope", scope, "index", SimpleItoa(field->index()),
-            "class",
+            "scope", scope, "index", StrCat(field->index()), "class",
             name_resolver_->GetImmutableClassName(field->message_type()));
             name_resolver_->GetImmutableClassName(field->message_type()));
       } else {
       } else {
         printer->Print("registry.add($scope$.getExtensions().get($index$));\n",
         printer->Print("registry.add($scope$.getExtensions().get($index$));\n",
-                       "scope", scope, "index",
-                       SimpleItoa(field->index()));
+                       "scope", scope, "index", StrCat(field->index()));
       }
       }
     }
     }
     printer->Print(
     printer->Print(

+ 7 - 8
src/google/protobuf/compiler/java/java_helpers.cc

@@ -46,6 +46,7 @@
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/substitute.h>
 
 
 
 
+
 #include <google/protobuf/stubs/hash.h>  // for hash<T *>
 #include <google/protobuf/stubs/hash.h>  // for hash<T *>
 
 
 namespace google {
 namespace google {
@@ -473,16 +474,14 @@ string DefaultValue(const FieldDescriptor* field, bool immutable,
   // of FieldDescriptor to call.
   // of FieldDescriptor to call.
   switch (field->cpp_type()) {
   switch (field->cpp_type()) {
     case FieldDescriptor::CPPTYPE_INT32:
     case FieldDescriptor::CPPTYPE_INT32:
-      return SimpleItoa(field->default_value_int32());
+      return StrCat(field->default_value_int32());
     case FieldDescriptor::CPPTYPE_UINT32:
     case FieldDescriptor::CPPTYPE_UINT32:
       // Need to print as a signed int since Java has no unsigned.
       // Need to print as a signed int since Java has no unsigned.
-      return SimpleItoa(
-          static_cast<int32>(field->default_value_uint32()));
+      return StrCat(static_cast<int32>(field->default_value_uint32()));
     case FieldDescriptor::CPPTYPE_INT64:
     case FieldDescriptor::CPPTYPE_INT64:
-      return SimpleItoa(field->default_value_int64()) + "L";
+      return StrCat(field->default_value_int64()) + "L";
     case FieldDescriptor::CPPTYPE_UINT64:
     case FieldDescriptor::CPPTYPE_UINT64:
-      return SimpleItoa(
-                 static_cast<int64>(field->default_value_uint64())) +
+      return StrCat(static_cast<int64>(field->default_value_uint64())) +
              "L";
              "L";
     case FieldDescriptor::CPPTYPE_DOUBLE: {
     case FieldDescriptor::CPPTYPE_DOUBLE: {
       double value = field->default_value_double();
       double value = field->default_value_double();
@@ -625,7 +624,7 @@ const char* bit_masks[] = {
 
 
 string GetBitFieldName(int index) {
 string GetBitFieldName(int index) {
   string varName = "bitField";
   string varName = "bitField";
-  varName += SimpleItoa(index);
+  varName += StrCat(index);
   varName += "_";
   varName += "_";
   return varName;
   return varName;
 }
 }
@@ -641,7 +640,7 @@ string GenerateGetBitInternal(const string& prefix, int bitIndex) {
   int bitInVarIndex = bitIndex % 32;
   int bitInVarIndex = bitIndex % 32;
 
 
   string mask = bit_masks[bitInVarIndex];
   string mask = bit_masks[bitInVarIndex];
-  string result = "((" + varName + " & " + mask + ") == " + mask + ")";
+  string result = "((" + varName + " & " + mask + ") != 0)";
   return result;
   return result;
 }
 }
 
 

+ 2 - 2
src/google/protobuf/compiler/java/java_map_field.cc

@@ -773,8 +773,8 @@ void ImmutableMapFieldGenerator::
 GenerateEqualsCode(io::Printer* printer) const {
 GenerateEqualsCode(io::Printer* printer) const {
   printer->Print(
   printer->Print(
       variables_,
       variables_,
-      "result = result && internalGet$capitalized_name$().equals(\n"
-      "    other.internalGet$capitalized_name$());\n");
+      "if (!internalGet$capitalized_name$().equals(\n"
+      "    other.internalGet$capitalized_name$())) return false;\n");
 }
 }
 
 
 void ImmutableMapFieldGenerator::
 void ImmutableMapFieldGenerator::

+ 21 - 24
src/google/protobuf/compiler/java/java_message.cc

@@ -56,6 +56,7 @@
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/substitute.h>
 
 
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -109,7 +110,7 @@ void ImmutableMessageGenerator::GenerateStaticVariables(
 
 
   std::map<string, string> vars;
   std::map<string, string> vars;
   vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
   vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
-  vars["index"] = SimpleItoa(descriptor_->index());
+  vars["index"] = StrCat(descriptor_->index());
   vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
   vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
   if (descriptor_->containing_type() != NULL) {
   if (descriptor_->containing_type() != NULL) {
     vars["parent"] = UniqueFileScopeIdentifier(
     vars["parent"] = UniqueFileScopeIdentifier(
@@ -153,7 +154,7 @@ int ImmutableMessageGenerator::GenerateStaticVariableInitializers(
   int bytecode_estimate = 0;
   int bytecode_estimate = 0;
   std::map<string, string> vars;
   std::map<string, string> vars;
   vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
   vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
-  vars["index"] = SimpleItoa(descriptor_->index());
+  vars["index"] = StrCat(descriptor_->index());
   vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
   vars["classname"] = name_resolver_->GetImmutableClassName(descriptor_);
   if (descriptor_->containing_type() != NULL) {
   if (descriptor_->containing_type() != NULL) {
     vars["parent"] = UniqueFileScopeIdentifier(
     vars["parent"] = UniqueFileScopeIdentifier(
@@ -417,8 +418,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
         descriptor_->oneof_decl(i))->name;
         descriptor_->oneof_decl(i))->name;
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
         descriptor_->oneof_decl(i))->capitalized_name;
         descriptor_->oneof_decl(i))->capitalized_name;
-    vars["oneof_index"] =
-        SimpleItoa(descriptor_->oneof_decl(i)->index());
+    vars["oneof_index"] = StrCat(descriptor_->oneof_decl(i)->index());
     // oneofCase_ and oneof_
     // oneofCase_ and oneof_
     printer->Print(vars,
     printer->Print(vars,
       "private int $oneof_name$Case_ = 0;\n"
       "private int $oneof_name$Case_ = 0;\n"
@@ -434,7 +434,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
           "$deprecation$$field_name$($field_number$),\n", "deprecation",
           "$deprecation$$field_name$($field_number$),\n", "deprecation",
           field->options().deprecated() ? "@java.lang.Deprecated " : "",
           field->options().deprecated() ? "@java.lang.Deprecated " : "",
           "field_name", ToUpper(field->name()), "field_number",
           "field_name", ToUpper(field->name()), "field_number",
-          SimpleItoa(field->number()));
+          StrCat(field->number()));
     }
     }
     printer->Print(
     printer->Print(
       "$cap_oneof_name$_NOT_SET(0);\n",
       "$cap_oneof_name$_NOT_SET(0);\n",
@@ -459,7 +459,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
       printer->Print("    case $field_number$: return $field_name$;\n",
       printer->Print("    case $field_number$: return $field_name$;\n",
-                     "field_number", SimpleItoa(field->number()),
+                     "field_number", StrCat(field->number()),
                      "field_name", ToUpper(field->name()));
                      "field_name", ToUpper(field->name()));
     }
     }
     printer->Print(
     printer->Print(
@@ -491,8 +491,7 @@ void ImmutableMessageGenerator::Generate(io::Printer* printer) {
   for (int i = 0; i < descriptor_->field_count(); i++) {
   for (int i = 0; i < descriptor_->field_count(); i++) {
     printer->Print("public static final int $constant_name$ = $number$;\n",
     printer->Print("public static final int $constant_name$ = $number$;\n",
                    "constant_name", FieldConstantName(descriptor_->field(i)),
                    "constant_name", FieldConstantName(descriptor_->field(i)),
-                   "number",
-                   SimpleItoa(descriptor_->field(i)->number()));
+                   "number", StrCat(descriptor_->field(i)->number()));
     field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
     field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
     printer->Print("\n");
     printer->Print("\n");
   }
   }
@@ -764,7 +763,7 @@ void ImmutableMessageGenerator::GenerateSerializeOneField(
 void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
 void ImmutableMessageGenerator::GenerateSerializeOneExtensionRange(
     io::Printer* printer, const Descriptor::ExtensionRange* range) {
     io::Printer* printer, const Descriptor::ExtensionRange* range) {
   printer->Print("extensionWriter.writeUntil($end$, output);\n", "end",
   printer->Print("extensionWriter.writeUntil($end$, output);\n", "end",
-                 SimpleItoa(range->end));
+                 StrCat(range->end));
 }
 }
 
 
 // ===================================================================
 // ===================================================================
@@ -838,7 +837,7 @@ GenerateDescriptorMethods(io::Printer* printer) {
       printer->Print(
       printer->Print(
           "case $number$:\n"
           "case $number$:\n"
           "  return internalGet$capitalized_name$();\n",
           "  return internalGet$capitalized_name$();\n",
-          "number", SimpleItoa(field->number()), "capitalized_name",
+          "number", StrCat(field->number()), "capitalized_name",
           info->capitalized_name);
           info->capitalized_name);
     }
     }
     printer->Print(
     printer->Print(
@@ -929,7 +928,7 @@ void ImmutableMessageGenerator::GenerateIsInitialized(
                 context_->GetOneofGeneratorInfo(oneof);
                 context_->GetOneofGeneratorInfo(oneof);
             printer->Print("if ($oneof_name$Case_ == $field_number$) {\n",
             printer->Print("if ($oneof_name$Case_ == $field_number$) {\n",
                            "oneof_name", oneof_info->name, "field_number",
                            "oneof_name", oneof_info->name, "field_number",
-                           SimpleItoa(field->number()));
+                           StrCat(field->number()));
           } else {
           } else {
             printer->Print(
             printer->Print(
               "if (has$name$()) {\n",
               "if (has$name$()) {\n",
@@ -1023,7 +1022,6 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
     "\n",
     "\n",
     "classname", name_resolver_->GetImmutableClassName(descriptor_));
     "classname", name_resolver_->GetImmutableClassName(descriptor_));
 
 
-  printer->Print("boolean result = true;\n");
   for (int i = 0; i < descriptor_->field_count(); i++) {
   for (int i = 0; i < descriptor_->field_count(); i++) {
     const FieldDescriptor* field = descriptor_->field(i);
     const FieldDescriptor* field = descriptor_->field(i);
     if (field->containing_oneof() == NULL) {
     if (field->containing_oneof() == NULL) {
@@ -1031,7 +1029,7 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
       bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
       bool check_has_bits = CheckHasBitsForEqualsAndHashCode(field);
       if (check_has_bits) {
       if (check_has_bits) {
         printer->Print(
         printer->Print(
-          "result = result && (has$name$() == other.has$name$());\n"
+          "if (has$name$() != other.has$name$()) return false;\n"
           "if (has$name$()) {\n",
           "if (has$name$()) {\n",
           "name", info->capitalized_name);
           "name", info->capitalized_name);
         printer->Indent();
         printer->Indent();
@@ -1048,13 +1046,12 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
   // Compare oneofs.
   // Compare oneofs.
   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
   for (int i = 0; i < descriptor_->oneof_decl_count(); i++) {
     printer->Print(
     printer->Print(
-      "result = result && get$oneof_capitalized_name$Case().equals(\n"
-      "    other.get$oneof_capitalized_name$Case());\n",
+      "if (!get$oneof_capitalized_name$Case().equals("
+      "other.get$oneof_capitalized_name$Case())) return false;\n",
       "oneof_capitalized_name",
       "oneof_capitalized_name",
       context_->GetOneofGeneratorInfo(
       context_->GetOneofGeneratorInfo(
           descriptor_->oneof_decl(i))->capitalized_name);
           descriptor_->oneof_decl(i))->capitalized_name);
     printer->Print(
     printer->Print(
-      "if (!result) return false;\n"
       "switch ($oneof_name$Case_) {\n",
       "switch ($oneof_name$Case_) {\n",
       "oneof_name",
       "oneof_name",
       context_->GetOneofGeneratorInfo(
       context_->GetOneofGeneratorInfo(
@@ -1063,7 +1060,7 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
       printer->Print("case $field_number$:\n", "field_number",
       printer->Print("case $field_number$:\n", "field_number",
-                     SimpleItoa(field->number()));
+                     StrCat(field->number()));
       printer->Indent();
       printer->Indent();
       field_generators_.get(field).GenerateEqualsCode(printer);
       field_generators_.get(field).GenerateEqualsCode(printer);
       printer->Print("break;\n");
       printer->Print("break;\n");
@@ -1080,14 +1077,14 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
   // false for non-canonical ordering when running in LITE_RUNTIME but it's
   // false for non-canonical ordering when running in LITE_RUNTIME but it's
   // the best we can do.
   // the best we can do.
   printer->Print(
   printer->Print(
-      "result = result && unknownFields.equals(other.unknownFields);\n");
+      "if (!unknownFields.equals(other.unknownFields)) return false;\n");
   if (descriptor_->extension_range_count() > 0) {
   if (descriptor_->extension_range_count() > 0) {
     printer->Print(
     printer->Print(
-      "result = result &&\n"
-      "    getExtensionFields().equals(other.getExtensionFields());\n");
+      "if (!getExtensionFields().equals(other.getExtensionFields()))\n"
+      "  return false;\n");
   }
   }
   printer->Print(
   printer->Print(
-    "return result;\n");
+    "return true;\n");
   printer->Outdent();
   printer->Outdent();
   printer->Print(
   printer->Print(
     "}\n"
     "}\n"
@@ -1145,7 +1142,7 @@ GenerateEqualsAndHashCode(io::Printer* printer) {
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
     for (int j = 0; j < descriptor_->oneof_decl(i)->field_count(); j++) {
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
       const FieldDescriptor* field = descriptor_->oneof_decl(i)->field(j);
       printer->Print("case $field_number$:\n", "field_number",
       printer->Print("case $field_number$:\n", "field_number",
-                     SimpleItoa(field->number()));
+                     StrCat(field->number()));
       printer->Indent();
       printer->Indent();
       field_generators_.get(field).GenerateHashCode(printer);
       field_generators_.get(field).GenerateHashCode(printer);
       printer->Print("break;\n");
       printer->Print("break;\n");
@@ -1252,7 +1249,7 @@ GenerateParsingConstructor(io::Printer* printer) {
       WireFormat::WireTypeForFieldType(field->type()));
       WireFormat::WireTypeForFieldType(field->type()));
 
 
     printer->Print("case $tag$: {\n", "tag",
     printer->Print("case $tag$: {\n", "tag",
-                   SimpleItoa(static_cast<int32>(tag)));
+                   StrCat(static_cast<int32>(tag)));
     printer->Indent();
     printer->Indent();
 
 
     field_generators_.get(field).GenerateParsingCode(printer);
     field_generators_.get(field).GenerateParsingCode(printer);
@@ -1268,7 +1265,7 @@ GenerateParsingConstructor(io::Printer* printer) {
       uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
       uint32 packed_tag = WireFormatLite::MakeTag(field->number(),
         WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
         WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
       printer->Print("case $tag$: {\n", "tag",
       printer->Print("case $tag$: {\n", "tag",
-                     SimpleItoa(static_cast<int32>(packed_tag)));
+                     StrCat(static_cast<int32>(packed_tag)));
       printer->Indent();
       printer->Indent();
 
 
       field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
       field_generators_.get(field).GenerateParsingCodeFromPacked(printer);

+ 5 - 5
src/google/protobuf/compiler/java/java_message_builder.cc

@@ -54,6 +54,7 @@
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/substitute.h>
 
 
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -125,8 +126,7 @@ Generate(io::Printer* printer) {
         descriptor_->oneof_decl(i))->name;
         descriptor_->oneof_decl(i))->name;
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
         descriptor_->oneof_decl(i))->capitalized_name;
         descriptor_->oneof_decl(i))->capitalized_name;
-    vars["oneof_index"] =
-        SimpleItoa(descriptor_->oneof_decl(i)->index());
+    vars["oneof_index"] = StrCat(descriptor_->oneof_decl(i)->index());
     // oneofCase_ and oneof_
     // oneofCase_ and oneof_
     printer->Print(vars,
     printer->Print(vars,
       "private int $oneof_name$Case_ = 0;\n"
       "private int $oneof_name$Case_ = 0;\n"
@@ -233,7 +233,7 @@ GenerateDescriptorMethods(io::Printer* printer) {
       printer->Print(
       printer->Print(
           "case $number$:\n"
           "case $number$:\n"
           "  return internalGet$capitalized_name$();\n",
           "  return internalGet$capitalized_name$();\n",
-          "number", SimpleItoa(field->number()), "capitalized_name",
+          "number", StrCat(field->number()), "capitalized_name",
           info->capitalized_name);
           info->capitalized_name);
     }
     }
     printer->Print(
     printer->Print(
@@ -259,7 +259,7 @@ GenerateDescriptorMethods(io::Printer* printer) {
       printer->Print(
       printer->Print(
           "case $number$:\n"
           "case $number$:\n"
           "  return internalGetMutable$capitalized_name$();\n",
           "  return internalGetMutable$capitalized_name$();\n",
-          "number", SimpleItoa(field->number()), "capitalized_name",
+          "number", StrCat(field->number()), "capitalized_name",
           info->capitalized_name);
           info->capitalized_name);
     }
     }
     printer->Print(
     printer->Print(
@@ -685,7 +685,7 @@ void MessageBuilderGenerator::GenerateIsInitialized(
                 context_->GetOneofGeneratorInfo(oneof);
                 context_->GetOneofGeneratorInfo(oneof);
             printer->Print("if ($oneof_name$Case_ == $field_number$) {\n",
             printer->Print("if ($oneof_name$Case_ == $field_number$) {\n",
                            "oneof_name", oneof_info->name, "field_number",
                            "oneof_name", oneof_info->name, "field_number",
-                           SimpleItoa(field->number()));
+                           StrCat(field->number()));
           } else {
           } else {
             printer->Print(
             printer->Print(
               "if (has$name$()) {\n",
               "if (has$name$()) {\n",

+ 2 - 2
src/google/protobuf/compiler/java/java_message_builder_lite.cc

@@ -53,6 +53,7 @@
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/substitute.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -101,8 +102,7 @@ Generate(io::Printer* printer) {
         descriptor_->oneof_decl(i))->name;
         descriptor_->oneof_decl(i))->name;
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
         descriptor_->oneof_decl(i))->capitalized_name;
         descriptor_->oneof_decl(i))->capitalized_name;
-    vars["oneof_index"] =
-        SimpleItoa(descriptor_->oneof_decl(i)->index());
+    vars["oneof_index"] = StrCat(descriptor_->oneof_decl(i)->index());
 
 
     // oneofCase() and clearOneof()
     // oneofCase() and clearOneof()
     printer->Print(vars,
     printer->Print(vars,

+ 4 - 4
src/google/protobuf/compiler/java/java_message_field.cc

@@ -506,8 +506,8 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
 void ImmutableMessageFieldGenerator::
 void ImmutableMessageFieldGenerator::
 GenerateEqualsCode(io::Printer* printer) const {
 GenerateEqualsCode(io::Printer* printer) const {
   printer->Print(variables_,
   printer->Print(variables_,
-    "result = result && get$capitalized_name$()\n"
-    "    .equals(other.get$capitalized_name$());\n");
+    "if (!get$capitalized_name$()\n"
+    "    .equals(other.get$capitalized_name$())) return false;\n");
 }
 }
 
 
 void ImmutableMessageFieldGenerator::
 void ImmutableMessageFieldGenerator::
@@ -1307,8 +1307,8 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
 void RepeatedImmutableMessageFieldGenerator::
 void RepeatedImmutableMessageFieldGenerator::
 GenerateEqualsCode(io::Printer* printer) const {
 GenerateEqualsCode(io::Printer* printer) const {
   printer->Print(variables_,
   printer->Print(variables_,
-    "result = result && get$capitalized_name$List()\n"
-    "    .equals(other.get$capitalized_name$List());\n");
+    "if (!get$capitalized_name$List()\n"
+    "    .equals(other.get$capitalized_name$List())) return false;\n");
 }
 }
 
 
 void RepeatedImmutableMessageFieldGenerator::
 void RepeatedImmutableMessageFieldGenerator::

+ 2 - 1
src/google/protobuf/compiler/java/java_message_field_lite.cc

@@ -36,14 +36,15 @@
 #include <string>
 #include <string>
 
 
 #include <google/protobuf/compiler/java/java_context.h>
 #include <google/protobuf/compiler/java/java_context.h>
-#include <google/protobuf/compiler/java/java_message_field_lite.h>
 #include <google/protobuf/compiler/java/java_doc_comment.h>
 #include <google/protobuf/compiler/java/java_doc_comment.h>
 #include <google/protobuf/compiler/java/java_helpers.h>
 #include <google/protobuf/compiler/java/java_helpers.h>
+#include <google/protobuf/compiler/java/java_message_field_lite.h>
 #include <google/protobuf/compiler/java/java_name_resolver.h>
 #include <google/protobuf/compiler/java/java_name_resolver.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {

+ 9 - 9
src/google/protobuf/compiler/java/java_message_lite.cc

@@ -56,6 +56,7 @@
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/substitute.h>
 
 
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -253,7 +254,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
     vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
     vars["oneof_name"] = context_->GetOneofGeneratorInfo(oneof)->name;
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
     vars["oneof_capitalized_name"] = context_->GetOneofGeneratorInfo(
         oneof)->capitalized_name;
         oneof)->capitalized_name;
-    vars["oneof_index"] = SimpleItoa(oneof->index());
+    vars["oneof_index"] = StrCat(oneof->index());
     // oneofCase_ and oneof_
     // oneofCase_ and oneof_
     printer->Print(vars,
     printer->Print(vars,
       "private int $oneof_name$Case_ = 0;\n"
       "private int $oneof_name$Case_ = 0;\n"
@@ -267,7 +268,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
       const FieldDescriptor* field = oneof->field(j);
       const FieldDescriptor* field = oneof->field(j);
       printer->Print("$field_name$($field_number$),\n", "field_name",
       printer->Print("$field_name$($field_number$),\n", "field_name",
                      ToUpper(field->name()), "field_number",
                      ToUpper(field->name()), "field_number",
-                     SimpleItoa(field->number()));
+                     StrCat(field->number()));
     }
     }
     printer->Print(
     printer->Print(
       "$cap_oneof_name$_NOT_SET(0);\n",
       "$cap_oneof_name$_NOT_SET(0);\n",
@@ -292,7 +293,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
     for (int j = 0; j < oneof->field_count(); j++) {
     for (int j = 0; j < oneof->field_count(); j++) {
       const FieldDescriptor* field = oneof->field(j);
       const FieldDescriptor* field = oneof->field(j);
       printer->Print("    case $field_number$: return $field_name$;\n",
       printer->Print("    case $field_number$: return $field_name$;\n",
-                     "field_number", SimpleItoa(field->number()),
+                     "field_number", StrCat(field->number()),
                      "field_name", ToUpper(field->name()));
                      "field_name", ToUpper(field->name()));
     }
     }
     printer->Print(
     printer->Print(
@@ -327,8 +328,7 @@ void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) {
   for (int i = 0; i < descriptor_->field_count(); i++) {
   for (int i = 0; i < descriptor_->field_count(); i++) {
     printer->Print("public static final int $constant_name$ = $number$;\n",
     printer->Print("public static final int $constant_name$ = $number$;\n",
                    "constant_name", FieldConstantName(descriptor_->field(i)),
                    "constant_name", FieldConstantName(descriptor_->field(i)),
-                   "number",
-                   SimpleItoa(descriptor_->field(i)->number()));
+                   "number", StrCat(descriptor_->field(i)->number()));
     field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
     field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
     printer->Print("\n");
     printer->Print("\n");
   }
   }
@@ -729,7 +729,7 @@ void ImmutableMessageLiteGenerator::GenerateSerializeOneField(
 void ImmutableMessageLiteGenerator::GenerateSerializeOneExtensionRange(
 void ImmutableMessageLiteGenerator::GenerateSerializeOneExtensionRange(
     io::Printer* printer, const Descriptor::ExtensionRange* range) {
     io::Printer* printer, const Descriptor::ExtensionRange* range) {
   printer->Print("extensionWriter.writeUntil($end$, output);\n", "end",
   printer->Print("extensionWriter.writeUntil($end$, output);\n", "end",
-                 SimpleItoa(range->end));
+                 StrCat(range->end));
 }
 }
 
 
 // ===================================================================
 // ===================================================================
@@ -810,7 +810,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodIsInitialized(
                 context_->GetOneofGeneratorInfo(oneof);
                 context_->GetOneofGeneratorInfo(oneof);
             printer->Print("if ($oneof_name$Case_ == $field_number$) {\n",
             printer->Print("if ($oneof_name$Case_ == $field_number$) {\n",
                            "oneof_name", oneof_info->name, "field_number",
                            "oneof_name", oneof_info->name, "field_number",
-                           SimpleItoa(field->number()));
+                           StrCat(field->number()));
           } else {
           } else {
             printer->Print(
             printer->Print(
               "if (has$name$()) {\n",
               "if (has$name$()) {\n",
@@ -1014,7 +1014,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFromStream(
         field->number(), WireFormat::WireTypeForFieldType(field->type()));
         field->number(), WireFormat::WireTypeForFieldType(field->type()));
 
 
     printer->Print("case $tag$: {\n", "tag",
     printer->Print("case $tag$: {\n", "tag",
-                   SimpleItoa(static_cast<int32>(tag)));
+                   StrCat(static_cast<int32>(tag)));
     printer->Indent();
     printer->Indent();
 
 
     field_generators_.get(field).GenerateParsingCode(printer);
     field_generators_.get(field).GenerateParsingCode(printer);
@@ -1031,7 +1031,7 @@ void ImmutableMessageLiteGenerator::GenerateDynamicMethodMergeFromStream(
       uint32 packed_tag = WireFormatLite::MakeTag(
       uint32 packed_tag = WireFormatLite::MakeTag(
           field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
           field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
       printer->Print("case $tag$: {\n", "tag",
       printer->Print("case $tag$: {\n", "tag",
-                     SimpleItoa(static_cast<int32>(packed_tag)));
+                     StrCat(static_cast<int32>(packed_tag)));
       printer->Indent();
       printer->Indent();
 
 
       field_generators_.get(field).GenerateParsingCodeFromPacked(printer);
       field_generators_.get(field).GenerateParsingCodeFromPacked(printer);

+ 16 - 17
src/google/protobuf/compiler/java/java_primitive_field.cc

@@ -46,6 +46,7 @@
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -113,8 +114,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
   (*variables)["capitalized_type"] =
   (*variables)["capitalized_type"] =
       GetCapitalizedType(descriptor, /* immutable = */ true);
       GetCapitalizedType(descriptor, /* immutable = */ true);
   (*variables)["tag"] =
   (*variables)["tag"] =
-      SimpleItoa(static_cast<int32>(WireFormat::MakeTag(descriptor)));
-  (*variables)["tag_size"] = SimpleItoa(
+      StrCat(static_cast<int32>(WireFormat::MakeTag(descriptor)));
+  (*variables)["tag_size"] = StrCat(
       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
   if (IsReferenceType(GetJavaType(descriptor))) {
   if (IsReferenceType(GetJavaType(descriptor))) {
     (*variables)["null_check"] =
     (*variables)["null_check"] =
@@ -130,7 +131,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
       ? "@java.lang.Deprecated " : "";
       ? "@java.lang.Deprecated " : "";
   int fixed_size = FixedSize(GetType(descriptor));
   int fixed_size = FixedSize(GetType(descriptor));
   if (fixed_size != -1) {
   if (fixed_size != -1) {
-    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+    (*variables)["fixed_size"] = StrCat(fixed_size);
   }
   }
   (*variables)["on_changed"] = "onChanged();";
   (*variables)["on_changed"] = "onChanged();";
 
 
@@ -385,31 +386,29 @@ GenerateEqualsCode(io::Printer* printer) const {
     case JAVATYPE_LONG:
     case JAVATYPE_LONG:
     case JAVATYPE_BOOLEAN:
     case JAVATYPE_BOOLEAN:
       printer->Print(variables_,
       printer->Print(variables_,
-        "result = result && (get$capitalized_name$()\n"
-        "    == other.get$capitalized_name$());\n");
+        "if (get$capitalized_name$()\n"
+        "    != other.get$capitalized_name$()) return false;\n");
       break;
       break;
 
 
     case JAVATYPE_FLOAT:
     case JAVATYPE_FLOAT:
       printer->Print(variables_,
       printer->Print(variables_,
-        "result = result && (\n"
-        "    java.lang.Float.floatToIntBits(get$capitalized_name$())\n"
-        "    == java.lang.Float.floatToIntBits(\n"
-        "        other.get$capitalized_name$()));\n");
+        "if (java.lang.Float.floatToIntBits(get$capitalized_name$())\n"
+        "    != java.lang.Float.floatToIntBits(\n"
+        "        other.get$capitalized_name$())) return false;\n");
       break;
       break;
 
 
     case JAVATYPE_DOUBLE:
     case JAVATYPE_DOUBLE:
       printer->Print(variables_,
       printer->Print(variables_,
-        "result = result && (\n"
-        "    java.lang.Double.doubleToLongBits(get$capitalized_name$())\n"
-        "    == java.lang.Double.doubleToLongBits(\n"
-        "        other.get$capitalized_name$()));\n");
+        "if (java.lang.Double.doubleToLongBits(get$capitalized_name$())\n"
+        "    != java.lang.Double.doubleToLongBits(\n"
+        "        other.get$capitalized_name$())) return false;\n");
       break;
       break;
 
 
     case JAVATYPE_STRING:
     case JAVATYPE_STRING:
     case JAVATYPE_BYTES:
     case JAVATYPE_BYTES:
       printer->Print(variables_,
       printer->Print(variables_,
-        "result = result && get$capitalized_name$()\n"
-        "    .equals(other.get$capitalized_name$());\n");
+        "if (!get$capitalized_name$()\n"
+        "    .equals(other.get$capitalized_name$())) return false;\n");
       break;
       break;
 
 
     case JAVATYPE_ENUM:
     case JAVATYPE_ENUM:
@@ -926,8 +925,8 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
 void RepeatedImmutablePrimitiveFieldGenerator::
 void RepeatedImmutablePrimitiveFieldGenerator::
 GenerateEqualsCode(io::Printer* printer) const {
 GenerateEqualsCode(io::Printer* printer) const {
   printer->Print(variables_,
   printer->Print(variables_,
-    "result = result && get$capitalized_name$List()\n"
-    "    .equals(other.get$capitalized_name$List());\n");
+    "if (!get$capitalized_name$List()\n"
+    "    .equals(other.get$capitalized_name$List())) return false;\n");
 }
 }
 
 
 void RepeatedImmutablePrimitiveFieldGenerator::
 void RepeatedImmutablePrimitiveFieldGenerator::

+ 4 - 3
src/google/protobuf/compiler/java/java_primitive_field_lite.cc

@@ -46,6 +46,7 @@
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -71,8 +72,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
   (*variables)["capitalized_type"] =
   (*variables)["capitalized_type"] =
       GetCapitalizedType(descriptor, /* immutable = */ true);
       GetCapitalizedType(descriptor, /* immutable = */ true);
   (*variables)["tag"] =
   (*variables)["tag"] =
-      SimpleItoa(static_cast<int32>(WireFormat::MakeTag(descriptor)));
-  (*variables)["tag_size"] = SimpleItoa(
+      StrCat(static_cast<int32>(WireFormat::MakeTag(descriptor)));
+  (*variables)["tag_size"] = StrCat(
       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
   (*variables)["required"] = descriptor->is_required() ? "true" : "false";
   (*variables)["required"] = descriptor->is_required() ? "true" : "false";
 
 
@@ -131,7 +132,7 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
       ? "@java.lang.Deprecated " : "";
       ? "@java.lang.Deprecated " : "";
   int fixed_size = FixedSize(GetType(descriptor));
   int fixed_size = FixedSize(GetType(descriptor));
   if (fixed_size != -1) {
   if (fixed_size != -1) {
-    (*variables)["fixed_size"] = SimpleItoa(fixed_size);
+    (*variables)["fixed_size"] = StrCat(fixed_size);
   }
   }
 
 
   if (SupportFieldPresence(descriptor->file())) {
   if (SupportFieldPresence(descriptor->file())) {

+ 7 - 6
src/google/protobuf/compiler/java/java_service.cc

@@ -41,6 +41,7 @@
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -90,7 +91,7 @@ void ImmutableServiceGenerator::Generate(io::Printer* printer) {
       "  return $file$.getDescriptor().getServices().get($index$);\n"
       "  return $file$.getDescriptor().getServices().get($index$);\n"
       "}\n",
       "}\n",
       "file", name_resolver_->GetImmutableClassName(descriptor_->file()),
       "file", name_resolver_->GetImmutableClassName(descriptor_->file()),
-      "index", SimpleItoa(descriptor_->index()));
+      "index", StrCat(descriptor_->index()));
   GenerateGetDescriptorForType(printer);
   GenerateGetDescriptorForType(printer);
 
 
   // Generate more stuff.
   // Generate more stuff.
@@ -209,7 +210,7 @@ void ImmutableServiceGenerator::GenerateCallMethod(io::Printer* printer) {
   for (int i = 0; i < descriptor_->method_count(); i++) {
   for (int i = 0; i < descriptor_->method_count(); i++) {
     const MethodDescriptor* method = descriptor_->method(i);
     const MethodDescriptor* method = descriptor_->method(i);
     std::map<string, string> vars;
     std::map<string, string> vars;
-    vars["index"] = SimpleItoa(i);
+    vars["index"] = StrCat(i);
     vars["method"] = UnderscoresToCamelCase(method);
     vars["method"] = UnderscoresToCamelCase(method);
     vars["input"] = name_resolver_->GetImmutableClassName(
     vars["input"] = name_resolver_->GetImmutableClassName(
         method->input_type());
         method->input_type());
@@ -256,7 +257,7 @@ void ImmutableServiceGenerator::GenerateCallBlockingMethod(
   for (int i = 0; i < descriptor_->method_count(); i++) {
   for (int i = 0; i < descriptor_->method_count(); i++) {
     const MethodDescriptor* method = descriptor_->method(i);
     const MethodDescriptor* method = descriptor_->method(i);
     std::map<string, string> vars;
     std::map<string, string> vars;
-    vars["index"] = SimpleItoa(i);
+    vars["index"] = StrCat(i);
     vars["method"] = UnderscoresToCamelCase(method);
     vars["method"] = UnderscoresToCamelCase(method);
     vars["input"] = name_resolver_->GetImmutableClassName(
     vars["input"] = name_resolver_->GetImmutableClassName(
         method->input_type());
         method->input_type());
@@ -302,7 +303,7 @@ void ImmutableServiceGenerator::GenerateGetPrototype(RequestOrResponse which,
   for (int i = 0; i < descriptor_->method_count(); i++) {
   for (int i = 0; i < descriptor_->method_count(); i++) {
     const MethodDescriptor* method = descriptor_->method(i);
     const MethodDescriptor* method = descriptor_->method(i);
     std::map<string, string> vars;
     std::map<string, string> vars;
-    vars["index"] = SimpleItoa(i);
+    vars["index"] = StrCat(i);
     vars["type"] = name_resolver_->GetImmutableClassName(
     vars["type"] = name_resolver_->GetImmutableClassName(
       (which == REQUEST) ? method->input_type() : method->output_type());
       (which == REQUEST) ? method->input_type() : method->output_type());
     printer->Print(vars,
     printer->Print(vars,
@@ -354,7 +355,7 @@ void ImmutableServiceGenerator::GenerateStub(io::Printer* printer) {
     printer->Indent();
     printer->Indent();
 
 
     std::map<string, string> vars;
     std::map<string, string> vars;
-    vars["index"] = SimpleItoa(i);
+    vars["index"] = StrCat(i);
     vars["output"] = GetOutput(method);
     vars["output"] = GetOutput(method);
     printer->Print(vars,
     printer->Print(vars,
       "channel.callMethod(\n"
       "channel.callMethod(\n"
@@ -418,7 +419,7 @@ void ImmutableServiceGenerator::GenerateBlockingStub(io::Printer* printer) {
     printer->Indent();
     printer->Indent();
 
 
     std::map<string, string> vars;
     std::map<string, string> vars;
-    vars["index"] = SimpleItoa(i);
+    vars["index"] = StrCat(i);
     vars["output"] = GetOutput(method);
     vars["output"] = GetOutput(method);
     printer->Print(vars,
     printer->Print(vars,
       "return ($output$) channel.callBlockingMethod(\n"
       "return ($output$) channel.callBlockingMethod(\n"

+ 7 - 6
src/google/protobuf/compiler/java/java_string_field.cc

@@ -47,6 +47,7 @@
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -72,8 +73,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
       "= " + ImmutableDefaultValue(descriptor, name_resolver);
       "= " + ImmutableDefaultValue(descriptor, name_resolver);
   (*variables)["capitalized_type"] = "String";
   (*variables)["capitalized_type"] = "String";
   (*variables)["tag"] =
   (*variables)["tag"] =
-      SimpleItoa(static_cast<int32>(WireFormat::MakeTag(descriptor)));
-  (*variables)["tag_size"] = SimpleItoa(
+      StrCat(static_cast<int32>(WireFormat::MakeTag(descriptor)));
+  (*variables)["tag_size"] = StrCat(
       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
   (*variables)["null_check"] =
   (*variables)["null_check"] =
       "  if (value == null) {\n"
       "  if (value == null) {\n"
@@ -451,8 +452,8 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
 void ImmutableStringFieldGenerator::
 void ImmutableStringFieldGenerator::
 GenerateEqualsCode(io::Printer* printer) const {
 GenerateEqualsCode(io::Printer* printer) const {
   printer->Print(variables_,
   printer->Print(variables_,
-    "result = result && get$capitalized_name$()\n"
-    "    .equals(other.get$capitalized_name$());\n");
+    "if (!get$capitalized_name$()\n"
+    "    .equals(other.get$capitalized_name$())) return false;\n");
 }
 }
 
 
 void ImmutableStringFieldGenerator::
 void ImmutableStringFieldGenerator::
@@ -1016,8 +1017,8 @@ GenerateSerializedSizeCode(io::Printer* printer) const {
 void RepeatedImmutableStringFieldGenerator::
 void RepeatedImmutableStringFieldGenerator::
 GenerateEqualsCode(io::Printer* printer) const {
 GenerateEqualsCode(io::Printer* printer) const {
   printer->Print(variables_,
   printer->Print(variables_,
-    "result = result && get$capitalized_name$List()\n"
-    "    .equals(other.get$capitalized_name$List());\n");
+    "if (!get$capitalized_name$List()\n"
+    "    .equals(other.get$capitalized_name$List())) return false;\n");
 }
 }
 
 
 void RepeatedImmutableStringFieldGenerator::
 void RepeatedImmutableStringFieldGenerator::

+ 3 - 2
src/google/protobuf/compiler/java/java_string_field_lite.cc

@@ -47,6 +47,7 @@
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/wire_format.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -73,8 +74,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor,
       "= " + ImmutableDefaultValue(descriptor, name_resolver);
       "= " + ImmutableDefaultValue(descriptor, name_resolver);
   (*variables)["capitalized_type"] = "java.lang.String";
   (*variables)["capitalized_type"] = "java.lang.String";
   (*variables)["tag"] =
   (*variables)["tag"] =
-      SimpleItoa(static_cast<int32>(WireFormat::MakeTag(descriptor)));
-  (*variables)["tag_size"] = SimpleItoa(
+      StrCat(static_cast<int32>(WireFormat::MakeTag(descriptor)));
+  (*variables)["tag_size"] = StrCat(
       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
   (*variables)["null_check"] =
   (*variables)["null_check"] =
       "  if (value == null) {\n"
       "  if (value == null) {\n"

+ 33 - 26
src/google/protobuf/compiler/js/js_generator.cc

@@ -43,6 +43,7 @@
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/common.h>
 #include <google/protobuf/stubs/stringprintf.h>
 #include <google/protobuf/stubs/stringprintf.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
+
 #include <google/protobuf/compiler/scc.h>
 #include <google/protobuf/compiler/scc.h>
 #include <google/protobuf/compiler/js/well_known_types_embed.h>
 #include <google/protobuf/compiler/js/well_known_types_embed.h>
 #include <google/protobuf/io/printer.h>
 #include <google/protobuf/io/printer.h>
@@ -615,12 +616,11 @@ string JSFieldIndex(const FieldDescriptor* field) {
     for (int i = 0; i < parent_type->field_count(); i++) {
     for (int i = 0; i < parent_type->field_count(); i++) {
       if (parent_type->field(i)->type() == FieldDescriptor::TYPE_GROUP &&
       if (parent_type->field(i)->type() == FieldDescriptor::TYPE_GROUP &&
           parent_type->field(i)->message_type() == containing_type) {
           parent_type->field(i)->message_type() == containing_type) {
-        return SimpleItoa(field->number() -
-                                   parent_type->field(i)->number());
+        return StrCat(field->number() - parent_type->field(i)->number());
       }
       }
     }
     }
   }
   }
-  return SimpleItoa(field->number());
+  return StrCat(field->number());
 }
 }
 
 
 string JSOneofIndex(const OneofDescriptor* oneof) {
 string JSOneofIndex(const OneofDescriptor* oneof) {
@@ -639,7 +639,7 @@ string JSOneofIndex(const OneofDescriptor* oneof) {
       break;
       break;
     }
     }
   }
   }
-  return SimpleItoa(index);
+  return StrCat(index);
 }
 }
 
 
 // Decodes a codepoint in \x0000 -- \xFFFF.
 // Decodes a codepoint in \x0000 -- \xFFFF.
@@ -845,23 +845,25 @@ string JSFieldDefault(const FieldDescriptor* field) {
 
 
   switch (field->cpp_type()) {
   switch (field->cpp_type()) {
     case FieldDescriptor::CPPTYPE_INT32:
     case FieldDescriptor::CPPTYPE_INT32:
-      return MaybeNumberString(
-          field, SimpleItoa(field->default_value_int32()));
+      return MaybeNumberString(field,
+                               StrCat(field->default_value_int32()));
     case FieldDescriptor::CPPTYPE_UINT32:
     case FieldDescriptor::CPPTYPE_UINT32:
       // The original codegen is in Java, and Java protobufs store unsigned
       // The original codegen is in Java, and Java protobufs store unsigned
       // integer values as signed integer values. In order to exactly match the
       // integer values as signed integer values. In order to exactly match the
       // output, we need to reinterpret as base-2 signed. Ugh.
       // output, we need to reinterpret as base-2 signed. Ugh.
-      return MaybeNumberString(field, SimpleItoa(static_cast<int32>(
-                                          field->default_value_uint32())));
-    case FieldDescriptor::CPPTYPE_INT64:
       return MaybeNumberString(
       return MaybeNumberString(
-          field, SimpleItoa(field->default_value_int64()));
+          field,
+          StrCat(static_cast<int32>(field->default_value_uint32())));
+    case FieldDescriptor::CPPTYPE_INT64:
+      return MaybeNumberString(field,
+                               StrCat(field->default_value_int64()));
     case FieldDescriptor::CPPTYPE_UINT64:
     case FieldDescriptor::CPPTYPE_UINT64:
       // See above note for uint32 -- reinterpreting as signed.
       // See above note for uint32 -- reinterpreting as signed.
-      return MaybeNumberString(field, SimpleItoa(static_cast<int64>(
-                                          field->default_value_uint64())));
+      return MaybeNumberString(
+          field,
+          StrCat(static_cast<int64>(field->default_value_uint64())));
     case FieldDescriptor::CPPTYPE_ENUM:
     case FieldDescriptor::CPPTYPE_ENUM:
-      return SimpleItoa(field->default_value_enum()->number());
+      return StrCat(field->default_value_enum()->number());
     case FieldDescriptor::CPPTYPE_BOOL:
     case FieldDescriptor::CPPTYPE_BOOL:
       return field->default_value_bool() ? "true" : "false";
       return field->default_value_bool() ? "true" : "false";
     case FieldDescriptor::CPPTYPE_FLOAT:
     case FieldDescriptor::CPPTYPE_FLOAT:
@@ -1444,7 +1446,7 @@ string GetPivot(const Descriptor* desc) {
         (max_field_number + 1) : kDefaultPivot;
         (max_field_number + 1) : kDefaultPivot;
   }
   }
 
 
-  return SimpleItoa(pivot);
+  return StrCat(pivot);
 }
 }
 
 
 // Whether this field represents presence.  For fields with presence, we
 // Whether this field represents presence.  For fields with presence, we
@@ -2104,6 +2106,12 @@ void Generator::GenerateClassConstructor(const GeneratorOptions& options,
       "};\n"
       "};\n"
       "goog.inherits($classname$, jspb.Message);\n"
       "goog.inherits($classname$, jspb.Message);\n"
       "if (goog.DEBUG && !COMPILED) {\n"
       "if (goog.DEBUG && !COMPILED) {\n"
+      // displayName overrides Function.prototype.displayName
+      // http://google3/javascript/externs/es3.js?l=511
+      "  /**\n"
+      "   * @public\n"
+      "   * @override\n"
+      "   */\n"
       "  $classname$.displayName = '$classname$';\n"
       "  $classname$.displayName = '$classname$';\n"
       "}\n",
       "}\n",
       "classname", GetMessagePath(options, desc));
       "classname", GetMessagePath(options, desc));
@@ -3128,8 +3136,7 @@ void Generator::GenerateClassDeserializeBinaryField(
     const GeneratorOptions& options,
     const GeneratorOptions& options,
     io::Printer* printer,
     io::Printer* printer,
     const FieldDescriptor* field) const {
     const FieldDescriptor* field) const {
-  printer->Print("    case $num$:\n", "num",
-                 SimpleItoa(field->number()));
+  printer->Print("    case $num$:\n", "num", StrCat(field->number()));
 
 
   if (field->is_map()) {
   if (field->is_map()) {
     const FieldDescriptor* key_field = MapFieldKey(field);
     const FieldDescriptor* key_field = MapFieldKey(field);
@@ -3165,7 +3172,7 @@ void Generator::GenerateClassDeserializeBinaryField(
           (field->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message",
           (field->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message",
           "grpfield",
           "grpfield",
           (field->type() == FieldDescriptor::TYPE_GROUP)
           (field->type() == FieldDescriptor::TYPE_GROUP)
-              ? (SimpleItoa(field->number()) + ", ")
+              ? (StrCat(field->number()) + ", ")
               : "");
               : "");
     } else {
     } else {
       printer->Print(
       printer->Print(
@@ -3328,7 +3335,7 @@ void Generator::GenerateClassSerializeBinaryField(
     printer->Print(
     printer->Print(
         "    f.serializeBinary($index$, writer, "
         "    f.serializeBinary($index$, writer, "
         "$keyWriterFn$, $valueWriterFn$",
         "$keyWriterFn$, $valueWriterFn$",
-        "index", SimpleItoa(field->number()), "keyWriterFn",
+        "index", StrCat(field->number()), "keyWriterFn",
         JSBinaryWriterMethodName(options, key_field), "valueWriterFn",
         JSBinaryWriterMethodName(options, key_field), "valueWriterFn",
         JSBinaryWriterMethodName(options, value_field));
         JSBinaryWriterMethodName(options, value_field));
 
 
@@ -3344,7 +3351,7 @@ void Generator::GenerateClassSerializeBinaryField(
         "      $index$,\n"
         "      $index$,\n"
         "      f",
         "      f",
         "method", JSBinaryReadWriteMethodName(field, /* is_writer = */ true),
         "method", JSBinaryReadWriteMethodName(field, /* is_writer = */ true),
-        "index", SimpleItoa(field->number()));
+        "index", StrCat(field->number()));
 
 
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
     if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
         !field->is_map()) {
         !field->is_map()) {
@@ -3381,7 +3388,7 @@ void Generator::GenerateEnum(const GeneratorOptions& options,
     const EnumValueDescriptor* value = enumdesc->value(i);
     const EnumValueDescriptor* value = enumdesc->value(i);
     printer->Print("  $name$: $value$$comma$\n", "name",
     printer->Print("  $name$: $value$$comma$\n", "name",
                    ToEnumCase(value->name()), "value",
                    ToEnumCase(value->name()), "value",
-                   SimpleItoa(value->number()), "comma",
+                   StrCat(value->number()), "comma",
                    (i == enumdesc->value_count() - 1) ? "" : ",");
                    (i == enumdesc->value_count() - 1) ? "" : ",");
     printer->Annotate("name", value);
     printer->Annotate("name", value);
   }
   }
@@ -3425,8 +3432,8 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
       "!Object} */ (\n"
       "!Object} */ (\n"
       "         $toObject$),\n"
       "         $toObject$),\n"
       "    $repeated$);\n",
       "    $repeated$);\n",
-      "index", SimpleItoa(field->number()), "name",
-      extension_object_name, "ctor",
+      "index", StrCat(field->number()), "name", extension_object_name,
+      "ctor",
       (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
       (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
            ? SubmessageTypeRef(options, field)
            ? SubmessageTypeRef(options, field)
            : string("null")),
            : string("null")),
@@ -3446,8 +3453,8 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
       "    $binaryMessageDeserializeFn$,\n",
       "    $binaryMessageDeserializeFn$,\n",
       "extendName",
       "extendName",
       JSExtensionsObjectName(options, field->file(), field->containing_type()),
       JSExtensionsObjectName(options, field->file(), field->containing_type()),
-      "index", SimpleItoa(field->number()), "class", extension_scope,
-      "name", extension_object_name, "binaryReaderFn",
+      "index", StrCat(field->number()), "class", extension_scope, "name",
+      extension_object_name, "binaryReaderFn",
       JSBinaryReaderMethodName(options, field), "binaryWriterFn",
       JSBinaryReaderMethodName(options, field), "binaryWriterFn",
       JSBinaryWriterMethodName(options, field), "binaryMessageSerializeFn",
       JSBinaryWriterMethodName(options, field), "binaryMessageSerializeFn",
       (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
       (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE)
@@ -3468,8 +3475,8 @@ void Generator::GenerateExtension(const GeneratorOptions& options,
       "\n",
       "\n",
       "extendName",
       "extendName",
       JSExtensionsObjectName(options, field->file(), field->containing_type()),
       JSExtensionsObjectName(options, field->file(), field->containing_type()),
-      "index", SimpleItoa(field->number()), "class", extension_scope,
-      "name", extension_object_name);
+      "index", StrCat(field->number()), "class", extension_scope, "name",
+      extension_object_name);
 }
 }
 
 
 bool GeneratorOptions::ParseFromOptions(
 bool GeneratorOptions::ParseFromOptions(

+ 3 - 2
src/google/protobuf/compiler/parser.cc

@@ -38,6 +38,7 @@
 #include <limits>
 #include <limits>
 #include <unordered_map>
 #include <unordered_map>
 
 
+
 #include <google/protobuf/stubs/hash.h>
 #include <google/protobuf/stubs/hash.h>
 
 
 #include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/casts.h>
@@ -1154,7 +1155,7 @@ bool Parser::ParseDefaultAssignment(
       DO(ConsumeInteger64(max_value, &value,
       DO(ConsumeInteger64(max_value, &value,
                           "Expected integer for field default value."));
                           "Expected integer for field default value."));
       // And stringify it again.
       // And stringify it again.
-      default_value->append(SimpleItoa(value));
+      default_value->append(StrCat(value));
       break;
       break;
     }
     }
 
 
@@ -1177,7 +1178,7 @@ bool Parser::ParseDefaultAssignment(
       DO(ConsumeInteger64(max_value, &value,
       DO(ConsumeInteger64(max_value, &value,
                           "Expected integer for field default value."));
                           "Expected integer for field default value."));
       // And stringify it again.
       // And stringify it again.
-      default_value->append(SimpleItoa(value));
+      default_value->append(StrCat(value));
       break;
       break;
     }
     }
 
 

+ 49 - 69
src/google/protobuf/compiler/plugin.pb.cc

@@ -326,31 +326,22 @@ const char* Version::_InternalParse(const char* begin, const char* end, void* ob
       // optional int32 major = 1;
       // optional int32 major = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_major(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int32 value = val;
-        msg->set_major(value);
         break;
         break;
       }
       }
       // optional int32 minor = 2;
       // optional int32 minor = 2;
       case 2: {
       case 2: {
         if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_minor(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int32 value = val;
-        msg->set_minor(value);
         break;
         break;
       }
       }
       // optional int32 patch = 3;
       // optional int32 patch = 3;
       case 3: {
       case 3: {
         if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_patch(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int32 value = val;
-        msg->set_patch(value);
         break;
         break;
       }
       }
       // optional string suffix = 4;
       // optional string suffix = 4;
@@ -359,16 +350,13 @@ const char* Version::_InternalParse(const char* begin, const char* end, void* ob
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.Version.suffix");
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.Version.suffix");
-        auto str = msg->mutable_suffix();
+        object = msg->mutable_suffix();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -387,6 +375,10 @@ const char* Version::_InternalParse(const char* begin, const char* end, void* ob
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -809,16 +801,13 @@ const char* CodeGeneratorRequest::_InternalParse(const char* begin, const char*
           ptr = ::google::protobuf::io::ReadSize(ptr, &size);
           ptr = ::google::protobuf::io::ReadSize(ptr, &size);
           GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
           GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
           ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
           ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorRequest.file_to_generate");
-          auto str = msg->add_file_to_generate();
+          object = msg->add_file_to_generate();
           if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
           if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-            object = str;
-            str->clear();
-            str->reserve(size);
             parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
             parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
-            goto len_delim_till_end;
+            goto string_till_end;
           }
           }
           GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
           GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
-          ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+          ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
           ptr += size;
           ptr += size;
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
@@ -830,16 +819,13 @@ const char* CodeGeneratorRequest::_InternalParse(const char* begin, const char*
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorRequest.parameter");
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorRequest.parameter");
-        auto str = msg->mutable_parameter();
+        object = msg->mutable_parameter();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -851,11 +837,9 @@ const char* CodeGeneratorRequest::_InternalParse(const char* begin, const char*
         parser_till_end = ::google::protobuf::compiler::Version::_InternalParse;
         parser_till_end = ::google::protobuf::compiler::Version::_InternalParse;
         object = msg->mutable_compiler_version();
         object = msg->mutable_compiler_version();
         if (size > end - ptr) goto len_delim_till_end;
         if (size > end - ptr) goto len_delim_till_end;
-        auto newend = ptr + size;
-        bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                       ptr, newend);
-        GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-        ptr = newend;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
         break;
         break;
       }
       }
       // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
       // repeated .google.protobuf.FileDescriptorProto proto_file = 15;
@@ -867,11 +851,9 @@ const char* CodeGeneratorRequest::_InternalParse(const char* begin, const char*
           parser_till_end = ::google::protobuf::FileDescriptorProto::_InternalParse;
           parser_till_end = ::google::protobuf::FileDescriptorProto::_InternalParse;
           object = msg->add_proto_file();
           object = msg->add_proto_file();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 122 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 122 && (ptr += 1));
         break;
         break;
@@ -891,6 +873,10 @@ const char* CodeGeneratorRequest::_InternalParse(const char* begin, const char*
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -1327,16 +1313,13 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* begin, const
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.name");
-        auto str = msg->mutable_name();
+        object = msg->mutable_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -1346,16 +1329,13 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* begin, const
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.insertion_point");
-        auto str = msg->mutable_insertion_point();
+        object = msg->mutable_insertion_point();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -1365,16 +1345,13 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* begin, const
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.content");
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.File.content");
-        auto str = msg->mutable_content();
+        object = msg->mutable_content();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -1393,6 +1370,10 @@ const char* CodeGeneratorResponse_File::_InternalParse(const char* begin, const
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -1779,16 +1760,13 @@ const char* CodeGeneratorResponse::_InternalParse(const char* begin, const char*
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.error");
         ctx->extra_parse_data().SetFieldName("google.protobuf.compiler.CodeGeneratorResponse.error");
-        auto str = msg->mutable_error();
+        object = msg->mutable_error();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8Verify;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8Verify(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -1801,11 +1779,9 @@ const char* CodeGeneratorResponse::_InternalParse(const char* begin, const char*
           parser_till_end = ::google::protobuf::compiler::CodeGeneratorResponse_File::_InternalParse;
           parser_till_end = ::google::protobuf::compiler::CodeGeneratorResponse_File::_InternalParse;
           object = msg->add_file();
           object = msg->add_file();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 122 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 122 && (ptr += 1));
         break;
         break;
@@ -1825,6 +1801,10 @@ const char* CodeGeneratorResponse::_InternalParse(const char* begin, const char*
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);

+ 22 - 22
src/google/protobuf/compiler/python/python_generator.cc

@@ -65,6 +65,7 @@
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/substitute.h>
 
 
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace compiler {
 namespace compiler {
@@ -218,13 +219,13 @@ string StringifyDefaultValue(const FieldDescriptor& field) {
 
 
   switch (field.cpp_type()) {
   switch (field.cpp_type()) {
     case FieldDescriptor::CPPTYPE_INT32:
     case FieldDescriptor::CPPTYPE_INT32:
-      return SimpleItoa(field.default_value_int32());
+      return StrCat(field.default_value_int32());
     case FieldDescriptor::CPPTYPE_UINT32:
     case FieldDescriptor::CPPTYPE_UINT32:
-      return SimpleItoa(field.default_value_uint32());
+      return StrCat(field.default_value_uint32());
     case FieldDescriptor::CPPTYPE_INT64:
     case FieldDescriptor::CPPTYPE_INT64:
-      return SimpleItoa(field.default_value_int64());
+      return StrCat(field.default_value_int64());
     case FieldDescriptor::CPPTYPE_UINT64:
     case FieldDescriptor::CPPTYPE_UINT64:
-      return SimpleItoa(field.default_value_uint64());
+      return StrCat(field.default_value_uint64());
     case FieldDescriptor::CPPTYPE_DOUBLE: {
     case FieldDescriptor::CPPTYPE_DOUBLE: {
       double value = field.default_value_double();
       double value = field.default_value_double();
       if (value == std::numeric_limits<double>::infinity()) {
       if (value == std::numeric_limits<double>::infinity()) {
@@ -260,7 +261,7 @@ string StringifyDefaultValue(const FieldDescriptor& field) {
     case FieldDescriptor::CPPTYPE_BOOL:
     case FieldDescriptor::CPPTYPE_BOOL:
       return field.default_value_bool() ? "True" : "False";
       return field.default_value_bool() ? "True" : "False";
     case FieldDescriptor::CPPTYPE_ENUM:
     case FieldDescriptor::CPPTYPE_ENUM:
-      return SimpleItoa(field.default_value_enum()->number());
+      return StrCat(field.default_value_enum()->number());
     case FieldDescriptor::CPPTYPE_STRING:
     case FieldDescriptor::CPPTYPE_STRING:
 //##!PY25      return "b\"" + CEscape(field.default_value_string()) +
 //##!PY25      return "b\"" + CEscape(field.default_value_string()) +
 //##!PY25             (field.type() != FieldDescriptor::TYPE_STRING ? "\"" :
 //##!PY25             (field.type() != FieldDescriptor::TYPE_STRING ? "\"" :
@@ -495,7 +496,7 @@ void Generator::PrintTopLevelEnums() const {
   for (int i = 0; i < top_level_enum_values.size(); ++i) {
   for (int i = 0; i < top_level_enum_values.size(); ++i) {
     printer_->Print("$name$ = $value$\n", "name",
     printer_->Print("$name$ = $value$\n", "name",
                     top_level_enum_values[i].first, "value",
                     top_level_enum_values[i].first, "value",
-                    SimpleItoa(top_level_enum_values[i].second));
+                    StrCat(top_level_enum_values[i].second));
   }
   }
   printer_->Print("\n");
   printer_->Print("\n");
 }
 }
@@ -569,7 +570,7 @@ void Generator::PrintTopLevelExtensions() const {
     UpperString(&constant_name);
     UpperString(&constant_name);
     printer_->Print("$constant_name$ = $number$\n", "constant_name",
     printer_->Print("$constant_name$ = $number$\n", "constant_name",
                     constant_name, "number",
                     constant_name, "number",
-                    SimpleItoa(extension_field.number()));
+                    StrCat(extension_field.number()));
     printer_->Print("$name$ = ", "name", extension_field.name());
     printer_->Print("$name$ = ", "name", extension_field.name());
     PrintFieldDescriptor(extension_field, is_extension);
     PrintFieldDescriptor(extension_field, is_extension);
     printer_->Print("\n");
     printer_->Print("\n");
@@ -616,7 +617,7 @@ void Generator::PrintServiceDescriptor(
   m["name"] = descriptor.name();
   m["name"] = descriptor.name();
   m["full_name"] = descriptor.full_name();
   m["full_name"] = descriptor.full_name();
   m["file"] = kDescriptorKey;
   m["file"] = kDescriptorKey;
-  m["index"] = SimpleItoa(descriptor.index());
+  m["index"] = StrCat(descriptor.index());
   m["options_value"] = OptionsValue(options_string);
   m["options_value"] = OptionsValue(options_string);
   const char required_function_arguments[] =
   const char required_function_arguments[] =
       "name='$name$',\n"
       "name='$name$',\n"
@@ -637,7 +638,7 @@ void Generator::PrintServiceDescriptor(
     m.clear();
     m.clear();
     m["name"] = method->name();
     m["name"] = method->name();
     m["full_name"] = method->full_name();
     m["full_name"] = method->full_name();
-    m["index"] = SimpleItoa(method->index());
+    m["index"] = StrCat(method->index());
     m["serialized_options"] = CEscape(options_string);
     m["serialized_options"] = CEscape(options_string);
     m["input_type"] = ModuleLevelDescriptorName(*(method->input_type()));
     m["input_type"] = ModuleLevelDescriptorName(*(method->input_type()));
     m["output_type"] = ModuleLevelDescriptorName(*(method->output_type()));
     m["output_type"] = ModuleLevelDescriptorName(*(method->output_type()));
@@ -762,9 +763,8 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
   for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
   for (int i = 0; i < message_descriptor.extension_range_count(); ++i) {
     const Descriptor::ExtensionRange* range =
     const Descriptor::ExtensionRange* range =
         message_descriptor.extension_range(i);
         message_descriptor.extension_range(i);
-    printer_->Print("($start$, $end$), ", "start",
-                    SimpleItoa(range->start), "end",
-                    SimpleItoa(range->end));
+    printer_->Print("($start$, $end$), ", "start", StrCat(range->start),
+                    "end", StrCat(range->end));
   }
   }
   printer_->Print("],\n");
   printer_->Print("],\n");
   printer_->Print("oneofs=[\n");
   printer_->Print("oneofs=[\n");
@@ -774,7 +774,7 @@ void Generator::PrintDescriptor(const Descriptor& message_descriptor) const {
     std::map<string, string> m;
     std::map<string, string> m;
     m["name"] = desc->name();
     m["name"] = desc->name();
     m["full_name"] = desc->full_name();
     m["full_name"] = desc->full_name();
-    m["index"] = SimpleItoa(desc->index());
+    m["index"] = StrCat(desc->index());
     string options_string =
     string options_string =
         OptionsValue(desc->options().SerializeAsString());
         OptionsValue(desc->options().SerializeAsString());
     if (options_string == "None") {
     if (options_string == "None") {
@@ -1108,8 +1108,8 @@ void Generator::PrintEnumValueDescriptor(
   descriptor.options().SerializeToString(&options_string);
   descriptor.options().SerializeToString(&options_string);
   std::map<string, string> m;
   std::map<string, string> m;
   m["name"] = descriptor.name();
   m["name"] = descriptor.name();
-  m["index"] = SimpleItoa(descriptor.index());
-  m["number"] = SimpleItoa(descriptor.number());
+  m["index"] = StrCat(descriptor.index());
+  m["number"] = StrCat(descriptor.number());
   m["options"] = OptionsValue(options_string);
   m["options"] = OptionsValue(options_string);
   printer_->Print(
   printer_->Print(
       m,
       m,
@@ -1137,11 +1137,11 @@ void Generator::PrintFieldDescriptor(
   std::map<string, string> m;
   std::map<string, string> m;
   m["name"] = field.name();
   m["name"] = field.name();
   m["full_name"] = field.full_name();
   m["full_name"] = field.full_name();
-  m["index"] = SimpleItoa(field.index());
-  m["number"] = SimpleItoa(field.number());
-  m["type"] = SimpleItoa(field.type());
-  m["cpp_type"] = SimpleItoa(field.cpp_type());
-  m["label"] = SimpleItoa(field.label());
+  m["index"] = StrCat(field.index());
+  m["number"] = StrCat(field.number());
+  m["type"] = StrCat(field.type());
+  m["cpp_type"] = StrCat(field.cpp_type());
+  m["label"] = StrCat(field.label());
   m["has_default_value"] = field.has_default_value() ? "True" : "False";
   m["has_default_value"] = field.has_default_value() ? "True" : "False";
   m["default_value"] = StringifyDefaultValue(field);
   m["default_value"] = StringifyDefaultValue(field);
   m["is_extension"] = is_extension ? "True" : "False";
   m["is_extension"] = is_extension ? "True" : "False";
@@ -1281,8 +1281,8 @@ void Generator::PrintSerializedPbInterval(
   printer_->Print(
   printer_->Print(
       "serialized_start=$serialized_start$,\n"
       "serialized_start=$serialized_start$,\n"
       "serialized_end=$serialized_end$,\n",
       "serialized_end=$serialized_end$,\n",
-      "serialized_start", SimpleItoa(offset), "serialized_end",
-      SimpleItoa(offset + sp.size()));
+      "serialized_start", StrCat(offset), "serialized_end",
+      StrCat(offset + sp.size()));
 }
 }
 
 
 namespace {
 namespace {

+ 5 - 4
src/google/protobuf/descriptor.cc

@@ -63,6 +63,7 @@
 #include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/casts.h>
 
 
 
 
+
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/stl_util.h>
 #include <google/protobuf/stubs/stl_util.h>
 #include <google/protobuf/stubs/hash.h>
 #include <google/protobuf/stubs/hash.h>
@@ -1926,16 +1927,16 @@ string FieldDescriptor::DefaultValueAsString(bool quote_string_type) const {
   GOOGLE_CHECK(has_default_value()) << "No default value";
   GOOGLE_CHECK(has_default_value()) << "No default value";
   switch (cpp_type()) {
   switch (cpp_type()) {
     case CPPTYPE_INT32:
     case CPPTYPE_INT32:
-      return SimpleItoa(default_value_int32());
+      return StrCat(default_value_int32());
       break;
       break;
     case CPPTYPE_INT64:
     case CPPTYPE_INT64:
-      return SimpleItoa(default_value_int64());
+      return StrCat(default_value_int64());
       break;
       break;
     case CPPTYPE_UINT32:
     case CPPTYPE_UINT32:
-      return SimpleItoa(default_value_uint32());
+      return StrCat(default_value_uint32());
       break;
       break;
     case CPPTYPE_UINT64:
     case CPPTYPE_UINT64:
-      return SimpleItoa(default_value_uint64());
+      return StrCat(default_value_uint64());
       break;
       break;
     case CPPTYPE_FLOAT:
     case CPPTYPE_FLOAT:
       return SimpleFtoa(default_value_float());
       return SimpleFtoa(default_value_float());

+ 2 - 4
src/google/protobuf/descriptor.h

@@ -1135,10 +1135,8 @@ class PROTOBUF_EXPORT EnumValueDescriptor {
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor);
   GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(EnumValueDescriptor);
 };
 };
 
 
-// Describes an RPC service.  To get the ServiceDescriptor for a service,
-// call Service::GetDescriptor().  Generated service classes also have a
-// static method called descriptor() which returns the type's
-// ServiceDescriptor.  Use DescriptorPool to construct your own descriptors.
+// Describes an RPC service. Use DescriptorPool to construct your own
+// descriptors.
 class PROTOBUF_EXPORT ServiceDescriptor {
 class PROTOBUF_EXPORT ServiceDescriptor {
  public:
  public:
   typedef ServiceDescriptorProto Proto;
   typedef ServiceDescriptorProto Proto;

File diff suppressed because it is too large
+ 182 - 306
src/google/protobuf/descriptor.pb.cc


+ 2 - 8
src/google/protobuf/duration.pb.cc

@@ -188,21 +188,15 @@ const char* Duration::_InternalParse(const char* begin, const char* end, void* o
       // int64 seconds = 1;
       // int64 seconds = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_seconds(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int64 value = val;
-        msg->set_seconds(value);
         break;
         break;
       }
       }
       // int32 nanos = 2;
       // int32 nanos = 2;
       case 2: {
       case 2: {
         if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_nanos(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int32 value = val;
-        msg->set_nanos(value);
         break;
         break;
       }
       }
       default: {
       default: {

+ 7 - 6
src/google/protobuf/field_mask.pb.cc

@@ -186,16 +186,13 @@ const char* FieldMask::_InternalParse(const char* begin, const char* end, void*
           ptr = ::google::protobuf::io::ReadSize(ptr, &size);
           ptr = ::google::protobuf::io::ReadSize(ptr, &size);
           GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
           GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
           ctx->extra_parse_data().SetFieldName("google.protobuf.FieldMask.paths");
           ctx->extra_parse_data().SetFieldName("google.protobuf.FieldMask.paths");
-          auto str = msg->add_paths();
+          object = msg->add_paths();
           if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
           if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-            object = str;
-            str->clear();
-            str->reserve(size);
             parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
             parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-            goto len_delim_till_end;
+            goto string_till_end;
           }
           }
           GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
           GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-          ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+          ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
           ptr += size;
           ptr += size;
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
@@ -216,6 +213,10 @@ const char* FieldMask::_InternalParse(const char* begin, const char* end, void*
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);

+ 4 - 4
src/google/protobuf/generated_message_util.h

@@ -219,10 +219,10 @@ inline void OnShutdownDestroyString(const ::std::string* ptr) {
 }
 }
 
 
 #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
 #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
-
-inline void InlineGreedyStringParser(std::string* str, const char* begin, int size,
-                               ParseContext*) {
-  str->assign(begin, size);
+// To simplify generation of the parse loop code we take objects by void ptr.
+inline void InlineGreedyStringParser(void* str, const char* begin, int size,
+                                     ParseContext*) {
+  static_cast<std::string*>(str)->assign(begin, size);
 }
 }
 
 
 
 

+ 1 - 0
src/google/protobuf/io/coded_stream.h

@@ -183,6 +183,7 @@ const char* VarintParse(const char* p, T* out) {
     }
     }
     extra += 128ull << (i * 7);
     extra += 128ull << (i * 7);
   }
   }
+  *out = 0;
   return nullptr;
   return nullptr;
 }
 }
 
 

+ 2 - 0
src/google/protobuf/map.h

@@ -559,6 +559,7 @@ class Map {
 
 
     iterator find(const Key& k) { return iterator(FindHelper(k).first); }
     iterator find(const Key& k) { return iterator(FindHelper(k).first); }
     const_iterator find(const Key& k) const { return find(k, NULL); }
     const_iterator find(const Key& k) const { return find(k, NULL); }
+    bool contains(const Key& k) const { return find(k) != end(); }
 
 
     // In traditional C++ style, this performs "insert if not present."
     // In traditional C++ style, this performs "insert if not present."
     std::pair<iterator, bool> insert(const KeyValuePair& kv) {
     std::pair<iterator, bool> insert(const KeyValuePair& kv) {
@@ -1079,6 +1080,7 @@ class Map {
     return const_iterator(iterator(elements_->find(key)));
     return const_iterator(iterator(elements_->find(key)));
   }
   }
   iterator find(const key_type& key) { return iterator(elements_->find(key)); }
   iterator find(const key_type& key) { return iterator(elements_->find(key)); }
+  bool contains(const Key& key) const { return elements_->contains(key); }
   std::pair<const_iterator, const_iterator> equal_range(
   std::pair<const_iterator, const_iterator> equal_range(
       const key_type& key) const {
       const key_type& key) const {
     const_iterator it = find(key);
     const_iterator it = find(key);

+ 9 - 0
src/google/protobuf/map_test.cc

@@ -126,6 +126,7 @@ class MapImplTest : public ::testing::Test {
     // Test map size is correct.
     // Test map size is correct.
     EXPECT_EQ(value, map_[key]);
     EXPECT_EQ(value, map_[key]);
     EXPECT_EQ(1, map_.count(key));
     EXPECT_EQ(1, map_.count(key));
+    EXPECT_TRUE(map_.contains(key));
 
 
     // Check mutable at and find work correctly.
     // Check mutable at and find work correctly.
     EXPECT_EQ(value, map_.at(key));
     EXPECT_EQ(value, map_.at(key));
@@ -248,6 +249,14 @@ TEST_F(MapImplTest, CountNonExist) {
   EXPECT_EQ(0, map_.count(0));
   EXPECT_EQ(0, map_.count(0));
 }
 }
 
 
+TEST_F(MapImplTest, ContainNotExist) {
+  EXPECT_FALSE(map_.contains(0));
+}
+
+TEST_F(MapImplTest, ImmutableContainNotExist) {
+  EXPECT_FALSE(const_map_.contains(0));
+}
+
 TEST_F(MapImplTest, MutableFindNonExist) {
 TEST_F(MapImplTest, MutableFindNonExist) {
   EXPECT_TRUE(map_.end() == map_.find(0));
   EXPECT_TRUE(map_.end() == map_.find(0));
 }
 }

+ 3 - 1
src/google/protobuf/parse_context.h

@@ -137,7 +137,9 @@ struct ParseClosure {
   //   (end <= retval < end + kSlopBytes).
   //   (end <= retval < end + kSlopBytes).
   //   All tag/value pairs between in [begin, retval) are parsed and retval
   //   All tag/value pairs between in [begin, retval) are parsed and retval
   //   points to start of a tag.
   //   points to start of a tag.
-  const char* operator()(const char* ptr, const char* end, ParseContext* ctx) {
+  PROTOBUF_ALWAYS_INLINE  // Don't pay for extra stack frame in debug mode
+      const char*
+      operator()(const char* ptr, const char* end, ParseContext* ctx) {
     GOOGLE_DCHECK(ptr < end);
     GOOGLE_DCHECK(ptr < end);
     return func(ptr, end, object, ctx);
     return func(ptr, end, object, ctx);
   }
   }

+ 2 - 1
src/google/protobuf/reflection_ops.cc

@@ -45,6 +45,7 @@
 #include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/unknown_field_set.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 namespace google {
 namespace google {
 namespace protobuf {
 namespace protobuf {
 namespace internal {
 namespace internal {
@@ -288,7 +289,7 @@ static string SubMessagePrefix(const string& prefix,
   }
   }
   if (index != -1) {
   if (index != -1) {
     result.append("[");
     result.append("[");
-    result.append(SimpleItoa(index));
+    result.append(StrCat(index));
     result.append("]");
     result.append("]");
   }
   }
   result.append(".");
   result.append(".");

+ 5 - 4
src/google/protobuf/repeated_field_unittest.cc

@@ -49,6 +49,7 @@
 #include <gmock/gmock.h>
 #include <gmock/gmock.h>
 #include <google/protobuf/testing/googletest.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 #include <gtest/gtest.h>
+
 #include <google/protobuf/stubs/stl_util.h>
 #include <google/protobuf/stubs/stl_util.h>
 
 
 namespace google {
 namespace google {
@@ -1786,11 +1787,11 @@ TEST_F(RepeatedFieldInsertionIteratorsTest,
   TestAllTypes goldenproto;
   TestAllTypes goldenproto;
   for (int i = 0; i < 10; ++i) {
   for (int i = 0; i < 10; ++i) {
     string* new_data = new string;
     string* new_data = new string;
-    *new_data = "name-" + SimpleItoa(i);
+    *new_data = "name-" + StrCat(i);
     data.push_back(new_data);
     data.push_back(new_data);
 
 
     new_data = goldenproto.add_repeated_string();
     new_data = goldenproto.add_repeated_string();
-    *new_data = "name-" + SimpleItoa(i);
+    *new_data = "name-" + StrCat(i);
   }
   }
   TestAllTypes testproto;
   TestAllTypes testproto;
   std::copy(data.begin(), data.end(), AllocatedRepeatedPtrFieldBackInserter(
   std::copy(data.begin(), data.end(), AllocatedRepeatedPtrFieldBackInserter(
@@ -1823,11 +1824,11 @@ TEST_F(RepeatedFieldInsertionIteratorsTest,
   TestAllTypes goldenproto;
   TestAllTypes goldenproto;
   for (int i = 0; i < 10; ++i) {
   for (int i = 0; i < 10; ++i) {
     string* new_data = new string;
     string* new_data = new string;
-    *new_data = "name-" + SimpleItoa(i);
+    *new_data = "name-" + StrCat(i);
     data.push_back(new_data);
     data.push_back(new_data);
 
 
     new_data = goldenproto.add_repeated_string();
     new_data = goldenproto.add_repeated_string();
-    *new_data = "name-" + SimpleItoa(i);
+    *new_data = "name-" + StrCat(i);
   }
   }
   TestAllTypes testproto;
   TestAllTypes testproto;
   std::copy(data.begin(), data.end(),
   std::copy(data.begin(), data.end(),

+ 7 - 6
src/google/protobuf/source_context.pb.cc

@@ -176,16 +176,13 @@ const char* SourceContext::_InternalParse(const char* begin, const char* end, vo
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.SourceContext.file_name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.SourceContext.file_name");
-        auto str = msg->mutable_file_name();
+        object = msg->mutable_file_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -204,6 +201,10 @@ const char* SourceContext::_InternalParse(const char* begin, const char* end, vo
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);

+ 21 - 33
src/google/protobuf/struct.pb.cc

@@ -856,20 +856,16 @@ const char* Value::_InternalParse(const char* begin, const char* end, void* obje
       // .google.protobuf.NullValue null_value = 1;
       // .google.protobuf.NullValue null_value = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_null_value(static_cast<::google::protobuf::NullValue>(val));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::NullValue value = static_cast<::google::protobuf::NullValue>(val);
-        msg->set_null_value(value);
         break;
         break;
       }
       }
       // double number_value = 2;
       // double number_value = 2;
       case 2: {
       case 2: {
         if (static_cast<::google::protobuf::uint8>(tag) != 17) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 17) goto handle_unusual;
-        double val;
-        ::std::memcpy(&val, ptr, 8);
-        ptr += 8;
-        msg->set_number_value(val);
+        msg->set_number_value(::google::protobuf::io::UnalignedLoad<double>(ptr));
+        ptr += sizeof(double);
         break;
         break;
       }
       }
       // string string_value = 3;
       // string string_value = 3;
@@ -878,27 +874,21 @@ const char* Value::_InternalParse(const char* begin, const char* end, void* obje
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Value.string_value");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Value.string_value");
-        auto str = msg->mutable_string_value();
+        object = msg->mutable_string_value();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
       // bool bool_value = 4;
       // bool bool_value = 4;
       case 4: {
       case 4: {
         if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 32) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_bool_value(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        bool value = val;
-        msg->set_bool_value(value);
         break;
         break;
       }
       }
       // .google.protobuf.Struct struct_value = 5;
       // .google.protobuf.Struct struct_value = 5;
@@ -909,11 +899,9 @@ const char* Value::_InternalParse(const char* begin, const char* end, void* obje
         parser_till_end = ::google::protobuf::Struct::_InternalParse;
         parser_till_end = ::google::protobuf::Struct::_InternalParse;
         object = msg->mutable_struct_value();
         object = msg->mutable_struct_value();
         if (size > end - ptr) goto len_delim_till_end;
         if (size > end - ptr) goto len_delim_till_end;
-        auto newend = ptr + size;
-        bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                       ptr, newend);
-        GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-        ptr = newend;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
         break;
         break;
       }
       }
       // .google.protobuf.ListValue list_value = 6;
       // .google.protobuf.ListValue list_value = 6;
@@ -924,11 +912,9 @@ const char* Value::_InternalParse(const char* begin, const char* end, void* obje
         parser_till_end = ::google::protobuf::ListValue::_InternalParse;
         parser_till_end = ::google::protobuf::ListValue::_InternalParse;
         object = msg->mutable_list_value();
         object = msg->mutable_list_value();
         if (size > end - ptr) goto len_delim_till_end;
         if (size > end - ptr) goto len_delim_till_end;
-        auto newend = ptr + size;
-        bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                       ptr, newend);
-        GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-        ptr = newend;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
         break;
         break;
       }
       }
       default: {
       default: {
@@ -946,6 +932,10 @@ const char* Value::_InternalParse(const char* begin, const char* end, void* obje
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -1424,11 +1414,9 @@ const char* ListValue::_InternalParse(const char* begin, const char* end, void*
           parser_till_end = ::google::protobuf::Value::_InternalParse;
           parser_till_end = ::google::protobuf::Value::_InternalParse;
           object = msg->add_values();
           object = msg->add_values();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 10 && (ptr += 1));
         break;
         break;

+ 8 - 8
src/google/protobuf/text_format.cc

@@ -764,7 +764,7 @@ label_skip_parsing:
                    LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
                    LookingAtType(io::Tokenizer::TYPE_INTEGER)) {
           int64 int_value;
           int64 int_value;
           DO(ConsumeSignedInteger(&int_value, kint32max));
           DO(ConsumeSignedInteger(&int_value, kint32max));
-          value = SimpleItoa(int_value);  // for error reporting
+          value = StrCat(int_value);  // for error reporting
           enum_value = enum_type->FindValueByNumber(int_value);
           enum_value = enum_type->FindValueByNumber(int_value);
         } else {
         } else {
           ReportError("Expected integer or identifier, got: " +
           ReportError("Expected integer or identifier, got: " +
@@ -1575,19 +1575,19 @@ void TextFormat::FastFieldValuePrinter::PrintBool(
 }
 }
 void TextFormat::FastFieldValuePrinter::PrintInt32(
 void TextFormat::FastFieldValuePrinter::PrintInt32(
     int32 val, BaseTextGenerator* generator) const {
     int32 val, BaseTextGenerator* generator) const {
-  generator->PrintString(SimpleItoa(val));
+  generator->PrintString(StrCat(val));
 }
 }
 void TextFormat::FastFieldValuePrinter::PrintUInt32(
 void TextFormat::FastFieldValuePrinter::PrintUInt32(
     uint32 val, BaseTextGenerator* generator) const {
     uint32 val, BaseTextGenerator* generator) const {
-  generator->PrintString(SimpleItoa(val));
+  generator->PrintString(StrCat(val));
 }
 }
 void TextFormat::FastFieldValuePrinter::PrintInt64(
 void TextFormat::FastFieldValuePrinter::PrintInt64(
     int64 val, BaseTextGenerator* generator) const {
     int64 val, BaseTextGenerator* generator) const {
-  generator->PrintString(SimpleItoa(val));
+  generator->PrintString(StrCat(val));
 }
 }
 void TextFormat::FastFieldValuePrinter::PrintUInt64(
 void TextFormat::FastFieldValuePrinter::PrintUInt64(
     uint64 val, BaseTextGenerator* generator) const {
     uint64 val, BaseTextGenerator* generator) const {
-  generator->PrintString(SimpleItoa(val));
+  generator->PrintString(StrCat(val));
 }
 }
 void TextFormat::FastFieldValuePrinter::PrintFloat(
 void TextFormat::FastFieldValuePrinter::PrintFloat(
     float val, BaseTextGenerator* generator) const {
     float val, BaseTextGenerator* generator) const {
@@ -2251,7 +2251,7 @@ void TextFormat::Printer::PrintFieldName(const Message& message,
   // if use_field_number_ is true, prints field number instead
   // if use_field_number_ is true, prints field number instead
   // of field name.
   // of field name.
   if (use_field_number_) {
   if (use_field_number_) {
-    generator->PrintString(SimpleItoa(field->number()));
+    generator->PrintString(StrCat(field->number()));
     return;
     return;
   }
   }
 
 
@@ -2396,13 +2396,13 @@ void TextFormat::Printer::PrintUnknownFields(
     const UnknownFieldSet& unknown_fields, TextGenerator* generator) const {
     const UnknownFieldSet& unknown_fields, TextGenerator* generator) const {
   for (int i = 0; i < unknown_fields.field_count(); i++) {
   for (int i = 0; i < unknown_fields.field_count(); i++) {
     const UnknownField& field = unknown_fields.field(i);
     const UnknownField& field = unknown_fields.field(i);
-    string field_number = SimpleItoa(field.number());
+    string field_number = StrCat(field.number());
 
 
     switch (field.type()) {
     switch (field.type()) {
       case UnknownField::TYPE_VARINT:
       case UnknownField::TYPE_VARINT:
         generator->PrintString(field_number);
         generator->PrintString(field_number);
         generator->PrintLiteral(": ");
         generator->PrintLiteral(": ");
-        generator->PrintString(SimpleItoa(field.varint()));
+        generator->PrintString(StrCat(field.varint()));
         if (single_line_mode_) {
         if (single_line_mode_) {
           generator->PrintLiteral(" ");
           generator->PrintLiteral(" ");
         } else {
         } else {

+ 5 - 4
src/google/protobuf/text_format_unittest.cc

@@ -54,6 +54,7 @@
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/io/zero_copy_stream_impl.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/stubs/substitute.h>
 #include <google/protobuf/testing/googletest.h>
 #include <google/protobuf/testing/googletest.h>
 #include <gtest/gtest.h>
 #include <gtest/gtest.h>
@@ -1284,9 +1285,9 @@ class TextFormatParserTest : public testing::Test {
     parser.RecordErrorsTo(&error_collector);
     parser.RecordErrorsTo(&error_collector);
     EXPECT_EQ(expected_result, parser.ParseFromString(input, proto))
     EXPECT_EQ(expected_result, parser.ParseFromString(input, proto))
         << input << " -> " << proto->DebugString();
         << input << " -> " << proto->DebugString();
-    EXPECT_EQ(SimpleItoa(line) + ":" + SimpleItoa(col) +
-                  ": " + message + "\n",
-              error_collector.text_);
+    EXPECT_EQ(
+        StrCat(line) + ":" + StrCat(col) + ": " + message + "\n",
+        error_collector.text_);
   }
   }
 
 
   void ExpectSuccessAndTree(const string& input, Message* proto,
   void ExpectSuccessAndTree(const string& input, Message* proto,
@@ -1509,7 +1510,7 @@ TEST_F(TextFormatParserTest, ParseFieldValueFromString) {
   // enum
   // enum
   EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR");
   EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAR, "BAR");
   EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ,
   EXPECT_FIELD(nested_enum, unittest::TestAllTypes::BAZ,
-               SimpleItoa(unittest::TestAllTypes::BAZ));
+               StrCat(unittest::TestAllTypes::BAZ));
   EXPECT_INVALID(nested_enum, "FOOBAR");
   EXPECT_INVALID(nested_enum, "FOOBAR");
 
 
   // message
   // message

+ 2 - 8
src/google/protobuf/timestamp.pb.cc

@@ -188,21 +188,15 @@ const char* Timestamp::_InternalParse(const char* begin, const char* end, void*
       // int64 seconds = 1;
       // int64 seconds = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_seconds(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int64 value = val;
-        msg->set_seconds(value);
         break;
         break;
       }
       }
       // int32 nanos = 2;
       // int32 nanos = 2;
       case 2: {
       case 2: {
         if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_nanos(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int32 value = val;
-        msg->set_nanos(value);
         break;
         break;
       }
       }
       default: {
       default: {

+ 86 - 131
src/google/protobuf/type.pb.cc

@@ -518,16 +518,13 @@ const char* Type::_InternalParse(const char* begin, const char* end, void* objec
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Type.name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Type.name");
-        auto str = msg->mutable_name();
+        object = msg->mutable_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -540,11 +537,9 @@ const char* Type::_InternalParse(const char* begin, const char* end, void* objec
           parser_till_end = ::google::protobuf::Field::_InternalParse;
           parser_till_end = ::google::protobuf::Field::_InternalParse;
           object = msg->add_fields();
           object = msg->add_fields();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
         break;
         break;
@@ -556,16 +551,13 @@ const char* Type::_InternalParse(const char* begin, const char* end, void* objec
           ptr = ::google::protobuf::io::ReadSize(ptr, &size);
           ptr = ::google::protobuf::io::ReadSize(ptr, &size);
           GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
           GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
           ctx->extra_parse_data().SetFieldName("google.protobuf.Type.oneofs");
           ctx->extra_parse_data().SetFieldName("google.protobuf.Type.oneofs");
-          auto str = msg->add_oneofs();
+          object = msg->add_oneofs();
           if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
           if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-            object = str;
-            str->clear();
-            str->reserve(size);
             parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
             parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-            goto len_delim_till_end;
+            goto string_till_end;
           }
           }
           GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
           GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-          ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+          ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
           ptr += size;
           ptr += size;
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
@@ -580,11 +572,9 @@ const char* Type::_InternalParse(const char* begin, const char* end, void* objec
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           object = msg->add_options();
           object = msg->add_options();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 34 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 34 && (ptr += 1));
         break;
         break;
@@ -597,21 +587,17 @@ const char* Type::_InternalParse(const char* begin, const char* end, void* objec
         parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
         parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
         object = msg->mutable_source_context();
         object = msg->mutable_source_context();
         if (size > end - ptr) goto len_delim_till_end;
         if (size > end - ptr) goto len_delim_till_end;
-        auto newend = ptr + size;
-        bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                       ptr, newend);
-        GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-        ptr = newend;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
         break;
         break;
       }
       }
       // .google.protobuf.Syntax syntax = 6;
       // .google.protobuf.Syntax syntax = 6;
       case 6: {
       case 6: {
         if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 48) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_syntax(static_cast<::google::protobuf::Syntax>(val));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::Syntax value = static_cast<::google::protobuf::Syntax>(val);
-        msg->set_syntax(value);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -629,6 +615,10 @@ const char* Type::_InternalParse(const char* begin, const char* end, void* objec
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -1167,31 +1157,24 @@ const char* Field::_InternalParse(const char* begin, const char* end, void* obje
       // .google.protobuf.Field.Kind kind = 1;
       // .google.protobuf.Field.Kind kind = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_kind(static_cast<::google::protobuf::Field_Kind>(val));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::Field_Kind value = static_cast<::google::protobuf::Field_Kind>(val);
-        msg->set_kind(value);
         break;
         break;
       }
       }
       // .google.protobuf.Field.Cardinality cardinality = 2;
       // .google.protobuf.Field.Cardinality cardinality = 2;
       case 2: {
       case 2: {
         if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_cardinality(static_cast<::google::protobuf::Field_Cardinality>(val));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::Field_Cardinality value = static_cast<::google::protobuf::Field_Cardinality>(val);
-        msg->set_cardinality(value);
         break;
         break;
       }
       }
       // int32 number = 3;
       // int32 number = 3;
       case 3: {
       case 3: {
         if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 24) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_number(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int32 value = val;
-        msg->set_number(value);
         break;
         break;
       }
       }
       // string name = 4;
       // string name = 4;
@@ -1200,16 +1183,13 @@ const char* Field::_InternalParse(const char* begin, const char* end, void* obje
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Field.name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Field.name");
-        auto str = msg->mutable_name();
+        object = msg->mutable_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -1219,37 +1199,28 @@ const char* Field::_InternalParse(const char* begin, const char* end, void* obje
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Field.type_url");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Field.type_url");
-        auto str = msg->mutable_type_url();
+        object = msg->mutable_type_url();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
       // int32 oneof_index = 7;
       // int32 oneof_index = 7;
       case 7: {
       case 7: {
         if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 56) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_oneof_index(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int32 value = val;
-        msg->set_oneof_index(value);
         break;
         break;
       }
       }
       // bool packed = 8;
       // bool packed = 8;
       case 8: {
       case 8: {
         if (static_cast<::google::protobuf::uint8>(tag) != 64) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 64) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_packed(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        bool value = val;
-        msg->set_packed(value);
         break;
         break;
       }
       }
       // repeated .google.protobuf.Option options = 9;
       // repeated .google.protobuf.Option options = 9;
@@ -1261,11 +1232,9 @@ const char* Field::_InternalParse(const char* begin, const char* end, void* obje
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           object = msg->add_options();
           object = msg->add_options();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 74 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 74 && (ptr += 1));
         break;
         break;
@@ -1276,16 +1245,13 @@ const char* Field::_InternalParse(const char* begin, const char* end, void* obje
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Field.json_name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Field.json_name");
-        auto str = msg->mutable_json_name();
+        object = msg->mutable_json_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -1295,16 +1261,13 @@ const char* Field::_InternalParse(const char* begin, const char* end, void* obje
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Field.default_value");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Field.default_value");
-        auto str = msg->mutable_default_value();
+        object = msg->mutable_default_value();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -1323,6 +1286,10 @@ const char* Field::_InternalParse(const char* begin, const char* end, void* obje
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -2028,16 +1995,13 @@ const char* Enum::_InternalParse(const char* begin, const char* end, void* objec
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Enum.name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Enum.name");
-        auto str = msg->mutable_name();
+        object = msg->mutable_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -2050,11 +2014,9 @@ const char* Enum::_InternalParse(const char* begin, const char* end, void* objec
           parser_till_end = ::google::protobuf::EnumValue::_InternalParse;
           parser_till_end = ::google::protobuf::EnumValue::_InternalParse;
           object = msg->add_enumvalue();
           object = msg->add_enumvalue();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 18 && (ptr += 1));
         break;
         break;
@@ -2068,11 +2030,9 @@ const char* Enum::_InternalParse(const char* begin, const char* end, void* objec
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           object = msg->add_options();
           object = msg->add_options();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
         break;
         break;
@@ -2085,21 +2045,17 @@ const char* Enum::_InternalParse(const char* begin, const char* end, void* objec
         parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
         parser_till_end = ::google::protobuf::SourceContext::_InternalParse;
         object = msg->mutable_source_context();
         object = msg->mutable_source_context();
         if (size > end - ptr) goto len_delim_till_end;
         if (size > end - ptr) goto len_delim_till_end;
-        auto newend = ptr + size;
-        bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                       ptr, newend);
-        GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-        ptr = newend;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
         break;
         break;
       }
       }
       // .google.protobuf.Syntax syntax = 5;
       // .google.protobuf.Syntax syntax = 5;
       case 5: {
       case 5: {
         if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 40) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_syntax(static_cast<::google::protobuf::Syntax>(val));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::Syntax value = static_cast<::google::protobuf::Syntax>(val);
-        msg->set_syntax(value);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -2117,6 +2073,10 @@ const char* Enum::_InternalParse(const char* begin, const char* end, void* objec
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -2575,27 +2535,21 @@ const char* EnumValue::_InternalParse(const char* begin, const char* end, void*
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.EnumValue.name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.EnumValue.name");
-        auto str = msg->mutable_name();
+        object = msg->mutable_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
       // int32 number = 2;
       // int32 number = 2;
       case 2: {
       case 2: {
         if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_number(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int32 value = val;
-        msg->set_number(value);
         break;
         break;
       }
       }
       // repeated .google.protobuf.Option options = 3;
       // repeated .google.protobuf.Option options = 3;
@@ -2607,11 +2561,9 @@ const char* EnumValue::_InternalParse(const char* begin, const char* end, void*
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           parser_till_end = ::google::protobuf::Option::_InternalParse;
           object = msg->add_options();
           object = msg->add_options();
           if (size > end - ptr) goto len_delim_till_end;
           if (size > end - ptr) goto len_delim_till_end;
-          auto newend = ptr + size;
-          bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                         ptr, newend);
-          GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-          ptr = newend;
+          ptr += size;
+          GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+              {parser_till_end, object}, ptr - size, ptr));
           if (ptr >= end) break;
           if (ptr >= end) break;
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
         } while ((::google::protobuf::io::UnalignedLoad<::google::protobuf::uint64>(ptr) & 255) == 26 && (ptr += 1));
         break;
         break;
@@ -2631,6 +2583,10 @@ const char* EnumValue::_InternalParse(const char* begin, const char* end, void*
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -3041,16 +2997,13 @@ const char* Option::_InternalParse(const char* begin, const char* end, void* obj
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.Option.name");
         ctx->extra_parse_data().SetFieldName("google.protobuf.Option.name");
-        auto str = msg->mutable_name();
+        object = msg->mutable_name();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -3062,11 +3015,9 @@ const char* Option::_InternalParse(const char* begin, const char* end, void* obj
         parser_till_end = ::google::protobuf::Any::_InternalParse;
         parser_till_end = ::google::protobuf::Any::_InternalParse;
         object = msg->mutable_value();
         object = msg->mutable_value();
         if (size > end - ptr) goto len_delim_till_end;
         if (size > end - ptr) goto len_delim_till_end;
-        auto newend = ptr + size;
-        bool ok = ctx->ParseExactRange({parser_till_end, object},
-                                       ptr, newend);
-        GOOGLE_PROTOBUF_PARSER_ASSERT(ok);
-        ptr = newend;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
         break;
         break;
       }
       }
       default: {
       default: {
@@ -3084,6 +3035,10 @@ const char* Option::_InternalParse(const char* begin, const char* end, void* obj
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);

+ 5 - 4
src/google/protobuf/util/internal/datapiece.cc

@@ -34,6 +34,7 @@
 #include <google/protobuf/type.pb.h>
 #include <google/protobuf/type.pb.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/descriptor.h>
 #include <google/protobuf/util/internal/utility.h>
 #include <google/protobuf/util/internal/utility.h>
+
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/mathlimits.h>
 #include <google/protobuf/stubs/mathlimits.h>
 #include <google/protobuf/stubs/mathutil.h>
 #include <google/protobuf/stubs/mathutil.h>
@@ -231,13 +232,13 @@ string DataPiece::ValueAsStringOrDefault(
     StringPiece default_string) const {
     StringPiece default_string) const {
   switch (type_) {
   switch (type_) {
     case TYPE_INT32:
     case TYPE_INT32:
-      return SimpleItoa(i32_);
+      return StrCat(i32_);
     case TYPE_INT64:
     case TYPE_INT64:
-      return SimpleItoa(i64_);
+      return StrCat(i64_);
     case TYPE_UINT32:
     case TYPE_UINT32:
-      return SimpleItoa(u32_);
+      return StrCat(u32_);
     case TYPE_UINT64:
     case TYPE_UINT64:
-      return SimpleItoa(u64_);
+      return StrCat(u64_);
     case TYPE_DOUBLE:
     case TYPE_DOUBLE:
       return DoubleAsString(double_);
       return DoubleAsString(double_);
     case TYPE_FLOAT:
     case TYPE_FLOAT:

+ 5 - 4
src/google/protobuf/util/internal/json_objectwriter.cc

@@ -36,6 +36,7 @@
 #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/util/internal/utility.h>
 #include <google/protobuf/util/internal/utility.h>
+
 #include <google/protobuf/util/internal/json_escaping.h>
 #include <google/protobuf/util/internal/json_escaping.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/mathlimits.h>
 #include <google/protobuf/stubs/mathlimits.h>
@@ -89,19 +90,19 @@ JsonObjectWriter* JsonObjectWriter::RenderBool(StringPiece name,
 
 
 JsonObjectWriter* JsonObjectWriter::RenderInt32(StringPiece name,
 JsonObjectWriter* JsonObjectWriter::RenderInt32(StringPiece name,
                                                 int32 value) {
                                                 int32 value) {
-  return RenderSimple(name, SimpleItoa(value));
+  return RenderSimple(name, StrCat(value));
 }
 }
 
 
 JsonObjectWriter* JsonObjectWriter::RenderUint32(StringPiece name,
 JsonObjectWriter* JsonObjectWriter::RenderUint32(StringPiece name,
                                                  uint32 value) {
                                                  uint32 value) {
-  return RenderSimple(name, SimpleItoa(value));
+  return RenderSimple(name, StrCat(value));
 }
 }
 
 
 JsonObjectWriter* JsonObjectWriter::RenderInt64(StringPiece name,
 JsonObjectWriter* JsonObjectWriter::RenderInt64(StringPiece name,
                                                 int64 value) {
                                                 int64 value) {
   WritePrefix(name);
   WritePrefix(name);
   WriteChar('"');
   WriteChar('"');
-  stream_->WriteString(SimpleItoa(value));
+  stream_->WriteString(StrCat(value));
   WriteChar('"');
   WriteChar('"');
   return this;
   return this;
 }
 }
@@ -110,7 +111,7 @@ JsonObjectWriter* JsonObjectWriter::RenderUint64(StringPiece name,
                                                  uint64 value) {
                                                  uint64 value) {
   WritePrefix(name);
   WritePrefix(name);
   WriteChar('"');
   WriteChar('"');
-  stream_->WriteString(SimpleItoa(value));
+  stream_->WriteString(StrCat(value));
   WriteChar('"');
   WriteChar('"');
   return this;
   return this;
 }
 }

+ 11 - 10
src/google/protobuf/util/internal/protostream_objectsource.cc

@@ -49,6 +49,7 @@
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/casts.h>
 #include <google/protobuf/stubs/casts.h>
 
 
+
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/status_macros.h>
 #include <google/protobuf/stubs/status_macros.h>
 
 
@@ -943,61 +944,61 @@ const string ProtoStreamObjectSource::ReadFieldValueAsString(
     case google::protobuf::Field_Kind_TYPE_INT32: {
     case google::protobuf::Field_Kind_TYPE_INT32: {
       uint32 buffer32;
       uint32 buffer32;
       stream_->ReadVarint32(&buffer32);
       stream_->ReadVarint32(&buffer32);
-      result = SimpleItoa(::google::protobuf::bit_cast<int32>(buffer32));
+      result = StrCat(::google::protobuf::bit_cast<int32>(buffer32));
       break;
       break;
     }
     }
     case google::protobuf::Field_Kind_TYPE_INT64: {
     case google::protobuf::Field_Kind_TYPE_INT64: {
       uint64 buffer64;
       uint64 buffer64;
       stream_->ReadVarint64(&buffer64);
       stream_->ReadVarint64(&buffer64);
-      result = SimpleItoa(::google::protobuf::bit_cast<int64>(buffer64));
+      result = StrCat(::google::protobuf::bit_cast<int64>(buffer64));
       break;
       break;
     }
     }
     case google::protobuf::Field_Kind_TYPE_UINT32: {
     case google::protobuf::Field_Kind_TYPE_UINT32: {
       uint32 buffer32;
       uint32 buffer32;
       stream_->ReadVarint32(&buffer32);
       stream_->ReadVarint32(&buffer32);
-      result = SimpleItoa(::google::protobuf::bit_cast<uint32>(buffer32));
+      result = StrCat(::google::protobuf::bit_cast<uint32>(buffer32));
       break;
       break;
     }
     }
     case google::protobuf::Field_Kind_TYPE_UINT64: {
     case google::protobuf::Field_Kind_TYPE_UINT64: {
       uint64 buffer64;
       uint64 buffer64;
       stream_->ReadVarint64(&buffer64);
       stream_->ReadVarint64(&buffer64);
-      result = SimpleItoa(::google::protobuf::bit_cast<uint64>(buffer64));
+      result = StrCat(::google::protobuf::bit_cast<uint64>(buffer64));
       break;
       break;
     }
     }
     case google::protobuf::Field_Kind_TYPE_SINT32: {
     case google::protobuf::Field_Kind_TYPE_SINT32: {
       uint32 buffer32;
       uint32 buffer32;
       stream_->ReadVarint32(&buffer32);
       stream_->ReadVarint32(&buffer32);
-      result = SimpleItoa(WireFormatLite::ZigZagDecode32(buffer32));
+      result = StrCat(WireFormatLite::ZigZagDecode32(buffer32));
       break;
       break;
     }
     }
     case google::protobuf::Field_Kind_TYPE_SINT64: {
     case google::protobuf::Field_Kind_TYPE_SINT64: {
       uint64 buffer64;
       uint64 buffer64;
       stream_->ReadVarint64(&buffer64);
       stream_->ReadVarint64(&buffer64);
-      result = SimpleItoa(WireFormatLite::ZigZagDecode64(buffer64));
+      result = StrCat(WireFormatLite::ZigZagDecode64(buffer64));
       break;
       break;
     }
     }
     case google::protobuf::Field_Kind_TYPE_SFIXED32: {
     case google::protobuf::Field_Kind_TYPE_SFIXED32: {
       uint32 buffer32;
       uint32 buffer32;
       stream_->ReadLittleEndian32(&buffer32);
       stream_->ReadLittleEndian32(&buffer32);
-      result = SimpleItoa(::google::protobuf::bit_cast<int32>(buffer32));
+      result = StrCat(::google::protobuf::bit_cast<int32>(buffer32));
       break;
       break;
     }
     }
     case google::protobuf::Field_Kind_TYPE_SFIXED64: {
     case google::protobuf::Field_Kind_TYPE_SFIXED64: {
       uint64 buffer64;
       uint64 buffer64;
       stream_->ReadLittleEndian64(&buffer64);
       stream_->ReadLittleEndian64(&buffer64);
-      result = SimpleItoa(::google::protobuf::bit_cast<int64>(buffer64));
+      result = StrCat(::google::protobuf::bit_cast<int64>(buffer64));
       break;
       break;
     }
     }
     case google::protobuf::Field_Kind_TYPE_FIXED32: {
     case google::protobuf::Field_Kind_TYPE_FIXED32: {
       uint32 buffer32;
       uint32 buffer32;
       stream_->ReadLittleEndian32(&buffer32);
       stream_->ReadLittleEndian32(&buffer32);
-      result = SimpleItoa(::google::protobuf::bit_cast<uint32>(buffer32));
+      result = StrCat(::google::protobuf::bit_cast<uint32>(buffer32));
       break;
       break;
     }
     }
     case google::protobuf::Field_Kind_TYPE_FIXED64: {
     case google::protobuf::Field_Kind_TYPE_FIXED64: {
       uint64 buffer64;
       uint64 buffer64;
       stream_->ReadLittleEndian64(&buffer64);
       stream_->ReadLittleEndian64(&buffer64);
-      result = SimpleItoa(::google::protobuf::bit_cast<uint64>(buffer64));
+      result = StrCat(::google::protobuf::bit_cast<uint64>(buffer64));
       break;
       break;
     }
     }
     case google::protobuf::Field_Kind_TYPE_FLOAT: {
     case google::protobuf::Field_Kind_TYPE_FLOAT: {

+ 3 - 2
src/google/protobuf/util/internal/protostream_objectwriter.cc

@@ -44,6 +44,7 @@
 #include <google/protobuf/util/internal/utility.h>
 #include <google/protobuf/util/internal/utility.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
 
 
+
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/map_util.h>
 #include <google/protobuf/stubs/statusor.h>
 #include <google/protobuf/stubs/statusor.h>
 
 
@@ -887,7 +888,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow,
         if (int_value.ok()) {
         if (int_value.ok()) {
           ow->ProtoWriter::RenderDataPiece(
           ow->ProtoWriter::RenderDataPiece(
               "string_value",
               "string_value",
-              DataPiece(SimpleItoa(int_value.ValueOrDie()), true));
+              DataPiece(StrCat(int_value.ValueOrDie()), true));
           return Status();
           return Status();
         }
         }
       }
       }
@@ -902,7 +903,7 @@ Status ProtoStreamObjectWriter::RenderStructValue(ProtoStreamObjectWriter* ow,
         if (int_value.ok()) {
         if (int_value.ok()) {
           ow->ProtoWriter::RenderDataPiece(
           ow->ProtoWriter::RenderDataPiece(
               "string_value",
               "string_value",
-              DataPiece(SimpleItoa(int_value.ValueOrDie()), true));
+              DataPiece(StrCat(int_value.ValueOrDie()), true));
           return Status();
           return Status();
         }
         }
       }
       }

+ 3 - 2
src/google/protobuf/util/internal/utility.h

@@ -39,8 +39,9 @@
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/stubs/logging.h>
 #include <google/protobuf/type.pb.h>
 #include <google/protobuf/type.pb.h>
 #include <google/protobuf/repeated_field.h>
 #include <google/protobuf/repeated_field.h>
-#include <google/protobuf/stubs/stringpiece.h>
 #include <google/protobuf/stubs/strutil.h>
 #include <google/protobuf/stubs/strutil.h>
+#include <google/protobuf/stubs/stringpiece.h>
+
 #include <google/protobuf/stubs/status.h>
 #include <google/protobuf/stubs/status.h>
 #include <google/protobuf/stubs/statusor.h>
 #include <google/protobuf/stubs/statusor.h>
 
 
@@ -187,7 +188,7 @@ PROTOBUF_EXPORT std::string FloatAsString(float value);
 // Convert from int32, int64, uint32, uint64, double or float to string.
 // Convert from int32, int64, uint32, uint64, double or float to string.
 template <typename T>
 template <typename T>
 std::string ValueAsString(T value) {
 std::string ValueAsString(T value) {
-  return SimpleItoa(value);
+  return StrCat(value);
 }
 }
 
 
 template <>
 template <>

+ 4 - 6
src/google/protobuf/util/message_differencer.cc

@@ -1761,16 +1761,14 @@ void MessageDifferencer::StreamReporter::PrintPath(
         continue;
         continue;
       }
       }
     } else {
     } else {
-      printer_->PrintRaw(
-          SimpleItoa(specific_field.unknown_field_number));
+      printer_->PrintRaw(StrCat(specific_field.unknown_field_number));
     }
     }
     if (left_side && specific_field.index >= 0) {
     if (left_side && specific_field.index >= 0) {
-      printer_->Print("[$name$]", "name",
-                      SimpleItoa(specific_field.index));
+      printer_->Print("[$name$]", "name", StrCat(specific_field.index));
     }
     }
     if (!left_side && specific_field.new_index >= 0) {
     if (!left_side && specific_field.new_index >= 0) {
       printer_->Print("[$name$]", "name",
       printer_->Print("[$name$]", "name",
-                      SimpleItoa(specific_field.new_index));
+                      StrCat(specific_field.new_index));
     }
     }
   }
   }
 }
 }
@@ -1825,7 +1823,7 @@ StreamReporter::PrintUnknownFieldValue(const UnknownField* unknown_field) {
   string output;
   string output;
   switch (unknown_field->type()) {
   switch (unknown_field->type()) {
     case UnknownField::TYPE_VARINT:
     case UnknownField::TYPE_VARINT:
-      output = SimpleItoa(unknown_field->varint());
+      output = StrCat(unknown_field->varint());
       break;
       break;
     case UnknownField::TYPE_FIXED32:
     case UnknownField::TYPE_FIXED32:
       output = StrCat(
       output = StrCat(

+ 2 - 1
src/google/protobuf/util/time_util.cc

@@ -38,6 +38,7 @@
 #include <google/protobuf/timestamp.pb.h>
 #include <google/protobuf/timestamp.pb.h>
 
 
 
 
+
 #include <google/protobuf/port_def.inc>
 #include <google/protobuf/port_def.inc>
 
 
 namespace google {
 namespace google {
@@ -184,7 +185,7 @@ string TimeUtil::ToString(const Duration& duration) {
     seconds = -seconds;
     seconds = -seconds;
     nanos = -nanos;
     nanos = -nanos;
   }
   }
-  result += SimpleItoa(seconds);
+  result += StrCat(seconds);
   if (nanos != 0) {
   if (nanos != 0) {
     result += "." + FormatNanos(nanos);
     result += "." + FormatNanos(nanos);
   }
   }

+ 4 - 4
src/google/protobuf/util/type_resolver_util.cc

@@ -315,16 +315,16 @@ class DescriptorPoolTypeResolver : public TypeResolver {
   string DefaultValueAsString(const FieldDescriptor* descriptor) {
   string DefaultValueAsString(const FieldDescriptor* descriptor) {
     switch (descriptor->cpp_type()) {
     switch (descriptor->cpp_type()) {
       case FieldDescriptor::CPPTYPE_INT32:
       case FieldDescriptor::CPPTYPE_INT32:
-        return SimpleItoa(descriptor->default_value_int32());
+        return StrCat(descriptor->default_value_int32());
         break;
         break;
       case FieldDescriptor::CPPTYPE_INT64:
       case FieldDescriptor::CPPTYPE_INT64:
-        return SimpleItoa(descriptor->default_value_int64());
+        return StrCat(descriptor->default_value_int64());
         break;
         break;
       case FieldDescriptor::CPPTYPE_UINT32:
       case FieldDescriptor::CPPTYPE_UINT32:
-        return SimpleItoa(descriptor->default_value_uint32());
+        return StrCat(descriptor->default_value_uint32());
         break;
         break;
       case FieldDescriptor::CPPTYPE_UINT64:
       case FieldDescriptor::CPPTYPE_UINT64:
-        return SimpleItoa(descriptor->default_value_uint64());
+        return StrCat(descriptor->default_value_uint64());
         break;
         break;
       case FieldDescriptor::CPPTYPE_FLOAT:
       case FieldDescriptor::CPPTYPE_FLOAT:
         return SimpleFtoa(descriptor->default_value_float());
         return SimpleFtoa(descriptor->default_value_float());

+ 23 - 0
src/google/protobuf/wire_format_lite.h

@@ -912,6 +912,29 @@ inline size_t ComputeUnknownMessageSetItemsSize(const std::string& unknown_field
   return unknown_fields.size();
   return unknown_fields.size();
 }
 }
 
 
+// Some convenience functions to simplify the generated parse loop code.
+// Returning the value and updating the buffer pointer allows for nicer
+// function composition. We rely on the compiler to inline this.
+// Also in debug compiles having local scoped variables tend to generated
+// stack frames that scale as O(num fields).
+inline uint64 ReadVarint(const char** p) {
+  uint64 tmp;
+  *p = io::Parse64(*p, &tmp);
+  return tmp;
+}
+
+inline int64 ReadVarintZigZag64(const char** p) {
+  uint64 tmp;
+  *p = io::Parse64(*p, &tmp);
+  return WireFormatLite::ZigZagDecode64(tmp);
+}
+
+inline int32 ReadVarintZigZag32(const char** p) {
+  uint64 tmp;
+  *p = io::Parse64(*p, &tmp);
+  return WireFormatLite::ZigZagDecode32(tmp);
+}
+
 }  // namespace internal
 }  // namespace internal
 }  // namespace protobuf
 }  // namespace protobuf
 }  // namespace google
 }  // namespace google

+ 23 - 40
src/google/protobuf/wrappers.pb.cc

@@ -402,10 +402,8 @@ const char* DoubleValue::_InternalParse(const char* begin, const char* end, void
       // double value = 1;
       // double value = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 9) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 9) goto handle_unusual;
-        double val;
-        ::std::memcpy(&val, ptr, 8);
-        ptr += 8;
-        msg->set_value(val);
+        msg->set_value(::google::protobuf::io::UnalignedLoad<double>(ptr));
+        ptr += sizeof(double);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -691,10 +689,8 @@ const char* FloatValue::_InternalParse(const char* begin, const char* end, void*
       // float value = 1;
       // float value = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 13) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 13) goto handle_unusual;
-        float val;
-        std::memcpy(&val, ptr, 4);
-        ptr += 4;
-        msg->set_value(val);
+        msg->set_value(::google::protobuf::io::UnalignedLoad<float>(ptr));
+        ptr += sizeof(float);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -980,11 +976,8 @@ const char* Int64Value::_InternalParse(const char* begin, const char* end, void*
       // int64 value = 1;
       // int64 value = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int64 value = val;
-        msg->set_value(value);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -1272,11 +1265,8 @@ const char* UInt64Value::_InternalParse(const char* begin, const char* end, void
       // uint64 value = 1;
       // uint64 value = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::uint64 value = val;
-        msg->set_value(value);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -1564,11 +1554,8 @@ const char* Int32Value::_InternalParse(const char* begin, const char* end, void*
       // int32 value = 1;
       // int32 value = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::int32 value = val;
-        msg->set_value(value);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -1856,11 +1843,8 @@ const char* UInt32Value::_InternalParse(const char* begin, const char* end, void
       // uint32 value = 1;
       // uint32 value = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        ::google::protobuf::uint32 value = val;
-        msg->set_value(value);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -2148,11 +2132,8 @@ const char* BoolValue::_InternalParse(const char* begin, const char* end, void*
       // bool value = 1;
       // bool value = 1;
       case 1: {
       case 1: {
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
-        ::google::protobuf::uint64 val;
-        ptr = ::google::protobuf::io::Parse64(ptr, &val);
+        msg->set_value(::google::protobuf::internal::ReadVarint(&ptr));
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        bool value = val;
-        msg->set_value(value);
         break;
         break;
       }
       }
       default: {
       default: {
@@ -2448,16 +2429,13 @@ const char* StringValue::_InternalParse(const char* begin, const char* end, void
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         ctx->extra_parse_data().SetFieldName("google.protobuf.StringValue.value");
         ctx->extra_parse_data().SetFieldName("google.protobuf.StringValue.value");
-        auto str = msg->mutable_value();
+        object = msg->mutable_value();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
           parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -2476,6 +2454,10 @@ const char* StringValue::_InternalParse(const char* begin, const char* end, void
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);
@@ -2772,16 +2754,13 @@ const char* BytesValue::_InternalParse(const char* begin, const char* end, void*
         if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
         if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         ptr = ::google::protobuf::io::ReadSize(ptr, &size);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
-        auto str = msg->mutable_value();
+        object = msg->mutable_value();
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
         if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
-          object = str;
-          str->clear();
-          str->reserve(size);
           parser_till_end = ::google::protobuf::internal::GreedyStringParser;
           parser_till_end = ::google::protobuf::internal::GreedyStringParser;
-          goto len_delim_till_end;
+          goto string_till_end;
         }
         }
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheck(ptr, size, ctx));
         GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheck(ptr, size, ctx));
-        ::google::protobuf::internal::InlineGreedyStringParser(str, ptr, size, ctx);
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
         ptr += size;
         ptr += size;
         break;
         break;
       }
       }
@@ -2800,6 +2779,10 @@ const char* BytesValue::_InternalParse(const char* begin, const char* end, void*
     }  // switch
     }  // switch
   }  // while
   }  // while
   return ptr;
   return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
 len_delim_till_end:
 len_delim_till_end:
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
   return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
                                {parser_till_end, object}, size);
                                {parser_till_end, object}, size);

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