liubao68 closed pull request #956: [SCB*675] Gen proto from swagger
URL: https://github.com/apache/incubator-servicecomb-java-chassis/pull/956
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/common/common-protobuf/pom.xml b/common/common-protobuf/pom.xml
index aa7036462..6fe465115 100644
--- a/common/common-protobuf/pom.xml
+++ b/common/common-protobuf/pom.xml
@@ -51,5 +51,14 @@
       <artifactId>log4j</artifactId>
       <scope>test</scope>
     </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>swagger-generator-springmvc</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.servicecomb</groupId>
+      <artifactId>foundation-test-scaffolding</artifactId>
+    </dependency>
   </dependencies>
 </project>
diff --git 
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/BodyParameterAdapter.java
 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/BodyParameterAdapter.java
new file mode 100644
index 000000000..cf4865670
--- /dev/null
+++ 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/BodyParameterAdapter.java
@@ -0,0 +1,101 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter;
+
+import java.util.List;
+
+import io.swagger.models.ArrayModel;
+import io.swagger.models.Model;
+import io.swagger.models.ModelImpl;
+import io.swagger.models.RefModel;
+import io.swagger.models.parameters.BodyParameter;
+import io.swagger.models.properties.ObjectProperty;
+import io.swagger.models.properties.Property;
+
+public class BodyParameterAdapter implements SwaggerTypeAdapter {
+  private final Model model;
+
+  public BodyParameterAdapter(BodyParameter parameter) {
+    this.model = parameter.getSchema();
+  }
+
+  @Override
+  public String getRefType() {
+    if (model instanceof RefModel) {
+      return ((RefModel) model).getSimpleRef();
+    }
+
+    return null;
+  }
+
+  @Override
+  public Property getArrayItem() {
+    if (model instanceof ArrayModel) {
+      return ((ArrayModel) model).getItems();
+    }
+
+    return null;
+  }
+
+  @Override
+  public Property getMapItem() {
+    if (model instanceof ModelImpl) {
+      return ((ModelImpl) model).getAdditionalProperties();
+    }
+
+    return null;
+  }
+
+  @Override
+  public List<String> getEnum() {
+    if (model instanceof ModelImpl) {
+      return ((ModelImpl) model).getEnum();
+    }
+
+    return null;
+  }
+
+  @Override
+  public String getType() {
+    if (model instanceof ModelImpl) {
+      return ((ModelImpl) model).getType();
+    }
+
+    return null;
+  }
+
+  @Override
+  public String getFormat() {
+    if (model instanceof ModelImpl) {
+      return ((ModelImpl) model).getFormat();
+    }
+
+    return null;
+  }
+
+  @Override
+  public boolean isObject() {
+    if (model instanceof ModelImpl) {
+      ModelImpl modelImpl = (ModelImpl) model;
+      return (ObjectProperty.TYPE.equals(modelImpl.getType())
+          && modelImpl.getProperties() == null
+          && modelImpl.getName() == null);
+    }
+
+    return false;
+  }
+}
diff --git 
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/PropertyAdapter.java
 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/PropertyAdapter.java
new file mode 100644
index 000000000..c23b08f36
--- /dev/null
+++ 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/PropertyAdapter.java
@@ -0,0 +1,85 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter;
+
+import java.util.List;
+
+import io.swagger.models.properties.ArrayProperty;
+import io.swagger.models.properties.MapProperty;
+import io.swagger.models.properties.ObjectProperty;
+import io.swagger.models.properties.Property;
+import io.swagger.models.properties.RefProperty;
+import io.swagger.models.properties.StringProperty;
+
+public class PropertyAdapter implements SwaggerTypeAdapter {
+  private final Property property;
+
+  public PropertyAdapter(Property property) {
+    this.property = property;
+  }
+
+  @Override
+  public String getRefType() {
+    if (property instanceof RefProperty) {
+      return ((RefProperty) property).getSimpleRef();
+    }
+
+    return null;
+  }
+
+  @Override
+  public Property getArrayItem() {
+    if (property instanceof ArrayProperty) {
+      return ((ArrayProperty) property).getItems();
+    }
+
+    return null;
+  }
+
+  @Override
+  public Property getMapItem() {
+    if (property instanceof MapProperty) {
+      return ((MapProperty) property).getAdditionalProperties();
+    }
+
+    return null;
+  }
+
+  @Override
+  public List<String> getEnum() {
+    if (property instanceof StringProperty) {
+      return ((StringProperty) property).getEnum();
+    }
+
+    return null;
+  }
+
+  @Override
+  public String getType() {
+    return property.getType();
+  }
+
+  @Override
+  public String getFormat() {
+    return property.getFormat();
+  }
+
+  @Override
+  public boolean isObject() {
+    return property instanceof ObjectProperty;
+  }
+}
diff --git 
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/ProtoMethod.java
 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/ProtoMethod.java
