CUnionDescriptor.java
/*
* Copyright 2016 Providence Authors
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package net.morimekta.providence.reflect.contained;
import net.morimekta.providence.PMessageBuilder;
import net.morimekta.providence.descriptor.PDescriptorProvider;
import net.morimekta.providence.descriptor.PField;
import net.morimekta.providence.descriptor.PUnionDescriptor;
import net.morimekta.util.collect.UnmodifiableMap;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Supplier;
/**
* @author Stein Eldar Johnsen
* @since 07.09.15
*/
public class CUnionDescriptor extends PUnionDescriptor<CUnion> implements CMessageDescriptor {
private final CField<CUnion>[] fields;
private final Map<Integer, CField<CUnion>> fieldIdMap;
private final Map<String, CField<CUnion>> fieldNameMap;
private final Map<String, CField<CUnion>> fieldPojoNameMap;
private final Map<String, String> annotations;
private final String comment;
private final PDescriptorProvider implementing;
private final boolean innerType;
private final boolean autoType;
@SuppressWarnings("unchecked")
public CUnionDescriptor(String comment,
String packageName,
String name,
List<CField<CUnion>> fields,
Map<String, String> annotations,
PDescriptorProvider implementing) {
super(packageName, name, new _Factory(),
// overrides isSimple instead to avoid having to check fields
// types before it's converted.
false);
((_Factory) getBuilderSupplier()).setType(this);
this.innerType = name.contains(".");
// TODO: Make better detection of auto-types. Currently only service RQ / RS.
this.autoType = innerType && name.indexOf(".") != name.lastIndexOf(".");
this.comment = comment;
this.fields = fields.toArray((CField<CUnion>[]) CField.EMPTY_ARRAY);
this.annotations = annotations;
UnmodifiableMap.Builder<Integer, CField<CUnion>> fieldIdMap = UnmodifiableMap.builder(this.fields.length);
UnmodifiableMap.Builder<String, CField<CUnion>> fieldNameMap = UnmodifiableMap.builder(this.fields.length);
UnmodifiableMap.Builder<String, CField<CUnion>> fieldPojoNameMap = UnmodifiableMap.builder(this.fields.length);
for (CField<CUnion> field : fields) {
field.setMessageType(this);
fieldIdMap.put(field.getId(), field);
fieldNameMap.put(field.getName(), field);
fieldPojoNameMap.put(field.getPojoName(), field);
}
this.fieldIdMap = fieldIdMap.build();
this.fieldNameMap = fieldNameMap.build();
this.fieldPojoNameMap = fieldPojoNameMap.build();
this.implementing = implementing;
}
@Override
public boolean isInnerType() {
return innerType;
}
@Override
public boolean isAutoType() {
return autoType;
}
@Override
public final String getDocumentation() {
return comment;
}
@Nonnull
@Override
public CField<CUnion>[] getFields() {
return Arrays.copyOf(fields, fields.length);
}
@Override
public CField<CUnion> findFieldByName(String name) {
return fieldNameMap.get(name);
}
@Override
public CField<CUnion> findFieldByPojoName(String pojoName) {
return fieldPojoNameMap.get(pojoName);
}
@Override
public CField<CUnion> findFieldById(int id) {
return fieldIdMap.get(id);
}
@Nullable
@Override
public CInterfaceDescriptor getImplementing() {
if (implementing == null) return null;
return (CInterfaceDescriptor) implementing.descriptor();
}
@Override
public boolean isSimple() {
for (PField<CUnion> field : getFields()) {
switch (field.getType()) {
case MAP:
case SET:
case LIST:
case MESSAGE:
return false;
default:
break;
}
}
return true;
}
@Nonnull
@Override
@SuppressWarnings("unchecked")
public Set<String> getAnnotations() {
if (annotations != null) {
return annotations.keySet();
}
return Collections.EMPTY_SET;
}
@Override
public boolean hasAnnotation(@Nonnull String name) {
if (annotations != null) {
return annotations.containsKey(name);
}
return false;
}
@Override
public String getAnnotationValue(@Nonnull String name) {
if (annotations != null) {
return annotations.get(name);
}
return null;
}
@Nonnull
@Override
public CUnion.Builder builder() {
return (CUnion.Builder) super.builder();
}
private static class _Factory implements Supplier<PMessageBuilder<CUnion>> {
private CUnionDescriptor mType;
public void setType(CUnionDescriptor type) {
mType = type;
}
@Nonnull
@Override
public PMessageBuilder<CUnion> get() {
return new CUnion.Builder(mType);
}
}
}