Merge branch 'master' into patch-1
This commit is contained in:
commit
619ffac4f7
2
BUILD
2
BUILD
@ -115,8 +115,8 @@ cc_library(
|
||||
"src/google/protobuf/generated_message_util.cc",
|
||||
"src/google/protobuf/implicit_weak_message.cc",
|
||||
"src/google/protobuf/io/coded_stream.cc",
|
||||
"src/google/protobuf/io/strtod.cc",
|
||||
"src/google/protobuf/io/io_win32.cc",
|
||||
"src/google/protobuf/io/strtod.cc",
|
||||
"src/google/protobuf/io/zero_copy_stream.cc",
|
||||
"src/google/protobuf/io/zero_copy_stream_impl.cc",
|
||||
"src/google/protobuf/io/zero_copy_stream_impl_lite.cc",
|
||||
|
71
CHANGES.txt
71
CHANGES.txt
@ -1,3 +1,74 @@
|
||||
2019-04-29 version 3.8.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
C++
|
||||
* Use std::atomic<int32> in case of myriad2 platform
|
||||
* Always declare enums to be int-sized
|
||||
* Added DebugString() and ShortDebugString() methods on MessageLite
|
||||
* Specialized different parse loop control flows
|
||||
* Make hasbits potentially in register. The or's start forming an obstacle because it's a read modify store on the same mem address on each iteration.
|
||||
* Move to an internal MACRO for parser validity checks.
|
||||
* Improve map parsing performance.
|
||||
* Make MergePartialFromCodedStream non virtual. This allows direct calls, potential inlining and is also a code health improvement
|
||||
* Add an overall limit to parse_context to prevent reading past it. This allows to remove a annoying level of indirection.
|
||||
* Fix a mistake, we shouldn't verify map key/value strings for utf8 in opt mode for proto2.
|
||||
* Further improvements to cut binary size.
|
||||
* Prepare to make MergePartialFromCodedStream non-virtual.
|
||||
* A report on some interesting behavior change in python (caused by b/27494216) made me realize there is a check that needs to be done in case the parse ended on a end group tag.
|
||||
* Add a note of caution to the comments around skip in CodedOutputStream.
|
||||
* Simplify end check.
|
||||
* Add overload for ParseMessage for MessageLite/Message types. If the explicit type is not known inlining won't help de-virtualizing the virtual call.
|
||||
* Reduce linker input. It turns out that ParseMessage is not inlined, producing template instantiations that are used only once and save nothing but cost more.
|
||||
* Improve the parser.
|
||||
* [c++17] Changed proto2::RepeatedPtrField iterators to no longer derive from the deprecated std::iterator class.
|
||||
* Change the default value of case_insensitive_enum_parsing to false for JsonStringToMessage.
|
||||
* Add a warning if a field name doesn't match the style guide.
|
||||
* Fix TextFormat not round-trip correctly when float value is max float.
|
||||
* Added locationed info for some errors at compiler
|
||||
* Python reserved keywords are now working with getattr()/setattr() for most descriptors.
|
||||
* Added AllowUnknownField() in text_format
|
||||
* Append '_' to C++ reserved keywords for message, enum, extension
|
||||
* Fix MSVC warning C4244 in protobuf's parse_context.h.
|
||||
* Updating Iterators to be compatible with C++17 in MSVC.
|
||||
* Use capability annotation in mutex.h
|
||||
* Fix "UndefinedBehaviorSanitizer: cfi-bad-type"
|
||||
* CriticalSectionLock class as a lightweight replacement for std::mutex on Windows platforms.
|
||||
* Removed vestigial wire_format_lite_inl.h
|
||||
|
||||
C#
|
||||
* Added System.Memory dependency.
|
||||
|
||||
Java
|
||||
* Make Java protoc code generator ignore optimize_for LITE_RUNTIME. Users should instead use the Java lite protoc plugin.
|
||||
* Change Extension getMessageDefaultInstance() to return Message instead of MessageLite.
|
||||
* Prevent malicious input streams from leaking buffers for ByteString or ByteBuffer parsing.
|
||||
* Release new Javalite runtime.
|
||||
* Show warning in case potential file name conflict.
|
||||
* Allow Java reserved keywords to be used in extensions.
|
||||
* Added setAllowUnknownFields() in text format
|
||||
* Add memoization to ExtensionRegistryLite.getEmptyRegistry()
|
||||
* Improve performance of CodedOutputStream.writeUInt32NoTag
|
||||
* Add an optimized mismatch-finding algorithm to UnsafeUtil.
|
||||
* When serializing uint32 varints, check that we have MAX_VARINT32_SIZE bytes left, not just MAX_VARINT_SIZE.
|
||||
* Minor optimization to RopeByteString.PieceIterator
|
||||
|
||||
JavaScript
|
||||
* Simplify generated toObject code when the default value is used.
|
||||
|
||||
Python
|
||||
* Changes implementation of Name() for enums that allow aliases in proto2 in Python to be in line with claims in C++ implementation (to return first value).
|
||||
* Added double_format option in text format printer.
|
||||
* Added iter and __contains__ to extension dict
|
||||
* Added allow_unknown_field option in python text format parser
|
||||
* Fixed Timestamp.ToDatetime() loses precision issue
|
||||
* Support unknown field in text format printer.
|
||||
* Float field will be convert to inf if bigger than struct.unpack('f', b'\xff\xff\x7f\x7f')[0] which is about 3.4028234664e+38,
|
||||
convert to -inf if smaller than -3.4028234664e+38
|
||||
* Allowed casting str->bytes in Message.__setstate__
|
||||
|
||||
Ruby
|
||||
* Helper methods to get enum name for Ruby.
|
||||
|
||||
|
||||
2019-01-24 version 3.7.0 (C++/Java/Python/PHP/Objective-C/C#/Ruby/JavaScript)
|
||||
|
||||
C++
|
||||
|
@ -83,6 +83,10 @@ the final release.
|
||||
Ultimately, the green signal will be provided by our testing infrastructure.
|
||||
The reviewer will help you if there are test failures that seem not related
|
||||
to the change you are making.
|
||||
|
||||
## Reviewer Guidelines
|
||||
|
||||
* Make sure that all tests are passing before approval.
|
||||
* Apply the "release notes: yes" label if the pull request's description should
|
||||
be included in the next release (e.g., any new feature / bug fix).
|
||||
Apply the "release notes: no" label if the pull request's description should
|
||||
@ -92,4 +96,3 @@ the final release.
|
||||
pull request. This will make it easier to identify which languages the pull
|
||||
request affects, allowing us to better identify appropriate reviewer, create
|
||||
a better release note, and make it easier to identify issues in the future.
|
||||
|
||||
|
@ -493,11 +493,15 @@ java_EXTRA_DIST=
|
||||
java/util/src/main/java/com/google/protobuf/util/FieldMaskUtil.java \
|
||||
java/util/src/main/java/com/google/protobuf/util/JsonFormat.java \
|
||||
java/util/src/main/java/com/google/protobuf/util/TimeUtil.java \
|
||||
java/util/src/main/java/com/google/protobuf/util/Structs.java \
|
||||
java/util/src/main/java/com/google/protobuf/util/Timestamps.java \
|
||||
java/util/src/main/java/com/google/protobuf/util/Values.java \
|
||||
java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java \
|
||||
java/util/src/test/java/com/google/protobuf/util/FieldMaskUtilTest.java \
|
||||
java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java \
|
||||
java/util/src/test/java/com/google/protobuf/util/StructsTest.java \
|
||||
java/util/src/test/java/com/google/protobuf/util/TimeUtilTest.java \
|
||||
java/util/src/test/java/com/google/protobuf/util/ValuesTest.java \
|
||||
java/util/src/test/proto/com/google/protobuf/util/json_test.proto
|
||||
|
||||
objectivec_EXTRA_DIST= \
|
||||
@ -1231,6 +1235,7 @@ EXTRA_DIST = $(@DIST_LANG@_EXTRA_DIST) \
|
||||
python/release/wheel/protobuf_optimized_pip.sh \
|
||||
python/release/wheel/README.md \
|
||||
six.BUILD \
|
||||
third_party/zlib.BUILD \
|
||||
util/python/BUILD
|
||||
|
||||
|
||||
|
@ -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.7.1'
|
||||
s.version = '3.8.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'
|
||||
|
@ -33,7 +33,7 @@ if (protobuf_BUILD_PROTOC_BINARIES)
|
||||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT protoc)
|
||||
if (UNIX AND NOT APPLE)
|
||||
set_property(TARGET protoc
|
||||
PROPERTY INSTALL_RPATH "$ORIGIN/../lib")
|
||||
PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}")
|
||||
elseif (APPLE)
|
||||
set_property(TARGET protoc
|
||||
PROPERTY INSTALL_RPATH "@loader_path/../lib")
|
||||
|
@ -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.7.1],[protobuf@googlegroups.com],[protobuf])
|
||||
AC_INIT([Protocol Buffers],[3.8.0],[protobuf@googlegroups.com],[protobuf])
|
||||
|
||||
AM_MAINTAINER_MODE([enable])
|
||||
|
||||
@ -47,6 +47,11 @@ AC_CANONICAL_TARGET
|
||||
|
||||
AM_INIT_AUTOMAKE([1.9 tar-ustar subdir-objects])
|
||||
|
||||
# Silent rules enabled: the output is minimal but informative.
|
||||
# In particular, the warnings from the compiler stick out very clearly.
|
||||
# To see all logs, use the --disable-silent-rules on configure or via make V=1
|
||||
AM_SILENT_RULES([yes])
|
||||
|
||||
AC_ARG_WITH([zlib],
|
||||
[AS_HELP_STRING([--with-zlib],
|
||||
[include classes for streaming compressed data in and out @<:@default=check@:>@])],
|
||||
|
@ -1980,12 +1980,12 @@ void BinaryAndJsonConformanceSuite::RunSuiteImpl() {
|
||||
"repeated_timestamp: {seconds: 253402300799 nanos: 999999999}");
|
||||
RunValidJsonTest(
|
||||
"TimestampWithPositiveOffset", REQUIRED,
|
||||
R"({"optionalTimestamp": "1970-01-01T08:00:00+08:00"})",
|
||||
"optional_timestamp: {seconds: 0}");
|
||||
R"({"optionalTimestamp": "1970-01-01T08:00:01+08:00"})",
|
||||
"optional_timestamp: {seconds: 1}");
|
||||
RunValidJsonTest(
|
||||
"TimestampWithNegativeOffset", REQUIRED,
|
||||
R"({"optionalTimestamp": "1969-12-31T16:00:00-08:00"})",
|
||||
"optional_timestamp: {seconds: 0}");
|
||||
R"({"optionalTimestamp": "1969-12-31T16:00:01-08:00"})",
|
||||
"optional_timestamp: {seconds: 1}");
|
||||
RunValidJsonTest(
|
||||
"TimestampNull", REQUIRED,
|
||||
R"({"optionalTimestamp": null})",
|
||||
|
@ -3,10 +3,6 @@ Recommended.FieldMaskPathsDontRoundTrip.JsonOutput
|
||||
Recommended.FieldMaskTooManyUnderscore.JsonOutput
|
||||
Recommended.Proto3.JsonInput.BytesFieldBase64Url.JsonOutput
|
||||
Recommended.Proto3.JsonInput.BytesFieldBase64Url.ProtobufOutput
|
||||
Recommended.Proto3.JsonInput.DurationHas3FractionalDigits.Validator
|
||||
Recommended.Proto3.JsonInput.DurationHas6FractionalDigits.Validator
|
||||
Recommended.Proto3.JsonInput.DurationHas9FractionalDigits.Validator
|
||||
Recommended.Proto3.JsonInput.DurationHasZeroFractionalDigit.Validator
|
||||
Recommended.Proto3.JsonInput.FieldMaskInvalidCharacter
|
||||
Required.Proto3.JsonInput.FloatFieldTooLarge
|
||||
Required.Proto3.JsonInput.FloatFieldTooSmall
|
||||
|
@ -51,11 +51,6 @@ Required.Proto3.JsonInput.RepeatedUint32Wrapper.JsonOutput
|
||||
Required.Proto3.JsonInput.RepeatedUint64Wrapper.JsonOutput
|
||||
Required.Proto3.JsonInput.StringFieldSurrogatePair.JsonOutput
|
||||
Required.Proto3.JsonInput.StringFieldSurrogatePair.ProtobufOutput
|
||||
Required.Proto3.JsonInput.TimestampJsonInputTooSmall
|
||||
Required.Proto3.JsonInput.TimestampMinValue.JsonOutput
|
||||
Required.Proto3.JsonInput.TimestampMinValue.ProtobufOutput
|
||||
Required.Proto3.JsonInput.TimestampRepeatedValue.JsonOutput
|
||||
Required.Proto3.JsonInput.TimestampRepeatedValue.ProtobufOutput
|
||||
Required.Proto3.ProtobufInput.DoubleFieldNormalizeQuietNan.JsonOutput
|
||||
Required.Proto3.ProtobufInput.DoubleFieldNormalizeSignalingNan.JsonOutput
|
||||
Required.Proto3.ProtobufInput.FloatFieldNormalizeQuietNan.JsonOutput
|
||||
|
@ -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.7.1</version>
|
||||
<version>3.8.0</version>
|
||||
<authors>Google Inc.</authors>
|
||||
<owners>protobuf-packages</owners>
|
||||
<licenseUrl>https://github.com/protocolbuffers/protobuf/blob/master/LICENSE</licenseUrl>
|
||||
|
Binary file not shown.
@ -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.7.1</VersionPrefix>
|
||||
<VersionPrefix>3.8.0</VersionPrefix>
|
||||
<LangVersion>6</LangVersion>
|
||||
<Authors>Google Inc.</Authors>
|
||||
<TargetFrameworks>netstandard1.0;netstandard2.0;net45</TargetFrameworks>
|
||||
@ -32,11 +32,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Condition=" '$(TargetFramework)' == 'netstandard2.0' ">
|
||||
<PackageReference Include="System.Memory" Version="4.5.2" />
|
||||
<PackageReference Include="System.Memory" Version="4.5.2"/>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta2-18618-05" PrivateAssets="All" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" PrivateAssets="All" Version="1.0.0-beta2-18618-05"/>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
@ -41,15 +41,11 @@ namespace Google.Protobuf.Reflection
|
||||
/// </summary>
|
||||
public class ExtensionCollection
|
||||
{
|
||||
private readonly FileDescriptor file;
|
||||
private readonly MessageDescriptor message;
|
||||
|
||||
private IDictionary<MessageDescriptor, IList<FieldDescriptor>> extensionsByTypeInDeclarationOrder;
|
||||
private IDictionary<MessageDescriptor, IList<FieldDescriptor>> extensionsByTypeInNumberOrder;
|
||||
|
||||
internal ExtensionCollection(FileDescriptor file, Extension[] extensions)
|
||||
{
|
||||
this.file = file;
|
||||
UnorderedExtensions = DescriptorUtil.ConvertAndMakeReadOnly(
|
||||
file.Proto.Extension,
|
||||
(extension, i) => new FieldDescriptor(extension, file, null, i, null, extensions?[i]));
|
||||
@ -57,7 +53,6 @@ namespace Google.Protobuf.Reflection
|
||||
|
||||
internal ExtensionCollection(MessageDescriptor message, Extension[] extensions)
|
||||
{
|
||||
this.message = message;
|
||||
UnorderedExtensions = DescriptorUtil.ConvertAndMakeReadOnly(
|
||||
message.Proto.Extension,
|
||||
(extension, i) => new FieldDescriptor(extension, message.File, message, i, null, extensions?[i]));
|
||||
|
@ -197,7 +197,11 @@ with info about your project (name and website) so we can add an entry for you.
|
||||
* Website: https://github.com/container-storage-interface/spec
|
||||
* Extensions: 1059-1069
|
||||
|
||||
1. TwirpQL Plugin
|
||||
* Website: https://twirpql.dev
|
||||
* Extensions: 1070
|
||||
|
||||
1. Protoc-gen-validate
|
||||
* Website: https://github.com/envoyproxy/protoc-gen-validate
|
||||
* Extensions: 1070
|
||||
|
||||
* Extensions: 1071
|
||||
|
||||
|
2
examples/README.md
Normal file → Executable file
2
examples/README.md
Normal file → Executable file
@ -38,7 +38,7 @@ and the protobuf runtime for the language you want to build.
|
||||
|
||||
You can simply run "make" to build the example for all languages (except for
|
||||
Go). However, since different language has different installation requirement,
|
||||
it will likely fail. It's better to follow individual instrutions below to
|
||||
it will likely fail. It's better to follow individual instructions below to
|
||||
build only the language you are interested in.
|
||||
|
||||
### C++
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-bom</artifactId>
|
||||
<version>3.7.1</version>
|
||||
<version>3.8.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Protocol Buffers [BOM]</name>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-parent</artifactId>
|
||||
<version>3.7.1</version>
|
||||
<version>3.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
|
@ -108,7 +108,7 @@ public abstract class AbstractMessage
|
||||
|
||||
@Override
|
||||
public final String toString() {
|
||||
return TextFormat.printToString(this);
|
||||
return TextFormat.printer().printToString(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -468,7 +468,7 @@ public abstract class AbstractMessage
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return TextFormat.printToString(this);
|
||||
return TextFormat.printer().printToString(this);
|
||||
}
|
||||
|
||||
/** Construct an UninitializedMessageException reporting missing fields in the given message. */
|
||||
|
@ -76,6 +76,10 @@ public class ExtensionRegistryLite {
|
||||
// applications. Need to support this feature on smaller granularity.
|
||||
private static volatile boolean eagerlyParseMessageSets = false;
|
||||
|
||||
// short circuit the ExtensionRegistryFactory via assumevalues trickery
|
||||
@SuppressWarnings("JavaOptionalSuggestions")
|
||||
private static boolean doFullRuntimeInheritanceCheck = true;
|
||||
|
||||
// Visible for testing.
|
||||
static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension";
|
||||
|
||||
@ -107,7 +111,9 @@ public class ExtensionRegistryLite {
|
||||
* available.
|
||||
*/
|
||||
public static ExtensionRegistryLite newInstance() {
|
||||
return ExtensionRegistryFactory.create();
|
||||
return doFullRuntimeInheritanceCheck
|
||||
? ExtensionRegistryFactory.create()
|
||||
: new ExtensionRegistryLite();
|
||||
}
|
||||
|
||||
private static volatile ExtensionRegistryLite emptyRegistry;
|
||||
@ -122,7 +128,11 @@ public class ExtensionRegistryLite {
|
||||
synchronized (ExtensionRegistryLite.class) {
|
||||
result = emptyRegistry;
|
||||
if (result == null) {
|
||||
result = emptyRegistry = ExtensionRegistryFactory.createEmpty();
|
||||
result =
|
||||
emptyRegistry =
|
||||
doFullRuntimeInheritanceCheck
|
||||
? ExtensionRegistryFactory.createEmpty()
|
||||
: EMPTY_REGISTRY_LITE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -163,7 +173,7 @@ public class ExtensionRegistryLite {
|
||||
if (GeneratedMessageLite.GeneratedExtension.class.isAssignableFrom(extension.getClass())) {
|
||||
add((GeneratedMessageLite.GeneratedExtension<?, ?>) extension);
|
||||
}
|
||||
if (ExtensionRegistryFactory.isFullRegistry(this)) {
|
||||
if (doFullRuntimeInheritanceCheck && ExtensionRegistryFactory.isFullRegistry(this)) {
|
||||
try {
|
||||
this.getClass().getMethod("add", extensionClass).invoke(this, extension);
|
||||
} catch (Exception e) {
|
||||
|
@ -85,7 +85,7 @@ public interface Message extends MessageLite, MessageOrBuilder {
|
||||
|
||||
/**
|
||||
* Converts the message to a string in protocol buffer text format. This is just a trivial wrapper
|
||||
* around {@link TextFormat#printToString(MessageOrBuilder)}.
|
||||
* around {@link TextFormat.Printer#printToString(MessageOrBuilder)}.
|
||||
*/
|
||||
@Override
|
||||
String toString();
|
||||
|
@ -61,135 +61,132 @@ public final class TextFormat {
|
||||
* Outputs a textual representation of the Protocol Message supplied into the parameter output.
|
||||
* (This representation is the new version of the classic "ProtocolPrinter" output from the
|
||||
* original Protocol Buffer system)
|
||||
*
|
||||
* @deprecated Use {@code printer().print(MessageOrBuilder, Appendable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void print(final MessageOrBuilder message, final Appendable output)
|
||||
throws IOException {
|
||||
Printer.DEFAULT.print(message, multiLineOutput(output));
|
||||
printer().print(message, output);
|
||||
}
|
||||
|
||||
/** Outputs a textual representation of {@code fields} to {@code output}. */
|
||||
/**
|
||||
* Outputs a textual representation of {@code fields} to {@code output}.
|
||||
*
|
||||
* @deprecated Use {@code printer().print(UnknownFieldSet, Appendable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void print(final UnknownFieldSet fields, final Appendable output)
|
||||
throws IOException {
|
||||
Printer.DEFAULT.printUnknownFields(fields, multiLineOutput(output));
|
||||
printer().print(fields, output);
|
||||
}
|
||||
|
||||
/** Same as {@code print()}, except that non-ASCII characters are not escaped. */
|
||||
/**
|
||||
* Same as {@code print()}, except that non-ASCII characters are not escaped.
|
||||
*
|
||||
* @deprecated Use {@code printer().escapingNonAscii(false).print(MessageOrBuilder, Appendable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void printUnicode(final MessageOrBuilder message, final Appendable output)
|
||||
throws IOException {
|
||||
Printer.UNICODE.print(message, multiLineOutput(output));
|
||||
printer().escapingNonAscii(false).print(message, output);
|
||||
}
|
||||
|
||||
/** Same as {@code print()}, except that non-ASCII characters are not escaped. */
|
||||
/**
|
||||
* Same as {@code print()}, except that non-ASCII characters are not escaped.
|
||||
*
|
||||
* @deprecated Use {@code printer().escapingNonAscii(false).print(UnknownFieldSet, Appendable)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static void printUnicode(final UnknownFieldSet fields, final Appendable output)
|
||||
throws IOException {
|
||||
Printer.UNICODE.printUnknownFields(fields, multiLineOutput(output));
|
||||
printer().escapingNonAscii(false).print(fields, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a human readable form of this message, useful for debugging and other purposes, with
|
||||
* no newline characters.
|
||||
* no newline characters. This is just a trivial wrapper around
|
||||
* {@link TextFormat.Printer#shortDebugString(MessageOrBuilder)}.
|
||||
*/
|
||||
public static String shortDebugString(final MessageOrBuilder message) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
Printer.DEFAULT.print(message, singleLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return printer().shortDebugString(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a human readable form of the field, useful for debugging and other purposes, with no
|
||||
* newline characters.
|
||||
*
|
||||
* @deprecated Use {@code printer().shortDebugString(FieldDescriptor, Object)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String shortDebugString(final FieldDescriptor field, final Object value) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
Printer.DEFAULT.printField(field, value, singleLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return printer().shortDebugString(field, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a human readable form of the unknown fields, useful for debugging and other purposes,
|
||||
* with no newline characters.
|
||||
*
|
||||
* @deprecated Use {@code printer().shortDebugString(UnknownFieldSet)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String shortDebugString(final UnknownFieldSet fields) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
Printer.DEFAULT.printUnknownFields(fields, singleLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return printer().shortDebugString(fields);
|
||||
}
|
||||
|
||||
/** Like {@code print()}, but writes directly to a {@code String} and returns it. */
|
||||
/**
|
||||
* Like {@code print()}, but writes directly to a {@code String} and returns it.
|
||||
*
|
||||
* @deprecated Use {@link MessageOrBuilder#toString()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String printToString(final MessageOrBuilder message) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
print(message, text);
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return printer().printToString(message);
|
||||
}
|
||||
|
||||
/** Like {@code print()}, but writes directly to a {@code String} and returns it. */
|
||||
/**
|
||||
* Like {@code print()}, but writes directly to a {@code String} and returns it.
|
||||
*
|
||||
* @deprecated Use {@link UnknownFieldSet#toString()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String printToString(final UnknownFieldSet fields) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
print(fields, text);
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return printer().printToString(fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@code printToString()}, except that non-ASCII characters in string type fields are not
|
||||
* escaped in backslash+octals.
|
||||
*
|
||||
* @deprecated Use {@code printer().escapingNonAscii(false).printToString(MessageOrBuilder)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String printToUnicodeString(final MessageOrBuilder message) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
Printer.UNICODE.print(message, multiLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return printer().escapingNonAscii(false).printToString(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@code printToString()}, except that non-ASCII characters in string type fields are not
|
||||
* escaped in backslash+octals.
|
||||
*
|
||||
* @deprecated Use {@code printer().escapingNonAscii(false).printToString(UnknownFieldSet)}
|
||||
*/
|
||||
@Deprecated
|
||||
public static String printToUnicodeString(final UnknownFieldSet fields) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
Printer.UNICODE.printUnknownFields(fields, multiLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return printer().escapingNonAscii(false).printToString(fields);
|
||||
}
|
||||
|
||||
/** @deprecated Use {@code printer().printField(FieldDescriptor, Object, Appendable)} */
|
||||
@Deprecated
|
||||
public static void printField(
|
||||
final FieldDescriptor field, final Object value, final Appendable output) throws IOException {
|
||||
Printer.DEFAULT.printField(field, value, multiLineOutput(output));
|
||||
printer().printField(field, value, output);
|
||||
}
|
||||
|
||||
/** @deprecated Use {@code printer().printFieldToString(FieldDescriptor, Object)} */
|
||||
@Deprecated
|
||||
public static String printFieldToString(final FieldDescriptor field, final Object value) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
printField(field, value, text);
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
return printer().printFieldToString(field, value);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -198,29 +195,34 @@ public final class TextFormat {
|
||||
* <p>Same as {@code printFieldValue()}, except that non-ASCII characters in string type fields
|
||||
* are not escaped in backslash+octals.
|
||||
*
|
||||
* @deprecated Use {@code printer().escapingNonAscii(false).printFieldValue(FieldDescriptor,
|
||||
* Object, Appendable)}
|
||||
* @param field the descriptor of the field
|
||||
* @param value the value of the field
|
||||
* @param output the output to which to append the formatted value
|
||||
* @throws ClassCastException if the value is not appropriate for the given field descriptor
|
||||
* @throws IOException if there is an exception writing to the output
|
||||
*/
|
||||
@Deprecated
|
||||
public static void printUnicodeFieldValue(
|
||||
final FieldDescriptor field, final Object value, final Appendable output) throws IOException {
|
||||
Printer.UNICODE.printFieldValue(field, value, multiLineOutput(output));
|
||||
printer().escapingNonAscii(false).printFieldValue(field, value, output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a textual representation of the value of given field value.
|
||||
*
|
||||
* @deprecated Use {@code printer().printFieldValue(FieldDescriptor, Object, Appendable)}
|
||||
* @param field the descriptor of the field
|
||||
* @param value the value of the field
|
||||
* @param output the output to which to append the formatted value
|
||||
* @throws ClassCastException if the value is not appropriate for the given field descriptor
|
||||
* @throws IOException if there is an exception writing to the output
|
||||
*/
|
||||
@Deprecated
|
||||
public static void printFieldValue(
|
||||
final FieldDescriptor field, final Object value, final Appendable output) throws IOException {
|
||||
Printer.DEFAULT.printFieldValue(field, value, multiLineOutput(output));
|
||||
printer().printFieldValue(field, value, output);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -256,7 +258,7 @@ public final class TextFormat {
|
||||
generator.print("{");
|
||||
generator.eol();
|
||||
generator.indent();
|
||||
Printer.DEFAULT.printUnknownFields(message, generator);
|
||||
Printer.printUnknownFields(message, generator);
|
||||
generator.outdent();
|
||||
generator.print("}");
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
@ -267,19 +269,23 @@ public final class TextFormat {
|
||||
}
|
||||
break;
|
||||
case WireFormat.WIRETYPE_START_GROUP:
|
||||
Printer.DEFAULT.printUnknownFields((UnknownFieldSet) value, generator);
|
||||
Printer.printUnknownFields((UnknownFieldSet) value, generator);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Bad tag: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
/** Printer instance which escapes non-ASCII characters. */
|
||||
public static Printer printer() {
|
||||
return Printer.DEFAULT;
|
||||
}
|
||||
|
||||
/** Helper class for converting protobufs to text. */
|
||||
private static final class Printer {
|
||||
public static final class Printer {
|
||||
|
||||
// Printer instance which escapes non-ASCII characters.
|
||||
static final Printer DEFAULT = new Printer(true);
|
||||
// Printer instance which emits Unicode (it still escapes newlines and quotes in strings).
|
||||
static final Printer UNICODE = new Printer(false);
|
||||
private static final Printer DEFAULT = new Printer(true);
|
||||
|
||||
/** Whether to escape non ASCII characters with backslash and octal. */
|
||||
private final boolean escapeNonAscii;
|
||||
@ -288,12 +294,51 @@ public final class TextFormat {
|
||||
this.escapeNonAscii = escapeNonAscii;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a new Printer instance with the specified escape mode.
|
||||
*
|
||||
* @param escapeNonAscii If true, the new Printer will escape non-ASCII characters (this is the
|
||||
* default behavior. If false, the new Printer will print non-ASCII characters as is. In
|
||||
* either case, the new Printer still escapes newlines and quotes in strings.
|
||||
* @return a new Printer that clones all other configurations from the current {@link Printer},
|
||||
* with the escape mode set to the given parameter.
|
||||
*/
|
||||
public Printer escapingNonAscii(boolean escapeNonAscii) {
|
||||
return new Printer(escapeNonAscii);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a textual representation of the Protocol Message supplied into the parameter output.
|
||||
* (This representation is the new version of the classic "ProtocolPrinter" output from the
|
||||
* original Protocol Buffer system)
|
||||
*/
|
||||
public void print(final MessageOrBuilder message, final Appendable output) throws IOException {
|
||||
print(message, multiLineOutput(output));
|
||||
}
|
||||
|
||||
/** Outputs a textual representation of {@code fields} to {@code output}. */
|
||||
public void print(final UnknownFieldSet fields, final Appendable output) throws IOException {
|
||||
printUnknownFields(fields, multiLineOutput(output));
|
||||
}
|
||||
|
||||
private void print(final MessageOrBuilder message, final TextGenerator generator)
|
||||
throws IOException {
|
||||
for (Map.Entry<FieldDescriptor, Object> field : message.getAllFields().entrySet()) {
|
||||
printField(field.getKey(), field.getValue(), generator);
|
||||
printMessage(message, generator);
|
||||
}
|
||||
|
||||
public String printFieldToString(final FieldDescriptor field, final Object value) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
printField(field, value, text);
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
printUnknownFields(message.getUnknownFields(), generator);
|
||||
}
|
||||
|
||||
public void printField(final FieldDescriptor field, final Object value, final Appendable output)
|
||||
throws IOException {
|
||||
printField(field, value, multiLineOutput(output));
|
||||
}
|
||||
|
||||
private void printField(
|
||||
@ -309,46 +354,19 @@ public final class TextFormat {
|
||||
}
|
||||
}
|
||||
|
||||
private void printSingleField(
|
||||
final FieldDescriptor field, final Object value, final TextGenerator generator)
|
||||
/**
|
||||
* Outputs a textual representation of the value of given field value.
|
||||
*
|
||||
* @param field the descriptor of the field
|
||||
* @param value the value of the field
|
||||
* @param output the output to which to append the formatted value
|
||||
* @throws ClassCastException if the value is not appropriate for the given field descriptor
|
||||
* @throws IOException if there is an exception writing to the output
|
||||
*/
|
||||
public void printFieldValue(
|
||||
final FieldDescriptor field, final Object value, final Appendable output)
|
||||
throws IOException {
|
||||
if (field.isExtension()) {
|
||||
generator.print("[");
|
||||
// We special-case MessageSet elements for compatibility with proto1.
|
||||
if (field.getContainingType().getOptions().getMessageSetWireFormat()
|
||||
&& (field.getType() == FieldDescriptor.Type.MESSAGE)
|
||||
&& (field.isOptional())
|
||||
// object equality
|
||||
&& (field.getExtensionScope() == field.getMessageType())) {
|
||||
generator.print(field.getMessageType().getFullName());
|
||||
} else {
|
||||
generator.print(field.getFullName());
|
||||
}
|
||||
generator.print("]");
|
||||
} else {
|
||||
if (field.getType() == FieldDescriptor.Type.GROUP) {
|
||||
// Groups must be serialized with their original capitalization.
|
||||
generator.print(field.getMessageType().getName());
|
||||
} else {
|
||||
generator.print(field.getName());
|
||||
}
|
||||
}
|
||||
|
||||
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
||||
generator.print(" {");
|
||||
generator.eol();
|
||||
generator.indent();
|
||||
} else {
|
||||
generator.print(": ");
|
||||
}
|
||||
|
||||
printFieldValue(field, value, generator);
|
||||
|
||||
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
||||
generator.outdent();
|
||||
generator.print("}");
|
||||
}
|
||||
generator.eol();
|
||||
printFieldValue(field, value, multiLineOutput(output));
|
||||
}
|
||||
|
||||
private void printFieldValue(
|
||||
@ -419,7 +437,157 @@ public final class TextFormat {
|
||||
}
|
||||
}
|
||||
|
||||
private void printUnknownFields(
|
||||
/** Like {@code print()}, but writes directly to a {@code String} and returns it. */
|
||||
public String printToString(final MessageOrBuilder message) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
print(message, text);
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
/** Like {@code print()}, but writes directly to a {@code String} and returns it. */
|
||||
public String printToString(final UnknownFieldSet fields) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
print(fields, text);
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a human readable form of this message, useful for debugging and other purposes,
|
||||
* with no newline characters.
|
||||
*/
|
||||
public String shortDebugString(final MessageOrBuilder message) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
print(message, singleLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a human readable form of the field, useful for debugging and other purposes, with
|
||||
* no newline characters.
|
||||
*/
|
||||
public String shortDebugString(final FieldDescriptor field, final Object value) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
printField(field, value, singleLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a human readable form of the unknown fields, useful for debugging and other
|
||||
* purposes, with no newline characters.
|
||||
*/
|
||||
public String shortDebugString(final UnknownFieldSet fields) {
|
||||
try {
|
||||
final StringBuilder text = new StringBuilder();
|
||||
printUnknownFields(fields, singleLineOutput(text));
|
||||
return text.toString();
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void printUnknownFieldValue(
|
||||
final int tag, final Object value, final TextGenerator generator) throws IOException {
|
||||
switch (WireFormat.getTagWireType(tag)) {
|
||||
case WireFormat.WIRETYPE_VARINT:
|
||||
generator.print(unsignedToString((Long) value));
|
||||
break;
|
||||
case WireFormat.WIRETYPE_FIXED32:
|
||||
generator.print(String.format((Locale) null, "0x%08x", (Integer) value));
|
||||
break;
|
||||
case WireFormat.WIRETYPE_FIXED64:
|
||||
generator.print(String.format((Locale) null, "0x%016x", (Long) value));
|
||||
break;
|
||||
case WireFormat.WIRETYPE_LENGTH_DELIMITED:
|
||||
try {
|
||||
// Try to parse and print the field as an embedded message
|
||||
UnknownFieldSet message = UnknownFieldSet.parseFrom((ByteString) value);
|
||||
generator.print("{");
|
||||
generator.eol();
|
||||
generator.indent();
|
||||
printUnknownFields(message, generator);
|
||||
generator.outdent();
|
||||
generator.print("}");
|
||||
} catch (InvalidProtocolBufferException e) {
|
||||
// If not parseable as a message, print as a String
|
||||
generator.print("\"");
|
||||
generator.print(escapeBytes((ByteString) value));
|
||||
generator.print("\"");
|
||||
}
|
||||
break;
|
||||
case WireFormat.WIRETYPE_START_GROUP:
|
||||
printUnknownFields((UnknownFieldSet) value, generator);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Bad tag: " + tag);
|
||||
}
|
||||
}
|
||||
|
||||
private void printMessage(final MessageOrBuilder message, final TextGenerator generator)
|
||||
throws IOException {
|
||||
for (Map.Entry<FieldDescriptor, Object> field : message.getAllFields().entrySet()) {
|
||||
printField(field.getKey(), field.getValue(), generator);
|
||||
}
|
||||
printUnknownFields(message.getUnknownFields(), generator);
|
||||
}
|
||||
|
||||
private void printSingleField(
|
||||
final FieldDescriptor field, final Object value, final TextGenerator generator)
|
||||
throws IOException {
|
||||
if (field.isExtension()) {
|
||||
generator.print("[");
|
||||
// We special-case MessageSet elements for compatibility with proto1.
|
||||
if (field.getContainingType().getOptions().getMessageSetWireFormat()
|
||||
&& (field.getType() == FieldDescriptor.Type.MESSAGE)
|
||||
&& (field.isOptional())
|
||||
// object equality
|
||||
&& (field.getExtensionScope() == field.getMessageType())) {
|
||||
generator.print(field.getMessageType().getFullName());
|
||||
} else {
|
||||
generator.print(field.getFullName());
|
||||
}
|
||||
generator.print("]");
|
||||
} else {
|
||||
if (field.getType() == FieldDescriptor.Type.GROUP) {
|
||||
// Groups must be serialized with their original capitalization.
|
||||
generator.print(field.getMessageType().getName());
|
||||
} else {
|
||||
generator.print(field.getName());
|
||||
}
|
||||
}
|
||||
|
||||
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
||||
generator.print(" {");
|
||||
generator.eol();
|
||||
generator.indent();
|
||||
} else {
|
||||
generator.print(": ");
|
||||
}
|
||||
|
||||
printFieldValue(field, value, generator);
|
||||
|
||||
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) {
|
||||
generator.outdent();
|
||||
generator.print("}");
|
||||
}
|
||||
generator.eol();
|
||||
}
|
||||
|
||||
private static void printUnknownFields(
|
||||
final UnknownFieldSet unknownFields, final TextGenerator generator) throws IOException {
|
||||
for (Map.Entry<Integer, UnknownFieldSet.Field> entry : unknownFields.asMap().entrySet()) {
|
||||
final int number = entry.getKey();
|
||||
@ -445,7 +613,7 @@ public final class TextFormat {
|
||||
}
|
||||
}
|
||||
|
||||
private void printUnknownField(
|
||||
private static void printUnknownField(
|
||||
final int number, final int wireType, final List<?> values, final TextGenerator generator)
|
||||
throws IOException {
|
||||
for (final Object value : values) {
|
||||
@ -1994,7 +2162,7 @@ public final class TextFormat {
|
||||
return escapeBytes(ByteString.copyFromUtf8(input));
|
||||
}
|
||||
|
||||
/** Escape double quotes and backslashes in a String for unicode output of a message. */
|
||||
/** Escape double quotes and backslashes in a String for emittingUnicode output of a message. */
|
||||
public static String escapeDoubleQuotesAndBackslashes(final String input) {
|
||||
return TextFormatEscaper.escapeDoubleQuotesAndBackslashes(input);
|
||||
}
|
||||
|
@ -140,11 +140,11 @@ public final class UnknownFieldSet implements MessageLite {
|
||||
|
||||
/**
|
||||
* Converts the set to a string in protocol buffer text format. This is just a trivial wrapper
|
||||
* around {@link TextFormat#printToString(UnknownFieldSet)}.
|
||||
* around {@link TextFormat.Printer#printToString(UnknownFieldSet)}.
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return TextFormat.printToString(this);
|
||||
return TextFormat.printer().printToString(this);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -766,7 +766,7 @@ public class MapForProto2Test extends TestCase {
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
|
||||
String textData = TextFormat.printToString(message);
|
||||
String textData = TextFormat.printer().printToString(message);
|
||||
|
||||
builder = TestMap.newBuilder();
|
||||
TextFormat.merge(textData, builder);
|
||||
|
@ -857,7 +857,7 @@ public class MapTest extends TestCase {
|
||||
setMapValuesUsingAccessors(builder);
|
||||
TestMap message = builder.build();
|
||||
|
||||
String textData = TextFormat.printToString(message);
|
||||
String textData = TextFormat.printer().printToString(message);
|
||||
|
||||
builder = TestMap.newBuilder();
|
||||
TextFormat.merge(textData, builder);
|
||||
|
@ -147,7 +147,7 @@ public class TextFormatTest extends TestCase {
|
||||
|
||||
/** Print TestAllTypes and compare with golden file. */
|
||||
public void testPrintMessage() throws Exception {
|
||||
String javaText = TextFormat.printToString(TestUtil.getAllSet());
|
||||
String javaText = TextFormat.printer().printToString(TestUtil.getAllSet());
|
||||
|
||||
// Java likes to add a trailing ".0" to floats and doubles. C printf
|
||||
// (with %g format) does not. Our golden files are used for both
|
||||
@ -159,7 +159,7 @@ public class TextFormatTest extends TestCase {
|
||||
|
||||
/** Print TestAllTypes as Builder and compare with golden file. */
|
||||
public void testPrintMessageBuilder() throws Exception {
|
||||
String javaText = TextFormat.printToString(TestUtil.getAllSetBuilder());
|
||||
String javaText = TextFormat.printer().printToString(TestUtil.getAllSetBuilder());
|
||||
|
||||
// Java likes to add a trailing ".0" to floats and doubles. C printf
|
||||
// (with %g format) does not. Our golden files are used for both
|
||||
@ -171,7 +171,7 @@ public class TextFormatTest extends TestCase {
|
||||
|
||||
/** Print TestAllExtensions and compare with golden file. */
|
||||
public void testPrintExtensions() throws Exception {
|
||||
String javaText = TextFormat.printToString(TestUtil.getAllExtensionsSet());
|
||||
String javaText = TextFormat.printer().printToString(TestUtil.getAllExtensionsSet());
|
||||
|
||||
// Java likes to add a trailing ".0" to floats and doubles. C printf
|
||||
// (with %g format) does not. Our golden files are used for both
|
||||
@ -237,12 +237,13 @@ public class TextFormatTest extends TestCase {
|
||||
+ "15: 12379813812177893520\n"
|
||||
+ "15: 0xabcd1234\n"
|
||||
+ "15: 0xabcdef1234567890\n",
|
||||
TextFormat.printToString(message));
|
||||
TextFormat.printer().printToString(message));
|
||||
}
|
||||
|
||||
public void testPrintField() throws Exception {
|
||||
final FieldDescriptor dataField = OneString.getDescriptor().findFieldByName("data");
|
||||
assertEquals("data: \"test data\"\n", TextFormat.printFieldToString(dataField, "test data"));
|
||||
assertEquals(
|
||||
"data: \"test data\"\n", TextFormat.printer().printFieldToString(dataField, "test data"));
|
||||
|
||||
final FieldDescriptor optionalField =
|
||||
TestAllTypes.getDescriptor().findFieldByName("optional_nested_message");
|
||||
@ -250,7 +251,7 @@ public class TextFormatTest extends TestCase {
|
||||
|
||||
assertEquals(
|
||||
"optional_nested_message {\n bb: 42\n}\n",
|
||||
TextFormat.printFieldToString(optionalField, value));
|
||||
TextFormat.printer().printFieldToString(optionalField, value));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -885,7 +886,8 @@ public class TextFormatTest extends TestCase {
|
||||
private void assertPrintFieldValue(String expect, Object value, String fieldName)
|
||||
throws Exception {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
TextFormat.printFieldValue(TestAllTypes.getDescriptor().findFieldByName(fieldName), value, sb);
|
||||
TextFormat.printer()
|
||||
.printFieldValue(TestAllTypes.getDescriptor().findFieldByName(fieldName), value, sb);
|
||||
assertEquals(expect, sb.toString());
|
||||
}
|
||||
|
||||
@ -902,14 +904,17 @@ public class TextFormatTest extends TestCase {
|
||||
|
||||
public void testShortDebugString_field() {
|
||||
final FieldDescriptor dataField = OneString.getDescriptor().findFieldByName("data");
|
||||
assertEquals("data: \"test data\"", TextFormat.shortDebugString(dataField, "test data"));
|
||||
assertEquals(
|
||||
"data: \"test data\"",
|
||||
TextFormat.printer().shortDebugString(dataField, "test data"));
|
||||
|
||||
final FieldDescriptor optionalField =
|
||||
TestAllTypes.getDescriptor().findFieldByName("optional_nested_message");
|
||||
final Object value = NestedMessage.newBuilder().setBb(42).build();
|
||||
|
||||
assertEquals(
|
||||
"optional_nested_message { bb: 42 }", TextFormat.shortDebugString(optionalField, value));
|
||||
"optional_nested_message { bb: 42 }",
|
||||
TextFormat.printer().shortDebugString(optionalField, value));
|
||||
}
|
||||
|
||||
public void testShortDebugString_unknown() {
|
||||
@ -917,7 +922,7 @@ public class TextFormatTest extends TestCase {
|
||||
"5: 1 5: 0x00000002 5: 0x0000000000000003 5: \"4\" 5: { 12: 6 } 5 { 10: 5 }"
|
||||
+ " 8: 1 8: 2 8: 3 15: 12379813812177893520 15: 0xabcd1234 15:"
|
||||
+ " 0xabcdef1234567890",
|
||||
TextFormat.shortDebugString(makeUnknownFieldSet()));
|
||||
TextFormat.printer().shortDebugString(makeUnknownFieldSet()));
|
||||
}
|
||||
|
||||
public void testPrintToUnicodeString() throws Exception {
|
||||
@ -925,23 +930,26 @@ public class TextFormatTest extends TestCase {
|
||||
"optional_string: \"abc\u3042efg\"\n"
|
||||
+ "optional_bytes: \"\\343\\201\\202\"\n"
|
||||
+ "repeated_string: \"\u3093XYZ\"\n",
|
||||
TextFormat.printToUnicodeString(
|
||||
TestAllTypes.newBuilder()
|
||||
.setOptionalString("abc\u3042efg")
|
||||
.setOptionalBytes(bytes(0xe3, 0x81, 0x82))
|
||||
.addRepeatedString("\u3093XYZ")
|
||||
.build()));
|
||||
TextFormat.printer()
|
||||
.escapingNonAscii(false)
|
||||
.printToString(
|
||||
TestAllTypes.newBuilder()
|
||||
.setOptionalString("abc\u3042efg")
|
||||
.setOptionalBytes(bytes(0xe3, 0x81, 0x82))
|
||||
.addRepeatedString("\u3093XYZ")
|
||||
.build()));
|
||||
|
||||
// Double quotes and backslashes should be escaped
|
||||
assertEquals(
|
||||
"optional_string: \"a\\\\bc\\\"ef\\\"g\"\n",
|
||||
TextFormat.printToUnicodeString(
|
||||
TestAllTypes.newBuilder().setOptionalString("a\\bc\"ef\"g").build()));
|
||||
TextFormat.printer()
|
||||
.escapingNonAscii(false)
|
||||
.printToString(TestAllTypes.newBuilder().setOptionalString("a\\bc\"ef\"g").build()));
|
||||
|
||||
// Test escaping roundtrip
|
||||
TestAllTypes message = TestAllTypes.newBuilder().setOptionalString("a\\bc\\\"ef\"g").build();
|
||||
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
|
||||
TextFormat.merge(TextFormat.printToUnicodeString(message), builder);
|
||||
TextFormat.merge(TextFormat.printer().escapingNonAscii(false).printToString(message), builder);
|
||||
assertEquals(message.getOptionalString(), builder.getOptionalString());
|
||||
}
|
||||
|
||||
@ -949,48 +957,61 @@ public class TextFormatTest extends TestCase {
|
||||
// No newlines at start and end
|
||||
assertEquals(
|
||||
"optional_string: \"test newlines\\n\\nin\\nstring\"\n",
|
||||
TextFormat.printToUnicodeString(
|
||||
TestAllTypes.newBuilder().setOptionalString("test newlines\n\nin\nstring").build()));
|
||||
TextFormat.printer()
|
||||
.escapingNonAscii(false)
|
||||
.printToString(
|
||||
TestAllTypes.newBuilder()
|
||||
.setOptionalString("test newlines\n\nin\nstring")
|
||||
.build()));
|
||||
|
||||
// Newlines at start and end
|
||||
assertEquals(
|
||||
"optional_string: \"\\ntest\\nnewlines\\n\\nin\\nstring\\n\"\n",
|
||||
TextFormat.printToUnicodeString(
|
||||
TestAllTypes.newBuilder()
|
||||
.setOptionalString("\ntest\nnewlines\n\nin\nstring\n")
|
||||
.build()));
|
||||
TextFormat.printer()
|
||||
.escapingNonAscii(false)
|
||||
.printToString(
|
||||
TestAllTypes.newBuilder()
|
||||
.setOptionalString("\ntest\nnewlines\n\nin\nstring\n")
|
||||
.build()));
|
||||
|
||||
// Strings with 0, 1 and 2 newlines.
|
||||
assertEquals(
|
||||
"optional_string: \"\"\n",
|
||||
TextFormat.printToUnicodeString(TestAllTypes.newBuilder().setOptionalString("").build()));
|
||||
TextFormat.printer()
|
||||
.escapingNonAscii(false)
|
||||
.printToString(TestAllTypes.newBuilder().setOptionalString("").build()));
|
||||
assertEquals(
|
||||
"optional_string: \"\\n\"\n",
|
||||
TextFormat.printToUnicodeString(TestAllTypes.newBuilder().setOptionalString("\n").build()));
|
||||
TextFormat.printer()
|
||||
.escapingNonAscii(false)
|
||||
.printToString(TestAllTypes.newBuilder().setOptionalString("\n").build()));
|
||||
assertEquals(
|
||||
"optional_string: \"\\n\\n\"\n",
|
||||
TextFormat.printToUnicodeString(
|
||||
TestAllTypes.newBuilder().setOptionalString("\n\n").build()));
|
||||
TextFormat.printer()
|
||||
.escapingNonAscii(false)
|
||||
.printToString(TestAllTypes.newBuilder().setOptionalString("\n\n").build()));
|
||||
|
||||
// Test escaping roundtrip
|
||||
TestAllTypes message =
|
||||
TestAllTypes.newBuilder().setOptionalString("\ntest\nnewlines\n\nin\nstring\n").build();
|
||||
TestAllTypes.Builder builder = TestAllTypes.newBuilder();
|
||||
TextFormat.merge(TextFormat.printToUnicodeString(message), builder);
|
||||
TextFormat.merge(TextFormat.printer().escapingNonAscii(false).printToString(message), builder);
|
||||
assertEquals(message.getOptionalString(), builder.getOptionalString());
|
||||
}
|
||||
|
||||
public void testPrintToUnicodeString_unknown() {
|
||||
assertEquals(
|
||||
"1: \"\\343\\201\\202\"\n",
|
||||
TextFormat.printToUnicodeString(
|
||||
UnknownFieldSet.newBuilder()
|
||||
.addField(
|
||||
1,
|
||||
UnknownFieldSet.Field.newBuilder()
|
||||
.addLengthDelimited(bytes(0xe3, 0x81, 0x82))
|
||||
.build())
|
||||
.build()));
|
||||
TextFormat.printer()
|
||||
.escapingNonAscii(false)
|
||||
.printToString(
|
||||
UnknownFieldSet.newBuilder()
|
||||
.addField(
|
||||
1,
|
||||
UnknownFieldSet.Field.newBuilder()
|
||||
.addLengthDelimited(bytes(0xe3, 0x81, 0x82))
|
||||
.build())
|
||||
.build()));
|
||||
}
|
||||
|
||||
|
||||
@ -1120,7 +1141,7 @@ public class TextFormatTest extends TestCase {
|
||||
TestUtil.setOneof(builder);
|
||||
TestOneof2 message = builder.build();
|
||||
TestOneof2.Builder dest = TestOneof2.newBuilder();
|
||||
TextFormat.merge(TextFormat.printToUnicodeString(message), dest);
|
||||
TextFormat.merge(TextFormat.printer().escapingNonAscii(false).printToString(message), dest);
|
||||
TestUtil.assertOneofSet(dest.build());
|
||||
}
|
||||
|
||||
@ -1159,7 +1180,7 @@ public class TextFormatTest extends TestCase {
|
||||
.putInt32ToStringField(20, "banana")
|
||||
.putInt32ToStringField(30, "cherry")
|
||||
.build();
|
||||
String text = TextFormat.printToUnicodeString(message);
|
||||
String text = TextFormat.printer().escapingNonAscii(false).printToString(message);
|
||||
{
|
||||
TestMap.Builder dest = TestMap.newBuilder();
|
||||
TextFormat.merge(text, dest);
|
||||
|
@ -234,7 +234,7 @@ public class UnknownEnumValueTest extends TestCase {
|
||||
TestAllTypes message = builder.build();
|
||||
|
||||
// We can print a message with unknown enum values.
|
||||
String textData = TextFormat.printToString(message);
|
||||
String textData = TextFormat.printer().printToString(message);
|
||||
assertEquals(
|
||||
"optional_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_4321\n"
|
||||
+ "repeated_nested_enum: UNKNOWN_ENUM_VALUE_NestedEnum_5432\n"
|
||||
|
@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-parent</artifactId>
|
||||
<version>3.7.0</version>
|
||||
<version>3.8.0-rc-1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>protobuf-javalite</artifactId>
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-parent</artifactId>
|
||||
<version>3.7.1</version>
|
||||
<version>3.8.0</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Protocol Buffers [Parent]</name>
|
||||
@ -101,6 +101,12 @@
|
||||
<version>26.0-jre</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.truth</groupId>
|
||||
<artifactId>truth</artifactId>
|
||||
<version>0.45</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
@ -1,134 +1,139 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-parent</artifactId>
|
||||
<version>3.7.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>protobuf-java-util</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>Protocol Buffers [Util]</name>
|
||||
<description>Utilities for Protocol Buffers</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava-testlib</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymockclassextension</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<!-- Use the core proto dir so that we can call the core generation script -->
|
||||
<test.proto.dir>../core/src/test/proto</test.proto.dir>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<!-- Generate the test protos -->
|
||||
<execution>
|
||||
<id>generate-test-sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<configuration>
|
||||
<target>
|
||||
<!-- Generate all of the test protos from the core module -->
|
||||
<ant antfile="../core/generate-test-sources-build.xml"/>
|
||||
|
||||
<!-- Generate additional test protos for this module -->
|
||||
<exec executable="${protoc}">
|
||||
<arg value="--java_out=${generated.testsources.dir}"/>
|
||||
<arg value="--proto_path=${protobuf.source.dir}"/>
|
||||
<arg value="--proto_path=src/test/proto"/>
|
||||
<arg value="src/test/proto/com/google/protobuf/util/json_test.proto"/>
|
||||
</exec>
|
||||
</target>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Add the generated test sources to the build -->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-generated-test-sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${generated.testsources.dir}</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Configure the OSGI bundle -->
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
|
||||
<Bundle-SymbolicName>com.google.protobuf.util</Bundle-SymbolicName>
|
||||
<Export-Package>com.google.protobuf.util;version=${project.version}</Export-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Configure the fat jar to include all dependencies -->
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protobuf-parent</artifactId>
|
||||
<version>3.8.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>protobuf-java-util</artifactId>
|
||||
<packaging>bundle</packaging>
|
||||
|
||||
<name>Protocol Buffers [Util]</name>
|
||||
<description>Utilities for Protocol Buffers</description>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>${project.groupId}</groupId>
|
||||
<artifactId>protobuf-java</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.errorprone</groupId>
|
||||
<artifactId>error_prone_annotations</artifactId>
|
||||
<version>2.3.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava-testlib</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.5</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymock</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.easymock</groupId>
|
||||
<artifactId>easymockclassextension</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.truth</groupId>
|
||||
<artifactId>truth</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<properties>
|
||||
<!-- Use the core proto dir so that we can call the core generation script -->
|
||||
<test.proto.dir>../core/src/test/proto</test.proto.dir>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<executions>
|
||||
<!-- Generate the test protos -->
|
||||
<execution>
|
||||
<id>generate-test-sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<configuration>
|
||||
<target>
|
||||
<!-- Generate all of the test protos from the core module -->
|
||||
<ant antfile="../core/generate-test-sources-build.xml"/>
|
||||
|
||||
<!-- Generate additional test protos for this module -->
|
||||
<exec executable="${protoc}">
|
||||
<arg value="--java_out=${generated.testsources.dir}"/>
|
||||
<arg value="--proto_path=${protobuf.source.dir}"/>
|
||||
<arg value="--proto_path=src/test/proto"/>
|
||||
<arg value="src/test/proto/com/google/protobuf/util/json_test.proto"/>
|
||||
</exec>
|
||||
</target>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Add the generated test sources to the build -->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>add-generated-test-sources</id>
|
||||
<phase>generate-test-sources</phase>
|
||||
<goals>
|
||||
<goal>add-test-source</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<sources>
|
||||
<source>${generated.testsources.dir}</source>
|
||||
</sources>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
|
||||
<!-- Configure the OSGI bundle -->
|
||||
<plugin>
|
||||
<groupId>org.apache.felix</groupId>
|
||||
<artifactId>maven-bundle-plugin</artifactId>
|
||||
<extensions>true</extensions>
|
||||
<configuration>
|
||||
<instructions>
|
||||
<Bundle-DocURL>https://developers.google.com/protocol-buffers/</Bundle-DocURL>
|
||||
<Bundle-SymbolicName>com.google.protobuf.util</Bundle-SymbolicName>
|
||||
<Export-Package>com.google.protobuf.util;version=${project.version}</Export-Package>
|
||||
</instructions>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
<!-- Configure the fat jar to include all dependencies -->
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
|
65
java/util/src/main/java/com/google/protobuf/util/Structs.java
Executable file
65
java/util/src/main/java/com/google/protobuf/util/Structs.java
Executable file
@ -0,0 +1,65 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf.util;
|
||||
|
||||
import com.google.protobuf.Struct;
|
||||
import com.google.protobuf.Value;
|
||||
|
||||
/** Utilities to help create {@code google.protobuf.Struct} messages. */
|
||||
public final class Structs {
|
||||
|
||||
/**
|
||||
* Returns a struct containing the key-value pair.
|
||||
*/
|
||||
public static Struct of(String k1, Value v1) {
|
||||
return Struct.newBuilder().putFields(k1, v1).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a struct containing each of the key-value pairs.
|
||||
*
|
||||
* <p>Providing duplicate keys is undefined behavior.
|
||||
*/
|
||||
public static Struct of(String k1, Value v1, String k2, Value v2) {
|
||||
return Struct.newBuilder().putFields(k1, v1).putFields(k2, v2).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a struct containing each of the key-value pairs.
|
||||
*
|
||||
* <p>Providing duplicate keys is undefined behavior.
|
||||
*/
|
||||
public static Struct of(String k1, Value v1, String k2, Value v2, String k3, Value v3) {
|
||||
return Struct.newBuilder().putFields(k1, v1).putFields(k2, v2).putFields(k3, v3).build();
|
||||
}
|
||||
|
||||
private Structs() {}
|
||||
}
|
85
java/util/src/main/java/com/google/protobuf/util/Values.java
Executable file
85
java/util/src/main/java/com/google/protobuf/util/Values.java
Executable file
@ -0,0 +1,85 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf.util;
|
||||
|
||||
import com.google.protobuf.ListValue;
|
||||
import com.google.protobuf.NullValue;
|
||||
import com.google.protobuf.Struct;
|
||||
import com.google.protobuf.Value;
|
||||
|
||||
/** Utilities to help create {@code google.protobuf.Value} messages. */
|
||||
public final class Values {
|
||||
|
||||
private static final Value NULL_VALUE =
|
||||
Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build();
|
||||
|
||||
public static Value ofNull() {
|
||||
return NULL_VALUE;
|
||||
}
|
||||
|
||||
/** Returns a Value object with number set to value. */
|
||||
public static Value of(boolean value) {
|
||||
return Value.newBuilder().setBoolValue(value).build();
|
||||
}
|
||||
|
||||
/** Returns a Value object with number set to value. */
|
||||
public static Value of(double value) {
|
||||
return Value.newBuilder().setNumberValue(value).build();
|
||||
}
|
||||
|
||||
/** Returns a Value object with string set to value. */
|
||||
public static Value of(String value) {
|
||||
return Value.newBuilder().setStringValue(value).build();
|
||||
}
|
||||
|
||||
/** Returns a Value object with struct set to value. */
|
||||
public static Value of(Struct value) {
|
||||
return Value.newBuilder().setStructValue(value).build();
|
||||
}
|
||||
|
||||
/** Returns a Value with ListValue set to value. */
|
||||
public static Value of(ListValue value) {
|
||||
return Value.newBuilder().setListValue(value).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a Value with ListValue set to the appending the result of calling {@link #of(Object)}
|
||||
* on each element in the iterable.
|
||||
*/
|
||||
public static Value of(Iterable<Value> values) {
|
||||
Value.Builder valueBuilder = Value.newBuilder();
|
||||
ListValue.Builder listValue = valueBuilder.getListValueBuilder();
|
||||
listValue.addAllValues(values);
|
||||
return valueBuilder.build();
|
||||
}
|
||||
|
||||
private Values() {}
|
||||
}
|
59
java/util/src/test/java/com/google/protobuf/util/StructsTest.java
Executable file
59
java/util/src/test/java/com/google/protobuf/util/StructsTest.java
Executable file
@ -0,0 +1,59 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf.util;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.google.protobuf.Struct;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public final class StructsTest extends TestCase {
|
||||
|
||||
public void test1pair_constructsObject() throws Exception {
|
||||
Struct.Builder expected = Struct.newBuilder();
|
||||
JsonFormat.parser().merge("{\"k1\": 1}", expected);
|
||||
assertThat(Structs.of("k1", Values.of(1))).isEqualTo(expected.build());
|
||||
}
|
||||
|
||||
public void test2pair_constructsObject() throws Exception {
|
||||
Struct.Builder expected = Struct.newBuilder();
|
||||
JsonFormat.parser().merge("{\"k1\": 1, \"k2\": 2}", expected);
|
||||
assertThat(Structs.of("k1", Values.of(1), "k2", Values.of(2))).isEqualTo(expected.build());
|
||||
}
|
||||
|
||||
public void test3pair_constructsObject() throws Exception {
|
||||
Struct.Builder expected = Struct.newBuilder();
|
||||
JsonFormat.parser().merge("{\"k1\": 1, \"k2\": 2, \"k3\": 3}", expected);
|
||||
assertThat(Structs.of("k1", Values.of(1), "k2", Values.of(2), "k3", Values.of(3)))
|
||||
.isEqualTo(expected.build());
|
||||
}
|
||||
|
||||
}
|
102
java/util/src/test/java/com/google/protobuf/util/ValuesTest.java
Executable file
102
java/util/src/test/java/com/google/protobuf/util/ValuesTest.java
Executable file
@ -0,0 +1,102 @@
|
||||
// Protocol Buffers - Google's data interchange format
|
||||
// Copyright 2008 Google Inc. All rights reserved.
|
||||
// https://developers.google.com/protocol-buffers/
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are
|
||||
// met:
|
||||
//
|
||||
// * Redistributions of source code must retain the above copyright
|
||||
// notice, this list of conditions and the following disclaimer.
|
||||
// * Redistributions in binary form must reproduce the above
|
||||
// copyright notice, this list of conditions and the following disclaimer
|
||||
// in the documentation and/or other materials provided with the
|
||||
// distribution.
|
||||
// * Neither the name of Google Inc. nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from
|
||||
// this software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
package com.google.protobuf.util;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import com.google.protobuf.ListValue;
|
||||
import com.google.protobuf.NullValue;
|
||||
import com.google.protobuf.Struct;
|
||||
import com.google.protobuf.Value;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import junit.framework.TestCase;
|
||||
|
||||
public final class ValuesTest extends TestCase {
|
||||
public void testOfNull_IsNullValue() throws Exception {
|
||||
assertThat(Values.ofNull())
|
||||
.isEqualTo(Value.newBuilder().setNullValue(NullValue.NULL_VALUE).build());
|
||||
}
|
||||
|
||||
public void testOfBoolean_ConstructsValue() {
|
||||
assertThat(Values.of(true)).isEqualTo(Value.newBuilder().setBoolValue(true).build());
|
||||
assertThat(Values.of(false)).isEqualTo(Value.newBuilder().setBoolValue(false).build());
|
||||
}
|
||||
|
||||
public void testOfNumeric_ConstructsValue() {
|
||||
assertThat(Values.of(100)).isEqualTo(Value.newBuilder().setNumberValue(100).build());
|
||||
assertThat(Values.of(1000L)).isEqualTo(Value.newBuilder().setNumberValue(1000).build());
|
||||
assertThat(Values.of(1000.23f)).isEqualTo(Value.newBuilder().setNumberValue(1000.23f).build());
|
||||
assertThat(Values.of(10000.23)).isEqualTo(Value.newBuilder().setNumberValue(10000.23).build());
|
||||
}
|
||||
|
||||
public void testOfString_ConstructsValue() {
|
||||
assertThat(Values.of("")).isEqualTo(Value.newBuilder().setStringValue("").build());
|
||||
assertThat(Values.of("foo")).isEqualTo(Value.newBuilder().setStringValue("foo").build());
|
||||
}
|
||||
|
||||
public void testOfStruct_ConstructsValue() {
|
||||
Struct.Builder builder = Struct.newBuilder();
|
||||
builder.putFields("a", Values.of("a"));
|
||||
builder.putFields("b", Values.of("b"));
|
||||
|
||||
assertThat(Values.of(builder.build()))
|
||||
.isEqualTo(Value.newBuilder().setStructValue(builder.build()).build());
|
||||
}
|
||||
|
||||
public void testOfListValue_ConstructsInstance() {
|
||||
ListValue.Builder builder = ListValue.newBuilder();
|
||||
builder.addValues(Values.of(1));
|
||||
builder.addValues(Values.of(2));
|
||||
|
||||
assertThat(Values.of(builder.build()))
|
||||
.isEqualTo(Value.newBuilder().setListValue(builder.build()).build());
|
||||
}
|
||||
|
||||
public void testOfIterable_ReturnsTheValue() {
|
||||
ListValue.Builder builder = ListValue.newBuilder();
|
||||
builder.addValues(Values.of(1));
|
||||
builder.addValues(Values.of(2));
|
||||
builder.addValues(Values.of(true));
|
||||
builder.addValues(Value.newBuilder().setListValue(builder.build()).build());
|
||||
|
||||
List<Value> list = new ArrayList<>();
|
||||
list.add(Values.of(1));
|
||||
list.add(Values.of(2));
|
||||
list.add(Values.of(true));
|
||||
List<Value> copyList = new ArrayList<>(list);
|
||||
list.add(Values.of(copyList));
|
||||
|
||||
assertThat(Values.of(list)).isEqualTo(Value.newBuilder().setListValue(builder).build());
|
||||
assertThat(Values.of(new ArrayList<Value>()))
|
||||
.isEqualTo(Value.newBuilder().setListValue(ListValue.getDefaultInstance()).build());
|
||||
}
|
||||
}
|
@ -958,19 +958,19 @@ jspb.Message.getMapField = function(msg, fieldNumber, noLazyCreate,
|
||||
// If we already have a map in the map wrappers, return that.
|
||||
if (fieldNumber in msg.wrappers_) {
|
||||
return msg.wrappers_[fieldNumber];
|
||||
} else if (noLazyCreate) {
|
||||
return undefined;
|
||||
} else {
|
||||
// Wrap the underlying elements array with a Map.
|
||||
var arr = jspb.Message.getField(msg, fieldNumber);
|
||||
if (!arr) {
|
||||
arr = [];
|
||||
jspb.Message.setField(msg, fieldNumber, arr);
|
||||
}
|
||||
return msg.wrappers_[fieldNumber] =
|
||||
new jspb.Map(
|
||||
/** @type {!Array<!Array<!Object>>} */ (arr), opt_valueCtor);
|
||||
}
|
||||
var arr = jspb.Message.getField(msg, fieldNumber);
|
||||
// Wrap the underlying elements array with a Map.
|
||||
if (!arr) {
|
||||
if (noLazyCreate) {
|
||||
return undefined;
|
||||
}
|
||||
arr = [];
|
||||
jspb.Message.setField(msg, fieldNumber, arr);
|
||||
}
|
||||
return msg.wrappers_[fieldNumber] =
|
||||
new jspb.Map(
|
||||
/** @type {!Array<!Array<!Object>>} */ (arr), opt_valueCtor);
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "google-protobuf",
|
||||
"version": "3.7.1",
|
||||
"version": "3.8.0",
|
||||
"description": "Protocol Buffers for JavaScript",
|
||||
"main": "google-protobuf.js",
|
||||
"files": [
|
||||
|
@ -41,7 +41,7 @@ OPTIONS:
|
||||
Skip the Xcode Debug configuration.
|
||||
--skip-xcode-release
|
||||
Skip the Xcode Release configuration.
|
||||
--skip-xcode-osx
|
||||
--skip-xcode-osx | --skip-xcode-macos
|
||||
Skip the invoke of Xcode to test the runtime on OS X.
|
||||
--skip-xcode-tvos
|
||||
Skip the invoke of Xcode to test the runtime on tvOS.
|
||||
@ -119,7 +119,7 @@ while [[ $# != 0 ]]; do
|
||||
--skip-xcode-ios )
|
||||
DO_XCODE_IOS_TESTS=no
|
||||
;;
|
||||
--skip-xcode-osx )
|
||||
--skip-xcode-osx | --skip-xcode-macos)
|
||||
DO_XCODE_OSX_TESTS=no
|
||||
;;
|
||||
--skip-xcode-tvos )
|
||||
@ -280,7 +280,16 @@ if [[ "${DO_XCODE_IOS_TESTS}" == "yes" ]] ; then
|
||||
-disable-concurrent-testing
|
||||
)
|
||||
;;
|
||||
10.[0-1]* )
|
||||
10.*)
|
||||
XCODEBUILD_TEST_BASE_IOS+=(
|
||||
-destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
|
||||
-destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
|
||||
# 10.x also seems to often fail running destinations in parallel (with
|
||||
# 32bit one include atleast)
|
||||
-disable-concurrent-destination-testing
|
||||
)
|
||||
;;
|
||||
11.0* )
|
||||
XCODEBUILD_TEST_BASE_IOS+=(
|
||||
-destination "platform=iOS Simulator,name=iPhone 4s,OS=8.1" # 32bit
|
||||
-destination "platform=iOS Simulator,name=iPhone 7,OS=latest" # 64bit
|
||||
@ -340,10 +349,27 @@ if [[ "${DO_XCODE_TVOS_TESTS}" == "yes" ]] ; then
|
||||
xcodebuild
|
||||
-project objectivec/ProtocolBuffers_tvOS.xcodeproj
|
||||
-scheme ProtocolBuffers
|
||||
# Test on the oldest and current.
|
||||
-destination "platform=tvOS Simulator,name=Apple TV 1080p,OS=9.0"
|
||||
-destination "platform=tvOS Simulator,name=Apple TV,OS=latest"
|
||||
)
|
||||
case "${XCODE_VERSION}" in
|
||||
[6-9].* )
|
||||
echo "ERROR: Xcode 10.0 or higher is required to build the test suite." 1>&2
|
||||
exit 11
|
||||
;;
|
||||
10.* | 11.* )
|
||||
XCODEBUILD_TEST_BASE_TVOS+=(
|
||||
# Test on the oldest and current.
|
||||
-destination "platform=tvOS Simulator,name=Apple TV,OS=11.0"
|
||||
-destination "platform=tvOS Simulator,name=Apple TV 4K,OS=latest"
|
||||
)
|
||||
;;
|
||||
* )
|
||||
echo ""
|
||||
echo "ATTENTION: Time to update the simulator targets for Xcode ${XCODE_VERSION}"
|
||||
echo ""
|
||||
echo "ERROR: Build aborted!"
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
if [[ "${XCODE_QUIET}" == "yes" ]] ; then
|
||||
XCODEBUILD_TEST_BASE_TVOS+=( -quiet )
|
||||
fi
|
||||
|
@ -75,7 +75,7 @@ typedef NS_ENUM(uint8_t, GPBFieldType) {
|
||||
/** Number of extension ranges declared for the message. */
|
||||
@property(nonatomic, readonly) uint32_t extensionRangesCount;
|
||||
/** Descriptor for the file where the message was defined. */
|
||||
@property(nonatomic, readonly, assign) GPBFileDescriptor *file;
|
||||
@property(nonatomic, readonly) GPBFileDescriptor *file;
|
||||
|
||||
/** Whether the message is in wire format or not. */
|
||||
@property(nonatomic, readonly, getter=isWireFormat) BOOL wireFormat;
|
||||
@ -188,10 +188,10 @@ typedef NS_ENUM(uint8_t, GPBFieldType) {
|
||||
@property(nonatomic, readonly, getter=isPackable) BOOL packable;
|
||||
|
||||
/** The containing oneof if this field is part of one, nil otherwise. */
|
||||
@property(nonatomic, readonly, assign, nullable) GPBOneofDescriptor *containingOneof;
|
||||
@property(nonatomic, readonly, nullable) GPBOneofDescriptor *containingOneof;
|
||||
|
||||
/** Class of the message if the field is of message type. */
|
||||
@property(nonatomic, readonly, assign, nullable) Class msgClass;
|
||||
@property(nonatomic, readonly, nullable) Class msgClass;
|
||||
|
||||
/** Descriptor for the enum if this field is an enum. */
|
||||
@property(nonatomic, readonly, strong, nullable) GPBEnumDescriptor *enumDescriptor;
|
||||
@ -305,7 +305,7 @@ typedef NS_ENUM(uint8_t, GPBFieldType) {
|
||||
/** Whether the extension is packable. */
|
||||
@property(nonatomic, readonly, getter=isPackable) BOOL packable;
|
||||
/** The class of the message if the extension is of message type. */
|
||||
@property(nonatomic, readonly, assign) Class msgClass;
|
||||
@property(nonatomic, readonly) Class msgClass;
|
||||
/** The singleton name for the extension. */
|
||||
@property(nonatomic, readonly) NSString *singletonName;
|
||||
/** The enum descriptor if the extension is of enum type. */
|
||||
|
@ -1482,7 +1482,7 @@
|
||||
[msg release];
|
||||
msg = [[Message2 alloc] init];
|
||||
|
||||
uint32_t values[] = {
|
||||
int32_t values[] = {
|
||||
Message2_O_OneOfCase_OneofInt32,
|
||||
Message2_O_OneOfCase_OneofInt64,
|
||||
Message2_O_OneOfCase_OneofUint32,
|
||||
@ -1992,7 +1992,7 @@
|
||||
[msg release];
|
||||
msg = [[Message3 alloc] init];
|
||||
|
||||
uint32_t values[] = {
|
||||
int32_t values[] = {
|
||||
Message3_O_OneOfCase_OneofInt32,
|
||||
Message3_O_OneOfCase_OneofInt64,
|
||||
Message3_O_OneOfCase_OneofUint32,
|
||||
@ -2113,7 +2113,7 @@
|
||||
|
||||
Message2 *msg = [[Message2 alloc] init];
|
||||
|
||||
uint32_t values[] = {
|
||||
int32_t values[] = {
|
||||
Message2_O_OneOfCase_OneofInt32,
|
||||
Message2_O_OneOfCase_OneofInt64,
|
||||
Message2_O_OneOfCase_OneofUint32,
|
||||
@ -2242,7 +2242,7 @@
|
||||
|
||||
Message3 *msg = [[Message3 alloc] init];
|
||||
|
||||
uint32_t values[] = {
|
||||
int32_t values[] = {
|
||||
Message3_O_OneOfCase_OneofInt32,
|
||||
Message3_O_OneOfCase_OneofInt64,
|
||||
Message3_O_OneOfCase_OneofUint32,
|
||||
|
@ -10,11 +10,11 @@
|
||||
<email>protobuf-opensource@google.com</email>
|
||||
<active>yes</active>
|
||||
</lead>
|
||||
<date>2019-03-25</date>
|
||||
<time>13:23:39</time>
|
||||
<date>2019-05-21</date>
|
||||
<time>14:07:13</time>
|
||||
<version>
|
||||
<release>3.7.1</release>
|
||||
<api>3.7.1</api>
|
||||
<release>3.8.0</release>
|
||||
<api>3.8.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
@ -26,6 +26,7 @@
|
||||
<dir baseinstalldir="/" name="/">
|
||||
<file baseinstalldir="/" name="config.m4" role="src"/>
|
||||
<file baseinstalldir="/" name="array.c" role="src"/>
|
||||
<file baseinstalldir="/" name="builtin_descriptors.inc" role="src"/>
|
||||
<file baseinstalldir="/" name="def.c" role="src"/>
|
||||
<file baseinstalldir="/" name="encode_decode.c" role="src"/>
|
||||
<file baseinstalldir="/" name="map.c" role="src"/>
|
||||
@ -318,5 +319,33 @@ 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.8.0RC1</release>
|
||||
<api>3.8.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2019-04-23</date>
|
||||
<time>16:14:52</time>
|
||||
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
|
||||
<notes>GA release.</notes>
|
||||
</release>
|
||||
<release>
|
||||
<version>
|
||||
<release>3.8.0</release>
|
||||
<api>3.8.0</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>stable</release>
|
||||
<api>stable</api>
|
||||
</stability>
|
||||
<date>2019-05-21</date>
|
||||
<time>14:07:13</time>
|
||||
<license uri="https://opensource.org/licenses/BSD-3-Clause">3-Clause BSD License</license>
|
||||
<notes>GA release.</notes>
|
||||
</release>
|
||||
</changelog>
|
||||
</package>
|
||||
|
@ -37,7 +37,7 @@
|
||||
#include "upb.h"
|
||||
|
||||
#define PHP_PROTOBUF_EXTNAME "protobuf"
|
||||
#define PHP_PROTOBUF_VERSION "3.7.1"
|
||||
#define PHP_PROTOBUF_VERSION "3.8.0"
|
||||
|
||||
#define MAX_LENGTH_OF_INT64 20
|
||||
#define SIZEOF_INT64 8
|
||||
|
@ -10460,6 +10460,48 @@ static void start_timestamp_zone(upb_json_parser *p, const char *ptr) {
|
||||
capture_begin(p, ptr);
|
||||
}
|
||||
|
||||
#define EPOCH_YEAR 1970
|
||||
#define TM_YEAR_BASE 1900
|
||||
|
||||
static bool isleap(int year) {
|
||||
return (year % 4) == 0 && (year % 100 != 0 || (year % 400) == 0);
|
||||
}
|
||||
|
||||
const unsigned short int __mon_yday[2][13] = {
|
||||
/* Normal years. */
|
||||
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
|
||||
/* Leap years. */
|
||||
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
|
||||
};
|
||||
|
||||
int64_t epoch(int year, int yday, int hour, int min, int sec) {
|
||||
int64_t years = year - EPOCH_YEAR;
|
||||
|
||||
int64_t leap_days = years / 4 - years / 100 + years / 400;
|
||||
|
||||
int64_t days = years * 365 + yday + leap_days;
|
||||
int64_t hours = days * 24 + hour;
|
||||
int64_t mins = hours * 60 + min;
|
||||
int64_t secs = mins * 60 + sec;
|
||||
return secs;
|
||||
}
|
||||
|
||||
|
||||
static int64_t upb_mktime(const struct tm *tp) {
|
||||
int sec = tp->tm_sec;
|
||||
int min = tp->tm_min;
|
||||
int hour = tp->tm_hour;
|
||||
int mday = tp->tm_mday;
|
||||
int mon = tp->tm_mon;
|
||||
int year = tp->tm_year + TM_YEAR_BASE;
|
||||
|
||||
/* Calculate day of year from year, month, and day of month. */
|
||||
int mon_yday = ((__mon_yday[isleap(year)][mon]) - 1);
|
||||
int yday = mon_yday + mday;
|
||||
|
||||
return epoch(year, yday, hour, min, sec);
|
||||
}
|
||||
|
||||
static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) {
|
||||
size_t len;
|
||||
const char *buf;
|
||||
@ -10487,7 +10529,7 @@ static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) {
|
||||
}
|
||||
|
||||
/* Normalize tm */
|
||||
seconds = mktime(&p->tm);
|
||||
seconds = upb_mktime(&p->tm);
|
||||
|
||||
/* Check timestamp boundary */
|
||||
if (seconds < -62135596800) {
|
||||
|
@ -55,7 +55,7 @@ class DescriptorPool
|
||||
return self::$pool;
|
||||
}
|
||||
|
||||
public function internalAddGeneratedFile($data)
|
||||
public function internalAddGeneratedFile($data, $use_nested = false)
|
||||
{
|
||||
$files = new FileDescriptorSet();
|
||||
$files->mergeFromString($data);
|
||||
|
@ -15,7 +15,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.DescriptorProto</code>
|
||||
*/
|
||||
class DescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
final class DescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>optional string name = 1;</code>
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.DescriptorProto.ExtensionRange</code>
|
||||
*/
|
||||
class ExtensionRange extends \Google\Protobuf\Internal\Message
|
||||
final class ExtensionRange extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Inclusive.
|
||||
|
@ -17,7 +17,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.DescriptorProto.ReservedRange</code>
|
||||
*/
|
||||
class ReservedRange extends \Google\Protobuf\Internal\Message
|
||||
final class ReservedRange extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Inclusive.
|
||||
|
@ -39,17 +39,26 @@ class EnumDescriptor
|
||||
|
||||
public function getValueByNumber($number)
|
||||
{
|
||||
return $this->value[$number];
|
||||
if (isset($this->value[$number])) {
|
||||
return $this->value[$number];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getValueByName($name)
|
||||
{
|
||||
return $this->name_to_value[$name];
|
||||
if (isset($this->name_to_value[$name])) {
|
||||
return $this->name_to_value[$name];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getValueDescriptorByIndex($index)
|
||||
{
|
||||
return $this->value_descriptor[$index];
|
||||
if (isset($this->value_descriptor[$index])) {
|
||||
return $this->value_descriptor[$index];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getValueCount()
|
||||
|
@ -15,7 +15,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.EnumDescriptorProto</code>
|
||||
*/
|
||||
class EnumDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
final class EnumDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>optional string name = 1;</code>
|
||||
|
@ -19,7 +19,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.EnumDescriptorProto.EnumReservedRange</code>
|
||||
*/
|
||||
class EnumReservedRange extends \Google\Protobuf\Internal\Message
|
||||
final class EnumReservedRange extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Inclusive.
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.EnumOptions</code>
|
||||
*/
|
||||
class EnumOptions extends \Google\Protobuf\Internal\Message
|
||||
final class EnumOptions extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Set this option to true to allow mapping different tag names to the same
|
||||
|
@ -15,7 +15,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.EnumValueDescriptorProto</code>
|
||||
*/
|
||||
class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
final class EnumValueDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>optional string name = 1;</code>
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.EnumValueOptions</code>
|
||||
*/
|
||||
class EnumValueOptions extends \Google\Protobuf\Internal\Message
|
||||
final class EnumValueOptions extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Is this enum value deprecated?
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.ExtensionRangeOptions</code>
|
||||
*/
|
||||
class ExtensionRangeOptions extends \Google\Protobuf\Internal\Message
|
||||
final class ExtensionRangeOptions extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* The parser stores options it doesn't recognize here. See above.
|
||||
|
@ -15,7 +15,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.FieldDescriptorProto</code>
|
||||
*/
|
||||
class FieldDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
final class FieldDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>optional string name = 1;</code>
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.FieldOptions</code>
|
||||
*/
|
||||
class FieldOptions extends \Google\Protobuf\Internal\Message
|
||||
final class FieldOptions extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* The ctype option instructs the C++ code generator to use a different
|
||||
|
@ -15,7 +15,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.FileDescriptorProto</code>
|
||||
*/
|
||||
class FileDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
final class FileDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* file name, relative to root of source tree
|
||||
|
@ -16,7 +16,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.FileDescriptorSet</code>
|
||||
*/
|
||||
class FileDescriptorSet extends \Google\Protobuf\Internal\Message
|
||||
final class FileDescriptorSet extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>repeated .google.protobuf.FileDescriptorProto file = 1;</code>
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.FileOptions</code>
|
||||
*/
|
||||
class FileOptions extends \Google\Protobuf\Internal\Message
|
||||
final class FileOptions extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Sets the Java package where classes generated from this .proto will be
|
||||
|
@ -504,18 +504,30 @@ class GPBUtil
|
||||
|
||||
public static function formatDuration($value)
|
||||
{
|
||||
if (bccomp($value->getSeconds(), "315576000001") != -1) {
|
||||
throw new GPBDecodeException("Duration number too large.");
|
||||
if (bccomp($value->getSeconds(), '315576000001') != -1) {
|
||||
throw new GPBDecodeException('Duration number too large.');
|
||||
}
|
||||
if (bccomp($value->getSeconds(), "-315576000001") != 1) {
|
||||
throw new GPBDecodeException("Duration number too small.");
|
||||
if (bccomp($value->getSeconds(), '-315576000001') != 1) {
|
||||
throw new GPBDecodeException('Duration number too small.');
|
||||
}
|
||||
return strval(bcadd($value->getSeconds(),
|
||||
$value->getNanos() / 1000000000.0, 9));
|
||||
|
||||
$nanos = $value->getNanos();
|
||||
if ($nanos === 0) {
|
||||
return (string) $value->getSeconds();
|
||||
}
|
||||
|
||||
if ($nanos % 1000000 === 0) {
|
||||
$digits = 3;
|
||||
} elseif ($nanos % 1000 === 0) {
|
||||
$digits = 6;
|
||||
} else {
|
||||
$digits = 9;
|
||||
}
|
||||
|
||||
$nanos = bcdiv($nanos, '1000000000', $digits);
|
||||
return bcadd($value->getSeconds(), $nanos, $digits);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public static function parseFieldMask($paths_string)
|
||||
{
|
||||
$field_mask = new FieldMask();
|
||||
|
@ -17,7 +17,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.GeneratedCodeInfo</code>
|
||||
*/
|
||||
class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message
|
||||
final class GeneratedCodeInfo extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* An Annotation connects some span of text in generated code to an element
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.GeneratedCodeInfo.Annotation</code>
|
||||
*/
|
||||
class Annotation extends \Google\Protobuf\Internal\Message
|
||||
final class Annotation extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Identifies the element in the original source .proto file. This field
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.MessageOptions</code>
|
||||
*/
|
||||
class MessageOptions extends \Google\Protobuf\Internal\Message
|
||||
final class MessageOptions extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Set true to use the old proto1 MessageSet wire format for extensions.
|
||||
|
@ -15,7 +15,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.MethodDescriptorProto</code>
|
||||
*/
|
||||
class MethodDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
final class MethodDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>optional string name = 1;</code>
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.MethodOptions</code>
|
||||
*/
|
||||
class MethodOptions extends \Google\Protobuf\Internal\Message
|
||||
final class MethodOptions extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Is this method deprecated?
|
||||
|
@ -15,7 +15,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.OneofDescriptorProto</code>
|
||||
*/
|
||||
class OneofDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
final class OneofDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>optional string name = 1;</code>
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.OneofOptions</code>
|
||||
*/
|
||||
class OneofOptions extends \Google\Protobuf\Internal\Message
|
||||
final class OneofOptions extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* The parser stores options it doesn't recognize here. See above.
|
||||
|
@ -15,7 +15,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.ServiceDescriptorProto</code>
|
||||
*/
|
||||
class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
final class ServiceDescriptorProto extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>optional string name = 1;</code>
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.ServiceOptions</code>
|
||||
*/
|
||||
class ServiceOptions extends \Google\Protobuf\Internal\Message
|
||||
final class ServiceOptions extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Is this service deprecated?
|
||||
|
@ -16,7 +16,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.SourceCodeInfo</code>
|
||||
*/
|
||||
class SourceCodeInfo extends \Google\Protobuf\Internal\Message
|
||||
final class SourceCodeInfo extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* A Location identifies a piece of source code in a .proto file which
|
||||
|
@ -13,7 +13,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
/**
|
||||
* Generated from protobuf message <code>google.protobuf.SourceCodeInfo.Location</code>
|
||||
*/
|
||||
class Location extends \Google\Protobuf\Internal\Message
|
||||
final class Location extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Identifies which part of the FileDescriptorProto was defined at this
|
||||
|
@ -20,7 +20,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.UninterpretedOption</code>
|
||||
*/
|
||||
class UninterpretedOption extends \Google\Protobuf\Internal\Message
|
||||
final class UninterpretedOption extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>repeated .google.protobuf.UninterpretedOption.NamePart name = 2;</code>
|
||||
|
@ -19,7 +19,7 @@ use Google\Protobuf\Internal\GPBUtil;
|
||||
*
|
||||
* Generated from protobuf message <code>google.protobuf.UninterpretedOption.NamePart</code>
|
||||
*/
|
||||
class NamePart extends \Google\Protobuf\Internal\Message
|
||||
final class NamePart extends \Google\Protobuf\Internal\Message
|
||||
{
|
||||
/**
|
||||
* Generated from protobuf field <code>required string name_part = 1;</code>
|
||||
|
@ -24,3 +24,14 @@ message TestWrapperSetters {
|
||||
|
||||
map<string, google.protobuf.StringValue> map_string_value = 13;
|
||||
}
|
||||
|
||||
message TestWrapperAccessorConflicts {
|
||||
int32 normal_vs_wrapper_value = 1;
|
||||
google.protobuf.Int32Value normal_vs_wrapper = 2;
|
||||
|
||||
int32 normal_vs_normal_value = 3;
|
||||
int32 normal_vs_normal = 4;
|
||||
|
||||
google.protobuf.Int32Value wrapper_vs_wrapper_value = 5;
|
||||
google.protobuf.Int32Value wrapper_vs_wrapper = 6;
|
||||
}
|
||||
|
@ -16,6 +16,44 @@ use Google\Protobuf\UInt64Value;
|
||||
|
||||
class WrapperTypeSettersTest extends TestBase
|
||||
{
|
||||
public function testConflictNormalVsWrapper()
|
||||
{
|
||||
$m = new Foo\TestWrapperAccessorConflicts();
|
||||
|
||||
$m->setNormalVsWrapperValue1(1);
|
||||
$this->assertSame(1, $m->getNormalVsWrapperValue1());
|
||||
|
||||
$m->setNormalVsWrapperValue2(1);
|
||||
$this->assertSame(1, $m->getNormalVsWrapperValue2());
|
||||
|
||||
$wrapper = new Int32Value(["value" => 1]);
|
||||
$m->setNormalVsWrapper($wrapper);
|
||||
$this->assertSame(1, $m->getNormalVsWrapper()->getValue());
|
||||
}
|
||||
|
||||
public function testConflictNormalVsNormal()
|
||||
{
|
||||
$m = new Foo\TestWrapperAccessorConflicts();
|
||||
|
||||
$m->setNormalVsNormalValue(1);
|
||||
$this->assertSame(1, $m->getNormalVsNormalValue());
|
||||
|
||||
$m->setNormalVsNormal(1);
|
||||
$this->assertSame(1, $m->getNormalVsNormal());
|
||||
}
|
||||
|
||||
public function testConflictWrapperVsWrapper()
|
||||
{
|
||||
$m = new Foo\TestWrapperAccessorConflicts();
|
||||
|
||||
$m->setWrapperVsWrapperValueValue(1);
|
||||
$this->assertSame(1, $m->getWrapperVsWrapperValueValue());
|
||||
|
||||
$wrapper = new Int32Value(["value" => 1]);
|
||||
$m->setWrapperVsWrapperValue5($wrapper);
|
||||
$this->assertSame(1, $m->getWrapperVsWrapperValue5()->getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider gettersAndSettersDataProvider
|
||||
*/
|
||||
|
@ -117,6 +117,7 @@ def _proto_gen_impl(ctx):
|
||||
|
||||
outs = [ctx.actions.declare_file(out, sibling = src) for out in outs]
|
||||
inputs = [src] + deps
|
||||
tools = [ctx.executable.protoc]
|
||||
if ctx.executable.plugin:
|
||||
plugin = ctx.executable.plugin
|
||||
lang = ctx.attr.plugin_language
|
||||
@ -131,11 +132,12 @@ def _proto_gen_impl(ctx):
|
||||
outdir = ",".join(ctx.attr.plugin_options) + ":" + outdir
|
||||
args += [("--plugin=protoc-gen-%s=" + path_tpl) % (lang, plugin.path)]
|
||||
args += ["--%s_out=%s" % (lang, outdir)]
|
||||
inputs += [plugin]
|
||||
tools.append(plugin)
|
||||
|
||||
if not in_gen_dir:
|
||||
ctx.actions.run(
|
||||
inputs = inputs,
|
||||
tools = tools,
|
||||
outputs = outs,
|
||||
arguments = args + import_flags + [src.path],
|
||||
executable = ctx.executable.protoc,
|
||||
@ -158,10 +160,11 @@ def _proto_gen_impl(ctx):
|
||||
if generated_out != out.path:
|
||||
command += ";mv %s %s" % (generated_out, out.path)
|
||||
ctx.actions.run_shell(
|
||||
inputs = inputs + [ctx.executable.protoc],
|
||||
inputs = inputs,
|
||||
outputs = [out],
|
||||
command = command,
|
||||
mnemonic = "ProtoCompile",
|
||||
tools = tools,
|
||||
use_default_shell_env = True,
|
||||
)
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
</parent>
|
||||
<groupId>com.google.protobuf</groupId>
|
||||
<artifactId>protoc</artifactId>
|
||||
<version>3.7.1</version>
|
||||
<version>3.8.0</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Protobuf Compiler</name>
|
||||
<description>
|
||||
|
@ -1,7 +1,7 @@
|
||||
Protocol Buffers - Google's data interchange format
|
||||
===================================================
|
||||
|
||||
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python_compatibility.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_compatibility%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_cpp%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython_cpp%2Fcontinuous)
|
||||
[![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python_compatibility.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_compatibility%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/linux-python_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fubuntu%2Fpython_cpp%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython%2Fcontinuous) [![Build status](https://storage.googleapis.com/protobuf-kokoro-results/status-badge/macos-python_cpp.png)](https://fusion.corp.google.com/projectanalysis/current/KOKORO/prod:protobuf%2Fgithub%2Fmaster%2Fmacos%2Fpython_cpp%2Fcontinuous) [![Compat check PyPI](https://python-compatibility-tools.appspot.com/one_badge_image?package=protobuf)](https://python-compatibility-tools.appspot.com/one_badge_target?package=protobuf)
|
||||
|
||||
Copyright 2008 Google Inc.
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
|
||||
# Copyright 2007 Google Inc. All Rights Reserved.
|
||||
|
||||
__version__ = '3.7.1'
|
||||
__version__ = '3.8.0'
|
||||
|
||||
if __name__ != '__main__':
|
||||
try:
|
||||
|
@ -99,8 +99,6 @@ def _IsMessageSetExtension(field):
|
||||
field.label == descriptor.FieldDescriptor.LABEL_OPTIONAL)
|
||||
|
||||
|
||||
|
||||
|
||||
class DescriptorPool(object):
|
||||
"""A collection of protobufs dynamically constructed by descriptor protos."""
|
||||
|
||||
|
@ -615,18 +615,86 @@ class SecondaryDescriptorFromDescriptorDB(DescriptorPoolTestBase,
|
||||
factory_test1_pb2.DESCRIPTOR.serialized_pb)
|
||||
self.factory_test2_fd = descriptor_pb2.FileDescriptorProto.FromString(
|
||||
factory_test2_pb2.DESCRIPTOR.serialized_pb)
|
||||
db = descriptor_database.DescriptorDatabase()
|
||||
db.Add(self.factory_test1_fd)
|
||||
db.Add(self.factory_test2_fd)
|
||||
db.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
||||
self.db = descriptor_database.DescriptorDatabase()
|
||||
self.db.Add(self.factory_test1_fd)
|
||||
self.db.Add(self.factory_test2_fd)
|
||||
self.db.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
||||
unittest_import_public_pb2.DESCRIPTOR.serialized_pb))
|
||||
db.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
||||
self.db.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
||||
unittest_import_pb2.DESCRIPTOR.serialized_pb))
|
||||
db.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
||||
self.db.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
||||
unittest_pb2.DESCRIPTOR.serialized_pb))
|
||||
db.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
||||
self.db.Add(descriptor_pb2.FileDescriptorProto.FromString(
|
||||
no_package_pb2.DESCRIPTOR.serialized_pb))
|
||||
self.pool = descriptor_pool.DescriptorPool(descriptor_db=db)
|
||||
self.pool = descriptor_pool.DescriptorPool(descriptor_db=self.db)
|
||||
|
||||
def testErrorCollector(self):
|
||||
file_proto = descriptor_pb2.FileDescriptorProto()
|
||||
file_proto.package = 'collector'
|
||||
file_proto.name = 'error_file'
|
||||
message_type = file_proto.message_type.add()
|
||||
message_type.name = 'ErrorMessage'
|
||||
field = message_type.field.add()
|
||||
field.number = 1
|
||||
field.name = 'nested_message_field'
|
||||
field.label = descriptor.FieldDescriptor.LABEL_OPTIONAL
|
||||
field.type = descriptor.FieldDescriptor.TYPE_MESSAGE
|
||||
field.type_name = 'SubMessage'
|
||||
oneof = message_type.oneof_decl.add()
|
||||
oneof.name = 'MyOneof'
|
||||
enum_type = file_proto.enum_type.add()
|
||||
enum_type.name = 'MyEnum'
|
||||
enum_value = enum_type.value.add()
|
||||
enum_value.name = 'MyEnumValue'
|
||||
enum_value.number = 0
|
||||
self.db.Add(file_proto)
|
||||
|
||||
self.assertRaisesRegexp(KeyError, 'SubMessage',
|
||||
self.pool.FindMessageTypeByName,
|
||||
'collector.ErrorMessage')
|
||||
self.assertRaisesRegexp(KeyError, 'SubMessage',
|
||||
self.pool.FindFileByName, 'error_file')
|
||||
with self.assertRaises(KeyError) as exc:
|
||||
self.pool.FindFileByName('none_file')
|
||||
self.assertIn(str(exc.exception), ('\'none_file\'',
|
||||
'\"Couldn\'t find file none_file\"'))
|
||||
|
||||
# Pure python _ConvertFileProtoToFileDescriptor() method has side effect
|
||||
# that all the symbols found in the file will load into the pool even the
|
||||
# file can not build. So when FindMessageTypeByName('ErrorMessage') was
|
||||
# called the first time, a KeyError will be raised but call the find
|
||||
# method later will return a descriptor which is not build.
|
||||
# TODO(jieluo): fix pure python to revert the load if file can not be build
|
||||
if api_implementation.Type() == 'cpp':
|
||||
error_msg = ('Invalid proto descriptor for file "error_file":\\n '
|
||||
'collector.ErrorMessage.nested_message_field: "SubMessage" '
|
||||
'is not defined.\\n collector.ErrorMessage.MyOneof: Oneof '
|
||||
'must have at least one field.\\n\'')
|
||||
with self.assertRaises(KeyError) as exc:
|
||||
self.pool.FindMessageTypeByName('collector.ErrorMessage')
|
||||
self.assertEqual(str(exc.exception), '\'Couldn\\\'t build file for '
|
||||
'message collector.ErrorMessage\\n' + error_msg)
|
||||
|
||||
with self.assertRaises(KeyError) as exc:
|
||||
self.pool.FindFieldByName('collector.ErrorMessage.nested_message_field')
|
||||
self.assertEqual(str(exc.exception), '\'Couldn\\\'t build file for field'
|
||||
' collector.ErrorMessage.nested_message_field\\n'
|
||||
+ error_msg)
|
||||
|
||||
with self.assertRaises(KeyError) as exc:
|
||||
self.pool.FindEnumTypeByName('collector.MyEnum')
|
||||
self.assertEqual(str(exc.exception), '\'Couldn\\\'t build file for enum'
|
||||
' collector.MyEnum\\n' + error_msg)
|
||||
|
||||
with self.assertRaises(KeyError) as exc:
|
||||
self.pool.FindFileContainingSymbol('collector.MyEnumValue')
|
||||
self.assertEqual(str(exc.exception), '\'Couldn\\\'t build file for symbol'
|
||||
' collector.MyEnumValue\\n' + error_msg)
|
||||
|
||||
with self.assertRaises(KeyError) as exc:
|
||||
self.pool.FindOneofByName('collector.ErrorMessage.MyOneof')
|
||||
self.assertEqual(str(exc.exception), '\'Couldn\\\'t build file for oneof'
|
||||
' collector.ErrorMessage.MyOneof\\n' + error_msg)
|
||||
|
||||
|
||||
class ProtoFile(object):
|
||||
|
@ -54,6 +54,7 @@ from google.protobuf import unittest_mset_pb2
|
||||
from google.protobuf import unittest_pb2
|
||||
from google.protobuf import descriptor_pool
|
||||
from google.protobuf import json_format
|
||||
from google.protobuf.util import json_format_pb2
|
||||
from google.protobuf.util import json_format_proto3_pb2
|
||||
|
||||
|
||||
@ -247,6 +248,22 @@ class JsonFormatTest(JsonFormatBase):
|
||||
}
|
||||
self.assertEqual(golden_dict, message_dict)
|
||||
|
||||
def testExtensionSerializationDictMatchesProto3SpecMore(self):
|
||||
"""See go/proto3-json-spec for spec.
|
||||
"""
|
||||
message = json_format_pb2.TestMessageWithExtension()
|
||||
ext = json_format_pb2.TestExtension.ext
|
||||
message.Extensions[ext].value = 'stuff'
|
||||
message_dict = json_format.MessageToDict(
|
||||
message
|
||||
)
|
||||
expected_dict = {
|
||||
'[protobuf_unittest.TestExtension.ext]': {
|
||||
'value': u'stuff',
|
||||
},
|
||||
}
|
||||
self.assertEqual(expected_dict, message_dict)
|
||||
|
||||
|
||||
def testExtensionSerializationJsonMatchesProto3Spec(self):
|
||||
"""See go/proto3-json-spec for spec.
|
||||
|
@ -1725,6 +1725,7 @@ class Proto3Test(unittest.TestCase):
|
||||
|
||||
self.assertIsNone(msg.map_int32_int32.get(5))
|
||||
self.assertEqual(10, msg.map_int32_int32.get(5, 10))
|
||||
self.assertEqual(10, msg.map_int32_int32.get(key=5, default=10))
|
||||
self.assertIsNone(msg.map_int32_int32.get(5))
|
||||
|
||||
msg.map_int32_int32[5] = 15
|
||||
@ -1735,6 +1736,7 @@ class Proto3Test(unittest.TestCase):
|
||||
|
||||
self.assertIsNone(msg.map_int32_foreign_message.get(5))
|
||||
self.assertEqual(10, msg.map_int32_foreign_message.get(5, 10))
|
||||
self.assertEqual(10, msg.map_int32_foreign_message.get(key=5, default=10))
|
||||
|
||||
submsg = msg.map_int32_foreign_message[5]
|
||||
self.assertIs(submsg, msg.map_int32_foreign_message.get(5))
|
||||
|
@ -233,12 +233,8 @@ class _Printer(object):
|
||||
js[name] = [self._FieldToJsonObject(field, k)
|
||||
for k in value]
|
||||
elif field.is_extension:
|
||||
f = field
|
||||
if (f.containing_type.GetOptions().message_set_wire_format and
|
||||
f.type == descriptor.FieldDescriptor.TYPE_MESSAGE and
|
||||
f.label == descriptor.FieldDescriptor.LABEL_OPTIONAL):
|
||||
f = f.message_type
|
||||
name = '[%s.%s]' % (f.full_name, name)
|
||||
full_qualifier = field.full_name[:-len(field.name)]
|
||||
name = '[%s%s]' % (full_qualifier, name)
|
||||
js[name] = self._FieldToJsonObject(field, value)
|
||||
else:
|
||||
js[name] = self._FieldToJsonObject(field, value)
|
||||
@ -493,10 +489,16 @@ class _Parser(object):
|
||||
raise ParseError('Message type {0} does not have extensions'.format(
|
||||
message_descriptor.full_name))
|
||||
identifier = name[1:-1] # strip [] brackets
|
||||
identifier = '.'.join(identifier.split('.')[:-1])
|
||||
# pylint: disable=protected-access
|
||||
field = message.Extensions._FindExtensionByName(identifier)
|
||||
# pylint: enable=protected-access
|
||||
if not field:
|
||||
# Try looking for extension by the message type name, dropping the
|
||||
# field name following the final . separator in full_name.
|
||||
identifier = '.'.join(identifier.split('.')[:-1])
|
||||
# pylint: disable=protected-access
|
||||
field = message.Extensions._FindExtensionByName(identifier)
|
||||
# pylint: enable=protected-access
|
||||
if not field:
|
||||
if self.ignore_unknown_fields:
|
||||
continue
|
||||
|
@ -67,6 +67,38 @@ static std::unordered_map<const DescriptorPool*, PyDescriptorPool*>*
|
||||
|
||||
namespace cdescriptor_pool {
|
||||
|
||||
// Collects errors that occur during proto file building to allow them to be
|
||||
// propagated in the python exception instead of only living in ERROR logs.
|
||||
class BuildFileErrorCollector : public DescriptorPool::ErrorCollector {
|
||||
public:
|
||||
BuildFileErrorCollector() : error_message(""), had_errors_(false) {}
|
||||
|
||||
void AddError(const string& filename, const string& element_name,
|
||||
const Message* descriptor, ErrorLocation location,
|
||||
const string& message) override {
|
||||
// Replicates the logging behavior that happens in the C++ implementation
|
||||
// when an error collector is not passed in.
|
||||
if (!had_errors_) {
|
||||
error_message +=
|
||||
("Invalid proto descriptor for file \"" + filename + "\":\n");
|
||||
had_errors_ = true;
|
||||
}
|
||||
// As this only happens on failure and will result in the program not
|
||||
// running at all, no effort is made to optimize this string manipulation.
|
||||
error_message += (" " + element_name + ": " + message + "\n");
|
||||
}
|
||||
|
||||
void Clear() {
|
||||
had_errors_ = false;
|
||||
error_message = "";
|
||||
}
|
||||
|
||||
string error_message;
|
||||
|
||||
private:
|
||||
bool had_errors_;
|
||||
};
|
||||
|
||||
// Create a Python DescriptorPool object, but does not fill the "pool"
|
||||
// attribute.
|
||||
static PyDescriptorPool* _CreateDescriptorPool() {
|
||||
@ -76,6 +108,7 @@ static PyDescriptorPool* _CreateDescriptorPool() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
cpool->error_collector = nullptr;
|
||||
cpool->underlay = NULL;
|
||||
cpool->database = NULL;
|
||||
|
||||
@ -124,7 +157,8 @@ static PyDescriptorPool* PyDescriptorPool_NewWithDatabase(
|
||||
return NULL;
|
||||
}
|
||||
if (database != NULL) {
|
||||
cpool->pool = new DescriptorPool(database);
|
||||
cpool->error_collector = new BuildFileErrorCollector();
|
||||
cpool->pool = new DescriptorPool(database, cpool->error_collector);
|
||||
cpool->database = database;
|
||||
} else {
|
||||
cpool->pool = new DescriptorPool();
|
||||
@ -167,6 +201,7 @@ static void Dealloc(PyObject* pself) {
|
||||
delete self->descriptor_options;
|
||||
delete self->database;
|
||||
delete self->pool;
|
||||
delete self->error_collector;
|
||||
Py_TYPE(self)->tp_free(pself);
|
||||
}
|
||||
|
||||
@ -182,6 +217,20 @@ static int GcClear(PyObject* pself) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
PyObject* SetErrorFromCollector(DescriptorPool::ErrorCollector* self,
|
||||
char* name, char* error_type) {
|
||||
BuildFileErrorCollector* error_collector =
|
||||
reinterpret_cast<BuildFileErrorCollector*>(self);
|
||||
if (error_collector && !error_collector->error_message.empty()) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't build file for %s %.200s\n%s",
|
||||
error_type, name, error_collector->error_message.c_str());
|
||||
error_collector->Clear();
|
||||
return NULL;
|
||||
}
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find %s %.200s", error_type, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject* FindMessageByName(PyObject* self, PyObject* arg) {
|
||||
Py_ssize_t name_size;
|
||||
char* name;
|
||||
@ -194,8 +243,9 @@ static PyObject* FindMessageByName(PyObject* self, PyObject* arg) {
|
||||
string(name, name_size));
|
||||
|
||||
if (message_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find message %.200s", name);
|
||||
return NULL;
|
||||
return SetErrorFromCollector(
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
|
||||
"message");
|
||||
}
|
||||
|
||||
|
||||
@ -212,12 +262,12 @@ static PyObject* FindFileByName(PyObject* self, PyObject* arg) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PyDescriptorPool* py_pool = reinterpret_cast<PyDescriptorPool*>(self);
|
||||
const FileDescriptor* file_descriptor =
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileByName(
|
||||
string(name, name_size));
|
||||
py_pool->pool->FindFileByName(string(name, name_size));
|
||||
|
||||
if (file_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find file %.200s", name);
|
||||
return NULL;
|
||||
return SetErrorFromCollector(py_pool->error_collector, name, "file");
|
||||
}
|
||||
return PyFileDescriptor_FromDescriptor(file_descriptor);
|
||||
}
|
||||
@ -232,9 +282,7 @@ PyObject* FindFieldByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
const FieldDescriptor* field_descriptor =
|
||||
self->pool->FindFieldByName(string(name, name_size));
|
||||
if (field_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find field %.200s",
|
||||
name);
|
||||
return NULL;
|
||||
return SetErrorFromCollector(self->error_collector, name, "field");
|
||||
}
|
||||
|
||||
|
||||
@ -255,8 +303,8 @@ PyObject* FindExtensionByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
const FieldDescriptor* field_descriptor =
|
||||
self->pool->FindExtensionByName(string(name, name_size));
|
||||
if (field_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find extension field %.200s", name);
|
||||
return NULL;
|
||||
return SetErrorFromCollector(self->error_collector, name,
|
||||
"extension field");
|
||||
}
|
||||
|
||||
|
||||
@ -277,8 +325,7 @@ PyObject* FindEnumTypeByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
const EnumDescriptor* enum_descriptor =
|
||||
self->pool->FindEnumTypeByName(string(name, name_size));
|
||||
if (enum_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find enum %.200s", name);
|
||||
return NULL;
|
||||
return SetErrorFromCollector(self->error_collector, name, "enum");
|
||||
}
|
||||
|
||||
|
||||
@ -299,8 +346,7 @@ PyObject* FindOneofByName(PyDescriptorPool* self, PyObject* arg) {
|
||||
const OneofDescriptor* oneof_descriptor =
|
||||
self->pool->FindOneofByName(string(name, name_size));
|
||||
if (oneof_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find oneof %.200s", name);
|
||||
return NULL;
|
||||
return SetErrorFromCollector(self->error_collector, name, "oneof");
|
||||
}
|
||||
|
||||
|
||||
@ -322,8 +368,9 @@ static PyObject* FindServiceByName(PyObject* self, PyObject* arg) {
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindServiceByName(
|
||||
string(name, name_size));
|
||||
if (service_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find service %.200s", name);
|
||||
return NULL;
|
||||
return SetErrorFromCollector(
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
|
||||
"service");
|
||||
}
|
||||
|
||||
|
||||
@ -341,8 +388,9 @@ static PyObject* FindMethodByName(PyObject* self, PyObject* arg) {
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindMethodByName(
|
||||
string(name, name_size));
|
||||
if (method_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find method %.200s", name);
|
||||
return NULL;
|
||||
return SetErrorFromCollector(
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
|
||||
"method");
|
||||
}
|
||||
|
||||
|
||||
@ -360,8 +408,9 @@ static PyObject* FindFileContainingSymbol(PyObject* self, PyObject* arg) {
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindFileContainingSymbol(
|
||||
string(name, name_size));
|
||||
if (file_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find symbol %.200s", name);
|
||||
return NULL;
|
||||
return SetErrorFromCollector(
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->error_collector, name,
|
||||
"symbol");
|
||||
}
|
||||
|
||||
|
||||
@ -384,7 +433,16 @@ static PyObject* FindExtensionByNumber(PyObject* self, PyObject* args) {
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->pool->FindExtensionByNumber(
|
||||
descriptor, number);
|
||||
if (extension_descriptor == NULL) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find extension %d", number);
|
||||
BuildFileErrorCollector* error_collector =
|
||||
reinterpret_cast<BuildFileErrorCollector*>(
|
||||
reinterpret_cast<PyDescriptorPool*>(self)->error_collector);
|
||||
if (error_collector && !error_collector->error_message.empty()) {
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't build file for Extension %.d\n%s",
|
||||
number, error_collector->error_message.c_str());
|
||||
error_collector->Clear();
|
||||
return NULL;
|
||||
}
|
||||
PyErr_Format(PyExc_KeyError, "Couldn't find Extension %d", number);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -511,32 +569,6 @@ static PyObject* AddServiceDescriptor(PyObject* self, PyObject* descriptor) {
|
||||
}
|
||||
|
||||
// The code below loads new Descriptors from a serialized FileDescriptorProto.
|
||||
|
||||
// Collects errors that occur during proto file building to allow them to be
|
||||
// propagated in the python exception instead of only living in ERROR logs.
|
||||
class BuildFileErrorCollector : public DescriptorPool::ErrorCollector {
|
||||
public:
|
||||
BuildFileErrorCollector() : error_message(""), had_errors(false) {}
|
||||
|
||||
void AddError(const string& filename, const string& element_name,
|
||||
const Message* descriptor, ErrorLocation location,
|
||||
const string& message) {
|
||||
// Replicates the logging behavior that happens in the C++ implementation
|
||||
// when an error collector is not passed in.
|
||||
if (!had_errors) {
|
||||
error_message +=
|
||||
("Invalid proto descriptor for file \"" + filename + "\":\n");
|
||||
had_errors = true;
|
||||
}
|
||||
// As this only happens on failure and will result in the program not
|
||||
// running at all, no effort is made to optimize this string manipulation.
|
||||
error_message += (" " + element_name + ": " + message + "\n");
|
||||
}
|
||||
|
||||
string error_message;
|
||||
bool had_errors;
|
||||
};
|
||||
|
||||
static PyObject* AddSerializedFile(PyObject* pself, PyObject* serialized_pb) {
|
||||
PyDescriptorPool* self = reinterpret_cast<PyDescriptorPool*>(pself);
|
||||
char* message_type;
|
||||
|
@ -59,6 +59,10 @@ typedef struct PyDescriptorPool {
|
||||
// The C++ pool containing Descriptors.
|
||||
DescriptorPool* pool;
|
||||
|
||||
// The error collector to store error info. Can be NULL. This pointer is
|
||||
// owned.
|
||||
DescriptorPool::ErrorCollector* error_collector;
|
||||
|
||||
// The C++ pool acting as an underlay. Can be NULL.
|
||||
// This pointer is not owned and must stay alive.
|
||||
const DescriptorPool* underlay;
|
||||
|
@ -464,10 +464,13 @@ int MapReflectionFriend::ScalarMapSetItem(PyObject* _self, PyObject* key,
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject* ScalarMapGet(PyObject* self, PyObject* args) {
|
||||
static PyObject* ScalarMapGet(PyObject* self, PyObject* args,
|
||||
PyObject* kwargs) {
|
||||
static char* kwlist[] = {"key", "default", nullptr};
|
||||
PyObject* key;
|
||||
PyObject* default_value = NULL;
|
||||
if (PyArg_ParseTuple(args, "O|O", &key, &default_value) < 0) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &key,
|
||||
&default_value)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -532,23 +535,23 @@ static void ScalarMapDealloc(PyObject* _self) {
|
||||
}
|
||||
|
||||
static PyMethodDef ScalarMapMethods[] = {
|
||||
{ "__contains__", MapReflectionFriend::Contains, METH_O,
|
||||
"Tests whether a key is a member of the map." },
|
||||
{ "clear", (PyCFunction)Clear, METH_NOARGS,
|
||||
"Removes all elements from the map." },
|
||||
{ "get", ScalarMapGet, METH_VARARGS,
|
||||
"Gets the value for the given key if present, or otherwise a default" },
|
||||
{ "GetEntryClass", (PyCFunction)GetEntryClass, METH_NOARGS,
|
||||
"Return the class used to build Entries of (key, value) pairs." },
|
||||
{ "MergeFrom", (PyCFunction)MapReflectionFriend::MergeFrom, METH_O,
|
||||
"Merges a map into the current map." },
|
||||
/*
|
||||
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
||||
"Makes a deep copy of the class." },
|
||||
{ "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
|
||||
"Outputs picklable representation of the repeated field." },
|
||||
*/
|
||||
{NULL, NULL},
|
||||
{"__contains__", MapReflectionFriend::Contains, METH_O,
|
||||
"Tests whether a key is a member of the map."},
|
||||
{"clear", (PyCFunction)Clear, METH_NOARGS,
|
||||
"Removes all elements from the map."},
|
||||
{"get", (PyCFunction)ScalarMapGet, METH_VARARGS | METH_KEYWORDS,
|
||||
"Gets the value for the given key if present, or otherwise a default"},
|
||||
{"GetEntryClass", (PyCFunction)GetEntryClass, METH_NOARGS,
|
||||
"Return the class used to build Entries of (key, value) pairs."},
|
||||
{"MergeFrom", (PyCFunction)MapReflectionFriend::MergeFrom, METH_O,
|
||||
"Merges a map into the current map."},
|
||||
/*
|
||||
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
||||
"Makes a deep copy of the class." },
|
||||
{ "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
|
||||
"Outputs picklable representation of the repeated field." },
|
||||
*/
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
PyTypeObject *ScalarMapContainer_Type;
|
||||
@ -773,10 +776,12 @@ PyObject* MapReflectionFriend::MessageMapToStr(PyObject* _self) {
|
||||
return PyObject_Repr(dict.get());
|
||||
}
|
||||
|
||||
PyObject* MessageMapGet(PyObject* self, PyObject* args) {
|
||||
PyObject* MessageMapGet(PyObject* self, PyObject* args, PyObject* kwargs) {
|
||||
static char* kwlist[] = {"key", "default", nullptr};
|
||||
PyObject* key;
|
||||
PyObject* default_value = NULL;
|
||||
if (PyArg_ParseTuple(args, "O|O", &key, &default_value) < 0) {
|
||||
if (!PyArg_ParseTupleAndKeywords(args, kwargs, "O|O", kwlist, &key,
|
||||
&default_value)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -810,25 +815,25 @@ static void MessageMapDealloc(PyObject* _self) {
|
||||
}
|
||||
|
||||
static PyMethodDef MessageMapMethods[] = {
|
||||
{ "__contains__", (PyCFunction)MapReflectionFriend::Contains, METH_O,
|
||||
"Tests whether the map contains this element."},
|
||||
{ "clear", (PyCFunction)Clear, METH_NOARGS,
|
||||
"Removes all elements from the map."},
|
||||
{ "get", MessageMapGet, METH_VARARGS,
|
||||
"Gets the value for the given key if present, or otherwise a default" },
|
||||
{ "get_or_create", MapReflectionFriend::MessageMapGetItem, METH_O,
|
||||
"Alias for getitem, useful to make explicit that the map is mutated." },
|
||||
{ "GetEntryClass", (PyCFunction)GetEntryClass, METH_NOARGS,
|
||||
"Return the class used to build Entries of (key, value) pairs." },
|
||||
{ "MergeFrom", (PyCFunction)MapReflectionFriend::MergeFrom, METH_O,
|
||||
"Merges a map into the current map." },
|
||||
/*
|
||||
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
||||
"Makes a deep copy of the class." },
|
||||
{ "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
|
||||
"Outputs picklable representation of the repeated field." },
|
||||
*/
|
||||
{NULL, NULL},
|
||||
{"__contains__", (PyCFunction)MapReflectionFriend::Contains, METH_O,
|
||||
"Tests whether the map contains this element."},
|
||||
{"clear", (PyCFunction)Clear, METH_NOARGS,
|
||||
"Removes all elements from the map."},
|
||||
{"get", (PyCFunction)MessageMapGet, METH_VARARGS | METH_KEYWORDS,
|
||||
"Gets the value for the given key if present, or otherwise a default"},
|
||||
{"get_or_create", MapReflectionFriend::MessageMapGetItem, METH_O,
|
||||
"Alias for getitem, useful to make explicit that the map is mutated."},
|
||||
{"GetEntryClass", (PyCFunction)GetEntryClass, METH_NOARGS,
|
||||
"Return the class used to build Entries of (key, value) pairs."},
|
||||
{"MergeFrom", (PyCFunction)MapReflectionFriend::MergeFrom, METH_O,
|
||||
"Merges a map into the current map."},
|
||||
/*
|
||||
{ "__deepcopy__", (PyCFunction)DeepCopy, METH_VARARGS,
|
||||
"Makes a deep copy of the class." },
|
||||
{ "__reduce__", (PyCFunction)Reduce, METH_NOARGS,
|
||||
"Outputs picklable representation of the repeated field." },
|
||||
*/
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
PyTypeObject *MessageMapContainer_Type;
|
||||
|
@ -92,6 +92,7 @@ def GenerateUnittestProtos():
|
||||
generate_proto("../src/google/protobuf/unittest_mset_wire_format.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_no_generic_services.proto", False)
|
||||
generate_proto("../src/google/protobuf/unittest_proto3_arena.proto", False)
|
||||
generate_proto("../src/google/protobuf/util/json_format.proto", False)
|
||||
generate_proto("../src/google/protobuf/util/json_format_proto3.proto", False)
|
||||
generate_proto("google/protobuf/internal/any_test.proto", False)
|
||||
generate_proto("google/protobuf/internal/descriptor_pool_test1.proto", False)
|
||||
|
@ -389,6 +389,9 @@ static bool endmap_handler(void *closure, const void *hd, upb_status* s) {
|
||||
if (mapdata->value_field_type == UPB_TYPE_MESSAGE ||
|
||||
mapdata->value_field_type == UPB_TYPE_ENUM) {
|
||||
value_field_typeclass = get_def_obj(mapdata->value_field_subdef);
|
||||
if (mapdata->value_field_type == UPB_TYPE_ENUM) {
|
||||
value_field_typeclass = EnumDescriptor_enummodule(value_field_typeclass);
|
||||
}
|
||||
}
|
||||
|
||||
value = native_slot_get(
|
||||
|
@ -847,7 +847,6 @@ void Map_register(VALUE module) {
|
||||
rb_define_method(klass, "dup", Map_dup, 0);
|
||||
rb_define_method(klass, "==", Map_eq, 1);
|
||||
rb_define_method(klass, "hash", Map_hash, 0);
|
||||
rb_define_method(klass, "to_hash", Map_to_h, 0);
|
||||
rb_define_method(klass, "to_h", Map_to_h, 0);
|
||||
rb_define_method(klass, "inspect", Map_inspect, 0);
|
||||
rb_define_method(klass, "merge", Map_merge, 1);
|
||||
|
@ -737,7 +737,6 @@ VALUE build_class_from_descriptor(Descriptor* desc) {
|
||||
rb_define_method(klass, "eql?", Message_eq, 1);
|
||||
rb_define_method(klass, "hash", Message_hash, 0);
|
||||
rb_define_method(klass, "to_h", Message_to_h, 0);
|
||||
rb_define_method(klass, "to_hash", Message_to_h, 0);
|
||||
rb_define_method(klass, "inspect", Message_inspect, 0);
|
||||
rb_define_method(klass, "to_s", Message_inspect, 0);
|
||||
rb_define_method(klass, "[]", Message_index, 1);
|
||||
|
@ -14299,6 +14299,47 @@ static void start_timestamp_zone(upb_json_parser *p, const char *ptr) {
|
||||
capture_begin(p, ptr);
|
||||
}
|
||||
|
||||
#define EPOCH_YEAR 1970
|
||||
#define TM_YEAR_BASE 1900
|
||||
|
||||
static bool isleap(int year) {
|
||||
return (year % 4) == 0 && (year % 100 != 0 || (year % 400) == 0);
|
||||
}
|
||||
|
||||
const unsigned short int __mon_yday[2][13] = {
|
||||
/* Normal years. */
|
||||
{ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
|
||||
/* Leap years. */
|
||||
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
|
||||
};
|
||||
|
||||
int64_t epoch(int year, int yday, int hour, int min, int sec) {
|
||||
int64_t years = year - EPOCH_YEAR;
|
||||
|
||||
int64_t leap_days = years / 4 - years / 100 + years / 400;
|
||||
|
||||
int64_t days = years * 365 + yday + leap_days;
|
||||
int64_t hours = days * 24 + hour;
|
||||
int64_t mins = hours * 60 + min;
|
||||
int64_t secs = mins * 60 + sec;
|
||||
return secs;
|
||||
}
|
||||
|
||||
static int64_t upb_mktime(const struct tm *tp) {
|
||||
int sec = tp->tm_sec;
|
||||
int min = tp->tm_min;
|
||||
int hour = tp->tm_hour;
|
||||
int mday = tp->tm_mday;
|
||||
int mon = tp->tm_mon;
|
||||
int year = tp->tm_year + TM_YEAR_BASE;
|
||||
|
||||
/* Calculate day of year from year, month, and day of month. */
|
||||
int mon_yday = ((__mon_yday[isleap(year)][mon]) - 1);
|
||||
int yday = mon_yday + mday;
|
||||
|
||||
return epoch(year, yday, hour, min, sec);
|
||||
}
|
||||
|
||||
static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) {
|
||||
size_t len;
|
||||
const char *buf;
|
||||
@ -14325,7 +14366,7 @@ static bool end_timestamp_zone(upb_json_parser *p, const char *ptr) {
|
||||
}
|
||||
|
||||
/* Normalize tm */
|
||||
seconds = mktime(&p->tm) - timezone;
|
||||
seconds = upb_mktime(&p->tm);
|
||||
seconds += 3600 * hours;
|
||||
|
||||
/* Check timestamp boundary */
|
||||
|
@ -1,6 +1,6 @@
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "google-protobuf"
|
||||
s.version = "3.7.1"
|
||||
s.version = "3.8.0"
|
||||
s.licenses = ["BSD-3-Clause"]
|
||||
s.summary = "Protocol Buffers"
|
||||
s.description = "Protocol Buffers are Google's data interchange format."
|
||||
@ -20,6 +20,7 @@ Gem::Specification.new do |s|
|
||||
s.test_files = ["tests/basic.rb",
|
||||
"tests/stress.rb",
|
||||
"tests/generated_code_test.rb"]
|
||||
s.required_ruby_version = '>= 2.3'
|
||||
s.add_development_dependency "rake-compiler", "~> 0.9.5"
|
||||
s.add_development_dependency "test-unit", '~> 3.0', '>= 3.0.9'
|
||||
s.add_development_dependency "rubygems-tasks", "~> 0.2.4"
|
||||
|
@ -338,7 +338,7 @@ public class RubyMap extends RubyObject {
|
||||
return newMap;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"to_h", "to_hash"})
|
||||
@JRubyMethod(name = "to_h")
|
||||
public RubyHash toHash(ThreadContext context) {
|
||||
return RubyHash.newHash(context.runtime, table, context.runtime.getNil());
|
||||
}
|
||||
|
@ -368,7 +368,7 @@ public class RubyMessage extends RubyObject {
|
||||
return ret;
|
||||
}
|
||||
|
||||
@JRubyMethod(name = {"to_h", "to_hash"})
|
||||
@JRubyMethod(name = "to_h")
|
||||
public IRubyObject toHash(ThreadContext context) {
|
||||
Ruby runtime = context.runtime;
|
||||
RubyHash ret = RubyHash.newHash(runtime);
|
||||
|
@ -170,10 +170,12 @@ module BasicTest
|
||||
m = MapMessage.new(
|
||||
:map_string_int32 => {"a" => 1, "b" => 2},
|
||||
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
||||
"b" => TestMessage2.new(:foo => 2)})
|
||||
"b" => TestMessage2.new(:foo => 2)},
|
||||
:map_string_enum => {"a" => :A, "b" => :B})
|
||||
assert m.map_string_int32.keys.sort == ["a", "b"]
|
||||
assert m.map_string_int32["a"] == 1
|
||||
assert m.map_string_msg["b"].foo == 2
|
||||
assert m.map_string_enum["a"] == :A
|
||||
|
||||
m.map_string_int32["c"] = 3
|
||||
assert m.map_string_int32["c"] == 3
|
||||
@ -206,8 +208,9 @@ module BasicTest
|
||||
m = MapMessage.new(
|
||||
:map_string_int32 => {"a" => 1, "b" => 2},
|
||||
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
||||
"b" => TestMessage2.new(:foo => 2)})
|
||||
expected = "<BasicTest::MapMessage: map_string_int32: {\"b\"=>2, \"a\"=>1}, map_string_msg: {\"b\"=><BasicTest::TestMessage2: foo: 2>, \"a\"=><BasicTest::TestMessage2: foo: 1>}>"
|
||||
"b" => TestMessage2.new(:foo => 2)},
|
||||
:map_string_enum => {"a" => :A, "b" => :B})
|
||||
expected = "<BasicTest::MapMessage: map_string_int32: {\"b\"=>2, \"a\"=>1}, map_string_msg: {\"b\"=><BasicTest::TestMessage2: foo: 2>, \"a\"=><BasicTest::TestMessage2: foo: 1>}, map_string_enum: {\"b\"=>:B, \"a\"=>:A}>"
|
||||
assert_equal expected, m.inspect
|
||||
end
|
||||
|
||||
@ -237,7 +240,8 @@ module BasicTest
|
||||
m = MapMessage.new(
|
||||
:map_string_int32 => {"a" => 1, "b" => 2},
|
||||
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
||||
"b" => TestMessage2.new(:foo => 2)})
|
||||
"b" => TestMessage2.new(:foo => 2)},
|
||||
:map_string_enum => {"a" => :A, "b" => :B})
|
||||
m2 = MapMessage.decode(MapMessage.encode(m))
|
||||
assert m == m2
|
||||
|
||||
@ -298,10 +302,12 @@ module BasicTest
|
||||
m = MapMessage.new(
|
||||
:map_string_int32 => {"a" => 1, "b" => 2},
|
||||
:map_string_msg => {"a" => TestMessage2.new(:foo => 1),
|
||||
"b" => TestMessage2.new(:foo => 2)})
|
||||
"b" => TestMessage2.new(:foo => 2)},
|
||||
:map_string_enum => {"a" => :A, "b" => :B})
|
||||
expected_result = {
|
||||
:map_string_int32 => {"a" => 1, "b" => 2},
|
||||
:map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}}
|
||||
:map_string_msg => {"a" => {:foo => 1}, "b" => {:foo => 2}},
|
||||
:map_string_enum => {"a" => :A, "b" => :B}
|
||||
}
|
||||
assert_equal expected_result, m.to_h
|
||||
end
|
||||
@ -311,26 +317,26 @@ module BasicTest
|
||||
# TODO: Fix JSON in JRuby version.
|
||||
return if RUBY_PLATFORM == "java"
|
||||
m = MapMessage.new(:map_string_int32 => {"a" => 1})
|
||||
expected = {mapStringInt32: {a: 1}, mapStringMsg: {}}
|
||||
expected_preserve = {map_string_int32: {a: 1}, map_string_msg: {}}
|
||||
assert JSON.parse(MapMessage.encode_json(m), :symbolize_names => true) == expected
|
||||
expected = {mapStringInt32: {a: 1}, mapStringMsg: {}, mapStringEnum: {}}
|
||||
expected_preserve = {map_string_int32: {a: 1}, map_string_msg: {}, map_string_enum: {}}
|
||||
assert_equal JSON.parse(MapMessage.encode_json(m), :symbolize_names => true), expected
|
||||
|
||||
json = MapMessage.encode_json(m, :preserve_proto_fieldnames => true)
|
||||
assert JSON.parse(json, :symbolize_names => true) == expected_preserve
|
||||
assert_equal JSON.parse(json, :symbolize_names => true), expected_preserve
|
||||
|
||||
m2 = MapMessage.decode_json(MapMessage.encode_json(m))
|
||||
assert m == m2
|
||||
assert_equal m, m2
|
||||
end
|
||||
|
||||
def test_json_maps_emit_defaults_submsg
|
||||
# TODO: Fix JSON in JRuby version.
|
||||
return if RUBY_PLATFORM == "java"
|
||||
m = MapMessage.new(:map_string_msg => {"a" => TestMessage2.new})
|
||||
expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}}
|
||||
expected = {mapStringInt32: {}, mapStringMsg: {a: {foo: 0}}, mapStringEnum: {}}
|
||||
|
||||
actual = MapMessage.encode_json(m, :emit_defaults => true)
|
||||
|
||||
assert JSON.parse(actual, :symbolize_names => true) == expected
|
||||
assert_equal JSON.parse(actual, :symbolize_names => true), expected
|
||||
end
|
||||
|
||||
def test_respond_to
|
||||
|
@ -80,6 +80,7 @@ message Recursive2 {
|
||||
message MapMessage {
|
||||
map<string, int32> map_string_int32 = 1;
|
||||
map<string, TestMessage2> map_string_msg = 2;
|
||||
map<string, TestEnum> map_string_enum = 3;
|
||||
}
|
||||
|
||||
message MapMessageWireEquiv {
|
||||
|
@ -18,7 +18,7 @@ else
|
||||
PTHREAD_DEF =
|
||||
endif
|
||||
|
||||
PROTOBUF_VERSION = 18:1:0
|
||||
PROTOBUF_VERSION = 19:0:0
|
||||
|
||||
if GCC
|
||||
# Turn on all warnings except for sign comparison (we ignore sign comparison
|
||||
|
@ -111,15 +111,10 @@ bool Any::ParseAnyTypeUrl(const string& type_url,
|
||||
full_type_name);
|
||||
}
|
||||
|
||||
class Any::HasBitSetters {
|
||||
class Any::_Internal {
|
||||
public:
|
||||
};
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
const int Any::kTypeUrlFieldNumber;
|
||||
const int Any::kValueFieldNumber;
|
||||
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
|
||||
Any::Any()
|
||||
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr), _any_metadata_(&type_url_, &value_) {
|
||||
SharedCtor();
|
||||
@ -131,11 +126,11 @@ Any::Any(const Any& from)
|
||||
_any_metadata_(&type_url_, &value_) {
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.type_url().size() > 0) {
|
||||
if (!from.type_url().empty()) {
|
||||
type_url_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.type_url_);
|
||||
}
|
||||
value_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.value().size() > 0) {
|
||||
if (!from.value().empty()) {
|
||||
value_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.value_);
|
||||
}
|
||||
// @@protoc_insertion_point(copy_constructor:google.protobuf.Any)
|
||||
@ -419,10 +414,6 @@ bool Any::IsInitialized() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Any::Swap(Any* other) {
|
||||
if (other == this) return;
|
||||
InternalSwap(other);
|
||||
}
|
||||
void Any::InternalSwap(Any* other) {
|
||||
using std::swap;
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
|
@ -8,12 +8,12 @@
|
||||
#include <string>
|
||||
|
||||
#include <google/protobuf/port_def.inc>
|
||||
#if PROTOBUF_VERSION < 3007000
|
||||
#if PROTOBUF_VERSION < 3008000
|
||||
#error This file was generated by a newer version of protoc which is
|
||||
#error incompatible with your Protocol Buffer headers. Please update
|
||||
#error your headers.
|
||||
#endif
|
||||
#if 3007001 < PROTOBUF_MIN_PROTOC_VERSION
|
||||
#if 3008000 < PROTOBUF_MIN_PROTOC_VERSION
|
||||
#error This file was generated by an older version of protoc which is
|
||||
#error incompatible with your Protocol Buffer headers. Please
|
||||
#error regenerate this file with a newer version of protoc.
|
||||
@ -126,10 +126,13 @@ class PROTOBUF_EXPORT Any :
|
||||
}
|
||||
static bool ParseAnyTypeUrl(const string& type_url,
|
||||
std::string* full_type_name);
|
||||
void Swap(Any* other);
|
||||
friend void swap(Any& a, Any& b) {
|
||||
a.Swap(&b);
|
||||
}
|
||||
inline void Swap(Any* other) {
|
||||
if (other == this) return;
|
||||
InternalSwap(other);
|
||||
}
|
||||
|
||||
// implements Message ----------------------------------------------
|
||||
|
||||
@ -191,9 +194,12 @@ class PROTOBUF_EXPORT Any :
|
||||
|
||||
// accessors -------------------------------------------------------
|
||||
|
||||
enum : int {
|
||||
kTypeUrlFieldNumber = 1,
|
||||
kValueFieldNumber = 2,
|
||||
};
|
||||
// string type_url = 1;
|
||||
void clear_type_url();
|
||||
static const int kTypeUrlFieldNumber = 1;
|
||||
const std::string& type_url() const;
|
||||
void set_type_url(const std::string& value);
|
||||
void set_type_url(std::string&& value);
|
||||
@ -205,7 +211,6 @@ class PROTOBUF_EXPORT Any :
|
||||
|
||||
// bytes value = 2;
|
||||
void clear_value();
|
||||
static const int kValueFieldNumber = 2;
|
||||
const std::string& value() const;
|
||||
void set_value(const std::string& value);
|
||||
void set_value(std::string&& value);
|
||||
@ -217,7 +222,7 @@ class PROTOBUF_EXPORT Any :
|
||||
|
||||
// @@protoc_insertion_point(class_scope:google.protobuf.Any)
|
||||
private:
|
||||
class HasBitSetters;
|
||||
class _Internal;
|
||||
|
||||
::PROTOBUF_NAMESPACE_ID::internal::InternalMetadataWithArena _internal_metadata_;
|
||||
::PROTOBUF_NAMESPACE_ID::internal::ArenaStringPtr type_url_;
|
||||
|
@ -178,13 +178,13 @@ void Api::InitAsDefaultInstance() {
|
||||
PROTOBUF_NAMESPACE_ID::_Api_default_instance_._instance.get_mutable()->source_context_ = const_cast< PROTOBUF_NAMESPACE_ID::SourceContext*>(
|
||||
PROTOBUF_NAMESPACE_ID::SourceContext::internal_default_instance());
|
||||
}
|
||||
class Api::HasBitSetters {
|
||||
class Api::_Internal {
|
||||
public:
|
||||
static const PROTOBUF_NAMESPACE_ID::SourceContext& source_context(const Api* msg);
|
||||
};
|
||||
|
||||
const PROTOBUF_NAMESPACE_ID::SourceContext&
|
||||
Api::HasBitSetters::source_context(const Api* msg) {
|
||||
Api::_Internal::source_context(const Api* msg) {
|
||||
return *msg->source_context_;
|
||||
}
|
||||
void Api::clear_options() {
|
||||
@ -196,16 +196,6 @@ void Api::clear_source_context() {
|
||||
}
|
||||
source_context_ = nullptr;
|
||||
}
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
const int Api::kNameFieldNumber;
|
||||
const int Api::kMethodsFieldNumber;
|
||||
const int Api::kOptionsFieldNumber;
|
||||
const int Api::kVersionFieldNumber;
|
||||
const int Api::kSourceContextFieldNumber;
|
||||
const int Api::kMixinsFieldNumber;
|
||||
const int Api::kSyntaxFieldNumber;
|
||||
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
|
||||
Api::Api()
|
||||
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
|
||||
SharedCtor();
|
||||
@ -219,11 +209,11 @@ Api::Api(const Api& from)
|
||||
mixins_(from.mixins_) {
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.name().size() > 0) {
|
||||
if (!from.name().empty()) {
|
||||
name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_);
|
||||
}
|
||||
version_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.version().size() > 0) {
|
||||
if (!from.version().empty()) {
|
||||
version_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.version_);
|
||||
}
|
||||
if (from.has_source_context()) {
|
||||
@ -542,7 +532,7 @@ void Api::SerializeWithCachedSizes(
|
||||
// .google.protobuf.SourceContext source_context = 5;
|
||||
if (this->has_source_context()) {
|
||||
::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::WriteMessageMaybeToArray(
|
||||
5, HasBitSetters::source_context(this), output);
|
||||
5, _Internal::source_context(this), output);
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
@ -615,7 +605,7 @@ void Api::SerializeWithCachedSizes(
|
||||
if (this->has_source_context()) {
|
||||
target = ::PROTOBUF_NAMESPACE_ID::internal::WireFormatLite::
|
||||
InternalWriteMessageToArray(
|
||||
5, HasBitSetters::source_context(this), target);
|
||||
5, _Internal::source_context(this), target);
|
||||
}
|
||||
|
||||
// repeated .google.protobuf.Mixin mixins = 6;
|
||||
@ -777,10 +767,6 @@ bool Api::IsInitialized() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Api::Swap(Api* other) {
|
||||
if (other == this) return;
|
||||
InternalSwap(other);
|
||||
}
|
||||
void Api::InternalSwap(Api* other) {
|
||||
using std::swap;
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
@ -804,23 +790,13 @@ void Api::InternalSwap(Api* other) {
|
||||
|
||||
void Method::InitAsDefaultInstance() {
|
||||
}
|
||||
class Method::HasBitSetters {
|
||||
class Method::_Internal {
|
||||
public:
|
||||
};
|
||||
|
||||
void Method::clear_options() {
|
||||
options_.Clear();
|
||||
}
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
const int Method::kNameFieldNumber;
|
||||
const int Method::kRequestTypeUrlFieldNumber;
|
||||
const int Method::kRequestStreamingFieldNumber;
|
||||
const int Method::kResponseTypeUrlFieldNumber;
|
||||
const int Method::kResponseStreamingFieldNumber;
|
||||
const int Method::kOptionsFieldNumber;
|
||||
const int Method::kSyntaxFieldNumber;
|
||||
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
|
||||
Method::Method()
|
||||
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
|
||||
SharedCtor();
|
||||
@ -832,15 +808,15 @@ Method::Method(const Method& from)
|
||||
options_(from.options_) {
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.name().size() > 0) {
|
||||
if (!from.name().empty()) {
|
||||
name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_);
|
||||
}
|
||||
request_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.request_type_url().size() > 0) {
|
||||
if (!from.request_type_url().empty()) {
|
||||
request_type_url_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.request_type_url_);
|
||||
}
|
||||
response_type_url_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.response_type_url().size() > 0) {
|
||||
if (!from.response_type_url().empty()) {
|
||||
response_type_url_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.response_type_url_);
|
||||
}
|
||||
::memcpy(&request_streaming_, &from.request_streaming_,
|
||||
@ -1374,10 +1350,6 @@ bool Method::IsInitialized() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Method::Swap(Method* other) {
|
||||
if (other == this) return;
|
||||
InternalSwap(other);
|
||||
}
|
||||
void Method::InternalSwap(Method* other) {
|
||||
using std::swap;
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
@ -1402,15 +1374,10 @@ void Method::InternalSwap(Method* other) {
|
||||
|
||||
void Mixin::InitAsDefaultInstance() {
|
||||
}
|
||||
class Mixin::HasBitSetters {
|
||||
class Mixin::_Internal {
|
||||
public:
|
||||
};
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
const int Mixin::kNameFieldNumber;
|
||||
const int Mixin::kRootFieldNumber;
|
||||
#endif // !defined(_MSC_VER) || _MSC_VER >= 1900
|
||||
|
||||
Mixin::Mixin()
|
||||
: ::PROTOBUF_NAMESPACE_ID::Message(), _internal_metadata_(nullptr) {
|
||||
SharedCtor();
|
||||
@ -1421,11 +1388,11 @@ Mixin::Mixin(const Mixin& from)
|
||||
_internal_metadata_(nullptr) {
|
||||
_internal_metadata_.MergeFrom(from._internal_metadata_);
|
||||
name_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.name().size() > 0) {
|
||||
if (!from.name().empty()) {
|
||||
name_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.name_);
|
||||
}
|
||||
root_.UnsafeSetDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited());
|
||||
if (from.root().size() > 0) {
|
||||
if (!from.root().empty()) {
|
||||
root_.AssignWithDefault(&::PROTOBUF_NAMESPACE_ID::internal::GetEmptyStringAlreadyInited(), from.root_);
|
||||
}
|
||||
// @@protoc_insertion_point(copy_constructor:google.protobuf.Mixin)
|
||||
@ -1721,10 +1688,6 @@ bool Mixin::IsInitialized() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
void Mixin::Swap(Mixin* other) {
|
||||
if (other == this) return;
|
||||
InternalSwap(other);
|
||||
}
|
||||
void Mixin::InternalSwap(Mixin* other) {
|
||||
using std::swap;
|
||||
_internal_metadata_.Swap(&other->_internal_metadata_);
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user