new file mode 100644
index 000000000..4ae87ae7e
--- /dev/null
+++ 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/ProtoMethod.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.servicecomb.swagger.invocation.context.HttpStatus;
+
+import com.fasterxml.jackson.annotation.JsonProperty;
+
+public class ProtoMethod {
+  private String argTypeName;
+
+  private boolean argWrapped;
+
+  @JsonProperty
+  // key is status
+  private Map<Integer, ProtoResponse> responses = new HashMap<>();
+
+  private ProtoResponse defaultResponse;
+
+  public String getArgTypeName() {
+    return argTypeName;
+  }
+
+  public void setArgTypeName(String argTypeName) {
+    this.argTypeName = argTypeName;
+  }
+
+  public boolean isArgWrapped() {
+    return argWrapped;
+  }
+
+  public void setArgWrapped(boolean argWrapped) {
+    this.argWrapped = argWrapped;
+  }
+
+  public void addResponse(String status, ProtoResponse response) {
+    if (status.equals("default")) {
+      defaultResponse = response;
+      return;
+    }
+
+    int statusCode = Integer.parseInt(status);
+    responses.put(statusCode, response);
+
+    if (defaultResponse == null && statusCode == Status.OK.getStatusCode()) {
+      defaultResponse = response;
+    }
+  }
+
+  public ProtoResponse findResponse(int statusCode) {
+    ProtoResponse response = responses.get(statusCode);
+    if (response != null) {
+      return response;
+    }
+
+    if (HttpStatus.isSuccess(statusCode)) {
+      return responses.get(Status.OK.getStatusCode());
+    }
+
+    return defaultResponse;
+  }
+}
diff --git 
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/ProtoResponse.java
 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/ProtoResponse.java
new file mode 100644
index 000000000..feaa4065f
--- /dev/null
+++ 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/ProtoResponse.java
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter;
+
+public class ProtoResponse {
+  private String typeName;
+
+  private boolean wrapped;
+
+  public String getTypeName() {
+    return typeName;
+  }
+
+  public void setTypeName(String typeName) {
+    this.typeName = typeName;
+  }
+
+  public boolean isWrapped() {
+    return wrapped;
+  }
+
+  public void setWrapped(boolean wrapped) {
+    this.wrapped = wrapped;
+  }
+}
diff --git 
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SerializableParameterAdapter.java
 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SerializableParameterAdapter.java
new file mode 100644
index 000000000..205afa794
--- /dev/null
+++ 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SerializableParameterAdapter.java
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter;
+
+import java.util.List;
+
+import io.swagger.models.parameters.SerializableParameter;
+import io.swagger.models.properties.Property;
+
+public class SerializableParameterAdapter implements SwaggerTypeAdapter {
+  private final SerializableParameter parameter;
+
+  public SerializableParameterAdapter(SerializableParameter parameter) {
+    this.parameter = parameter;
+  }
+
+  @Override
+  public String getRefType() {
+    return null;
+  }
+
+  @Override
+  public Property getArrayItem() {
+    if ("array".equals(parameter.getType())) {
+      return parameter.getItems();
+    }
+    
+    return null;
+  }
+
+  @Override
+  public Property getMapItem() {
+    return null;
+  }
+
+  @Override
+  public List<String> getEnum() {
+    return parameter.getEnum();
+  }
+
+  @Override
+  public String getType() {
+    return parameter.getType();
+  }
+
+  @Override
+  public String getFormat() {
+    return parameter.getFormat();
+  }
+
+  @Override
+  public boolean isObject() {
+    return false;
+  }
+}
diff --git 
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java
 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java
