Search in sources :

Example 1 with FieldType

use of net.morimekta.providence.model.FieldType in project providence by morimekta.

the class ProgramConverter method convert.

/**
 * Convert document model to declared document.
 *
 * @param path The program file path.
 * @param path Path of the program file to convert.
 * @param program Program model to convert.
 * @return The declared thrift document.
 */
public CProgram convert(String path, ProgramType program) {
    ImmutableList.Builder<PDeclaredDescriptor<?>> declaredTypes = ImmutableList.builder();
    ImmutableList.Builder<CConst> constants = ImmutableList.builder();
    ImmutableMap.Builder<String, String> typedefs = ImmutableMap.builder();
    ImmutableList.Builder<CService> services = ImmutableList.builder();
    RecursiveTypeRegistry registry = programRegistry.registryForPath(path);
    File dir = new File(path).getParentFile();
    if (program.hasIncludes()) {
        for (String include : program.getIncludes()) {
            String includePath = new File(dir, include).getPath();
            registry.registerInclude(ReflectionUtils.programNameFromPath(include), programRegistry.registryForPath(includePath));
        }
    }
    for (Declaration decl : program.getDecl()) {
        switch(decl.unionField()) {
            case DECL_ENUM:
                {
                    EnumType enumType = decl.getDeclEnum();
                    int nextValue = PEnumDescriptor.DEFAULT_FIRST_VALUE;
                    CEnumDescriptor type = new CEnumDescriptor(enumType.getDocumentation(), program.getProgramName(), enumType.getName(), enumType.getAnnotations());
                    List<CEnumValue> values = new ArrayList<>();
                    for (EnumValue value : enumType.getValues()) {
                        int v = value.hasId() ? value.getId() : nextValue;
                        nextValue = v + 1;
                        values.add(new CEnumValue(value.getDocumentation(), value.getId(), value.getName(), type, value.getAnnotations()));
                    }
                    type.setValues(values);
                    declaredTypes.add(type);
                    registry.register(type);
                    break;
                }
            case DECL_STRUCT:
                {
                    MessageType messageType = decl.getDeclStruct();
                    List<CField> fields = new ArrayList<>();
                    if (messageType.hasFields()) {
                        fields.addAll(messageType.getFields().stream().map(field -> makeField(registry, program.getProgramName(), field, messageType.getVariant())).collect(Collectors.toList()));
                    }
                    PMessageDescriptor<?, ?> type;
                    switch(messageType.getVariant()) {
                        case STRUCT:
                            type = new CStructDescriptor(messageType.getDocumentation(), program.getProgramName(), messageType.getName(), fields, messageType.getAnnotations());
                            break;
                        case UNION:
                            type = new CUnionDescriptor(messageType.getDocumentation(), program.getProgramName(), messageType.getName(), fields, messageType.getAnnotations());
                            break;
                        case EXCEPTION:
                            type = new CExceptionDescriptor(messageType.getDocumentation(), program.getProgramName(), messageType.getName(), fields, messageType.getAnnotations());
                            break;
                        default:
                            throw new UnsupportedOperationException("Unhandled message variant " + messageType.getVariant());
                    }
                    declaredTypes.add(type);
                    registry.register(type);
                    break;
                }
            case DECL_CONST:
                {
                    ConstType constant = decl.getDeclConst();
                    constants.add(makeConst(registry, program.getProgramName(), constant));
                    break;
                }
            case DECL_TYPEDEF:
                {
                    typedefs.put(decl.getDeclTypedef().getName(), decl.getDeclTypedef().getType());
                    registry.registerTypedef(decl.getDeclTypedef().getName(), program.getProgramName(), decl.getDeclTypedef().getType());
                    break;
                }
            case DECL_SERVICE:
                {
                    ServiceType serviceType = decl.getDeclService();
                    ImmutableList.Builder<CServiceMethod> methodBuilder = ImmutableList.builder();
                    if (serviceType.hasMethods()) {
                        for (FunctionType sm : serviceType.getMethods()) {
                            List<CField> rqFields = new ArrayList<>();
                            if (sm.numParams() > 0) {
                                for (FieldType field : sm.getParams()) {
                                    rqFields.add(makeField(registry, program.getProgramName(), field, MessageVariant.STRUCT));
                                }
                            }
                            CStructDescriptor request = new CStructDescriptor(null, program.getProgramName(), serviceType.getName() + '.' + sm.getName() + ".request", rqFields, null);
                            CUnionDescriptor response = null;
                            if (!sm.isOneWay()) {
                                List<CField> rsFields = new ArrayList<>();
                                CField success;
                                if (sm.getReturnType() != null) {
                                    PDescriptorProvider type = registry.getProvider(sm.getReturnType(), program.getProgramName(), sm.getAnnotations());
                                    success = new CField(null, 0, PRequirement.OPTIONAL, "success", type, null, null);
                                } else {
                                    success = new CField(null, 0, PRequirement.OPTIONAL, "success", PPrimitive.VOID.provider(), null, null);
                                }
                                rsFields.add(success);
                                if (sm.numExceptions() > 0) {
                                    for (FieldType field : sm.getExceptions()) {
                                        rsFields.add(makeField(registry, program.getProgramName(), field, MessageVariant.UNION));
                                    }
                                }
                                response = new CUnionDescriptor(null, program.getProgramName(), serviceType.getName() + '.' + sm.getName() + ".response", rsFields, null);
                            }
                            CServiceMethod method = new CServiceMethod(sm.getDocumentation(), sm.getName(), sm.isOneWay(), request, response, sm.getAnnotations());
                            methodBuilder.add(method);
                        }
                    // for each method
                    }
                    // if has methods
                    PServiceProvider extendsProvider = null;
                    if (serviceType.hasExtend()) {
                        extendsProvider = registry.getServiceProvider(serviceType.getExtend(), program.getProgramName());
                    }
                    CService service = new CService(serviceType.getDocumentation(), program.getProgramName(), serviceType.getName(), extendsProvider, methodBuilder.build(), serviceType.getAnnotations());
                    services.add(service);
                    registry.registerRecursively(service);
                }
        }
    }
    return new CProgram(path, program.getDocumentation(), program.getProgramName(), program.getNamespaces(), getIncludedProgramNames(program), program.getIncludes(), typedefs.build(), declaredTypes.build(), services.build(), constants.build());
}
Also used : PEnumDescriptor(net.morimekta.providence.descriptor.PEnumDescriptor) PPrimitive(net.morimekta.providence.descriptor.PPrimitive) PDeclaredDescriptor(net.morimekta.providence.descriptor.PDeclaredDescriptor) CEnumValue(net.morimekta.providence.reflect.contained.CEnumValue) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) EnumValue(net.morimekta.providence.model.EnumValue) ReflectionUtils.programNameFromPath(net.morimekta.providence.reflect.util.ReflectionUtils.programNameFromPath) CExceptionDescriptor(net.morimekta.providence.reflect.contained.CExceptionDescriptor) TypeRegistry(net.morimekta.providence.util.TypeRegistry) EnumType(net.morimekta.providence.model.EnumType) CService(net.morimekta.providence.reflect.contained.CService) PServiceProvider(net.morimekta.providence.descriptor.PServiceProvider) CConst(net.morimekta.providence.reflect.contained.CConst) ImmutableMap(com.google.common.collect.ImmutableMap) CProgram(net.morimekta.providence.reflect.contained.CProgram) Declaration(net.morimekta.providence.model.Declaration) Set(java.util.Set) ConstType(net.morimekta.providence.model.ConstType) Collectors(java.util.stream.Collectors) File(java.io.File) PDescriptorProvider(net.morimekta.providence.descriptor.PDescriptorProvider) CUnionDescriptor(net.morimekta.providence.reflect.contained.CUnionDescriptor) MessageVariant(net.morimekta.providence.model.MessageVariant) List(java.util.List) MessageType(net.morimekta.providence.model.MessageType) CEnumDescriptor(net.morimekta.providence.reflect.contained.CEnumDescriptor) CField(net.morimekta.providence.reflect.contained.CField) FunctionType(net.morimekta.providence.model.FunctionType) CStructDescriptor(net.morimekta.providence.reflect.contained.CStructDescriptor) PRequirement(net.morimekta.providence.descriptor.PRequirement) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) ServiceType(net.morimekta.providence.model.ServiceType) FieldType(net.morimekta.providence.model.FieldType) ProgramType(net.morimekta.providence.model.ProgramType) CServiceMethod(net.morimekta.providence.reflect.contained.CServiceMethod) ImmutableList(com.google.common.collect.ImmutableList) CEnumValue(net.morimekta.providence.reflect.contained.CEnumValue) EnumValue(net.morimekta.providence.model.EnumValue) CServiceMethod(net.morimekta.providence.reflect.contained.CServiceMethod) CUnionDescriptor(net.morimekta.providence.reflect.contained.CUnionDescriptor) EnumType(net.morimekta.providence.model.EnumType) ServiceType(net.morimekta.providence.model.ServiceType) CField(net.morimekta.providence.reflect.contained.CField) CConst(net.morimekta.providence.reflect.contained.CConst) CService(net.morimekta.providence.reflect.contained.CService) ArrayList(java.util.ArrayList) ImmutableList(com.google.common.collect.ImmutableList) List(java.util.List) Declaration(net.morimekta.providence.model.Declaration) PMessageDescriptor(net.morimekta.providence.descriptor.PMessageDescriptor) CStructDescriptor(net.morimekta.providence.reflect.contained.CStructDescriptor) ConstType(net.morimekta.providence.model.ConstType) MessageType(net.morimekta.providence.model.MessageType) CEnumValue(net.morimekta.providence.reflect.contained.CEnumValue) FunctionType(net.morimekta.providence.model.FunctionType) ImmutableMap(com.google.common.collect.ImmutableMap) FieldType(net.morimekta.providence.model.FieldType) PServiceProvider(net.morimekta.providence.descriptor.PServiceProvider) CProgram(net.morimekta.providence.reflect.contained.CProgram) PDeclaredDescriptor(net.morimekta.providence.descriptor.PDeclaredDescriptor) CEnumDescriptor(net.morimekta.providence.reflect.contained.CEnumDescriptor) File(java.io.File) PDescriptorProvider(net.morimekta.providence.descriptor.PDescriptorProvider) CExceptionDescriptor(net.morimekta.providence.reflect.contained.CExceptionDescriptor)

