This is an automated email from the ASF dual-hosted git repository.

iluo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-dubbo.git


The following commit(s) were added to refs/heads/master by this push:
     new a7f56a3  [DUBBO-4010] TypeDefinitonBuilder support google protobuf 
entity build # (#4011)
a7f56a3 is described below

commit a7f56a36be1408602b4b31baaf7947ee9bba5985
Author: violin <[email protected]>
AuthorDate: Wed May 22 14:45:37 2019 +0800

    [DUBBO-4010] TypeDefinitonBuilder support google protobuf entity build # 
(#4011)
    
    * add protobuf typeDefinitionBuilder
    
    * fix pull request comment
    add test case to test NestPbType
---
 .../dubbo-metadata-definition/pom.xml              |   1 -
 .../metadata/definition/TypeDefinitionBuilder.java |  21 +-
 .../definition/builder/CollectionTypeBuilder.java  |   9 +-
 .../definition/builder/MapTypeBuilder.java         |   9 +-
 .../metadata/definition/builder/TypeBuilder.java   |   2 +
 ...e.dubbo.metadata.definition.builder.TypeBuilder |   4 +
 .../dubbo-serialization-protobuf-json/pom.xml      |   5 +
 .../protobuf/support/ProtobufTypeBuilder.java      | 308 +++++++++++++++++++++
 ...e.dubbo.metadata.definition.builder.TypeBuilder |   1 +
 .../protobuf/support/ProtobufTypeBuilderTest.java  |  69 +++++
 .../protobuf/support/model/ServiceInterface.java   |  24 +-
 11 files changed, 408 insertions(+), 45 deletions(-)

diff --git a/dubbo-metadata-report/dubbo-metadata-definition/pom.xml 
b/dubbo-metadata-report/dubbo-metadata-definition/pom.xml
index 6e9a58f..093c7e2 100644
--- a/dubbo-metadata-report/dubbo-metadata-definition/pom.xml
+++ b/dubbo-metadata-report/dubbo-metadata-definition/pom.xml
@@ -21,7 +21,6 @@
         <version>${revision}</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
-
     <artifactId>dubbo-metadata-definition</artifactId>
 
 
diff --git 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
 
b/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
index 53e8c88..19e5f8a 100755
--- 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/TypeDefinitionBuilder.java
@@ -16,17 +16,13 @@
  */
 package org.apache.dubbo.metadata.definition;
 
-import org.apache.dubbo.metadata.definition.builder.ArrayTypeBuilder;
-import org.apache.dubbo.metadata.definition.builder.CollectionTypeBuilder;
+import org.apache.dubbo.common.extension.ExtensionLoader;
 import org.apache.dubbo.metadata.definition.builder.DefaultTypeBuilder;
-import org.apache.dubbo.metadata.definition.builder.EnumTypeBuilder;
-import org.apache.dubbo.metadata.definition.builder.MapTypeBuilder;
 import org.apache.dubbo.metadata.definition.builder.TypeBuilder;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 
 import java.lang.reflect.Type;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -35,13 +31,16 @@ import java.util.Map;
  * 2015/1/27.
  */
 public class TypeDefinitionBuilder {
+    private static final List<TypeBuilder> BUILDERS;
 
-    private static final TypeBuilder ARRAY_BUILDER = new ArrayTypeBuilder();
-    private static final TypeBuilder COLLECTION_BUILDER = new 
CollectionTypeBuilder();
-    private static final TypeBuilder MAP_BUILDER = new MapTypeBuilder();
-    private static final TypeBuilder ENUM_BUILDER = new EnumTypeBuilder();
-
-    private static final List<TypeBuilder> BUILDERS = 
Arrays.asList(ARRAY_BUILDER, COLLECTION_BUILDER, MAP_BUILDER, ENUM_BUILDER);
+    static{
+        List<TypeBuilder> builders = new ArrayList<>();
+        ExtensionLoader<TypeBuilder> extensionLoader = 
ExtensionLoader.getExtensionLoader(TypeBuilder.class);
+        for(String extensionName : extensionLoader.getSupportedExtensions()){
+            builders.add(extensionLoader.getExtension(extensionName));
+        }
+        BUILDERS = builders;
+    }
 
     public static TypeDefinition build(Type type, Class<?> clazz, 
Map<Class<?>, TypeDefinition> typeCache) {
         TypeBuilder builder = getGenericTypeBuilder(type, clazz);
diff --git 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
 
b/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
index de7dc73..1e74684 100755
--- 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/CollectionTypeBuilder.java
@@ -49,7 +49,8 @@ public class CollectionTypeBuilder implements TypeBuilder {
         Type[] actualTypeArgs = parameterizedType.getActualTypeArguments();
         if (actualTypeArgs == null || actualTypeArgs.length != 1) {
             throw new IllegalArgumentException(MessageFormat.format(
-                    "[ServiceDefinitionBuilder] Collection type [{0}] with 
unexpected amount of arguments [{1}]." + Arrays.toString(actualTypeArgs),
+                    "[ServiceDefinitionBuilder] Collection type [{0}] with 
unexpected amount of arguments [{1}]."
+                            + Arrays.toString(actualTypeArgs),
                     type, actualTypeArgs));
         }
 
@@ -60,11 +61,7 @@ public class CollectionTypeBuilder implements TypeBuilder {
             TypeDefinitionBuilder.build(actualType, rawType, typeCache);
         } else if (actualType instanceof Class<?>) {
             Class<?> actualClass = (Class<?>) actualType;
-            if (actualClass.isArray() || actualClass.isEnum()) {
-                TypeDefinitionBuilder.build(null, actualClass, typeCache);
-            } else {
-                DefaultTypeBuilder.build(actualClass, typeCache);
-            }
+            TypeDefinitionBuilder.build(null, actualClass, typeCache);
         }
 
         return new TypeDefinition(type.toString());
diff --git 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
 
b/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
index 905ad07..a207082 100755
--- 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/MapTypeBuilder.java
@@ -48,7 +48,8 @@ public class MapTypeBuilder implements TypeBuilder {
         Type[] actualTypeArgs = parameterizedType.getActualTypeArguments();
         if (actualTypeArgs == null || actualTypeArgs.length != 2) {
             throw new IllegalArgumentException(MessageFormat.format(
-                    "[ServiceDefinitionBuilder] Map type [{0}] with unexpected 
amount of arguments [{1}]." + Arrays.toString(actualTypeArgs), type, 
actualTypeArgs));
+                    "[ServiceDefinitionBuilder] Map type [{0}] with unexpected 
amount of arguments [{1}]."
+                            + Arrays.toString(actualTypeArgs), type, 
actualTypeArgs));
         }
 
         for (Type actualType : actualTypeArgs) {
@@ -58,11 +59,7 @@ public class MapTypeBuilder implements TypeBuilder {
                 TypeDefinitionBuilder.build(actualType, rawType, typeCache);
             } else if (actualType instanceof Class<?>) {
                 Class<?> actualClass = (Class<?>) actualType;
-                if (actualClass.isArray() || actualClass.isEnum()) {
-                    TypeDefinitionBuilder.build(null, actualClass, typeCache);
-                } else {
-                    DefaultTypeBuilder.build(actualClass, typeCache);
-                }
+                TypeDefinitionBuilder.build(null, actualClass, typeCache);
             }
         }
 
diff --git 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
 
b/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
index ef79a3f..d7022bd 100755
--- 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
+++ 
b/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
@@ -16,6 +16,7 @@
  */
 package org.apache.dubbo.metadata.definition.builder;
 
+import org.apache.dubbo.common.extension.SPI;
 import org.apache.dubbo.metadata.definition.model.TypeDefinition;
 
 import java.lang.reflect.Type;
@@ -24,6 +25,7 @@ import java.util.Map;
 /**
  * 2015/1/27.
  */
+@SPI
 public interface TypeBuilder {
 
     /**
diff --git 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
 
b/dubbo-metadata-report/dubbo-metadata-definition/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
new file mode 100644
index 0000000..a0d82d2
--- /dev/null
+++ 
b/dubbo-metadata-report/dubbo-metadata-definition/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
@@ -0,0 +1,4 @@
+array=org.apache.dubbo.metadata.definition.builder.ArrayTypeBuilder
+collection=org.apache.dubbo.metadata.definition.builder.CollectionTypeBuilder
+map=org.apache.dubbo.metadata.definition.builder.MapTypeBuilder
+enum=org.apache.dubbo.metadata.definition.builder.EnumTypeBuilder
\ No newline at end of file
diff --git a/dubbo-serialization/dubbo-serialization-protobuf-json/pom.xml 
b/dubbo-serialization/dubbo-serialization-protobuf-json/pom.xml
index 6580e87..75b290b 100644
--- a/dubbo-serialization/dubbo-serialization-protobuf-json/pom.xml
+++ b/dubbo-serialization/dubbo-serialization-protobuf-json/pom.xml
@@ -42,5 +42,10 @@ limitations under the License.
             <groupId>com.google.protobuf</groupId>
             <artifactId>protobuf-java-util</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.apache.dubbo</groupId>
+            <artifactId>dubbo-metadata-definition</artifactId>
+            <version>${project.parent.version}</version>
+        </dependency>
     </dependencies>
 </project>
\ No newline at end of file
diff --git 
a/dubbo-serialization/dubbo-serialization-protobuf-json/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufTypeBuilder.java
 
b/dubbo-serialization/dubbo-serialization-protobuf-json/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufTypeBuilder.java
new file mode 100644
index 0000000..75fcc5f
--- /dev/null
+++ 
b/dubbo-serialization/dubbo-serialization-protobuf-json/src/main/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufTypeBuilder.java
@@ -0,0 +1,308 @@
+/*
+ * 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.dubbo.common.serialize.protobuf.support;
+
+import org.apache.dubbo.common.logger.Logger;
+import org.apache.dubbo.common.logger.LoggerFactory;
+import org.apache.dubbo.metadata.definition.TypeDefinitionBuilder;
+import org.apache.dubbo.metadata.definition.builder.TypeBuilder;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import com.google.protobuf.ByteString;
+import com.google.protobuf.Descriptors;
+import com.google.protobuf.GeneratedMessageV3;
+import com.google.protobuf.ProtocolStringList;
+import com.google.protobuf.UnknownFieldSet;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ProtobufTypeBuilder implements TypeBuilder {
+    private final Logger logger = LoggerFactory.getLogger(getClass());
+    private static final Pattern MAP_PATTERN = 
Pattern.compile("^java\\.util\\.Map<(\\S+), (\\S+)>$");
+    private static final Pattern LIST_PATTERN = 
Pattern.compile("^java\\.util\\.List<(\\S+)>$");
+    private static final List<String> list = null;
+    /**
+     * provide a List<String> type for 
TypeDefinitionBuilder.build(type,class,cache)
+     * "repeated string" transform to ProtocolStringList, should be build as 
List<String> type.
+     */
+    private static Type STRING_LIST_TYPE;
+
+    static {
+        try {
+            STRING_LIST_TYPE = 
ProtobufTypeBuilder.class.getDeclaredField("list").getGenericType();
+        } catch (NoSuchFieldException e) {
+            // do nothing
+        }
+    }
+
+    @Override
+    public boolean accept(Type type, Class<?> clazz) {
+        if (clazz == null) {
+            return false;
+        }
+
+        return GeneratedMessageV3.class.isAssignableFrom(clazz);
+    }
+
+    @Override
+    public TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, 
TypeDefinition> typeCache) {
+        TypeDefinition typeDefinition = new TypeDefinition(clazz.getName());
+        try {
+            GeneratedMessageV3.Builder builder = getMessageBuilder(clazz);
+            typeDefinition = buildProtobufTypeDefinition(clazz, builder, 
typeCache);
+        } catch (Exception e) {
+            logger.info("TypeDefinition build failed.", e);
+        }
+
+        return typeDefinition;
+    }
+
+    private GeneratedMessageV3.Builder getMessageBuilder(Class<?> requestType) 
throws Exception {
+        Method method = requestType.getMethod("newBuilder");
+        return (GeneratedMessageV3.Builder) method.invoke(null, null);
+    }
+
+    private TypeDefinition buildProtobufTypeDefinition(Class<?> clazz, 
GeneratedMessageV3.Builder builder, Map<Class<?>, TypeDefinition> typeCache) {
+        TypeDefinition typeDefinition = new TypeDefinition(clazz.getName());
+        if (builder == null) {
+            return typeDefinition;
+        }
+
+        Map<String, TypeDefinition> properties = new HashMap<>();
+        Method[] methods = builder.getClass().getDeclaredMethods();
+        for (Method method : methods) {
+            String methodName = method.getName();
+
+            if (isSimplePropertySettingMethod(method)) {
+                // property of custom type or primitive type
+                properties.put(generateSimpleFiledName(methodName), 
TypeDefinitionBuilder.build(method.getGenericParameterTypes()[0], 
method.getParameterTypes()[0], typeCache));
+            } else if (isMapPropertySettingMethod(method)) {
+                // property of map
+                Type type = method.getGenericParameterTypes()[0];
+                String fieldName = generateMapFieldName(methodName);
+                validateMapType(fieldName, type.toString());
+                properties.put(fieldName, TypeDefinitionBuilder.build(type, 
method.getParameterTypes()[0], typeCache));
+            } else if (isListPropertySettingMethod(method)) {
+                // property of list
+                Type type = method.getGenericReturnType();
+                String fieldName = generateListFieldName(methodName);
+                validateListType(fieldName, type.toString());
+                TypeDefinition td;
+                if 
(ProtocolStringList.class.isAssignableFrom(method.getReturnType())) {
+                    // property defined as "repeated string" transform to 
ProtocolStringList,
+                    // should be build as List<String>.
+                    td = TypeDefinitionBuilder.build(STRING_LIST_TYPE, 
List.class, typeCache);
+                } else {
+                    td = TypeDefinitionBuilder.build(type, 
method.getReturnType(), typeCache);
+                }
+                properties.put(fieldName, td);
+            }
+        }
+        typeDefinition.setProperties(properties);
+        typeCache.put(clazz, typeDefinition);
+        return typeDefinition;
+    }
+
+    /**
+     * 1. Unsupported List with value type is Bytes <br/>
+     * Bytes is a primitive type in Proto, transform to ByteString.class in 
java<br/>
+     *
+     * @param fieldName
+     * @param typeName
+     * @return
+     */
+    private void validateListType(String fieldName, String typeName) {
+        Matcher matcher = LIST_PATTERN.matcher(typeName);
+        if (!matcher.matches()) {
+            throw new IllegalArgumentException("List protobuf property " + 
fieldName + "of Type " +
+                    typeName + " can't be parsed.The type name should mathch[" 
+ LIST_PATTERN.toString() + "].");
+        }
+
+        if (ByteString.class.getName().equals(matcher.group(1))) {
+            throw new IllegalArgumentException("List protobuf property " + 
fieldName + "of Type " +
+                    typeName + " can't be parsed.List of ByteString is not 
supported.");
+        }
+    }
+
+    /**
+     * 1. Unsupported Map with value type is Bytes <br/>
+     * 2. Unsupported Map with key type is not String <br/>
+     * Bytes is a primitive type in Proto, transform to ByteString.class in 
java<br/>
+     *
+     * @param fieldName
+     * @param typeName
+     * @return
+     */
+    private void validateMapType(String fieldName, String typeName) {
+        Matcher matcher = MAP_PATTERN.matcher(typeName);
+        if (!matcher.matches()) {
+            throw new IllegalArgumentException("Map protobuf property " + 
fieldName + "of Type " +
+                    typeName + " can't be parsed.The type name should mathch[" 
+ MAP_PATTERN.toString() + "].");
+        }
+
+        if (!String.class.getName().equals(matcher.group(1)) || 
ByteString.class.getName().equals(matcher.group(2))) {
+            throw new IllegalArgumentException("Map protobuf property " + 
fieldName + "of Type " +
+                    typeName + " can't be parsed.Map with unString key or 
ByteString value is not supported.");
+        }
+    }
+
+    /**
+     * get unCollection unMap property name from setting method.<br/>
+     * ex:setXXX();<br/>
+     *
+     * @param methodName
+     * @return
+     */
+    private String generateSimpleFiledName(String methodName) {
+        return toCamelCase(methodName.substring(3));
+    }
+
+    /**
+     * get map property name from setting method.<br/>
+     * ex: putAllXXX();<br/>
+     *
+     * @param methodName
+     * @return
+     */
+    private String generateMapFieldName(String methodName) {
+        return toCamelCase(methodName.substring(6));
+    }
+
+    /**
+     * get list property name from setting method.<br/>
+     * ex: getXXXList()<br/>
+     *
+     * @param methodName
+     * @return
+     */
+    private String generateListFieldName(String methodName) {
+        return toCamelCase(methodName.substring(3, methodName.length() - 4));
+    }
+
+
+    private String toCamelCase(String nameString) {
+        char[] chars = nameString.toCharArray();
+        chars[0] = Character.toLowerCase(chars[0]);
+        return new String(chars);
+    }
+
+    /**
+     * judge custom type or primitive type property<br/>
+     * 1. proto3 grammar ex: string name = 1 <br/>
+     * 2. proto3 grammar ex: optional string name =1 <br/>
+     * generated setting method setNameValue(String name);
+     *
+     * @param method
+     * @return
+     */
+    private boolean isSimplePropertySettingMethod(Method method) {
+        String methodName = method.getName();
+        Class<?>[] types = method.getParameterTypes();
+
+        if (!methodName.startsWith("set") || types.length != 1) {
+            return false;
+        }
+
+        // filter general setting method
+        // 1. - setUnknownFields( com.google.protobuf.UnknownFieldSet 
unknownFields)
+        // 2. - setField(com.google.protobuf.Descriptors.FieldDescriptor 
field,java.lang.Object value)
+        // 3. - 
setRepeatedField(com.google.protobuf.Descriptors.FieldDescriptor field,int 
index,java.lang.Object value)
+        if (methodName.equals("setField") && 
types[0].equals(Descriptors.FieldDescriptor.class)
+                || methodName.equals("setUnknownFields") && 
types[0].equals(UnknownFieldSet.class)
+                || methodName.equals("setRepeatedField") && 
types[0].equals(Descriptors.FieldDescriptor.class)) {
+            return false;
+        }
+
+        // String property has two setting method.
+        // skip setXXXBytes(com.google.protobuf.ByteString value)
+        // parse setXXX(String string)
+        if (methodName.endsWith("Bytes") && types[0].equals(ByteString.class)) 
{
+            return false;
+        }
+
+        // Protobuf property has two setting method.
+        // skip setXXX(com.google.protobuf.Builder value)
+        // parse setXXX(com.google.protobuf.Message value)
+        if (GeneratedMessageV3.Builder.class.isAssignableFrom(types[0])) {
+            return false;
+        }
+
+        // Enum property has two setting method.
+        // skip setXXX(int value)
+        // parse setXXX(SomeEnum value)
+        if (methodName.endsWith("Value") && types[0] == int.class) {
+            return false;
+        }
+
+        return true;
+    }
+
+
+    /**
+     * judge List property</br>
+     * proto3 grammar ex: repeated string names; </br>
+     * generated setting method:List<String> getNamesList()
+     *
+     * @param method
+     * @return
+     */
+    boolean isListPropertySettingMethod(Method method) {
+        String methodName = method.getName();
+        Class<?> type = method.getReturnType();
+
+
+        if (!methodName.startsWith("get") || !methodName.endsWith("List")) {
+            return false;
+        }
+
+        // skip the setting method with Pb entity builder as parameter
+        if (methodName.endsWith("BuilderList")) {
+            return false;
+        }
+
+        // if field name end with List, should skip
+        if (!List.class.isAssignableFrom(type)) {
+            return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * judge map property</br>
+     * proto3 grammar : map<string,string> card = 1; </br>
+     * generated setting method: putAllCards(java.util.Map<String, string> 
values) </br>
+     *
+     * @param methodTemp
+     * @return
+     */
+    private boolean isMapPropertySettingMethod(Method methodTemp) {
+        String methodName = methodTemp.getName();
+        Class[] parameters = methodTemp.getParameterTypes();
+        if (methodName.startsWith("putAll") && parameters.length == 1 && 
Map.class.isAssignableFrom(parameters[0])) {
+            return true;
+        }
+
+        return false;
+    }
+}
diff --git 
a/dubbo-serialization/dubbo-serialization-protobuf-json/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
 
b/dubbo-serialization/dubbo-serialization-protobuf-json/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
new file mode 100644
index 0000000..97795f2
--- /dev/null
+++ 
b/dubbo-serialization/dubbo-serialization-protobuf-json/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.metadata.definition.builder.TypeBuilder
@@ -0,0 +1 @@
+protobuf=org.apache.dubbo.common.serialize.protobuf.support.ProtobufTypeBuilder
\ No newline at end of file
diff --git 
a/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufTypeBuilderTest.java
 
b/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufTypeBuilderTest.java
new file mode 100644
index 0000000..0d59c08
--- /dev/null
+++ 
b/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protobuf/support/ProtobufTypeBuilderTest.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.dubbo.common.serialize.protobuf.support;
+
+import 
org.apache.dubbo.common.serialize.protobuf.support.model.ServiceInterface;
+import org.apache.dubbo.metadata.definition.ServiceDefinitionBuilder;
+import org.apache.dubbo.metadata.definition.model.FullServiceDefinition;
+import org.apache.dubbo.metadata.definition.model.MethodDefinition;
+import org.apache.dubbo.metadata.definition.model.TypeDefinition;
+
+import org.junit.jupiter.api.Test;
+
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
+
+
+public class ProtobufTypeBuilderTest {
+    @Test
+    public void testProtobufBuilder() {
+        // TEST Pb Service metaData builder
+        FullServiceDefinition serviceDefinition = 
ServiceDefinitionBuilder.buildFullDefinition(ServiceInterface.class);
+        MethodDefinition methodDefinition = 
serviceDefinition.getMethods().get(0);
+        String parameterName = methodDefinition.getParameterTypes()[0];
+        TypeDefinition typeDefinition = null;
+        for (TypeDefinition type : serviceDefinition.getTypes()) {
+            if (parameterName.equals(type.getType())) {
+                typeDefinition = type;
+                break;
+            }
+        }
+        Map<String, TypeDefinition> propertiesMap = 
typeDefinition.getProperties();
+        assertThat(propertiesMap.size(), is(9));
+        assertThat(propertiesMap.containsKey("money"), is(true));
+        assertThat(propertiesMap.get("money").getType(), equalTo("double"));
+        assertThat(propertiesMap.containsKey("cash"), is(true));
+        assertThat(propertiesMap.get("cash").getType(), equalTo("float"));
+        assertThat(propertiesMap.containsKey("age"), is(true));
+        assertThat(propertiesMap.get("age").getType(), equalTo("int"));
+        assertThat(propertiesMap.containsKey("num"), is(true));
+        assertThat(propertiesMap.get("num").getType(), equalTo("long"));
+        assertThat(propertiesMap.containsKey("sex"), is(true));
+        assertThat(propertiesMap.get("sex").getType(), equalTo("boolean"));
+        assertThat(propertiesMap.containsKey("name"), is(true));
+        assertThat(propertiesMap.get("name").getType(), 
equalTo("java.lang.String"));
+        assertThat(propertiesMap.containsKey("msg"), is(true));
+        assertThat(propertiesMap.get("msg").getType(), 
equalTo("com.google.protobuf.ByteString"));
+        assertThat(propertiesMap.containsKey("phone"), is(true));
+        assertThat(propertiesMap.get("phone").getType(), 
equalTo("java.util.List<org.apache.dubbo.common.serialize.protobuf.support.model.GooglePB$PhoneNumber>"));
+        assertThat(propertiesMap.containsKey("doubleMap"), is(true));
+        assertThat(propertiesMap.get("doubleMap").getType(), 
equalTo("java.util.Map<java.lang.String, 
org.apache.dubbo.common.serialize.protobuf.support.model.GooglePB$PhoneNumber>"));
+    }
+}
diff --git 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
 
b/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protobuf/support/model/ServiceInterface.java
old mode 100755
new mode 100644
similarity index 60%
copy from 
dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
copy to 
dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protobuf/support/model/ServiceInterface.java
index ef79a3f..ffdbdd4
--- 
a/dubbo-metadata-report/dubbo-metadata-definition/src/main/java/org/apache/dubbo/metadata/definition/builder/TypeBuilder.java
+++ 
b/dubbo-serialization/dubbo-serialization-test/src/test/java/org/apache/dubbo/common/serialize/protobuf/support/model/ServiceInterface.java
@@ -14,26 +14,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.apache.dubbo.metadata.definition.builder;
-
-import org.apache.dubbo.metadata.definition.model.TypeDefinition;
-
-import java.lang.reflect.Type;
-import java.util.Map;
-
-/**
- * 2015/1/27.
- */
-public interface TypeBuilder {
-
-    /**
-     * Whether the build accept the type or class passed in.
-     */
-    boolean accept(Type type, Class<?> clazz);
-
-    /**
-     * Build type definition with the type or class.
-     */
-    TypeDefinition build(Type type, Class<?> clazz, Map<Class<?>, 
TypeDefinition> typeCache);
+package org.apache.dubbo.common.serialize.protobuf.support.model;
 
+public interface ServiceInterface {
+    GooglePB.PBResponseType sayHello(GooglePB.PBRequestType requestType);
 }

Reply via email to