new file mode 100644
index 000000000..cd8942a9f
--- /dev/null
+++ 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerToProtoGenerator.java
@@ -0,0 +1,317 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter;
+
+import static 
org.apache.servicecomb.foundation.common.utils.StringBuilderUtils.appendLine;
+
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+import javax.ws.rs.core.Response.Status;
+
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
+import org.apache.servicecomb.foundation.protobuf.internal.parser.ProtoParser;
+
+import com.google.common.hash.Hashing;
+
+import io.protostuff.compiler.model.Message;
+import io.protostuff.compiler.model.Proto;
+import io.swagger.models.Model;
+import io.swagger.models.ModelImpl;
+import io.swagger.models.Operation;
+import io.swagger.models.Path;
+import io.swagger.models.Response;
+import io.swagger.models.Swagger;
+import io.swagger.models.parameters.Parameter;
+import io.swagger.models.properties.Property;
+import io.vertx.core.json.Json;
+
+public class SwaggerToProtoGenerator {
+  private final String protoPackage;
+
+  private final Swagger swagger;
+
+  private final StringBuilder msgStringBuilder = new StringBuilder();
+
+  private final StringBuilder serviceBuilder = new StringBuilder();
+
+  private final Set<String> imports = new HashSet<>();
+
+  private final Set<String> messages = new HashSet<>();
+
+  private final List<Runnable> pending = new ArrayList<>();
+
+  // not java package
+  // better to be: app_${app}.mid_{microservice}.sid_{schemaId}
+  public SwaggerToProtoGenerator(String protoPackage, Swagger swagger) {
+    this.protoPackage = protoPackage;
+    this.swagger = swagger;
+  }
+
+  public Proto convert() {
+    convertDefinitions();
+    convertOperations();
+    for (Runnable runnable : pending) {
+      runnable.run();
+    }
+
+    return createProto();
+  }
+
+  private void convertDefinitions() {
+    if (swagger.getDefinitions() == null) {
+      return;
+    }
+
+    for (Entry<String, Model> entry : swagger.getDefinitions().entrySet()) {
+      convertDefinition(entry.getKey(), (ModelImpl) entry.getValue());
+    }
+  }
+
+  private void convertDefinition(String modelName, ModelImpl model) {
+    Map<String, Property> properties = model.getProperties();
+    if (properties == null) {
+      // it's a empty message
+      properties = Collections.emptyMap();
+    }
+
+    // complex
+    messages.add(modelName);
+    appendLine(msgStringBuilder, "message %s {", modelName);
+    int tag = 1;
+    for (Entry<String, Property> entry : properties.entrySet()) {
+      Property property = entry.getValue();
+      String propertyType = convertSwaggerType(property);
+
+      appendLine(msgStringBuilder, "  %s %s = %d;", propertyType, 
entry.getKey(), tag);
+      tag++;
+    }
+    appendLine(msgStringBuilder, "}");
+  }
+
+  private void addImports(Proto proto) {
+    imports.add(proto.getFilename());
+    for (Message message : proto.getMessages()) {
+      messages.add(message.getCanonicalName());
+    }
+  }
+
+  private String convertSwaggerType(Object swaggerType) {
+    if (swaggerType == null) {
+      // void
+      addImports(ProtoConst.EMPTY_PROTO);
+      return ProtoConst.EMPTY.getCanonicalName();
+    }
+
+    SwaggerTypeAdapter adapter = SwaggerTypeAdapter.create(swaggerType);
+    String type = tryFindEnumType(adapter.getEnum());
+    if (type != null) {
+      return type;
+    }
+
+    type = findBaseType(adapter.getType(), adapter.getFormat());
+    if (type != null) {
+      return type;
+    }
+
+    type = adapter.getRefType();
+    if (type != null) {
+      return type;
+    }
+
+    Property property = adapter.getArrayItem();
+    if (property != null) {
+      return "repeated " + convertSwaggerType(property);
+    }
+
+    property = adapter.getMapItem();
+    if (property != null) {
+      return String.format("map<string, %s>", convertSwaggerType(property));
+    }
+
+    if (adapter.isObject()) {
+      addImports(ProtoConst.ANY_PROTO);
+      return ProtoConst.ANY.getCanonicalName();
+    }
+
+    throw new IllegalStateException(String
+        .format("not support swagger type, class=%s, content=%s.", 
swaggerType.getClass().getName(),
+            Json.encode(swaggerType)));
+  }
+
+  private String tryFindEnumType(List<String> enums) {
+    if (enums != null && !enums.isEmpty()) {
+      String strEnums = enums.toString();
+      String enumName = "Enum_" + Hashing.sha256().hashString(strEnums, 
StandardCharsets.UTF_8).toString();
+      pending.add(() -> createEnum(enumName, enums));
+      return enumName;
+    }
+    return null;
+  }
+
+  private void createEnum(String enumName, List<String> enums) {
+    if (!messages.add(enumName)) {
+      // already created
+      return;
+    }
+
+    appendLine(msgStringBuilder, "enum %s {", enumName);
+    for (int idx = 0; idx < enums.size(); idx++) {
+      appendLine(msgStringBuilder, "  %s =%d;", enums.get(idx), idx);
+    }
+    appendLine(msgStringBuilder, "}");
+  }
+
+  private String findBaseType(String swaggerType, String swaggerFmt) {
+    String key = swaggerType + ":" + swaggerFmt;
+    switch (key) {
+      case "boolean:null":
+        return "bool";
+      // there is no int8/int16 in protobuf
+      case "integer:null":
+        return "int64";
+      case "integer:int8":
+      case "integer:int16":
+      case "integer:int32":
+        return "int32";
+      case "integer:int64":
+        return "int64";
+      case "number:null":
+        return "double";
+      case "number:float":
+        return "float";
+      case "number:double":
+        return "double";
+      case "string:null":
+        return "string";
+      case "string:byte":
+        return "bytes";
+      case "string:date": // LocalDate
+      case "string:date-time": // Date
+        return "int64";
+      case "file:null":
+        throw new IllegalStateException("not support swagger type: " + 
swaggerType);
+    }
+    return null;
+  }
+
+  private void convertOperations() {
+    Map<String, Path> paths = swagger.getPaths();
+    if (paths == null || paths.isEmpty()) {
+      return;
+    }
+
+    appendLine(serviceBuilder, "service MainService {");
+    for (Path path : paths.values()) {
+      for (Operation operation : path.getOperationMap().values()) {
+        convertOpeation(operation);
+      }
+    }
+    serviceBuilder.setLength(serviceBuilder.length() - 1);
+    appendLine(serviceBuilder, "}");
+  }
+
+  private void convertOpeation(Operation operation) {
+    ProtoMethod protoMethod = new ProtoMethod();
+    fillRequestType(operation, protoMethod);
+    fillResponseType(operation, protoMethod);
+
+    appendLine(serviceBuilder, "  //%s%s", ProtoConst.OP_HINT, 
Json.encode(protoMethod));
+    appendLine(serviceBuilder, "  rpc %s (%s) returns (%s);\n", 
operation.getOperationId(),
+        protoMethod.getArgTypeName(),
+        protoMethod.findResponse(Status.OK.getStatusCode()).getTypeName());
+  }
+
+  private void fillRequestType(Operation operation, ProtoMethod protoMethod) {
+    List<Parameter> parameters = operation.getParameters();
+    if (parameters.isEmpty()) {
+      addImports(ProtoConst.EMPTY_PROTO);
+      protoMethod.setArgTypeName(ProtoConst.EMPTY.getCanonicalName());
+      return;
+    }
+
+    if (parameters.size() == 1) {
+      String type = convertSwaggerType(parameters.get(0));
+      if (messages.contains(type)) {
+        protoMethod.setArgTypeName(type);
+        return;
+      }
+    }
+
+    String wrapName = operation.getOperationId() + "RequestWrap";
+    createWrapArgs(wrapName, parameters);
+
+    protoMethod.setArgWrapped(true);
+    protoMethod.setArgTypeName(wrapName);
+  }
+
+  private void fillResponseType(Operation operation, ProtoMethod protoMethod) {
+    for (Entry<String, Response> entry : operation.getResponses().entrySet()) {
+      String type = convertSwaggerType(entry.getValue().getSchema());
+
+      ProtoResponse protoResponse = new ProtoResponse();
+      protoResponse.setWrapped(!messages.contains(type));
+      protoResponse.setTypeName(type);
+
+      if (protoResponse.isWrapped()) {
+        String wrapName = operation.getOperationId() + "ResponseWrap" + 
entry.getKey();
+        appendLine(msgStringBuilder, "message %s {", wrapName);
+        appendLine(msgStringBuilder, "  %s response = 1;", type);
+        appendLine(msgStringBuilder, "}");
+
+        protoResponse.setTypeName(wrapName);
+      }
+      protoMethod.addResponse(entry.getKey(), protoResponse);
+    }
+  }
+
+  private void createWrapArgs(String wrapName, List<Parameter> parameters) {
+    appendLine(msgStringBuilder, "message %s {", wrapName);
+
+    int idx = 1;
+    for (Parameter parameter : parameters) {
+      String type = convertSwaggerType(parameter);
+      appendLine(msgStringBuilder, "  %s %s = %d;", type, parameter.getName(), 
idx);
+      idx++;
+    }
+
+    appendLine(msgStringBuilder, "}");
+  }
+
+  protected Proto createProto() {
+    StringBuilder sb = new StringBuilder();
+    appendLine(sb, "syntax = \"proto3\";");
+    for (String importMsg : imports) {
+      appendLine(sb, "import \"%s\";", importMsg);
+    }
+    if (StringUtils.isNotEmpty(protoPackage)) {
+      sb.append("package ").append(protoPackage).append(";\n");
+    }
+    sb.append(msgStringBuilder);
+    sb.append(serviceBuilder);
+
+    ProtoParser protoParser = new ProtoParser();
+    return protoParser.parseFromContent(sb.toString());
+  }
+}
diff --git 
a/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerTypeAdapter.java
 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerTypeAdapter.java
