Skip to content

Commit

Permalink
Merge release branch into master. (#7517)
Browse files Browse the repository at this point in the history
* Added background information about proto3 presence. (#7501)

* Fixed bug in map key sorting for Java TextFormat. (#7508)

Fixes: #7505

* Update protobuf version

* Added a changelog entry about the Java fix. (#7516)
  • Loading branch information
haberman committed May 16, 2020
1 parent 63da77b commit 9952e36
Show file tree
Hide file tree
Showing 20 changed files with 109 additions and 39 deletions.
1 change: 1 addition & 0 deletions CHANGES.txt
Expand Up @@ -44,6 +44,7 @@
* Mark java enum _VALUE constants as @Deprecated if the enum field is deprecated
* reduce <clinit> size for enums with allow_alias set to true.
* Sort map fields alphabetically by the field's key when printing textproto.
* Fixed a bug in map sorting that appeared in -rc1 and -rc2 (#7508).
* TextFormat.merge() handles Any as top level type.
* Throw a descriptive IllegalArgumentException when calling
getValueDescriptor() on enum special value UNRECOGNIZED instead of
Expand Down
2 changes: 1 addition & 1 deletion Protobuf-C++.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'Protobuf-C++'
s.version = '3.12.0-rc2'
s.version = '3.12.0'
s.summary = 'Protocol Buffers v3 runtime library for C++.'
s.homepage = 'https://github.com/google/protobuf'
s.license = '3-Clause BSD License'
Expand Down
2 changes: 1 addition & 1 deletion Protobuf.podspec
Expand Up @@ -5,7 +5,7 @@
# dependent projects use the :git notation to refer to the library.
Pod::Spec.new do |s|
s.name = 'Protobuf'
s.version = '3.12.0-rc2'
s.version = '3.12.0'
s.summary = 'Protocol Buffers v.3 runtime library for Objective-C.'
s.homepage = 'https://github.com/protocolbuffers/protobuf'
s.license = '3-Clause BSD License'
Expand Down
2 changes: 1 addition & 1 deletion configure.ac
Expand Up @@ -17,7 +17,7 @@ AC_PREREQ(2.59)
# In the SVN trunk, the version should always be the next anticipated release
# version with the "-pre" suffix. (We used to use "-SNAPSHOT" but this pushed
# the size of one file name in the dist tarfile over the 99-char limit.)
AC_INIT([Protocol Buffers],[3.12.0-rc-2],[protobuf@googlegroups.com],[protobuf])
AC_INIT([Protocol Buffers],[3.12.0],[protobuf@googlegroups.com],[protobuf])

AM_MAINTAINER_MODE([enable])

Expand Down
2 changes: 1 addition & 1 deletion csharp/Google.Protobuf.Tools.nuspec
Expand Up @@ -5,7 +5,7 @@
<title>Google Protocol Buffers tools</title>
<summary>Tools for Protocol Buffers - Google's data interchange format.</summary>
<description>See project site for more info.</description>
<version>3.12.0-rc2</version>
<version>3.12.0</version>
<authors>Google Inc.</authors>
<owners>protobuf-packages</owners>
<licenseUrl>https://github.com/protocolbuffers/protobuf/blob/master/LICENSE</licenseUrl>
Expand Down
2 changes: 1 addition & 1 deletion csharp/src/Google.Protobuf/Google.Protobuf.csproj
Expand Up @@ -4,7 +4,7 @@
<Description>C# runtime library for Protocol Buffers - Google's data interchange format.</Description>
<Copyright>Copyright 2015, Google Inc.</Copyright>
<AssemblyTitle>Google Protocol Buffers</AssemblyTitle>
<VersionPrefix>3.12.0-rc2</VersionPrefix>
<VersionPrefix>3.12.0</VersionPrefix>
<!-- C# 7.2 is required for Span/BufferWriter/ReadOnlySequence -->
<LangVersion>7.2</LangVersion>
<Authors>Google Inc.</Authors>
Expand Down
50 changes: 50 additions & 0 deletions docs/implementing_proto3_presence.md
Expand Up @@ -5,6 +5,8 @@ proto3. Proto3 optional fields track presence like in proto2. For background
information about what presence tracking means, please see
[docs/field_presence](field_presence.md).

## Document Summary

This document is targeted at developers who own or maintain protobuf code
generators. All code generators will need to be updated to support proto3
optional fields. First-party code generators developed by Google are being
Expand All @@ -14,13 +16,61 @@ independently by their authors. This includes:
- implementations of Protocol Buffers for other languges.
- alternate implementations of Protocol Buffers that target specialized use
cases.
- RPC code generators that create generated APIs for service calls.
- code generators that implement some utility code on top of protobuf generated
classes.

While this document speaks in terms of "code generators", these same principles
apply to implementations that dynamically generate a protocol buffer API "on the
fly", directly from a descriptor, in languages that support this kind of usage.

## Background

Presence tracking was added to proto3 in response to user feedback, both from
inside Google and [from open-source
users](https://github.com/protocolbuffers/protobuf/issues/1606). The [proto3
wrapper
types](https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/wrappers.proto)
were previously the only supported presence mechanism for proto3. Users have
pointed to both efficiency and usability issues with the wrapper types.

Presence in proto3 uses exactly the same syntax and semantics as in proto2.
Proto3 Fields marked `optional` will track presence like proto2, while fields
without any label (known as "singular fields"), will continue to omit presence
information. The `optional` keyword was chosen to minimize differences with
proto2.

Unfortunately, for the current descriptor protos and `Descriptor` API (as of
3.11.4) it is not possible to use the same representation as proto2. Proto3
descriptors already use `LABEL_OPTIONAL` for proto3 singular fields, which do
not track presence. There is a lot of existing code that reflects over proto3
protos and assumes that `LABEL_OPTIONAL` in proto3 means "no presence." Changing
the semantics now would be risky, since old software would likely drop proto3
presence information, which would be a data loss bug.

To minimize this risk we chose a descriptor representation that is semantically
compatible with existing proto3 reflection. Every proto3 optional field is
placed into a one-field `oneof`. We call this a "synthetic" oneof, as it was not
present in the source `.proto` file.

Since oneof fields in proto3 already track presence, existing proto3
reflection-based algorithms should correctly preserve presence for proto3
optional fields with no code changes. For example, the JSON and TextFormat
parsers/serializers in C++ and Java did not require any changes to support
proto3 presence. This is the major benefit of synthetic oneofs.

This design does leave some cruft in descriptors. Synthetic oneofs are a
compatibility measure that we can hopefully clean up in the future. For now
though, it is important to preserve them across different descriptor formats and
APIs. It is never safe to drop synthetic oneofs from a proto schema. Code
generators can (and should) skip synthetic oneofs when generating a user-facing
API or user-facing documentation. But for any schema representation that is
consumed programmatically, it is important to keep the synthetic oneofs around.

In APIs it can be helpful to offer separate accessors that refer to "real"
oneofs (see [API Changes](#api-changes) below). This is a convenient way to omit
synthetic oneofs in code generators.

## Updating a Code Generator

When a user adds an `optional` field to proto3, this is internally rewritten as
Expand Down
2 changes: 1 addition & 1 deletion java/bom/pom.xml
Expand Up @@ -4,7 +4,7 @@

<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-bom</artifactId>
<version>3.12.0-rc-2</version>
<version>3.12.0</version>
<packaging>pom</packaging>

<name>Protocol Buffers [BOM]</name>
Expand Down
2 changes: 1 addition & 1 deletion java/core/pom.xml
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.12.0-rc-2</version>
<version>3.12.0</version>
</parent>

<artifactId>protobuf-java</artifactId>
Expand Down
22 changes: 3 additions & 19 deletions java/core/src/main/java/com/google/protobuf/TextFormat.java
Expand Up @@ -490,27 +490,11 @@ public int compareTo(MapEntryAdapter b) {
}
switch (fieldType) {
case BOOLEAN:
boolean aBoolean = (boolean) getKey();
boolean bBoolean = (boolean) b.getKey();
if (aBoolean == bBoolean) {
return 0;
} else if (aBoolean) {
return 1;
} else {
return -1;
}
return Boolean.compare((boolean) getKey(), (boolean) b.getKey());
case LONG:
long aLong = (long) getKey();
long bLong = (long) b.getKey();
if (aLong < bLong) {
return -1;
} else if (aLong > bLong) {
return 1;
} else {
return 0;
}
return Long.compare((long) getKey(), (long) b.getKey());
case INT:
return (int) getKey() - (int) b.getKey();
return Integer.compare((int) getKey(), (int) b.getKey());
case STRING:
String aString = (String) getKey();
String bString = (String) b.getKey();
Expand Down
21 changes: 21 additions & 0 deletions java/core/src/test/java/com/google/protobuf/TextFormatTest.java
Expand Up @@ -1404,6 +1404,27 @@ public void testMapTextFormat() throws Exception {
}
}

public void testMapDuplicateKeys() throws Exception {
String input =
"int32_to_int32_field: {\n"
+ " key: 1\n"
+ " value: 1\n"
+ "}\n"
+ "int32_to_int32_field: {\n"
+ " key: -2147483647\n"
+ " value: 5\n"
+ "}\n"
+ "int32_to_int32_field: {\n"
+ " key: 1\n"
+ " value: -1\n"
+ "}\n";
TestMap msg = TextFormat.parse(input, TestMap.class);
int val1 = msg.getInt32ToInt32Field().get(1);
TestMap msg2 = TextFormat.parse(msg.toString(), TestMap.class);
int val2 = msg2.getInt32ToInt32Field().get(1);
assertEquals(val1, val2);
}

public void testMapShortForm() throws Exception {
String text =
"string_to_int32_field [{ key: 'x' value: 10 }, { key: 'y' value: 20 }]\n"
Expand Down
2 changes: 1 addition & 1 deletion java/lite/pom.xml
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.12.0-rc-2</version>
<version>3.12.0</version>
</parent>

<artifactId>protobuf-javalite</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion java/pom.xml
Expand Up @@ -4,7 +4,7 @@

<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.12.0-rc-2</version>
<version>3.12.0</version>
<packaging>pom</packaging>

<name>Protocol Buffers [Parent]</name>
Expand Down
2 changes: 1 addition & 1 deletion java/util/pom.xml
Expand Up @@ -4,7 +4,7 @@
<parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-parent</artifactId>
<version>3.12.0-rc-2</version>
<version>3.12.0</version>
</parent>

<artifactId>protobuf-java-util</artifactId>
Expand Down
2 changes: 1 addition & 1 deletion js/package.json
@@ -1,6 +1,6 @@
{
"name": "google-protobuf",
"version": "3.12.0-rc.2",
"version": "3.12.0",
"description": "Protocol Buffers for JavaScript",
"main": "google-protobuf.js",
"files": [
Expand Down
24 changes: 19 additions & 5 deletions php/ext/google/protobuf/package.xml
Expand Up @@ -10,15 +10,15 @@
<email>protobuf-opensource@google.com</email>
<active>yes</active>
</lead>
<date>2020-05-12</date>
<time>12:48:03</time>
<date>2020-05-15</date>
<time>13:26:23</time>
<version>
<release>3.12.0RC2</release>
<release>3.12.0</release>
<api>3.12.0</api>
</version>
<stability>
<release>beta</release>
<api>beta</api>
<release>stable</release>
<api>stable</api>
</stability>
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
<notes>GA release.</notes>
Expand Down Expand Up @@ -557,5 +557,19 @@ G A release.
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
<notes>GA release.</notes>
</release>
<release>
<version>
<release>3.12.0</release>
<api>3.12.0</api>
</version>
<stability>
<release>stable</release>
<api>stable</api>
</stability>
<date>2020-05-15</date>
<time>13:26:23</time>
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
<notes>GA release.</notes>
</release>
</changelog>
</package>
2 changes: 1 addition & 1 deletion php/ext/google/protobuf/protobuf.h
Expand Up @@ -37,7 +37,7 @@
#include "upb.h"

#define PHP_PROTOBUF_EXTNAME "protobuf"
#define PHP_PROTOBUF_VERSION "3.12.0RC2"
#define PHP_PROTOBUF_VERSION "3.12.0"

#define MAX_LENGTH_OF_INT64 20
#define SIZEOF_INT64 8
Expand Down
2 changes: 1 addition & 1 deletion protoc-artifacts/pom.xml
Expand Up @@ -8,7 +8,7 @@
</parent>
<groupId>com.google.protobuf</groupId>
<artifactId>protoc</artifactId>
<version>3.12.0-rc-2</version>
<version>3.12.0</version>
<packaging>pom</packaging>
<name>Protobuf Compiler</name>
<description>
Expand Down
2 changes: 1 addition & 1 deletion python/google/protobuf/__init__.py
Expand Up @@ -30,7 +30,7 @@

# Copyright 2007 Google Inc. All Rights Reserved.

__version__ = '3.12.0rc2'
__version__ = '3.12.0'

if __name__ != '__main__':
try:
Expand Down
2 changes: 1 addition & 1 deletion ruby/google-protobuf.gemspec
@@ -1,6 +1,6 @@
Gem::Specification.new do |s|
s.name = "google-protobuf"
s.version = "3.12.0.rc.2"
s.version = "3.12.0"
git_tag = "v#{s.version.to_s.sub('.rc.', '-rc')}" # Converts X.Y.Z.rc.N to vX.Y.Z-rcN, used for the git tag
s.licenses = ["BSD-3-Clause"]
s.summary = "Protocol Buffers"
Expand Down

0 comments on commit 9952e36

Please sign in to comment.