From b56703eadc93d7be6b4330bf2d94b4da5362e007 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Thu, 17 Jul 2014 18:24:03 +0200 Subject: [PATCH] Add Google Protobuf support with a MessageConverter This change adds a new HttpMessageConverter supporting Google protocol buffers (aka Protobuf). This message converter supports the following media types: * application/json * application/xml * text/plain * text/html (output only) * and by default application/x-protobuf Note, in order to generate Proto Message classes, the protoc binary must be available on your system. Issue: SPR-5807/SPR-6259 --- build.gradle | 19 + .../ExtensionRegistryInitializer.java | 40 ++ .../ProtobufHttpMessageConverter.java | 204 ++++++ .../ProtobufHttpMessageConverterTests.java | 124 ++++ .../org/springframework/protobuf/Msg.java | 636 ++++++++++++++++++ .../protobuf/MsgOrBuilder.java | 37 + .../springframework/protobuf/OuterSample.java | 62 ++ .../springframework/protobuf/SecondMsg.java | 388 +++++++++++ .../protobuf/SecondMsgOrBuilder.java | 18 + spring-web/src/test/proto/sample.proto | 12 + 10 files changed, 1540 insertions(+) create mode 100644 spring-web/src/main/java/org/springframework/http/converter/protobuf/ExtensionRegistryInitializer.java create mode 100644 spring-web/src/main/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverter.java create mode 100644 spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java create mode 100644 spring-web/src/test/java/org/springframework/protobuf/Msg.java create mode 100644 spring-web/src/test/java/org/springframework/protobuf/MsgOrBuilder.java create mode 100644 spring-web/src/test/java/org/springframework/protobuf/OuterSample.java create mode 100644 spring-web/src/test/java/org/springframework/protobuf/SecondMsg.java create mode 100644 spring-web/src/test/java/org/springframework/protobuf/SecondMsgOrBuilder.java create mode 100644 spring-web/src/test/proto/sample.proto diff --git a/build.gradle b/build.gradle index 78913c1d61..82a0227c70 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ buildscript { classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7") classpath("org.asciidoctor:asciidoctor-gradle-plugin:0.7.0") classpath("org.springframework.build.gradle:docbook-reference-plugin:0.2.8") + classpath("ws.antonov.gradle.plugins:gradle-plugin-protobuf:0.9.1") } } @@ -37,6 +38,7 @@ configure(allprojects) { project -> ext.tiles3Version = "3.0.4" ext.tomcatVersion = "8.0.9" ext.xstreamVersion = "1.4.7" + ext.protobufVersion = "2.5.0" ext.gradleScriptDir = "${rootProject.projectDir}/gradle" @@ -611,6 +613,21 @@ project("spring-web") { description = "Spring Web" apply plugin: "groovy" + // Re-generate Protobuf classes from *.proto files and move them in test sources + if (project.hasProperty('genProtobuf')) { + apply plugin: 'protobuf' + + task updateGenProtobuf(type:Copy, dependsOn: ":spring-web:generateTestProto") { + from "${project.buildDir}/generated-sources/test/" + into "${projectDir}/src/test/java" + doLast { + project.delete "${project.buildDir}/generated-sources/test" + } + } + + tasks.getByPath("compileTestJava").dependsOn "updateGenProtobuf" + } + dependencies { compile(project(":spring-aop")) // for JaxWsPortProxyFactoryBean compile(project(":spring-beans")) // for MultiPartFilter @@ -638,6 +655,8 @@ project("spring-web") { exclude group: "javax.servlet", module: "javax.servlet-api" } optional("log4j:log4j:1.2.17") + optional("com.googlecode.protobuf-java-format:protobuf-java-format:1.2") + optional("com.google.protobuf:protobuf-java:${protobufVersion}") testCompile(project(":spring-context-support")) // for JafMediaTypeFactory testCompile("xmlunit:xmlunit:1.5") testCompile("org.slf4j:slf4j-jcl:${slf4jVersion}") diff --git a/spring-web/src/main/java/org/springframework/http/converter/protobuf/ExtensionRegistryInitializer.java b/spring-web/src/main/java/org/springframework/http/converter/protobuf/ExtensionRegistryInitializer.java new file mode 100644 index 0000000000..ac08b660eb --- /dev/null +++ b/spring-web/src/main/java/org/springframework/http/converter/protobuf/ExtensionRegistryInitializer.java @@ -0,0 +1,40 @@ +/* + * Copyright 2002-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.http.converter.protobuf; + +import com.google.protobuf.ExtensionRegistry; + +/** + * Google Protocol Messages can contain message extensions that can be parsed if + * the appropriate configuration has been registered in the {@code ExtensionRegistry}. + * + * This interface provides a facility to populate the {@code ExtensionRegistry}. + * + * @author Alex Antonov + * @since 4.1 + * @see + * com.google.protobuf.ExtensionRegistry + */ +public interface ExtensionRegistryInitializer { + + /** + * Initializes the {@code ExtensionRegistry} with Protocol Message extensions + * @param registry the registry to populate + */ + void initializeExtensionRegistry(ExtensionRegistry registry); + +} diff --git a/spring-web/src/main/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverter.java b/spring-web/src/main/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverter.java new file mode 100644 index 0000000000..3379b13d25 --- /dev/null +++ b/spring-web/src/main/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverter.java @@ -0,0 +1,204 @@ +/* + * Copyright 2002-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.http.converter.protobuf; + +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.StringWriter; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Method; +import java.nio.charset.Charset; +import java.util.concurrent.ConcurrentHashMap; + +import com.google.protobuf.ExtensionRegistry; +import com.google.protobuf.Message; +import com.google.protobuf.TextFormat; +import com.googlecode.protobuf.format.HtmlFormat; +import com.googlecode.protobuf.format.JsonFormat; +import com.googlecode.protobuf.format.XmlFormat; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpInputMessage; +import org.springframework.http.HttpOutputMessage; +import org.springframework.http.MediaType; +import org.springframework.http.converter.AbstractHttpMessageConverter; +import org.springframework.http.converter.HttpMessageNotReadableException; +import org.springframework.http.converter.HttpMessageNotWritableException; +import org.springframework.util.Assert; +import org.springframework.util.FileCopyUtils; + + +/** + * Implementation of {@link org.springframework.http.converter.HttpMessageConverter} + * that can read and write Protobuf {@code Message}s using the + * Google Protocol buffers library. + * + *

By default, it supports {@code application/json}, {@code application/xml}, {@code text/plain} + * and {@code application/x-protobuf}. {@code text/html} is only supported when writing messages. + * + *

In order to generate Message Java classes, you should install the protoc binary on your system. + *

Tested against Protobuf version 2.5.0. + * + * @author Alex Antonov + * @author Brian Clozel + * @since 4.1 + */ +public class ProtobufHttpMessageConverter extends AbstractHttpMessageConverter { + + public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); + + public static final MediaType PROTOBUF = new MediaType("application", "x-protobuf", DEFAULT_CHARSET); + + public static final String X_PROTOBUF_SCHEMA_HEADER = "X-Protobuf-Schema"; + public static final String X_PROTOBUF_MESSAGE_HEADER = "X-Protobuf-Message"; + + private static final ConcurrentHashMap, Method> newBuilderMethodCache = + new ConcurrentHashMap, Method>(); + + private ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance(); + + /** + * Construct a new {@code ProtobufHttpMessageConverter}. + */ + public ProtobufHttpMessageConverter() { + this(null); + } + + /** + * Construct a new {@code ProtobufHttpMessageConverter} with a {@link ExtensionRegistryInitializer}, + * allowing to register message extensions. + */ + public ProtobufHttpMessageConverter(ExtensionRegistryInitializer registryInitializer) { + + //TODO: should we handle "*+json", "*+xml" as well? + super(PROTOBUF, MediaType.TEXT_PLAIN, + MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON); + Assert.notNull(registryInitializer, "ExtensionRegistryInitializer must not be null"); + registryInitializer.initializeExtensionRegistry(extensionRegistry); + } + + @Override + protected boolean supports(Class clazz) { + return Message.class.isAssignableFrom(clazz); + } + + + @Override + protected Message readInternal(Class clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { + MediaType contentType = inputMessage.getHeaders().getContentType(); + contentType = contentType != null ? contentType : PROTOBUF; + + InputStreamReader reader = new InputStreamReader(inputMessage.getBody(), getCharset(inputMessage.getHeaders())); + + try { + Message.Builder builder = createMessageBuilder(clazz); + + if (MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) { + JsonFormat.merge(reader, extensionRegistry, builder); + } + else if (MediaType.TEXT_PLAIN.isCompatibleWith(contentType)) { + TextFormat.merge(reader, extensionRegistry, builder); + } + else if (MediaType.APPLICATION_XML.isCompatibleWith(contentType)) { + XmlFormat.merge(reader, extensionRegistry, builder); + } + else { // ProtobufHttpMessageConverter.PROTOBUF + builder.mergeFrom(inputMessage.getBody(), extensionRegistry); + } + return builder.build(); + } + catch (Exception e) { + throw new HttpMessageNotReadableException("Could not read Protobuf message: " + e.getMessage(), e); + } + } + + private Charset getCharset(HttpHeaders headers) { + if (headers == null || headers.getContentType() == null || headers.getContentType().getCharSet() == null) { + return DEFAULT_CHARSET; + } + return headers.getContentType().getCharSet(); + } + + /** + * Create a new {@code Message.Builder} instance for the given class. + *

This method uses a ConcurrentHashMap for caching method lookups. + */ + private Message.Builder createMessageBuilder(Class clazz) throws Exception { + Method m = newBuilderMethodCache.get(clazz); + if (m == null) { + m = clazz.getMethod("newBuilder"); + newBuilderMethodCache.put(clazz, m); + } + return (Message.Builder) m.invoke(clazz); + } + + /** + * This method overrides the parent implementation, since this HttpMessageConverter + * can also produce {@code MediaType.HTML "text/html"} ContentType. + */ + @Override + protected boolean canWrite(MediaType mediaType) { + return super.canWrite(mediaType) || MediaType.TEXT_HTML.isCompatibleWith(mediaType); + } + + @Override + protected void writeInternal(Message message, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException { + MediaType contentType = outputMessage.getHeaders().getContentType(); + Charset charset = getCharset(contentType); + OutputStreamWriter writer = new OutputStreamWriter(outputMessage.getBody(), charset); + + if (MediaType.TEXT_HTML.isCompatibleWith(contentType)) { + HtmlFormat.print(message, writer); + } + else if (MediaType.APPLICATION_JSON.isCompatibleWith(contentType)) { + JsonFormat.print(message, writer); + } + else if (MediaType.TEXT_PLAIN.isCompatibleWith(contentType)) { + TextFormat.print(message, writer); + } + else if (MediaType.APPLICATION_XML.isCompatibleWith(contentType)) { + XmlFormat.print(message, writer); + } + else if (PROTOBUF.isCompatibleWith(contentType)) { + setProtoHeader(outputMessage, message); + FileCopyUtils.copy(message.toByteArray(), outputMessage.getBody()); + } + } + + private Charset getCharset(MediaType contentType) { + return contentType.getCharSet() != null ? contentType.getCharSet() : DEFAULT_CHARSET; + } + + /** + * Set the "X-Protobuf-*" HTTP headers when responding with + * a message of ContentType "application/x-protobuf" + */ + private void setProtoHeader(final HttpOutputMessage response, final Message message) { + response.getHeaders().set(X_PROTOBUF_SCHEMA_HEADER, + message.getDescriptorForType().getFile().getName()); + + response.getHeaders().set(X_PROTOBUF_MESSAGE_HEADER, + message.getDescriptorForType().getFullName()); + } + + @Override + protected MediaType getDefaultContentType(Message message) { + return PROTOBUF; + } + +} diff --git a/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java b/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java new file mode 100644 index 0000000000..965b9d7467 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/http/converter/protobuf/ProtobufHttpMessageConverterTests.java @@ -0,0 +1,124 @@ +/* + * Copyright 2002-2014 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.http.converter.protobuf; + +import java.io.IOException; + +import com.google.protobuf.Message; +import org.junit.Before; +import org.junit.Test; + +import org.springframework.http.MediaType; +import org.springframework.http.MockHttpInputMessage; +import org.springframework.http.MockHttpOutputMessage; +import org.springframework.protobuf.Msg; +import org.springframework.protobuf.SecondMsg; + +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; + +/** + * Test suite for {@link ProtobufHttpMessageConverter} + * @author Alex Antonov + */ +public class ProtobufHttpMessageConverterTests { + + private ProtobufHttpMessageConverter converter; + + private ExtensionRegistryInitializer registryInitializer; + + private Msg testMsg; + + @Before + public void setUp() { + this.registryInitializer = mock(ExtensionRegistryInitializer.class); + this.converter = new ProtobufHttpMessageConverter(this.registryInitializer); + this.testMsg = Msg.newBuilder().setFoo("Foo").setBlah(SecondMsg.newBuilder().setBlah(123).build()).build(); + } + + @Test + public void extensionRegistryInitialized() { + verify(this.registryInitializer, times(1)).initializeExtensionRegistry(anyObject()); + } + + @Test + public void canRead() { + assertTrue(this.converter.canRead(Msg.class, null)); + assertTrue(this.converter.canRead(Msg.class, ProtobufHttpMessageConverter.PROTOBUF)); + assertTrue(this.converter.canRead(Msg.class, MediaType.APPLICATION_JSON)); + assertTrue(this.converter.canRead(Msg.class, MediaType.APPLICATION_XML)); + assertTrue(this.converter.canRead(Msg.class, MediaType.TEXT_PLAIN)); + // only supported as an output format + assertFalse(this.converter.canRead(Msg.class, MediaType.TEXT_HTML)); + } + + @Test + public void canWrite() { + assertTrue(this.converter.canWrite(Msg.class, null)); + assertTrue(this.converter.canWrite(Msg.class, ProtobufHttpMessageConverter.PROTOBUF)); + assertTrue(this.converter.canWrite(Msg.class, MediaType.APPLICATION_JSON)); + assertTrue(this.converter.canWrite(Msg.class, MediaType.APPLICATION_XML)); + assertTrue(this.converter.canWrite(Msg.class, MediaType.TEXT_PLAIN)); + assertTrue(this.converter.canWrite(Msg.class, MediaType.TEXT_HTML)); + } + + @Test + public void read() throws IOException { + byte[] body = this.testMsg.toByteArray(); + MockHttpInputMessage inputMessage = new MockHttpInputMessage(body); + inputMessage.getHeaders().setContentType(ProtobufHttpMessageConverter.PROTOBUF); + Message result = this.converter.read(Msg.class, inputMessage); + assertEquals(this.testMsg, result); + } + + @Test + public void readNoContentType() throws IOException { + byte[] body = this.testMsg.toByteArray(); + MockHttpInputMessage inputMessage = new MockHttpInputMessage(body); + Message result = this.converter.read(Msg.class, inputMessage); + assertEquals(this.testMsg, result); + } + + @Test + public void write() throws IOException { + MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); + MediaType contentType = ProtobufHttpMessageConverter.PROTOBUF; + this.converter.write(this.testMsg, contentType, outputMessage); + assertEquals(contentType, outputMessage.getHeaders().getContentType()); + assertTrue(outputMessage.getBodyAsBytes().length > 0); + Message result = Msg.parseFrom(outputMessage.getBodyAsBytes()); + assertEquals(this.testMsg, result); + + String messageHeader = outputMessage.getHeaders().getFirst(ProtobufHttpMessageConverter.X_PROTOBUF_MESSAGE_HEADER); + assertEquals("Msg", messageHeader); + String schemaHeader = outputMessage.getHeaders().getFirst(ProtobufHttpMessageConverter.X_PROTOBUF_SCHEMA_HEADER); + assertEquals("sample.proto", schemaHeader); + } + + @Test + public void defaultContentType() throws Exception { + assertEquals(ProtobufHttpMessageConverter.PROTOBUF, this.converter.getDefaultContentType(this.testMsg)); + } + + @Test + public void getContentLength() throws Exception { + MockHttpOutputMessage outputMessage = new MockHttpOutputMessage(); + MediaType contentType = ProtobufHttpMessageConverter.PROTOBUF; + this.converter.write(this.testMsg, contentType, outputMessage); + assertEquals(-1, outputMessage.getHeaders().getContentLength()); + } +} diff --git a/spring-web/src/test/java/org/springframework/protobuf/Msg.java b/spring-web/src/test/java/org/springframework/protobuf/Msg.java new file mode 100644 index 0000000000..b8d966600f --- /dev/null +++ b/spring-web/src/test/java/org/springframework/protobuf/Msg.java @@ -0,0 +1,636 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: sample.proto + +package org.springframework.protobuf; + +/** + * Protobuf type {@code Msg} + */ +public final class Msg extends + com.google.protobuf.GeneratedMessage + implements MsgOrBuilder { + // Use Msg.newBuilder() to construct. + private Msg(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private Msg(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final Msg defaultInstance; + public static Msg getDefaultInstance() { + return defaultInstance; + } + + public Msg getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private Msg( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 10: { + bitField0_ |= 0x00000001; + foo_ = input.readBytes(); + break; + } + case 18: { + org.springframework.protobuf.SecondMsg.Builder subBuilder = null; + if (((bitField0_ & 0x00000002) == 0x00000002)) { + subBuilder = blah_.toBuilder(); + } + blah_ = input.readMessage(org.springframework.protobuf.SecondMsg.PARSER, extensionRegistry); + if (subBuilder != null) { + subBuilder.mergeFrom(blah_); + blah_ = subBuilder.buildPartial(); + } + bitField0_ |= 0x00000002; + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.springframework.protobuf.OuterSample.internal_static_Msg_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.springframework.protobuf.OuterSample.internal_static_Msg_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.springframework.protobuf.Msg.class, org.springframework.protobuf.Msg.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public Msg parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new Msg(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional string foo = 1; + public static final int FOO_FIELD_NUMBER = 1; + private java.lang.Object foo_; + /** + * optional string foo = 1; + */ + public boolean hasFoo() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string foo = 1; + */ + public java.lang.String getFoo() { + java.lang.Object ref = foo_; + if (ref instanceof java.lang.String) { + return (java.lang.String) ref; + } else { + com.google.protobuf.ByteString bs = + (com.google.protobuf.ByteString) ref; + java.lang.String s = bs.toStringUtf8(); + if (bs.isValidUtf8()) { + foo_ = s; + } + return s; + } + } + /** + * optional string foo = 1; + */ + public com.google.protobuf.ByteString + getFooBytes() { + java.lang.Object ref = foo_; + if (ref instanceof java.lang.String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + foo_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + + // optional .SecondMsg blah = 2; + public static final int BLAH_FIELD_NUMBER = 2; + private org.springframework.protobuf.SecondMsg blah_; + /** + * optional .SecondMsg blah = 2; + */ + public boolean hasBlah() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .SecondMsg blah = 2; + */ + public org.springframework.protobuf.SecondMsg getBlah() { + return blah_; + } + /** + * optional .SecondMsg blah = 2; + */ + public org.springframework.protobuf.SecondMsgOrBuilder getBlahOrBuilder() { + return blah_; + } + + private void initFields() { + foo_ = ""; + blah_ = org.springframework.protobuf.SecondMsg.getDefaultInstance(); + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeBytes(1, getFooBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + output.writeMessage(2, blah_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeBytesSize(1, getFooBytes()); + } + if (((bitField0_ & 0x00000002) == 0x00000002)) { + size += com.google.protobuf.CodedOutputStream + .computeMessageSize(2, blah_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.springframework.protobuf.Msg parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.springframework.protobuf.Msg parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.springframework.protobuf.Msg parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.springframework.protobuf.Msg parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.springframework.protobuf.Msg parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.springframework.protobuf.Msg parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.springframework.protobuf.Msg parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.springframework.protobuf.Msg parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.springframework.protobuf.Msg parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.springframework.protobuf.Msg parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.springframework.protobuf.Msg prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code Msg} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.springframework.protobuf.MsgOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.springframework.protobuf.OuterSample.internal_static_Msg_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.springframework.protobuf.OuterSample.internal_static_Msg_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.springframework.protobuf.Msg.class, org.springframework.protobuf.Msg.Builder.class); + } + + // Construct using org.springframework.protobuf.Msg.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + getBlahFieldBuilder(); + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + foo_ = ""; + bitField0_ = (bitField0_ & ~0x00000001); + if (blahBuilder_ == null) { + blah_ = org.springframework.protobuf.SecondMsg.getDefaultInstance(); + } else { + blahBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.springframework.protobuf.OuterSample.internal_static_Msg_descriptor; + } + + public org.springframework.protobuf.Msg getDefaultInstanceForType() { + return org.springframework.protobuf.Msg.getDefaultInstance(); + } + + public org.springframework.protobuf.Msg build() { + org.springframework.protobuf.Msg result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.springframework.protobuf.Msg buildPartial() { + org.springframework.protobuf.Msg result = new org.springframework.protobuf.Msg(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.foo_ = foo_; + if (((from_bitField0_ & 0x00000002) == 0x00000002)) { + to_bitField0_ |= 0x00000002; + } + if (blahBuilder_ == null) { + result.blah_ = blah_; + } else { + result.blah_ = blahBuilder_.build(); + } + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.springframework.protobuf.Msg) { + return mergeFrom((org.springframework.protobuf.Msg)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.springframework.protobuf.Msg other) { + if (other == org.springframework.protobuf.Msg.getDefaultInstance()) return this; + if (other.hasFoo()) { + bitField0_ |= 0x00000001; + foo_ = other.foo_; + onChanged(); + } + if (other.hasBlah()) { + mergeBlah(other.getBlah()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.springframework.protobuf.Msg parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.springframework.protobuf.Msg) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional string foo = 1; + private java.lang.Object foo_ = ""; + /** + * optional string foo = 1; + */ + public boolean hasFoo() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional string foo = 1; + */ + public java.lang.String getFoo() { + java.lang.Object ref = foo_; + if (!(ref instanceof java.lang.String)) { + java.lang.String s = ((com.google.protobuf.ByteString) ref) + .toStringUtf8(); + foo_ = s; + return s; + } else { + return (java.lang.String) ref; + } + } + /** + * optional string foo = 1; + */ + public com.google.protobuf.ByteString + getFooBytes() { + java.lang.Object ref = foo_; + if (ref instanceof String) { + com.google.protobuf.ByteString b = + com.google.protobuf.ByteString.copyFromUtf8( + (java.lang.String) ref); + foo_ = b; + return b; + } else { + return (com.google.protobuf.ByteString) ref; + } + } + /** + * optional string foo = 1; + */ + public Builder setFoo( + java.lang.String value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + foo_ = value; + onChanged(); + return this; + } + /** + * optional string foo = 1; + */ + public Builder clearFoo() { + bitField0_ = (bitField0_ & ~0x00000001); + foo_ = getDefaultInstance().getFoo(); + onChanged(); + return this; + } + /** + * optional string foo = 1; + */ + public Builder setFooBytes( + com.google.protobuf.ByteString value) { + if (value == null) { + throw new NullPointerException(); + } + bitField0_ |= 0x00000001; + foo_ = value; + onChanged(); + return this; + } + + // optional .SecondMsg blah = 2; + private org.springframework.protobuf.SecondMsg blah_ = org.springframework.protobuf.SecondMsg.getDefaultInstance(); + private com.google.protobuf.SingleFieldBuilder< + org.springframework.protobuf.SecondMsg, org.springframework.protobuf.SecondMsg.Builder, org.springframework.protobuf.SecondMsgOrBuilder> blahBuilder_; + /** + * optional .SecondMsg blah = 2; + */ + public boolean hasBlah() { + return ((bitField0_ & 0x00000002) == 0x00000002); + } + /** + * optional .SecondMsg blah = 2; + */ + public org.springframework.protobuf.SecondMsg getBlah() { + if (blahBuilder_ == null) { + return blah_; + } else { + return blahBuilder_.getMessage(); + } + } + /** + * optional .SecondMsg blah = 2; + */ + public Builder setBlah(org.springframework.protobuf.SecondMsg value) { + if (blahBuilder_ == null) { + if (value == null) { + throw new NullPointerException(); + } + blah_ = value; + onChanged(); + } else { + blahBuilder_.setMessage(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .SecondMsg blah = 2; + */ + public Builder setBlah( + org.springframework.protobuf.SecondMsg.Builder builderForValue) { + if (blahBuilder_ == null) { + blah_ = builderForValue.build(); + onChanged(); + } else { + blahBuilder_.setMessage(builderForValue.build()); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .SecondMsg blah = 2; + */ + public Builder mergeBlah(org.springframework.protobuf.SecondMsg value) { + if (blahBuilder_ == null) { + if (((bitField0_ & 0x00000002) == 0x00000002) && + blah_ != org.springframework.protobuf.SecondMsg.getDefaultInstance()) { + blah_ = + org.springframework.protobuf.SecondMsg.newBuilder(blah_).mergeFrom(value).buildPartial(); + } else { + blah_ = value; + } + onChanged(); + } else { + blahBuilder_.mergeFrom(value); + } + bitField0_ |= 0x00000002; + return this; + } + /** + * optional .SecondMsg blah = 2; + */ + public Builder clearBlah() { + if (blahBuilder_ == null) { + blah_ = org.springframework.protobuf.SecondMsg.getDefaultInstance(); + onChanged(); + } else { + blahBuilder_.clear(); + } + bitField0_ = (bitField0_ & ~0x00000002); + return this; + } + /** + * optional .SecondMsg blah = 2; + */ + public org.springframework.protobuf.SecondMsg.Builder getBlahBuilder() { + bitField0_ |= 0x00000002; + onChanged(); + return getBlahFieldBuilder().getBuilder(); + } + /** + * optional .SecondMsg blah = 2; + */ + public org.springframework.protobuf.SecondMsgOrBuilder getBlahOrBuilder() { + if (blahBuilder_ != null) { + return blahBuilder_.getMessageOrBuilder(); + } else { + return blah_; + } + } + /** + * optional .SecondMsg blah = 2; + */ + private com.google.protobuf.SingleFieldBuilder< + org.springframework.protobuf.SecondMsg, org.springframework.protobuf.SecondMsg.Builder, org.springframework.protobuf.SecondMsgOrBuilder> + getBlahFieldBuilder() { + if (blahBuilder_ == null) { + blahBuilder_ = new com.google.protobuf.SingleFieldBuilder< + org.springframework.protobuf.SecondMsg, org.springframework.protobuf.SecondMsg.Builder, org.springframework.protobuf.SecondMsgOrBuilder>( + blah_, + getParentForChildren(), + isClean()); + blah_ = null; + } + return blahBuilder_; + } + + // @@protoc_insertion_point(builder_scope:Msg) + } + + static { + defaultInstance = new Msg(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:Msg) +} + diff --git a/spring-web/src/test/java/org/springframework/protobuf/MsgOrBuilder.java b/spring-web/src/test/java/org/springframework/protobuf/MsgOrBuilder.java new file mode 100644 index 0000000000..7a25a3ad55 --- /dev/null +++ b/spring-web/src/test/java/org/springframework/protobuf/MsgOrBuilder.java @@ -0,0 +1,37 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: sample.proto + +package org.springframework.protobuf; + +public interface MsgOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional string foo = 1; + /** + * optional string foo = 1; + */ + boolean hasFoo(); + /** + * optional string foo = 1; + */ + java.lang.String getFoo(); + /** + * optional string foo = 1; + */ + com.google.protobuf.ByteString + getFooBytes(); + + // optional .SecondMsg blah = 2; + /** + * optional .SecondMsg blah = 2; + */ + boolean hasBlah(); + /** + * optional .SecondMsg blah = 2; + */ + org.springframework.protobuf.SecondMsg getBlah(); + /** + * optional .SecondMsg blah = 2; + */ + org.springframework.protobuf.SecondMsgOrBuilder getBlahOrBuilder(); +} diff --git a/spring-web/src/test/java/org/springframework/protobuf/OuterSample.java b/spring-web/src/test/java/org/springframework/protobuf/OuterSample.java new file mode 100644 index 0000000000..c952ef5a9f --- /dev/null +++ b/spring-web/src/test/java/org/springframework/protobuf/OuterSample.java @@ -0,0 +1,62 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: sample.proto + +package org.springframework.protobuf; + +public final class OuterSample { + private OuterSample() {} + public static void registerAllExtensions( + com.google.protobuf.ExtensionRegistry registry) { + } + static com.google.protobuf.Descriptors.Descriptor + internal_static_Msg_descriptor; + static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_Msg_fieldAccessorTable; + static com.google.protobuf.Descriptors.Descriptor + internal_static_SecondMsg_descriptor; + static + com.google.protobuf.GeneratedMessage.FieldAccessorTable + internal_static_SecondMsg_fieldAccessorTable; + + public static com.google.protobuf.Descriptors.FileDescriptor + getDescriptor() { + return descriptor; + } + private static com.google.protobuf.Descriptors.FileDescriptor + descriptor; + static { + java.lang.String[] descriptorData = { + "\n\014sample.proto\",\n\003Msg\022\013\n\003foo\030\001 \001(\t\022\030\n\004bl" + + "ah\030\002 \001(\0132\n.SecondMsg\"\031\n\tSecondMsg\022\014\n\004bla" + + "h\030\001 \001(\005B-\n\034org.springframework.protobufB" + + "\013OuterSampleP\001" + }; + com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner assigner = + new com.google.protobuf.Descriptors.FileDescriptor.InternalDescriptorAssigner() { + public com.google.protobuf.ExtensionRegistry assignDescriptors( + com.google.protobuf.Descriptors.FileDescriptor root) { + descriptor = root; + internal_static_Msg_descriptor = + getDescriptor().getMessageTypes().get(0); + internal_static_Msg_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_Msg_descriptor, + new java.lang.String[] { "Foo", "Blah", }); + internal_static_SecondMsg_descriptor = + getDescriptor().getMessageTypes().get(1); + internal_static_SecondMsg_fieldAccessorTable = new + com.google.protobuf.GeneratedMessage.FieldAccessorTable( + internal_static_SecondMsg_descriptor, + new java.lang.String[] { "Blah", }); + return null; + } + }; + com.google.protobuf.Descriptors.FileDescriptor + .internalBuildGeneratedFileFrom(descriptorData, + new com.google.protobuf.Descriptors.FileDescriptor[] { + }, assigner); + } + + // @@protoc_insertion_point(outer_class_scope) +} diff --git a/spring-web/src/test/java/org/springframework/protobuf/SecondMsg.java b/spring-web/src/test/java/org/springframework/protobuf/SecondMsg.java new file mode 100644 index 0000000000..9e3ec7639a --- /dev/null +++ b/spring-web/src/test/java/org/springframework/protobuf/SecondMsg.java @@ -0,0 +1,388 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: sample.proto + +package org.springframework.protobuf; + +/** + * Protobuf type {@code SecondMsg} + */ +public final class SecondMsg extends + com.google.protobuf.GeneratedMessage + implements SecondMsgOrBuilder { + // Use SecondMsg.newBuilder() to construct. + private SecondMsg(com.google.protobuf.GeneratedMessage.Builder builder) { + super(builder); + this.unknownFields = builder.getUnknownFields(); + } + private SecondMsg(boolean noInit) { this.unknownFields = com.google.protobuf.UnknownFieldSet.getDefaultInstance(); } + + private static final SecondMsg defaultInstance; + public static SecondMsg getDefaultInstance() { + return defaultInstance; + } + + public SecondMsg getDefaultInstanceForType() { + return defaultInstance; + } + + private final com.google.protobuf.UnknownFieldSet unknownFields; + @java.lang.Override + public final com.google.protobuf.UnknownFieldSet + getUnknownFields() { + return this.unknownFields; + } + private SecondMsg( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + initFields(); + int mutable_bitField0_ = 0; + com.google.protobuf.UnknownFieldSet.Builder unknownFields = + com.google.protobuf.UnknownFieldSet.newBuilder(); + try { + boolean done = false; + while (!done) { + int tag = input.readTag(); + switch (tag) { + case 0: + done = true; + break; + default: { + if (!parseUnknownField(input, unknownFields, + extensionRegistry, tag)) { + done = true; + } + break; + } + case 8: { + bitField0_ |= 0x00000001; + blah_ = input.readInt32(); + break; + } + } + } + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + throw e.setUnfinishedMessage(this); + } catch (java.io.IOException e) { + throw new com.google.protobuf.InvalidProtocolBufferException( + e.getMessage()).setUnfinishedMessage(this); + } finally { + this.unknownFields = unknownFields.build(); + makeExtensionsImmutable(); + } + } + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.springframework.protobuf.OuterSample.internal_static_SecondMsg_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.springframework.protobuf.OuterSample.internal_static_SecondMsg_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.springframework.protobuf.SecondMsg.class, org.springframework.protobuf.SecondMsg.Builder.class); + } + + public static com.google.protobuf.Parser PARSER = + new com.google.protobuf.AbstractParser() { + public SecondMsg parsePartialFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return new SecondMsg(input, extensionRegistry); + } + }; + + @java.lang.Override + public com.google.protobuf.Parser getParserForType() { + return PARSER; + } + + private int bitField0_; + // optional int32 blah = 1; + public static final int BLAH_FIELD_NUMBER = 1; + private int blah_; + /** + * optional int32 blah = 1; + */ + public boolean hasBlah() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional int32 blah = 1; + */ + public int getBlah() { + return blah_; + } + + private void initFields() { + blah_ = 0; + } + private byte memoizedIsInitialized = -1; + public final boolean isInitialized() { + byte isInitialized = memoizedIsInitialized; + if (isInitialized != -1) return isInitialized == 1; + + memoizedIsInitialized = 1; + return true; + } + + public void writeTo(com.google.protobuf.CodedOutputStream output) + throws java.io.IOException { + getSerializedSize(); + if (((bitField0_ & 0x00000001) == 0x00000001)) { + output.writeInt32(1, blah_); + } + getUnknownFields().writeTo(output); + } + + private int memoizedSerializedSize = -1; + public int getSerializedSize() { + int size = memoizedSerializedSize; + if (size != -1) return size; + + size = 0; + if (((bitField0_ & 0x00000001) == 0x00000001)) { + size += com.google.protobuf.CodedOutputStream + .computeInt32Size(1, blah_); + } + size += getUnknownFields().getSerializedSize(); + memoizedSerializedSize = size; + return size; + } + + private static final long serialVersionUID = 0L; + @java.lang.Override + protected java.lang.Object writeReplace() + throws java.io.ObjectStreamException { + return super.writeReplace(); + } + + public static org.springframework.protobuf.SecondMsg parseFrom( + com.google.protobuf.ByteString data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.springframework.protobuf.SecondMsg parseFrom( + com.google.protobuf.ByteString data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.springframework.protobuf.SecondMsg parseFrom(byte[] data) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data); + } + public static org.springframework.protobuf.SecondMsg parseFrom( + byte[] data, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws com.google.protobuf.InvalidProtocolBufferException { + return PARSER.parseFrom(data, extensionRegistry); + } + public static org.springframework.protobuf.SecondMsg parseFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.springframework.protobuf.SecondMsg parseFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + public static org.springframework.protobuf.SecondMsg parseDelimitedFrom(java.io.InputStream input) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input); + } + public static org.springframework.protobuf.SecondMsg parseDelimitedFrom( + java.io.InputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseDelimitedFrom(input, extensionRegistry); + } + public static org.springframework.protobuf.SecondMsg parseFrom( + com.google.protobuf.CodedInputStream input) + throws java.io.IOException { + return PARSER.parseFrom(input); + } + public static org.springframework.protobuf.SecondMsg parseFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + return PARSER.parseFrom(input, extensionRegistry); + } + + public static Builder newBuilder() { return Builder.create(); } + public Builder newBuilderForType() { return newBuilder(); } + public static Builder newBuilder(org.springframework.protobuf.SecondMsg prototype) { + return newBuilder().mergeFrom(prototype); + } + public Builder toBuilder() { return newBuilder(this); } + + @java.lang.Override + protected Builder newBuilderForType( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + Builder builder = new Builder(parent); + return builder; + } + /** + * Protobuf type {@code SecondMsg} + */ + public static final class Builder extends + com.google.protobuf.GeneratedMessage.Builder + implements org.springframework.protobuf.SecondMsgOrBuilder { + public static final com.google.protobuf.Descriptors.Descriptor + getDescriptor() { + return org.springframework.protobuf.OuterSample.internal_static_SecondMsg_descriptor; + } + + protected com.google.protobuf.GeneratedMessage.FieldAccessorTable + internalGetFieldAccessorTable() { + return org.springframework.protobuf.OuterSample.internal_static_SecondMsg_fieldAccessorTable + .ensureFieldAccessorsInitialized( + org.springframework.protobuf.SecondMsg.class, org.springframework.protobuf.SecondMsg.Builder.class); + } + + // Construct using org.springframework.protobuf.SecondMsg.newBuilder() + private Builder() { + maybeForceBuilderInitialization(); + } + + private Builder( + com.google.protobuf.GeneratedMessage.BuilderParent parent) { + super(parent); + maybeForceBuilderInitialization(); + } + private void maybeForceBuilderInitialization() { + if (com.google.protobuf.GeneratedMessage.alwaysUseFieldBuilders) { + } + } + private static Builder create() { + return new Builder(); + } + + public Builder clear() { + super.clear(); + blah_ = 0; + bitField0_ = (bitField0_ & ~0x00000001); + return this; + } + + public Builder clone() { + return create().mergeFrom(buildPartial()); + } + + public com.google.protobuf.Descriptors.Descriptor + getDescriptorForType() { + return org.springframework.protobuf.OuterSample.internal_static_SecondMsg_descriptor; + } + + public org.springframework.protobuf.SecondMsg getDefaultInstanceForType() { + return org.springframework.protobuf.SecondMsg.getDefaultInstance(); + } + + public org.springframework.protobuf.SecondMsg build() { + org.springframework.protobuf.SecondMsg result = buildPartial(); + if (!result.isInitialized()) { + throw newUninitializedMessageException(result); + } + return result; + } + + public org.springframework.protobuf.SecondMsg buildPartial() { + org.springframework.protobuf.SecondMsg result = new org.springframework.protobuf.SecondMsg(this); + int from_bitField0_ = bitField0_; + int to_bitField0_ = 0; + if (((from_bitField0_ & 0x00000001) == 0x00000001)) { + to_bitField0_ |= 0x00000001; + } + result.blah_ = blah_; + result.bitField0_ = to_bitField0_; + onBuilt(); + return result; + } + + public Builder mergeFrom(com.google.protobuf.Message other) { + if (other instanceof org.springframework.protobuf.SecondMsg) { + return mergeFrom((org.springframework.protobuf.SecondMsg)other); + } else { + super.mergeFrom(other); + return this; + } + } + + public Builder mergeFrom(org.springframework.protobuf.SecondMsg other) { + if (other == org.springframework.protobuf.SecondMsg.getDefaultInstance()) return this; + if (other.hasBlah()) { + setBlah(other.getBlah()); + } + this.mergeUnknownFields(other.getUnknownFields()); + return this; + } + + public final boolean isInitialized() { + return true; + } + + public Builder mergeFrom( + com.google.protobuf.CodedInputStream input, + com.google.protobuf.ExtensionRegistryLite extensionRegistry) + throws java.io.IOException { + org.springframework.protobuf.SecondMsg parsedMessage = null; + try { + parsedMessage = PARSER.parsePartialFrom(input, extensionRegistry); + } catch (com.google.protobuf.InvalidProtocolBufferException e) { + parsedMessage = (org.springframework.protobuf.SecondMsg) e.getUnfinishedMessage(); + throw e; + } finally { + if (parsedMessage != null) { + mergeFrom(parsedMessage); + } + } + return this; + } + private int bitField0_; + + // optional int32 blah = 1; + private int blah_ ; + /** + * optional int32 blah = 1; + */ + public boolean hasBlah() { + return ((bitField0_ & 0x00000001) == 0x00000001); + } + /** + * optional int32 blah = 1; + */ + public int getBlah() { + return blah_; + } + /** + * optional int32 blah = 1; + */ + public Builder setBlah(int value) { + bitField0_ |= 0x00000001; + blah_ = value; + onChanged(); + return this; + } + /** + * optional int32 blah = 1; + */ + public Builder clearBlah() { + bitField0_ = (bitField0_ & ~0x00000001); + blah_ = 0; + onChanged(); + return this; + } + + // @@protoc_insertion_point(builder_scope:SecondMsg) + } + + static { + defaultInstance = new SecondMsg(true); + defaultInstance.initFields(); + } + + // @@protoc_insertion_point(class_scope:SecondMsg) +} + diff --git a/spring-web/src/test/java/org/springframework/protobuf/SecondMsgOrBuilder.java b/spring-web/src/test/java/org/springframework/protobuf/SecondMsgOrBuilder.java new file mode 100644 index 0000000000..baafb872dd --- /dev/null +++ b/spring-web/src/test/java/org/springframework/protobuf/SecondMsgOrBuilder.java @@ -0,0 +1,18 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: sample.proto + +package org.springframework.protobuf; + +public interface SecondMsgOrBuilder + extends com.google.protobuf.MessageOrBuilder { + + // optional int32 blah = 1; + /** + * optional int32 blah = 1; + */ + boolean hasBlah(); + /** + * optional int32 blah = 1; + */ + int getBlah(); +} diff --git a/spring-web/src/test/proto/sample.proto b/spring-web/src/test/proto/sample.proto new file mode 100644 index 0000000000..812b4c2e4d --- /dev/null +++ b/spring-web/src/test/proto/sample.proto @@ -0,0 +1,12 @@ +option java_package = "org.springframework.protobuf"; +option java_outer_classname = "OuterSample"; +option java_multiple_files = true; + +message Msg { + optional string foo = 1; + optional SecondMsg blah = 2; +} + +message SecondMsg { + optional int32 blah = 1; +} -- GitLab