new file mode 100644
index 000000000..235ebe89f
--- /dev/null
+++ 
b/common/common-protobuf/src/main/java/org/apache/servicecomb/codec/protobuf/internal/converter/SwaggerTypeAdapter.java
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter;
+
+import java.util.List;
+
+import io.swagger.models.parameters.BodyParameter;
+import io.swagger.models.parameters.SerializableParameter;
+import io.swagger.models.properties.Property;
+
+public interface SwaggerTypeAdapter {
+  static SwaggerTypeAdapter create(Object swaggerType) {
+    if (swaggerType instanceof Property) {
+      return new PropertyAdapter((Property) swaggerType);
+    }
+
+    if (swaggerType instanceof SerializableParameter) {
+      return new SerializableParameterAdapter((SerializableParameter) 
swaggerType);
+    }
+
+    if (swaggerType instanceof BodyParameter) {
+      return new BodyParameterAdapter((BodyParameter) swaggerType);
+    }
+
+    throw new IllegalStateException("not support swagger type: " + 
swaggerType.getClass().getName());
+  }
+
+  String getRefType();
+
+  Property getArrayItem();
+
+  Property getMapItem();
+
+  List<String> getEnum();
+
+  String getType();
+
+  String getFormat();
+
+  boolean isObject();
+}
diff --git 
a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSwaggerToProtoGenerator.java
 