Example 2 with FieldType

use of net.morimekta.providence.model.FieldType in project providence by morimekta.

the class ThriftProgramParser method parseMessage.

private MessageType parseMessage(ThriftTokenizer tokenizer, String variant, String comment, Set<String> includedPrograms) throws IOException {
    MessageType._Builder struct = MessageType.builder();
    if (comment != null) {
        struct.setDocumentation(comment);
        comment = null;
    }
    boolean union = variant.equals("union");
    if (!variant.equals("struct")) {
        struct.setVariant(MessageVariant.valueForName(variant.toUpperCase(Locale.US)));
    }
    Token nameToken = tokenizer.expectIdentifier("message name identifier");
    String name = nameToken.asString();
    if (!allowedNameIdentifier(name)) {
        throw tokenizer.failure(nameToken, "Message with reserved name: " + name);
    }
    struct.setName(name);
    int nextAutoFieldKey = -1;
    tokenizer.expectSymbol("message start", Token.kMessageStart);
    Set<String> fieldNames = new HashSet<>();
    Set<String> fieldNameVariants = new HashSet<>();
    Set<Integer> fieldIds = new HashSet<>();
    while (true) {
        Token token = tokenizer.expect("field def or message end");
        if (token.isSymbol(Token.kMessageEnd)) {
            break;
        } else if (token.strEquals(kLineCommentStart)) {
            comment = parseDocLine(tokenizer, comment);
            continue;
        } else if (token.strEquals(kBlockCommentStart)) {
            comment = tokenizer.parseDocBlock();
            continue;
        }
        FieldType._Builder field = FieldType.builder();
        field.setDocumentation(comment);
        comment = null;
        if (token.isInteger()) {
            int fId = (int) token.parseInteger();
            if (fId < 1) {
                throw tokenizer.failure(token, "Negative or 0 field id " + fId + " not allowed.");
            }
            if (fieldIds.contains(fId)) {
                throw tokenizer.failure(token, "Field id " + fId + " already exists in " + struct.build().getName());
            }
            fieldIds.add(fId);
            field.setId(fId);
            tokenizer.expectSymbol("field id sep", Token.kKeyValueSep);
            token = tokenizer.expect("field requirement or type", t -> t.isIdentifier() || t.isQualifiedIdentifier());
        } else {
            if (requireFieldId) {
                throw tokenizer.failure(token, "Missing field ID in strict declaration");
            }
            field.setId(nextAutoFieldKey--);
        }
        if (token.strEquals(kRequired)) {
            if (union) {
                throw tokenizer.failure(token, "Found required field in union");
            }
            field.setRequirement(FieldRequirement.REQUIRED);
            token = tokenizer.expect("field type", t -> t.isIdentifier() || t.isQualifiedIdentifier());
        } else if (token.strEquals(kOptional)) {
            if (!union) {
                // All union fields are optional regardless.
                field.setRequirement(FieldRequirement.OPTIONAL);
            }
            token = tokenizer.expect("field type", t -> t.isIdentifier() || t.isQualifiedIdentifier());
        }
        // Get type.... This is mandatory.
        field.setType(parseType(tokenizer, token, includedPrograms));
        nameToken = tokenizer.expectIdentifier("field name");
        String fName = nameToken.asString();
        if (!allowedNameIdentifier(fName)) {
            throw tokenizer.failure(nameToken, "Field with reserved name: " + fName);
        }
        if (fieldNames.contains(fName)) {
            throw tokenizer.failure(nameToken, "Field %s already exists in %s", fName, struct.build().getName());
        }
        if (fieldNameVariants.contains(Strings.camelCase("get", fName))) {
            throw tokenizer.failure(nameToken, "Field %s has field with conflicting name in %s", fName, struct.build().getName());
        }
        fieldNames.add(fName);
        fieldNameVariants.add(Strings.camelCase("get", fName));
        field.setName(fName);
        token = tokenizer.peek("default sep, annotation, field def or message end");
        // Default value
        if (token.isSymbol(Token.kFieldValueSep)) {
            tokenizer.next();
            Token defaultValue = tokenizer.parseValue();
            field.setDefaultValue(defaultValue.asString());
            field.setStartLineNo(defaultValue.getLineNo());
            field.setStartLinePos(defaultValue.getLinePos());
            token = tokenizer.peek("field annotation, def or message end");
        }
        // Annotation
        if (token.isSymbol(Token.kParamsStart)) {
            tokenizer.next();
            field.setAnnotations(parseAnnotations(tokenizer, "field"));
            token = tokenizer.peek("field def or message end");
        }
        struct.addToFields(field.build());
        if (token.isSymbol(Token.kLineSep1) || token.isSymbol(Token.kLineSep2)) {
            tokenizer.next();
        }
    }
    if (tokenizer.hasNext()) {
        Token token = tokenizer.peek("optional annotations");
        if (token.isSymbol(Token.kParamsStart)) {
            tokenizer.next();
            struct.setAnnotations(parseAnnotations(tokenizer, "message"));
        }
    }
    return struct.build();
}
Also used : TypedefType(net.morimekta.providence.model.TypedefType) ThriftTokenizer.kNamespace(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kNamespace) FieldRequirement(net.morimekta.providence.model.FieldRequirement) EnumValue(net.morimekta.providence.model.EnumValue) Locale(java.util.Locale) Map(java.util.Map) Strings(net.morimekta.util.Strings) Token(net.morimekta.providence.serializer.pretty.Token) EnumType(net.morimekta.providence.model.EnumType) Collection(java.util.Collection) Declaration(net.morimekta.providence.model.Declaration) Set(java.util.Set) ThriftTokenizer.kInclude(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kInclude) ThriftTokenizer(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer) ThriftTokenizer.kService(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kService) List(java.util.List) ThriftTokenizer.kOneway(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kOneway) ThriftTokenizer.kConst(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kConst) TokenizerException(net.morimekta.providence.serializer.pretty.TokenizerException) Pattern(java.util.regex.Pattern) ServiceType(net.morimekta.providence.model.ServiceType) FieldType(net.morimekta.providence.model.FieldType) ProgramType(net.morimekta.providence.model.ProgramType) PEnumDescriptor(net.morimekta.providence.descriptor.PEnumDescriptor) Model_Constants(net.morimekta.providence.model.Model_Constants) ThriftTokenizer.kEnum(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kEnum) ThriftTokenizer.kException(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kException) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) IOUtils(net.morimekta.util.io.IOUtils) ThriftTokenizer.kLineCommentStart(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kLineCommentStart) ThriftTokenizer.kVoid(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kVoid) ThriftTokenizer.kUnion(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kUnion) ThriftTokenizer.kOptional(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kOptional) ThriftTokenizer.kRequired(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kRequired) IOException(java.io.IOException) ConstType(net.morimekta.providence.model.ConstType) ThriftTokenizer.kTypedef(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kTypedef) File(java.io.File) ReflectionUtils(net.morimekta.providence.reflect.util.ReflectionUtils) MessageVariant(net.morimekta.providence.model.MessageVariant) MessageType(net.morimekta.providence.model.MessageType) TreeMap(java.util.TreeMap) ThriftTokenizer.kExtends(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kExtends) ThriftTokenizer.kThrows(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kThrows) FunctionType(net.morimekta.providence.model.FunctionType) PRequirement(net.morimekta.providence.descriptor.PRequirement) ThriftTokenizer.kBlockCommentStart(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kBlockCommentStart) ThriftTokenizer.kStruct(net.morimekta.providence.reflect.parser.internal.ThriftTokenizer.kStruct) InputStream(java.io.InputStream) Token(net.morimekta.providence.serializer.pretty.Token) FieldType(net.morimekta.providence.model.FieldType) MessageType(net.morimekta.providence.model.MessageType) HashSet(java.util.HashSet)

