001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.fusesource.hawtbuf.proto.compiler;
018
019 import java.util.LinkedHashMap;
020 import java.util.List;
021 import java.util.Map;
022
023 public class EnumDescriptor implements TypeDescriptor {
024
025 private String name;
026 private Map<String,EnumFieldDescriptor> fields= new LinkedHashMap<String, EnumFieldDescriptor>();
027 private final ProtoDescriptor protoDescriptor;
028 private final MessageDescriptor parent;
029 private Map<String, OptionDescriptor> options = new LinkedHashMap<String, OptionDescriptor>();
030
031 public EnumDescriptor(ProtoDescriptor protoDescriptor, MessageDescriptor parent) {
032 this.protoDescriptor = protoDescriptor;
033 this.parent = parent;
034 }
035
036 public String getName() {
037 return name;
038 }
039
040 public Map<String,EnumFieldDescriptor> getFields() {
041 return fields;
042 }
043
044 public void setName(String name) {
045 this.name = name;
046 }
047
048 public void setFields(Map<String,EnumFieldDescriptor> fields) {
049 this.fields = fields;
050 }
051 public ProtoDescriptor getProtoDescriptor() {
052 return protoDescriptor;
053 }
054
055 private String getOption(Map<String, OptionDescriptor> options, String optionName, String defaultValue) {
056 OptionDescriptor optionDescriptor = options.get(optionName);
057 if (optionDescriptor == null) {
058 return defaultValue;
059 }
060 return optionDescriptor.getValue();
061 }
062
063 private String constantToUCamelCase(String name) {
064 boolean upNext=true;
065 StringBuilder sb = new StringBuilder();
066 for (int i = 0; i < name.length(); i++) {
067 char c = name.charAt(i);
068 if( Character.isJavaIdentifierPart(c) && Character.isLetterOrDigit(c)) {
069 if( upNext ) {
070 c = Character.toUpperCase(c);
071 upNext=false;
072 } else {
073 c = Character.toLowerCase(c);
074 }
075 sb.append(c);
076 } else {
077 upNext=true;
078 }
079 }
080 return sb.toString();
081 }
082
083 public void validate(List<String> errors) {
084 String createMessage = getOption(getOptions(), "java_create_message", null);
085 if( "true".equals(createMessage) ) {
086 for (EnumFieldDescriptor field : getFields().values()) {
087 String type = constantToUCamelCase(field.getName());
088
089 TypeDescriptor typeDescriptor=null;
090 // Find the type def for that guy..
091 if( parent!=null ) {
092 typeDescriptor = parent.getType(type);
093 }
094 if( typeDescriptor == null ) {
095 typeDescriptor = protoDescriptor.getType(type);
096 }
097 if( typeDescriptor == null ) {
098 errors.add("ENUM constant '"+field.getName()+"' did not find expected associated message: "+type);
099 } else {
100 field.associate(typeDescriptor);
101 typeDescriptor.associate(field);
102 }
103 }
104 }
105 }
106
107 public MessageDescriptor getParent() {
108 return parent;
109 }
110
111 public String getQName() {
112 if( parent==null ) {
113 return name;
114 } else {
115 return parent.getQName()+"."+name;
116 }
117 }
118
119 public boolean isEnum() {
120 return true;
121 }
122
123 public Map<String, OptionDescriptor> getOptions() {
124 return options;
125 }
126
127 public void setOptions(Map<String, OptionDescriptor> options) {
128 this.options = options;
129 }
130
131 public void associate(EnumFieldDescriptor desc) {
132 throw new RuntimeException("not supported.");
133 }
134
135
136 }