b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSwaggerToProtoGenerator.java
new file mode 100644
index 000000000..4b604a4da
--- /dev/null
+++ 
b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/TestSwaggerToProtoGenerator.java
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter;
+
+import 
org.apache.servicecomb.codec.protobuf.internal.converter.model.ProtoSchema;
+import org.apache.servicecomb.foundation.test.scaffolding.model.Color;
+import org.apache.servicecomb.swagger.generator.core.SwaggerGenerator;
+import org.apache.servicecomb.swagger.generator.core.SwaggerGeneratorContext;
+import 
org.apache.servicecomb.swagger.generator.springmvc.SpringmvcSwaggerGeneratorContext;
+import org.junit.Assert;
+import org.junit.Test;
+
+import io.protostuff.compiler.model.Proto;
+import io.swagger.models.Swagger;
+import io.vertx.core.json.Json;
+
+public class TestSwaggerToProtoGenerator {
+  static String protoContent = "syntax = \"proto3\";\n"
+      + "import \"google/protobuf/empty.proto\";\n"
+      + "import \"google/protobuf/any.proto\";\n"
+      + "package a.b;\n"
+      + "\n"
+      + "message Empty {\n"
+      + "}\n"
+      + "\n"
+      + "message User {\n"
+      + "  string name = 1;\n"
+      + "  repeated User friends = 2;\n"
+      + "}\n"
+      + "\n"
+      + "message Ref1 {\n"
+      + "  Ref2 ref = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message Ref2 {\n"
+      + "  Ref1 ref = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message baseRequestWrap {\n"
+      + "  bool boolValue = 1;\n"
+      + "  int32 iValue = 2;\n"
+      + "  int64 lValue = 3;\n"
+      + "  float fValue = 4;\n"
+      + "  double dValue = 5;\n"
+      + "  string sValue = 6;\n"
+      + "  repeated int32 iArray = 7;\n"
+      + "  
Enum_2610aa5dc6cd086cf20168892802c9c765a557f4951557340ad9f0982c53e055 color = 
8;\n"
+      + "  int64 localDate = 9;\n"
+      + "  int64 date = 10;\n"
+      + "  Empty empty = 11;\n"
+      + "}\n"
+      + "\n"
+      + "message baseResponseWrap444 {\n"
+      + "  
Enum_2610aa5dc6cd086cf20168892802c9c765a557f4951557340ad9f0982c53e055 response 
= 1;\n"
+      + "}\n"
+      + "\n"
+      + "message baseResponseWrap200 {\n"
+      + "  int32 response = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message bytesRequestWrap {\n"
+      + "  bytes value = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message bytesResponseWrap200 {\n"
+      + "  bytes response = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message colorBodyRequestWrap {\n"
+      + "  
Enum_2610aa5dc6cd086cf20168892802c9c765a557f4951557340ad9f0982c53e055 color = 
1;\n"
+      + "}\n"
+      + "\n"
+      + "message colorBodyResponseWrap200 {\n"
+      + "  
Enum_2610aa5dc6cd086cf20168892802c9c765a557f4951557340ad9f0982c53e055 response 
= 1;\n"
+      + "}\n"
+      + "\n"
+      + "message listObjRequestWrap {\n"
+      + "  repeated google.protobuf.Any objs = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message listObjResponseWrap200 {\n"
+      + "  repeated google.protobuf.Any response = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message listUserRequestWrap {\n"
+      + "  repeated User users = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message listUserResponseWrap200 {\n"
+      + "  repeated User response = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message mapObjRequestWrap {\n"
+      + "  map<string, google.protobuf.Any> objs = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message mapObjResponseWrap200 {\n"
+      + "  map<string, google.protobuf.Any> response = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message mapUserRequestWrap {\n"
+      + "  map<string, User> users = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message mapUserResponseWrap200 {\n"
+      + "  map<string, User> response = 1;\n"
+      + "}\n"
+      + "\n"
+      + "message userWrapInProtobufRequestWrap {\n"
+      + "  User user = 1;\n"
+      + "  int32 ivalue = 2;\n"
+      + "}\n"
+      + "\n"
+      + "enum 
Enum_2610aa5dc6cd086cf20168892802c9c765a557f4951557340ad9f0982c53e055 {\n"
+      + "  RED = 0;\n"
+      + "  YELLOW = 1;\n"
+      + "  BLUE = 2;\n"
+      + "}\n"
+      + "\n"
+      + "service MainService {\n"
+      + "  
//scb:{\"argTypeName\":\"baseRequestWrap\",\"argWrapped\":true,\"responses\":{\"200\":{\"typeName\":\"baseResponseWrap200\",\"wrapped\":true},\"444\":{\"typeName\":\"baseResponseWrap444\",\"wrapped\":true}}}\n"
+      + "  rpc base (baseRequestWrap) returns (baseResponseWrap200);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"bytesRequestWrap\",\"argWrapped\":true,\"responses\":{\"200\":{\"typeName\":\"bytesResponseWrap200\",\"wrapped\":true}}}\n"
+      + "  rpc bytes (bytesRequestWrap) returns (bytesResponseWrap200);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"colorBodyRequestWrap\",\"argWrapped\":true,\"responses\":{\"200\":{\"typeName\":\"colorBodyResponseWrap200\",\"wrapped\":true}}}\n"
+      + "  rpc colorBody (colorBodyRequestWrap) returns 
(colorBodyResponseWrap200);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"listObjRequestWrap\",\"argWrapped\":true,\"responses\":{\"200\":{\"typeName\":\"listObjResponseWrap200\",\"wrapped\":true}}}\n"
+      + "  rpc listObj (listObjRequestWrap) returns 
(listObjResponseWrap200);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"listUserRequestWrap\",\"argWrapped\":true,\"responses\":{\"200\":{\"typeName\":\"listUserResponseWrap200\",\"wrapped\":true}}}\n"
+      + "  rpc listUser (listUserRequestWrap) returns 
(listUserResponseWrap200);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"mapObjRequestWrap\",\"argWrapped\":true,\"responses\":{\"200\":{\"typeName\":\"mapObjResponseWrap200\",\"wrapped\":true}}}\n"
+      + "  rpc mapObj (mapObjRequestWrap) returns (mapObjResponseWrap200);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"mapUserRequestWrap\",\"argWrapped\":true,\"responses\":{\"200\":{\"typeName\":\"mapUserResponseWrap200\",\"wrapped\":true}}}\n"
+      + "  rpc mapUser (mapUserRequestWrap) returns 
(mapUserResponseWrap200);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"google.protobuf.Empty\",\"argWrapped\":false,\"responses\":{\"200\":{\"typeName\":\"google.protobuf.Empty\",\"wrapped\":false}}}\n"
+      + "  rpc noParamVoid (google.protobuf.Empty) returns 
(google.protobuf.Empty);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"google.protobuf.Any\",\"argWrapped\":false,\"responses\":{\"200\":{\"typeName\":\"google.protobuf.Any\",\"wrapped\":false}}}\n"
+      + "  rpc obj (google.protobuf.Any) returns (google.protobuf.Any);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"Ref1\",\"argWrapped\":false,\"responses\":{\"200\":{\"typeName\":\"Ref2\",\"wrapped\":false}}}\n"
+      + "  rpc ref (Ref1) returns (Ref2);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"User\",\"argWrapped\":false,\"responses\":{\"200\":{\"typeName\":\"User\",\"wrapped\":false}}}\n"
+      + "  rpc user (User) returns (User);\n"
+      + "\n"
+      + "  
//scb:{\"argTypeName\":\"userWrapInProtobufRequestWrap\",\"argWrapped\":true,\"responses\":{\"200\":{\"typeName\":\"User\",\"wrapped\":false}}}\n"
+      + "  rpc userWrapInProtobuf (userWrapInProtobufRequestWrap) returns 
(User);\n"
+      + "}\n";
+
+  @Test
+  public void convert() {
+    SwaggerGeneratorContext context = new SpringmvcSwaggerGeneratorContext();
+    SwaggerGenerator swaggerGenerator = new SwaggerGenerator(context, 
ProtoSchema.class);
+    Swagger swagger = swaggerGenerator.generate();
+
+    SwaggerToProtoGenerator generator = new SwaggerToProtoGenerator("a.b", 
swagger);
+    Proto proto = generator.convert();
+
+    Assert.assertEquals(protoContent, new 
ProtoToStringGenerator(proto).protoToString());
+  }
+
+  public static void main(String[] args) {
+    String json = Json.encode(Color.BLUE);
+    System.out.println(json);
+    System.out.println(Json.decodeValue(json, Color.class));
+    System.out.println(Json.decodeValue("2", Color.class));
+    System.out.println(Json.mapper.convertValue("BLUE", Color.class));
+  }
+}
diff --git 
a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchema.java
 
b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchema.java
new file mode 100644
index 000000000..3b046ec72
--- /dev/null
+++ 
b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/ProtoSchema.java
@@ -0,0 +1,98 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter.model;
+
+
+import java.time.LocalDate;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.foundation.test.scaffolding.model.Color;
+import org.apache.servicecomb.foundation.test.scaffolding.model.Empty;
+import org.apache.servicecomb.foundation.test.scaffolding.model.User;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+import org.springframework.web.bind.annotation.RequestMapping;
+
+import io.swagger.annotations.ApiResponse;
+import io.swagger.annotations.ApiResponses;
+
+@RequestMapping(path = "/")
+public class ProtoSchema {
+  @ApiResponses(value = {@ApiResponse(code = 444, response = Color.class, 
message = "xxx")})
+  @GetMapping(path = "/base")
+  public int base(boolean boolValue, int iValue, long lValue, float fValue, 
double dValue, String sValue, int[] iArray,
+      Color color,
+      LocalDate localDate, Date date, @RequestBody Empty empty) {
+    return 0;
+  }
+
+  @GetMapping(path = "/bytes")
+  public byte[] bytes(@RequestBody byte[] value) {
+    return null;
+  }
+
+  @GetMapping(path = "/colorBody")
+  public Color colorBody(@RequestBody Color color) {
+    return null;
+  }
+
+  @GetMapping(path = "/obj")
+  public Object obj(@RequestBody Object value) {
+    return null;
+  }
+
+  @GetMapping(path = "/user")
+  public User user(@RequestBody User user) {
+    return null;
+  }
+
+  @GetMapping(path = "/userWrapInProtobuf")
+  public User userWrapInProtobuf(@RequestBody User user, int ivalue) {
+    return null;
+  }
+
+  @GetMapping(path = "/listObj")
+  public List<Object> listObj(@RequestBody List<Object> objs) {
+    return null;
+  }
+
+  @GetMapping(path = "/listUser")
+  public List<User> listUser(@RequestBody List<User> users) {
+    return null;
+  }
+
+  @GetMapping(path = "/mapUser")
+  public Map<String, User> mapUser(@RequestBody Map<String, User> users) {
+    return null;
+  }
+
+  @GetMapping(path = "/mapObj")
+  public Map<String, Object> mapObj(@RequestBody Map<String, Object> objs) {
+    return null;
+  }
+
+  @GetMapping(path = "/ref")
+  public Ref2 ref(@RequestBody Ref1 ref) {
+    return null;
+  }
+
+  @GetMapping(path = "/noParamVoid")
+  public void noParamVoid() {
+  }
+}
diff --git 
a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/Ref1.java
 
b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/Ref1.java
new file mode 100644
index 000000000..c637bf59e
--- /dev/null
+++ 
b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/Ref1.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter.model;
+
+public class Ref1 {
+  public Ref2 ref;
+}
diff --git 
a/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/Ref2.java
 
b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/Ref2.java
new file mode 100644
index 000000000..f4b9d9e5a
--- /dev/null
+++ 
b/common/common-protobuf/src/test/java/org/apache/servicecomb/codec/protobuf/internal/converter/model/Ref2.java
@@ -0,0 +1,21 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.apache.servicecomb.codec.protobuf.internal.converter.model;
+
+public class Ref2 {
+  public Ref1 ref;
+}
diff --git 
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoConst.java
 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoConst.java
index c15dbaeb3..53ec0c2f6 100644
--- 
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoConst.java
+++ 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/ProtoConst.java
@@ -18,15 +18,43 @@
 
 import java.util.LinkedHashMap;
 
+import org.apache.servicecomb.foundation.protobuf.internal.parser.ProtoParser;
+
 import com.fasterxml.jackson.databind.JavaType;
 import com.fasterxml.jackson.databind.type.TypeFactory;
 
-public interface ProtoConst {
-  String PACK_SCHEMA = "type.googleapis.com/";
+import io.protostuff.compiler.model.Message;
+import io.protostuff.compiler.model.Proto;
+
+public final class ProtoConst {
+  private ProtoConst() {
+  }
+
+  public static String OP_HINT = " scb:";
+
+  public static String PACK_SCHEMA = "type.googleapis.com/";
+
+  public static String JSON_SCHEMA = "json/";
+
+  public static String JSON_ID_NAME = "@type";
+
+  public static JavaType MAP_TYPE = 
TypeFactory.defaultInstance().constructType(LinkedHashMap.class);
+
+  public static Proto ANY_PROTO;
+
+  public static Message ANY;
+
+  public static Proto EMPTY_PROTO;
+
+  public static Message EMPTY;
 
-  String JSON_SCHEMA = "json/";
+  static {
+    ProtoParser protoParser = new ProtoParser();
 
-  String JSON_ID_NAME = "@type";
+    ANY_PROTO = protoParser.parse("google/protobuf/any.proto");
+    ANY = ANY_PROTO.getMessage("Any");
 
-  JavaType MAP_TYPE = 
TypeFactory.defaultInstance().constructType(LinkedHashMap.class);
+    EMPTY_PROTO = protoParser.parse("google/protobuf/empty.proto");
+    EMPTY = EMPTY_PROTO.getMessage("Empty");
+  }
 }
diff --git 
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
index 49e8c9a51..5e7d50726 100644
--- 
a/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
+++ 
b/foundations/foundation-protobuf/src/main/java/org/apache/servicecomb/foundation/protobuf/internal/schema/SchemaManager.java
@@ -17,6 +17,7 @@
 package org.apache.servicecomb.foundation.protobuf.internal.schema;
 
 import org.apache.servicecomb.foundation.protobuf.ProtoMapper;
+import org.apache.servicecomb.foundation.protobuf.internal.ProtoConst;
 import 
org.apache.servicecomb.foundation.protobuf.internal.schema.scalar.BoolSchema;
 import 
org.apache.servicecomb.foundation.protobuf.internal.schema.scalar.BytesSchema;
 import 
org.apache.servicecomb.foundation.protobuf.internal.schema.scalar.DoubleSchema;
@@ -48,7 +49,7 @@ public SchemaManager(ProtoMapper protoMapper) {
   }
 
   protected boolean isAnyField(Field protoField, boolean repeated) {
-    return !repeated && 
protoField.getType().getCanonicalName().equals("google.protobuf.Any");
+    return !repeated && 
protoField.getType().getCanonicalName().equals(ProtoConst.ANY.getCanonicalName());
   }
 
   protected FieldSchema createScalarField(Field protoField) {


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to