diff --git a/.gitignore b/.gitignore index 1040236af1..4fe3edde37 100644 --- a/.gitignore +++ b/.gitignore @@ -222,3 +222,7 @@ _build/ # BenchmarkDotNet BenchmarkDotNet.Artifacts/ + +# Clangd uses these common ephemeral files +.cache +compile_commands.json diff --git a/CHANGES.txt b/CHANGES.txt index 13d5cbb851..d443caf3df 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -49,6 +49,7 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) * Adds client_streaming and server_streaming fields to MethodDescriptor. * Add "ensure_ascii" parameter to json_format.MessageToJson. This allows smaller JSON serializations with UTF-8 or other non-ASCII encodings. + * Added experimental support for directly assigning numpy scalars and array. Compiler * Migrate IsDefault(const std::string*) and UnsafeSetDefault(const std::string*) @@ -88,6 +89,7 @@ Unreleased Changes (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) * add proto_h flag for speeding up large builds * Add missing overload for reference wrapped fields. * Add MergedDescriptorDatabase::FindAllFileNames() + * RepeatedField now defines an iterator type instead of using a pointer. 2022-01-28 version 3.19.4 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript) diff --git a/cmake/libprotobuf.cmake b/cmake/libprotobuf.cmake index ef5a3cf593..db2b30cbb1 100644 --- a/cmake/libprotobuf.cmake +++ b/cmake/libprotobuf.cmake @@ -90,6 +90,7 @@ set(libprotobuf_includes ${protobuf_source_dir}/src/google/protobuf/util/delimited_message_util.h ${protobuf_source_dir}/src/google/protobuf/util/field_comparator.h ${protobuf_source_dir}/src/google/protobuf/util/field_mask_util.h + ${protobuf_source_dir}/src/google/protobuf/util/internal/json_escaping.h ${protobuf_source_dir}/src/google/protobuf/util/json_util.h ${protobuf_source_dir}/src/google/protobuf/util/message_differencer.h ${protobuf_source_dir}/src/google/protobuf/util/time_util.h diff --git a/java/BUILD b/java/BUILD index 3e57ab6d7b..4a1cdc2c0f 100644 --- a/java/BUILD +++ b/java/BUILD @@ -13,6 +13,8 @@ filegroup( name = "release", srcs = [ "//java/core:release", # contains lite. + "//java/kotlin:release", + "//java/kotlin-lite:release", "//java/util:release", ] ) diff --git a/java/core/src/main/java/com/google/protobuf/TextFormat.java b/java/core/src/main/java/com/google/protobuf/TextFormat.java index 0b15b5972e..5d2ee7fd2c 100644 --- a/java/core/src/main/java/com/google/protobuf/TextFormat.java +++ b/java/core/src/main/java/com/google/protobuf/TextFormat.java @@ -59,6 +59,8 @@ public final class TextFormat { private static final Logger logger = Logger.getLogger(TextFormat.class.getName()); + private static final String DEBUG_STRING_SILENT_MARKER = "\t "; + /** * Outputs a textual representation of the Protocol Message supplied into the parameter output. @@ -945,6 +947,14 @@ public final class TextFormat { Pattern.compile("-?inf(inity)?f?", Pattern.CASE_INSENSITIVE); private static final Pattern FLOAT_NAN = Pattern.compile("nanf?", Pattern.CASE_INSENSITIVE); + /** + * {@link containsSilentMarkerAfterCurrentToken} indicates if there is a silent marker after the + * current token. This value is moved to {@link containsSilentMarkerAfterPrevToken} every time + * the next token is parsed. + */ + private boolean containsSilentMarkerAfterCurrentToken = false; + private boolean containsSilentMarkerAfterPrevToken = false; + /** Construct a tokenizer that parses tokens from the given text. */ private Tokenizer(final CharSequence text) { this.text = text; @@ -969,6 +979,14 @@ public final class TextFormat { return column; } + boolean getContainsSilentMarkerAfterCurrentToken() { + return containsSilentMarkerAfterCurrentToken; + } + + boolean getContainsSilentMarkerAfterPrevToken() { + return containsSilentMarkerAfterPrevToken; + } + /** Are we at the end of the input? */ public boolean atEnd() { return currentToken.length() == 0; @@ -1534,6 +1552,23 @@ public final class TextFormat { * control the parser behavior. */ public static class Parser { + private int debugStringSilentMarker; + + int getSilentMarkerCount() { + return debugStringSilentMarker; + } + + /** + * A valid silent marker appears between a field name and its value. If there is a ":" in + * between, the silent marker will only appear after the colon. This is called after a field + * name is parsed, and before the ":" if it exists. If the current token is ":", then + * containsSilentMarkerAfterCurrentToken indicates if there is a valid silent marker. Otherwise, + * the current token is part of the field value, so the silent marker is indicated by + * containsSilentMarkerAfterPrevToken. + */ + private void detectSilentMarker(Tokenizer tokenizer) { + } + /** * Determines if repeated values for non-repeated fields and oneofs are permitted. For example, * given required/optional field "foo" and a oneof containing "baz" and "qux": @@ -1890,6 +1925,7 @@ public final class TextFormat { // start with "{" or "<" which indicates the beginning of a message body. // If there is no ":" or there is a "{" or "<" after ":", this field has // to be a message or the input is ill-formed. + detectSilentMarker(tokenizer); if (tokenizer.tryConsume(":") && !tokenizer.lookingAt("{") && !tokenizer.lookingAt("<")) { skipFieldValue(tokenizer); } else { @@ -1900,6 +1936,7 @@ public final class TextFormat { // Handle potential ':'. if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { + detectSilentMarker(tokenizer); tokenizer.tryConsume(":"); // optional if (parseTreeBuilder != null) { TextFormatParseInfoTree.Builder childParseTreeBuilder = @@ -1923,6 +1960,7 @@ public final class TextFormat { unknownFields); } } else { + detectSilentMarker(tokenizer); tokenizer.consume(":"); // required consumeFieldValues( tokenizer, @@ -2184,6 +2222,7 @@ public final class TextFormat { throw tokenizer.parseExceptionPreviousToken("Expected a valid type URL."); } } + detectSilentMarker(tokenizer); tokenizer.tryConsume(":"); final String anyEndToken; if (tokenizer.tryConsume("<")) { @@ -2220,7 +2259,7 @@ public final class TextFormat { } /** Skips the next field including the field's name and value. */ - private static void skipField(Tokenizer tokenizer) throws ParseException { + private void skipField(Tokenizer tokenizer) throws ParseException { if (tokenizer.tryConsume("[")) { // Extension name. do { @@ -2237,6 +2276,7 @@ public final class TextFormat { // start with "{" or "<" which indicates the beginning of a message body. // If there is no ":" or there is a "{" or "<" after ":", this field has // to be a message or the input is ill-formed. + detectSilentMarker(tokenizer); if (tokenizer.tryConsume(":") && !tokenizer.lookingAt("<") && !tokenizer.lookingAt("{")) { skipFieldValue(tokenizer); } else { @@ -2252,7 +2292,7 @@ public final class TextFormat { /** * Skips the whole body of a message including the beginning delimiter and the ending delimiter. */ - private static void skipFieldMessage(Tokenizer tokenizer) throws ParseException { + private void skipFieldMessage(Tokenizer tokenizer) throws ParseException { final String delimiter; if (tokenizer.tryConsume("<")) { delimiter = ">"; @@ -2267,7 +2307,7 @@ public final class TextFormat { } /** Skips a field value. */ - private static void skipFieldValue(Tokenizer tokenizer) throws ParseException { + private void skipFieldValue(Tokenizer tokenizer) throws ParseException { if (tokenizer.tryConsumeString()) { while (tokenizer.tryConsumeString()) {} return; diff --git a/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java b/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java index eb24dded51..ef27323f48 100644 --- a/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java +++ b/java/core/src/test/java/com/google/protobuf/CodedOutputStreamTest.java @@ -764,6 +764,7 @@ public class CodedOutputStreamTest { * Writes the given value using writeRawVarint32() and writeRawVarint64() and checks that the * result matches the given bytes. */ + @SuppressWarnings("UnnecessaryLongToIntConversion") // Intentionally tests 32-bit int values. private static void assertWriteVarint(byte[] data, long value) throws Exception { for (OutputType outputType : OutputType.values()) { // Only test 32-bit write if the value fits into an int. diff --git a/java/core/src/test/java/com/google/protobuf/ServiceTest.java b/java/core/src/test/java/com/google/protobuf/ServiceTest.java index 33ce537a4a..eccdf1c14c 100644 --- a/java/core/src/test/java/com/google/protobuf/ServiceTest.java +++ b/java/core/src/test/java/com/google/protobuf/ServiceTest.java @@ -32,6 +32,8 @@ package com.google.protobuf; import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import com.google.protobuf.Descriptors.FileDescriptor; import com.google.protobuf.Descriptors.MethodDescriptor; @@ -46,145 +48,124 @@ import protobuf_unittest.UnittestProto.TestService; import protobuf_unittest.no_generic_services_test.UnittestNoGenericServices; import java.util.HashSet; import java.util.Set; -import org.easymock.EasyMock; -import org.easymock.IArgumentMatcher; -import org.easymock.IMocksControl; -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import org.mockito.InOrder; +import org.mockito.Mockito; -/** Tests services and stubs. */ @RunWith(JUnit4.class) public class ServiceTest { - private IMocksControl control; - private RpcController mockController; - private final Descriptors.MethodDescriptor fooDescriptor = TestService.getDescriptor().getMethods().get(0); private final Descriptors.MethodDescriptor barDescriptor = TestService.getDescriptor().getMethods().get(1); - - @Before - public void setUp() throws Exception { - control = EasyMock.createStrictControl(); - mockController = control.createMock(RpcController.class); - } - - // ================================================================= + private static final FooRequest FOO_REQUEST = FooRequest.getDefaultInstance(); + private static final BarRequest BAR_REQUEST = BarRequest.getDefaultInstance(); + private static final RpcController MOCK_RPC_CONTROLLER = Mockito.mock(RpcController.class); + private static final FooResponse FOO_RESPONSE = FooResponse.getDefaultInstance(); + private static final BarResponse BAR_RESPONSE = BarResponse.getDefaultInstance(); + private static final MessageWithNoOuter MESSAGE_WITH_NO_OUTER = + MessageWithNoOuter.getDefaultInstance(); /** Tests Service.callMethod(). */ @Test + @SuppressWarnings({"unchecked", "rawtypes"}) public void testCallMethod() throws Exception { - FooRequest fooRequest = FooRequest.newBuilder().build(); - BarRequest barRequest = BarRequest.newBuilder().build(); - MockCallback fooCallback = new MockCallback(); - MockCallback barCallback = new MockCallback(); - TestService mockService = EasyMock.createMock(TestService.class); - - mockService.foo( - EasyMock.same(mockController), - EasyMock.same(fooRequest), - this.wrapsCallback(fooCallback)); - mockService.bar( - EasyMock.same(mockController), - EasyMock.same(barRequest), - this.wrapsCallback(barCallback)); - control.replay(); - - mockService.callMethod( - fooDescriptor, mockController, - fooRequest, fooCallback); - mockService.callMethod( - barDescriptor, mockController, - barRequest, barCallback); - control.verify(); + TestService mockService = Mockito.mock(TestService.class); + RpcCallback mockFooRpcCallback = Mockito.mock(RpcCallback.class); + RpcCallback mockBarRpcCallback = Mockito.mock(RpcCallback.class); + InOrder order = Mockito.inOrder(mockService); + + mockService.callMethod(fooDescriptor, MOCK_RPC_CONTROLLER, FOO_REQUEST, mockFooRpcCallback); + mockService.callMethod(barDescriptor, MOCK_RPC_CONTROLLER, BAR_REQUEST, mockBarRpcCallback); + order + .verify(mockService) + .foo( + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(FOO_REQUEST), + Mockito.same(mockFooRpcCallback)); + order + .verify(mockService) + .bar( + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(BAR_REQUEST), + Mockito.same(mockBarRpcCallback)); } /** Tests Service.get{Request,Response}Prototype(). */ @Test public void testGetPrototype() throws Exception { - TestService mockService = EasyMock.createMock(TestService.class); - - assertThat(mockService.getRequestPrototype(fooDescriptor)) - .isSameInstanceAs(FooRequest.getDefaultInstance()); - assertThat(mockService.getResponsePrototype(fooDescriptor)) - .isSameInstanceAs(FooResponse.getDefaultInstance()); - assertThat(mockService.getRequestPrototype(barDescriptor)) - .isSameInstanceAs(BarRequest.getDefaultInstance()); - assertThat(mockService.getResponsePrototype(barDescriptor)) - .isSameInstanceAs(BarResponse.getDefaultInstance()); + Descriptors.MethodDescriptor fooDescriptor = TestService.getDescriptor().getMethods().get(0); + Descriptors.MethodDescriptor barDescriptor = TestService.getDescriptor().getMethods().get(1); + TestService mockService = Mockito.mock(TestService.class); + + assertThat(mockService.getRequestPrototype(fooDescriptor)).isSameInstanceAs(FOO_REQUEST); + assertThat(mockService.getResponsePrototype(fooDescriptor)).isSameInstanceAs(FOO_RESPONSE); + assertThat(mockService.getRequestPrototype(barDescriptor)).isSameInstanceAs(BAR_REQUEST); + assertThat(mockService.getResponsePrototype(barDescriptor)).isSameInstanceAs(BAR_RESPONSE); } /** Tests generated stubs. */ @Test + @SuppressWarnings({"unchecked", "rawtypes"}) public void testStub() throws Exception { - FooRequest fooRequest = FooRequest.newBuilder().build(); - BarRequest barRequest = BarRequest.newBuilder().build(); - MockCallback fooCallback = new MockCallback(); - MockCallback barCallback = new MockCallback(); - RpcChannel mockChannel = control.createMock(RpcChannel.class); - TestService stub = TestService.newStub(mockChannel); - - mockChannel.callMethod( - EasyMock.same(fooDescriptor), - EasyMock.same(mockController), - EasyMock.same(fooRequest), - EasyMock.same(FooResponse.getDefaultInstance()), - this.wrapsCallback(fooCallback)); - mockChannel.callMethod( - EasyMock.same(barDescriptor), - EasyMock.same(mockController), - EasyMock.same(barRequest), - EasyMock.same(BarResponse.getDefaultInstance()), - this.wrapsCallback(barCallback)); - control.replay(); - - stub.foo(mockController, fooRequest, fooCallback); - stub.bar(mockController, barRequest, barCallback); - control.verify(); + RpcCallback mockFooRpcCallback = Mockito.mock(RpcCallback.class); + RpcCallback mockBarRpcCallback = Mockito.mock(RpcCallback.class); + RpcChannel mockRpcChannel = Mockito.mock(RpcChannel.class); + InOrder order = Mockito.inOrder(mockRpcChannel); + TestService stub = TestService.newStub(mockRpcChannel); + + stub.foo(MOCK_RPC_CONTROLLER, FOO_REQUEST, mockFooRpcCallback); + stub.bar(MOCK_RPC_CONTROLLER, BAR_REQUEST, mockBarRpcCallback); + + order + .verify(mockRpcChannel) + .callMethod( + Mockito.same(fooDescriptor), + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(FOO_REQUEST), + Mockito.same(FOO_RESPONSE), + Mockito.any(RpcCallback.class)); + order + .verify(mockRpcChannel) + .callMethod( + Mockito.same(barDescriptor), + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(BAR_REQUEST), + Mockito.same(BAR_RESPONSE), + Mockito.any(RpcCallback.class)); } /** Tests generated blocking stubs. */ @Test public void testBlockingStub() throws Exception { - FooRequest fooRequest = FooRequest.newBuilder().build(); - BarRequest barRequest = BarRequest.newBuilder().build(); - BlockingRpcChannel mockChannel = control.createMock(BlockingRpcChannel.class); - TestService.BlockingInterface stub = TestService.newBlockingStub(mockChannel); - - FooResponse fooResponse = FooResponse.newBuilder().build(); - BarResponse barResponse = BarResponse.newBuilder().build(); - - EasyMock.expect( - mockChannel.callBlockingMethod( - EasyMock.same(fooDescriptor), - EasyMock.same(mockController), - EasyMock.same(fooRequest), - EasyMock.same(FooResponse.getDefaultInstance()))) - .andReturn(fooResponse); - EasyMock.expect( - mockChannel.callBlockingMethod( - EasyMock.same(barDescriptor), - EasyMock.same(mockController), - EasyMock.same(barRequest), - EasyMock.same(BarResponse.getDefaultInstance()))) - .andReturn(barResponse); - control.replay(); - - assertThat(fooResponse).isSameInstanceAs(stub.foo(mockController, fooRequest)); - assertThat(barResponse).isSameInstanceAs(stub.bar(mockController, barRequest)); - control.verify(); + BlockingRpcChannel mockBlockingRpcChannel = Mockito.mock(BlockingRpcChannel.class); + TestService.BlockingInterface stub = TestService.newBlockingStub(mockBlockingRpcChannel); + + when(mockBlockingRpcChannel.callBlockingMethod( + Mockito.same(fooDescriptor), + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(FOO_REQUEST), + Mockito.same(FOO_RESPONSE))) + .thenReturn(FOO_RESPONSE); + when(mockBlockingRpcChannel.callBlockingMethod( + Mockito.same(barDescriptor), + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(BAR_REQUEST), + Mockito.same(BAR_RESPONSE))) + .thenReturn(BAR_RESPONSE); + + assertThat(FOO_RESPONSE).isSameInstanceAs(stub.foo(MOCK_RPC_CONTROLLER, FOO_REQUEST)); + assertThat(BAR_RESPONSE).isSameInstanceAs(stub.bar(MOCK_RPC_CONTROLLER, BAR_REQUEST)); } @Test public void testNewReflectiveService() { - ServiceWithNoOuter.Interface impl = control.createMock(ServiceWithNoOuter.Interface.class); - RpcController controller = control.createMock(RpcController.class); + ServiceWithNoOuter.Interface impl = Mockito.mock(ServiceWithNoOuter.Interface.class); Service service = ServiceWithNoOuter.newReflectiveService(impl); MethodDescriptor fooMethod = ServiceWithNoOuter.getDescriptor().findMethodByName("Foo"); - MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance(); RpcCallback callback = new RpcCallback() { @Override @@ -195,36 +176,30 @@ public class ServiceTest { }; RpcCallback specializedCallback = RpcUtil.specializeCallback(callback); - impl.foo(EasyMock.same(controller), EasyMock.same(request), EasyMock.same(specializedCallback)); - EasyMock.expectLastCall(); - - control.replay(); - - service.callMethod(fooMethod, controller, request, callback); - - control.verify(); + service.callMethod(fooMethod, MOCK_RPC_CONTROLLER, MESSAGE_WITH_NO_OUTER, callback); + verify(impl) + .foo( + Mockito.same(MOCK_RPC_CONTROLLER), + Mockito.same(MESSAGE_WITH_NO_OUTER), + Mockito.same(specializedCallback)); } @Test public void testNewReflectiveBlockingService() throws ServiceException { ServiceWithNoOuter.BlockingInterface impl = - control.createMock(ServiceWithNoOuter.BlockingInterface.class); - RpcController controller = control.createMock(RpcController.class); + Mockito.mock(ServiceWithNoOuter.BlockingInterface.class); + BlockingService service = ServiceWithNoOuter.newReflectiveBlockingService(impl); MethodDescriptor fooMethod = ServiceWithNoOuter.getDescriptor().findMethodByName("Foo"); - MessageWithNoOuter request = MessageWithNoOuter.getDefaultInstance(); TestAllTypes expectedResponse = TestAllTypes.getDefaultInstance(); - EasyMock.expect(impl.foo(EasyMock.same(controller), EasyMock.same(request))) - .andReturn(expectedResponse); - - control.replay(); - Message response = service.callBlockingMethod(fooMethod, controller, request); + when(impl.foo(Mockito.same(MOCK_RPC_CONTROLLER), Mockito.same(MESSAGE_WITH_NO_OUTER))) + .thenReturn(expectedResponse); + Message response = + service.callBlockingMethod(fooMethod, MOCK_RPC_CONTROLLER, MESSAGE_WITH_NO_OUTER); assertThat(response).isEqualTo(expectedResponse); - - control.verify(); } @Test @@ -243,7 +218,7 @@ public class ServiceTest { "protobuf_unittest.no_generic_services_test.UnittestNoGenericServices"; Class outerClass = Class.forName(outerName); - Set innerClassNames = new HashSet(); + Set innerClassNames = new HashSet<>(); for (Class innerClass : outerClass.getClasses()) { String fullName = innerClass.getName(); // Figure out the unqualified name of the inner class. @@ -279,57 +254,4 @@ public class ServiceTest { // ================================================================= - - /** - * wrapsCallback() is an EasyMock argument predicate. wrapsCallback(c) matches a callback if - * calling that callback causes c to be called. In other words, c wraps the given callback. - */ - private RpcCallback wrapsCallback(MockCallback callback) { - EasyMock.reportMatcher(new WrapsCallback(callback)); - return null; - } - - /** The parameter to wrapsCallback() must be a MockCallback. */ - private static class MockCallback implements RpcCallback { - private boolean called = false; - - public boolean isCalled() { - return called; - } - - public void reset() { - called = false; - } - - @Override - public void run(T message) { - called = true; - } - } - - /** Implementation of the wrapsCallback() argument matcher. */ - private static class WrapsCallback implements IArgumentMatcher { - private MockCallback callback; - - public WrapsCallback(MockCallback callback) { - this.callback = callback; - } - - @Override - public boolean matches(Object actual) { - if (!(actual instanceof RpcCallback)) { - return false; - } - RpcCallback actualCallback = (RpcCallback) actual; - - callback.reset(); - actualCallback.run(null); - return callback.isCalled(); - } - - @Override - public void appendTo(StringBuffer buffer) { - buffer.append("wrapsCallback(mockCallback)"); - } - } } diff --git a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java index 7f018cac4f..cde1776830 100644 --- a/java/core/src/test/java/com/google/protobuf/TextFormatTest.java +++ b/java/core/src/test/java/com/google/protobuf/TextFormatTest.java @@ -1831,4 +1831,5 @@ public class TextFormatTest { assertThat(TextFormat.printer().printToString(message)) .isEqualTo("optional_float: -0.0\noptional_double: -0.0\n"); } + } diff --git a/java/kotlin-lite/BUILD b/java/kotlin-lite/BUILD index a41584a8bb..fd0c103166 100644 --- a/java/kotlin-lite/BUILD +++ b/java/kotlin-lite/BUILD @@ -1,5 +1,7 @@ load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") load("@rules_java//java:defs.bzl", "java_lite_proto_library") +load("@rules_jvm_external//:kt_defs.bzl", "kt_jvm_export") +load("//:protobuf_version.bzl", "PROTOBUF_VERSION") load("//:protobuf.bzl", "internal_gen_kt_protos") java_lite_proto_library( @@ -13,6 +15,47 @@ kt_jvm_library( deps = ["//java/lite"], ) +kt_jvm_library( + name = "well_known_protos_kotlin_lite", + srcs = [ + "//:gen_well_known_protos_kotlinlite", + ], + deps = [ + "//java/lite", + "//java/kotlin:only_for_use_in_proto_generated_code_its_generator_and_tests", + "//java/kotlin:shared_runtime", + ], +) + +kt_jvm_export( + name = "kotlin-lite_mvn", + maven_coordinates = "com.google.protobuf:protobuf-kotlin-lite:%s" % PROTOBUF_VERSION, + pom_template = "//java/kotlin-lite:pom_template.xml", + resources = ["//:well_known_protos"], + runtime_deps = [ + ":lite_extensions", + ":well_known_protos_kotlin_lite", + "//java/kotlin:bytestring_lib", + "//java/kotlin:only_for_use_in_proto_generated_code_its_generator_and_tests", + "//java/kotlin:shared_runtime", + ], + deploy_env = [ + "@com_github_jetbrains_kotlin//:kotlin-stdlib", + "//java/lite", + ], +) + +filegroup( + name = "release", + srcs = [ + ":kotlin-lite_mvn-docs", + ":kotlin-lite_mvn-maven-source", + ":kotlin-lite_mvn-pom", + ":kotlin-lite_mvn-project", + ], + visibility = ["//java:__pkg__"], +) + test_suite( name = "tests", tests = [ diff --git a/java/kotlin/BUILD b/java/kotlin/BUILD index b4bdf7393f..1da4de535c 100644 --- a/java/kotlin/BUILD +++ b/java/kotlin/BUILD @@ -1,5 +1,6 @@ load("@io_bazel_rules_kotlin//kotlin:jvm.bzl", "kt_jvm_library") load("@rules_java//java:defs.bzl", "java_proto_library") +load("@rules_jvm_external//:kt_defs.bzl", "kt_jvm_export") load("@rules_proto//proto:defs.bzl", "proto_library") load("//:protobuf_version.bzl", "PROTOBUF_VERSION") load("//:protobuf.bzl", "internal_gen_kt_protos") @@ -36,6 +37,7 @@ kt_jvm_library( name = "bytestring_lib", srcs = ["src/main/kotlin/com/google/protobuf/ByteStrings.kt"], deps = ["//java/lite"], + visibility = ["//java:__subpackages__"], ) kt_jvm_library( @@ -47,6 +49,35 @@ kt_jvm_library( deps = ["//java/core"], ) +kt_jvm_export( + name = "kotlin_mvn", + maven_coordinates = "com.google.protobuf:protobuf-kotlin:%s" % PROTOBUF_VERSION, + pom_template = "//java/kotlin:pom_template.xml", + resources = ["//:well_known_protos"], + runtime_deps = [ + ":bytestring_lib", + ":full_extensions", + ":only_for_use_in_proto_generated_code_its_generator_and_tests", + ":shared_runtime", + ":well_known_protos_kotlin", + ], + deploy_env = [ + "@com_github_jetbrains_kotlin//:kotlin-stdlib", + "//java/core", + ], +) + +filegroup( + name = "release", + srcs = [ + ":kotlin_mvn-docs", + ":kotlin_mvn-maven-source", + ":kotlin_mvn-pom", + ":kotlin_mvn-project", + ], + visibility = ["//java:__pkg__"], +) + test_suite( name = "tests", tests = [ diff --git a/java/kotlin/src/test/kotlin/com/google/protobuf/Proto3Test.kt b/java/kotlin/src/test/kotlin/com/google/protobuf/Proto3Test.kt index ba69dca8fc..d6d0ab5218 100644 --- a/java/kotlin/src/test/kotlin/com/google/protobuf/Proto3Test.kt +++ b/java/kotlin/src/test/kotlin/com/google/protobuf/Proto3Test.kt @@ -44,6 +44,7 @@ import proto3_unittest.UnittestProto3.TestAllTypes import proto3_unittest.UnittestProto3.TestAllTypes.NestedEnum import proto3_unittest.UnittestProto3.TestEmptyMessage import proto3_unittest.copy +import proto3_unittest.optionalForeignMessageOrNull import proto3_unittest.optionalNestedMessageOrNull import proto3_unittest.testAllTypes import proto3_unittest.testEmptyMessage @@ -347,5 +348,8 @@ class Proto3Test { } assertThat(someNestedMessage.optionalNestedMessageOrNull) .isEqualTo(TestAllTypesKt.nestedMessage { bb = 118 }) + + // No optional keyword, OrNull should still be generated + assertThat(someNestedMessage.optionalForeignMessageOrNull).isEqualTo(null) } } diff --git a/java/util/BUILD b/java/util/BUILD index 2714917e41..c835b68202 100644 --- a/java/util/BUILD +++ b/java/util/BUILD @@ -27,6 +27,7 @@ java_export( pom_template = "pom_template.xml", visibility = ["//java:__pkg__"], runtime_deps = [":util"], + deploy_env = ["//java/core"], ) filegroup( diff --git a/kokoro/linux/dockerfile/test/ruby/Dockerfile b/kokoro/linux/dockerfile/test/ruby/Dockerfile index 836287090a..cfdc5ba031 100644 --- a/kokoro/linux/dockerfile/test/ruby/Dockerfile +++ b/kokoro/linux/dockerfile/test/ruby/Dockerfile @@ -35,8 +35,8 @@ RUN /bin/bash -l -c "rvm install 2.5.1" RUN /bin/bash -l -c "rvm install 2.6.0" RUN /bin/bash -l -c "rvm install 2.7.0" RUN /bin/bash -l -c "rvm install 3.0.0" -RUN /bin/bash -l -c "rvm install jruby-9.2.19.0" -RUN /bin/bash -l -c "rvm install jruby-9.3.0.0" +RUN /bin/bash -l -c "rvm install jruby-9.2.20.1" +RUN /bin/bash -l -c "rvm install jruby-9.3.3.0" RUN /bin/bash -l -c "echo 'gem: --no-ri --no-rdoc' > ~/.gemrc" RUN /bin/bash -l -c "echo 'export PATH=/usr/local/rvm/bin:$PATH' >> ~/.bashrc" diff --git a/objectivec/GPBAny.pbobjc.h b/objectivec/GPBAny.pbobjc.h index 5ed3f2ee68..7fb4129b13 100644 --- a/objectivec/GPBAny.pbobjc.h +++ b/objectivec/GPBAny.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/any.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBAny.pbobjc.m b/objectivec/GPBAny.pbobjc.m index a5143f15dc..7632c8c279 100644 --- a/objectivec/GPBAny.pbobjc.m +++ b/objectivec/GPBAny.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/any.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBAny.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBAny.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBApi.pbobjc.h b/objectivec/GPBApi.pbobjc.h index 5d55ebf399..1634a9212e 100644 --- a/objectivec/GPBApi.pbobjc.h +++ b/objectivec/GPBApi.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/api.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBApi.pbobjc.m b/objectivec/GPBApi.pbobjc.m index 5915ce1122..639462b19d 100644 --- a/objectivec/GPBApi.pbobjc.m +++ b/objectivec/GPBApi.pbobjc.m @@ -1,27 +1,11 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/api.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBApi.pbobjc.h" - #import "GPBSourceContext.pbobjc.h" - #import "GPBType.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBApi.pbobjc.h" +#import "GPBSourceContext.pbobjc.h" +#import "GPBType.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBDuration.pbobjc.h b/objectivec/GPBDuration.pbobjc.h index 88527f520d..d6236b07f3 100644 --- a/objectivec/GPBDuration.pbobjc.h +++ b/objectivec/GPBDuration.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/duration.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBDuration.pbobjc.m b/objectivec/GPBDuration.pbobjc.m index d3cc7e31ca..11ba5e5f7b 100644 --- a/objectivec/GPBDuration.pbobjc.m +++ b/objectivec/GPBDuration.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/duration.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBDuration.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBDuration.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBEmpty.pbobjc.h b/objectivec/GPBEmpty.pbobjc.h index 45600ead86..8a31c04ff5 100644 --- a/objectivec/GPBEmpty.pbobjc.h +++ b/objectivec/GPBEmpty.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/empty.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBEmpty.pbobjc.m b/objectivec/GPBEmpty.pbobjc.m index df3e398170..8aefddb5b4 100644 --- a/objectivec/GPBEmpty.pbobjc.m +++ b/objectivec/GPBEmpty.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/empty.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBEmpty.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBEmpty.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBFieldMask.pbobjc.h b/objectivec/GPBFieldMask.pbobjc.h index 3028b775dc..c4667b44db 100644 --- a/objectivec/GPBFieldMask.pbobjc.h +++ b/objectivec/GPBFieldMask.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/field_mask.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBFieldMask.pbobjc.m b/objectivec/GPBFieldMask.pbobjc.m index 3605f89d80..ab25d3f9b1 100644 --- a/objectivec/GPBFieldMask.pbobjc.m +++ b/objectivec/GPBFieldMask.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/field_mask.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBFieldMask.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBFieldMask.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBProtocolBuffers.h b/objectivec/GPBProtocolBuffers.h index c5df916396..619c08228b 100644 --- a/objectivec/GPBProtocolBuffers.h +++ b/objectivec/GPBProtocolBuffers.h @@ -44,33 +44,14 @@ #import "GPBWellKnownTypes.h" #import "GPBWireFormat.h" -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - // Well-known proto types -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import - #import - #import - #import - #import - #import - #import - #import -#else - #import "GPBAny.pbobjc.h" - #import "GPBApi.pbobjc.h" - #import "GPBDuration.pbobjc.h" - #import "GPBEmpty.pbobjc.h" - #import "GPBFieldMask.pbobjc.h" - #import "GPBSourceContext.pbobjc.h" - #import "GPBStruct.pbobjc.h" - #import "GPBTimestamp.pbobjc.h" - #import "GPBType.pbobjc.h" - #import "GPBWrappers.pbobjc.h" -#endif +#import "GPBAny.pbobjc.h" +#import "GPBApi.pbobjc.h" +#import "GPBDuration.pbobjc.h" +#import "GPBEmpty.pbobjc.h" +#import "GPBFieldMask.pbobjc.h" +#import "GPBSourceContext.pbobjc.h" +#import "GPBStruct.pbobjc.h" +#import "GPBTimestamp.pbobjc.h" +#import "GPBType.pbobjc.h" +#import "GPBWrappers.pbobjc.h" diff --git a/objectivec/GPBSourceContext.pbobjc.h b/objectivec/GPBSourceContext.pbobjc.h index 7a103362b5..b17fec0b78 100644 --- a/objectivec/GPBSourceContext.pbobjc.h +++ b/objectivec/GPBSourceContext.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/source_context.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBSourceContext.pbobjc.m b/objectivec/GPBSourceContext.pbobjc.m index b3e6fa759c..376d4421de 100644 --- a/objectivec/GPBSourceContext.pbobjc.m +++ b/objectivec/GPBSourceContext.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/source_context.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBSourceContext.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBSourceContext.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBStruct.pbobjc.h b/objectivec/GPBStruct.pbobjc.h index abdd6c82be..dd6ab28f0e 100644 --- a/objectivec/GPBStruct.pbobjc.h +++ b/objectivec/GPBStruct.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/struct.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBStruct.pbobjc.m b/objectivec/GPBStruct.pbobjc.m index 554046a9fe..726cfb860e 100644 --- a/objectivec/GPBStruct.pbobjc.m +++ b/objectivec/GPBStruct.pbobjc.m @@ -1,25 +1,11 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/struct.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBStruct.pbobjc.h" #import -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBStruct.pbobjc.h" -#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBTimestamp.pbobjc.h b/objectivec/GPBTimestamp.pbobjc.h index a328afc7c9..8203383bdd 100644 --- a/objectivec/GPBTimestamp.pbobjc.h +++ b/objectivec/GPBTimestamp.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/timestamp.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBTimestamp.pbobjc.m b/objectivec/GPBTimestamp.pbobjc.m index 736a75d19f..72d348f42a 100644 --- a/objectivec/GPBTimestamp.pbobjc.m +++ b/objectivec/GPBTimestamp.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/timestamp.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBTimestamp.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBTimestamp.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBType.pbobjc.h b/objectivec/GPBType.pbobjc.h index 747e15d455..ee02b0a683 100644 --- a/objectivec/GPBType.pbobjc.h +++ b/objectivec/GPBType.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/type.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBType.pbobjc.m b/objectivec/GPBType.pbobjc.m index 70dae31c68..556df19711 100644 --- a/objectivec/GPBType.pbobjc.m +++ b/objectivec/GPBType.pbobjc.m @@ -1,29 +1,13 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/type.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBType.pbobjc.h" +#import "GPBAny.pbobjc.h" +#import "GPBSourceContext.pbobjc.h" #import -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBType.pbobjc.h" - #import "GPBAny.pbobjc.h" - #import "GPBSourceContext.pbobjc.h" -#endif // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/GPBWellKnownTypes.h b/objectivec/GPBWellKnownTypes.h index 784ba9ff99..80d9db00e9 100644 --- a/objectivec/GPBWellKnownTypes.h +++ b/objectivec/GPBWellKnownTypes.h @@ -30,21 +30,9 @@ #import -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBAny.pbobjc.h" - #import "GPBDuration.pbobjc.h" - #import "GPBTimestamp.pbobjc.h" -#endif +#import "GPBAny.pbobjc.h" +#import "GPBDuration.pbobjc.h" +#import "GPBTimestamp.pbobjc.h" NS_ASSUME_NONNULL_BEGIN diff --git a/objectivec/GPBWrappers.pbobjc.h b/objectivec/GPBWrappers.pbobjc.h index 713bafc89b..e6741ae120 100644 --- a/objectivec/GPBWrappers.pbobjc.h +++ b/objectivec/GPBWrappers.pbobjc.h @@ -1,21 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/wrappers.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import - #import - #import -#else - #import "GPBDescriptor.h" - #import "GPBMessage.h" - #import "GPBRootObject.h" -#endif +#import "GPBDescriptor.h" +#import "GPBMessage.h" +#import "GPBRootObject.h" #if GOOGLE_PROTOBUF_OBJC_VERSION < 30004 #error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. diff --git a/objectivec/GPBWrappers.pbobjc.m b/objectivec/GPBWrappers.pbobjc.m index 32201d4d83..b02a0716e2 100644 --- a/objectivec/GPBWrappers.pbobjc.m +++ b/objectivec/GPBWrappers.pbobjc.m @@ -1,23 +1,9 @@ // Generated by the protocol buffer compiler. DO NOT EDIT! // source: google/protobuf/wrappers.proto -// This CPP symbol can be defined to use imports that match up to the framework -// imports needed when using CocoaPods. -#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) - #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBProtocolBuffers_RuntimeSupport.h" -#endif - -#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS - #import -#else - #import "GPBWrappers.pbobjc.h" -#endif +#import "GPBProtocolBuffers_RuntimeSupport.h" +#import "GPBWrappers.pbobjc.h" + // @@protoc_insertion_point(imports) #pragma clang diagnostic push diff --git a/objectivec/README.md b/objectivec/README.md index b0278f2aee..955fa531b7 100644 --- a/objectivec/README.md +++ b/objectivec/README.md @@ -133,12 +133,12 @@ This options allow you to provide a custom prefix for all the symbols generated from a proto file (classes (from message), enums, the Root for extension support). -If not set, the generation options `default_objc_class_prefix` and `use_package_as_prefix` -(documented below) control what is used instead. Since Objective C uses a global namespace for all -of its classes, there can be collisions. `use_package_as_prefix=yes` should -avoid collisions since proto package are used to scope/name things in other -languages, but this option can be used to get shorter names instead. Convention -is to base the explicit prefix on the proto package. +If not set, the generation options `package_to_prefix_mappings_path` and +`use_package_as_prefix` (documented below) controls what is used instead. Since +Objective C uses a global namespace for all of its classes, there can be collisions. +`use_package_as_prefix=yes` should avoid collisions since proto package are used to +scope/name things in other languages, but this option can be used to get shorter +names instead. Convention is to base the explicit prefix on the proto package. Objective C Generator `protoc` Options -------------------------------------- @@ -182,11 +182,23 @@ supported keys are: having to add the runtime directory to the header search path since the generate `#import` will be more complete. - * `default_objc_class_prefix`: The default ObjC prefix value to use when - generating sources. The generator will use this if the `objc_class_prefix` - file option is not set. This option can be useful if multiple iOS apps - consume the same proto file but wish to use a different prefix for their - generated sources. + * `package_to_prefix_mappings_path`: The `value` used for this key is a + path to a file containing a list of proto packages and prefixes. + The generator will use this to locate which ObjC class prefix to use when + generating sources _unless_ the `objc_class_prefix` file option is set. + This option can be useful if multiple apps consume a common set of + proto files but wish to use a different prefix for the generated sources + between them. This option takes precedent over the `use_package_as_prefix` + option. + + The format of the file is: + * An entry is a line of "package=prefix". + * Comments start with `#`. + * A comment can go on a line after a expected package/prefix pair. + (i.e. - "package=prefix # comment") + * For files that do NOT have a proto package (not recommended), an + entry can be made as "no_package:PATH=prefix", where PATH is the + path for the .proto file. * `use_package_as_prefix` and `proto_package_prefix_exceptions_path`: The `value` for `use_package_as_prefix` can be `yes` or `no`, and indicates diff --git a/protobuf_deps.bzl b/protobuf_deps.bzl index 7e2caa3302..27b8bee258 100644 --- a/protobuf_deps.bzl +++ b/protobuf_deps.bzl @@ -70,9 +70,9 @@ def protobuf_deps(): if not native.existing_rule("rules_jvm_external"): http_archive( name = "rules_jvm_external", - sha256 = "f36441aa876c4f6427bfb2d1f2d723b48e9d930b62662bf723ddfb8fc80f0140", - strip_prefix = "rules_jvm_external-4.1", - urls = ["https://github.com/bazelbuild/rules_jvm_external/archive/4.1.zip"], + sha256 = "744bd7436f63af7e9872948773b8b106016dc164acb3960b4963f86754532ee7", + strip_prefix = "rules_jvm_external-906875b0d5eaaf61a8ca2c9c3835bde6f435d011", + urls = ["https://github.com/bazelbuild/rules_jvm_external/archive/906875b0d5eaaf61a8ca2c9c3835bde6f435d011.zip"], ) if not native.existing_rule("rules_pkg"): diff --git a/protobuf_release.bzl b/protobuf_release.bzl index cac0a0c52a..c5d5f2bf2c 100644 --- a/protobuf_release.bzl +++ b/protobuf_release.bzl @@ -20,6 +20,8 @@ def _package_naming_impl(ctx): cpu = "s390_64" elif cpu == "aarch64": cpu = "aarch_64" + elif cpu == "ppc64": + cpu = "ppcle_64" # use the system name to determine the os and then create platform names if "apple" in system_name: @@ -27,7 +29,7 @@ def _package_naming_impl(ctx): elif "linux" in system_name: values["platform"] = "linux-" + cpu elif "mingw" in system_name: - if "cpu" == "x86_64": + if cpu == "x86_64": values["platform"] = "win64" else: values["platform"] = "win32" diff --git a/python/google/protobuf/pyext/message.cc b/python/google/protobuf/pyext/message.cc index 076b71c281..5931aaad6f 100644 --- a/python/google/protobuf/pyext/message.cc +++ b/python/google/protobuf/pyext/message.cc @@ -784,7 +784,6 @@ PyMessageFactory* GetFactoryForMessage(CMessage* message) { static int MaybeReleaseOverlappingOneofField( CMessage* cmessage, const FieldDescriptor* field) { -#ifdef GOOGLE_PROTOBUF_HAS_ONEOF Message* message = cmessage->message; const Reflection* reflection = message->GetReflection(); if (!field->containing_oneof() || @@ -804,7 +803,6 @@ static int MaybeReleaseOverlappingOneofField( if (InternalReleaseFieldByDescriptor(cmessage, existing_field) < 0) { return -1; } -#endif return 0; } diff --git a/ruby/lib/google/protobuf/descriptor_dsl.rb b/ruby/lib/google/protobuf/descriptor_dsl.rb index c3e9a5a620..7349b6df15 100644 --- a/ruby/lib/google/protobuf/descriptor_dsl.rb +++ b/ruby/lib/google/protobuf/descriptor_dsl.rb @@ -2,7 +2,14 @@ # # Code that implements the DSL for defining proto messages. -require 'google/protobuf/descriptor_pb' +# Suppress warning: loading in progress, circular require considered harmful. +# This circular require is intentional to avoid missing dependency. +begin + old_verbose, $VERBOSE = $VERBOSE, nil + require 'google/protobuf/descriptor_pb' +ensure + $VERBOSE = old_verbose +end module Google module Protobuf diff --git a/ruby/pom.xml b/ruby/pom.xml index c9ae9e6633..7fd164ac02 100644 --- a/ruby/pom.xml +++ b/ruby/pom.xml @@ -81,7 +81,7 @@ org.jruby jruby-complete - 9.2.19.0 + 9.2.20.1 provided diff --git a/src/Makefile.am b/src/Makefile.am index d53cf57420..3331482ffd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -172,6 +172,7 @@ nobase_include_HEADERS = \ google/protobuf/util/delimited_message_util.h \ google/protobuf/util/field_comparator.h \ google/protobuf/util/field_mask_util.h \ + google/protobuf/util/internal/json_escaping.h \ google/protobuf/util/json_util.h \ google/protobuf/util/message_differencer.h \ google/protobuf/util/time_util.h \ @@ -284,7 +285,6 @@ libprotobuf_la_SOURCES = \ google/protobuf/util/internal/field_mask_utility.cc \ google/protobuf/util/internal/field_mask_utility.h \ google/protobuf/util/internal/json_escaping.cc \ - google/protobuf/util/internal/json_escaping.h \ google/protobuf/util/internal/json_objectwriter.cc \ google/protobuf/util/internal/json_objectwriter.h \ google/protobuf/util/internal/json_stream_parser.cc \ @@ -803,12 +803,6 @@ protobuf_test_SOURCES = \ google/protobuf/util/delimited_message_util_test.cc \ google/protobuf/util/field_comparator_test.cc \ google/protobuf/util/field_mask_util_test.cc \ - google/protobuf/util/internal/default_value_objectwriter_test.cc \ - google/protobuf/util/internal/json_objectwriter_test.cc \ - google/protobuf/util/internal/json_stream_parser_test.cc \ - google/protobuf/util/internal/protostream_objectsource_test.cc \ - google/protobuf/util/internal/protostream_objectwriter_test.cc \ - google/protobuf/util/internal/type_info_test_helper.cc \ google/protobuf/util/json_util_test.cc \ google/protobuf/util/message_differencer_unittest.cc \ google/protobuf/util/time_util_test.cc \ diff --git a/src/google/protobuf/any.pb.cc b/src/google/protobuf/any.pb.cc index 05f51a05f6..74b7903655 100644 --- a/src/google/protobuf/any.pb.cc +++ b/src/google/protobuf/any.pb.cc @@ -25,13 +25,13 @@ namespace _pbi = _pb::internal; #pragma clang diagnostic ignored "-Wuninitialized" #endif // __llvm__ PROTOBUF_NAMESPACE_OPEN -constexpr Any::Any( +PROTOBUF_CONSTEXPR Any::Any( ::_pbi::ConstantInitialized) : type_url_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , value_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , _any_metadata_(&type_url_, &value_){} struct AnyDefaultTypeInternal { - constexpr AnyDefaultTypeInternal() + PROTOBUF_CONSTEXPR AnyDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} ~AnyDefaultTypeInternal() {} union { diff --git a/src/google/protobuf/any.pb.h b/src/google/protobuf/any.pb.h index 79636ad91f..fc1b311ba6 100644 --- a/src/google/protobuf/any.pb.h +++ b/src/google/protobuf/any.pb.h @@ -61,7 +61,7 @@ class PROTOBUF_EXPORT Any final : public: inline Any() : Any(nullptr) {} ~Any() override; - explicit constexpr Any(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Any(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Any(const Any& from); Any(Any&& from) noexcept diff --git a/src/google/protobuf/api.pb.cc b/src/google/protobuf/api.pb.cc index 441f3aafb5..7b35b0c577 100644 --- a/src/google/protobuf/api.pb.cc +++ b/src/google/protobuf/api.pb.cc @@ -21,7 +21,7 @@ namespace _pb = ::PROTOBUF_NAMESPACE_ID; namespace _pbi = _pb::internal; PROTOBUF_NAMESPACE_OPEN -constexpr Api::Api( +PROTOBUF_CONSTEXPR Api::Api( ::_pbi::ConstantInitialized) : methods_() , options_() @@ -32,7 +32,7 @@ constexpr Api::Api( , syntax_(0) {} struct ApiDefaultTypeInternal { - constexpr ApiDefaultTypeInternal() + PROTOBUF_CONSTEXPR ApiDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} ~ApiDefaultTypeInternal() {} union { @@ -40,7 +40,7 @@ struct ApiDefaultTypeInternal { }; }; PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 ApiDefaultTypeInternal _Api_default_instance_; -constexpr Method::Method( +PROTOBUF_CONSTEXPR Method::Method( ::_pbi::ConstantInitialized) : options_() , name_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) @@ -51,7 +51,7 @@ constexpr Method::Method( , syntax_(0) {} struct MethodDefaultTypeInternal { - constexpr MethodDefaultTypeInternal() + PROTOBUF_CONSTEXPR MethodDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} ~MethodDefaultTypeInternal() {} union { @@ -59,12 +59,12 @@ struct MethodDefaultTypeInternal { }; }; PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 MethodDefaultTypeInternal _Method_default_instance_; -constexpr Mixin::Mixin( +PROTOBUF_CONSTEXPR Mixin::Mixin( ::_pbi::ConstantInitialized) : name_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , root_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}){} struct MixinDefaultTypeInternal { - constexpr MixinDefaultTypeInternal() + PROTOBUF_CONSTEXPR MixinDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} ~MixinDefaultTypeInternal() {} union { diff --git a/src/google/protobuf/api.pb.h b/src/google/protobuf/api.pb.h index 4ffdbb2934..fb14ef9ce3 100644 --- a/src/google/protobuf/api.pb.h +++ b/src/google/protobuf/api.pb.h @@ -71,7 +71,7 @@ class PROTOBUF_EXPORT Api final : public: inline Api() : Api(nullptr) {} ~Api() override; - explicit constexpr Api(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Api(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Api(const Api& from); Api(Api&& from) noexcept @@ -326,7 +326,7 @@ class PROTOBUF_EXPORT Method final : public: inline Method() : Method(nullptr) {} ~Method() override; - explicit constexpr Method(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Method(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Method(const Method& from); Method(Method&& from) noexcept @@ -559,7 +559,7 @@ class PROTOBUF_EXPORT Mixin final : public: inline Mixin() : Mixin(nullptr) {} ~Mixin() override; - explicit constexpr Mixin(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Mixin(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Mixin(const Mixin& from); Mixin(Mixin&& from) noexcept diff --git a/src/google/protobuf/arenastring.cc b/src/google/protobuf/arenastring.cc index b358fdddab..d886ddad66 100644 --- a/src/google/protobuf/arenastring.cc +++ b/src/google/protobuf/arenastring.cc @@ -175,6 +175,10 @@ template std::string* ArenaStringPtr::MutableSlow(::google::protobuf::Arena* arena, const Lazy&... lazy_default) { GOOGLE_DCHECK(IsDefault()); + + // For empty defaults, this ends up calling the default constructor which is + // more efficient than a copy construction from + // GetEmptyStringAlreadyInited(). return NewString(arena, lazy_default.get()...); } diff --git a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc index 89c864d111..0e832023e2 100644 --- a/src/google/protobuf/compiler/cpp/cpp_enum_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_enum_field.cc @@ -54,6 +54,9 @@ void SetEnumVariables(const FieldDescriptor* descriptor, (*variables)["type"] = QualifiedClassName(descriptor->enum_type(), options); (*variables)["default"] = Int32ToString(default_value->number()); (*variables)["full_name"] = descriptor->full_name(); + (*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor); + (*variables)["cached_byte_size_field"] = + MakeVarintCachedSizeFieldName(descriptor); } } // namespace @@ -235,7 +238,7 @@ void RepeatedEnumFieldGenerator::GeneratePrivateMembers( format("::$proto_ns$::RepeatedField $name$_;\n"); if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->file(), options_)) { - format("mutable std::atomic _$name$_cached_byte_size_;\n"); + format("mutable std::atomic $cached_byte_size_name$;\n"); } } @@ -341,7 +344,7 @@ void RepeatedEnumFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "{\n" " int byte_size = " - "_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n" + "$cached_byte_size_field$.load(std::memory_order_relaxed);\n" " if (byte_size > 0) {\n" " target = stream->WriteEnumPacked(\n" " $number$, $field$, byte_size, target);\n" @@ -379,7 +382,7 @@ void RepeatedEnumFieldGenerator::GenerateByteSize(io::Printer* printer) const { "::_pbi::WireFormatLite::Int32Size(static_cast<$int32$>(data_size));\n" "}\n" "int cached_size = ::_pbi::ToCachedSize(data_size);\n" - "_$name$_cached_byte_size_.store(cached_size,\n" + "$cached_byte_size_field$.store(cached_size,\n" " std::memory_order_relaxed);\n" "total_size += data_size;\n"); } else { @@ -395,7 +398,7 @@ void RepeatedEnumFieldGenerator::GenerateConstinitInitializer( format("$name$_()"); if (descriptor_->is_packed() && HasGeneratedMethods(descriptor_->file(), options_)) { - format("\n, _$name$_cached_byte_size_(0)"); + format("\n, $cached_byte_size_name$(0)"); } } diff --git a/src/google/protobuf/compiler/cpp/cpp_extension.cc b/src/google/protobuf/compiler/cpp/cpp_extension.cc index d5d0520e72..90e292b411 100644 --- a/src/google/protobuf/compiler/cpp/cpp_extension.cc +++ b/src/google/protobuf/compiler/cpp/cpp_extension.cc @@ -78,6 +78,7 @@ ExtensionGenerator::ExtensionGenerator(const FieldDescriptor* descriptor, break; } SetCommonVars(options, &variables_); + SetCommonMessageDataVariables(&variables_); variables_["extendee"] = QualifiedClassName(descriptor_->containing_type(), options_); variables_["type_traits"] = type_traits_; diff --git a/src/google/protobuf/compiler/cpp/cpp_field.cc b/src/google/protobuf/compiler/cpp/cpp_field.cc index 52cc299db5..49d62487ec 100644 --- a/src/google/protobuf/compiler/cpp/cpp_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_field.cc @@ -154,7 +154,8 @@ void AddAccessorAnnotations(const FieldDescriptor* descriptor, const google::protobuf::OneofDescriptor* oneof_member = descriptor->real_containing_oneof(); const std::string proto_ns = (*variables)["proto_ns"]; - const std::string substitute_template_prefix = " _tracker_.$1<$0>(this, "; + const std::string substitute_template_prefix = + StrCat(" ", (*variables)["tracker"], ".$1<$0>(this, "); std::string prepared_template; // Flat template is needed if the prepared one is introspecting the values @@ -235,6 +236,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, std::map* variables, const Options& options) { SetCommonVars(options, variables); + SetCommonMessageDataVariables(variables); + (*variables)["ns"] = Namespace(descriptor, options); (*variables)["name"] = FieldName(descriptor); (*variables)["index"] = StrCat(descriptor->index()); @@ -251,7 +254,8 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, (*variables)["clear_hasbit"] = ""; if (HasHasbit(descriptor)) { (*variables)["set_hasbit_io"] = - "_Internal::set_has_" + FieldName(descriptor) + "(&_has_bits_);"; + StrCat("_Internal::set_has_", FieldName(descriptor), "(&", + (*variables)["has_bits"], ");"); } else { (*variables)["set_hasbit_io"] = ""; } @@ -272,10 +276,10 @@ void FieldGenerator::SetHasBitIndex(int32_t has_bit_index) { return; } variables_["set_hasbit"] = StrCat( - "_has_bits_[", has_bit_index / 32, "] |= 0x", + variables_["has_bits"], "[", has_bit_index / 32, "] |= 0x", strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;"); variables_["clear_hasbit"] = StrCat( - "_has_bits_[", has_bit_index / 32, "] &= ~0x", + variables_["has_bits"], "[", has_bit_index / 32, "] &= ~0x", strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8), "u;"); } @@ -288,11 +292,13 @@ void FieldGenerator::SetInlinedStringIndex(int32_t inlined_string_index) { GOOGLE_CHECK_GT(inlined_string_index, 0) << "_inlined_string_donated_'s bit 0 is reserved for arena dtor tracking"; variables_["inlined_string_donated"] = StrCat( - "(_inlined_string_donated_[", inlined_string_index / 32, "] & 0x", + "(", variables_["inlined_string_donated_array"], "[", + inlined_string_index / 32, "] & 0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), "u) != 0;"); variables_["donating_states_word"] = - StrCat("_inlined_string_donated_[", inlined_string_index / 32, "]"); + StrCat(variables_["inlined_string_donated_array"], "[", + inlined_string_index / 32, "]"); variables_["mask_for_undonate"] = StrCat( "~0x", strings::Hex(1u << (inlined_string_index % 32), strings::ZERO_PAD_8), "u"); diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc index 8b088e1180..24f2ccba46 100644 --- a/src/google/protobuf/compiler/cpp/cpp_file.cc +++ b/src/google/protobuf/compiler/cpp/cpp_file.cc @@ -486,7 +486,7 @@ void FileGenerator::GenerateSourceDefaultInstance(int idx, // destructor that we need to elide. format( "struct $1$ {\n" - " constexpr $1$()\n" + " PROTOBUF_CONSTEXPR $1$()\n" " : _instance(::_pbi::ConstantInitialized{}) {}\n" " ~$1$() {}\n" " union {\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc index 2eb91f3327..9545ff078e 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc @@ -229,6 +229,18 @@ void SetCommonVars(const Options& options, (*variables)["string"] = "std::string"; } +void SetCommonMessageDataVariables( + std::map* variables) { + (*variables)["any_metadata"] = "_any_metadata_"; + (*variables)["cached_size"] = "_cached_size_"; + (*variables)["extensions"] = "_extensions_"; + (*variables)["has_bits"] = "_has_bits_"; + (*variables)["inlined_string_donated_array"] = "_inlined_string_donated_"; + (*variables)["oneof_case"] = "_oneof_case_"; + (*variables)["tracker"] = "_tracker_"; + (*variables)["weak_field_map"] = "_weak_field_map_"; +} + void SetUnknownFieldsVariable(const Descriptor* descriptor, const Options& options, std::map* variables) { diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h index 08a191a77a..6a713c4e00 100644 --- a/src/google/protobuf/compiler/cpp/cpp_helpers.h +++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h @@ -87,6 +87,10 @@ extern const char kThinSeparator[]; void SetCommonVars(const Options& options, std::map* variables); +// Variables to access message data from the message scope. +void SetCommonMessageDataVariables( + std::map* variables); + void SetUnknownFieldsVariable(const Descriptor* descriptor, const Options& options, std::map* variables); @@ -362,8 +366,7 @@ inline bool IsExplicitLazy(const FieldDescriptor* field) { inline bool IsLazilyVerifiedLazy(const FieldDescriptor* field, const Options& options) { // TODO(b/211906113): Make lazy() imply eagerly verified lazy. - return IsExplicitLazy(field) && - !field->is_repeated() && + return IsExplicitLazy(field) && !field->is_repeated() && field->type() == FieldDescriptor::TYPE_MESSAGE && GetOptimizeFor(field->file(), options) != FileOptions::LITE_RUNTIME && !options.opensource_runtime; @@ -491,15 +494,34 @@ inline std::string MakeDefaultName(const FieldDescriptor* field) { // variable name. // For example, declarations of default variables should always use just // MakeDefaultName to produce code like: -// Type _i_give_permission_to_break_this_code_default_field_; +// Type _i_give_permission_to_break_this_code_default_field_; // // Code that references these should use MakeDefaultFieldName, in case the field // exists at some nested level like: -// internal_container_._i_give_permission_to_break_this_code_default_field_; +// internal_container_._i_give_permission_to_break_this_code_default_field_; inline std::string MakeDefaultFieldName(const FieldDescriptor* field) { return MakeDefaultName(field); } +inline std::string MakeVarintCachedSizeName(const FieldDescriptor* field) { + return StrCat("_", FieldName(field), "_cached_byte_size_"); +} + +// Semantically distinct from MakeVarintCachedSizeName in that it gives the C++ +// code referencing the object from the message scope, rather than just the +// variable name. +// For example, declarations of default variables should always use just +// MakeVarintCachedSizeName to produce code like: +// Type _field_cached_byte_size_; +// +// Code that references these variables should use +// MakeVarintCachedSizeFieldName, in case the field exists at some nested level +// like: +// internal_container_._field_cached_byte_size_; +inline std::string MakeVarintCachedSizeFieldName(const FieldDescriptor* field) { + return StrCat("_", FieldName(field), "_cached_byte_size_"); +} + bool IsAnyMessage(const FileDescriptor* descriptor, const Options& options); bool IsAnyMessage(const Descriptor* descriptor, const Options& options); diff --git a/src/google/protobuf/compiler/cpp/cpp_message.cc b/src/google/protobuf/compiler/cpp/cpp_message.cc index cdb8f112a0..8be652b8f2 100644 --- a/src/google/protobuf/compiler/cpp/cpp_message.cc +++ b/src/google/protobuf/compiler/cpp/cpp_message.cc @@ -108,7 +108,7 @@ void PrintPresenceCheck(const Formatter& format, const FieldDescriptor* field, int has_bit_index = has_bit_indices[field->index()]; if (*cached_has_word_index != (has_bit_index / 32)) { *cached_has_word_index = (has_bit_index / 32); - format("cached_has_bits = _has_bits_[$1$];\n", *cached_has_word_index); + format("cached_has_bits = $has_bits$[$1$];\n", *cached_has_word_index); } const std::string mask = StrCat(strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); @@ -411,6 +411,7 @@ class ColdChunkSkipper { access_info_map_(options.access_info_map), cold_threshold_(cold_threshold) { SetCommonVars(options, &variables_); + SetCommonMessageDataVariables(&variables_); } // May open an external if check for a batch of cold fields. "from" is the @@ -551,6 +552,8 @@ void GenerateExtensionAnnotations( google::protobuf::FileOptions::LITE_RUNTIME) { return; } + StringPiece tracker = (*variables)["tracker"]; + StringPiece extensions = (*variables)["extensions"]; for (const auto& annotation : accessor_annotations_to_hooks) { const std::string& annotation_name = annotation.first; const std::string& listener_call = annotation.second; @@ -560,29 +563,29 @@ void GenerateExtensionAnnotations( // Primitive fields accessors. // "Has" is here as users calling "has" on a repeated field is a mistake. (*variables)[annotation_name] = StrCat( - " _tracker_.", listener_call, - "(this, id.number(), _proto_TypeTraits::GetPtr(id.number(), " - "_extensions_, id.default_value_ref()));"); + " ", tracker, ".", listener_call, + "(this, id.number(), _proto_TypeTraits::GetPtr(id.number(), ", + extensions, ", id.default_value_ref()));"); } else if (StrContains(annotation_name, "repeated") && !StrContains(annotation_name, "list") && !StrContains(annotation_name, "size")) { // Repeated index accessors. std::string str_index = "index"; if (StrContains(annotation_name, "add")) { - str_index = "_extensions_.ExtensionSize(id.number()) - 1"; + str_index = StrCat(extensions, ".ExtensionSize(id.number()) - 1"); } (*variables)[annotation_name] = - StrCat(" _tracker_.", listener_call, + StrCat(" ", tracker, ".", listener_call, "(this, id.number(), " - "_proto_TypeTraits::GetPtr(id.number(), _extensions_, ", - str_index, "));"); + "_proto_TypeTraits::GetPtr(id.number(), ", + extensions, ", ", str_index, "));"); } else if (StrContains(annotation_name, "list") || StrContains(annotation_name, "size")) { // Repeated full accessors. (*variables)[annotation_name] = StrCat( - " _tracker_.", listener_call, - "(this, id.number(), _proto_TypeTraits::GetRepeatedPtr(id.number(), " - "_extensions_));"); + " ", tracker, ".", listener_call, + "(this, id.number(), _proto_TypeTraits::GetRepeatedPtr(id.number(), ", + extensions, "));"); } else { // Generic accessors such as "clear". // TODO(b/190614678): Generalize clear from both repeated and non repeated @@ -614,6 +617,7 @@ MessageGenerator::MessageGenerator( if (!message_layout_helper_) { message_layout_helper_.reset(new PaddingOptimizer()); } + SetCommonMessageDataVariables(&variables_); // Variables that apply to this class variables_["classname"] = classname_; @@ -629,7 +633,8 @@ MessageGenerator::MessageGenerator( if (options.field_listener_options.inject_field_listener_events && descriptor->file()->options().optimize_for() != google::protobuf::FileOptions::LITE_RUNTIME) { - const std::string injector_template = " _tracker_."; + const std::string injector_template = + StrCat(" ", variables_["tracker"], "."); MaySetAnnotationVariable(options, "serialize", injector_template, "OnSerialize(this);\n", &variables_); @@ -845,7 +850,7 @@ inline bool HasExtension( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { $annotate_extension_has$ - return _extensions_.Has(id.number()); + return $extensions$.Has(id.number()); } template & id) { - _extensions_.ClearExtension(id.number()); + $extensions$.ClearExtension(id.number()); $annotate_extension_clear$ } @@ -865,7 +870,7 @@ inline int ExtensionSize( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { $annotate_extension_repeated_size$ - return _extensions_.ExtensionSize(id.number()); + return $extensions$.ExtensionSize(id.number()); } template & id) const { $annotate_extension_get$ - return _proto_TypeTraits::Get(id.number(), _extensions_, + return _proto_TypeTraits::Get(id.number(), $extensions$, id.default_value()); } @@ -887,7 +892,7 @@ inline typename _proto_TypeTraits::Singular::MutableType MutableExtension( $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { $annotate_extension_mutable$ return _proto_TypeTraits::Mutable(id.number(), _field_type, - &_extensions_); + &$extensions$); } template & id, typename _proto_TypeTraits::Singular::ConstType value) { - _proto_TypeTraits::Set(id.number(), _field_type, value, &_extensions_); + _proto_TypeTraits::Set(id.number(), _field_type, value, &$extensions$); $annotate_extension_set$ } @@ -909,7 +914,7 @@ inline void SetAllocatedExtension( $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, typename _proto_TypeTraits::Singular::MutableType value) { _proto_TypeTraits::SetAllocated(id.number(), _field_type, value, - &_extensions_); + &$extensions$); $annotate_extension_set$ } template & id, typename _proto_TypeTraits::Singular::MutableType value) { _proto_TypeTraits::UnsafeArenaSetAllocated(id.number(), _field_type, - value, &_extensions_); + value, &$extensions$); $annotate_extension_set$ } template & id) { $annotate_extension_release$ return _proto_TypeTraits::Release(id.number(), _field_type, - &_extensions_); + &$extensions$); } template & id) { $annotate_extension_release$ return _proto_TypeTraits::UnsafeArenaRelease(id.number(), _field_type, - &_extensions_); + &$extensions$); } template & id, int index) const { $annotate_repeated_extension_get$ - return _proto_TypeTraits::Get(id.number(), _extensions_, index); + return _proto_TypeTraits::Get(id.number(), $extensions$, index); } template & id, int index) { $annotate_repeated_extension_mutable$ - return _proto_TypeTraits::Mutable(id.number(), index, &_extensions_); + return _proto_TypeTraits::Mutable(id.number(), index, &$extensions$); } template & id, int index, typename _proto_TypeTraits::Repeated::ConstType value) { - _proto_TypeTraits::Set(id.number(), index, value, &_extensions_); + _proto_TypeTraits::Set(id.number(), index, value, &$extensions$); $annotate_repeated_extension_set$ } @@ -987,7 +992,7 @@ inline typename _proto_TypeTraits::Repeated::MutableType AddExtension( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) { typename _proto_TypeTraits::Repeated::MutableType to_add = - _proto_TypeTraits::Add(id.number(), _field_type, &_extensions_); + _proto_TypeTraits::Add(id.number(), _field_type, &$extensions$); $annotate_repeated_extension_add_mutable$ return to_add; } @@ -1000,7 +1005,7 @@ inline void AddExtension( $classname$, _proto_TypeTraits, _field_type, _is_packed>& id, typename _proto_TypeTraits::Repeated::ConstType value) { _proto_TypeTraits::Add(id.number(), _field_type, _is_packed, value, - &_extensions_); + &$extensions$); $annotate_repeated_extension_add$ } @@ -1012,7 +1017,7 @@ GetRepeatedExtension( const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< $classname$, _proto_TypeTraits, _field_type, _is_packed>& id) const { $annotate_repeated_extension_list$ - return _proto_TypeTraits::GetRepeated(id.number(), _extensions_); + return _proto_TypeTraits::GetRepeated(id.number(), $extensions$); } template & id) { $annotate_repeated_extension_list_mutable$ return _proto_TypeTraits::MutableRepeated(id.number(), _field_type, - _is_packed, &_extensions_); + _is_packed, &$extensions$); } )"); @@ -1061,7 +1066,7 @@ void MessageGenerator::GenerateSingularFieldHasBits( format( "inline bool $classname$::has_$name$() const {\n" "$annotate_has$" - " return _weak_field_map_.Has($number$);\n" + " return $weak_field_map$.Has($number$);\n" "}\n"); return; } @@ -1075,7 +1080,7 @@ void MessageGenerator::GenerateSingularFieldHasBits( format( "inline bool $classname$::_internal_has_$name$() const {\n" " bool value = " - "(_has_bits_[$has_array_index$] & 0x$has_mask$u) != 0;\n"); + "($has_bits$[$has_array_index$] & 0x$has_mask$u) != 0;\n"); if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE && !IsLazy(field, options_, scc_analyzer_)) { @@ -1125,7 +1130,7 @@ void MessageGenerator::GenerateOneofHasBits(io::Printer* printer) { " return $oneof_name$_case() != $cap_oneof_name$_NOT_SET;\n" "}\n" "inline void $classname$::clear_has_$oneof_name$() {\n" - " _oneof_case_[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n" + " $oneof_case$[$oneof_index$] = $cap_oneof_name$_NOT_SET;\n" "}\n"); } } @@ -1171,7 +1176,7 @@ void MessageGenerator::GenerateOneofMemberHasBits(const FieldDescriptor* field, // annotated. format( "inline void $classname$::set_has_$name$() {\n" - " _oneof_case_[$oneof_index$] = k$field_name$;\n" + " $oneof_case$[$oneof_index$] = k$field_name$;\n" "}\n"); } @@ -1206,7 +1211,7 @@ void MessageGenerator::GenerateFieldClear(const FieldDescriptor* field, format.Set("has_array_index", has_bit_index / 32); format.Set("has_mask", strings::Hex(1u << (has_bit_index % 32), strings::ZERO_PAD_8)); - format("_has_bits_[$has_array_index$] &= ~0x$has_mask$u;\n"); + format("$has_bits$[$has_array_index$] &= ~0x$has_mask$u;\n"); } } format("$annotate_clear$"); @@ -1303,7 +1308,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { " ::$proto_ns$::internal::WireFormatLite::$val_wire_type$> " "SuperType;\n" " $classname$();\n" - " explicit constexpr $classname$(\n" + " explicit PROTOBUF_CONSTEXPR $classname$(\n" " ::$proto_ns$::internal::ConstantInitialized);\n" " explicit $classname$(::$proto_ns$::Arena* arena);\n" " void MergeFrom(const $classname$& other);\n" @@ -1400,7 +1405,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { format("~$classname$() override;\n"); } format( - "explicit constexpr " + "explicit PROTOBUF_CONSTEXPR " "$classname$(::$proto_ns$::internal::ConstantInitialized);\n" "\n" "$classname$(const $classname$& from);\n" @@ -1505,16 +1510,16 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { if (HasDescriptorMethods(descriptor_->file(), options_)) { format( "bool PackFrom(const ::$proto_ns$::Message& message) {\n" - " return _any_metadata_.PackFrom(GetArena(), message);\n" + " return $any_metadata$.PackFrom(GetArena(), message);\n" "}\n" "bool PackFrom(const ::$proto_ns$::Message& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " return _any_metadata_.PackFrom(GetArena(), message, " + " return $any_metadata$.PackFrom(GetArena(), message, " "type_url_prefix);\n" "}\n" "bool UnpackTo(::$proto_ns$::Message* message) const {\n" - " return _any_metadata_.UnpackTo(message);\n" + " return $any_metadata$.UnpackTo(message);\n" "}\n" "static bool GetAnyFieldDescriptors(\n" " const ::$proto_ns$::Message& message,\n" @@ -1524,7 +1529,7 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "!std::is_convertible" "::value>::type>\n" "bool PackFrom(const T& message) {\n" - " return _any_metadata_.PackFrom(GetArena(), message);\n" + " return $any_metadata$.PackFrom(GetArena(), message);\n" "}\n" "template " @@ -1532,36 +1537,36 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "bool PackFrom(const T& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " return _any_metadata_.PackFrom(GetArena(), message, " + " return $any_metadata$.PackFrom(GetArena(), message, " "type_url_prefix);" "}\n" "template " "::value>::type>\n" "bool UnpackTo(T* message) const {\n" - " return _any_metadata_.UnpackTo(message);\n" + " return $any_metadata$.UnpackTo(message);\n" "}\n"); } else { format( "template \n" "bool PackFrom(const T& message) {\n" - " return _any_metadata_.PackFrom(GetArena(), message);\n" + " return $any_metadata$.PackFrom(GetArena(), message);\n" "}\n" "template \n" "bool PackFrom(const T& message,\n" " ::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url_prefix) {\n" - " return _any_metadata_.PackFrom(GetArena(), message, " + " return $any_metadata$.PackFrom(GetArena(), message, " "type_url_prefix);\n" "}\n" "template \n" "bool UnpackTo(T* message) const {\n" - " return _any_metadata_.UnpackTo(message);\n" + " return $any_metadata$.UnpackTo(message);\n" "}\n"); } format( "template bool Is() const {\n" - " return _any_metadata_.Is();\n" + " return $any_metadata$.Is();\n" "}\n" "static bool ParseAnyTypeUrl(::PROTOBUF_NAMESPACE_ID::ConstStringParam " "type_url,\n" @@ -1668,7 +1673,8 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { if (!HasSimpleBaseClass(descriptor_, options_)) { format( - "int GetCachedSize() const final { return _cached_size_.Get(); }" + "int GetCachedSize() const final { return " + "$cached_size$.Get(); }" "\n\nprivate:\n" "void SharedCtor();\n" "void SharedDtor();\n" @@ -1701,11 +1707,13 @@ void MessageGenerator::GenerateClassDefinition(io::Printer* printer) { "static void ArenaDtor(void* object);\n" "inline void OnDemandRegisterArenaDtor(::$proto_ns$::Arena* arena) " "override {\n" - " if (arena == nullptr || (_inlined_string_donated_[0] & 0x1u) == " + " if (arena == nullptr || ($inlined_string_donated_array$[0] & " + "0x1u) " + "== " "0) {\n" " return;\n" " }\n" - " _inlined_string_donated_[0] &= 0xFFFFFFFEu;\n" + " $inlined_string_donated_array$[0] &= 0xFFFFFFFEu;\n" " arena->OwnCustomDestructor(this, &$classname$::ArenaDtor);\n" "}\n"); break; @@ -1956,7 +1964,7 @@ void MessageGenerator::GenerateInlineMethods(io::Printer* printer) { "inline $classname$::$camel_oneof_name$Case $classname$::" "${1$$oneof_name$_case$}$() const {\n" " return $classname$::$camel_oneof_name$Case(" - "_oneof_case_[$oneof_index$]);\n" + "$oneof_case$[$oneof_index$]);\n" "}\n", oneof); } @@ -2040,7 +2048,8 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { format.Indent(); if (!has_bit_indices_.empty()) { format( - "using HasBits = decltype(std::declval<$classname$>()._has_bits_);\n"); + "using HasBits = " + "decltype(std::declval<$classname$>().$has_bits$);\n"); } for (auto field : FieldRange(descriptor_)) { field_generators_.get(field).GenerateInternalAccessorDeclarations(printer); @@ -2168,7 +2177,7 @@ void MessageGenerator::GenerateClassMethods(io::Printer* printer) { google::protobuf::FileOptions::LITE_RUNTIME) { format( "::$proto_ns$::AccessListener<$classtype$> " - "$1$::_tracker_(&FullMessageName);\n", + "$1$::$tracker$(&FullMessageName);\n", ClassName(descriptor_)); } } @@ -2178,28 +2187,30 @@ std::pair MessageGenerator::GenerateOffsets( Formatter format(printer, variables_); if (!has_bit_indices_.empty() || IsMapEntryMessage(descriptor_)) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _has_bits_),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $has_bits$),\n"); } else { format("~0u, // no _has_bits_\n"); } format("PROTOBUF_FIELD_OFFSET($classtype$, _internal_metadata_),\n"); if (descriptor_->extension_range_count() > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _extensions_),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $extensions$),\n"); } else { format("~0u, // no _extensions_\n"); } if (descriptor_->real_oneof_decl_count() > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _oneof_case_[0]),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $oneof_case$[0]),\n"); } else { format("~0u, // no _oneof_case_\n"); } if (num_weak_fields_ > 0) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _weak_field_map_),\n"); + format("PROTOBUF_FIELD_OFFSET($classtype$, $weak_field_map$),\n"); } else { format("~0u, // no _weak_field_map_\n"); } if (!inlined_string_indices_.empty()) { - format("PROTOBUF_FIELD_OFFSET($classtype$, _inlined_string_donated_),\n"); + format( + "PROTOBUF_FIELD_OFFSET($classtype$, " + "$inlined_string_donated_array$),\n"); } else { format("~0u, // no _inlined_string_donated_\n"); } @@ -2310,7 +2321,7 @@ void MessageGenerator::GenerateSharedDestructorCode(io::Printer* printer) { } if (num_weak_fields_) { - format("_weak_field_map_.ClearAll();\n"); + format("$weak_field_map$.ClearAll();\n"); } format.Outdent(); format( @@ -2368,7 +2379,7 @@ void MessageGenerator::GenerateConstexprConstructor(io::Printer* printer) { Formatter format(printer, variables_); format( - "constexpr $classname$::$classname$(\n" + "PROTOBUF_CONSTEXPR $classname$::$classname$(\n" " ::_pbi::ConstantInitialized)"); format.Indent(); const char* field_sep = ":"; @@ -2519,16 +2530,16 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { if (NeedsArenaDestructor() == ArenaDtorNeeds::kOnDemand) { format( " if (!is_message_owned) {\n" - " _inlined_string_donated_[0] = ~0u;\n" + " $inlined_string_donated_array$[0] = ~0u;\n" " } else {\n" // We should not register ArenaDtor for MOA. - " _inlined_string_donated_[0] = 0xFFFFFFFEu;\n" + " $inlined_string_donated_array$[0] = 0xFFFFFFFEu;\n" " }\n"); } else { - format(" _inlined_string_donated_[0] = 0xFFFFFFFEu;\n"); + format(" $inlined_string_donated_array$[0] = 0xFFFFFFFEu;\n"); } for (size_t i = 1; i < InlinedStringDonatedSize(); ++i) { - format(" _inlined_string_donated_[$1$] = ~0u;\n", i); + format(" $inlined_string_donated_array$[$1$] = ~0u;\n", i); } format("}\n"); format.Outdent(); @@ -2606,8 +2617,8 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { format( - "_extensions_.MergeFrom(internal_default_instance(), " - "from._extensions_);\n"); + "$extensions$.MergeFrom(internal_default_instance(), " + "from.$extensions$);\n"); } GenerateConstructorBody(printer, processed, true); @@ -2687,7 +2698,7 @@ void MessageGenerator::GenerateStructors(io::Printer* printer) { // Generate SetCachedSize. format( "void $classname$::SetCachedSize(int size) const {\n" - " _cached_size_.Set(size);\n" + " $cached_size$.Set(size);\n" "}\n"); } } @@ -2723,7 +2734,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { "(void) cached_has_bits;\n\n"); if (descriptor_->extension_range_count() > 0) { - format("_extensions_.Clear();\n"); + format("$extensions$.Clear();\n"); } // Collect fields into chunks. Each chunk may have an if() condition that @@ -2796,7 +2807,7 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { if (cached_has_word_index != HasWordIndex(chunk.front())) { cached_has_word_index = HasWordIndex(chunk.front()); - format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index); + format("cached_has_bits = $has_bits$[$1$];\n", cached_has_word_index); } format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str); format.Indent(); @@ -2858,14 +2869,14 @@ void MessageGenerator::GenerateClear(io::Printer* printer) { } if (num_weak_fields_) { - format("_weak_field_map_.ClearAll();\n"); + format("$weak_field_map$.ClearAll();\n"); } // We don't clear donated status. if (!has_bit_indices_.empty()) { // Step 5: Everything else. - format("_has_bits_.Clear();\n"); + format("$has_bits$.Clear();\n"); } std::map vars; @@ -2911,7 +2922,7 @@ void MessageGenerator::GenerateOneofClear(io::Printer* printer) { format.Outdent(); format( "}\n" - "_oneof_case_[$1$] = $2$_NOT_SET;\n", + "$oneof_case$[$1$] = $2$_NOT_SET;\n", i, ToUpper(oneof->name())); format.Outdent(); format( @@ -2931,7 +2942,9 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { if (HasGeneratedMethods(descriptor_->file(), options_)) { if (descriptor_->extension_range_count() > 0) { - format("_extensions_.InternalSwap(&other->_extensions_);\n"); + format( + "$extensions$.InternalSwap(&other->$extensions$);" + "\n"); } std::map vars; @@ -2946,7 +2959,7 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { if (!has_bit_indices_.empty()) { for (int i = 0; i < HasBitsSize(); ++i) { - format("swap(_has_bits_[$1$], other->_has_bits_[$1$]);\n", i); + format("swap($has_bits$[$1$], other->$has_bits$[$1$]);\n", i); } } @@ -2993,18 +3006,23 @@ void MessageGenerator::GenerateSwap(io::Printer* printer) { } for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) { - format("swap(_oneof_case_[$1$], other->_oneof_case_[$1$]);\n", i); + format( + "swap($oneof_case$[$1$], " + "other->$oneof_case$[$1$]);\n", + i); } if (num_weak_fields_) { - format("_weak_field_map_.UnsafeArenaSwap(&other->_weak_field_map_);\n"); + format( + "$weak_field_map$.UnsafeArenaSwap(&other->$weak_field_map$)" + ";\n"); } if (!inlined_string_indices_.empty()) { for (size_t i = 0; i < InlinedStringDonatedSize(); ++i) { format( - "swap(_inlined_string_donated_[$1$], " - "other->_inlined_string_donated_[$1$]);\n", + "swap($inlined_string_donated_array$[$1$], " + "other->$inlined_string_donated_array$[$1$]);\n", i); } } @@ -3119,7 +3137,7 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { if (cached_has_word_index != HasWordIndex(chunk.front())) { cached_has_word_index = HasWordIndex(chunk.front()); - format("cached_has_bits = from._has_bits_[$1$];\n", + format("cached_has_bits = from.$has_bits$[$1$];\n", cached_has_word_index); } @@ -3180,7 +3198,7 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { if (deferred_has_bit_changes) { // Flush the has bits for the primitives we deferred. GOOGLE_CHECK_LE(0, cached_has_word_index); - format("_has_bits_[$1$] |= cached_has_bits;\n", cached_has_word_index); + format("$has_bits$[$1$] |= cached_has_bits;\n", cached_has_word_index); } format.Outdent(); @@ -3216,15 +3234,17 @@ void MessageGenerator::GenerateClassSpecificMergeFrom(io::Printer* printer) { format("}\n"); } if (num_weak_fields_) { - format("_weak_field_map_.MergeFrom(from._weak_field_map_);\n"); + format( + "$weak_field_map$.MergeFrom(from.$weak_field_map$);" + "\n"); } // Merging of extensions and unknown fields is done last, to maximize // the opportunity for tail calls. if (descriptor_->extension_range_count() > 0) { format( - "_extensions_.MergeFrom(internal_default_instance(), " - "from._extensions_);\n"); + "$extensions$.MergeFrom(internal_default_instance(), " + "from.$extensions$);\n"); } format( @@ -3360,7 +3380,7 @@ void MessageGenerator::GenerateSerializeOneExtensionRange( Formatter format(printer, vars); format("// Extension range [$start$, $end$)\n"); format( - "target = _extensions_._InternalSerialize(\n" + "target = $extensions$._InternalSerialize(\n" "internal_default_instance(), $start$, $end$, target, stream);\n\n"); } @@ -3375,7 +3395,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesToArray( " $uint8$* target, ::$proto_ns$::io::EpsCopyOutputStream* stream) " "const {\n" "$annotate_serialize$" - " target = _extensions_." + " target = $extensions$." "InternalSerializeMessageSetWithCachedSizesToArray(\n" // "internal_default_instance(), target, stream);\n"); std::map vars; @@ -3578,7 +3598,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBody( if (num_weak_fields_) { format( "::_pbi::WeakFieldMap::FieldWriter field_writer(" - "_weak_field_map_);\n"); + "$weak_field_map$);\n"); } format( @@ -3668,7 +3688,7 @@ void MessageGenerator::GenerateSerializeWithCachedSizesBodyShuffled( if (num_weak_fields_) { format( "::_pbi::WeakFieldMap::FieldWriter field_writer(" - "_weak_field_map_);\n"); + "$weak_field_map$);\n"); } format("for (int i = $1$; i >= 0; i-- ) {\n", num_fields - 1); @@ -3759,7 +3779,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { "size_t $classname$::ByteSizeLong() const {\n" "$annotate_bytesize$" "// @@protoc_insertion_point(message_set_byte_size_start:$full_name$)\n" - " size_t total_size = _extensions_.MessageSetByteSize();\n" + " size_t total_size = $extensions$.MessageSetByteSize();\n" " if ($have_unknown_fields$) {\n" " total_size += ::_pbi::\n" " ComputeUnknownMessageSetItemsSize($unknown_fields$);\n" @@ -3812,7 +3832,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { format( - "total_size += _extensions_.ByteSize();\n" + "total_size += $extensions$.ByteSize();\n" "\n"); } @@ -3893,7 +3913,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { if (cached_has_word_index != HasWordIndex(chunk.front())) { cached_has_word_index = HasWordIndex(chunk.front()); - format("cached_has_bits = _has_bits_[$1$];\n", cached_has_word_index); + format("cached_has_bits = $has_bits$[$1$];\n", cached_has_word_index); } format("if (cached_has_bits & 0x$1$u) {\n", chunk_mask_str); format.Indent(); @@ -3973,7 +3993,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { if (num_weak_fields_) { // TagSize + MessageSize - format("total_size += _weak_field_map_.ByteSizeLong();\n"); + format("total_size += $weak_field_map$.ByteSizeLong();\n"); } if (UseUnknownFieldSet(descriptor_->file(), options_)) { @@ -3981,7 +4001,7 @@ void MessageGenerator::GenerateByteSize(io::Printer* printer) { // unknown fields in tail position. This allows for better code generation // of this function for simple protos. format( - "return MaybeComputeUnknownFieldsSize(total_size, &_cached_size_);\n"); + "return MaybeComputeUnknownFieldsSize(total_size, &$cached_size$);\n"); } else { format("if (PROTOBUF_PREDICT_FALSE($have_unknown_fields$)) {\n"); format(" total_size += $unknown_fields$.size();\n"); @@ -4013,14 +4033,14 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { if (descriptor_->extension_range_count() > 0) { format( - "if (!_extensions_.IsInitialized()) {\n" + "if (!$extensions$.IsInitialized()) {\n" " return false;\n" "}\n\n"); } if (num_required_fields_ > 0) { format( - "if (_Internal::MissingRequiredFields(_has_bits_))" + "if (_Internal::MissingRequiredFields($has_bits$))" " return false;\n"); } @@ -4030,7 +4050,7 @@ void MessageGenerator::GenerateIsInitialized(io::Printer* printer) { } if (num_weak_fields_) { // For Weak fields. - format("if (!_weak_field_map_.IsInitialized()) return false;\n"); + format("if (!$weak_field_map$.IsInitialized()) return false;\n"); } // Go through the oneof fields, emitting a switch if any might have required // fields. diff --git a/src/google/protobuf/compiler/cpp/cpp_options.h b/src/google/protobuf/compiler/cpp/cpp_options.h index aaecda58eb..c407c0540b 100644 --- a/src/google/protobuf/compiler/cpp/cpp_options.h +++ b/src/google/protobuf/compiler/cpp/cpp_options.h @@ -82,6 +82,7 @@ struct Options { bool unverified_lazy_message_sets = true; bool eagerly_verified_lazy = true; bool profile_driven_inline_string = true; + bool force_split = false; #ifdef PROTOBUF_STABLE_EXPERIMENTS bool force_eagerly_verified_lazy = true; bool force_inline_string = true; diff --git a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc index 0983b5c07c..e9b48cd92d 100644 --- a/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc +++ b/src/google/protobuf/compiler/cpp/cpp_parse_function_generator.cc @@ -450,6 +450,7 @@ ParseFunctionGenerator::ParseFunctionGenerator( inlined_string_indices, scc_analyzer)); } SetCommonVars(options_, &variables_); + SetCommonMessageDataVariables(&variables_); SetUnknownFieldsVariable(descriptor_, options_, &variables_); variables_["classname"] = ClassName(descriptor, false); } @@ -491,7 +492,7 @@ void ParseFunctionGenerator::GenerateMethodImpls(io::Printer* printer) { " ctx->set_lazy_eager_verify_func(&$classname$::InternalVerify);\n"); } format( - " return _extensions_.ParseMessageSet(ptr, \n" + " return $extensions$.ParseMessageSet(ptr, \n" " internal_default_instance(), &_internal_metadata_, ctx);\n" "}\n"); } @@ -785,7 +786,7 @@ void ParseFunctionGenerator::GenerateTailCallTable(Formatter& format) { } if (descriptor_->extension_range_count() == 1) { format( - "PROTOBUF_FIELD_OFFSET($classname$, _extensions_),\n" + "PROTOBUF_FIELD_OFFSET($classname$, $extensions$),\n" "$1$, $2$, // extension_range_{low,high}\n", descriptor_->extension_range(0)->start, descriptor_->extension_range(0)->end); @@ -1131,7 +1132,7 @@ void ParseFunctionGenerator::GenerateArenaString(Formatter& format, GOOGLE_DCHECK(!inlined_string_indices_.empty()); int inlined_string_index = inlined_string_indices_[field->index()]; GOOGLE_DCHECK_GT(inlined_string_index, 0); - format(", &$msg$_inlined_string_donated_[0], $1$, $this$", + format(", &$msg$$inlined_string_donated_array$[0], $1$, $this$", inlined_string_index); } else { GOOGLE_DCHECK(field->default_value_string().empty()); @@ -1318,7 +1319,7 @@ void ParseFunctionGenerator::GenerateLengthDelim(Formatter& format, format( "{\n" " auto* default_ = &reinterpret_cast($1$);\n" - " ptr = ctx->ParseMessage($msg$_weak_field_map_.MutableMessage(" + " ptr = ctx->ParseMessage($msg$$weak_field_map$.MutableMessage(" "$2$, default_), ptr);\n" "}\n", QualifiedDefaultInstanceName(field->message_type(), options_), @@ -1533,7 +1534,7 @@ void ParseFunctionGenerator::GenerateParseIterationBody( } format( ") {\n" - " ptr = $msg$_extensions_.ParseField(tag, ptr, " + " ptr = $msg$$extensions$.ParseField(tag, ptr, " "internal_default_instance(), &$msg$_internal_metadata_, ctx);\n" " CHK_(ptr != nullptr);\n" " $next_tag$;\n" diff --git a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc index 53661d6e34..cef623c991 100644 --- a/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_primitive_field.cc @@ -104,6 +104,9 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, SetCommonFieldVariables(descriptor, variables, options); (*variables)["type"] = PrimitiveTypeName(options, descriptor->cpp_type()); (*variables)["default"] = DefaultValue(options, descriptor); + (*variables)["cached_byte_size_name"] = MakeVarintCachedSizeName(descriptor); + (*variables)["cached_byte_size_field"] = + MakeVarintCachedSizeFieldName(descriptor); (*variables)["tag"] = StrCat(internal::WireFormat::MakeTag(descriptor)); int fixed_size = FixedSize(descriptor->type()); if (fixed_size != -1) { @@ -313,7 +316,7 @@ void RepeatedPrimitiveFieldGenerator::GeneratePrivateMembers( format("::$proto_ns$::RepeatedField< $type$ > $name$_;\n"); if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 && HasGeneratedMethods(descriptor_->file(), options_)) { - format("mutable std::atomic _$name$_cached_byte_size_;\n"); + format("mutable std::atomic $cached_byte_size_name$;\n"); } } @@ -412,7 +415,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateSerializeWithCachedSizesToArray( format( "{\n" " int byte_size = " - "_$name$_cached_byte_size_.load(std::memory_order_relaxed);\n" + "$cached_byte_size_field$.load(std::memory_order_relaxed);\n" " if (byte_size > 0) {\n" " target = stream->Write$declared_type$Packed(\n" " $number$, _internal_$name$(), byte_size, target);\n" @@ -462,7 +465,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateByteSize( if (FixedSize(descriptor_->type()) == -1) { format( "int cached_size = ::_pbi::ToCachedSize(data_size);\n" - "_$name$_cached_byte_size_.store(cached_size,\n" + "$cached_byte_size_field$.store(cached_size,\n" " std::memory_order_relaxed);\n"); } format("total_size += data_size;\n"); @@ -483,7 +486,7 @@ void RepeatedPrimitiveFieldGenerator::GenerateConstinitInitializer( format("$name$_()"); if (descriptor_->is_packed() && FixedSize(descriptor_->type()) == -1 && HasGeneratedMethods(descriptor_->file(), options_)) { - format("\n, _$name$_cached_byte_size_(0)"); + format("\n, $cached_byte_size_name$(0)"); } } diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc index 49bacb776e..41daed221f 100644 --- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc +++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc @@ -418,9 +418,9 @@ void StringFieldGenerator::GenerateSwappingCode(io::Printer* printer) const { format( "::$proto_ns$::internal::InlinedStringField::InternalSwap(\n" " &$field$, lhs_arena, " - "(_inlined_string_donated_[0] & 0x1u) == 0, this,\n" + "($inlined_string_donated_array$[0] & 0x1u) == 0, this,\n" " &other->$field$, rhs_arena, " - "(other->_inlined_string_donated_[0] & 0x1u) == 0, other);\n"); + "(other->$inlined_string_donated_array$[0] & 0x1u) == 0, other);\n"); } } diff --git a/src/google/protobuf/compiler/java/java_message.cc b/src/google/protobuf/compiler/java/java_message.cc index 3f27c59705..9918abc04f 100644 --- a/src/google/protobuf/compiler/java/java_message.cc +++ b/src/google/protobuf/compiler/java/java_message.cc @@ -1505,8 +1505,7 @@ void ImmutableMessageGenerator::GenerateTopLevelKotlinMembers( void ImmutableMessageGenerator::GenerateKotlinOrNull(io::Printer* printer) const { for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->has_optional_keyword() && - GetJavaType(field) == JAVATYPE_MESSAGE) { + if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) { printer->Print( "val $full_classname$OrBuilder.$camelcase_name$OrNull: $full_name$?\n" " get() = if (has$name$()) get$name$() else null\n\n", diff --git a/src/google/protobuf/compiler/java/java_message_lite.cc b/src/google/protobuf/compiler/java/java_message_lite.cc index 0fc9fd0f1f..8073bac090 100644 --- a/src/google/protobuf/compiler/java/java_message_lite.cc +++ b/src/google/protobuf/compiler/java/java_message_lite.cc @@ -825,8 +825,7 @@ void ImmutableMessageLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) c // Generate getFieldOrNull getters for all optional message fields. for (int i = 0; i < descriptor_->field_count(); i++) { const FieldDescriptor* field = descriptor_->field(i); - if (field->has_optional_keyword() && - GetJavaType(field) == JAVATYPE_MESSAGE) { + if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) { printer->Print( "val $full_classname$OrBuilder.$camelcase_name$OrNull: " "$full_name$?\n" diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc index ff69f39f48..cdb208065e 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.cc @@ -65,9 +65,8 @@ void SetEnumVariables(const FieldDescriptor* descriptor, } } // namespace -EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { +EnumFieldGenerator::EnumFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { SetEnumVariables(descriptor, &variables_); } @@ -129,8 +128,8 @@ void EnumFieldGenerator::DetermineForwardDeclarations( } RepeatedEnumFieldGenerator::RepeatedEnumFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetEnumVariables(descriptor, &variables_); variables_["array_storage_type"] = "GPBEnumArray"; } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h index 3fb0a9fd11..f89107e857 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_enum_field.h @@ -41,8 +41,7 @@ namespace compiler { namespace objectivec { class EnumFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); EnumFieldGenerator(const EnumFieldGenerator&) = delete; EnumFieldGenerator& operator=(const EnumFieldGenerator&) = delete; @@ -56,20 +55,18 @@ class EnumFieldGenerator : public SingleFieldGenerator { std::set* fwd_decls) const override; protected: - EnumFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + EnumFieldGenerator(const FieldDescriptor* descriptor); virtual ~EnumFieldGenerator(); }; class RepeatedEnumFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); public: virtual void FinishInitialization() override; protected: - RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedEnumFieldGenerator(); }; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_field.cc index eb23fee19f..2500f37dd0 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.cc @@ -118,40 +118,39 @@ void SetCommonFieldVariables(const FieldDescriptor* descriptor, } // namespace -FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options) { +FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field) { FieldGenerator* result = NULL; if (field->is_repeated()) { switch (GetObjectiveCType(field)) { case OBJECTIVECTYPE_MESSAGE: { if (field->is_map()) { - result = new MapFieldGenerator(field, options); + result = new MapFieldGenerator(field); } else { - result = new RepeatedMessageFieldGenerator(field, options); + result = new RepeatedMessageFieldGenerator(field); } break; } case OBJECTIVECTYPE_ENUM: - result = new RepeatedEnumFieldGenerator(field, options); + result = new RepeatedEnumFieldGenerator(field); break; default: - result = new RepeatedPrimitiveFieldGenerator(field, options); + result = new RepeatedPrimitiveFieldGenerator(field); break; } } else { switch (GetObjectiveCType(field)) { case OBJECTIVECTYPE_MESSAGE: { - result = new MessageFieldGenerator(field, options); + result = new MessageFieldGenerator(field); break; } case OBJECTIVECTYPE_ENUM: - result = new EnumFieldGenerator(field, options); + result = new EnumFieldGenerator(field); break; default: if (IsReferenceType(field)) { - result = new PrimitiveObjFieldGenerator(field, options); + result = new PrimitiveObjFieldGenerator(field); } else { - result = new PrimitiveFieldGenerator(field, options); + result = new PrimitiveFieldGenerator(field); } break; } @@ -160,8 +159,7 @@ FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, return result; } -FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor, - const Options& options) +FieldGenerator::FieldGenerator(const FieldDescriptor* descriptor) : descriptor_(descriptor) { SetCommonFieldVariables(descriptor, &variables_); } @@ -266,9 +264,8 @@ void FieldGenerator::FinishInitialization(void) { } } -SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : FieldGenerator(descriptor, options) { +SingleFieldGenerator::SingleFieldGenerator(const FieldDescriptor* descriptor) + : FieldGenerator(descriptor) { // Nothing } @@ -310,9 +307,8 @@ bool SingleFieldGenerator::RuntimeUsesHasBit(void) const { return true; } -ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : SingleFieldGenerator(descriptor, options) { +ObjCObjFieldGenerator::ObjCObjFieldGenerator(const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { variables_["property_storage_attribute"] = "strong"; if (IsRetainedName(variables_["name"])) { variables_["storage_attribute"] = " NS_RETURNS_NOT_RETAINED"; @@ -353,8 +349,8 @@ void ObjCObjFieldGenerator::GeneratePropertyDeclaration( } RepeatedFieldGenerator::RepeatedFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { // Default to no comment and let the cases needing it fill it in. variables_["array_comment"] = ""; } @@ -407,19 +403,18 @@ bool RepeatedFieldGenerator::RuntimeUsesHasBit(void) const { return false; // The array (or map/dict) having anything is what is used. } -FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor, - const Options& options) +FieldGeneratorMap::FieldGeneratorMap(const Descriptor* descriptor) : descriptor_(descriptor), field_generators_(descriptor->field_count()), extension_generators_(descriptor->extension_count()) { // Construct all the FieldGenerators. for (int i = 0; i < descriptor->field_count(); i++) { field_generators_[i].reset( - FieldGenerator::Make(descriptor->field(i), options)); + FieldGenerator::Make(descriptor->field(i))); } for (int i = 0; i < descriptor->extension_count(); i++) { extension_generators_[i].reset( - FieldGenerator::Make(descriptor->extension(i), options)); + FieldGenerator::Make(descriptor->extension(i))); } } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_field.h b/src/google/protobuf/compiler/objectivec/objectivec_field.h index ad8e55aeb2..c5080d6ba6 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_field.h @@ -33,7 +33,6 @@ #include #include -#include #include #include @@ -44,8 +43,7 @@ namespace objectivec { class FieldGenerator { public: - static FieldGenerator* Make(const FieldDescriptor* field, - const Options& options); + static FieldGenerator* Make(const FieldDescriptor* field); virtual ~FieldGenerator(); @@ -96,7 +94,7 @@ class FieldGenerator { std::string raw_field_name() const { return variable("raw_field_name"); } protected: - FieldGenerator(const FieldDescriptor* descriptor, const Options& options); + FieldGenerator(const FieldDescriptor* descriptor); virtual void FinishInitialization(void); bool WantsHasProperty(void) const; @@ -120,8 +118,7 @@ class SingleFieldGenerator : public FieldGenerator { virtual bool RuntimeUsesHasBit(void) const override; protected: - SingleFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + SingleFieldGenerator(const FieldDescriptor* descriptor); }; // Subclass with common support for when the field ends up as an ObjC Object. @@ -136,8 +133,7 @@ class ObjCObjFieldGenerator : public SingleFieldGenerator { virtual void GeneratePropertyDeclaration(io::Printer* printer) const override; protected: - ObjCObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + ObjCObjFieldGenerator(const FieldDescriptor* descriptor); }; class RepeatedFieldGenerator : public ObjCObjFieldGenerator { @@ -155,15 +151,14 @@ class RepeatedFieldGenerator : public ObjCObjFieldGenerator { virtual bool RuntimeUsesHasBit(void) const override; protected: - RepeatedFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedFieldGenerator(const FieldDescriptor* descriptor); virtual void FinishInitialization(void) override; }; // Convenience class which constructs FieldGenerators for a Descriptor. class FieldGeneratorMap { public: - FieldGeneratorMap(const Descriptor* descriptor, const Options& options); + FieldGeneratorMap(const Descriptor* descriptor); ~FieldGeneratorMap(); FieldGeneratorMap(const FieldGeneratorMap&) = delete; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index d9f43a55c7..163639701d 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -185,18 +186,19 @@ bool IsDirectDependency(const FileDescriptor* dep, const FileDescriptor* file) { } // namespace -FileGenerator::FileGenerator(const FileDescriptor* file, const Options& options) +FileGenerator::FileGenerator(const FileDescriptor* file, + const GenerationOptions& generation_options) : file_(file), + generation_options_(generation_options), root_class_name_(FileClassName(file)), - is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)), - options_(options) { + is_bundled_proto_(IsProtobufLibraryBundledProtoFile(file)) { for (int i = 0; i < file_->enum_type_count(); i++) { EnumGenerator* generator = new EnumGenerator(file_->enum_type(i)); enum_generators_.emplace_back(generator); } for (int i = 0; i < file_->message_type_count(); i++) { MessageGenerator* generator = - new MessageGenerator(root_class_name_, file_->message_type(i), options_); + new MessageGenerator(root_class_name_, file_->message_type(i)); message_generators_.emplace_back(generator); } for (int i = 0; i < file_->extension_count(); i++) { @@ -240,10 +242,10 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { // #import any headers for "public imports" in the proto file. { ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); + generation_options_.generate_for_named_framework, + generation_options_.named_framework_to_proto_path_mappings_path, + generation_options_.runtime_import_prefix, + /* include_wkt_imports = */ false); const std::string header_extension(kHeaderExtension); for (int i = 0; i < file_->public_dependency_count(); i++) { import_writer.AddFile(file_->public_dependency(i), header_extension); @@ -338,8 +340,17 @@ void FileGenerator::GenerateHeader(io::Printer* printer) { void FileGenerator::GenerateSource(io::Printer* printer) { // #import the runtime support. + const std::string header_extension(kHeaderExtension); std::vector headers; headers.push_back("GPBProtocolBuffers_RuntimeSupport.h"); + if (is_bundled_proto_) { + headers.push_back("GPB" + FilePathBasename(file_) + header_extension); + for (int i = 0; i < file_->dependency_count(); i++) { + const std::string header_name = + "GPB" + FilePathBasename(file_->dependency(i)) + header_extension; + headers.push_back(header_name); + } + } PrintFileRuntimePreamble(printer, headers); // Enums use atomic in the generated code, so add the system import as needed. @@ -354,11 +365,10 @@ void FileGenerator::GenerateSource(io::Printer* printer) { { ImportWriter import_writer( - options_.generate_for_named_framework, - options_.named_framework_to_proto_path_mappings_path, - options_.runtime_import_prefix, - is_bundled_proto_); - const std::string header_extension(kHeaderExtension); + generation_options_.generate_for_named_framework, + generation_options_.named_framework_to_proto_path_mappings_path, + generation_options_.runtime_import_prefix, + /* include_wkt_imports = */ false); // #import the header for this proto file. import_writer.AddFile(file_, header_extension); @@ -599,8 +609,26 @@ void FileGenerator::PrintFileRuntimePreamble( "// source: $filename$\n" "\n", "filename", file_->name()); - ImportWriter::PrintRuntimeImports( - printer, headers_to_import, options_.runtime_import_prefix, true); + + if (is_bundled_proto_) { + // This is basically a clone of ImportWriter::PrintRuntimeImports() but + // without the CPP symbol gate, since within the bundled files, that isn't + // needed. + std::string import_prefix = generation_options_.runtime_import_prefix; + if (!import_prefix.empty()) { + import_prefix += "/"; + } + for (const auto& header : headers_to_import) { + printer->Print( + "#import \"$import_prefix$$header$\"\n", + "import_prefix", import_prefix, + "header", header); + } + } else { + ImportWriter::PrintRuntimeImports( + printer, headers_to_import, generation_options_.runtime_import_prefix, true); + } + printer->Print("\n"); } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.h b/src/google/protobuf/compiler/objectivec/objectivec_file.h index 87258a39fe..fc71c70c9d 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.h @@ -34,7 +34,6 @@ #include #include #include -#include #include #include @@ -49,7 +48,15 @@ class MessageGenerator; class FileGenerator { public: - FileGenerator(const FileDescriptor* file, const Options& options); + struct GenerationOptions { + GenerationOptions() {} + std::string generate_for_named_framework; + std::string named_framework_to_proto_path_mappings_path; + std::string runtime_import_prefix; + }; + + FileGenerator(const FileDescriptor* file, + const GenerationOptions& generation_options); ~FileGenerator(); FileGenerator(const FileGenerator&) = delete; @@ -60,6 +67,7 @@ class FileGenerator { private: const FileDescriptor* file_; + const GenerationOptions& generation_options_; std::string root_class_name_; bool is_bundled_proto_; @@ -67,8 +75,6 @@ class FileGenerator { std::vector> message_generators_; std::vector> extension_generators_; - const Options options_; - void PrintFileRuntimePreamble( io::Printer* printer, const std::vector& headers_to_import) const; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index b6f53a5a9f..e0279a1d2e 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -94,7 +94,8 @@ bool ObjectiveCGenerator::GenerateAll( // // e.g. protoc ... --objc_opt=expected_prefixes=file.txt,generate_for_named_framework=MyFramework - Options generation_options; + Options validation_options; + FileGenerator::GenerationOptions generation_options; std::vector > options; ParseGeneratorParameter(parameter, &options); @@ -116,14 +117,14 @@ bool ObjectiveCGenerator::GenerateAll( // // There is no validation that the prefixes are good prefixes, it is // assumed that they are when you create the file. - generation_options.expected_prefixes_path = options[i].second; + validation_options.expected_prefixes_path = options[i].second; } else if (options[i].first == "expected_prefixes_suppressions") { // A semicolon delimited string that lists the paths of .proto files to // exclude from the package prefix validations (expected_prefixes_path). // This is provided as an "out", to skip some files being checked. for (StringPiece split_piece : Split( options[i].second, ";", true)) { - generation_options.expected_prefixes_suppressions.push_back( + validation_options.expected_prefixes_suppressions.push_back( std::string(split_piece)); } } else if (options[i].first == "prefixes_must_be_registered") { @@ -135,7 +136,7 @@ bool ObjectiveCGenerator::GenerateAll( // tried to use a prefix that isn't registered. // Default is "no". if (!StringToBool(options[i].second, - &generation_options.prefixes_must_be_registered)) { + &validation_options.prefixes_must_be_registered)) { *error = "error: Unknown value for prefixes_must_be_registered: " + options[i].second; return false; } @@ -147,7 +148,7 @@ bool ObjectiveCGenerator::GenerateAll( // raised if a files doesn't have one. // Default is "no". if (!StringToBool(options[i].second, - &generation_options.require_prefixes)) { + &validation_options.require_prefixes)) { *error = "error: Unknown value for require_prefixes: " + options[i].second; return false; } @@ -190,20 +191,25 @@ bool ObjectiveCGenerator::GenerateAll( // header search path since the generate #import will be more complete. generation_options.runtime_import_prefix = StripSuffixString(options[i].second, "/"); - } else if (options[i].first == "default_objc_class_prefix") { - // The default objc class prefix to use if specified by the command line - // invocation. The file option is always honored first if one is present. - std::string value = options[i].second; - if (value.empty()) { - *error = "error: default_objc_class_prefix cannot be empty."; - return false; - } - SetDefaultObjcClassPrefix(value); + } else if (options[i].first == "package_to_prefix_mappings_path") { + // Path to use for when loading the objc class prefix mappings to use. + // The `objc_class_prefix` file option is always honored first if one is present. + // This option also has precedent over the use_package_as_prefix option. + // + // The format of the file is: + // - An entry is a line of "package=prefix". + // - Comments start with "#". + // - A comment can go on a line after a expected package/prefix pair. + // (i.e. - "package=prefix # comment") + // - For files that do NOT have a proto package (not recommended), an + // entry can be made as "no_package:PATH=prefix", where PATH is the + // path for the .proto file. + // + SetPackageToPrefixMappingsPath(options[i].second); } else if (options[i].first == "use_package_as_prefix") { // Controls how the symbols should be prefixed to avoid symbols - // collisions. The objc_class_prefix file option is always honored first - // followed by the default_objc_class_prefix generator option. This is is just - // what to do if either of these options are not set. The available options are: + // collisions. The objc_class_prefix file option is always honored, this + // is just what to do if that isn't set. The available options are: // "no": Not prefixed (the existing mode). // "yes": Make a prefix out of the proto package. bool value = false; @@ -253,7 +259,7 @@ bool ObjectiveCGenerator::GenerateAll( // ----------------------------------------------------------------- // Validate the objc prefix/package pairings. - if (!ValidateObjCClassPrefixes(files, generation_options, error)) { + if (!ValidateObjCClassPrefixes(files, validation_options, error)) { // *error will have been filled in. return false; } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 7b85c517f2..b15f580954 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -95,12 +95,30 @@ class SimpleLineCollector : public LineConsumer { std::unordered_set* set_; }; +class PackageToPrefixesCollector : public LineConsumer { + public: + PackageToPrefixesCollector(const std::string &usage, + std::map* inout_package_to_prefix_map) + : usage_(usage), prefix_map_(inout_package_to_prefix_map) {} + + virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override; + + private: + const std::string usage_; + std::map* prefix_map_; +}; + class PrefixModeStorage { public: PrefixModeStorage(); - const std::string default_objc_class_prefix() const { return default_objc_class_prefix_; } - void set_default_objc_class_prefix(const std::string& default_objc_class_prefix) { default_objc_class_prefix_ = default_objc_class_prefix; } + const std::string package_to_prefix_mappings_path() const { return package_to_prefix_mappings_path_; } + void set_package_to_prefix_mappings_path(const std::string& path) { + package_to_prefix_mappings_path_ = path; + package_to_prefix_map_.clear(); + } + + std::string prefix_from_proto_package_mappings(const FileDescriptor* file); bool use_package_name() const { return use_package_name_; } void set_use_package_name(bool on_or_off) { use_package_name_ = on_or_off; } @@ -119,14 +137,15 @@ class PrefixModeStorage { private: bool use_package_name_; - std::string default_objc_class_prefix_; + std::map package_to_prefix_map_; + std::string package_to_prefix_mappings_path_; std::string exception_path_; std::string forced_prefix_; std::unordered_set exceptions_; }; PrefixModeStorage::PrefixModeStorage() { - // Even though there are generation options, have an env back door since some + // Even thought there are generation options, have an env back door since some // of these helpers could be used in other plugins. use_package_name_ = BoolFromEnvVar("GPB_OBJC_USE_PACKAGE_AS_PREFIX", false); @@ -144,6 +163,44 @@ PrefixModeStorage::PrefixModeStorage() { } } +std::string PrefixModeStorage::prefix_from_proto_package_mappings(const FileDescriptor* file) { + if (!file) { + return ""; + } + + if (package_to_prefix_map_.empty() && !package_to_prefix_mappings_path_.empty()) { + std::string error_str; + // Re use the same collector as we use for expected_prefixes_path since the file + // format is the same. + PackageToPrefixesCollector collector("Package to prefixes", &package_to_prefix_map_); + if (!ParseSimpleFile(package_to_prefix_mappings_path_, &collector, &error_str)) { + if (error_str.empty()) { + error_str = std::string("protoc:0: warning: Failed to parse") + + std::string(" prefix to proto package mappings file: ") + + package_to_prefix_mappings_path_; + } + std::cerr << error_str << std::endl; + std::cerr.flush(); + package_to_prefix_map_.clear(); + } + } + + const std::string package = file->package(); + // For files without packages, the can be registered as "no_package:PATH", + // allowing the expected prefixes file. + static const std::string no_package_prefix("no_package:"); + const std::string lookup_key = package.empty() ? no_package_prefix + file->name() : package; + + std::map::const_iterator prefix_lookup = + package_to_prefix_map_.find(lookup_key); + + if (prefix_lookup != package_to_prefix_map_.end()) { + return prefix_lookup->second; + } + + return ""; +} + bool PrefixModeStorage::is_package_exempted(const std::string& package) { if (exceptions_.empty() && !exception_path_.empty()) { std::string error_str; @@ -173,8 +230,12 @@ PrefixModeStorage g_prefix_mode; } // namespace -void SetDefaultObjcClassPrefix(const std::string& default_objc_class_prefix) { - g_prefix_mode.set_default_objc_class_prefix(default_objc_class_prefix); +std::string GetPackageToPrefixMappingsPath() { + return g_prefix_mode.package_to_prefix_mappings_path(); +} + +void SetPackageToPrefixMappingsPath(const std::string& file_path) { + g_prefix_mode.set_package_to_prefix_mappings_path(file_path); } bool UseProtoPackageAsDefaultPrefix() { @@ -534,14 +595,15 @@ std::string BaseFileName(const FileDescriptor* file) { } std::string FileClassPrefix(const FileDescriptor* file) { - // Always honor the file option first. + // Always honor the file option. if (file->options().has_objc_class_prefix()) { return file->options().objc_class_prefix(); } - // If a default prefix is passed through objc_opt then accept it. - if (!g_prefix_mode.default_objc_class_prefix().empty()) { - return g_prefix_mode.default_objc_class_prefix(); + // If package prefix is specified in an prefix to proto mappings file then use that. + std::string objc_class_prefix = g_prefix_mode.prefix_from_proto_package_mappings(file); + if (!objc_class_prefix.empty()) { + return objc_class_prefix; } // If package prefix isn't enabled, done. @@ -1218,23 +1280,11 @@ void RemoveComment(StringPiece* input) { namespace { -class ExpectedPrefixesCollector : public LineConsumer { - public: - ExpectedPrefixesCollector(std::map* inout_package_to_prefix_map) - : prefix_map_(inout_package_to_prefix_map) {} - - virtual bool ConsumeLine(const StringPiece& line, std::string* out_error) override; - - private: - std::map* prefix_map_; -}; - -bool ExpectedPrefixesCollector::ConsumeLine( +bool PackageToPrefixesCollector::ConsumeLine( const StringPiece& line, std::string* out_error) { int offset = line.find('='); if (offset == StringPiece::npos) { - *out_error = std::string("Expected prefixes file line without equal sign: '") + - std::string(line) + "'."; + *out_error = usage_ + " file line without equal sign: '" + StrCat(line) + "'."; return false; } StringPiece package = line.substr(0, offset); @@ -1248,16 +1298,16 @@ bool ExpectedPrefixesCollector::ConsumeLine( return true; } -bool LoadExpectedPackagePrefixes(const Options& generation_options, +bool LoadExpectedPackagePrefixes(const std::string& expected_prefixes_path, std::map* prefix_map, std::string* out_error) { - if (generation_options.expected_prefixes_path.empty()) { + if (expected_prefixes_path.empty()) { return true; } - ExpectedPrefixesCollector collector(prefix_map); + PackageToPrefixesCollector collector("Expected prefixes", prefix_map); return ParseSimpleFile( - generation_options.expected_prefixes_path, &collector, out_error); + expected_prefixes_path, &collector, out_error); } bool ValidateObjCClassPrefix( @@ -1404,6 +1454,13 @@ bool ValidateObjCClassPrefix( } // namespace +bool ValidateObjCClassPrefixes(const std::vector& files, + std::string* out_error) { + // Options's ctor load from the environment. + Options options; + return ValidateObjCClassPrefixes(files, options, out_error); +} + bool ValidateObjCClassPrefixes(const std::vector& files, const Options& generation_options, std::string* out_error) { @@ -1415,7 +1472,7 @@ bool ValidateObjCClassPrefixes(const std::vector& files, // Load the expected package prefixes, if available, to validate against. std::map expected_package_prefixes; - if (!LoadExpectedPackagePrefixes(generation_options, + if (!LoadExpectedPackagePrefixes(generation_options.expected_prefixes_path, &expected_package_prefixes, out_error)) { return false; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index 418ffaba5e..d21fed215a 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -47,9 +47,10 @@ namespace protobuf { namespace compiler { namespace objectivec { -// Set the default objc class prefix that should be used. This method is used only -// when default_objc_class_prefix is passed through objc_opt. -void PROTOC_EXPORT SetDefaultObjcClassPrefix(const std::string& objc_class_prefix); +// Get/Set the path to a file to load for objc class prefix lookups. +std::string PROTOC_EXPORT GetPackageToPrefixMappingsPath(); +void PROTOC_EXPORT SetPackageToPrefixMappingsPath( + const std::string& file_path); // Get/Set if the proto package should be used to make the default prefix for // symbols. This will then impact most of the type naming apis below. It is done // as a global to not break any other generator reusing the methods since they @@ -63,15 +64,12 @@ std::string PROTOC_EXPORT GetProtoPackagePrefixExceptionList(); void PROTOC_EXPORT SetProtoPackagePrefixExceptionList( const std::string& file_path); -// Generator options (see objectivec_generator.cc for a description of each): +// Generator Prefix Validation Options (see objectivec_generator.cc for a +// description of each): struct Options { Options(); std::string expected_prefixes_path; std::vector expected_prefixes_suppressions; - std::string generate_for_named_framework; - std::string named_framework_to_proto_path_mappings_path; - std::string runtime_import_prefix; - std::string default_objc_class_prefix; bool prefixes_must_be_registered; bool require_prefixes; }; @@ -255,7 +253,11 @@ IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); // and the result is false. bool PROTOC_EXPORT ValidateObjCClassPrefixes( const std::vector& files, - const Options& generation_options, std::string* out_error); + const Options& validation_options, std::string* out_error); +// Same was the other ValidateObjCClassPrefixes() calls, but the options all +// come from the environment variables. +bool PROTOC_EXPORT ValidateObjCClassPrefixes( + const std::vector& files, std::string* out_error); // Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform // the input into the expected output. diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc index c1b1f53b14..f6943cd990 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc @@ -81,14 +81,13 @@ const char* MapEntryTypeName(const FieldDescriptor* descriptor, bool isKey) { } // namespace -MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : RepeatedFieldGenerator(descriptor, options) { +MapFieldGenerator::MapFieldGenerator(const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { const FieldDescriptor* key_descriptor = descriptor->message_type()->map_key(); const FieldDescriptor* value_descriptor = descriptor->message_type()->map_value(); - value_field_generator_.reset(FieldGenerator::Make(value_descriptor, options)); + value_field_generator_.reset(FieldGenerator::Make(value_descriptor)); // Pull over some variables_ from the value. variables_["field_type"] = value_field_generator_->variable("field_type"); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h index 84eac6183a..c5b9b1df43 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.h @@ -41,8 +41,7 @@ namespace compiler { namespace objectivec { class MapFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); public: virtual void FinishInitialization(void) override; @@ -51,7 +50,7 @@ class MapFieldGenerator : public RepeatedFieldGenerator { MapFieldGenerator& operator=(const MapFieldGenerator&) = delete; protected: - MapFieldGenerator(const FieldDescriptor* descriptor, const Options& options); + MapFieldGenerator(const FieldDescriptor* descriptor); virtual ~MapFieldGenerator(); virtual void DetermineObjectiveCClassDefinitions( diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc index 3a00113f32..634b227d3f 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -171,11 +171,10 @@ const FieldDescriptor** SortFieldsByStorageSize(const Descriptor* descriptor) { } // namespace MessageGenerator::MessageGenerator(const std::string& root_classname, - const Descriptor* descriptor, - const Options& options) + const Descriptor* descriptor) : root_classname_(root_classname), descriptor_(descriptor), - field_generators_(descriptor, options), + field_generators_(descriptor), class_name_(ClassName(descriptor_)), deprecated_attribute_(GetOptionalDeprecatedAttribute( descriptor, descriptor->file(), false, true)) { @@ -197,8 +196,7 @@ MessageGenerator::MessageGenerator(const std::string& root_classname, for (int i = 0; i < descriptor_->nested_type_count(); i++) { MessageGenerator* generator = new MessageGenerator(root_classname_, - descriptor_->nested_type(i), - options); + descriptor_->nested_type(i)); nested_message_generators_.emplace_back(generator); } } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.h b/src/google/protobuf/compiler/objectivec/objectivec_message.h index 01108d29e7..f532751810 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.h @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include @@ -51,7 +50,7 @@ class EnumGenerator; class MessageGenerator { public: MessageGenerator(const std::string& root_classname, - const Descriptor* descriptor, const Options& options); + const Descriptor* descriptor); ~MessageGenerator(); MessageGenerator(const MessageGenerator&) = delete; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc index 299a20b152..437da524ae 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc @@ -58,9 +58,8 @@ void SetMessageVariables(const FieldDescriptor* descriptor, } // namespace -MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { +MessageFieldGenerator::MessageFieldGenerator(const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); } @@ -79,8 +78,8 @@ void MessageFieldGenerator::DetermineObjectiveCClassDefinitions( } RepeatedMessageFieldGenerator::RepeatedMessageFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetMessageVariables(descriptor, &variables_); variables_["array_storage_type"] = "NSMutableArray"; variables_["array_property_type"] = diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h index 01799a120b..1abf5c8ed5 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.h @@ -41,12 +41,10 @@ namespace compiler { namespace objectivec { class MessageFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - MessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + MessageFieldGenerator(const FieldDescriptor* descriptor); MessageFieldGenerator(const MessageFieldGenerator&) = delete; MessageFieldGenerator& operator=(const MessageFieldGenerator&) = delete; @@ -61,12 +59,10 @@ class MessageFieldGenerator : public ObjCObjFieldGenerator { }; class RepeatedMessageFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedMessageFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedMessageFieldGenerator(); RepeatedMessageFieldGenerator(const RepeatedMessageFieldGenerator&) = delete; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc index e198c5c182..5a89f45c0d 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.cc @@ -125,8 +125,8 @@ void SetPrimitiveVariables(const FieldDescriptor* descriptor, } // namespace PrimitiveFieldGenerator::PrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : SingleFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : SingleFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); } @@ -159,8 +159,8 @@ void PrimitiveFieldGenerator::SetExtraRuntimeHasBitsBase(int has_base) { } PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : ObjCObjFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : ObjCObjFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); variables_["property_storage_attribute"] = "copy"; } @@ -168,8 +168,8 @@ PrimitiveObjFieldGenerator::PrimitiveObjFieldGenerator( PrimitiveObjFieldGenerator::~PrimitiveObjFieldGenerator() {} RepeatedPrimitiveFieldGenerator::RepeatedPrimitiveFieldGenerator( - const FieldDescriptor* descriptor, const Options& options) - : RepeatedFieldGenerator(descriptor, options) { + const FieldDescriptor* descriptor) + : RepeatedFieldGenerator(descriptor) { SetPrimitiveVariables(descriptor, &variables_); std::string base_name = PrimitiveArrayTypeName(descriptor); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h index a9f30f6419..291d11a2e3 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_primitive_field.h @@ -41,12 +41,10 @@ namespace compiler { namespace objectivec { class PrimitiveFieldGenerator : public SingleFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - PrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + PrimitiveFieldGenerator(const FieldDescriptor* descriptor); virtual ~PrimitiveFieldGenerator(); PrimitiveFieldGenerator(const PrimitiveFieldGenerator&) = delete; @@ -59,12 +57,10 @@ class PrimitiveFieldGenerator : public SingleFieldGenerator { }; class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + PrimitiveObjFieldGenerator(const FieldDescriptor* descriptor); virtual ~PrimitiveObjFieldGenerator(); PrimitiveObjFieldGenerator(const PrimitiveObjFieldGenerator&) = delete; @@ -73,12 +69,10 @@ class PrimitiveObjFieldGenerator : public ObjCObjFieldGenerator { }; class RepeatedPrimitiveFieldGenerator : public RepeatedFieldGenerator { - friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field, - const Options& options); + friend FieldGenerator* FieldGenerator::Make(const FieldDescriptor* field); protected: - RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor, - const Options& options); + RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor); virtual ~RepeatedPrimitiveFieldGenerator(); RepeatedPrimitiveFieldGenerator(const RepeatedPrimitiveFieldGenerator&) = diff --git a/src/google/protobuf/compiler/parser.cc b/src/google/protobuf/compiler/parser.cc index 3c3620ea3f..1d4519cedc 100644 --- a/src/google/protobuf/compiler/parser.cc +++ b/src/google/protobuf/compiler/parser.cc @@ -941,7 +941,7 @@ bool Parser::ParseMessageField(FieldDescriptorProto* field, const FileDescriptorProto* containing_file) { { FieldDescriptorProto::Label label; - if (ParseLabel(&label, field_location, containing_file)) { + if (ParseLabel(&label, field_location)) { field->set_label(label); if (label == FieldDescriptorProto::LABEL_OPTIONAL && syntax_identifier_ == "proto3") { @@ -2245,8 +2245,7 @@ bool Parser::ParseMethodOptions(const LocationRecorder& parent_location, // ------------------------------------------------------------------- bool Parser::ParseLabel(FieldDescriptorProto::Label* label, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file) { + const LocationRecorder& field_location) { if (!LookingAt("optional") && !LookingAt("repeated") && !LookingAt("required")) { return false; diff --git a/src/google/protobuf/compiler/parser.h b/src/google/protobuf/compiler/parser.h index f95c419a83..70fc436ee9 100644 --- a/src/google/protobuf/compiler/parser.h +++ b/src/google/protobuf/compiler/parser.h @@ -440,8 +440,7 @@ class PROTOBUF_EXPORT Parser { // Parse "required", "optional", or "repeated" and fill in "label" // with the value. Returns true if such a label is consumed. bool ParseLabel(FieldDescriptorProto::Label* label, - const LocationRecorder& field_location, - const FileDescriptorProto* containing_file); + const LocationRecorder& field_location); // Parse a type name and fill in "type" (if it is a primitive) or // "type_name" (if it is not) with the type parsed. diff --git a/src/google/protobuf/compiler/plugin.pb.cc b/src/google/protobuf/compiler/plugin.pb.cc index 37c1a54a48..61a6700cfc 100644 --- a/src/google/protobuf/compiler/plugin.pb.cc +++ b/src/google/protobuf/compiler/plugin.pb.cc @@ -22,14 +22,14 @@ namespace _pbi = _pb::internal; PROTOBUF_NAMESPACE_OPEN namespace compiler { -constexpr Version::Version( +PROTOBUF_CONSTEXPR Version::Version( ::_pbi::ConstantInitialized) : suffix_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , major_(0) , minor_(0) , patch_(0){} struct VersionDefaultTypeInternal { - constexpr VersionDefaultTypeInternal() + PROTOBUF_CONSTEXPR VersionDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} ~VersionDefaultTypeInternal() {} union { @@ -37,14 +37,14 @@ struct VersionDefaultTypeInternal { }; }; PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 VersionDefaultTypeInternal _Version_default_instance_; -constexpr CodeGeneratorRequest::CodeGeneratorRequest( +PROTOBUF_CONSTEXPR CodeGeneratorRequest::CodeGeneratorRequest( ::_pbi::ConstantInitialized) : file_to_generate_() , proto_file_() , parameter_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , compiler_version_(nullptr){} struct CodeGeneratorRequestDefaultTypeInternal { - constexpr CodeGeneratorRequestDefaultTypeInternal() + PROTOBUF_CONSTEXPR CodeGeneratorRequestDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorRequestDefaultTypeInternal() {} union { @@ -52,14 +52,14 @@ struct CodeGeneratorRequestDefaultTypeInternal { }; }; PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorRequestDefaultTypeInternal _CodeGeneratorRequest_default_instance_; -constexpr CodeGeneratorResponse_File::CodeGeneratorResponse_File( +PROTOBUF_CONSTEXPR CodeGeneratorResponse_File::CodeGeneratorResponse_File( ::_pbi::ConstantInitialized) : name_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , insertion_point_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , content_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , generated_code_info_(nullptr){} struct CodeGeneratorResponse_FileDefaultTypeInternal { - constexpr CodeGeneratorResponse_FileDefaultTypeInternal() + PROTOBUF_CONSTEXPR CodeGeneratorResponse_FileDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorResponse_FileDefaultTypeInternal() {} union { @@ -67,13 +67,13 @@ struct CodeGeneratorResponse_FileDefaultTypeInternal { }; }; PROTOBUF_ATTRIBUTE_NO_DESTROY PROTOBUF_CONSTINIT PROTOBUF_ATTRIBUTE_INIT_PRIORITY1 CodeGeneratorResponse_FileDefaultTypeInternal _CodeGeneratorResponse_File_default_instance_; -constexpr CodeGeneratorResponse::CodeGeneratorResponse( +PROTOBUF_CONSTEXPR CodeGeneratorResponse::CodeGeneratorResponse( ::_pbi::ConstantInitialized) : file_() , error_(&::_pbi::fixed_address_empty_string, ::_pbi::ConstantInitialized{}) , supported_features_(uint64_t{0u}){} struct CodeGeneratorResponseDefaultTypeInternal { - constexpr CodeGeneratorResponseDefaultTypeInternal() + PROTOBUF_CONSTEXPR CodeGeneratorResponseDefaultTypeInternal() : _instance(::_pbi::ConstantInitialized{}) {} ~CodeGeneratorResponseDefaultTypeInternal() {} union { diff --git a/src/google/protobuf/compiler/plugin.pb.h b/src/google/protobuf/compiler/plugin.pb.h index 889c550fb2..ffe721297d 100644 --- a/src/google/protobuf/compiler/plugin.pb.h +++ b/src/google/protobuf/compiler/plugin.pb.h @@ -107,7 +107,7 @@ class PROTOC_EXPORT Version final : public: inline Version() : Version(nullptr) {} ~Version() override; - explicit constexpr Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR Version(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); Version(const Version& from); Version(Version&& from) noexcept @@ -312,7 +312,7 @@ class PROTOC_EXPORT CodeGeneratorRequest final : public: inline CodeGeneratorRequest() : CodeGeneratorRequest(nullptr) {} ~CodeGeneratorRequest() override; - explicit constexpr CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorRequest(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorRequest(const CodeGeneratorRequest& from); CodeGeneratorRequest(CodeGeneratorRequest&& from) noexcept @@ -538,7 +538,7 @@ class PROTOC_EXPORT CodeGeneratorResponse_File final : public: inline CodeGeneratorResponse_File() : CodeGeneratorResponse_File(nullptr) {} ~CodeGeneratorResponse_File() override; - explicit constexpr CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse_File(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorResponse_File(const CodeGeneratorResponse_File& from); CodeGeneratorResponse_File(CodeGeneratorResponse_File&& from) noexcept @@ -758,7 +758,7 @@ class PROTOC_EXPORT CodeGeneratorResponse final : public: inline CodeGeneratorResponse() : CodeGeneratorResponse(nullptr) {} ~CodeGeneratorResponse() override; - explicit constexpr CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); + explicit PROTOBUF_CONSTEXPR CodeGeneratorResponse(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized); CodeGeneratorResponse(const CodeGeneratorResponse& from); CodeGeneratorResponse(CodeGeneratorResponse&& from) noexcept diff --git a/src/google/protobuf/descriptor.cc b/src/google/protobuf/descriptor.cc index 5dd319035e..5be4fa6179 100644 --- a/src/google/protobuf/descriptor.cc +++ b/src/google/protobuf/descriptor.cc @@ -143,7 +143,68 @@ struct ExpressionEater { }; void Fold(std::initializer_list) {} -constexpr size_t RoundUp(size_t n) { return (n + 7) & ~7; } +template +constexpr size_t RoundUpTo(size_t n) { + static_assert((R & (R - 1)) == 0, "Must be power of two"); + return (n + (R - 1)) & ~(R - 1); +} + +constexpr size_t Max(size_t a, size_t b) { return a > b ? a : b; } +template +constexpr size_t Max(T a, Ts... b) { + return Max(a, Max(b...)); +} + +template +constexpr size_t EffectiveAlignof() { + // `char` is special in that it gets aligned to 8. It is where we drop the + // trivial structs. + return std::is_same::value ? 8 : alignof(T); +} + +// Metafunction to sort types in descending order of alignment. +// Useful for the flat allocator to ensure proper alignment of all elements +// without having to add padding. +// For simplicity we use a function pointer as a type list. +struct TypeListSorter { + template + static auto AppendIfAlign(void (*)(T...)) -> + typename std::conditional() == align, + void (*)(T..., U), void (*)(T...)>::type { + return nullptr; + } + + template + static auto SortImpl(void (*)(), void (*)(T16...), void (*)(T8...), + void (*)(T4...), void (*)(T2...), void (*)(T1...)) + -> void (*)(T16..., T8..., T4..., T2..., T1...) { + return nullptr; + } + + template + static auto SortImpl(void (*)(T, Ts...), T16 p16, T8 p8, T4 p4, T2 p2, T1 p1) + -> decltype(Self::template SortImpl( + static_cast(nullptr), AppendIfAlign<16, T>(p16), + AppendIfAlign<8, T>(p8), AppendIfAlign<4, T>(p4), + AppendIfAlign<2, T>(p2), AppendIfAlign<1, T>(p1))) { + return nullptr; + } + + // Instead of implementing a proper sort metafunction we just do a + // filter+merge, which is much simpler to write as a metafunction. + // We have a fixed set of alignments we can filter on. + template + static auto SortByAlignment(void (*p)() = nullptr) + -> decltype(SortImpl(static_cast(nullptr), p, p, p, p, + p)) { + return nullptr; + } +}; + +template