Example 3 with FieldType

use of net.morimekta.providence.model.FieldType in project providence by morimekta.

the class ThriftProgramParser method parseService.

private ServiceType parseService(ThriftTokenizer tokenizer, String doc_string, Set<String> includedPrograms) throws IOException {
    ServiceType._Builder service = ServiceType.builder();
    if (doc_string != null) {
        service.setDocumentation(doc_string);
        doc_string = null;
    }
    Token identifier = tokenizer.expectIdentifier("service name");
    if (!allowedNameIdentifier(identifier.asString())) {
        throw tokenizer.failure(identifier, "Service with reserved name: " + identifier.asString());
    }
    service.setName(identifier.asString());
    if (tokenizer.peek("service start or extends").strEquals(kExtends)) {
        tokenizer.next();
        service.setExtend(tokenizer.expect("service extending identifier", t -> t.isIdentifier() || t.isQualifiedIdentifier()).asString());
    }
    tokenizer.expectSymbol("reading service start", Token.kMessageStart);
    Set<String> methodNames = new TreeSet<>();
    while (true) {
        Token token = tokenizer.expect("service method initializer");
        if (token.isSymbol(Token.kMessageEnd)) {
            break;
        } else if (token.strEquals(kLineCommentStart)) {
            doc_string = parseDocLine(tokenizer, doc_string);
            continue;
        } else if (token.strEquals(kBlockCommentStart)) {
            doc_string = tokenizer.parseDocBlock();
            continue;
        }
        FunctionType._Builder method = FunctionType.builder();
        if (doc_string != null) {
            method.setDocumentation(doc_string);
            doc_string = null;
        }
        if (token.strEquals(kOneway)) {
            method.setOneWay(true);
            token = tokenizer.expect("service method type");
        }
        if (!token.strEquals(kVoid)) {
            if (method.isSetOneWay()) {
                throw tokenizer.failure(token, "Oneway methods must have void return type, found '%s'", Strings.escape(token.asString()));
            }
            method.setReturnType(parseType(tokenizer, token, includedPrograms));
        }
        token = tokenizer.expectIdentifier("method name");
        String name = token.asString();
        if (!allowedNameIdentifier(name)) {
            throw tokenizer.failure(token, "Method with reserved name: " + name);
        }
        String normalized = Strings.camelCase("", name);
        if (methodNames.contains(normalized)) {
            throw tokenizer.failure(token, "Service method " + name + " has normalized name conflict");
        }
        methodNames.add(normalized);
        method.setName(name);
        tokenizer.expectSymbol("method params begin", Token.kParamsStart);
        int nextAutoParamKey = -1;
        while (true) {
            token = tokenizer.expect("method params");
            if (token.isSymbol(Token.kParamsEnd)) {
                break;
            } else if (token.strEquals(kLineCommentStart)) {
                doc_string = parseDocLine(tokenizer, doc_string);
                continue;
            } else if (token.strEquals(kBlockCommentStart)) {
                doc_string = tokenizer.parseDocBlock();
                continue;
            }
            FieldType._Builder field = FieldType.builder();
            if (doc_string != null) {
                field.setDocumentation(doc_string);
                doc_string = null;
            }
            if (token.isInteger()) {
                field.setId((int) token.parseInteger());
                tokenizer.expectSymbol("params kv sep", Token.kKeyValueSep);
                token = tokenizer.expect("param type");
            } else {
                if (requireFieldId) {
                    throw tokenizer.failure(token, "Missing param ID in strict declaration");
                }
                field.setId(nextAutoParamKey--);
            }
            if (PRequirement.OPTIONAL.label.equals(token.asString())) {
                field.setRequirement(FieldRequirement.OPTIONAL);
                token = tokenizer.expect("param type");
            } else if (PRequirement.REQUIRED.label.equals(token.asString())) {
                field.setRequirement(FieldRequirement.REQUIRED);
                token = tokenizer.expect("param type");
            }
            field.setType(parseType(tokenizer, token, includedPrograms));
            token = tokenizer.expectIdentifier("param name");
            name = token.asString();
            if (!allowedNameIdentifier(name)) {
                throw tokenizer.failure(token, "Param with reserved name: " + name);
            }
            field.setName(name);
            // Annotations.
            if (tokenizer.peek("method param annotation").isSymbol(Token.kParamsStart)) {
                tokenizer.next();
                field.setAnnotations(parseAnnotations(tokenizer, "params"));
            }
            token = tokenizer.peek("method params");
            if (token.isSymbol(Token.kLineSep1) || token.isSymbol(Token.kLineSep2)) {
                tokenizer.next();
            }
            method.addToParams(field.build());
        }
        // for each param
        doc_string = null;
        if (tokenizer.peek("possible throws statement").strEquals(kThrows)) {
            tokenizer.next();
            tokenizer.expectSymbol("throws group start", Token.kParamsStart);
            int nextAutoExceptionKey = -1;
            while (true) {
                token = tokenizer.expect("exception key, type or end throws");
                if (token.isSymbol(Token.kParamsEnd)) {
                    break;
                } else if (token.strEquals(kLineCommentStart)) {
                    doc_string = parseDocLine(tokenizer, doc_string);
                    continue;
                } else if (token.strEquals(kBlockCommentStart)) {
                    doc_string = tokenizer.parseDocBlock();
                    continue;
                }
                FieldType._Builder field = FieldType.builder();
                if (doc_string != null) {
                    field.setDocumentation(doc_string);
                    doc_string = null;
                }
                if (token.isInteger()) {
                    field.setId((int) token.parseInteger());
                    tokenizer.expectSymbol("exception KV sep", Token.kKeyValueSep);
                    token = tokenizer.expect("exception type");
                } else {
                    if (requireFieldId) {
                        throw tokenizer.failure(token, "Missing exception ID in strict declaration");
                    }
                    field.setId(nextAutoExceptionKey--);
                }
                field.setType(parseType(tokenizer, token, includedPrograms));
                token = tokenizer.expectIdentifier("exception name");
                name = token.asString();
                if (!allowedNameIdentifier(name)) {
                    throw tokenizer.failure(token, "Thrown field with reserved name: " + name);
                }
                field.setName(name);
                // Annotations.
                if (tokenizer.peek("exception annotation start").isSymbol(Token.kParamsStart)) {
                    tokenizer.next();
                    field.setAnnotations(parseAnnotations(tokenizer, "exception"));
                }
                method.addToExceptions(field.build());
                token = tokenizer.peek("method exceptions");
                if (token.isSymbol(Token.kLineSep1) || token.isSymbol(Token.kLineSep2)) {
                    tokenizer.next();
                }
            }
        }
        token = tokenizer.peek("");
        // Method Annotations.
        if (token.isSymbol(Token.kParamsStart)) {
            tokenizer.next();
            method.setAnnotations(parseAnnotations(tokenizer, "method"));
            token = tokenizer.peek("method or service end");
        }
        service.addToMethods(method.build());
        if (token.isSymbol(Token.kLineSep1) || token.isSymbol(Token.kLineSep2)) {
            tokenizer.next();
        }
    }
    if (tokenizer.hasNext()) {
        Token token = tokenizer.peek("optional annotations");
        if (token.isSymbol(Token.kParamsStart)) {
            // Method Annotations.
            tokenizer.next();
            service.setAnnotations(parseAnnotations(tokenizer, "service"));
        }
    }
    return service.build();
}
Also used : ServiceType(net.morimekta.providence.model.ServiceType) TreeSet(java.util.TreeSet) FunctionType(net.morimekta.providence.model.FunctionType) Token(net.morimekta.providence.serializer.pretty.Token) FieldType(net.morimekta.providence.model.FieldType)

Aggregations

TreeSet (java.util.TreeSet)3 FieldType (net.morimekta.providence.model.FieldType)3 FunctionType (net.morimekta.providence.model.FunctionType)3 ServiceType (net.morimekta.providence.model.ServiceType)3 File (java.io.File)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 Set (java.util.Set)2 PEnumDescriptor (net.morimekta.providence.descriptor.PEnumDescriptor)2 PRequirement (net.morimekta.providence.descriptor.PRequirement)2 ConstType (net.morimekta.providence.model.ConstType)2 Declaration (net.morimekta.providence.model.Declaration)2 EnumType (net.morimekta.providence.model.EnumType)2 EnumValue (net.morimekta.providence.model.EnumValue)2 MessageType (net.morimekta.providence.model.MessageType)2 MessageVariant (net.morimekta.providence.model.MessageVariant)2 ProgramType (net.morimekta.providence.model.ProgramType)2 Token (net.morimekta.providence.serializer.pretty.Token)2 ImmutableList (com.google.common.collect.ImmutableList)1 ImmutableMap (com.google.common.collect.ImmutableMap)1