public static Type decode(TypeProto proto) { Stack<Type> stack = new Stack<>(); for (int curIdx = 0; curIdx < proto.getElementsCount(); curIdx++) { TypeElement e = proto.getElements(curIdx); if (e.hasChildNum()) { // if it is a type-parameterized, that is List<Type> childTypes = popMultiItems(stack, e.getChildNum()); if (e.getKind() == ARRAY || e.getKind() == MAP) { stack.push(createTypeParameterizedType(e, childTypes)); } else { // record assertCondition(e.getKind() == RECORD, "This type must be RECORD type."); assertCondition(childTypes.size() == e.getFieldNamesCount(), "The number of Field types and names must be equal."); ImmutableList.Builder<Field> fields = ImmutableList.builder(); for (int i = 0; i < childTypes.size(); i++) { fields.add(new Field(QualifiedIdentifier.fromProto(e.getFieldNames(i)), childTypes.get(i))); } stack.push(Record(fields.build())); } } else { stack.push(createPrimitiveType(e)); } } assertCondition(stack.size() == 1, "Stack size has two or more items."); return stack.pop(); }