private void walkRootNode(
     final Compiler.Context context, final AST node, final String namespace) {
   switch (node.getNodeLabel()) {
     case ProtoLexer.ENUM:
       context.addExpandedRoot(walkEnumNode(context, node, namespace, MessageDefinition.NULL));
       break;
     case ProtoLexer.EXTERN:
       walkExternNode(context, node, namespace, MessageDefinition.NULL);
       break;
     case ProtoLexer.MESSAGE:
       context.addExpandedRoot(walkMessageNode(context, node, namespace, MessageDefinition.NULL));
       break;
     case ProtoLexer.NAMESPACE:
       walkNamespaceNode(context, node, namespace);
       break;
     case ProtoLexer.TAXONOMY:
       context.addExpandedRoot(walkTaxonomyNode(context, node, namespace));
       break;
     case ProtoLexer.TYPEDEF:
       context.addExpandedRoot(walkTypedefNode(context, node, namespace, false));
       break;
     default:
       throw new IllegalStateException("invalid root type '" + node.getNodeLabel() + "'");
   }
 }
 private void walkExternNode(
     final Compiler.Context context,
     final AST node,
     final String namespace,
     final MessageDefinition outerMessage) {
   final List<AST> children = node.getChildNodes();
   final AST what = children.get(0);
   switch (what.getNodeLabel()) {
     case ProtoLexer.TYPEDEF:
       {
         final AST typedef = walkTypedefNode(context, what, namespace, true);
         children.set(0, typedef);
         context.addExpandedRoot(new ASTNode(node, children));
         return;
       }
   }
   final String localNamespace;
   final AST identifier = fixupFullIdentifier(children.get(1));
   if (namespace.length() != 0) {
     localNamespace = namespace + "." + identifier.getNodeValue();
   } else {
     localNamespace = identifier.getNodeValue();
   }
   switch (what.getNodeLabel()) {
     case ProtoLexer.ENUM:
       context.addDefinition(
           outerMessage.createEnumDefinition(localNamespace, identifier.getCodePosition(), false));
       break;
     case ProtoLexer.MESSAGE:
       final MessageDefinition messageDefinition =
           outerMessage.createMessageDefinition(
               localNamespace, identifier.getCodePosition(), false);
       if (children.size() < 3) {
         messageDefinition.setExternal();
       }
       context.addDefinition(messageDefinition);
       break;
     case ProtoLexer.TAXONOMY:
       context.addDefinition(
           new TaxonomyDefinition(localNamespace, identifier.getCodePosition(), false));
       break;
     default:
       throw new IllegalStateException("unexpected extern type '" + node.getNodeLabel() + "'");
   }
 }