Java tutorial
/* * Copyright (C) 2015 Square, Inc. * * Licensed 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 com.squareup.wire.schema; import com.google.common.collect.ImmutableList; import com.squareup.wire.schema.internal.parser.FieldElement; import java.util.Collection; import static com.squareup.wire.schema.Options.FIELD_OPTIONS; public final class Field { static final ProtoMember DEPRECATED = ProtoMember.get(FIELD_OPTIONS, "deprecated"); static final ProtoMember PACKED = ProtoMember.get(FIELD_OPTIONS, "packed"); private final String packageName; private final Location location; private final Label label; private final String name; private final String documentation; private final int tag; private final String defaultValue; private final String elementType; private final boolean extension; private final Options options; private ProtoType type; private Object deprecated; private Object packed; private Field(String packageName, Location location, Label label, String name, String documentation, int tag, String defaultValue, String elementType, Options options, boolean extension) { this.packageName = packageName; this.location = location; this.label = label; this.name = name; this.documentation = documentation; this.tag = tag; this.defaultValue = defaultValue; this.elementType = elementType; this.extension = extension; this.options = options; } static ImmutableList<Field> fromElements(String packageName, ImmutableList<FieldElement> fieldElements, boolean extension) { ImmutableList.Builder<Field> fields = ImmutableList.builder(); for (FieldElement field : fieldElements) { fields.add(new Field(packageName, field.location(), field.label(), field.name(), field.documentation(), field.tag(), field.defaultValue(), field.type(), new Options(Options.FIELD_OPTIONS, field.options()), extension)); } return fields.build(); } static ImmutableList<FieldElement> toElements(ImmutableList<Field> fields) { ImmutableList.Builder<FieldElement> elements = new ImmutableList.Builder<>(); for (Field field : fields) { elements.add(FieldElement.builder(field.location).label(field.label).name(field.name) .documentation(field.documentation).tag(field.tag).defaultValue(field.defaultValue) .options(field.options.toElements()).type(field.elementType).build()); } return elements.build(); } public Location location() { return location; } public String packageName() { return packageName; } public Label label() { return label; } public boolean isRepeated() { return label() == Label.REPEATED; } public boolean isOptional() { return label() == Label.OPTIONAL; } public boolean isRequired() { return label() == Label.REQUIRED; } public ProtoType type() { return type; } public String name() { return name; } /** * Returns this field's name, prefixed with its package name. Uniquely identifies extension * fields, such as in options. */ public String qualifiedName() { return packageName != null ? packageName + '.' + name : name; } public int tag() { return tag; } public String documentation() { return documentation; } public Options options() { return options; } public boolean isDeprecated() { return "true".equals(deprecated); } public boolean isPacked() { return "true".equals(packed); } public String getDefault() { return defaultValue; } private boolean isPackable(Linker linker, ProtoType type) { return !type.equals(ProtoType.STRING) && !type.equals(ProtoType.BYTES) && !(linker.get(type) instanceof MessageType); } public boolean isExtension() { return extension; } void link(Linker linker) { linker = linker.withContext(this); type = linker.resolveType(elementType); } void linkOptions(Linker linker) { linker = linker.withContext(this); options.link(linker); deprecated = options().get(DEPRECATED); packed = options().get(PACKED); } void validate(Linker linker) { linker = linker.withContext(this); if (isPacked() && !isPackable(linker, type)) { linker.addError("packed=true not permitted on %s", type); } if (extension && isRequired()) { linker.addError("extension fields cannot be required", type); } linker.validateImport(location(), type); } Field retainAll(Schema schema, MarkSet markSet) { if (!markSet.contains(type)) return null; Field result = new Field(packageName, location, label, name, documentation, tag, defaultValue, elementType, options.retainAll(schema, markSet), extension); result.type = type; result.deprecated = deprecated; result.packed = packed; return result; } static ImmutableList<Field> retainAll(Schema schema, MarkSet markSet, ProtoType enclosingType, Collection<Field> fields) { ImmutableList.Builder<Field> result = ImmutableList.builder(); for (Field field : fields) { Field retainedField = field.retainAll(schema, markSet); if (retainedField != null && markSet.contains(ProtoMember.get(enclosingType, field.name()))) { result.add(retainedField); } } return result.build(); } @Override public String toString() { return name(); } public enum Label { OPTIONAL, REQUIRED, REPEATED, /** Indicates the field is a member of a {@code oneof} block. */ ONE_OF } }