Remove RevisionSourceIdentifier
[yangtools.git] / parser / rfc8040-parser-support / src / main / java / org / opendaylight / yangtools / rfc8040 / parser / OperationsValidateModuleAction.java
1 /*
2  * Copyright (c) 2021 PANTHEON.tech, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.rfc8040.parser;
9
10 import static java.util.Objects.requireNonNull;
11
12 import java.util.Collection;
13 import org.eclipse.jdt.annotation.NonNull;
14 import org.opendaylight.yangtools.rfc8040.model.api.YangDataConstants;
15 import org.opendaylight.yangtools.yang.common.QNameModule;
16 import org.opendaylight.yangtools.yang.common.UnresolvedQName.Unqualified;
17 import org.opendaylight.yangtools.yang.model.api.stmt.ContainerStatement;
18 import org.opendaylight.yangtools.yang.model.api.stmt.GroupingStatement;
19 import org.opendaylight.yangtools.yang.model.api.stmt.ModuleStatement;
20 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceAction;
21 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.InferenceContext;
22 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelActionBuilder.Prerequisite;
23 import org.opendaylight.yangtools.yang.parser.spi.meta.ModelProcessingPhase;
24 import org.opendaylight.yangtools.yang.parser.spi.meta.StmtContext.Mutable;
25 import org.opendaylight.yangtools.yang.parser.spi.source.ModuleCtxToModuleQName;
26
27 /**
28  * An {@link InferenceAction} tasked with identifying when we are dealing with {@link YangDataConstants#RFC8040_SOURCE}.
29  */
30 final class OperationsValidateModuleAction implements InferenceAction {
31     private static final Unqualified IETF_RESTCONF = YangDataConstants.RFC8040_SOURCE.name();
32
33     private final Prerequisite<? extends Mutable<?, ?, ?>> prereq;
34
35     private OperationsValidateModuleAction(final Prerequisite<? extends Mutable<?, ?, ?>> prereq) {
36         this.prereq = requireNonNull(prereq);
37     }
38
39     static void applyTo(@NonNull final Mutable<?, ?, ?> module) {
40         // Quick checks we can
41         if (module.producesDeclared(ModuleStatement.class) && IETF_RESTCONF.equals(module.argument())) {
42             // This is 'yang-api' definition within a 'ietf-restconf' module, but we are not certain about revisions
43             // and its structure. Next up we require the module to be fully declared, hence an inference action is
44             // needed to continue this process.
45             final var action = module.newInferenceAction(ModelProcessingPhase.FULL_DECLARATION);
46             final var prereq = action.mutatesEffectiveCtx(module);
47
48             action.apply(new OperationsValidateModuleAction(prereq));
49         }
50     }
51
52     @Override
53     public void apply(final InferenceContext ctx) {
54         final Mutable<?, ?, ?> moduleCtx = prereq.resolve(ctx);
55
56         // Check namespace and revision first
57         final QNameModule moduleQName = moduleCtx.getFromNamespace(ModuleCtxToModuleQName.class, moduleCtx);
58         if (!YangDataConstants.RFC8040_MODULE.equals(moduleQName)) {
59             return;
60         }
61
62         // Now carefully locate the operations container:
63         //
64         //   grouping restconf {
65         //     container restconf {
66         //       container operations;
67         //     }
68         //   }
69         //
70         for (var moduleSub : moduleCtx.mutableDeclaredSubstatements()) {
71             if (moduleSub.producesDeclared(GroupingStatement.class) && "restconf".equals(moduleSub.rawArgument())) {
72                 for (var grpSub : moduleSub.mutableDeclaredSubstatements()) {
73                     if (grpSub.producesDeclared(ContainerStatement.class) && "restconf".equals(grpSub.rawArgument())) {
74                         for (var contSub : grpSub.mutableDeclaredSubstatements()) {
75                             if (contSub.producesDeclared(ContainerStatement.class)
76                                 && "operations".equals(contSub.rawArgument())) {
77                                 // Alright, we have a match. Hook the second stage of processing.
78                                 OperationsCreateLeafStatements.applyTo(moduleCtx, contSub);
79                                 return;
80                             }
81                         }
82                     }
83                 }
84             }
85         }
86     }
87
88     @Override
89     public void prerequisiteFailed(final Collection<? extends Prerequisite<?>> failed) {
90         // We do not really need to fail, as this means reactor will fail anyway
91     }
92 }